diff --git a/DCC.cpp b/DCC.cpp index e81cb04..6942d76 100644 --- a/DCC.cpp +++ b/DCC.cpp @@ -523,6 +523,7 @@ const ackOp FLASH LOCO_ID_PROG[] = { V0, WACK, MERGE, V0, WACK, MERGE, VB, WACK, NAKSKIP, // bad read of cv20, assume its 0 + BAD20SKIP, // detect invalid cv20 value and ignore STASHLOCOID, // keep cv 20 until we have cv19 as well. SETCV, (ackOp)19, STARTMERGE, // Setup to read cv 19 @@ -628,7 +629,9 @@ const ackOp FLASH CONSIST_ID_PROG[] = { BASELINE, SETCV,(ackOp)20, SETBYTEH, // high byte to CV 20 - WB,WACK, // ignore dedcoder without cv20 support + WB,WACK,ITSKIP, + FAIL_IF_NONZERO_NAK, // fail if writing long address to decoder that cant support it + SKIPTARGET, SETCV,(ackOp)19, SETBYTEL, // low byte of word WB,WACK,ITC1, // If ACK, we are done - callback(1) means Ok diff --git a/DCCACK.cpp b/DCCACK.cpp index 7a43cd1..0ae5224 100644 --- a/DCCACK.cpp +++ b/DCCACK.cpp @@ -347,6 +347,20 @@ void DCCACK::loop() { opcode=GETFLASH(ackManagerProg); } break; + case BAD20SKIP: + if (ackManagerByte > 120) { + // skip to SKIPTARGET if cv20 is >120 (some decoders respond with 255) + if (Diag::ACK) DIAG(F("XX cv20=%d "),ackManagerByte); + while (opcode!=SKIPTARGET) { + ackManagerProg++; + opcode=GETFLASH(ackManagerProg); + } + } + break; + case FAIL_IF_NONZERO_NAK: // fail if writing long address to decoder that cant support it + if (ackManagerByte==0) break; + callback(-4); + return; case SKIPTARGET: break; default: diff --git a/DCCACK.h b/DCCACK.h index c50dbbd..3a6148d 100644 --- a/DCCACK.h +++ b/DCCACK.h @@ -58,6 +58,8 @@ enum ackOp : byte ITSKIP, // skip to SKIPTARGET if ack true NAKSKIP, // skip to SKIPTARGET if ack false COMBINE1920, // combine cvs 19 and 20 and callback + BAD20SKIP, // skip to SKIPTARGET if cv20 is >120 (some decoders respond with 255) + FAIL_IF_NONZERO_NAK, // fail if writing long address to decoder that cant support it SKIPTARGET = 0xFF // jump to target }; diff --git a/DCCEXParser.cpp b/DCCEXParser.cpp index 6bec5fb..0aae191 100644 --- a/DCCEXParser.cpp +++ b/DCCEXParser.cpp @@ -1452,6 +1452,7 @@ void DCCEXParser::callback_Wloco(int16_t result) void DCCEXParser::callback_Wconsist(int16_t result) { + if (result==-4) DIAG(F("Long Consist %d not supported by decoder"),stashP[1]); if (result==1) result=stashP[1]; // pick up original requested id from command StringFormatter::send(getAsyncReplyStream(), F("\n"), result, stashP[2]=="REVERSE"_hk ? F(" REVERSE") : F("")); diff --git a/version.h b/version.h index ccf326c..131d09a 100644 --- a/version.h +++ b/version.h @@ -3,7 +3,9 @@ #include "StringFormatter.h" -#define VERSION "5.4.8" +#define VERSION "5.4.9" +// 5.4.9 - Handle non-compliant decoders returning 255 for cv 20 and confusing with bad consist addresses. +// - handles non-compliant decoders which NAK cv 20 writes. // 5.4.8 - Bugfix: Insert idle packet at end of speed reminder loop; treat all function groups equal // 5.4.7 - Bugfix: EXRAIL fix CLEAR_ALL_STASH // 5.4.6 - Bugfix: Do not drop further commands in same packet