Implementing a 32-bit input capture timer

Go To Last Post
22 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm trying to figure out all of the nitty gritty details surrounding implementing an input capture timer that has > 16 bit resolution. I want to use the timer 1 input capture unit, but I also want to accurately account for timer overflows.

 

I've read this forum post:

 

https://www.avrfreaks.net/forum/at90can128-32-bit-timer

 

but it's not clear if the last proposed solution is correct. I've also read app note AVR135:

 

https://www.microchip.com/wwwAppNotes/AppNotes.aspx?appnote=en591541

 

but that seems to assume that the next event will happen within 64K clocks of the last event, so there's no need to keep track of timer1 overflows.

 

For concreteness let's make the following assumptions:

 

- CPU is a atmega328 running at 8 MHz

- the TIMER1 prescaler is 1

- the event being timed is greater than a couple of microseconds but could be up to a few seconds in length so a 24 or 32-bit counter would be needed to hold the timer value.

- only one event duration needs to be measured - although it would be nice if the timer could be kept running so that you could record the times of subsequent events; again, you can assume that the time between events will be at least a few microseconds

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How fixed is your CPU choice? I think some of these later AVRs that have appeared in the last couple of years may have the ability to gang their timers.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm not fixed on the 328 and am open to using other cpus.

 

It would be valuable to know whether is it feasible or not on the popular devices such as the 328 or atemga2560.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The easiest way would be to use one of xmegaA to xmegaE. These use an event system to cascade 16-bit timers, resulting in a 32-bit timer.
Other AVR8 chips cannot completely eliminate the slightest concern in overflow.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Could you use two timers? A 16-bit unit with a /1 prescaler and an 8-bit one with a /256 prescaler? I'm on a mobile at the moment so looking at datasheets is not easy so it might be a stupid idea.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Interesting idea. I think you'd want the 8-bit timer to have the /1 prescaler and the 16-bit timer to have /256. That would give you a 24-bit counter.

 

As far as I can tell, though, the 328 only has one input capture unit (for timer 1).

 

The 2560 has multiple input capture units and multiple 16-bit timers, so it looks like you could drive one at /1024 and another at /1 which would give you 26 bits.

 

So that raises another question... is it possible to start two timers at exactly the same time?

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ledtester wrote:
is it possible to start two timers at exactly the same time?

Yes if they share the same prescaler like T0 and T1, see section 17.4.1, bit 7 sync mode for details.

Jim

 

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm not sure why you can not use an overflow interrupt to extend your 16 bit count to 24 or 32 bits, and then in the input capture interrupt include this extended count with your IP count. 

I could see where there may be an added overflow if IP capture was close to $FFFF, but you could test for that and decrement your extended count by one.  It would all depend on how fast your were clocking T1.

You could also tie T1's output capture to T0's external input clock to extend the count to 24 bits, then in the input capture ISR() grab T0's TNCT and the contents of T1's input capture reg.

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ki0bk wrote:

ledtester wrote:
is it possible to start two timers at exactly the same time?

Yes if they share the same prescaler like T0 and T1, see section 17.4.1, bit 7 sync mode for details.

Jim

 

Thanks! I found it in section 18.4.1 (2560 docs) - the TSM bit in the GTCCR register seems to be made exactly for this purpose.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ledtester wrote:
Thanks! I found it in section 18.4.1 (2560 docs) - the TSM bit in the GTCCR register seems to be made exactly for this purpose.

That said, "input capture" usually implies a delta between events.  So why would it matter if two times are started at exactly the same time?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:

That said, "input capture" usually implies a delta between events.  So why would it matter if two times are started at exactly the same time?

 

In this particular case the idea is to combine two 16-bit timer/counters to create a 26-bit input capture timer. One counter will run with a prescaler of /1024 and the other with /1. The input signal will be routed to both input capture pins on the mcu so that the desired event will trigger the input capture units of the two counters at exactly the same time.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ki0bk wrote:

I'm not sure why you can not use an overflow interrupt to extend your 16 bit count to 24 or 32 bits, and then in the input capture interrupt include this extended count with your IP count. 

I could see where there may be an added overflow if IP capture was close to $FFFF, but you could test for that and decrement your extended count by one.  It would all depend on how fast your were clocking T1.

You could also tie T1's output capture to T0's external input clock to extend the count to 24 bits, then in the input capture ISR() grab T0's TNCT and the contents of T1's input capture reg.

Jim

 

The last time I tried this, I ran into problems. I can't remember exactly why, but it was to do with overflow interrupts happening while the ICP interrupt was being serviced. There may be a foolproof way round it, but I didn't find it.

 

Four legs good, two legs bad, three legs stable.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ledtester wrote:
The input signal will be routed to both input capture pins on the mcu so that the desired event will trigger the input capture units of the two counters at exactly the same time.
theusch wrote:
"input capture" usually implies a delta between events.  So why would it matter if two times are started at exactly the same time?

==================

On another note, about "increasing resolution".  Please tell more about what you are trying to measure. How does a /1024 "increase resolution"?  An AVR8 timer can masure down to one clock tick; one timer tick at /1.  If you choose to run at a sedate 8MHz (with the less-than-real-accurate internal clock?) then the resolution is 125ns, right?  You can cascade n timers, and the resolution is still 125ns, right?

 

