From a245b9d119d2188c6daaa918fa5569b2a84f6510 Mon Sep 17 00:00:00 2001 From: Asbelos Date: Sun, 12 Jul 2020 00:11:30 +0100 Subject: [PATCH] Prog-Track-As-Siding --- DCC.cpp | 4 +++- DCC.h | 1 + DCCWaveform.cpp | 26 +++++++++++++++++++------- DCCWaveform.h | 4 +++- 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/DCC.cpp b/DCC.cpp index e5e9638..97564be 100644 --- a/DCC.cpp +++ b/DCC.cpp @@ -157,7 +157,9 @@ void DCC::writeCVBitMain(int cab, int cv, byte bNum, bool bValue) { DCCWaveform::mainTrack.schedulePacket(b, nB, 4); } - +void DCC::setProgTrackSyncMain(bool on) { + DCCWaveform::progTrackSyncMain=on; +} const ackOp PROGMEM WRITE_BIT0_PROG[] = { BASELINE, diff --git a/DCC.h b/DCC.h index f825e3d..4111263 100644 --- a/DCC.h +++ b/DCC.h @@ -63,6 +63,7 @@ class DCC { static void setAccessory(int aAdd, byte aNum, bool activate) ; static bool writeTextPacket( byte *b, int nBytes); static void setDebug(bool on); + static void setProgTrackSyncMain(bool on); // when true, prog track becomes driveable // ACKable progtrack calls bitresults callback 0,0 or -1, cv returns value or -1 static void readCV(int cv, ACK_CALLBACK callback); diff --git a/DCCWaveform.cpp b/DCCWaveform.cpp index 8c14c43..e6ee023 100644 --- a/DCCWaveform.cpp +++ b/DCCWaveform.cpp @@ -26,7 +26,7 @@ DCCWaveform DCCWaveform::progTrack(PREAMBLE_BITS_PROG, false, (int)(PROG_MAX_MI const int ACK_MIN_PULSE_RAW=65 / PROG_SENSE_FACTOR; - +bool DCCWaveform::progTrackSyncMain=false; void DCCWaveform::begin() { Hardware::init(); @@ -102,6 +102,8 @@ void DCCWaveform::checkPowerOverload() { if (millis() - lastSampleTaken < sampleDelay) return; lastSampleTaken = millis(); + int tripValue= rawCurrentTripValue; + if (!isMainTrack && (ackPending || progTrackSyncMain)) tripValue=ACK_CURRENT_TRIP; switch (powerMode) { case POWERMODE::OFF: @@ -110,11 +112,11 @@ void DCCWaveform::checkPowerOverload() { case POWERMODE::ON: // Check current lastCurrent = Hardware::getCurrentRaw(isMainTrack); - if (lastCurrent <= (ackPending?ACK_CURRENT_TRIP:rawCurrentTripValue)) sampleDelay = POWER_SAMPLE_ON_WAIT; + if (lastCurrent <= tripValue) sampleDelay = POWER_SAMPLE_ON_WAIT; else { setPowerMode(POWERMODE::OVERLOAD); unsigned int mA=Hardware::getCurrentMilliamps(isMainTrack,lastCurrent); - unsigned int maxmA=Hardware::getCurrentMilliamps(isMainTrack,ackPending?ACK_CURRENT_TRIP:rawCurrentTripValue); + unsigned int maxmA=Hardware::getCurrentMilliamps(isMainTrack,tripValue); DIAG(F("\n*** %S TRACK POWER OVERLOAD current=%d max=%d ***\n"), isMainTrack ? F("MAIN") : F("PROG"), mA, maxmA); sampleDelay = POWER_SAMPLE_OVERLOAD_WAIT; } @@ -140,19 +142,19 @@ bool DCCWaveform::interrupt1() { // otherwise can cause hangs in main loop waiting for the pendingBuffer. switch (state) { case 0: // start of bit transmission - Hardware::setSignal(isMainTrack, HIGH); + setSignal(HIGH); state = 1; return true; // must call interrupt2 to set currentBit case 1: // 58us after case 0 if (currentBit) { - Hardware::setSignal(isMainTrack, LOW); + setSignal(LOW); state = 0; } else state = 2; break; case 2: // 116us after case 0 - Hardware::setSignal(isMainTrack, LOW); + setSignal(LOW); state = 3; break; case 3: // finished sending zero bit @@ -168,7 +170,17 @@ bool DCCWaveform::interrupt1() { } - +void DCCWaveform::setSignal(bool high) { + if (progTrackSyncMain) { + if (!isMainTrack) return; // ignore PROG track waveform while in sync + // set both tracks to same signal + Hardware::setSignal(true, high); + Hardware::setSignal(false, high); + return; + } + Hardware::setSignal(isMainTrack,high); +} + void DCCWaveform::interrupt2() { // set currentBit to be the next bit to be sent. diff --git a/DCCWaveform.h b/DCCWaveform.h index af562b0..3fc8015 100644 --- a/DCCWaveform.h +++ b/DCCWaveform.h @@ -62,13 +62,15 @@ class DCCWaveform { void setAckBaseline(bool debug); //prog track only void setAckPending(bool debug); //prog track only byte getAck(bool debug); //prog track only 0=NACK, 1=ACK 2=keep waiting - + static bool progTrackSyncMain; // true when prog track is a siding switched to main + private: static void interruptHandler(); bool interrupt1(); void interrupt2(); void checkAck(); + void setSignal(bool high); bool isMainTrack;