diff --git a/DCCEXParser.cpp b/DCCEXParser.cpp index 6779178..2c50ac1 100644 --- a/DCCEXParser.cpp +++ b/DCCEXParser.cpp @@ -58,6 +58,8 @@ const int16_t HASH_KEYWORD_SPEED28 = -17064; const int16_t HASH_KEYWORD_SPEED128 = 25816; const int16_t HASH_KEYWORD_SERVO=27709; const int16_t HASH_KEYWORD_VPIN=-415; +const int16_t HASH_KEYWORD_C=67; +const int16_t HASH_KEYWORD_T=84; int16_t DCCEXParser::stashP[MAX_COMMAND_PARAMS]; bool DCCEXParser::stashBusy; @@ -674,63 +676,62 @@ bool DCCEXParser::parseT(Print *stream, int16_t params, int16_t p[]) return true; case 2: // - switch (p[1]) { -#ifdef TURNOUT_LEGACY_BEHAVIOUR - // turnout 1 or T=THROW, 0 or C=CLOSE - case 1: case 0x54: // 1 or T - if (!Turnout::setClosed(p[0], false)) return false; - p[1] = 1; - break; - case 0: case 0x43: // 0 or C - if (!Turnout::setClosed(p[0], true)) return false; - p[1] = 0; - break; -#else - // turnout 0 or T=THROW,1 or C=CLOSE - case 0: case 0x54: // 0 or T - if (!Turnout::setClosed(p[0], false)) return false; - p[1] = 0; - break; - case 1: case 0x43: // 1 or C - if (!Turnout::setClosed(p[0], true)) return false; - p[1] = 1; - break; -#endif - default: - return false; - } - // Send acknowledgement to caller if the command was not received over Serial (acknowledgement - // messages on Serial are sent by the Turnout class). - if (stream != &Serial) StringFormatter::send(stream, F("\n"), p[0], p[1]); - return true; + { + bool state = false; + switch (p[1]) { + // By default turnout command uses 0=throw, 1=close, + // but legacy DCC++ behaviour is 1=throw, 0=close. + case 0: + state = Turnout::useLegacyTurnoutBehaviour; + break; + case 1: + state = !Turnout::useLegacyTurnoutBehaviour; + break; + case HASH_KEYWORD_C: + state = true; + break; + case HASH_KEYWORD_T: + state= false; + break; + default: + return false; + } + if (!Turnout::setClosed(p[0], state)) return false; - default: // Anything else is some kind of create function. - if (p[1] == HASH_KEYWORD_SERVO) { // - if (params == 6) { - if (!ServoTurnout::create(p[0], (VPIN)p[2], (uint16_t)p[3], (uint16_t)p[4], (uint8_t)p[5])) - return false; - } else + // Send acknowledgement to caller if the command was not received over Serial + // (acknowledgement messages on Serial are sent by the Turnout class). + if (stream != &Serial) Turnout::printState(p[0], stream); + return true; + } + + default: // Anything else is some kind of turnout create function. + if (params == 6 && p[1] == HASH_KEYWORD_SERVO) { // + if (!ServoTurnout::create(p[0], (VPIN)p[2], (uint16_t)p[3], (uint16_t)p[4], (uint8_t)p[5])) return false; } else - if (p[1] == HASH_KEYWORD_VPIN) { // - if (params==3) { - if (!VpinTurnout::create(p[0], p[2])) return false; - } else - return false; - } else - if (p[1]==HASH_KEYWORD_DCC) { - if (params==4 && p[2]>0 && p[2]<=512 && p[3]>=0 && p[3]<4) { // + if (params == 3 && p[1] == HASH_KEYWORD_VPIN) { // + if (!VpinTurnout::create(p[0], p[2])) return false; + } else + if (params >= 3 && p[1] == HASH_KEYWORD_DCC) { + if (params==4 && p[2]>0 && p[2]<=512 && p[3]>=0 && p[3]<4) { // if (!DCCTurnout::create(p[0], p[2], p[3])) return false; - } else if (params==3 && p[2]>0 && p[2]<=512*4) { // + } else if (params==3 && p[2]>0 && p[2]<=512*4) { // , 1<=nn<=2048 if (!DCCTurnout::create(p[0], (p[2]-1)/4+1, (p[2]-1)%4)) return false; } else return false; - } else if (params==3) { // for DCC or LCN - if (!DCCTurnout::create(p[0], p[1], p[2])) return false; + } else + if (params==3) { // legacy for DCC accessory + if (p[1]>0 && p[1]<=512 && p[2]>=0 && p[2]<4) { + if (!DCCTurnout::create(p[0], p[1], p[2])) return false; + } else + return false; } - else if (params==3) { // legacy for Servo + else + if (params==4) { // legacy for Servo if (!ServoTurnout::create(p[0], (VPIN)p[1], (uint16_t)p[2], (uint16_t)p[3], 1)) return false; - } + } else + return false; + StringFormatter::send(stream, F("\n")); return true; } diff --git a/Turnouts.cpp b/Turnouts.cpp index 8a77f57..86607f4 100644 --- a/Turnouts.cpp +++ b/Turnouts.cpp @@ -20,6 +20,14 @@ * along with CommandStation. If not, see . */ +#ifndef TURNOUTS_CPP +#define TURNOUTS_CPP + +// Set the following definition to true for = throw and = close +// or to false for = close and = throw (the original way). +#ifndef USE_LEGACY_TURNOUT_BEHAVIOUR +#define USE_LEGACY_TURNOUT_BEHAVIOUR false +#endif #include "defines.h" #include "EEStore.h" @@ -30,12 +38,6 @@ #include "DIAG.h" #endif -// Keywords used for turnout configuration. -const int16_t HASH_KEYWORD_SERVO=27709; -const int16_t HASH_KEYWORD_DCC=6436; -const int16_t HASH_KEYWORD_VPIN=-415; - - /* * Protected static data */ @@ -46,6 +48,7 @@ const int16_t HASH_KEYWORD_VPIN=-415; * Public static data */ int Turnout::turnoutlistHash = 0; + bool Turnout::useLegacyTurnoutBehaviour = USE_LEGACY_TURNOUT_BEHAVIOUR; /* * Protected static functions @@ -130,8 +133,7 @@ const int16_t HASH_KEYWORD_VPIN=-415; // Send message to JMRI etc. over Serial USB. This is done here // to ensure that the message is sent when the turnout operation // is not initiated by a Serial command. - StringFormatter::send(Serial, F("\n"), id, closeFlag); - + printState(id, &Serial); return ok; } @@ -189,3 +191,12 @@ const int16_t HASH_KEYWORD_VPIN=-415; return tt; } + // Display, on the specified stream, the current state of the turnout (1 or 0). + void Turnout::printState(uint16_t id, Print *stream) { + Turnout *tt = get(id); + if (!tt) + StringFormatter::send(stream, F("\n"), + id, tt->_turnoutData.closed ^ useLegacyTurnoutBehaviour); + } + +#endif \ No newline at end of file diff --git a/Turnouts.h b/Turnouts.h index 6659c24..32a8a94 100644 --- a/Turnouts.h +++ b/Turnouts.h @@ -109,6 +109,7 @@ public: * Static data */ static int turnoutlistHash; + static bool useLegacyTurnoutBehaviour; /* * Public base class functions @@ -171,6 +172,8 @@ public: for (Turnout *tt = _firstTurnout; tt != 0; tt = tt->_nextTurnout) tt->print(stream); } + + static void printState(uint16_t id, Print *stream); }; @@ -259,7 +262,8 @@ public: void print(Print *stream) override { StringFormatter::send(stream, F("\n"), _turnoutData.id, _servoTurnoutData.vpin, - _servoTurnoutData.thrownPosition, _servoTurnoutData.closedPosition, _servoTurnoutData.profile, _turnoutData.closed); + _servoTurnoutData.thrownPosition, _servoTurnoutData.closedPosition, _servoTurnoutData.profile, + _turnoutData.closed ^ useLegacyTurnoutBehaviour); } // Load a Servo turnout definition from EEPROM. The common Turnout data has already been read at this point. @@ -338,7 +342,8 @@ public: void print(Print *stream) override { StringFormatter::send(stream, F("\n"), _turnoutData.id, - (((_dccTurnoutData.address-1) >> 2)+1), ((_dccTurnoutData.address-1) & 3), _turnoutData.closed); + (((_dccTurnoutData.address-1) >> 2)+1), ((_dccTurnoutData.address-1) & 3), + _turnoutData.closed ^ useLegacyTurnoutBehaviour); } // Load a DCC turnout definition from EEPROM. The common Turnout data has already been read at this point. @@ -413,8 +418,8 @@ public: } void print(Print *stream) override { - StringFormatter::send(stream, F("\n"), _turnoutData.id, - _vpinTurnoutData.vpin, _turnoutData.closed); + StringFormatter::send(stream, F("\n"), _turnoutData.id, _vpinTurnoutData.vpin, + _turnoutData.closed ^ useLegacyTurnoutBehaviour); } // Load a VPIN turnout definition from EEPROM. The common Turnout data has already been read at this point. @@ -477,7 +482,8 @@ public: //static Turnout *load(struct TurnoutData *turnoutData) { void print(Print *stream) override { - StringFormatter::send(stream, F("\n"), _turnoutData.id, _turnoutData.closed); + StringFormatter::send(stream, F("\n"), _turnoutData.id, + _turnoutData.closed ^ useLegacyTurnoutBehaviour); } };