1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-12-23 21:01:25 +01:00

Optional Timer number override

This commit is contained in:
Asbelos 2020-08-28 12:34:58 +01:00
parent 6939c4c2e3
commit 31651d3e44
5 changed files with 33 additions and 16 deletions

View File

@ -97,6 +97,9 @@ void setup() {
// detailed pin mappings and may also require modified subclasses of the MotorDriver to implement specialist logic. // 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 // 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); DCC::begin(STANDARD_MOTOR_SHIELD);

View File

@ -42,9 +42,9 @@ const byte FN_GROUP_4=0x08;
const byte FN_GROUP_5=0x10; const byte FN_GROUP_5=0x10;
void DCC::begin(MotorDriver * mainDriver, MotorDriver* progDriver) { void DCC::begin(MotorDriver * mainDriver, MotorDriver* progDriver, byte timerNumber) {
debugMode=false; debugMode=false;
DCCWaveform::begin(mainDriver,progDriver); DCCWaveform::begin(mainDriver,progDriver, timerNumber);
} }
void DCC::setThrottle( uint16_t cab, uint8_t tSpeed, bool tDirection) { void DCC::setThrottle( uint16_t cab, uint8_t tSpeed, bool tDirection) {

2
DCC.h
View File

@ -59,7 +59,7 @@ SKIPTARGET=0xFF // jump to target
class DCC { class DCC {
public: public:
static void begin(MotorDriver * mainDriver, MotorDriver * progDriver); static void begin(MotorDriver * mainDriver, MotorDriver * progDriver, byte timerNumber=1);
static void loop(); static void loop();
// Public DCC API functions // Public DCC API functions

View File

@ -20,27 +20,36 @@
#include "DCCWaveform.h" #include "DCCWaveform.h"
#include "DIAG.h" #include "DIAG.h"
#include "MotorDriver.h"
#include "ArduinoTimers.h"
DCCWaveform DCCWaveform::mainTrack(PREAMBLE_BITS_MAIN, true); DCCWaveform DCCWaveform::mainTrack(PREAMBLE_BITS_MAIN, true);
DCCWaveform DCCWaveform::progTrack(PREAMBLE_BITS_PROG, false); DCCWaveform DCCWaveform::progTrack(PREAMBLE_BITS_PROG, false);
bool DCCWaveform::progTrackSyncMain=false; bool DCCWaveform::progTrackSyncMain=false;
VirtualTimer * DCCWaveform::interruptTimer=NULL;
void DCCWaveform::begin(MotorDriver * mainDriver, MotorDriver * progDriver) {
void DCCWaveform::begin(MotorDriver * mainDriver, MotorDriver * progDriver, byte timerNumber) {
mainTrack.motorDriver=mainDriver; mainTrack.motorDriver=mainDriver;
progTrack.motorDriver=progDriver; progTrack.motorDriver=progDriver;
mainTrack.setPowerMode(POWERMODE::OFF); mainTrack.setPowerMode(POWERMODE::OFF);
progTrack.setPowerMode(POWERMODE::OFF); progTrack.setPowerMode(POWERMODE::OFF);
switch (timerNumber) {
TimerA.initialize(); case 1: interruptTimer= &TimerA; break;
TimerA.setPeriod(58); // this is the 58uS DCC 1-bit waveform half-cycle case 2: interruptTimer= &TimerB; break;
TimerA.attachInterrupt(interruptHandler); #ifndef ARDUINO_AVR_UNO
TimerA.start(); 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() { void DCCWaveform::loop() {
@ -95,6 +104,10 @@ POWERMODE DCCWaveform::getPowerMode() {
} }
void DCCWaveform::setPowerMode(POWERMODE mode) { 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; powerMode = mode;
bool ison = (mode == POWERMODE::ON); bool ison = (mode == POWERMODE::ON);
motorDriver->setPower( ison); motorDriver->setPower( ison);

View File

@ -19,6 +19,7 @@
#ifndef DCCWaveform_h #ifndef DCCWaveform_h
#define DCCWaveform_h #define DCCWaveform_h
#include "MotorDriver.h" #include "MotorDriver.h"
#include "ArduinoTimers.h"
const int POWER_SAMPLE_ON_WAIT = 100; const int POWER_SAMPLE_ON_WAIT = 100;
const int POWER_SAMPLE_OFF_WAIT = 1000; const int POWER_SAMPLE_OFF_WAIT = 1000;
@ -46,7 +47,7 @@ const byte resetPacket[] = {0x00, 0x00, 0x00};
class DCCWaveform { class DCCWaveform {
public: public:
DCCWaveform( byte preambleBits, bool isMain); 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 void loop();
static DCCWaveform mainTrack; static DCCWaveform mainTrack;
static DCCWaveform progTrack; static DCCWaveform progTrack;
@ -65,7 +66,7 @@ class DCCWaveform {
static bool progTrackSyncMain; // true when prog track is a siding switched to main static bool progTrackSyncMain; // true when prog track is a siding switched to main
private: private:
static VirtualTimer * interruptTimer;
static void interruptHandler(); static void interruptHandler();
bool interrupt1(); bool interrupt1();
void interrupt2(); void interrupt2();