1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-12-23 12:51:24 +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.
// 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);

View File

@ -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) {

2
DCC.h
View File

@ -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

View File

@ -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);

View File

@ -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();