mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2025-01-27 12:48:52 +01:00
Clean simple Timer interface
Removes overkill files, puts all timer in a single small file. (DCCTimer)
This commit is contained in:
parent
f646f12c65
commit
8a9feaef22
@ -1,194 +0,0 @@
|
||||
#ifndef ATMEGA2560Timer_h
|
||||
#define ATMEGA2560Timer_h
|
||||
|
||||
#include "../VirtualTimer.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
class Timer : public VirtualTimer {
|
||||
private:
|
||||
int pwmPeriod;
|
||||
unsigned long timer_resolution;
|
||||
unsigned char clockSelectBits;
|
||||
int timer_num;
|
||||
unsigned long lastMicroseconds;
|
||||
public:
|
||||
void (*isrCallback)();
|
||||
Timer(int timer_num) {
|
||||
switch (timer_num)
|
||||
{
|
||||
case 1:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
timer_resolution = 65536;
|
||||
break;
|
||||
}
|
||||
this->timer_num = timer_num;
|
||||
lastMicroseconds = 0;
|
||||
}
|
||||
|
||||
void initialize() {
|
||||
switch (timer_num)
|
||||
{
|
||||
case 1:
|
||||
TCCR1B = _BV(WGM13) | _BV(WGM12);
|
||||
TCCR1A = _BV(WGM11);
|
||||
break;
|
||||
case 3:
|
||||
TCCR3B = _BV(WGM33) | _BV(WGM32);
|
||||
TCCR3A = _BV(WGM31);
|
||||
break;
|
||||
case 4:
|
||||
TCCR4B = _BV(WGM43) | _BV(WGM42);
|
||||
TCCR4A = _BV(WGM41);
|
||||
break;
|
||||
case 5:
|
||||
TCCR5B = _BV(WGM53) | _BV(WGM52);
|
||||
TCCR5A = _BV(WGM51);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void setPeriod(unsigned long microseconds) {
|
||||
if(microseconds == lastMicroseconds)
|
||||
return;
|
||||
lastMicroseconds = microseconds;
|
||||
const unsigned long cycles = (F_CPU / 1000000) * microseconds;
|
||||
if (cycles < timer_resolution) {
|
||||
clockSelectBits = 1 << 0;
|
||||
pwmPeriod = cycles;
|
||||
} else
|
||||
if (cycles < timer_resolution * 8) {
|
||||
clockSelectBits = 1 << 1;
|
||||
pwmPeriod = cycles / 8;
|
||||
} else
|
||||
if (cycles < timer_resolution * 64) {
|
||||
clockSelectBits = (1 << 0) | (1 << 1);
|
||||
pwmPeriod = cycles / 64;
|
||||
} else
|
||||
if (cycles < timer_resolution * 256) {
|
||||
clockSelectBits = 1 << 2;
|
||||
pwmPeriod = cycles / 256;
|
||||
} else
|
||||
if (cycles < timer_resolution * 1024) {
|
||||
clockSelectBits = (1 << 2) | (1 << 0);
|
||||
pwmPeriod = cycles / 1024;
|
||||
} else {
|
||||
clockSelectBits = (1 << 2) | (1 << 0);
|
||||
pwmPeriod = timer_resolution - 1;
|
||||
}
|
||||
|
||||
switch (timer_num)
|
||||
{
|
||||
case 1:
|
||||
ICR1 = pwmPeriod;
|
||||
TCCR1B = _BV(WGM13) | _BV(WGM12) | clockSelectBits;
|
||||
break;
|
||||
case 3:
|
||||
ICR3 = pwmPeriod;
|
||||
TCCR3B = _BV(WGM33) | _BV(WGM32) | clockSelectBits;
|
||||
break;
|
||||
case 4:
|
||||
ICR4 = pwmPeriod;
|
||||
TCCR4B = _BV(WGM43) | _BV(WGM42) | clockSelectBits;
|
||||
break;
|
||||
case 5:
|
||||
ICR5 = pwmPeriod;
|
||||
TCCR5B = _BV(WGM53) | _BV(WGM52) | clockSelectBits;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
void start() {
|
||||
switch (timer_num)
|
||||
{
|
||||
case 1:
|
||||
TCCR1B = 0;
|
||||
TCNT1 = 0; // TODO: does this cause an undesired interrupt?
|
||||
TCCR1B = _BV(WGM13) | _BV(WGM12) | clockSelectBits;
|
||||
break;
|
||||
case 3:
|
||||
TCCR3B = 0;
|
||||
TCNT3 = 0; // TODO: does this cause an undesired interrupt?
|
||||
TCCR3B = _BV(WGM33) | _BV(WGM32) | clockSelectBits;
|
||||
break;
|
||||
case 4:
|
||||
TCCR4B = 0;
|
||||
TCNT4 = 0; // TODO: does this cause an undesired interrupt?
|
||||
TCCR4B = _BV(WGM43) | _BV(WGM42) | clockSelectBits;
|
||||
break;
|
||||
case 5:
|
||||
TCCR5B = 0;
|
||||
TCNT5 = 0; // TODO: does this cause an undesired interrupt?
|
||||
TCCR5B = _BV(WGM53) | _BV(WGM52) | clockSelectBits;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
void stop() {
|
||||
switch (timer_num)
|
||||
{
|
||||
case 1:
|
||||
TCCR1B = _BV(WGM13) | _BV(WGM12);
|
||||
break;
|
||||
case 3:
|
||||
TCCR3B = _BV(WGM33) | _BV(WGM32);
|
||||
break;
|
||||
case 4:
|
||||
TCCR4B = _BV(WGM43) | _BV(WGM42);
|
||||
break;
|
||||
case 5:
|
||||
TCCR5B = _BV(WGM53) | _BV(WGM52);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void attachInterrupt(void (*isr)()) {
|
||||
isrCallback = isr;
|
||||
|
||||
switch (timer_num)
|
||||
{
|
||||
case 1:
|
||||
TIMSK1 = _BV(TOIE1);
|
||||
break;
|
||||
case 3:
|
||||
TIMSK3 = _BV(TOIE3);
|
||||
break;
|
||||
case 4:
|
||||
TIMSK4 = _BV(TOIE4);
|
||||
break;
|
||||
case 5:
|
||||
TIMSK5 = _BV(TOIE5);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void detachInterrupt() {
|
||||
switch (timer_num)
|
||||
{
|
||||
case 1:
|
||||
TIMSK1 = 0;
|
||||
break;
|
||||
case 3:
|
||||
TIMSK3 = 0;
|
||||
break;
|
||||
case 4:
|
||||
TIMSK4 = 0;
|
||||
break;
|
||||
case 5:
|
||||
TIMSK5 = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
extern Timer TimerA;
|
||||
extern Timer TimerB;
|
||||
extern Timer TimerC;
|
||||
extern Timer TimerD;
|
||||
|
||||
|
||||
|
||||
#endif
|
@ -1,208 +0,0 @@
|
||||
#ifndef ATMEGA328Timer_h
|
||||
#define ATMEGA328Timer_h
|
||||
|
||||
#include "../VirtualTimer.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
class Timer : public VirtualTimer {
|
||||
private:
|
||||
int pwmPeriod;
|
||||
unsigned long timer_resolution;
|
||||
unsigned char clockSelectBits;
|
||||
int timer_num;
|
||||
unsigned long lastMicroseconds;
|
||||
public:
|
||||
void (*isrCallback)();
|
||||
Timer(int timer_num) {
|
||||
switch (timer_num)
|
||||
{
|
||||
//case 0:
|
||||
case 2:
|
||||
timer_resolution = 256;
|
||||
break;
|
||||
case 1:
|
||||
timer_resolution = 65536;
|
||||
break;
|
||||
}
|
||||
this->timer_num = timer_num;
|
||||
lastMicroseconds = 0;
|
||||
}
|
||||
|
||||
void initialize() {
|
||||
switch (timer_num)
|
||||
{
|
||||
// case 0:
|
||||
// TCCR0B = _BV(WGM02);
|
||||
// TCCR0A = _BV(WGM00) | _BV(WGM01);
|
||||
// break;
|
||||
case 1:
|
||||
TCCR1B = _BV(WGM13) | _BV(WGM12);
|
||||
TCCR1A = _BV(WGM11);
|
||||
break;
|
||||
case 2:
|
||||
TCCR2B = _BV(WGM22);
|
||||
TCCR2A = _BV(WGM20) | _BV(WGM21);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void setPeriod(unsigned long microseconds) {
|
||||
if(microseconds == lastMicroseconds)
|
||||
return;
|
||||
lastMicroseconds = microseconds;
|
||||
const unsigned long cycles = (F_CPU / 1000000) * microseconds;
|
||||
|
||||
switch(timer_num) {
|
||||
case 2:
|
||||
if (cycles < timer_resolution) {
|
||||
clockSelectBits = 1 << 0;
|
||||
pwmPeriod = cycles;
|
||||
} else
|
||||
if (cycles < timer_resolution * 8) {
|
||||
clockSelectBits = 1 << 1;
|
||||
pwmPeriod = cycles / 8;
|
||||
} else
|
||||
if (cycles < timer_resolution * 32) {
|
||||
clockSelectBits = 1 << 0 | 1 << 1;
|
||||
pwmPeriod = cycles / 32;
|
||||
} else
|
||||
if (cycles < timer_resolution * 64) {
|
||||
clockSelectBits = 1 << 2;
|
||||
pwmPeriod = cycles / 64;
|
||||
} else
|
||||
if (cycles < timer_resolution * 128) {
|
||||
clockSelectBits = 1 << 2 | 1 << 0;
|
||||
pwmPeriod = cycles / 128;
|
||||
} else
|
||||
if (cycles < timer_resolution * 256) {
|
||||
clockSelectBits = 1 << 2 | 1 << 1;
|
||||
pwmPeriod = cycles / 256;
|
||||
} else
|
||||
if (cycles < timer_resolution * 1024) {
|
||||
clockSelectBits = 1 << 2 | 1 << 1 | 1 << 0;
|
||||
pwmPeriod = cycles / 1024;
|
||||
} else {
|
||||
clockSelectBits = 1 << 2 | 1 << 1 | 1 << 0;
|
||||
pwmPeriod = timer_resolution - 1;
|
||||
}
|
||||
break;
|
||||
//case 0:
|
||||
case 1:
|
||||
if (cycles < timer_resolution) {
|
||||
clockSelectBits = 1 << 0;
|
||||
pwmPeriod = cycles;
|
||||
} else
|
||||
if (cycles < timer_resolution * 8) {
|
||||
clockSelectBits = 1 << 1;
|
||||
pwmPeriod = cycles / 8;
|
||||
} else
|
||||
if (cycles < timer_resolution * 64) {
|
||||
clockSelectBits = (1 << 0) | (1 << 1);
|
||||
pwmPeriod = cycles / 64;
|
||||
} else
|
||||
if (cycles < timer_resolution * 256) {
|
||||
clockSelectBits = 1 << 2;
|
||||
pwmPeriod = cycles / 256;
|
||||
} else
|
||||
if (cycles < timer_resolution * 1024) {
|
||||
clockSelectBits = (1 << 2) | (1 << 0);
|
||||
pwmPeriod = cycles / 1024;
|
||||
} else {
|
||||
clockSelectBits = (1 << 2) | (1 << 0);
|
||||
pwmPeriod = timer_resolution - 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch (timer_num)
|
||||
{
|
||||
// case 0:
|
||||
// OCR0A = pwmPeriod;
|
||||
// TCCR0B = _BV(WGM02) | clockSelectBits;
|
||||
// break;
|
||||
case 1:
|
||||
ICR1 = pwmPeriod;
|
||||
TCCR1B = _BV(WGM13) | _BV(WGM12) | clockSelectBits;
|
||||
break;
|
||||
case 2:
|
||||
OCR2A = pwmPeriod;
|
||||
TCCR2B = _BV(WGM22) | clockSelectBits;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
void start() {
|
||||
switch (timer_num)
|
||||
{
|
||||
// case 0:
|
||||
// TCCR0B = 0;
|
||||
// TCNT0 = 0; // TODO: does this cause an undesired interrupt?
|
||||
// TCCR0B = _BV(WGM02) | clockSelectBits;
|
||||
// break;
|
||||
case 1:
|
||||
TCCR1B = 0;
|
||||
TCNT1 = 0; // TODO: does this cause an undesired interrupt?
|
||||
TCCR1B = _BV(WGM13) | _BV(WGM12) | clockSelectBits;
|
||||
break;
|
||||
case 2:
|
||||
TCCR2B = 0;
|
||||
TCNT2 = 0; // TODO: does this cause an undesired interrupt?
|
||||
TCCR2B = _BV(WGM22) | clockSelectBits;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
void stop() {
|
||||
switch (timer_num)
|
||||
{
|
||||
// case 0:
|
||||
// TCCR0B = _BV(WGM02);
|
||||
// break;
|
||||
case 1:
|
||||
TCCR1B = _BV(WGM13) | _BV(WGM12);
|
||||
break;
|
||||
case 2:
|
||||
TCCR2B = _BV(WGM22);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void attachInterrupt(void (*isr)()) {
|
||||
isrCallback = isr;
|
||||
|
||||
switch (timer_num)
|
||||
{
|
||||
// case 0:
|
||||
// TIMSK0 = _BV(TOIE0);
|
||||
// break;
|
||||
case 1:
|
||||
TIMSK1 = _BV(TOIE1);
|
||||
break;
|
||||
case 2:
|
||||
TIMSK2 = _BV(TOIE2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void detachInterrupt() {
|
||||
switch (timer_num)
|
||||
{
|
||||
// case 0:
|
||||
// TIMSK0 = 0;
|
||||
// break;
|
||||
case 1:
|
||||
TIMSK1 = 0;
|
||||
break;
|
||||
case 2:
|
||||
TIMSK2 = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
extern Timer TimerA;
|
||||
extern Timer TimerB;
|
||||
|
||||
#endif
|
@ -1,18 +0,0 @@
|
||||
// This file is copied from https://github.com/davidcutting42/ArduinoTimers
|
||||
// All Credit and copyright David Cutting
|
||||
// The files included below come from the same source.
|
||||
// This library had been included with the DCC code to avoid issues with
|
||||
// library management for inexperienced users. "It just works (TM)"
|
||||
|
||||
#ifndef ArduinoTimers_h
|
||||
#define ArduinoTimers_h
|
||||
|
||||
#if defined(ARDUINO_AVR_MEGA) || defined(ARDUINO_AVR_MEGA2560)
|
||||
#include "ATMEGA2560/Timer.h"
|
||||
#elif defined(ARDUINO_AVR_UNO)
|
||||
#include "ATMEGA328/Timer.h"
|
||||
#else
|
||||
#error "Cannot compile - ArduinoTimers library does not support your board, or you are missing compatible build flags."
|
||||
#endif
|
||||
|
||||
#endif
|
@ -49,9 +49,7 @@ void setup()
|
||||
|
||||
// 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(MOTOR_SHIELD_TYPE);
|
||||
|
||||
#if defined(RMFT_ACTIVE)
|
||||
|
5
DCC.cpp
5
DCC.cpp
@ -45,7 +45,7 @@ const byte FN_GROUP_5=0x10;
|
||||
|
||||
__FlashStringHelper* DCC::shieldName=NULL;
|
||||
|
||||
void DCC::begin(const __FlashStringHelper* motorShieldName, MotorDriver * mainDriver, MotorDriver* progDriver, byte timerNumber) {
|
||||
void DCC::begin(const __FlashStringHelper* motorShieldName, MotorDriver * mainDriver, MotorDriver* progDriver) {
|
||||
shieldName=(__FlashStringHelper*)motorShieldName;
|
||||
DIAG(F("<iDCC-EX V-%S / %S / %S G-%S>\n"), F(VERSION), F(ARDUINO_TYPE), shieldName, F(GITHUB_SHA));
|
||||
|
||||
@ -53,7 +53,7 @@ void DCC::begin(const __FlashStringHelper* motorShieldName, MotorDriver * mainDr
|
||||
(void)EEPROM; // tell compiler not to warn this is unused
|
||||
EEStore::init();
|
||||
|
||||
DCCWaveform::begin(mainDriver,progDriver, timerNumber);
|
||||
DCCWaveform::begin(mainDriver,progDriver);
|
||||
}
|
||||
|
||||
void DCC::setThrottle( uint16_t cab, uint8_t tSpeed, bool tDirection) {
|
||||
@ -481,7 +481,6 @@ void DCC::getLocoId(ACK_CALLBACK callback, bool blocking) {
|
||||
|
||||
void DCC::setLocoId(int id,ACK_CALLBACK callback, bool blocking) {
|
||||
if (id<=0 || id>9999) callback(-1);
|
||||
int wordval;
|
||||
if (id<=127) ackManagerSetup(id,SHORT_LOCO_ID_PROG, callback, blocking);
|
||||
else ackManagerSetup(id | 0xc000,LONG_LOCO_ID_PROG, callback, blocking);
|
||||
}
|
||||
|
2
DCC.h
2
DCC.h
@ -64,7 +64,7 @@ const byte MAX_LOCOS = 50;
|
||||
class DCC
|
||||
{
|
||||
public:
|
||||
static void begin(const __FlashStringHelper *motorShieldName, MotorDriver *mainDriver, MotorDriver *progDriver, byte timerNumber = 1);
|
||||
static void begin(const __FlashStringHelper *motorShieldName, MotorDriver *mainDriver, MotorDriver *progDriver);
|
||||
static void loop();
|
||||
|
||||
// Public DCC API functions
|
||||
|
54
DCCTimer.cpp
Normal file
54
DCCTimer.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* © 2021, Chris Harlow & David Cutting. All rights reserved.
|
||||
*
|
||||
* This file is part of Asbelos DCC API
|
||||
*
|
||||
* This is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* It is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with CommandStation. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
/* This timer class is used to manage the single timer required to handle the DCC waveform.
|
||||
* All timer access comes through this class so that it can be compiled for
|
||||
* various hardware CPU types.
|
||||
*
|
||||
* DCCEX works on a single timer interrupt at a regular 58uS interval.
|
||||
* The DCCWaveform class generates the signals to the motor shield
|
||||
* based on this timer.
|
||||
*/
|
||||
|
||||
#include "DCCTimer.h"
|
||||
|
||||
const int DCC_SIGNAL_TIME=58; // this is the 58uS DCC 1-bit waveform half-cycle
|
||||
const int DCC_SLOW_TIME=58*512; // for <D DCC SLOW> command diagnostics
|
||||
|
||||
INTERRUPT_CALLBACK interruptHandler=0;
|
||||
|
||||
|
||||
void DCCTimer::begin(INTERRUPT_CALLBACK callback, bool slow) {
|
||||
interruptHandler=callback;
|
||||
// Initialise timer1 to trigger every 58us (DCC_SIGNAL_TIME)
|
||||
noInterrupts();
|
||||
TCCR1A = 0;
|
||||
ICR1 = ((F_CPU / 1000000) * (slow? DCC_SLOW_TIME : DCC_SIGNAL_TIME)) >>1;
|
||||
TCNT1 = 0;
|
||||
TCCR1B = _BV(WGM13) | _BV(CS10); // Mode 8, clock select 1
|
||||
TIMSK1 = _BV(TOIE1); // Enable Software interrupt
|
||||
interrupts();
|
||||
}
|
||||
|
||||
// Timer interrupt every 58uS
|
||||
ISR(TIMER1_OVF_vect)
|
||||
{
|
||||
if (interruptHandler) interruptHandler();
|
||||
}
|
13
DCCTimer.h
Normal file
13
DCCTimer.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef DCCTimer_h
|
||||
#define DCCTimer_h
|
||||
#include "Arduino.h"
|
||||
|
||||
typedef void (*INTERRUPT_CALLBACK)();
|
||||
|
||||
class DCCTimer {
|
||||
public:
|
||||
static void begin(INTERRUPT_CALLBACK interrupt, bool slow=false);
|
||||
private:
|
||||
};
|
||||
|
||||
#endif
|
@ -20,10 +20,9 @@
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "DCCWaveform.h"
|
||||
#include "DCCTimer.h"
|
||||
#include "DIAG.h"
|
||||
|
||||
const int NORMAL_SIGNAL_TIME=58; // this is the 58uS DCC 1-bit waveform half-cycle
|
||||
const int SLOW_SIGNAL_TIME=NORMAL_SIGNAL_TIME*512;
|
||||
|
||||
DCCWaveform DCCWaveform::mainTrack(PREAMBLE_BITS_MAIN, true);
|
||||
DCCWaveform DCCWaveform::progTrack(PREAMBLE_BITS_PROG, false);
|
||||
@ -31,32 +30,18 @@ DCCWaveform DCCWaveform::progTrack(PREAMBLE_BITS_PROG, false);
|
||||
|
||||
bool DCCWaveform::progTrackSyncMain=false;
|
||||
bool DCCWaveform::progTrackBoosted=false;
|
||||
VirtualTimer * DCCWaveform::interruptTimer=NULL;
|
||||
|
||||
void DCCWaveform::begin(MotorDriver * mainDriver, MotorDriver * progDriver, byte timerNumber) {
|
||||
void DCCWaveform::begin(MotorDriver * mainDriver, MotorDriver * progDriver) {
|
||||
mainTrack.motorDriver=mainDriver;
|
||||
progTrack.motorDriver=progDriver;
|
||||
|
||||
mainTrack.setPowerMode(POWERMODE::OFF);
|
||||
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;
|
||||
#endif
|
||||
default:
|
||||
DIAG(F("\n\n *** Invalid Timer number %d requested. Only 1..3 valid. DCC will not work.*** \n\n"), timerNumber);
|
||||
return;
|
||||
}
|
||||
interruptTimer->initialize();
|
||||
interruptTimer->setPeriod(NORMAL_SIGNAL_TIME); // this is the 58uS DCC 1-bit waveform half-cycle
|
||||
interruptTimer->attachInterrupt(interruptHandler);
|
||||
interruptTimer->start();
|
||||
DCCTimer::begin(DCCWaveform::interruptHandler);
|
||||
}
|
||||
void DCCWaveform::setDiagnosticSlowWave(bool slow) {
|
||||
interruptTimer->setPeriod(slow? SLOW_SIGNAL_TIME : NORMAL_SIGNAL_TIME);
|
||||
interruptTimer->start();
|
||||
|
||||
void DCCWaveform::setDiagnosticSlowWave(bool slow) {
|
||||
DCCTimer::begin(DCCWaveform::interruptHandler, slow);
|
||||
DIAG(F("\nDCC SLOW WAVE %S\n"),slow?F("SET. DO NOT ADD LOCOS TO TRACK"):F("RESET"));
|
||||
}
|
||||
|
||||
@ -65,8 +50,6 @@ void DCCWaveform::loop() {
|
||||
progTrack.checkPowerOverload();
|
||||
}
|
||||
|
||||
|
||||
// static //
|
||||
void DCCWaveform::interruptHandler() {
|
||||
// call the timer edge sensitive actions for progtrack and maintrack
|
||||
bool mainCall2 = mainTrack.interrupt1();
|
||||
@ -112,10 +95,6 @@ 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);
|
||||
@ -168,10 +147,6 @@ void DCCWaveform::checkPowerOverload() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// process time-edge sensitive part of interrupt
|
||||
// return true if second level required
|
||||
bool DCCWaveform::interrupt1() {
|
||||
|
@ -20,7 +20,6 @@
|
||||
#ifndef DCCWaveform_h
|
||||
#define DCCWaveform_h
|
||||
#include "MotorDriver.h"
|
||||
#include "ArduinoTimers.h"
|
||||
|
||||
// Wait times for power management. Unit: milliseconds
|
||||
const int POWER_SAMPLE_ON_WAIT = 100;
|
||||
@ -46,7 +45,7 @@ const byte resetPacket[] = {0x00, 0x00, 0x00};
|
||||
class DCCWaveform {
|
||||
public:
|
||||
DCCWaveform( byte preambleBits, bool isMain);
|
||||
static void begin(MotorDriver * mainDriver, MotorDriver * progDriver, byte timerNumber);
|
||||
static void begin(MotorDriver * mainDriver, MotorDriver * progDriver);
|
||||
static void setDiagnosticSlowWave(bool slow);
|
||||
static void loop();
|
||||
static DCCWaveform mainTrack;
|
||||
@ -105,7 +104,7 @@ class DCCWaveform {
|
||||
}
|
||||
|
||||
private:
|
||||
static VirtualTimer * interruptTimer;
|
||||
|
||||
static void interruptHandler();
|
||||
bool interrupt1();
|
||||
void interrupt2();
|
||||
|
52
Timer.cpp
52
Timer.cpp
@ -1,52 +0,0 @@
|
||||
// This file is copied from https://github.com/davidcutting42/ArduinoTimers
|
||||
// All Credit to David Cutting
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#if defined(ARDUINO_AVR_MEGA) || defined(ARDUINO_AVR_MEGA2560)
|
||||
|
||||
#include "ATMEGA2560/Timer.h"
|
||||
|
||||
Timer TimerA(1);
|
||||
Timer TimerB(3);
|
||||
Timer TimerC(4);
|
||||
Timer TimerD(5);
|
||||
|
||||
ISR(TIMER1_OVF_vect)
|
||||
{
|
||||
TimerA.isrCallback();
|
||||
}
|
||||
|
||||
ISR(TIMER3_OVF_vect)
|
||||
{
|
||||
TimerB.isrCallback();
|
||||
}
|
||||
|
||||
ISR(TIMER4_OVF_vect)
|
||||
{
|
||||
TimerC.isrCallback();
|
||||
}
|
||||
|
||||
ISR(TIMER5_OVF_vect)
|
||||
{
|
||||
TimerD.isrCallback();
|
||||
}
|
||||
|
||||
#elif defined(ARDUINO_AVR_UNO) // Todo: add other 328 boards for compatibility
|
||||
|
||||
#include "ATMEGA328/Timer.h"
|
||||
|
||||
Timer TimerA(1);
|
||||
Timer TimerB(2);
|
||||
|
||||
ISR(TIMER1_OVF_vect)
|
||||
{
|
||||
TimerA.isrCallback();
|
||||
}
|
||||
|
||||
ISR(TIMER2_OVF_vect)
|
||||
{
|
||||
TimerB.isrCallback();
|
||||
}
|
||||
|
||||
#endif
|
@ -1,21 +0,0 @@
|
||||
// This file is copied from https://github.com/davidcutting42/ArduinoTimers
|
||||
// All Credit to David Cutting
|
||||
|
||||
#ifndef VirtualTimer_h
|
||||
#define VirtualTimer_h
|
||||
|
||||
class VirtualTimer
|
||||
{
|
||||
public:
|
||||
virtual void initialize() = 0;
|
||||
virtual void setPeriod(unsigned long microseconds) = 0;
|
||||
virtual void start() = 0;
|
||||
virtual void stop() = 0;
|
||||
|
||||
virtual void attachInterrupt(void (*isr)()) = 0;
|
||||
virtual void detachInterrupt() = 0;
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user