From 4f7d3a5cfc1b4e92f430fbce158803fa9b5a98c0 Mon Sep 17 00:00:00 2001 From: Asbelos Date: Tue, 9 Mar 2021 20:44:44 +0000 Subject: [PATCH 1/3] ED Drive away from prog track featuire --- WiThrottle.cpp | 31 ++++++++++++++++++++++++++++++- WiThrottle.h | 10 +++++++++- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/WiThrottle.cpp b/WiThrottle.cpp index e3c817a..c08b2b7 100644 --- a/WiThrottle.cpp +++ b/WiThrottle.cpp @@ -207,6 +207,25 @@ int WiThrottle::getLocoId(byte * cmd) { if (cmd[0]!='L' && cmd[0]!='S') return 0; // should not match any locos return getInt(cmd+1); } + +RingStream * WiThrottle::stashStream; +WiThrottle * WiThrottle::stashInstance; +byte WiThrottle::stashClient; +char WiThrottle::stashThrottleChar; + +void WiThrottle::getLocoCallback(int locoid) { + stashStream->mark(stashClient); + if (locoid<0) StringFormatter::send(stashStream,F("HMNo loco found on prog track\n")); + else { + char addcmd[20]={'M',stashThrottleChar,'+',(locoid>127)?'L':'S'}; + itoa(locoid,addcmd+4,10); + stashInstance->multithrottle(stashStream, (byte *)addcmd); + DCCWaveform::progTrack.setPowerMode(POWERMODE::ON); + DCC::setProgTrackSyncMain(true); // <1 JOIN> so we can drive loco away + } + stashStream->commit(); +} + void WiThrottle::multithrottle(RingStream * stream, byte * cmd){ char throttleChar=cmd[1]; int locoid=getLocoId(cmd+3); // -1 for * @@ -217,6 +236,16 @@ void WiThrottle::multithrottle(RingStream * stream, byte * cmd){ // DIAG(F("\nMultithrottle aval=%c cab=%d"), aval[0],locoid); switch(cmd[2]) { case '+': // add loco request + if (cmd[3]=='*') { + // M+* means get loco from prog track + stashStream= stream; + stashClient=stream->peekTargetMark(); + stashThrottleChar=throttleChar; + stashInstance=this; + DCC::setProgTrackSyncMain(false); // remove JOIN so we can read prog + DCC::getLocoId(getLocoCallback); + return; // return nothing in stream as response comes later + } //return error if address zero requested if (locoid==0) { StringFormatter::send(stream, F("HMAddress '0' not supported!\n"), cmd[3] ,locoid); @@ -236,7 +265,7 @@ void WiThrottle::multithrottle(RingStream * stream, byte * cmd){ //Get known Fn states from DCC for(int fKey=0; fKey<=28; fKey++) { int fstate=DCC::getFn(locoid,fKey); - if (fstate>=0) StringFormatter::send(stream,F("M%cA%c%d<;>F%d%d\n"),throttleChar,cmd[3],locoid,fstate,fKey); + if (fstate>=0) StringFormatter::send(stream,F("M%cA%c<;>F%d%d\n"),throttleChar,cmd[3],fstate,fKey); } StringFormatter::send(stream, F("M%cA%c%d<;>V%d\n"), throttleChar, cmd[3], locoid, DCCToWiTSpeed(DCC::getThrottleSpeed(locoid))); StringFormatter::send(stream, F("M%cA%c%d<;>R%d\n"), throttleChar, cmd[3], locoid, DCC::getThrottleDirection(locoid)); diff --git a/WiThrottle.h b/WiThrottle.h index 161020d..b065d4f 100644 --- a/WiThrottle.h +++ b/WiThrottle.h @@ -60,6 +60,14 @@ class WiThrottle { void multithrottle(RingStream * stream, byte * cmd); void locoAction(RingStream * stream, byte* aval, char throttleChar, int cab); void accessory(RingStream *, byte* cmd); - void checkHeartbeat(); + void checkHeartbeat(); + + // callback stuff to support prog track acquire + static RingStream * stashStream; + static WiThrottle * stashInstance; + static byte stashClient; + static char stashThrottleChar; + static void getLocoCallback(int locoid); + }; #endif From c51b445e410b6ca2942cb074d26ccb5786e1cb31 Mon Sep 17 00:00:00 2001 From: Asbelos Date: Thu, 11 Mar 2021 13:35:47 +0000 Subject: [PATCH 2/3] unjoin automatically --- DCC.cpp | 17 ++++++----------- WiThrottle.cpp | 49 ++++++++++++++++++++++++++----------------------- 2 files changed, 32 insertions(+), 34 deletions(-) diff --git a/DCC.cpp b/DCC.cpp index 6fe07c1..854f9b2 100644 --- a/DCC.cpp +++ b/DCC.cpp @@ -659,6 +659,7 @@ void DCC::ackManagerLoop() { // (typically waiting for a reset counter or ACK waiting, or when all finished.) switch (opcode) { case BASELINE: + setProgTrackSyncMain(false); if (DCCWaveform::progTrack.getPowerMode() == POWERMODE::OFF) { if (Diag::ACK) DIAG(F("\nAuto Prog power on")); DCCWaveform::progTrack.setPowerMode(POWERMODE::ON); @@ -725,23 +726,20 @@ void DCC::ackManagerLoop() { case ITC0: case ITC1: // If True Callback(0 or 1) (if prevous WACK got an ACK) if (ackReceived) { - ackManagerProg = NULL; // all done now - callback(opcode==ITC0?0:1); + callback(opcode==ITC0?0:1); return; } break; case ITCB: // If True callback(byte) if (ackReceived) { - ackManagerProg = NULL; // all done now callback(ackManagerByte); return; } break; - case ITCB7: // If True callback(byte & 0xF) + case ITCB7: // If True callback(byte & 0x7F) if (ackReceived) { - ackManagerProg = NULL; // all done now callback(ackManagerByte & 0x7F); return; } @@ -749,15 +747,13 @@ void DCC::ackManagerLoop() { case NAKFAIL: // If nack callback(-1) if (!ackReceived) { - ackManagerProg = NULL; // all done now - callback(-1); + callback(-1); return; } break; case FAIL: // callback(-1) - ackManagerProg = NULL; - callback(-1); + callback(-1); return; case STARTMERGE: @@ -801,7 +797,6 @@ void DCC::ackManagerLoop() { case COMBINELOCOID: // ackManagerStash is cv17, ackManagerByte is CV 18 - ackManagerProg=NULL; callback( ackManagerByte + ((ackManagerStash - 192) << 8)); return; @@ -817,7 +812,6 @@ void DCC::ackManagerLoop() { break; default: DIAG(F("\n!! ackOp %d FAULT!!"),opcode); - ackManagerProg=NULL; callback( -1); return; @@ -826,6 +820,7 @@ void DCC::ackManagerLoop() { } } void DCC::callback(int value) { + ackManagerProg=NULL; // no more steps to execute if (DCCWaveform::progTrack.autoPowerOff) { if (Diag::ACK) DIAG(F("\nAuto Prog power off")); DCCWaveform::progTrack.doAutoPowerOff(); diff --git a/WiThrottle.cpp b/WiThrottle.cpp index c08b2b7..72814f8 100644 --- a/WiThrottle.cpp +++ b/WiThrottle.cpp @@ -208,24 +208,6 @@ int WiThrottle::getLocoId(byte * cmd) { return getInt(cmd+1); } -RingStream * WiThrottle::stashStream; -WiThrottle * WiThrottle::stashInstance; -byte WiThrottle::stashClient; -char WiThrottle::stashThrottleChar; - -void WiThrottle::getLocoCallback(int locoid) { - stashStream->mark(stashClient); - if (locoid<0) StringFormatter::send(stashStream,F("HMNo loco found on prog track\n")); - else { - char addcmd[20]={'M',stashThrottleChar,'+',(locoid>127)?'L':'S'}; - itoa(locoid,addcmd+4,10); - stashInstance->multithrottle(stashStream, (byte *)addcmd); - DCCWaveform::progTrack.setPowerMode(POWERMODE::ON); - DCC::setProgTrackSyncMain(true); // <1 JOIN> so we can drive loco away - } - stashStream->commit(); -} - void WiThrottle::multithrottle(RingStream * stream, byte * cmd){ char throttleChar=cmd[1]; int locoid=getLocoId(cmd+3); // -1 for * @@ -237,14 +219,15 @@ void WiThrottle::multithrottle(RingStream * stream, byte * cmd){ switch(cmd[2]) { case '+': // add loco request if (cmd[3]=='*') { - // M+* means get loco from prog track + // M+* means get loco from prog track, then join tracks ready to drive away + // Stash the things the callback will need later stashStream= stream; stashClient=stream->peekTargetMark(); stashThrottleChar=throttleChar; stashInstance=this; - DCC::setProgTrackSyncMain(false); // remove JOIN so we can read prog - DCC::getLocoId(getLocoCallback); - return; // return nothing in stream as response comes later + // ask DCC to call us back when the loco id has been read + DCC::getLocoId(getLocoCallback); // will remove any previous join + return; // return nothing in stream as response is sent later in the callback } //return error if address zero requested if (locoid==0) { @@ -396,4 +379,24 @@ void WiThrottle::checkHeartbeat() { char WiThrottle::LorS(int cab) { return (cab<127)?'S':'L'; -} +} + +// Drive Away feature. Callback handling + +RingStream * WiThrottle::stashStream; +WiThrottle * WiThrottle::stashInstance; +byte WiThrottle::stashClient; +char WiThrottle::stashThrottleChar; + +void WiThrottle::getLocoCallback(int locoid) { + stashStream->mark(stashClient); + if (locoid<0) StringFormatter::send(stashStream,F("HMNo loco found on prog track\n")); + else { + char addcmd[20]={'M',stashThrottleChar,'+',LorS(locoid) }; + itoa(locoid,addcmd+4,10); + stashInstance->multithrottle(stashStream, (byte *)addcmd); + DCCWaveform::progTrack.setPowerMode(POWERMODE::ON); + DCC::setProgTrackSyncMain(true); // <1 JOIN> so we can drive loco away + } + stashStream->commit(); +} From cec26c47e2cc9d6818036271c352eb285a454d7a Mon Sep 17 00:00:00 2001 From: Asbelos Date: Fri, 12 Mar 2021 10:38:30 +0000 Subject: [PATCH 3/3] Catch up with Steves change --- WiThrottle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WiThrottle.cpp b/WiThrottle.cpp index 72814f8..f824771 100644 --- a/WiThrottle.cpp +++ b/WiThrottle.cpp @@ -248,7 +248,7 @@ void WiThrottle::multithrottle(RingStream * stream, byte * cmd){ //Get known Fn states from DCC for(int fKey=0; fKey<=28; fKey++) { int fstate=DCC::getFn(locoid,fKey); - if (fstate>=0) StringFormatter::send(stream,F("M%cA%c<;>F%d%d\n"),throttleChar,cmd[3],fstate,fKey); + if (fstate>=0) StringFormatter::send(stream,F("M%cA%c%d<;>F%d%d\n"),throttleChar,cmd[3],locoid,fstate,fKey); } StringFormatter::send(stream, F("M%cA%c%d<;>V%d\n"), throttleChar, cmd[3], locoid, DCCToWiTSpeed(DCC::getThrottleSpeed(locoid))); StringFormatter::send(stream, F("M%cA%c%d<;>R%d\n"), throttleChar, cmd[3], locoid, DCC::getThrottleDirection(locoid));