1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2025-06-15 20:15:23 +02:00

Compare commits

...

2 Commits

Author SHA1 Message Date
Asbelos
6e5668c258 5.5.23
Reminder loop idle optimisation
2025-04-29 15:24:30 +01:00
Asbelos
a623a79c6a Reminder idle reduction 2025-04-29 15:09:28 +01:00
3 changed files with 59 additions and 30 deletions

78
DCC.cpp
View File

@ -862,15 +862,34 @@ void DCC::loop() {
} }
void DCC::issueReminders() { void DCC::issueReminders() {
while(true) {
// Move to next loco slot. If occupied, send a reminder. // Move to next loco slot. If occupied, send a reminder.
auto slot = nextLocoReminder; // slot.loco is -1 for deleted locos, 0 for end of list.
if (slot >= &speedTable[MAX_LOCOS]) slot=&speedTable[0]; // Go to start of table for (auto slot=nextLocoReminder;slot->loco;slot++) {
if (slot->loco > 0) if (slot->loco<0) continue; // deleted loco, skip it
if (!issueReminder(slot)) if (issueReminder(slot)) {
return; nextLocoReminder=slot+1; // remember next one to check
// a loco=0 is at the end of the list, a loco <0 is deleted return; // reminder sent, exit
if (slot->loco==0) nextLocoReminder = &speedTable[0]; }
else nextLocoReminder=slot+1; }
// we have reached the end of the table, so we can move on to
// the next loop state and start from the top.
// There are 0-9 loop states.. speed,f1,speed,f2,speed,f3,speed,f4,speed,f5
loopStatus++;
if (loopStatus>9) loopStatus=0; // reset to 0
// try looking from the start of the table down to where we started last time
for (auto slot=&speedTable[0];slot<nextLocoReminder;slot++) {
if (slot->loco<0) continue; // deleted loco, skip it
if (issueReminder(slot)) {
nextLocoReminder=slot+1; // remember next one to check
return; // reminder sent, exit
}
}
// if we get here then we can update the loop status and start again
if (loopStatus==0) return; // nothing found at all
}
} }
int16_t normalize(byte speed) { int16_t normalize(byte speed) {
@ -891,7 +910,11 @@ bool DCC::issueReminder(LOCO * slot) {
byte flags=slot->groupFlags; byte flags=slot->groupFlags;
switch (loopStatus) { switch (loopStatus) {
case 0: { case 0:
case 2:
case 4:
case 6:
case 8: {
// calculate any momentum change going on // calculate any momentum change going on
auto sc=slot->speedCode; auto sc=slot->speedCode;
if (slot->targetSpeed!=sc) { if (slot->targetSpeed!=sc) {
@ -923,34 +946,39 @@ bool DCC::issueReminder(LOCO * slot) {
// DIAG(F("Reminder %d speed %d"),loco,slot->speedCode); // DIAG(F("Reminder %d speed %d"),loco,slot->speedCode);
setThrottle2(loco, sc); setThrottle2(loco, sc);
} }
break; return true; // reminder sent
case 1: // remind function group 1 (F0-F4) case 1: // remind function group 1 (F0-F4)
if (flags & FN_GROUP_1) if (flags & FN_GROUP_1) {
setFunctionInternal(loco,0, 128 | ((functions>>1)& 0x0F) | ((functions & 0x01)<<4)); // 100D DDDD setFunctionInternal(loco,0, 128 | ((functions>>1)& 0x0F) | ((functions & 0x01)<<4)); // 100D DDDD
return true; // reminder sent
}
break; break;
case 2: // remind function group 2 F5-F8 case 3: // remind function group 2 F5-F8
if (flags & FN_GROUP_2) if (flags & FN_GROUP_2) {
setFunctionInternal(loco,0, 176 | ((functions>>5)& 0x0F)); // 1011 DDDD setFunctionInternal(loco,0, 176 | ((functions>>5)& 0x0F)); // 1011 DDDD
return true; // reminder sent
}
break; break;
case 3: // remind function group 3 F9-F12 case 5: // remind function group 3 F9-F12
if (flags & FN_GROUP_3) if (flags & FN_GROUP_3) {
setFunctionInternal(loco,0, 160 | ((functions>>9)& 0x0F)); // 1010 DDDD setFunctionInternal(loco,0, 160 | ((functions>>9)& 0x0F)); // 1010 DDDD
return true; // reminder sent
}
break; break;
case 4: // remind function group 4 F13-F20 case 7: // remind function group 4 F13-F20
if (flags & FN_GROUP_4) if (flags & FN_GROUP_4) {
setFunctionInternal(loco,222, ((functions>>13)& 0xFF)); setFunctionInternal(loco,222, ((functions>>13)& 0xFF));
return true;
}
break; break;
case 5: // remind function group 5 F21-F28 case 9: // remind function group 5 F21-F28
if (flags & FN_GROUP_5) if (flags & FN_GROUP_5) {
setFunctionInternal(loco,223, ((functions>>21)& 0xFF)); setFunctionInternal(loco,223, ((functions>>21)& 0xFF));
return true; // reminder sent
}
break; break;
} }
loopStatus++; return false; // no reminder sent
// if we reach status 6 then this loco is done so
// reset status to 0 for next loco and return true so caller
// moves on to next loco.
if (loopStatus>5) loopStatus=0;
return loopStatus==0;
} }

View File

@ -159,7 +159,7 @@ void DCCWaveform::interrupt2() {
// As we get to the end of the preambles, open the reminder window. // As we get to the end of the preambles, open the reminder window.
// This delays any reminder insertion until the last moment so // This delays any reminder insertion until the last moment so
// that the reminder doesn't block a more urgent packet. // that the reminder doesn't block a more urgent packet.
reminderWindowOpen=transmitRepeats==0 && remainingPreambles<10 && remainingPreambles>1; reminderWindowOpen=transmitRepeats==0 && remainingPreambles<12 && remainingPreambles>1;
if (remainingPreambles==1) if (remainingPreambles==1)
promotePendingPacket(); promotePendingPacket();

View File

@ -3,7 +3,8 @@
#include "StringFormatter.h" #include "StringFormatter.h"
#define VERSION "5.5.22" #define VERSION "5.5.23"
// 5.5.23 - Reminder loop Idle packet optimization
// 5.5.22 - (5.4.9) Handle non-compliant decoders returning 255 for cv 20 and confusing <R> with bad consist addresses. // 5.5.22 - (5.4.9) Handle non-compliant decoders returning 255 for cv 20 and confusing <R> with bad consist addresses.
// - DCC 5mS gap to same loco DCC packet restriction // - DCC 5mS gap to same loco DCC packet restriction
// - Catch up MASTER for ESP32 IDF version check // - Catch up MASTER for ESP32 IDF version check