diff --git a/DCC.cpp b/DCC.cpp index f42ddf7..8726534 100644 --- a/DCC.cpp +++ b/DCC.cpp @@ -84,7 +84,7 @@ void DCC::setThrottle2( uint16_t cab, byte speedCode) { uint8_t nB = 0; // DIAG(F("setSpeedInternal %d %x"),cab,speedCode); - if (cab > 127) + if (cab > HIGHEST_SHORT_ADDR) b[nB++] = highByte(cab) | 0xC0; // convert train number into a two-byte address b[nB++] = lowByte(cab); @@ -124,7 +124,7 @@ void DCC::setFunctionInternal(int cab, byte byte1, byte byte2) { byte b[4]; byte nB = 0; - if (cab > 127) + if (cab > HIGHEST_SHORT_ADDR) b[nB++] = highByte(cab) | 0xC0; // convert train number into a two-byte address b[nB++] = lowByte(cab); if (byte1!=0) b[nB++] = byte1; @@ -153,7 +153,7 @@ void DCC::setFn( int cab, int16_t functionNumber, bool on) { //non reminding advanced binary bit set byte b[5]; byte nB = 0; - if (cab > 127) + if (cab > HIGHEST_SHORT_ADDR) b[nB++] = highByte(cab) | 0xC0; // convert train number into a two-byte address b[nB++] = lowByte(cab); if (functionNumber <= 127) { @@ -262,7 +262,7 @@ void DCC::setAccessory(int address, byte number, bool activate) { void DCC::writeCVByteMain(int cab, int cv, byte bValue) { byte b[5]; byte nB = 0; - if (cab > 127) + if (cab > HIGHEST_SHORT_ADDR) b[nB++] = highByte(cab) | 0xC0; // convert train number into a two-byte address b[nB++] = lowByte(cab); @@ -283,7 +283,7 @@ void DCC::writeCVBitMain(int cab, int cv, byte bNum, bool bValue) { bValue = bValue % 2; bNum = bNum % 8; - if (cab > 127) + if (cab > HIGHEST_SHORT_ADDR) b[nB++] = highByte(cab) | 0xC0; // convert train number into a two-byte address b[nB++] = lowByte(cab); @@ -548,7 +548,7 @@ void DCC::setLocoId(int id,ACK_CALLBACK callback) { callback(-1); return; } - if (id<=127) + if (id<=HIGHEST_SHORT_ADDR) ackManagerSetup(id, SHORT_LOCO_ID_PROG, callback); else ackManagerSetup(id | 0xc000,LONG_LOCO_ID_PROG, callback); @@ -906,7 +906,7 @@ void DCC::ackManagerLoop() { case COMBINELOCOID: // ackManagerStash is cv17, ackManagerByte is CV 18 - callback( ackManagerByte + ((ackManagerStash - 192) << 8)); + callback( LONG_ADDR_MARKER | ( ackManagerByte + ((ackManagerStash - 192) << 8))); return; case ITSKIP: diff --git a/DCC.h b/DCC.h index 8cb5d97..283b406 100644 --- a/DCC.h +++ b/DCC.h @@ -23,6 +23,16 @@ #include "MotorDrivers.h" #include "FSH.h" +#include "config.h" +#ifndef HIGHEST_SHORT_ADDR +#define HIGHEST_SHORT_ADDR 127 +#else +#if HIGHEST_SHORT_ADDR > 127 +#error short addr greater than 127 does not make sense +#endif +#endif +#define LONG_ADDR_MARKER 0x4000 + typedef void (*ACK_CALLBACK)(int16_t result); enum ackOp : byte diff --git a/DCCEXParser.cpp b/DCCEXParser.cpp index ed1f684..98cd1be 100644 --- a/DCCEXParser.cpp +++ b/DCCEXParser.cpp @@ -960,8 +960,17 @@ void DCCEXParser::callback_R(int16_t result) void DCCEXParser::callback_Rloco(int16_t result) { + if (result <= 0) + StringFormatter::send(getAsyncReplyStream(), F("\n")); + else if (result & LONG_ADDR_MARKER ) { //long addr + result = result & ~LONG_ADDR_MARKER; + if (result > HIGHEST_SHORT_ADDR) //real long + StringFormatter::send(getAsyncReplyStream(), F("\n"), result); + else + StringFormatter::send(getAsyncReplyStream(), F("\n"), result); + } else // short addr StringFormatter::send(getAsyncReplyStream(), F("\n"), result); - commitAsyncReplyStream(); + commitAsyncReplyStream(); } void DCCEXParser::callback_Wloco(int16_t result) diff --git a/WiThrottle.cpp b/WiThrottle.cpp index 07017ba..62369ce 100644 --- a/WiThrottle.cpp +++ b/WiThrottle.cpp @@ -409,7 +409,7 @@ void WiThrottle::checkHeartbeat() { } char WiThrottle::LorS(int cab) { - return (cab<127)?'S':'L'; + return (cab<=HIGHEST_SHORT_ADDR)?'S':'L'; } // Drive Away feature. Callback handling @@ -421,9 +421,20 @@ char WiThrottle::stashThrottleChar; void WiThrottle::getLocoCallback(int16_t locoid) { stashStream->mark(stashClient); - if (locoid<0) StringFormatter::send(stashStream,F("HMNo loco found on prog track\n")); + + char addrchar; + if (locoid & LONG_ADDR_MARKER) { // long addr + locoid = locoid & ~LONG_ADDR_MARKER; + addrchar = 'L'; + } else + addrchar = 'S'; + + if (locoid<=0) + StringFormatter::send(stashStream,F("HMNo loco found on prog track\n")); + else if (addrchar == 'L' && locoid <= HIGHEST_SHORT_ADDR ) + StringFormatter::send(stashStream,F("HMLong addr <= 127 not supported\n")); else { - char addcmd[20]={'M',stashThrottleChar,'+',LorS(locoid) }; + char addcmd[20]={'M',stashThrottleChar,'+', addrchar}; itoa(locoid,addcmd+4,10); stashInstance->multithrottle(stashStream, (byte *)addcmd); DCCWaveform::progTrack.setPowerMode(POWERMODE::ON); diff --git a/config.example.h b/config.example.h index 5f26ca7..2708bae 100644 --- a/config.example.h +++ b/config.example.h @@ -128,6 +128,18 @@ The configuration file for DCC-EX Command Station // Define scroll mode as 0, 1 or 2 #define SCROLLMODE 1 +///////////////////////////////////////////////////////////////////////////////////// +// REDEFINE WHERE SHORT/LONG ADDR break is. According to NMRA the last short address +// is 127 and the first long address is 128. There are manufacturers which have +// another view. Lenz CS for example have considered addresses long from 100. If +// you want to change to that mode, do +//#define HIGHEST_SHORT_ADDR 99 +// If you want to run all your locos addressed long format, you could even do a +//#define HIGHEST_SHORT_ADDR 0 +// We do not support to use the same address, for example 100(long) and 100(short) +// at the same time, there must be a border. + + ///////////////////////////////////////////////////////////////////////////////////// // // DEFINE TURNOUTS/ACCESSORIES FOLLOW NORM RCN-213