1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-11-30 03:26:13 +01:00

Performance improvements in function DCC::issueReminders

Function issueReminders was taking around 1700us to complete.  It has been refactored to optimise calculations and reduce the amount of the loco table that needs to be scanned each time.  It now takes typically under 50us to execute.
This commit is contained in:
Neil McKechnie 2022-11-22 17:24:11 +00:00
parent 70203c3733
commit 644cb29a3a
2 changed files with 19 additions and 28 deletions

44
DCC.cpp
View File

@ -589,36 +589,24 @@ byte DCC::loopStatus=0;
void DCC::loop() { void DCC::loop() {
TrackManager::loop(); // power overload checks TrackManager::loop(); // power overload checks
bitSet(DDRE, 4);
bitSet(PORTE, 4);
issueReminders(); issueReminders();
bitClear(PORTE, 4);
} }
void DCC::issueReminders() { void DCC::issueReminders() {
// if the main track transmitter still has a pending packet, skip this time around. // if the main track transmitter still has a pending packet, skip this time around.
if ( DCCWaveform::mainTrack.getPacketPending()) return; if ( DCCWaveform::mainTrack.getPacketPending()) return;
// Move to next loco slot. If occupied, send a reminder.
// This loop searches for a loco in the speed table starting at nextLoco and cycling back around int reg = lastLocoReminder+1;
/* if (reg > highestUsedReg) reg = 0; // Go to start of table
for (int reg=0;reg<MAX_LOCOS;reg++) { if (speedTable[reg].loco > 0) {
int slot=reg+nextLoco; // have found loco to remind
if (slot>=MAX_LOCOS) slot-=MAX_LOCOS; if (issueReminder(reg))
if (speedTable[slot].loco > 0) { lastLocoReminder = reg;
// have found the next loco to remind } else
// issueReminder will return true if this loco is completed (ie speed and functions) lastLocoReminder = reg;
if (issueReminder(slot)) nextLoco=slot+1;
return;
}
}
*/
for (int reg=nextLoco;reg<MAX_LOCOS+nextLoco;reg++) {
int slot=reg%MAX_LOCOS;
if (speedTable[slot].loco > 0) {
// have found the next loco to remind
// issueReminder will return true if this loco is completed (ie speed and functions)
if (issueReminder(slot))
nextLoco=(slot+1)%MAX_LOCOS;
return;
}
}
} }
bool DCC::issueReminder(int reg) { bool DCC::issueReminder(int reg) {
@ -698,6 +686,7 @@ int DCC::lookupSpeedTable(int locoId, bool autoCreate) {
speedTable[reg].groupFlags=0; speedTable[reg].groupFlags=0;
speedTable[reg].functions=0; speedTable[reg].functions=0;
} }
if (reg > highestUsedReg) highestUsedReg = reg;
return reg; return reg;
} }
@ -705,7 +694,7 @@ void DCC::updateLocoReminder(int loco, byte speedCode) {
if (loco==0) { if (loco==0) {
// broadcast stop/estop but dont change direction // broadcast stop/estop but dont change direction
for (int reg = 0; reg < MAX_LOCOS; reg++) { for (int reg = 0; reg < highestUsedReg; reg++) {
if (speedTable[reg].loco==0) continue; if (speedTable[reg].loco==0) continue;
byte newspeed=(speedTable[reg].speedCode & 0x80) | (speedCode & 0x7f); byte newspeed=(speedTable[reg].speedCode & 0x80) | (speedCode & 0x7f);
if (speedTable[reg].speedCode != newspeed) { if (speedTable[reg].speedCode != newspeed) {
@ -725,13 +714,14 @@ void DCC::updateLocoReminder(int loco, byte speedCode) {
} }
DCC::LOCO DCC::speedTable[MAX_LOCOS]; DCC::LOCO DCC::speedTable[MAX_LOCOS];
int DCC::nextLoco = 0; int DCC::lastLocoReminder = 0;
int DCC::highestUsedReg = 0;
void DCC::displayCabList(Print * stream) { void DCC::displayCabList(Print * stream) {
int used=0; int used=0;
for (int reg = 0; reg < MAX_LOCOS; reg++) { for (int reg = 0; reg <= highestUsedReg; reg++) {
if (speedTable[reg].loco>0) { if (speedTable[reg].loco>0) {
used ++; used ++;
StringFormatter::send(stream,F("cab=%d, speed=%d, dir=%c \n"), StringFormatter::send(stream,F("cab=%d, speed=%d, dir=%c \n"),

3
DCC.h
View File

@ -108,7 +108,8 @@ private:
static void updateLocoReminder(int loco, byte speedCode); static void updateLocoReminder(int loco, byte speedCode);
static void setFunctionInternal(int cab, byte fByte, byte eByte); static void setFunctionInternal(int cab, byte fByte, byte eByte);
static bool issueReminder(int reg); static bool issueReminder(int reg);
static int nextLoco; static int lastLocoReminder;
static int highestUsedReg;
static FSH *shieldName; static FSH *shieldName;
static byte globalSpeedsteps; static byte globalSpeedsteps;