cancel
Showing results for 
Search instead for 
Did you mean: 

Timer Capture Compare Race Condition

raptorhal
Associate II
Posted on November 11, 2009 at 22:22

Timer Capture Compare Race Condition

6 REPLIES 6
picguy
Associate II
Posted on May 17, 2011 at 13:29

This looks like a special case but it is not. Consider the general case of reading two halves of a running timer, tmrHI and tmrLO.

The procedure is simple:

saveHI=tmrHI

saveLO=tmrLO

Then if another read of tmrHI = saveHI return saveHI:saveLO.

Else...repeat the saves and the test until you return.

But in your case (if you know your ISR will not be interrupted) you know that saveHI+1 = tmrHI. Simply read tmrLO again and you are done. With enough registers saveHI & saveLO do not need to go to RAM until you are done.

If the timers continue to run you will have ISR latency (mostly 12 clocks but sometimes more) added to the time.

I did not check your setup. Is it possible to set things such that your captured event stops timer3 and timer3 overflow bumps timer4. Do that and your interrupt will read stopped timers.

raptorhal
Associate II
Posted on May 17, 2011 at 13:29

The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6Yx&d=%2Fa%2F0X0000000bqm%2FYEKlQ9H9PfSIjmy8B.vZQTJxjVOswnpswlYzf8W5Mc0&asPdf=false
raptorhal
Associate II
Posted on May 17, 2011 at 13:29

picguy:

Your idea was one solution I tried that didn't work. If I repeat the read, all I get is the same wrong answer.

Cheers, Hal

tomas23
Associate II
Posted on May 17, 2011 at 13:29

Check in your oveflow int. whether the CC occured and if the value is around, but less than the ARR register => you got it before OF.

-- or -- raise priority of the timer interrupts, if they are short enough. Delay of hundreds of pulses is nonsense, if the interrupt is not blocked by something with higher priority.

raptorhal
Associate II
Posted on May 17, 2011 at 13:29

Edison:

Quote: Check in your oveflow int. whether the CC occured and if the value is around, but less than the ARR register => you got it before OF.

Response: Creative thinking, but sometimes my processing will use the CC data before the overflow check says the data is wrong. And this is still a crutch to get around a problem that shouldn't exist.

I previously implemented my code design on a TI MSP430F processor which has a very similar timer design, and this problem did not exist there.

Quote: -- or -- raise priority of the timer interrupts, if they are short enough. Delay of hundreds of pulses is nonsense, if the interrupt is not blocked by something with higher priority.

Response: Please check my code. I thought I had made Timer3 the highest priority. My problem occurs even when only Timer3 CCs are occurring. To get minimum blockage between interrupts, I bypassed the Library for the CC and OFlow interrupt service routines.

When you say hundreds of pulses, I presume you mean hundreds of ARR register counts. I am not getting delays of hundreds of CC interrupt pulses.

Cheers, Hal

raptorhal
Associate II
Posted on May 17, 2011 at 13:29

With edison's insight, my problem is 99% solved. I had not set NVIC priority groupings, so the Timer2 loop doing extensive data sampling was blocking the Timer3 and 4 interrupts.

I still have an infrequent race condition when the capture happens one count before counter overflow update. The overflow update interrupt apparently has higher priority than the capture interrupt. In retrospect, that is not suprising, since that is the default priority scheme for Timer1 and Timer8.

I will try software fixes to the problem. If that doesn't work, I will try Timer1 and 8 with their resettable priorities.

Cheers, Hal