From 68e7ea11d2fff321f1d03eafd9aadfdc62370a20 Mon Sep 17 00:00:00 2001 From: NitrofMtl Date: Tue, 24 Nov 2020 21:20:51 -0500 Subject: [PATCH 1/2] first edit --- .../FanSpeed/{FanSpeed.pde => FanSpeed.ino} | 5 +- .../{Interrupt.pde => Interrupt.ino} | 33 +++--- TimerOne.cpp => src/TimerOne.cpp | 0 TimerOne.h => src/TimerOne.h | 110 ++++++++++-------- {config => src/config}/known_16bit_timers.h | 0 5 files changed, 81 insertions(+), 67 deletions(-) rename examples/FanSpeed/{FanSpeed.pde => FanSpeed.ino} (90%) rename examples/Interrupt/{Interrupt.pde => Interrupt.ino} (73%) rename TimerOne.cpp => src/TimerOne.cpp (100%) rename TimerOne.h => src/TimerOne.h (82%) rename {config => src/config}/known_16bit_timers.h (100%) diff --git a/examples/FanSpeed/FanSpeed.pde b/examples/FanSpeed/FanSpeed.ino similarity index 90% rename from examples/FanSpeed/FanSpeed.pde rename to examples/FanSpeed/FanSpeed.ino index c3f46ee..ef0f59f 100644 --- a/examples/FanSpeed/FanSpeed.pde +++ b/examples/FanSpeed/FanSpeed.ino @@ -1,4 +1,4 @@ -#include +#inc#include // This example creates a PWM signal with 25 kHz carrier. // @@ -20,7 +20,8 @@ const int fanPin = 4; void setup(void) { - Timer1.initialize(40); // 40 us = 25 kHz + //Timer1.initialize(40); // 40 us = 25 kHz + Timer1.setFrequency(25000); // 25 kHz Serial.begin(9600); } diff --git a/examples/Interrupt/Interrupt.pde b/examples/Interrupt/Interrupt.ino similarity index 73% rename from examples/Interrupt/Interrupt.pde rename to examples/Interrupt/Interrupt.ino index 7e0c959..82d9856 100644 --- a/examples/Interrupt/Interrupt.pde +++ b/examples/Interrupt/Interrupt.ino @@ -1,20 +1,7 @@ #include -// This example uses the timer interrupt to blink an LED -// and also demonstrates how to share a variable between -// the interrupt and the main program. - - const int led = LED_BUILTIN; // the pin with a LED -void setup(void) -{ - pinMode(led, OUTPUT); - Timer1.initialize(150000); - Timer1.attachInterrupt(blinkLED); // blinkLED to run every 0.15 seconds - Serial.begin(9600); -} - // The interrupt will blink the LED, and keep // track of how many times it has blinked. @@ -33,6 +20,19 @@ void blinkLED(void) } + +void setup(void) +{ + pinMode(led, OUTPUT); + //Timer1.initialize(150000); + //Timer1.attachInterrupt(blinkLED); // blinkLED to run every 0.15 seconds + //Timer1.initialize(150000).attachInterrupt(blinkLED); //alternative way to enable the timer in one line + Timer1.setFrequency(6.66).attachInterrupt(blinkLED); //alternative way to enable the timer by frequency + Serial.begin(9600); +} + + + // The main program will print the blink count // to the Arduino Serial Monitor void loop(void) @@ -44,11 +44,12 @@ void loop(void) // not change while we are reading. To minimize the time // with interrupts off, just quickly make a copy, and then // use the copy while allowing the interrupt to keep working. - noInterrupts(); - blinkCopy = blinkCount; - interrupts(); + //noInterrupts(); + //blinkCopy = blinkCount; + //interrupts(); Serial.print("blinkCount = "); Serial.println(blinkCopy); delay(100); + } diff --git a/TimerOne.cpp b/src/TimerOne.cpp similarity index 100% rename from TimerOne.cpp rename to src/TimerOne.cpp diff --git a/TimerOne.h b/src/TimerOne.h similarity index 82% rename from TimerOne.h rename to src/TimerOne.h index fea75f2..ed76bf4 100644 --- a/TimerOne.h +++ b/src/TimerOne.h @@ -43,10 +43,11 @@ class TimerOne //**************************** // Configuration //**************************** - void initialize(unsigned long microseconds=1000000) __attribute__((always_inline)) { + TimerOne& initialize(unsigned long microseconds=1000000) __attribute__((always_inline)) { TCCR1B = _BV(WGM13); // set mode as phase and frequency correct pwm, stop the timer TCCR1A = 0; // clear control register A setPeriod(microseconds); + return *this; } void setPeriod(unsigned long microseconds) __attribute__((always_inline)) { const unsigned long cycles = (F_CPU / 2000000) * microseconds; @@ -76,6 +77,10 @@ class TimerOne ICR1 = pwmPeriod; TCCR1B = _BV(WGM13) | clockSelectBits; } + TimerOne& setFrequency(float f = 1) { + unsigned long period = 1000000 / f; + return initialize(period); + } //**************************** // Run Control @@ -138,13 +143,14 @@ class TimerOne //**************************** // Interrupt Function //**************************** - void attachInterrupt(void (*isr)()) __attribute__((always_inline)) { + TimerOne& attachInterrupt(void (*isr)()) __attribute__((always_inline)) { isrCallback = isr; TIMSK1 = _BV(TOIE1); + return *this; } - void attachInterrupt(void (*isr)(), unsigned long microseconds) __attribute__((always_inline)) { + TimerOne& attachInterrupt(void (*isr)(), unsigned long microseconds) __attribute__((always_inline)) { if(microseconds > 0) setPeriod(microseconds); - attachInterrupt(isr); + return attachInterrupt(isr); } void detachInterrupt() __attribute__((always_inline)) { TIMSK1 = 0; @@ -174,11 +180,12 @@ class TimerOne //**************************** // Configuration //**************************** - void initialize(unsigned long microseconds=1000000) __attribute__((always_inline)) { - setPeriod(microseconds); + TimerOne& initialize(unsigned long microseconds=1000000) __attribute__((always_inline)) { + setPeriod(microseconds); + return *this; } void setPeriod(unsigned long microseconds) __attribute__((always_inline)) { - const unsigned long cycles = (F_TIMER / 2000000) * microseconds; + const unsigned long cycles = (F_TIMER / 2000000) * microseconds; // A much faster if-else // This is like a binary serch tree and no more than 3 conditions are evaluated. // I haven't checked if this becomes significantly longer ASM than the simple ladder. @@ -226,47 +233,51 @@ class TimerOne } } */ - if (cycles < TIMER1_RESOLUTION) { - clockSelectBits = 0; - pwmPeriod = cycles; - } else - if (cycles < TIMER1_RESOLUTION * 2) { - clockSelectBits = 1; - pwmPeriod = cycles >> 1; - } else - if (cycles < TIMER1_RESOLUTION * 4) { - clockSelectBits = 2; - pwmPeriod = cycles >> 2; - } else - if (cycles < TIMER1_RESOLUTION * 8) { - clockSelectBits = 3; - pwmPeriod = cycles >> 3; - } else - if (cycles < TIMER1_RESOLUTION * 16) { - clockSelectBits = 4; - pwmPeriod = cycles >> 4; - } else - if (cycles < TIMER1_RESOLUTION * 32) { - clockSelectBits = 5; - pwmPeriod = cycles >> 5; - } else - if (cycles < TIMER1_RESOLUTION * 64) { - clockSelectBits = 6; - pwmPeriod = cycles >> 6; - } else - if (cycles < TIMER1_RESOLUTION * 128) { - clockSelectBits = 7; - pwmPeriod = cycles >> 7; - } else { - clockSelectBits = 7; - pwmPeriod = TIMER1_RESOLUTION - 1; - } - - uint32_t sc = FTM1_SC; - FTM1_SC = 0; - FTM1_MOD = pwmPeriod; - FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_CPWMS | clockSelectBits | (sc & FTM_SC_TOIE); + if (cycles < TIMER1_RESOLUTION) { + clockSelectBits = 0; + pwmPeriod = cycles; + } else + if (cycles < TIMER1_RESOLUTION * 2) { + clockSelectBits = 1; + pwmPeriod = cycles >> 1; + } else + if (cycles < TIMER1_RESOLUTION * 4) { + clockSelectBits = 2; + pwmPeriod = cycles >> 2; + } else + if (cycles < TIMER1_RESOLUTION * 8) { + clockSelectBits = 3; + pwmPeriod = cycles >> 3; + } else + if (cycles < TIMER1_RESOLUTION * 16) { + clockSelectBits = 4; + pwmPeriod = cycles >> 4; + } else + if (cycles < TIMER1_RESOLUTION * 32) { + clockSelectBits = 5; + pwmPeriod = cycles >> 5; + } else + if (cycles < TIMER1_RESOLUTION * 64) { + clockSelectBits = 6; + pwmPeriod = cycles >> 6; + } else + if (cycles < TIMER1_RESOLUTION * 128) { + clockSelectBits = 7; + pwmPeriod = cycles >> 7; + } else { + clockSelectBits = 7; + pwmPeriod = TIMER1_RESOLUTION - 1; + } + + uint32_t sc = FTM1_SC; + FTM1_SC = 0; + FTM1_MOD = pwmPeriod; + FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_CPWMS | clockSelectBits | (sc & FTM_SC_TOIE); } + TimerOne& setFrequency(float f = 1) { + unsigned long period = 1000000 / f; + return initialize(period); + } //**************************** // Run Control @@ -322,14 +333,15 @@ class TimerOne //**************************** // Interrupt Function //**************************** - void attachInterrupt(void (*isr)()) __attribute__((always_inline)) { + TimerOne& attachInterrupt(void (*isr)()) __attribute__((always_inline)) { isrCallback = isr; FTM1_SC |= FTM_SC_TOIE; NVIC_ENABLE_IRQ(IRQ_FTM1); + return *this; } void attachInterrupt(void (*isr)(), unsigned long microseconds) __attribute__((always_inline)) { if(microseconds > 0) setPeriod(microseconds); - attachInterrupt(isr); + return attachInterrupt(isr); } void detachInterrupt() __attribute__((always_inline)) { FTM1_SC &= ~FTM_SC_TOIE; diff --git a/config/known_16bit_timers.h b/src/config/known_16bit_timers.h similarity index 100% rename from config/known_16bit_timers.h rename to src/config/known_16bit_timers.h From 447abd2ad465c26013ffac3a04da76af3c2e246e Mon Sep 17 00:00:00 2001 From: NitrofMtl Date: Tue, 24 Nov 2020 21:38:05 -0500 Subject: [PATCH 2/2] Update FanSpeed.ino --- examples/FanSpeed/FanSpeed.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/FanSpeed/FanSpeed.ino b/examples/FanSpeed/FanSpeed.ino index ef0f59f..5a453ab 100644 --- a/examples/FanSpeed/FanSpeed.ino +++ b/examples/FanSpeed/FanSpeed.ino @@ -1,4 +1,4 @@ -#inc#include +#include // This example creates a PWM signal with 25 kHz carrier. //