LPC1768 TIM strange behavior when STOP and RESET is requested at match event without ever erasing the IRQ flag

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC1768 TIM strange behavior when STOP and RESET is requested at match event without ever erasing the IRQ flag

692 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by 0xdeadbeef on Wed Apr 23 11:20:42 MST 2014
In a project I'm using a timer like this (my own code looks different due to macros etc, but functionally this should be identical):

LPC_TIM3->MR0 = 6000; // match at 6000 ticks
LPC_TIM3->IR = 1;     // clear MR0 interrupt flag
LPC_TIM3->CTCR = 0;   // timer mode
LPC_TIM3->MCR = 7;    // interrupt on match, stop timer on match, reset timer on match
LPC_TIM3->TCR = 1;    // enable timer

Note that in my real program, the write access to TCR to start the timer is done via DMA.
Furthermore, the interrupt request actually triggers another DMA transfer, so there is no interrupt handler and the interrupt request flag is never cleared.

Now while this seems to work exactly as expected, I have cases where I want to update the match register.
To do this in a safe way, I first disable the DMA transfer that could restart the timer. Then I want to make sure that the last match already happened by
waiting until the timer is stopped/reset (note that I can't use the interrupt flag as this is always set due to the absence of an interrupt service routine).

According to the manual, the enable bit in TCR should be erased and TC should be 0 after the match:

Stop on MR0: the TC and PC will be stopped and TCR[0] will be set to 0 if MR0 matches the TC.
Reset on MR0: the TC will be reset if MR0 matches it.

However when I try to poll for either ((TCR1 & 1) == 0) [timer was disabled] or (TC==0) [timer was reset], I'm stuck in an endless loop sooner or later.
If I break there, I can see that the TC==MR0==6000 and TCR=1. So the match occurred and TC is not changing anymore, but neither was the timer
reset nor was the enable bit erased - even though the timer is obviously stopped.
Only when I also erase the interrupt service flag inside my polling loop, the enable bit is really always erased.

Even then though, the TC is not (always) reset and I have to do it manually to avoid hangups.

I can't find any hint in the manual that there reset/stop is only correctly performed when the IR flag is reset or that the combination of STOP and RESET
doesn't work reliably. So is this a flaw or the way it should be???
Labels (1)
0 Kudos
2 Replies

580 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by 0xdeadbeef on Thu Apr 24 10:14:23 MST 2014

Quote: wmues
I do not know if "stop timer on match" and "reset timer on match" are designed so that they can be used together.


Well, they should. At least I need that to work for my usecase. I wouldn't care if the timer is only reset after it is started again (which I assume is what happens during normal operation).


Quote: wmues
Try to use only "stop timer on match". You can reset the timer per software later.


There is no need for this as the timer itself works as expected. It's just that polling for the timer being stopped doesn't work as it should - which I only need to avoid inconsistencies during period updates.


Quote: wmues
Have you tried to clear the interrupt service flag via DMA?


I don't see really how this would help.
In a nutshell: I don't want to fiddle with other workarounds. I want to know why the TIM peripheral doesn't work as described in the manual or if I'm missing some details. The intention is to implement a solution that will always work - not one that works by chance.
0 Kudos

580 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by wmues on Wed Apr 23 23:57:52 MST 2014
I do not know if "stop timer on match" and "reset timer on match" are designed so that they can be used together.
Try to use only "stop timer on match". You can reset the timer per software later.

Have you tried to clear the interrupt service flag via DMA?

regards
Wolfgang
0 Kudos