I am trying to setup a 250uS interrupt service routine. I have the interrupt working @ 250uS but for some reason the timer stops and restarts. It will run for about 170ms, interrupting the Due every 250uS. Then the interrupt stops happening for some time and then the 250uS interrupt starts again. It just loops doing this. It's almost like the timer isn't auto reloading. Any help
would be appreciated.
I set an output pin when entering the ISR and clear it when I leave. I am in the ISR for just a few microseconds.
I took a bare bones board and put just this code for the ISR in it and get the same results. Interrupt happen regularly for 62ms this time and then stops. Then starts again for 62ms then stops. No other code is running on the Due except the code below.
#include <DueTimer.h>
DueTimer mainInt = DueTimer(4);
void setup() {
// put your setup code here, to run once:
pinMode(14, OUTPUT);
mainInt.attachInterrupt(mainIntSvc).setPeriod(250);// Set timer interrupt
mainInt.start();
}
void loop() {
// put your main code here, to run repeatedly:
}
void mainIntSvc(void) {
digitalWrite(14, HIGH);
digitalWrite(14, LOW);
}
I don't know how the DueTimer library works, but here's how to do it with direct register manipulation. The code calls timer TC6's interrupt service routine every 250us:
// Set timer TC6 to call interrupt service routine every 250us
void setup()
{
PMC->PMC_PCER1 |= PMC_PCER1_PID33; // Enable peripheral TC6 (TC2 Channel 0)
TC2->TC_CHANNEL[0].TC_CMR = TC_CMR_WAVSEL_UP_RC | // Count up with automatic trigger on RC compare
TC_CMR_TCCLKS_TIMER_CLOCK1; // Set the timer clock to TCLK1 (MCK/2 = 84MHz/2 = 42MHz)
TC2->TC_CHANNEL[0].TC_RC = 10499; // Load the RC0 register f = 42MHz / (10499 + 1) = 4kHz (250us period)
NVIC_SetPriority(TC6_IRQn, 0); // Set the Nested Vector Interrupt Controller (NVIC) priority for TC6 to 0 (highest)
NVIC_EnableIRQ(TC6_IRQn); // Connect TC6 to Nested Vector Interrupt Controller (NVIC)
TC2->TC_CHANNEL[0].TC_IER |= TC_IER_CPCS; // Enable interrupts for TC6 (TC2 Channel 0)
TC2->TC_CHANNEL[0].TC_CCR = TC_CCR_SWTRG | TC_CCR_CLKEN; // Enable the timer TC6
}
void loop() {}
void TC6_Handler() // ISR TC6 (TC2 Channel 0)
{
if (TC2->TC_CHANNEL[0].TC_SR & TC_SR_CPCS) // Check for RC compare condition
{
// Add you code here...
}
}
Unfortunately this has the same result as I had. I have attached the code you provided with a image. The bit is set coming into the ISR and cleared when leaving the ISR. I don't know why it stops and restarts. Very weird.
void setup() {
// put your setup code here, to run once:
pinMode(14, OUTPUT);
PMC->PMC_PCER1 |= PMC_PCER1_PID33; // Enable peripheral TC6 (TC2 Channel 0)
TC2->TC_CHANNEL[0].TC_CMR = TC_CMR_WAVSEL_UP_RC | // Count up with automatic trigger on RC compare
TC_CMR_TCCLKS_TIMER_CLOCK1; // Set the timer clock to TCLK1 (MCK/2 = 84MHz/2 = 42MHz)
TC2->TC_CHANNEL[0].TC_RC = 10499; // Load the RC0 register f = 42MHz / (10499 + 1) = 4kHz (250us period)
NVIC_SetPriority(TC6_IRQn, 0); // Set the Nested Vector Interrupt Controller (NVIC) priority for TC6 to 0 (highest)
NVIC_EnableIRQ(TC6_IRQn); // Connect TC6 to Nested Vector Interrupt Controller (NVIC)
TC2->TC_CHANNEL[0].TC_IER |= TC_IER_CPCS; // Enable interrupts for TC6 (TC2 Channel 0)
TC2->TC_CHANNEL[0].TC_CCR = TC_CCR_SWTRG | TC_CCR_CLKEN; // Enable the timer TC6
}
void loop() {
// put your main code here, to run repeatedly:
}
void TC6_Handler() // ISR TC6 (TC2 Channel 0)
{
digitalWrite(14, HIGH);
if (TC2->TC_CHANNEL[0].TC_SR & TC_SR_CPCS) // Check for RC compare condition
{
// Add you code here...
}
digitalWrite(14, LOW);
}