1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2025-07-28 18:03:45 +02:00

Compare commits

...

13 Commits

Author SHA1 Message Date
Harald Barth
c8ac10e893 default power off for CS mode 2025-02-23 08:48:17 +01:00
Harald Barth
1db0b8ab3e add EXRAIL for booster 2025-02-23 08:16:24 +01:00
Harald Barth
d9bd1e75f2 sort power output different 2025-02-21 00:09:35 +01:00
Harald Barth
d1daf41f12 version 5.4.5 2025-02-20 21:21:41 +01:00
Harald Barth
6bfa7028c4 Merge branch 'master' of https://github.com/DCC-EX/CommandStation-EX 2025-02-20 21:20:44 +01:00
Harald Barth
a5d1d04882 remove unneccessary warning about prog track as it can happen normally 2025-02-20 21:18:10 +01:00
Harald Barth
bd6e426499 track power is always turned on after setJoin() not by setJoin() 2025-02-20 21:16:50 +01:00
Harald Barth
09bae44cc0 ESP32: Better detection of wrong IDF version 2025-02-20 21:15:49 +01:00
Fred
9f3354c687 Move xls release notes to release notes folder (#440) 2025-02-18 09:23:30 -05:00
Fred
fb495985f4 Add XLS searchable version of 5.4 release notes (#439) 2025-02-18 08:30:28 -05:00
Harald Barth
f868604ca9 version 5.4.4 2025-01-31 11:22:55 +01:00
Harald Barth
41168a9dd8 Bugfix: trailing > in command was not replaced with \0 which did break <+> commands 2025-01-31 11:19:22 +01:00
Harald Barth
0154e7fd78 Bugfix: serial COMMAND_BUFFER_SIZE could be silently overrun 2025-01-31 11:17:59 +01:00
10 changed files with 116 additions and 38 deletions

62
BoosterAutomation.h Normal file
View File

@@ -0,0 +1,62 @@
// Booster/CS switch automations
// uses BOOSTER_INPUT from config.h
// uses sequences BOOSTER_START, BOOSTER_CSMODE, BOOSTER_BOOSTERMODE, BOOSTER_CHANGELOGIC
// uses latches 200
#if defined(ARDUINO_ARCH_ESP32)
#ifndef BOOSTER_INPUT
#error You need to define BOOSTER_INPUT in config.h
#endif
ALIAS(BOOSTER_START)
ALIAS(BOOSTER_CSMODE)
ALIAS(BOOSTER_BOOSTERMODE)
ALIAS(BOOSTER_CHANGELOGIC)
AUTOSTART // remove this if you want manual start
ROUTE(BOOSTER_START, "BOOSTER/CS auto START")
PRINT("BOOTER/CS auto mode starting for both tracks")
CALL(BOOSTER_BOOSTERMODE) // try booster mode
FOLLOW(BOOSTER_CHANGELOGIC) // goto automatic mode
ROUTE(BOOSTER_CSMODE, "RUN AS CS")
SET_TRACK(A, MAIN)
// SET_POWER(A, ON)
SET_TRACK(B, PROG)
// SET_POWER(B, ON)
PRINT("CS START")
LATCH(200)
RETURN
ROUTE(BOOSTER_BOOSTERMODE, "RUN AS BOOSTER")
SET_TRACK(A, BOOST)
SET_POWER(A, ON)
SET_TRACK(B, BOOST)
SET_POWER(B, ON)
PRINT("BOOSTER START")
UNLATCH(200)
RETURN
#define BOOSTER_TIMEOUT 500
SEQUENCE(BOOSTER_CHANGELOGIC)
// Monitor pin change and get a timeout if not
IF(BOOSTER_INPUT)
ATTIMEOUT(-BOOSTER_INPUT,BOOSTER_TIMEOUT)
ELSE
ATTIMEOUT(BOOSTER_INPUT,BOOSTER_TIMEOUT)
ENDIF
IFTIMEOUT
IF(200)
// already switched to CS mode
ELSE
CALL(BOOSTER_CSMODE)
ENDIF
// hang here and wait for pin change
IF(BOOSTER_INPUT)
AT(-BOOSTER_INPUT)
ELSE
AT(BOOSTER_INPUT)
ENDIF
// pin change has happened, go to booster mode
CALL(BOOSTER_BOOSTERMODE)
ENDIF
FOLLOW(BOOSTER_CHANGELOGIC)
#undef BOOSTER_TIMEOUT
#endif

View File

@@ -280,6 +280,9 @@ void CommandDistributor::broadcastPower() {
state = '1';
}
if (state != '2')
broadcastReply(COMMAND_TYPE, F("<p%c>\n"),state);
// additional info about MAIN, PROG and JOIN
bool main=TrackManager::getMainPower()==POWERMODE::ON;
bool prog=TrackManager::getProgPower()==POWERMODE::ON;
@@ -288,7 +291,7 @@ void CommandDistributor::broadcastPower() {
const FSH * reason=F("");
if (join) {
reason = F(" JOIN"); // with space at start so we can append without space
broadcastReply(COMMAND_TYPE, F("<p1 %S>\n"),reason);
broadcastReply(COMMAND_TYPE, F("<p1%S>\n"),reason);
} else {
if (main) {
//reason = F("MAIN");
@@ -299,9 +302,6 @@ void CommandDistributor::broadcastPower() {
broadcastReply(COMMAND_TYPE, F("<p1 PROG>\n"));
}
}
if (state != '2')
broadcastReply(COMMAND_TYPE, F("<p%c>\n"),state);
#ifdef CD_HANDLE_RING
// send '1' if all main are on, otherwise global state (which in that case is '0' or '2')
broadcastReply(WITHROTTLE_TYPE, F("PPA%c\n"), main?'1': state);

View File

@@ -167,8 +167,10 @@ int16_t DCCEXParser::splitValues(int16_t result[MAX_COMMAND_PARAMS], byte *cmd,
break;
if (hot == '\0')
return -1;
if (hot == '>')
if (hot == '>') {
*remainingCmd = '\0'; // terminate the cmd string with 0 instead of '>'
return parameterCount;
}
state = 2;
continue;
@@ -265,8 +267,9 @@ void DCCEXParser::parse(const FSH * cmd) {
// See documentation on DCC class for info on this section
void DCCEXParser::parse(Print *stream, byte *com, RingStream *ringStream) {
// This function can get stings of the form "<C OMM AND>" or "C OMM AND"
// found is true first after the leading "<" has been passed
// This function can get stings of the form "<C OMM AND>" or "C OMM AND>"
// found is true first after the leading "<" has been passed which results
// in parseOne() getting c="C OMM AND>"
bool found = (com[0] != '<');
for (byte *c=com; c[0] != '\0'; c++) {
if (found) {

View File

@@ -78,11 +78,17 @@ int DCCTimer::freeMemory() {
////////////////////////////////////////////////////////////////////////
#ifdef ARDUINO_ARCH_ESP32
#if __has_include("esp_idf_version.h")
#include "esp_idf_version.h"
#if ESP_IDF_VERSION_MAJOR > 4
#endif
#if ESP_IDF_VERSION_MAJOR == 4
// all well correct IDF version
#else
#error "DCC-EX does not support compiling with IDF version 5.0 or later. Downgrade your ESP32 library to a version that contains IDF version 4. Arduino ESP32 library 3.0.0 is too new. Downgrade to one of 2.0.9 to 2.0.17"
#endif
// protect all the rest of the code from IDF version 5
#if ESP_IDF_VERSION_MAJOR == 4
#include "DIAG.h"
#include <driver/adc.h>
#include <soc/sens_reg.h>
@@ -322,5 +328,5 @@ void ADCee::scan() {
void ADCee::begin() {
}
#endif //IDF v4
#endif //ESP32

View File

@@ -931,8 +931,9 @@ void RMFT2::loop2() {
#ifndef DISABLE_PROG
case OPCODE_JOIN:
TrackManager::setPower(POWERMODE::ON);
TrackManager::setJoin(true);
TrackManager::setMainPower(POWERMODE::ON);
TrackManager::setProgPower(POWERMODE::ON);
break;
case OPCODE_UNJOIN:

Binary file not shown.

View File

@@ -126,29 +126,33 @@ void SerialManager::loop2() {
buffer[0] = '\0';
}
} else { // if (inCommandPayload)
if (bufferLength < (COMMAND_BUFFER_SIZE-1))
buffer[bufferLength++] = ch;
if (inCommandPayload > PAYLOAD_NORMAL) {
if (inCommandPayload > 32 + 2) { // String way too long
ch = '>'; // we end this nonsense
inCommandPayload = PAYLOAD_NORMAL;
DIAG(F("Parse error: Unbalanced string"));
// fall through to ending parsing below
} else if (ch == '"') { // String end
inCommandPayload = PAYLOAD_NORMAL;
continue; // do not fall through
} else
inCommandPayload++;
}
if (inCommandPayload == PAYLOAD_NORMAL) {
if (ch == '>') {
buffer[bufferLength] = '\0';
DCCEXParser::parse(serial, buffer, NULL);
inCommandPayload = PAYLOAD_FALSE;
break;
} else if (ch == '"') {
inCommandPayload = PAYLOAD_STRING;
}
if (bufferLength < (COMMAND_BUFFER_SIZE-1)) {
buffer[bufferLength++] = ch; // advance bufferLength
if (inCommandPayload > PAYLOAD_NORMAL) {
if (inCommandPayload > 32 + 2) { // String way too long
ch = '>'; // we end this nonsense
inCommandPayload = PAYLOAD_NORMAL;
DIAG(F("Parse error: Unbalanced string"));
// fall through to ending parsing below
} else if (ch == '"') { // String end
inCommandPayload = PAYLOAD_NORMAL;
continue; // do not fall through
} else
inCommandPayload++;
}
if (inCommandPayload == PAYLOAD_NORMAL) {
if (ch == '>') {
buffer[bufferLength] = '\0'; // This \0 is after the '>'
DCCEXParser::parse(serial, buffer, NULL); // buffer parsed with trailing '>'
inCommandPayload = PAYLOAD_FALSE;
break;
} else if (ch == '"') {
inCommandPayload = PAYLOAD_STRING;
}
}
} else {
DIAG(F("Parse error: input buffer overflow"));
inCommandPayload = PAYLOAD_FALSE;
}
}
}

View File

@@ -668,7 +668,8 @@ void TrackManager::setJoin(bool joined) {
if (track[t]->getMode() & TRACK_MODE_PROG) { // find PROG track
tempProgTrack = t; // remember PROG track
setTrackMode(t, TRACK_MODE_MAIN);
track[t]->setPower(POWERMODE::ON); // if joined, always on
// setPower() of the track called after
// seperately after setJoin() instead
break; // there is only one prog track, done
}
}
@@ -680,8 +681,6 @@ void TrackManager::setJoin(bool joined) {
setTrackMode(tempProgTrack, TRACK_MODE_PROG); // set track mode back to prog
track[tempProgTrack]->setPower(tPTmode); // set power status as it was before
tempProgTrack = MAX_TRACKS+1;
} else {
DIAG(F("Unjoin but no remembered prog track"));
}
}
#endif

View File

@@ -500,9 +500,9 @@ void WiThrottle::getLocoCallback(int16_t locoid) {
char addcmd[20]={'M',stashThrottleChar,'+', addrchar};
itoa(locoid,addcmd+4,10);
stashInstance->multithrottle(stashStream, (byte *)addcmd);
TrackManager::setJoin(true); // <1 JOIN> so we can drive loco away
TrackManager::setMainPower(POWERMODE::ON);
TrackManager::setProgPower(POWERMODE::ON);
TrackManager::setJoin(true); // <1 JOIN> so we can drive loco away
DIAG(F("LocoCallback commit success"));
stashStream->commit();
}

View File

@@ -3,7 +3,10 @@
#include "StringFormatter.h"
#define VERSION "5.4.3"
#define VERSION "5.4.5"
// 5.4.5 - ESP32: Better detection of correct IDF version
// - track power is always turned on after setJoin() not by setJoin()
// 5.4.4 - bugfix in parser, input buffer overrun and trailing > that did break <+>
// 5.4.3 - bugfix changeFn for functions 29..31
// 5.4.2 - Reversed turnout bugfix
// 5.4.1 - ESP32 bugfix packet buffer race