Created
December 8, 2016 02:21
-
-
Save jdneo/43be30d85080b175cb5aed3500d3f989 to your computer and use it in GitHub Desktop.
Timer Interrupt example for Adafruit Feather M0. Callback function can be written in TC3_Handler().
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define LED_PIN 13 | |
#define CPU_HZ 48000000 | |
#define TIMER_PRESCALER_DIV 1024 | |
void startTimer(int frequencyHz); | |
void setTimerFrequency(int frequencyHz); | |
void TC3_Handler(); | |
bool isLEDOn = false; | |
void setup() { | |
pinMode(LED_PIN, OUTPUT); | |
startTimer(10); | |
} | |
void loop() {} | |
void setTimerFrequency(int frequencyHz) { | |
int compareValue = (CPU_HZ / (TIMER_PRESCALER_DIV * frequencyHz)) - 1; | |
TcCount16* TC = (TcCount16*) TC3; | |
// Make sure the count is in a proportional position to where it was | |
// to prevent any jitter or disconnect when changing the compare value. | |
TC->COUNT.reg = map(TC->COUNT.reg, 0, TC->CC[0].reg, 0, compareValue); | |
TC->CC[0].reg = compareValue; | |
Serial.println(TC->COUNT.reg); | |
Serial.println(TC->CC[0].reg); | |
while (TC->STATUS.bit.SYNCBUSY == 1); | |
} | |
void startTimer(int frequencyHz) { | |
REG_GCLK_CLKCTRL = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID_TCC2_TC3) ; | |
while ( GCLK->STATUS.bit.SYNCBUSY == 1 ); // wait for sync | |
TcCount16* TC = (TcCount16*) TC3; | |
TC->CTRLA.reg &= ~TC_CTRLA_ENABLE; | |
while (TC->STATUS.bit.SYNCBUSY == 1); // wait for sync | |
// Use the 16-bit timer | |
TC->CTRLA.reg |= TC_CTRLA_MODE_COUNT16; | |
while (TC->STATUS.bit.SYNCBUSY == 1); // wait for sync | |
// Use match mode so that the timer counter resets when the count matches the compare register | |
TC->CTRLA.reg |= TC_CTRLA_WAVEGEN_MFRQ; | |
while (TC->STATUS.bit.SYNCBUSY == 1); // wait for sync | |
// Set prescaler to 1024 | |
TC->CTRLA.reg |= TC_CTRLA_PRESCALER_DIV1024; | |
while (TC->STATUS.bit.SYNCBUSY == 1); // wait for sync | |
setTimerFrequency(frequencyHz); | |
// Enable the compare interrupt | |
TC->INTENSET.reg = 0; | |
TC->INTENSET.bit.MC0 = 1; | |
NVIC_EnableIRQ(TC3_IRQn); | |
TC->CTRLA.reg |= TC_CTRLA_ENABLE; | |
while (TC->STATUS.bit.SYNCBUSY == 1); // wait for sync | |
} | |
void TC3_Handler() { | |
TcCount16* TC = (TcCount16*) TC3; | |
// If this interrupt is due to the compare register matching the timer count | |
// we toggle the LED. | |
if (TC->INTFLAG.bit.MC0 == 1) { | |
TC->INTFLAG.bit.MC0 = 1; | |
// Write callback here!!! | |
digitalWrite(LED_PIN, isLEDOn); | |
isLEDOn = !isLEDOn; | |
} | |
} |
Awesome! Thanks for putting this up.
TcCount16* TC = (TcCount16*) TC3;
TcCount16* is not declared any where
error mesage comming please explain
Awesome code sample, Sheng. This worked for me on the first try on a Feather M0.
I then adapted it to a different timer rate (200Hz) and that worked too.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I'm using a library that has already defined TC3_Handler. Is there another timer I can use on the Adafruit Feather M0? It looks like there is a T4 and T5, but a simple find+replace of T3 didn't work.
Also, where are docs for this?
EDIT: I found another gist that sets up T5: https://gist.github.com/nonsintetic/ad13e70f164801325f5f552f84306d6f. Still curious where docs explaining this are.