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:
parent
854ddb0c6c
commit
002ec5f176
51
DCC.cpp
51
DCC.cpp
@ -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
3
DCC.h
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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]));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user