diff --git a/CVReader.ino b/CVReader.ino index bc0b0e1..d1c0b6e 100644 --- a/CVReader.ino +++ b/CVReader.ino @@ -97,6 +97,9 @@ void setup() { // detailed pin mappings and may also require modified subclasses of the MotorDriver to implement specialist logic. // STANDARD_MOTOR_SHIELD, POLOLU_MOTOR_SHIELD, FIREBOX_MK1, FIREBOX_MK1S are pre defined in MotorShields.h + + // Optionally a Timer number (1..4) may be passed to DCC::begin to override the default Timer1 used for the + // waveform generation. e.g. DCC::begin(STANDARD_MOTOR_SHIELD,2); to use timer 2 DCC::begin(STANDARD_MOTOR_SHIELD); diff --git a/DCC.cpp b/DCC.cpp index 3e160b1..31f9373 100644 --- a/DCC.cpp +++ b/DCC.cpp @@ -42,9 +42,9 @@ const byte FN_GROUP_4=0x08; const byte FN_GROUP_5=0x10; -void DCC::begin(MotorDriver * mainDriver, MotorDriver* progDriver) { +void DCC::begin(MotorDriver * mainDriver, MotorDriver* progDriver, byte timerNumber) { debugMode=false; - DCCWaveform::begin(mainDriver,progDriver); + DCCWaveform::begin(mainDriver,progDriver, timerNumber); } void DCC::setThrottle( uint16_t cab, uint8_t tSpeed, bool tDirection) { diff --git a/DCC.h b/DCC.h index ccc871d..195a918 100644 --- a/DCC.h +++ b/DCC.h @@ -59,7 +59,7 @@ SKIPTARGET=0xFF // jump to target class DCC { public: - static void begin(MotorDriver * mainDriver, MotorDriver * progDriver); + static void begin(MotorDriver * mainDriver, MotorDriver * progDriver, byte timerNumber=1); static void loop(); // Public DCC API functions diff --git a/DCCWaveform.cpp b/DCCWaveform.cpp index 6f38663..272eb78 100644 --- a/DCCWaveform.cpp +++ b/DCCWaveform.cpp @@ -20,27 +20,36 @@ #include "DCCWaveform.h" #include "DIAG.h" -#include "MotorDriver.h" -#include "ArduinoTimers.h" + DCCWaveform DCCWaveform::mainTrack(PREAMBLE_BITS_MAIN, true); DCCWaveform DCCWaveform::progTrack(PREAMBLE_BITS_PROG, false); bool DCCWaveform::progTrackSyncMain=false; - -void DCCWaveform::begin(MotorDriver * mainDriver, MotorDriver * progDriver) { +VirtualTimer * DCCWaveform::interruptTimer=NULL; + +void DCCWaveform::begin(MotorDriver * mainDriver, MotorDriver * progDriver, byte timerNumber) { mainTrack.motorDriver=mainDriver; progTrack.motorDriver=progDriver; mainTrack.setPowerMode(POWERMODE::OFF); - progTrack.setPowerMode(POWERMODE::OFF); - - TimerA.initialize(); - TimerA.setPeriod(58); // this is the 58uS DCC 1-bit waveform half-cycle - TimerA.attachInterrupt(interruptHandler); - TimerA.start(); - + progTrack.setPowerMode(POWERMODE::OFF); + switch (timerNumber) { + case 1: interruptTimer= &TimerA; break; + case 2: interruptTimer= &TimerB; break; +#ifndef ARDUINO_AVR_UNO + case 3: interruptTimer= &TimerC; break; + case 4: interruptTimer= &TimerD; break; +#endif + default: + DIAG(F("\n\n *** Invalid Timer number %d requested. Only 1..4 valid. DCC will not work.*** \n\n"), timerNumber); + return; + } + interruptTimer->initialize(); + interruptTimer->setPeriod(58); // this is the 58uS DCC 1-bit waveform half-cycle + interruptTimer->attachInterrupt(interruptHandler); + interruptTimer->start(); } void DCCWaveform::loop() { @@ -95,6 +104,10 @@ POWERMODE DCCWaveform::getPowerMode() { } void DCCWaveform::setPowerMode(POWERMODE mode) { + + // Prevent power switch on with no timer... Otheruise track will get full power DC and locos will run away. + if (!interruptTimer) return; + powerMode = mode; bool ison = (mode == POWERMODE::ON); motorDriver->setPower( ison); diff --git a/DCCWaveform.h b/DCCWaveform.h index 6826cfd..6537611 100644 --- a/DCCWaveform.h +++ b/DCCWaveform.h @@ -19,6 +19,7 @@ #ifndef DCCWaveform_h #define DCCWaveform_h #include "MotorDriver.h" +#include "ArduinoTimers.h" const int POWER_SAMPLE_ON_WAIT = 100; const int POWER_SAMPLE_OFF_WAIT = 1000; @@ -46,7 +47,7 @@ const byte resetPacket[] = {0x00, 0x00, 0x00}; class DCCWaveform { public: DCCWaveform( byte preambleBits, bool isMain); - static void begin(MotorDriver * mainDriver, MotorDriver * progDriver); + static void begin(MotorDriver * mainDriver, MotorDriver * progDriver, byte timerNumber); static void loop(); static DCCWaveform mainTrack; static DCCWaveform progTrack; @@ -65,7 +66,7 @@ class DCCWaveform { static bool progTrackSyncMain; // true when prog track is a siding switched to main private: - + static VirtualTimer * interruptTimer; static void interruptHandler(); bool interrupt1(); void interrupt2();