1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-12-23 21:01:25 +01:00

better long/short addr handling under <R>; configurable long/short border

This commit is contained in:
Harald Barth 2021-11-25 00:10:11 +01:00
parent f05b3d1730
commit 3bddeeda3e
5 changed files with 53 additions and 11 deletions

14
DCC.cpp
View File

@ -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:

10
DCC.h
View File

@ -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

View File

@ -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("<r ERROR>\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("<r %d>\n"), result);
else
StringFormatter::send(getAsyncReplyStream(), F("<r LONG %d UNSUPPORTED>\n"), result);
} else // short addr
StringFormatter::send(getAsyncReplyStream(), F("<r %d>\n"), result);
commitAsyncReplyStream();
commitAsyncReplyStream();
}
void DCCEXParser::callback_Wloco(int16_t result)

View File

@ -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);

View File

@ -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