mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-27 01:56:14 +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.)
|
// (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();
|
||||||
|
|
|
@ -207,6 +207,7 @@ int WiThrottle::getLocoId(byte * cmd) {
|
||||||
if (cmd[0]!='L' && cmd[0]!='S') return 0; // should not match any locos
|
if (cmd[0]!='L' && cmd[0]!='S') return 0; // should not match any locos
|
||||||
return getInt(cmd+1);
|
return getInt(cmd+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 *
|
||||||
|
@ -217,6 +218,17 @@ void WiThrottle::multithrottle(RingStream * stream, byte * cmd){
|
||||||
// DIAG(F("\nMultithrottle aval=%c cab=%d"), aval[0],locoid);
|
// DIAG(F("\nMultithrottle aval=%c cab=%d"), aval[0],locoid);
|
||||||
switch(cmd[2]) {
|
switch(cmd[2]) {
|
||||||
case '+': // add loco request
|
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
|
//return error if address zero requested
|
||||||
if (locoid==0) {
|
if (locoid==0) {
|
||||||
StringFormatter::send(stream, F("HMAddress '0' not supported!\n"), cmd[3] ,locoid);
|
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
|
//Get known Fn states from DCC
|
||||||
for(int fKey=0; fKey<=28; fKey++) {
|
for(int fKey=0; fKey<=28; fKey++) {
|
||||||
int fstate=DCC::getFn(locoid,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<;>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));
|
StringFormatter::send(stream, F("M%cA%c%d<;>R%d\n"), throttleChar, cmd[3], locoid, DCC::getThrottleDirection(locoid));
|
||||||
|
@ -367,4 +379,24 @@ 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();
|
||||||
|
}
|
||||||
|
|
10
WiThrottle.h
10
WiThrottle.h
|
@ -60,6 +60,14 @@ class WiThrottle {
|
||||||
void multithrottle(RingStream * stream, byte * cmd);
|
void multithrottle(RingStream * stream, byte * cmd);
|
||||||
void locoAction(RingStream * stream, byte* aval, char throttleChar, int cab);
|
void locoAction(RingStream * stream, byte* aval, char throttleChar, int cab);
|
||||||
void accessory(RingStream *, byte* cmd);
|
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
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue
Block a user