From 3bddeeda3ec3dd6ad4eb21520dc57a6f2ae37a11 Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Thu, 25 Nov 2021 00:10:11 +0100 Subject: [PATCH 1/3] better long/short addr handling under ; configurable long/short border --- DCC.cpp | 14 +++++++------- DCC.h | 10 ++++++++++ DCCEXParser.cpp | 11 ++++++++++- WiThrottle.cpp | 17 ++++++++++++++--- config.example.h | 12 ++++++++++++ 5 files changed, 53 insertions(+), 11 deletions(-) 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 From 8a17965cd2195b659c50c2d5c51bd7970be71dcf Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Thu, 25 Nov 2021 19:55:48 +0100 Subject: [PATCH 2/3] type and correct include --- DCC.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DCC.h b/DCC.h index 283b406..fea9a1a 100644 --- a/DCC.h +++ b/DCC.h @@ -23,7 +23,7 @@ #include "MotorDrivers.h" #include "FSH.h" -#include "config.h" +#include "defines.h" #ifndef HIGHEST_SHORT_ADDR #define HIGHEST_SHORT_ADDR 127 #else @@ -31,7 +31,7 @@ #error short addr greater than 127 does not make sense #endif #endif -#define LONG_ADDR_MARKER 0x4000 +const uint16_t LONG_ADDR_MARKER = 0x4000; typedef void (*ACK_CALLBACK)(int16_t result); From 43538d3b327c6e532f2410008dbab04758c0fa31 Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Fri, 26 Nov 2021 19:32:45 +0100 Subject: [PATCH 3/3] smaller code --- DCCEXParser.cpp | 24 +++++++++++++----------- WiThrottle.cpp | 32 ++++++++++++++++++-------------- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/DCCEXParser.cpp b/DCCEXParser.cpp index 98cd1be..e3c9eac 100644 --- a/DCCEXParser.cpp +++ b/DCCEXParser.cpp @@ -958,18 +958,20 @@ void DCCEXParser::callback_R(int16_t result) commitAsyncReplyStream(); } -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); +void DCCEXParser::callback_Rloco(int16_t result) { + const FSH * detail; + if (result<=0) { + detail=F("\n"); + } else { + bool longAddr=result & LONG_ADDR_MARKER; //long addr + if (longAddr) + result = result^LONG_ADDR_MARKER; + if (longAddr && result <= HIGHEST_SHORT_ADDR) + detail=F("\n"); else - StringFormatter::send(getAsyncReplyStream(), F("\n"), result); - } else // short addr - StringFormatter::send(getAsyncReplyStream(), F("\n"), result); + detail=F("\n"); + } + StringFormatter::send(getAsyncReplyStream(), detail, result); commitAsyncReplyStream(); } diff --git a/WiThrottle.cpp b/WiThrottle.cpp index 62369ce..8aabb82 100644 --- a/WiThrottle.cpp +++ b/WiThrottle.cpp @@ -51,6 +51,8 @@ #include "version.h" #include "RMFT2.h" +#define STR_HELPER(x) #x +#define STR(x) STR_HELPER(x) #define LOOPLOCOS(THROTTLECHAR, CAB) for (int loco=0;locomark(stashClient); - 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,'+', addrchar}; - 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 + // short or long + char addrchar; + if (locoid & LONG_ADDR_MARKER) { // long addr + locoid = locoid ^ LONG_ADDR_MARKER; + addrchar = 'L'; + } else + addrchar = 'S'; + if (addrchar == 'L' && locoid <= HIGHEST_SHORT_ADDR ) + StringFormatter::send(stashStream,F("HMLong addr <= " STR(HIGHEST_SHORT_ADDR) " not supported\n")); + else { + char addcmd[20]={'M',stashThrottleChar,'+', addrchar}; + 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(); }