Long Timers: How To Ensure Coherency

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

Long Timers: How To Ensure Coherency

4,803 Views
ewhac
Contributor I
We have an application requiring fine-grained, long-duration timers. As such, we need to maintain a 32-bit tick count. The obvious implementation is to have an ISR handling overflows from TPMCNT, and then to read the entire 32-bit count as follows:
seilda TPMCNTLsta ticks+3lda TPMCNTHsta ticks+2lda TPM_overflow+1sta ticks+1lda TPM_overflowsta tickscli

The problem is between the 'sei' and the 'lda TPMCNTL'. It's conceivable that TPMCNT could overflow between those two instructions. TPM_overflow will then need to be incremented, but it won't because of the 'sei', making the lower 16 bits incoherent with the upper 16 bits. Swapping the instructions doesn't fix it; it just changes the "polarity" of the vulnerability.

Anyone know how to do long timers reliably?

Schwab

Labels (1)
0 Kudos
Reply
10 Replies

908 Views
bigmac
Specialist III
Hello Schwab,
 
I might suggest the following sequence would provide coherent operation -
  1. Disable interrupts, and read TPMCNTH and TPMCNTL as you currently do.
  2. Check whether overflow flag is set - if so an overflow interrupt is pending.
  3. If no interrupt pending, or TPMCNT value is $FFFF, simply read the higher order value.
  4. If interrupt is pending, and TPMCNT value is $0000, increment the higher order value before reading, and clear the overflow flag.
  5. Re-enable interrupts and exit.
Regards,
Mac
 
0 Kudos
Reply

908 Views
rocco
Senior Contributor II
Sorry, Mac, but there is one situation where that fails:

If the overflow flag sets AFTER he has reads the counter, but BEFORE he tests the flag, the 32 bit value will be wrong. The low 16 bits will be pre-overflow, and the high 16 bits will be post-overflow.

I can't think of any way to do this without doing a check on the value read from the counter. Almost exactly like you described, but also qualifying the increment decision with the most significant bit of the counter.

This is a tough problem . . .

--------------------------- little later:

Ok, I see that you ARE qualifying the decision with the count value. However, a test for $0000 or $FFFF may not be adequate for a fast counter, as the counter can increment a few times in the course of one instruction. Again, a test of the msb should work.

Message Edited by rocco on 2007-02-0102:28 PM

0 Kudos
Reply

908 Views
ewhac
Contributor I
So, the random off-the-cuff thought I've had to "solve" this runs as follows:
    sei    lda   TPMCNTL    sta   ticks+3    lda   TPMCNTH    brclr TPMSC_TOF, TPMSC, normal    ; Overflow; resample.    cli            ; Allow interrupt to fire, increment TPM_overflow.    sei    lda   TPMCNTL  ; Resample the timer    sta   ticks+3    lda   TPMCNTHnormal:    sta   ticks+2    lda   TPM_overflow+1    sta   ticks+1    lda   TPM_overflow    sta   ticks    cli    rts

In other words, we solve the problem by ignoring it Smiley Happy. This approach probably consumes no more time than fancy comparisons against $0000 and/or $FFFF, and probably less. For extra speed, we could increment TPM_overflow and clear TOF inline, rather than letting the ISR actually execute.

Unless anyone sees anything obviously and horribly wrong with this, this is the approach I plan to take.

Schwab

0 Kudos
Reply

908 Views
thisobj
Contributor III
Hello ewhac,

I recall going through this process some time back. I don't think there is any way to guarantee coherency without considering the state of both the TOF and the CHxF (channel interrupt flag). I found the following pub of great assistance:

EB389/D at the following link:

http://www.freescale.com/files/microcontrollers/doc/eng_bulletin/EB389.pdf?fsrch=1

Hope this helps.

Frank
0 Kudos
Reply

908 Views
bigmac
Specialist III
Hello,
 
My understanding of  EB389 is that it pertains to timer overflow with respect to input capture measurement only - not quite the same issue as the present problem.
 
However, it does raise the observation that a timer channel interrupt (or any other interrupt) may delay the execution of the timer overflow ISR.  This then gives the possibility that TPMCNT may have advanced by many cycles by the time the "main" code is processed.  But this shouldn't really be an issue since the overflow flag will definitely be set, and the overflow ISR will execute before the main code does - of course the timer value read will reflect the delayed result.  These potential delays are a limitation of method.
 
