diff --git a/DCCEXParser.cpp b/DCCEXParser.cpp index 3f61f7b..5b335d2 100644 --- a/DCCEXParser.cpp +++ b/DCCEXParser.cpp @@ -1036,10 +1036,27 @@ bool DCCEXParser::parseC(Print *stream, int16_t params, int16_t p[]) { DIAG(F("128 Speedsteps")); return true; case "RAILCOM"_hk: - { - bool onOff = (params > 1) && (p[1] == 1 || p[1] == "ON"_hk); // dont care if other stuff or missing... just means off + { // + if (params<2) return false; + bool on=false; + bool debug=false; + switch (p[1]) { + case "ON"_hk: + case 1: + on=true; + break; + case "DEBUG"_hk: + on=true; + debug=true; + break; + case "OFF"_hk: + case 0: + break; + default: + return false; + } DIAG(F("Railcom %S") - ,DCCWaveform::setRailcom(onOff)?F("ON"):F("OFF")); + ,DCCWaveform::setRailcom(on,debug)?F("ON"):F("OFF")); return true; } #ifndef DISABLE_PROG diff --git a/DCCTimerMEGAAVR.cpp b/DCCTimerMEGAAVR.cpp index 2b2bdab..19eb409 100644 --- a/DCCTimerMEGAAVR.cpp +++ b/DCCTimerMEGAAVR.cpp @@ -80,6 +80,14 @@ extern char *__malloc_heap_start; interruptHandler(); } +void DCCTimer::startRailcomTimer(byte brakePin) { + // TODO: for intended operation see DCCTimerAVR.cpp +} + +void DCCTimer::ackRailcomTimer() { + // TODO: for intended operation see DCCTimerAVR.cpp +} + bool DCCTimer::isPWMPin(byte pin) { (void) pin; return false; // TODO what are the relevant pins? diff --git a/DCCTimerSAMD.cpp b/DCCTimerSAMD.cpp index f878ae5..a0b4da5 100644 --- a/DCCTimerSAMD.cpp +++ b/DCCTimerSAMD.cpp @@ -76,6 +76,14 @@ void DCCTimer::begin(INTERRUPT_CALLBACK callback) { interrupts(); } +void DCCTimer::startRailcomTimer(byte brakePin) { + // TODO: for intended operation see DCCTimerAVR.cpp +} + +void DCCTimer::ackRailcomTimer() { + // TODO: for intended operation see DCCTimerAVR.cpp +} + // Timer IRQ handlers replace the dummy handlers (in cortex_handlers) // copied from rf24 branch void TCC0_Handler() { diff --git a/DCCTimerSTM32.cpp b/DCCTimerSTM32.cpp index f24adc2..eb7e1ca 100644 --- a/DCCTimerSTM32.cpp +++ b/DCCTimerSTM32.cpp @@ -201,6 +201,14 @@ void DCCTimer::begin(INTERRUPT_CALLBACK callback) { interrupts(); } +void DCCTimer::startRailcomTimer(byte brakePin) { + // TODO: for intended operation see DCCTimerAVR.cpp +} + +void DCCTimer::ackRailcomTimer() { + // TODO: for intended operation see DCCTimerAVR.cpp +} + bool DCCTimer::isPWMPin(byte pin) { //TODO: STM32 whilst this call to digitalPinHasPWM will reveal which pins can do PWM, // there's no support yet for High Accuracy, so for now return false diff --git a/DCCTimerTEENSY.cpp b/DCCTimerTEENSY.cpp index 0619e21..1230180 100644 --- a/DCCTimerTEENSY.cpp +++ b/DCCTimerTEENSY.cpp @@ -39,6 +39,14 @@ void DCCTimer::begin(INTERRUPT_CALLBACK callback) { myDCCTimer.begin(interruptHandler, DCC_SIGNAL_TIME); } +void DCCTimer::startRailcomTimer(byte brakePin) { + // TODO: for intended operation see DCCTimerAVR.cpp +} + +void DCCTimer::ackRailcomTimer() { + // TODO: for intended operation see DCCTimerAVR.cpp +} + bool DCCTimer::isPWMPin(byte pin) { //Teensy: digitalPinHasPWM, todo (void) pin; diff --git a/DCCWaveform.cpp b/DCCWaveform.cpp index 707f8f4..2d50929 100644 --- a/DCCWaveform.cpp +++ b/DCCWaveform.cpp @@ -117,14 +117,17 @@ DCCWaveform::DCCWaveform( byte preambleBits, bool isMain) { } volatile bool DCCWaveform::railcomActive=false; // switched on by user +volatile bool DCCWaveform::railcomDebug=false; // switched on by user -bool DCCWaveform::setRailcom(bool on) { +bool DCCWaveform::setRailcom(bool on, bool debug) { if (on) { // TODO check possible railcomActive=true; + railcomDebug=debug; } else { railcomActive=false; + railcomDebug=false; } return railcomActive; } @@ -225,9 +228,11 @@ void DCCWaveform::promotePendingPacket() { // nothing to do, just send idles or resets // Fortunately reset and idle packets are the same length - // TEMPORARY DEBUG FOR RAILCOM - // memcpy( transmitPacket, isMainTrack ? idlePacket : resetPacket, sizeof(idlePacket)); - memcpy( transmitPacket, resetPacket, sizeof(idlePacket)); + // Note: If railcomDebug is on, then we send resets to the main + // track instead of idles. This means that all data will be zeros + // and only the porersets will be ones, making it much + // easier to read on a logic analyser. + memcpy( transmitPacket, (isMainTrack && (!railcomDebug)) ? idlePacket : resetPacket, sizeof(idlePacket)); transmitLength = sizeof(idlePacket); transmitRepeats = 0; if (getResets() < 250) sentResetsSincePacket++; // only place to increment (private!) @@ -316,4 +321,10 @@ bool DCCWaveform::isReminderWindowOpen() { void IRAM_ATTR DCCWaveform::loop() { DCCACK::checkAck(progTrack.getResets()); } + +bool DCCWaveform::setRailcom(bool on, bool debug) { + // TODO... ESP32 railcom waveform + return false; +} + #endif diff --git a/DCCWaveform.h b/DCCWaveform.h index 3f6de18..a3e20da 100644 --- a/DCCWaveform.h +++ b/DCCWaveform.h @@ -85,7 +85,7 @@ class DCCWaveform { void schedulePacket(const byte buffer[], byte byteCount, byte repeats); bool isReminderWindowOpen(); void promotePendingPacket(); - static bool setRailcom(bool on); + static bool setRailcom(bool on, bool debug); static bool isRailcom() {return railcomActive;} private: @@ -113,6 +113,7 @@ class DCCWaveform { byte pendingLength; byte pendingRepeats; static volatile bool railcomActive; // switched on by user + static volatile bool railcomDebug; // switched on by user #ifdef ARDUINO_ARCH_ESP32 static RMTChannel *rmtMainChannel;