diff --git a/ATMEGA4809/Timer.h b/ATMEGA4809/Timer.h new file mode 100644 index 0000000..1690ad5 --- /dev/null +++ b/ATMEGA4809/Timer.h @@ -0,0 +1,131 @@ +#ifndef ATMEGA328Timer_h +#define ATMEGA328Timer_h + +#include "../VirtualTimer.h" +#include + +// We only define behavior for timer 0 (TCA0), because TCB0 is very limited in functionality. + +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: + timer_resolution = 65536; + break; + } + this->timer_num = timer_num; + lastMicroseconds = 0; + } + + void initialize() { + switch (timer_num) + { + case 0: + break; + } + } + + void setPeriod(unsigned long microseconds) { + if(microseconds == lastMicroseconds) + return; + lastMicroseconds = microseconds; + const unsigned long cycles = (F_CPU / 1000000) * microseconds; + + switch(timer_num) { + case 0: + if (cycles < timer_resolution) { + clockSelectBits = 0x0; + pwmPeriod = cycles; + } else + if (cycles < timer_resolution * 2) { + clockSelectBits = 0x1; + pwmPeriod = cycles / 8; + } else + if (cycles < timer_resolution * 4) { + clockSelectBits = 0x2; + pwmPeriod = cycles / 32; + } else + if (cycles < timer_resolution * 8) { + clockSelectBits = 0x3; + pwmPeriod = cycles / 64; + } else + if (cycles < timer_resolution * 64) { + clockSelectBits = 0x5; + pwmPeriod = cycles / 128; + } else + if (cycles < timer_resolution * 256) { + clockSelectBits = 0x6; + pwmPeriod = cycles / 256; + } else + if (cycles < timer_resolution * 1024) { + clockSelectBits = 0x7; + pwmPeriod = cycles / 1024; + } else { + clockSelectBits = 0x7; + pwmPeriod = timer_resolution - 1; + } + break; + } + + switch (timer_num) + { + case 0: + TCA0.SINGLE.PER = pwmPeriod; + TCA0.SINGLE.CTRLA = clockSelectBits << 1; + break; + } + } + + void start() { + switch (timer_num) + { + case 0: + bitSet(TCA0.SINGLE.CTRLA, 0); + break; + } + + + } + void stop() { + switch (timer_num) + { + case 0: + bitClear(TCA0.SINGLE.CTRLA, 0); + break; + } + } + + void attachInterrupt(void (*isr)()) { + isrCallback = isr; + + switch (timer_num) + { + case 0: + TCA0.SINGLE.INTCTRL = 0x1; + break; + } + } + + void detachInterrupt() { + switch (timer_num) + { + case 0: + TCA0.SINGLE.INTCTRL = 0x0; + break; + } + } + +}; + +extern Timer TimerA; + +#endif \ No newline at end of file diff --git a/ArduinoTimers.h b/ArduinoTimers.h index c0acd30..99af18f 100644 --- a/ArduinoTimers.h +++ b/ArduinoTimers.h @@ -3,16 +3,18 @@ // 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" +#include "ATMEGA2560/Timer.h" #elif defined(ARDUINO_AVR_UNO) - #include "ATMEGA328/Timer.h" +#include "ATMEGA328/Timer.h" +#elif defined(ARDUINO_ARCH_MEGAAVR) +#include "ATMEGA4809/Timer.h" #else - #error "Cannot compile - ArduinoTimers library does not support your board, or you are missing compatible build flags." +#error "Cannot compile - ArduinoTimers library does not support your board, or you are missing compatible build flags." #endif #endif diff --git a/DCC.h b/DCC.h index 122e934..b2070a9 100644 --- a/DCC.h +++ b/DCC.h @@ -155,6 +155,8 @@ private: #define ARDUINO_TYPE "NANO" #elif defined(ARDUINO_AVR_MEGA2560) #define ARDUINO_TYPE "MEGA" +#elif defined(ARDUINO_ARCH_MEGAAVR) +#define ARDUINO_TYPE "UNOWIFIR2" #else #error CANNOT COMPILE - DCC++ EX ONLY WORKS WITH AN ARDUINO UNO, NANO 328, OR ARDUINO MEGA 1280/2560 #endif