From ffea04a499e836aab81216807968db906a350fa1 Mon Sep 17 00:00:00 2001 From: Asbelos Date: Tue, 16 Jun 2020 11:06:36 +0100 Subject: [PATCH] tIMER WRAP PROTECTION and broadcast speed fix --- DCC.cpp | 12 +++++++++--- DCC.h | 2 +- DCCWaveform.cpp | 22 +++++++++++----------- DCCWaveform.h | 3 ++- 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/DCC.cpp b/DCC.cpp index 45193b7..32c131f 100644 --- a/DCC.cpp +++ b/DCC.cpp @@ -272,8 +272,15 @@ byte DCC::cv2(int cv) { void DCC::updateLocoReminder(int loco, byte speedCode) { - // determine speed reg for this loco int reg; + + if (loco==0) { + // broadcast message + for (reg = 0; reg < MAX_LOCOS; reg++) speedTable[reg].speedCode = speedCode; + return; + } + + // determine speed reg for this loco int firstEmpty = MAX_LOCOS; for (reg = 0; reg < MAX_LOCOS; reg++) { if (speedTable[reg].loco == loco) break; @@ -299,7 +306,7 @@ int DCC::ackManagerCv; byte DCC::ackManagerBitNum; bool DCC::ackReceived; int DCC::ackTriggerMilliamps; -long DCC::ackPulseStart; +unsigned long DCC::ackPulseStart; ACK_CALLBACK DCC::ackManagerCallback; @@ -393,7 +400,6 @@ void DCC::ackManagerLoop() { if (ackPulseStart==0) return; // keep waiting for leading edge { // detected trailing edge of pulse long pulseDuration=micros()-ackPulseStart; - // TODO handle timer wrapover if (pulseDuration>4500 && pulseDuration<8000) { ackReceived=true; DCCWaveform::progTrack.killRemainingRepeats(); // probably no need after 8.5ms!! diff --git a/DCC.h b/DCC.h index e51fc49..80b45fb 100644 --- a/DCC.h +++ b/DCC.h @@ -72,7 +72,7 @@ private: static byte ackManagerStash; static bool ackReceived; static int ackTriggerMilliamps; - static long ackPulseStart; + static unsigned long ackPulseStart; static ACK_CALLBACK ackManagerCallback; static void ackManagerSetup(int cv, byte bitNumOrbyteValue, ackOp const program[], ACK_CALLBACK callback); static void ackManagerLoop(); diff --git a/DCCWaveform.cpp b/DCCWaveform.cpp index f50b285..dcfb1d5 100644 --- a/DCCWaveform.cpp +++ b/DCCWaveform.cpp @@ -55,11 +55,12 @@ DCCWaveform::DCCWaveform( byte preambleBits, bool isMain) { requiredPreambles = preambleBits; bytes_sent = 0; bits_sent = 0; - nextSampleDue = 0; - + sampleDelay = 0; + lastSampleTaken = millis(); } void DCCWaveform::beginTrack() { setPowerMode(POWERMODE::ON); + } POWERMODE DCCWaveform::getPowerMode() { @@ -74,32 +75,31 @@ void DCCWaveform::setPowerMode(POWERMODE mode) { void DCCWaveform::checkPowerOverload() { - if (millis() < nextSampleDue) return; - int delay; - + if (millis() - lastSampleTaken < sampleDelay) return; + lastSampleTaken = millis(); + switch (powerMode) { case POWERMODE::OFF: - delay = POWER_SAMPLE_OFF_WAIT; + sampleDelay = POWER_SAMPLE_OFF_WAIT; break; case POWERMODE::ON: // Check current lastCurrent = Hardware::getCurrentMilliamps(isMainTrack); - if (lastCurrent < POWER_SAMPLE_MAX) delay = POWER_SAMPLE_ON_WAIT; + if (lastCurrent < POWER_SAMPLE_MAX) sampleDelay = POWER_SAMPLE_ON_WAIT; else { setPowerMode(POWERMODE::OVERLOAD); DIAG(F("\n*** %S TRACK POWER OVERLOAD current=%d max=%d ***\n"), isMainTrack ? F("MAIN") : F("PROG"), lastCurrent, POWER_SAMPLE_MAX); - delay = POWER_SAMPLE_OVERLOAD_WAIT; + sampleDelay = POWER_SAMPLE_OVERLOAD_WAIT; } break; case POWERMODE::OVERLOAD: // Try setting it back on after the OVERLOAD_WAIT setPowerMode(POWERMODE::ON); - delay = POWER_SAMPLE_ON_WAIT; + sampleDelay = POWER_SAMPLE_ON_WAIT; break; default: - delay = 999; // cant get here..meaningless statement to avoid compiler warning. + sampleDelay = 999; // cant get here..meaningless statement to avoid compiler warning. } - nextSampleDue = millis() + delay; } diff --git a/DCCWaveform.h b/DCCWaveform.h index fe86d75..284cdf6 100644 --- a/DCCWaveform.h +++ b/DCCWaveform.h @@ -78,6 +78,7 @@ class DCCWaveform { // current sampling POWERMODE powerMode; - unsigned long nextSampleDue; + unsigned long lastSampleTaken; + int sampleDelay; }; #endif