diff --git a/DCCTimer.h b/DCCTimer.h index fb8184b..4ad507c 100644 --- a/DCCTimer.h +++ b/DCCTimer.h @@ -60,7 +60,7 @@ class DCCTimer { static void getSimulatedMacAddress(byte mac[6]); static bool isPWMPin(byte pin); static void setPWM(byte pin, bool high); - + static void clearPWM(); // Update low ram level. Allow for extra bytes to be specified // by estimation or inspection, that may be used by other // called subroutines. Must be called with interrupts disabled. diff --git a/DCCTimerAVR.cpp b/DCCTimerAVR.cpp index ff0143b..b6a5161 100644 --- a/DCCTimerAVR.cpp +++ b/DCCTimerAVR.cpp @@ -83,6 +83,10 @@ void DCCTimer::begin(INTERRUPT_CALLBACK callback) { #endif } +void DCCTimer::clearPWM() { + TCCR1A= 0; +} + void DCCTimer::getSimulatedMacAddress(byte mac[6]) { for (byte i=0; i<6; i++) { mac[i]=boot_signature_byte_get(0x0E + i); diff --git a/DCCTimerESP.cpp b/DCCTimerESP.cpp index d4b4a2b..d80b0fe 100644 --- a/DCCTimerESP.cpp +++ b/DCCTimerESP.cpp @@ -47,6 +47,8 @@ bool IRAM_ATTR DCCTimer::isPWMPin(byte pin) { } void IRAM_ATTR DCCTimer::setPWM(byte pin, bool high) { } +void IRAM_ATTR DCCTimer::clearPWM() { +} // Fake this as it should not be used void DCCTimer::getSimulatedMacAddress(byte mac[6]) { diff --git a/DCCTimerMEGAAVR.cpp b/DCCTimerMEGAAVR.cpp index 8b43340..521e7f7 100644 --- a/DCCTimerMEGAAVR.cpp +++ b/DCCTimerMEGAAVR.cpp @@ -90,6 +90,10 @@ extern char *__malloc_heap_start; // TODO what are the relevant pins? } +void DCCTimer::clearPWM() { + // Do nothing unless we implent HA +} + void DCCTimer::getSimulatedMacAddress(byte mac[6]) { memcpy(mac,(void *) &SIGROW.SERNUM0,6); // serial number mac[0] &= 0xFE; diff --git a/DCCTimerTEENSY.cpp b/DCCTimerTEENSY.cpp index 99b147a..a75fe3a 100644 --- a/DCCTimerTEENSY.cpp +++ b/DCCTimerTEENSY.cpp @@ -50,6 +50,10 @@ void DCCTimer::setPWM(byte pin, bool high) { (void) high; } +void DCCTimer::clearPWM() { + // Do nothing unless we implent HA +} + #if defined(__IMXRT1062__) //Teensy 4.0 and Teensy 4.1 void DCCTimer::getSimulatedMacAddress(byte mac[6]) { uint32_t m1 = HW_OCOTP_MAC1; @@ -119,4 +123,4 @@ static inline int freeMemory() { } #endif -#endif \ No newline at end of file +#endif diff --git a/MotorDriver.cpp b/MotorDriver.cpp index b26161e..92d8c88 100644 --- a/MotorDriver.cpp +++ b/MotorDriver.cpp @@ -25,11 +25,6 @@ #include "DCCTimer.h" #include "DIAG.h" -#define setHIGH(fastpin) *fastpin.inout |= fastpin.maskHIGH -#define setLOW(fastpin) *fastpin.inout &= fastpin.maskLOW -#define isHIGH(fastpin) (*fastpin.inout & fastpin.maskHIGH) -#define isLOW(fastpin) (!isHIGH(fastpin)) - bool MotorDriver::usePWM=false; bool MotorDriver::commonFaultPin=false; @@ -119,23 +114,6 @@ void MotorDriver::setBrake(bool on) { else setLOW(fastBrakePin); } -void MotorDriver::setSignal( bool high) { - if (usePWM) { - DCCTimer::setPWM(signalPin,high); - } - else { - if (high) { - setHIGH(fastSignalPin); - if (dualSignal) setLOW(fastSignalPin2); - } - else { - setLOW(fastSignalPin); - if (dualSignal) setHIGH(fastSignalPin2); - } - } -} - - bool MotorDriver::canMeasureCurrent() { return currentPin!=UNUSED_PIN; } diff --git a/MotorDriver.h b/MotorDriver.h index d0dd999..61ddf5c 100644 --- a/MotorDriver.h +++ b/MotorDriver.h @@ -23,6 +23,12 @@ #define MotorDriver_h #include "FSH.h" #include "IODevice.h" +#include "DCCTimer.h" + +#define setHIGH(fastpin) *fastpin.inout |= fastpin.maskHIGH +#define setLOW(fastpin) *fastpin.inout &= fastpin.maskLOW +#define isHIGH(fastpin) (*fastpin.inout & fastpin.maskHIGH) +#define isLOW(fastpin) (!isHIGH(fastpin)) // Virtualised Motor shield 1-track hardware Interface @@ -53,7 +59,21 @@ class MotorDriver { byte current_pin, float senseFactor, unsigned int tripMilliamps, byte faultPin); virtual void setPower( POWERMODE mode); virtual POWERMODE getPower() { return powerMode;} - virtual void setSignal( bool high); + __attribute__((always_inline)) inline void setSignal( bool high) { + if (usePWM) { + DCCTimer::setPWM(signalPin,high); + } + else { + if (high) { + setHIGH(fastSignalPin); + if (dualSignal) setLOW(fastSignalPin2); + } + else { + setLOW(fastSignalPin); + if (dualSignal) setHIGH(fastSignalPin2); + } + } + }; virtual void setBrake( bool on); virtual void setDCSignal(byte speedByte); virtual int getCurrentRaw(); diff --git a/TrackManager.cpp b/TrackManager.cpp index 58f10f7..74b3a7d 100644 --- a/TrackManager.cpp +++ b/TrackManager.cpp @@ -22,6 +22,7 @@ #include "DCCWaveform.h" #include "DCC.h" #include "MotorDriver.h" +#include "DCCTimer.h" #include "DIAG.h" // Virtualised Motor shield multi-track hardware Interface #define FOR_EACH_TRACK(t) for (byte t=0;t<=lastTrack;t++) @@ -110,6 +111,7 @@ void TrackManager::setDCSignal(int16_t cab, byte speedbyte) { bool TrackManager::setTrackMode(byte trackToSet, TRACK_MODE mode, int16_t dcAddr) { if (trackToSet>lastTrack || track[trackToSet]==NULL) return false; + //DIAG(F("Track=%c"),trackToSet+'A'); // DC tracks require a motorDriver that can set brake! if ((mode==TRACK_MODE_DC || mode==TRACK_MODE_DCX) && !track[trackToSet]->canBrake()) { @@ -120,7 +122,7 @@ bool TrackManager::setTrackMode(byte trackToSet, TRACK_MODE mode, int16_t dcAddr if (mode==TRACK_MODE_PROG) { // only allow 1 track to be prog FOR_EACH_TRACK(t) - if (trackMode[t]==TRACK_MODE_PROG) { + if (trackMode[t]==TRACK_MODE_PROG && t != trackToSet) { track[t]->setPower(POWERMODE::OFF); trackMode[t]=TRACK_MODE_OFF; } @@ -150,6 +152,10 @@ bool TrackManager::setTrackMode(byte trackToSet, TRACK_MODE mode, int16_t dcAddr FOR_EACH_TRACK(t) if (trackMode[t]==TRACK_MODE_MAIN ||trackMode[t]==TRACK_MODE_PROG) canDo &= track[t]->isPWMCapable(); + //DIAG(F("HAMode=%d"),canDo); + if (!canDo) { + DCCTimer::clearPWM(); + } MotorDriver::usePWM=canDo; @@ -157,7 +163,7 @@ bool TrackManager::setTrackMode(byte trackToSet, TRACK_MODE mode, int16_t dcAddr track[trackToSet]->setPower( (mode==TRACK_MODE_MAIN || mode==TRACK_MODE_DC || mode==TRACK_MODE_DCX) ? mainPowerGuess : POWERMODE::OFF); - + //DIAG(F("TrackMode=%d"),mode); return true; }