diff --git a/DCCEXParser.cpp b/DCCEXParser.cpp index cfb7219..26e97fc 100644 --- a/DCCEXParser.cpp +++ b/DCCEXParser.cpp @@ -32,7 +32,7 @@ #include "DIAG.h" #include -// These keywords are used in the <1> command. The number is what you get if you use the keyword as a parameter. +// These keywords are used in various commands. The number is what you get if you use the keyword as a parameter. // To discover new keyword numbers , use the <$ YOURKEYWORD> command const int16_t HASH_KEYWORD_PROG = -29718; const int16_t HASH_KEYWORD_MAIN = 11339; @@ -56,6 +56,7 @@ const int16_t HASH_KEYWORD_LCN = 15137; const int16_t HASH_KEYWORD_RESET = 26133; const int16_t HASH_KEYWORD_SPEED28 = -17064; const int16_t HASH_KEYWORD_SPEED128 = 25816; +const int16_t HASH_KEYWORD_RAILCOM = 29097; int16_t DCCEXParser::stashP[MAX_COMMAND_PARAMS]; bool DCCEXParser::stashBusy; @@ -776,6 +777,9 @@ bool DCCEXParser::parseD(Print *stream, int16_t params, int16_t p[]) Diag::LCN = onOff; return true; + case HASH_KEYWORD_RAILCOM: // + return DCCWaveform::setUseRailcom(onOff); + case HASH_KEYWORD_PROGBOOST: DCC::setProgTrackBoost(true); return true; diff --git a/DCCWaveform.cpp b/DCCWaveform.cpp index 2ab014f..269202e 100644 --- a/DCCWaveform.cpp +++ b/DCCWaveform.cpp @@ -28,6 +28,8 @@ DCCWaveform DCCWaveform::mainTrack(PREAMBLE_BITS_MAIN, true); DCCWaveform DCCWaveform::progTrack(PREAMBLE_BITS_PROG, false); +bool DCCWaveform::useRailcom=false; +bool DCCWaveform::supportsRailcom=false; bool DCCWaveform::progTrackSyncMain=false; bool DCCWaveform::progTrackBoosted=false; int DCCWaveform::progTripValue=0; @@ -46,11 +48,15 @@ void DCCWaveform::begin(MotorDriver * mainDriver, MotorDriver * progDriver) { && (mainDriver->getFaultPin() != UNUSED_PIN)); // Only use PWM if both pins are PWM capable. Otherwise JOIN does not work MotorDriver::usePWM= mainDriver->isPWMCapable() && progDriver->isPWMCapable(); - MotorDriver::useRailcom= MotorDriver::usePWM && mainDriver->isRailcomCapable() && progDriver->isRailcomCapable(); + supportsRailcom= MotorDriver::usePWM && mainDriver->isRailcomCapable() && progDriver->isRailcomCapable(); + + // supportsRailcom depends on hardware caopability + // useRailcom is user switchable at run time. + useRailcom=supportsRailcom; if (MotorDriver::usePWM){ DIAG(F("Signal pin config: high accuracy waveform")); - if (MotorDriver::useRailcom) DIAG(F("Railcom Enabled")); + if (supportsRailcom) DIAG(F("Railcom cutout enabled")); } else DIAG(F("Signal pin config: normal accuracy waveform")); @@ -120,6 +126,16 @@ void DCCWaveform::setPowerMode(POWERMODE mode) { motorDriver->setPower( ison); } +bool DCCWaveform::setUseRailcom(bool on) { + if (!supportsRailcom) return false; + useRailcom=on; + if (!on) { + // turn off any existing cutout + mainTrack.motorDriver->setRailcomCutout(false); + progTrack.motorDriver->setRailcomCutout(false); + } + return true; +} void DCCWaveform::checkPowerOverload(bool ackManagerActive) { if (millis() - lastSampleTaken < sampleDelay) return; @@ -209,13 +225,20 @@ void DCCWaveform::interrupt2() { if (remainingPreambles > 0 ) { state=WAVE_MID_1; // switch state to trigger LOW on next interrupt remainingPreambles--; - // Railcom cutout - if (remainingPreambles==(requiredPreambles-2)) motorDriver->setRailcomCutout(true); - else if (remainingPreambles==(requiredPreambles-4)) motorDriver->setRailcomCutout(false); + + // Railcom cutout processing but not on prog if synced with main + if (useRailcom && (isMainTrack || !progTrackSyncMain)) do { + bool cutout; + if (remainingPreambles==(requiredPreambles-2)) cutout=true; + else if (remainingPreambles==(requiredPreambles-6)) cutout=false; + else break; + motorDriver->setRailcomCutout(cutout); + if (progTrackSyncMain) progTrack.motorDriver->setRailcomCutout(cutout); + } while(false); // this is to allow break out of do {...} above // Update free memory diagnostic as we don't have anything else to do this time. // Allow for checkAck and its called functions using 22 bytes more. - else updateMinimumFreeMemory(22); + updateMinimumFreeMemory(22); return; } diff --git a/DCCWaveform.h b/DCCWaveform.h index 29d6a29..20f6fb9 100644 --- a/DCCWaveform.h +++ b/DCCWaveform.h @@ -53,10 +53,14 @@ class DCCWaveform { static void loop(bool ackManagerActive); static DCCWaveform mainTrack; static DCCWaveform progTrack; + static bool supportsRailcom; + static bool useRailcom; void beginTrack(); void setPowerMode(POWERMODE); POWERMODE getPowerMode(); + static bool setUseRailcom(bool on); + void checkPowerOverload(bool ackManagerActive); inline int get1024Current() { if (powerMode == POWERMODE::ON) diff --git a/MotorDriver.cpp b/MotorDriver.cpp index 25a8b61..9b9f3e5 100644 --- a/MotorDriver.cpp +++ b/MotorDriver.cpp @@ -27,8 +27,6 @@ #define isLOW(fastpin) (!isHIGH(fastpin)) bool MotorDriver::usePWM=false; -bool MotorDriver::useRailcom=false; - bool MotorDriver::commonFaultPin=false; MotorDriver::MotorDriver(byte power_pin, byte signal_pin, byte signal_pin2, int8_t brake_pin, @@ -117,7 +115,7 @@ void MotorDriver::setBrake(bool on) { } void MotorDriver::setRailcomCutout(bool on) { - if (useRailcom) DCCTimer::setPWM(brakePin,on); + DCCTimer::setPWM(brakePin,on); } void MotorDriver::setSignal( bool high) { diff --git a/MotorDriver.h b/MotorDriver.h index 4723339..67a99bb 100644 --- a/MotorDriver.h +++ b/MotorDriver.h @@ -58,7 +58,6 @@ class MotorDriver { bool canMeasureCurrent(); void setRailcomCutout(bool on); static bool usePWM; - static bool useRailcom; static bool commonFaultPin; // This is a stupid motor shield which has only a common fault pin for both outputs inline byte getFaultPin() { return faultPin;