PDA

View Full Version : Can't update CCU4 timer without adding nops between start/stop



jef
Mar 25th, 2013, 08:35 AM
I have a CCU4 slice that is counting external pulses. There is a routine that updates the timer with a new value:



void SetTimer(int NewTimerValue)
{

//Stop the timer
CCU42_CC42->TCCLR = CCU4_CC4_TCCLR_TRBC_Msk;

//Set new value
CCU42_CC42->TIMER = NewTimerValue;

//Start timer again
CCU42_CC42->TCSET = CCU4_CC4_TCSET_TRBS_Msk;

}

This does not work. The timer is not updated with the new value.

To solve the problem I hade to add nops before starting the timer. I testes with looking at the run bit of the timer and not setting the timer until this hade been cleared but this did not work.

The code below works:



void SetTimer(int NewTimerValue)
{

//Stop the timer
CCU42_CC42->TCCLR = CCU4_CC4_TCCLR_TRBC_Msk;

//Set new value
CCU42_CC42->TIMER = NewTimerValue;

Nop();
Nop();

//Start timer again
CCU42_CC42->TCSET = CCU4_CC4_TCSET_TRBS_Msk;

}

The only information in the user manual is that the timer can't be updated while running.

Adding nops works but is there a better or more recomended solution to solve this problem.

Jackson
Mar 27th, 2013, 01:40 AM
Hi jef,

Perhaps you can try External Load function that is available in CCU4 module.
It used an external signal to trigger for reloading the timer value.
The value you want to updated into the timer is preset in the compare register and when the event triggered, it will load into the timer.
Hope this suggestion works for you.

jef
Mar 27th, 2013, 11:49 PM
Your solutions to all problems seems to be to "use external triggers". If the user manual says that it is possible to update the timer as long as it is stopped, it should work without having to be forced to generate external trig signals.

What I would like to know is what causes the problem and the best solution to solve it. Is it a cache problem, pipeline problem, clock domain synchronization problem or what? Without knowing it is hard to know if I need to add other solution in other places where "external triggers" may not be possible.

I did some more tests and found that adding the __DSB(); instruction after the stop of the timer instead of the the nops also solves the problem. So forcing the instruction that stopped the timer to finish solves the problem.


Hi jef,

Perhaps you can try External Load function that is available in CCU4 module.
It used an external signal to trigger for reloading the timer value.
The value you want to updated into the timer is preset in the compare register and when the event triggered, it will load into the timer.
Hope this suggestion works for you.