Peripheral Timer Configuration for Atmel SAM3X8E With FreeRTOS on Arduino Due

jjkind wrote on Friday, October 18, 2019:

I am trying to use the hardware timer peripherals on the Arduino Due (Atmel SAM3X8E) with FreeRTOS. I can setup a bare project without FreeRTOS and get TC8 working using the following code:

Here’s my code for setting up Timer2, Channel2 (TC8) in my FreeRTOS project:

//Enable TC2 Timer Channel 2
PMC->PMC_PCER1 |= (1<<(ID_TC8 - 32));

//Setup Channel Mode Register for TC2 - Channel 2
TC2->TC_CHANNEL[2].TC_CMR = TC_CMR_WAVE |				    
							TC_CMR_TCCLKS_TIMER_CLOCK2 |	
							TC_CMR_WAVSEL_UP |			
							TC_CMR_ACPC_TOGGLE |
							TC_CMR_CPCTRG;

TC2->TC_CHANNEL[2].TC_RC = 52500000;

//Enable interrupt for the timers
TC2->TC_CHANNEL[2].TC_IER = TC_IER_CPCS;

//Enable interrupts for TC8 in NVIC
NVIC_EnableIRQ(TC8_IRQn);

//Enable TC2 channel 2
TC2->TC_CHANNEL[2].TC_CCR = TC_CCR_CLKEN | TC_CCR_SWTRG;

//Handler code
void TC8_Handler()
{
xSemaphoreGiveFromISR(xSemaphore, pdFALSE);
uint32_t read_n_clear = TC2->TC_CHANNEL[2].TC_SR;
}

The xSemaphoreGiveFromISR code does not seem to be getting called.

My question is this:

  1. Is there a special way to setup the Timer2/Channel2 Peripheral via FreeRTOS API? Or is the code above (ASF API) OK?

  2. Can I use TC8_Handler as is? Or again is there a special handler to use for timer peripherals in the FreeRTOS API?

richard_damon wrote on Friday, October 18, 2019:

I don’t know that processor so this is just some generic advice, your call to xSemaphoreGiveFromISR looks wrong. the last parameter you are giving as ‘pdFALSE’ is supposed to be a pointer to a variable which the call will set to indicate the the scheduler should be run at the end of the ISR as a task was woken up. pdFALSE will have the value 0, so this looks like a null pointer, which is syntactly correct, but is an indicaation that your ISR intentionally either knows that it can’t be wakeing up a new higher priority task, or doesn’t care, or something of that like. You should look at the documentation for the function to see exaples of how this is done. The exact way you call the scheduler can vary a bit port to port.

Another possibility is that the interrupt has too high of a priority (which for Arm Cortexes means too low of a number, and they often default to 0) and FreeRTOS is catching in an assert or otherwise breaking.

rtel wrote on Friday, October 18, 2019:

The last parameter in xSemaphoreGiveFromISR() is optional, so NULL
(pdFALSE in this case, but as you point out, that is the same thing) is
a valid parameter and means no variable is being passed in. The
consequence of that is that a switch to a ‘higher priority task that was
woken’ will not happen until the next tick interrupt (or the current
task blocks).