To increase the range, simply count overflows.  The resulting counter is essentially the same as what you are doing, with the "coarse" being /65536 of the "fine".

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Tue. Sep 10, 2019 - 11:21 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Only T1 has an input capture reg!
Jim

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:

How does a /1024 "increase resolution"? 

...

To increase the range, simply count overflows.  The resulting counter is essentially the same as what you are doing, with the "coarse" being /65536 of the "fine".

 

Perhaps "resolution" is not the right word here. I think the initial post in this thread adequately describes the problem. If you have a rock-solid method of accounting for overflows during input capture I'd like to hear it. As the discussion I referenced in the initial post suggests, it doesn't seem to be entirely straight forward.

 

ki0bk wrote:

Only T1 has an input capture reg!

On the 328, yes, but on the 2560 there is ICR3, ICR4 and ICR5 -- section 17.11.29-32, page 161 in the [url=http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2549-8-bit-AVR-Microcontroller-ATmega640-1280-1281-2560-2561_datasheet.pdf]datasheet[/url] or am I missing something?

 

 

 

 

Last Edited: Tue. Sep 10, 2019 - 04:14 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Go on.   It is pretty straightforward.

 

Run Timer1 with OVF interrupt.   The ISR() counts overflows.

Use Capture to start on one edge.   End on the other edge.  The ISR() alternates the edge.  Saves the start capture (+ overflows) in one variable.  Saves the end capture in another variable.   

 

The hardware will be working 100% perfectly.   It does not matter how quickly ISR()s are serviced or even if they collide.

 

Your "capture period" is simply end - start.    uint32_t subtraction will give you the correct result.

 

Yes,   you could have an event coinciding with an OVF.    But you simply have to examine the capture 16-bit value.    If it is near 65535 you might have had an OVF arriving "after" the Capture.    It is pretty easy to distinguish.

 

Think about it.    You can look at the clock on the wall.  It says 17:32 at the moment.    I "know" that it is Tuesday.

If I took a snapshot of the clock at 23:59 or at 00.01 I can make a good guess as to whether it is Tuesday or Wednesday.

 

David.

Last Edited: Tue. Sep 10, 2019 - 04:37 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1


Can't help wondering if you missed these posts?:

clawson wrote:
I think some of these later AVRs that have appeared in the last couple of years may have the ability to gang their timers.

kabasan wrote:
The easiest way would be to use one of xmegaA to xmegaE. These use an event system to cascade 16-bit timers, resulting in a 32-bit timer.

 

 

http://ww1.microchip.com/downloads/en/AppNotes/doc8045.pdf

 

it's quite possible that the new/extensive AVR-0/AVR-1 range of chips, that derive from Xmega (some called "Xtiny"), inherit some of these features.

 

If you are still at the design stage I don't see much point picking an inappropriate chip for the job at hand then beating yourself up trying to "make it work somehow" when you could simply pick the right chip for the job to start with.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I once built a 32-bit capture with 32MHz (31.25nS) time resolution in xmegaA.
However, as far as I can see, this function does not seem to be inherited in AVR-0 / AVR-1.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Even if you cascade two 16-bit Timers,  the Capture is still 16-bit.

 

So you still have to distinguish between 23:59 on Tuesday or Wednesday.   This is not difficult.   The Capture ISR() has a known priority versus OVF on an AVR.

 

Of course you can use an ARM chip with 32-bit Capture.    Note that ARM peripherals vary greatly between different makes and models.

 

Quite honestly,  16-bit Timer with OVF interrupt works just fine.    (if you check for the midnight case)

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The xmega cascading timer is very careful about the lower 16bit overflow, so you don't need to be aware of 23:59 after proper initialization.

 

This is an xmegaA 32bit capture interrupt routine that I am actually using.
In order to confirm that the problem does not occur, the read order is deliberately set from upper.

////////////////////////////////////////////////////////////////
// 32bit capture A
////////////////////////////////////////////////////////////////
ISR(TCE0_CCA_vect){
    ccah = TCE0.CCA;    // Upper 16bit read
    ccal = TCD0.CCA;    // Lower 16bit read
    f_capt = true;
}

I like it very easily.

Last Edited: Wed. Sep 11, 2019 - 11:19 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

ledtester wrote:
If you have a rock-solid method of accounting for overflows during input capture I'd like to hear it. As the discussion I referenced in the initial post suggests, it doesn't seem to be entirely straight forward.
It does indeed require a bit of thinking.  Handling the overflows has been discussed over the years.  I've got an industrial app at 20MHz and max resolution that doesn't miss anything, and the input signal can be several hundred kHz.

 

IMO, just a guess, you will have more problems fussing with two timers than counting overflows.  Other veteran 'Freak opinions seem to concur.

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am probably barking up the wrong tree. The thing I had problems with was a slightly different scenario, whereby I was using the external clock input to a timer to count pulses of around 4MHz over a period of 100mS. It's also probably doable, but it certainly gave me a headache.

Four legs good, two legs bad, three legs stable.