From 865c8dd3bd654f727f476d0111cd5207454b9161 Mon Sep 17 00:00:00 2001 From: Asbelos Date: Sat, 19 Mar 2022 16:26:29 +0000 Subject: [PATCH] DCX Track mode And unified SET_TRACK Exrail macro --- EXRAIL2.cpp | 10 +++++++--- EXRAIL2MacroReset.h | 6 ++---- EXRAILMacros.h | 3 +-- TrackManager.cpp | 37 ++++++++++++++++++++++++++++--------- TrackManager.h | 22 ++++++++++++++++------ 5 files changed, 54 insertions(+), 24 deletions(-) diff --git a/EXRAIL2.cpp b/EXRAIL2.cpp index e4451a2..c7a61dc 100644 --- a/EXRAIL2.cpp +++ b/EXRAIL2.cpp @@ -670,9 +670,13 @@ void RMFT2::loop2() { break; case OPCODE_SET_TRACK: - // operand is track id and +128= Use my loco for DC - TrackManager::setTrackMode(operand & 0x0F, - operand>=128 ? loco : TrackManager::TRACK_MODE_MAIN); + // operand is trackmode<<8 | track id + // If DC/DCX use my loco for DC address + { + TRACK_MODE mode = (TRACK_MODE)(operand>>8); + int16_t cab=(mode==TRACK_MODE_DC || mode==TRACK_MODE_DCX) ? loco : 0; + TrackManager::setTrackMode(operand & 0x0F, mode, cab); + } break; case OPCODE_RESUME: diff --git a/EXRAIL2MacroReset.h b/EXRAIL2MacroReset.h index e140a32..c7c106c 100644 --- a/EXRAIL2MacroReset.h +++ b/EXRAIL2MacroReset.h @@ -103,8 +103,7 @@ #undef SERVO_TURNOUT #undef SERVO_SIGNAL #undef SET -#undef SET_TRACK_DC -#undef SET_TRACK_DCC +#undef SET_TRACK #undef SETLOCO #undef SIGNAL #undef SIGNALH @@ -200,8 +199,7 @@ #define SERVO_SIGNAL(vpin,redpos,amberpos,greenpos) #define SERVO_TURNOUT(id,pin,activeAngle,inactiveAngle,profile,description...) #define SET(pin) -#define SET_TRACK_DC(trackid) -#define SET_TRACK_DCC(trackid) +#define SET_TRACK(track,mode) #define SETLOCO(loco) #define SIGNAL(redpin,amberpin,greenpin) #define SIGNALH(redpin,amberpin,greenpin) diff --git a/EXRAILMacros.h b/EXRAILMacros.h index 4e7e065..d32cfae 100644 --- a/EXRAILMacros.h +++ b/EXRAILMacros.h @@ -247,8 +247,7 @@ const FLASH int16_t RMFT2::SignalDefinitions[] = { #define SERVO_SIGNAL(vpin,redpos,amberpos,greenpos) #define SERVO_TURNOUT(id,pin,activeAngle,inactiveAngle,profile,description...) OPCODE_SERVOTURNOUT,V(id),OPCODE_PAD,V(pin),OPCODE_PAD,V(activeAngle),OPCODE_PAD,V(inactiveAngle),OPCODE_PAD,V(PCA9685::ProfileType::profile), #define SET(pin) OPCODE_SET,V(pin), -#define SET_TRACK_DC(track) OPCODE_SET_TRACK,V(128+track), -#define SET_TRACK_DCC(track) OPCODE_SET_TRACK,V(track), +#define SET_TRACK(track,mode) OPCODE_SET_TRACK,V(TRACK_MODE_##mode <<8 | TRACK_NUMBER_##track), #define SETLOCO(loco) OPCODE_SETLOCO,V(loco), #define SIGNAL(redpin,amberpin,greenpin) #define SIGNALH(redpin,amberpin,greenpin) diff --git a/TrackManager.cpp b/TrackManager.cpp index 470e039..074f8df 100644 --- a/TrackManager.cpp +++ b/TrackManager.cpp @@ -35,10 +35,13 @@ const int16_t HASH_KEYWORD_PROG = -29718; const int16_t HASH_KEYWORD_MAIN = 11339; const int16_t HASH_KEYWORD_OFF = 22479; const int16_t HASH_KEYWORD_DC = 2183; +const int16_t HASH_KEYWORD_DCX = 6463; // DC reversed polarity const int16_t HASH_KEYWORD_A = 65; // parser makes single chars the ascii. MotorDriver * TrackManager::track[MAX_TRACKS]; -int16_t TrackManager::trackMode[MAX_TRACKS]; +TRACK_MODE TrackManager::trackMode[MAX_TRACKS]; +int16_t TrackManager::trackDCAddr[MAX_TRACKS]; + POWERMODE TrackManager::mainPowerGuess=POWERMODE::OFF; byte TrackManager::lastTrack=0; bool TrackManager::progTrackSyncMain=false; @@ -61,7 +64,7 @@ void TrackManager::Setup(const FSH * shieldname, addTrack(6,track6); addTrack(7,track7); - // Default the first 2 tracks (which mat be null) and perform HA waveform check. + // Default the first 2 tracks (which may be null) and perform HA waveform check. setTrackMode(0,TRACK_MODE_MAIN); setTrackMode(1,TRACK_MODE_PROG); @@ -93,17 +96,24 @@ void TrackManager::setPROGSignal( bool on) { } void TrackManager::setDCSignal(int16_t cab, byte speedbyte) { - APPLY_BY_MODE(cab,setDCSignal(speedbyte)); -} + FOR_EACH_TRACK(t) { + if (trackDCAddr[t]!=cab) continue; + if (trackMode[t]==TRACK_MODE_DC) track[t]->setDCSignal(speedbyte); + else if (trackMode[t]==TRACK_MODE_DCX) track[t]->setDCSignal(speedbyte ^ 128); + } +} -bool TrackManager::setTrackMode(byte trackToSet, int16_t modeOrAddr) { + +bool TrackManager::setTrackMode(byte trackToSet, TRACK_MODE mode, int16_t dcAddr) { if (trackToSet>lastTrack || track[trackToSet]==NULL) return false; - if (modeOrAddr==TRACK_MODE_PROG) { + if (mode==TRACK_MODE_PROG) { // only allow 1 track to be prog FOR_EACH_TRACK(t) if (trackMode[t]==TRACK_MODE_PROG) trackMode[t]=TRACK_MODE_OFF; } - trackMode[trackToSet]=modeOrAddr; + trackMode[trackToSet]=mode; + trackDCAddr[trackToSet]=dcAddr; + // re-evaluate HighAccuracy mode // We can only do this is all main and prog tracks agree @@ -132,8 +142,14 @@ bool TrackManager::parseJ(Print *stream, int16_t params, int16_t p[]) case TRACK_MODE_OFF: StringFormatter::send(stream,F("OFF")); break; + case TRACK_MODE_DC: + StringFormatter::send(stream,F("DC %d"),trackDCAddr[t]); + break; + case TRACK_MODE_DCX: + StringFormatter::send(stream,F("DCX %d"),trackDCAddr[t]); + break; default: - StringFormatter::send(stream,F("DC %d"),trackMode[t]); + break; // unknown, dont care } StringFormatter::send(stream,F(">\n")); } @@ -155,7 +171,10 @@ bool TrackManager::parseJ(Print *stream, int16_t params, int16_t p[]) return setTrackMode(p[0],TRACK_MODE_OFF); if (params==3 && p[1]==HASH_KEYWORD_DC && p[2]>0) // <= id DC cab> - return setTrackMode(p[0],p[2]); + return setTrackMode(p[0],TRACK_MODE_DC,p[2]); + + if (params==3 && p[1]==HASH_KEYWORD_DCX && p[2]>0) // <= id DCX cab> + return setTrackMode(p[0],TRACK_MODE_DCX,p[2]); return false; } diff --git a/TrackManager.h b/TrackManager.h index 18a073f..dde4b90 100644 --- a/TrackManager.h +++ b/TrackManager.h @@ -23,6 +23,18 @@ #include "MotorDriver.h" // Virtualised Motor shield multi-track hardware Interface +enum TRACK_MODE : byte {TRACK_MODE_MAIN, TRACK_MODE_PROG, TRACK_MODE_OFF, + TRACK_MODE_DC, TRACK_MODE_DCX}; + +// These constants help EXRAIL macros say SET_TRACK(2,mode) OR SET_TRACK(C,mode) etc. +const byte TRACK_NUMBER_0=0, TRACK_NUMBER_A=0; +const byte TRACK_NUMBER_1=1, TRACK_NUMBER_B=1; +const byte TRACK_NUMBER_2=2, TRACK_NUMBER_C=2; +const byte TRACK_NUMBER_3=3, TRACK_NUMBER_D=3; +const byte TRACK_NUMBER_4=4, TRACK_NUMBER_E=4; +const byte TRACK_NUMBER_5=5, TRACK_NUMBER_F=5; +const byte TRACK_NUMBER_6=6, TRACK_NUMBER_G=6; +const byte TRACK_NUMBER_7=7, TRACK_NUMBER_H=7; class TrackManager { public: @@ -47,11 +59,8 @@ class TrackManager { static void setMainPower(POWERMODE mode) {setPower2(false,mode);} static void setProgPower(POWERMODE mode) {setPower2(true,mode);} - static const int16_t TRACK_MODE_MAIN=32760; - static const int16_t TRACK_MODE_PROG=32761; - static const int16_t TRACK_MODE_OFF=0; static const int16_t MAX_TRACKS=8; - static bool setTrackMode(byte track, int16_t DCaddrOrMode); + static bool setTrackMode(byte track, TRACK_MODE mode, int16_t DCaddr=0); static bool parseJ(Print * stream, int16_t params, int16_t p[]); static void loop(); static POWERMODE getMainPower() {return mainPowerGuess;} @@ -71,7 +80,8 @@ class TrackManager { static POWERMODE mainPowerGuess; static MotorDriver* track[MAX_TRACKS]; - static int16_t trackMode[MAX_TRACKS]; // dc address or TRACK_MODE_DCC, TRACK_MODE_PROG, TRACK_MODE_OFF -}; + static TRACK_MODE trackMode[MAX_TRACKS]; + static int16_t trackDCAddr[MAX_TRACKS]; // dc address if TRACK_MODE_DC or TRACK_MODE_DCX + }; #endif