1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-12-25 05:31:24 +01:00

unjoin automatically

This commit is contained in:
Asbelos 2021-03-11 13:35:47 +00:00
parent 4f7d3a5cfc
commit c51b445e41
2 changed files with 32 additions and 34 deletions

17
DCC.cpp
View File

@ -659,6 +659,7 @@ void DCC::ackManagerLoop() {
// (typically waiting for a reset counter or ACK waiting, or when all finished.) // (typically waiting for a reset counter or ACK waiting, or when all finished.)
switch (opcode) { switch (opcode) {
case BASELINE: case BASELINE:
setProgTrackSyncMain(false);
if (DCCWaveform::progTrack.getPowerMode() == POWERMODE::OFF) { if (DCCWaveform::progTrack.getPowerMode() == POWERMODE::OFF) {
if (Diag::ACK) DIAG(F("\nAuto Prog power on")); if (Diag::ACK) DIAG(F("\nAuto Prog power on"));
DCCWaveform::progTrack.setPowerMode(POWERMODE::ON); DCCWaveform::progTrack.setPowerMode(POWERMODE::ON);
@ -725,23 +726,20 @@ void DCC::ackManagerLoop() {
case ITC0: case ITC0:
case ITC1: // If True Callback(0 or 1) (if prevous WACK got an ACK) case ITC1: // If True Callback(0 or 1) (if prevous WACK got an ACK)
if (ackReceived) { if (ackReceived) {
ackManagerProg = NULL; // all done now callback(opcode==ITC0?0:1);
callback(opcode==ITC0?0:1);
return; return;
} }
break; break;
case ITCB: // If True callback(byte) case ITCB: // If True callback(byte)
if (ackReceived) { if (ackReceived) {
ackManagerProg = NULL; // all done now
callback(ackManagerByte); callback(ackManagerByte);
return; return;
} }
break; break;
case ITCB7: // If True callback(byte & 0xF) case ITCB7: // If True callback(byte & 0x7F)
if (ackReceived) { if (ackReceived) {
ackManagerProg = NULL; // all done now
callback(ackManagerByte & 0x7F); callback(ackManagerByte & 0x7F);
return; return;
} }
@ -749,15 +747,13 @@ void DCC::ackManagerLoop() {
case NAKFAIL: // If nack callback(-1) case NAKFAIL: // If nack callback(-1)
if (!ackReceived) { if (!ackReceived) {
ackManagerProg = NULL; // all done now callback(-1);
callback(-1);
return; return;
} }
break; break;
case FAIL: // callback(-1) case FAIL: // callback(-1)
ackManagerProg = NULL; callback(-1);
callback(-1);
return; return;
case STARTMERGE: case STARTMERGE:
@ -801,7 +797,6 @@ void DCC::ackManagerLoop() {
case COMBINELOCOID: case COMBINELOCOID:
// ackManagerStash is cv17, ackManagerByte is CV 18 // ackManagerStash is cv17, ackManagerByte is CV 18
ackManagerProg=NULL;
callback( ackManagerByte + ((ackManagerStash - 192) << 8)); callback( ackManagerByte + ((ackManagerStash - 192) << 8));
return; return;
@ -817,7 +812,6 @@ void DCC::ackManagerLoop() {
break; break;
default: default:
DIAG(F("\n!! ackOp %d FAULT!!"),opcode); DIAG(F("\n!! ackOp %d FAULT!!"),opcode);
ackManagerProg=NULL;
callback( -1); callback( -1);
return; return;
@ -826,6 +820,7 @@ void DCC::ackManagerLoop() {
} }
} }
void DCC::callback(int value) { void DCC::callback(int value) {
ackManagerProg=NULL; // no more steps to execute
if (DCCWaveform::progTrack.autoPowerOff) { if (DCCWaveform::progTrack.autoPowerOff) {
if (Diag::ACK) DIAG(F("\nAuto Prog power off")); if (Diag::ACK) DIAG(F("\nAuto Prog power off"));
DCCWaveform::progTrack.doAutoPowerOff(); DCCWaveform::progTrack.doAutoPowerOff();

View File

@ -208,24 +208,6 @@ int WiThrottle::getLocoId(byte * cmd) {
return getInt(cmd+1); 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){ void WiThrottle::multithrottle(RingStream * stream, byte * cmd){
char throttleChar=cmd[1]; char throttleChar=cmd[1];
int locoid=getLocoId(cmd+3); // -1 for * int locoid=getLocoId(cmd+3); // -1 for *
@ -237,14 +219,15 @@ void WiThrottle::multithrottle(RingStream * stream, byte * cmd){
switch(cmd[2]) { switch(cmd[2]) {
case '+': // add loco request case '+': // add loco request
if (cmd[3]=='*') { 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; stashStream= stream;
stashClient=stream->peekTargetMark(); stashClient=stream->peekTargetMark();
stashThrottleChar=throttleChar; stashThrottleChar=throttleChar;
stashInstance=this; stashInstance=this;
DCC::setProgTrackSyncMain(false); // remove JOIN so we can read prog // ask DCC to call us back when the loco id has been read
DCC::getLocoId(getLocoCallback); DCC::getLocoId(getLocoCallback); // will remove any previous join
return; // return nothing in stream as response comes later return; // return nothing in stream as response is sent later in the callback
} }
//return error if address zero requested //return error if address zero requested
if (locoid==0) { if (locoid==0) {
@ -397,3 +380,23 @@ void WiThrottle::checkHeartbeat() {
char WiThrottle::LorS(int cab) { char WiThrottle::LorS(int cab) {
return (cab<127)?'S':'L'; 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();
}