mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-23 08:06:13 +01:00
commit
9e49167be9
17
DCC.cpp
17
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();
|
||||
|
|
|
@ -207,6 +207,7 @@ int WiThrottle::getLocoId(byte * cmd) {
|
|||
if (cmd[0]!='L' && cmd[0]!='S') return 0; // should not match any locos
|
||||
return getInt(cmd+1);
|
||||
}
|
||||
|
||||
void WiThrottle::multithrottle(RingStream * stream, byte * cmd){
|
||||
char throttleChar=cmd[1];
|
||||
int locoid=getLocoId(cmd+3); // -1 for *
|
||||
|
@ -217,6 +218,17 @@ 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, then join tracks ready to drive away
|
||||
// Stash the things the callback will need later
|
||||
stashStream= stream;
|
||||
stashClient=stream->peekTargetMark();
|
||||
stashThrottleChar=throttleChar;
|
||||
stashInstance=this;
|
||||
// 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) {
|
||||
StringFormatter::send(stream, F("HMAddress '0' not supported!\n"), cmd[3] ,locoid);
|
||||
|
@ -236,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%d<;>F%d%d\n"),throttleChar,cmd[3],locoid,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));
|
||||
|
@ -368,3 +380,23 @@ 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();
|
||||
}
|
||||
|
|
|
@ -61,5 +61,13 @@ class WiThrottle {
|
|||
void locoAction(RingStream * stream, byte* aval, char throttleChar, int cab);
|
||||
void accessory(RingStream *, byte* cmd);
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue
Block a user