I would concur with Rocco about testing the state of the MS bit of TPMCNTH, however I would also note that there must be in excess of 256 TPM clock cycles delay for the high byte to actually become non-zero.
 
The alternative of re-enabling interrupts if the timer overflow flag is set should also work.
 
If attempting to time an external events, greater accuracy will be achieved using an input capture channel (and EB389 considerations would then apply).
 
Regards,
Mac
 
0 Kudos
Reply

908 Views
thisobj
Contributor III
Schwab,

Your 2nd method looks good. I don't see any problem with it.


Mac,

Yes, EB389 specifically mentions input capture, but the "early TOF" issue is relevent to any function that relies on the state of the TOF bit. With that said, I re-read the document and noticed that it pertains to the 'HC08 series--NOT the '9s08. I was most surprised to see that the TOF is handled differently in these two families as follows:

'HC08 -- TOF is set when the free-running count EQUALS the value in the modulo registers. The next (timer) clock pulse will cause the count value to rollover to H'0000. This scenario is referred to as "early TOF" and is most awkward with very slow timer clocks.

'9S08 -- TOF is set on the next timer clock pulse AFTER the timer count matches the modulo register value (rolls over to H'0000). There is no "early TOF" issue.

Unfortunately, this is not mentioned in "AN2717--MC68HC08 to HCS08 Transistion", which describes the differences between the two families. Most likely, there would be few consequences in moving timer routines from 'HC08 to '9S08, but timer routines moved from '9S08 to 'HC08 could have problems.

Frank
0 Kudos
Reply

908 Views
peg
Senior Contributor IV
Hi all,
 
I have come in on this late, it pricked up my ears as it may explain a little issue I have never got to the bottom of. The HC08GP32 manual says that TOF is set when "the counter resets to $0000" which is apparently wrong. The GP32A manual says "reaches modulo value" (apparently correct).
 
However, Franks observation that S08 corrects this seems not quite correct either.
 
S08GT16 - "reaches modulo value"
S08GT16A - "changes to 0x0000 after reaching the modulo value"
 
If this is indeed true then it is not mentioned in the GT16 to GT16A transition documentation!!!
 
No time to actually confirm this with hardware at the moment.
I wonder if the simulator knows about this???
 
Regards
Peg
 
0 Kudos
Reply

908 Views
thisobj
Contributor III
Hi Peg,

I tested the 'S08's timer overflow scenario on a DEMO9S08QG8 board. Even with a (relatively) slow timer clock, upon entering the Timer Overflow isr, the count is always H'0000; never H'ffff or any other non-zero value. I tested in the default free-running mode and also with values, H'fff0 and H'0ff0 values in the modulus register.

The document, MC9S08QG8.PDF on page 231 reads as follows:

(begin quote from manual)
"TOF - Timer Overflow Flag — This flag is set when the TPM counter changes to 0x0000 after reaching the modulo value programmed in the TPM counter modulo registers. When the TPM is configured for CPWM, TOF is set after the counter has reached the value in the modulo register, at the transition to the next lower count value."
(end quote from manual)

The only document I have for the S08GT16 is MC9S08GB60.PDF (12/24), which includes the SO8GT16. It states that the TOF bit is set on the transition to H'0000.

Regards,

Frank
0 Kudos
Reply

908 Views
bigmac
Specialist III
Hello all,
 
This difference between the TIM and the TPM timers would also have an effect for unbuffered PWM.
 
For the HC08 devices, the pulse width is one more period than the channel register value would suggest - because the output pulse commences on timer overflow, when the count reaches the TMOD value.  This situation can be handled by decreasing the channel register value, and with zero duty cycle requiring special processing (by disabling toggle on overflow).  To my observation, the PWM pulse width error does not seem to have been documented in the 'HC08 data sheets.
 
It would now appear that TPM based 'S08 devices may not require a similar adjustment (for edge aligned PWM).  Perhaps the difference was necessary with the inclusion of centre aligned PWM mode for the TPM.
 
With respect to the subject of the original post, the testing of the high byte of the timer counter, as already suggested, would seem to cater for either timer scenario.
 
Regards,
Mac
 
0 Kudos
Reply

908 Views
peg
Senior Contributor IV
Hi Frank,
 
I fear my brain is still in holiday mode. I think I looked in the HC908GT16 manual to get this quote even though I am well aware the only manual for non-A GB/GT's is the GB60 one. So it looks like all the S08's may have this issue corrected although you can still get the old way in some (all?) with the CPWMS bit.
 
Regards
Peg
 
0 Kudos
Reply