Feeling silly...
My timer counter was set up to raise an interupt when the counter value matched RC, which is as most of the timer examples on this forum:
void startTimer(Tc *tc, uint32_t channel, IRQn_Type irq) {
pmc_set_writeprotect(false);
pmc_enable_periph_clk((uint32_t)irq);
tc->TC_WPMR = 0x54494D00;
TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1);
TC_SetRA(tc, channel, 500); // Interupt raised at this value.
TC_SetRC(tc, channel, 400); // Counter resets at this value.
TC_Start(tc, channel);
tc->TC_CHANNEL[channel].TC_IER=TC_IER_CPCS;
tc->TC_CHANNEL[channel].TC_IDR=~TC_IER_CPCS;
NVIC_EnableIRQ(irq);
}
void TC3_Handler() {
....code to execute when timer counter value == RA....
}
startTimer(TC1, 0, TC3_IRQn);
As you can see in that example I had started a timer that would never trigger the interrupt, as it counts upto 400 and then resets to 0 before reaching the timer interrupt of 500. My thinking was that this was a stopped state, and I could dynamically change the value of RC to adjust the frequency.
I could change the value of RC, but only by running the code following:
TC_SetRC(TC1, 0, 400);
TC_Start(tc, channel);
After looking throught the arduino folders I found that TC_Start in it's rawest form (tc.c) is:
TC1->TC_CHANNEL[0].TC_CCR = TC_CCR_CLKEN | TC_CCR_SWTRG ;
TC_CCR is the command register for a particular timer counter. As I wasn't starting the timer, merely trying to force it to reload the value of RC I found that this could be cut back to:
TC1->TC_CHANNEL[0].TC_CCR = TC_CCR_SWTRG ;
This is calling the software trigger which resets the timer. This still causes the difficulty of resetting the timer counter back to zero at the same time. This means that if you call this many times on the trot then it can cause a nice smooth chain of pulses to become irratic.
To address this I've added a pulse_period variable in my main code that I update whenever I like and section to the TC3_Handler that checks to see if it has changed, and if so updates RC and forces a reset.
void TC3_Handler() {
....code to execute when timer counter value == RA....
if (pulse_period != TC1->TC_CHANNEL[0].TC_RC) {
TC1->TC_CHANNEL[0].TC_RC = pulse_period;
TC1->TC_CHANNEL[0].TC_CCR = TC_CCR_SWTRG;
}
}
This isn't quite perfect as this change will take place at RA counts through the timer but it is a lot better than it was before. By making the difference inbetween RA and RC much smaller this effect would be reduced, or I could use the second channel and get that triggered by the RB value.