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

Cleaning access to speedByte

This commit is contained in:
Asbelos 2024-07-22 12:42:43 +01:00
parent 854ddb0c6c
commit 002ec5f176
6 changed files with 35 additions and 27 deletions

51
DCC.cpp
View File

@ -75,6 +75,10 @@ void DCC::begin() {
int16_t DCC::defaultMomentum=0;
void DCC::setThrottle( uint16_t cab, uint8_t tSpeed, bool tDirection) {
if (cab==0) {
if (tSpeed==1) estopAll(); // ESTOP broadcast fix
return;
}
byte speedCode = (tSpeed & 0x7F) + tDirection * 128;
int reg=lookupSpeedTable(cab);
if (reg<0 || speedTable[reg].targetSpeed==speedCode) return;
@ -89,7 +93,6 @@ void DCC::setThrottle( uint16_t cab, uint8_t tSpeed, bool tDirection) {
speedTable[reg].speedCode = speedCode;
setThrottle2(cab, speedCode);
TrackManager::setDCSignal(cab,speedCode); // in case this is a dcc track on this addr
if ((speedCode & 0x7f)==1) updateLocoReminder(cab,speedCode); // ESTOP broadcast fix
}
CommandDistributor::broadcastLoco(reg);
}
@ -152,14 +155,22 @@ void DCC::setFunctionInternal(int cab, byte byte1, byte byte2, byte count) {
// returns speed steps 0 to 127 (1 == emergency stop)
// or -1 on "loco not found"
int8_t DCC::getThrottleSpeed(int cab) {
int reg=lookupSpeedTable(cab);
if (reg<0) return -1;
return speedTable[reg].speedCode & 0x7F;
return getThrottleSpeedByte(cab) & 0x7F;
}
// returns speed code byte
// or 128 (speed 0, dir forward) on "loco not found".
// This is the throttle set speed
uint8_t DCC::getThrottleSpeedByte(int cab) {
int reg=lookupSpeedTable(cab);
if (reg<0)
return 128;
return speedTable[reg].targetSpeed;
}
// returns speed code byte for loco.
// This is the most recently send DCC speed packet byte
// or 128 (speed 0, dir forward) on "loco not found".
uint8_t DCC::getLocoSpeedByte(int cab) {
int reg=lookupSpeedTable(cab);
if (reg<0)
return 128;
@ -185,9 +196,7 @@ uint8_t DCC::getThrottleFrequency(int cab) {
// returns direction on loco
// or true/forward on "loco not found"
bool DCC::getThrottleDirection(int cab) {
int reg=lookupSpeedTable(cab);
if (reg<0) return true;
return (speedTable[reg].speedCode & 0x80) !=0;
return getThrottleSpeedByte(cab) % 0x80;
}
// Set function to value on or off
@ -754,7 +763,6 @@ void DCC::forgetLoco(int cab) { // removes any speed reminders for this loco
int reg=lookupSpeedTable(cab, false);
if (reg>=0) {
speedTable[reg].loco=0;
setThrottle2(cab,1); // ESTOP if this loco still on track
CommandDistributor::broadcastForgetLoco(cab);
}
}
@ -808,7 +816,7 @@ bool DCC::issueReminder(int reg) {
case 0: {
// calculate any momentum change going on
auto sc=speedTable[reg].speedCode;
if (speedTable[reg].targetSpeed!=speedTable[reg].speedCode) {
if (speedTable[reg].targetSpeed!=sc) {
// calculate new speed code
auto now=millis();
int16_t delay=now-speedTable[reg].momentum_base;
@ -942,22 +950,21 @@ bool DCC::setMomentum(int locoId,int16_t millis_per_notch) {
return true;
}
void DCC::updateLocoReminder(int loco, byte speedCode) {
if (loco==0) {
// broadcast stop/estop but dont change direction
for (int reg = 0; reg <= highestUsedReg; reg++) {
if (speedTable[reg].loco==0) continue;
byte newspeed=(speedTable[reg].speedCode & 0x80) | (speedCode & 0x7f);
if (speedTable[reg].speedCode != newspeed) {
speedTable[reg].speedCode = newspeed;
speedTable[reg].targetSpeed = newspeed;
CommandDistributor::broadcastLoco(reg);
}
}
void DCC::estopAll() {
setThrottle2(0,1); // estop all locos
TrackManager::setDCSignal(0,1);
// remind stop/estop but dont change direction
for (int reg = 0; reg <= highestUsedReg; reg++) {
if (speedTable[reg].loco==0) continue;
byte newspeed=(speedTable[reg].speedCode & 0x80) | 0x01;
speedTable[reg].speedCode = newspeed;
speedTable[reg].targetSpeed = newspeed;
CommandDistributor::broadcastLoco(reg);
}
}
DCC::LOCO DCC::speedTable[MAX_LOCOS];
int DCC::lastLocoReminder = 0;
int DCC::highestUsedReg = 0;

3
DCC.h
View File

@ -59,8 +59,10 @@ public:
// Public DCC API functions
static void setThrottle(uint16_t cab, uint8_t tSpeed, bool tDirection);
static void estopAll();
static int8_t getThrottleSpeed(int cab);
static uint8_t getThrottleSpeedByte(int cab);
static uint8_t getLocoSpeedByte(int cab); // may lag throttle
static uint8_t getThrottleFrequency(int cab);
static bool getThrottleDirection(int cab);
static void writeCVByteMain(int cab, int cv, byte bValue);
@ -117,7 +119,6 @@ private:
static byte loopStatus;
static int16_t defaultMomentum; // Millis per speed step
static void setThrottle2(uint16_t cab, uint8_t speedCode);
static void updateLocoReminder(int loco, byte speedCode);
static void setFunctionInternal(int cab, byte fByte, byte eByte, byte count);
static bool issueReminder(int reg);
static int lastLocoReminder;

View File

@ -586,7 +586,7 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream)
}
case '!': // ESTOP ALL <!>
DCC::setThrottle(0,1,1); // this broadcasts speed 1(estop) and sets all reminders to speed 1.
DCC::estopAll(); // this broadcasts speed 1(estop) and sets all reminders to speed 1.
return;
#ifdef HAS_ENOUGH_MEMORY

View File

@ -683,7 +683,7 @@ void RMFT2::loop2() {
break;
case OPCODE_PAUSE:
DCC::setThrottle(0,1,true); // pause all locos on the track
DCC::estopAll(); // pause all locos on the track
pausingTask=this;
break;

View File

@ -276,7 +276,7 @@ bool RMFT2::parseSlash(Print * stream, byte & paramCount, int16_t p[]) {
switch (p[0]) {
case "PAUSE"_hk: // </ PAUSE>
if (paramCount!=1) return false;
DCC::setThrottle(0,1,true); // pause all locos on the track
DCC::estopAll(); // pause all locos on the track
pausingTask=(RMFT2 *)1; // Impossible task address
return true;

View File

@ -358,7 +358,7 @@ bool TrackManager::setTrackMode(byte trackToSet, TRACK_MODE mode, int16_t dcAddr
}
void TrackManager::applyDCSpeed(byte t) {
track[t]->setDCSignal(DCC::getThrottleSpeedByte(trackDCAddr[t]),
track[t]->setDCSignal(DCC::getLocoSpeedByte(trackDCAddr[t]),
DCC::getThrottleFrequency(trackDCAddr[t]));
}