2008-01-22 11:27 AM
Cascading timers overflow handling and capture
2011-05-17 03:21 AM
Dear STOne32,
I tested the AN2592 (32bit timers) and it works well. But the two timers are asynchronously cascaded and not synchronously. I am worrying about the overflow propagating to msb timer could not be handled correctly in combination with asynchronous capture. Just imagine the following situation with master timer(=0xFFFF) and slave timer(=0x0010): 1. Master Timer rolles over (->now = 0x0000) and triggers an Update Event to slave timer 2. A Capture for both master and slave timer occurs Capture master = 0x0000, capture slave = 0x0010 3. the slave increments therafter due to external Mode 1 from 0x0010 to 0x0011 Therefore this would result in a wrong capture result. Could this ever happen? Where a detailed timing diagrams in the reference manual regarding input capture handling in respect to internal clocking? Thanks for your help Andi2011-05-17 03:21 AM
Dear STONe32,
meanwhile I proved with a small piece of software that the overflow problem exists when capturing 32Bit cascaded-timers. So the AN2592 is not giving a correct result when the lsb timer rolls over right in the moment when the capture occurs. How can this be avoided? Best regards Andi2011-05-17 03:21 AM
after the capture, while in the ISR, if the master capture is < some critical low value, then the current slave value instead of the captured slave value should be used to form the 32 bit integer. ISR *must* run in (0xFFFF - ''critical low value'') time measured in master clocks, or this will fail.
you could also handle the case where master > some other critical high value to handle the strange case where carry and capture of slave occurs before capture of master (??!). in that case: if master capture > ''critical high value'' you would read a sequence of current slave-master-slave-master-slave values, select two consecutive slave reads with equal values ''S'' and use the sandwiched master ''M'' value. if M > ''critical high value'' then use S:(captured master), else use (S-1):(captured master) (edited: the forum messed up with my symbols!)[ This message was edited by: lanchon on 22-01-2008 22:28 ]2011-05-17 03:21 AM
Hi lanchon,
I did already solve the problem by software in the ISR. I form the current 32bit value by reading the counter, if the slave changes during the read I read it again. This value is then compared to 32bit captured value. If there is a big difference of say more than 1000 cycles, then capture has lost an overflow in the slave. In this case the slave capture is incremented +1 by software. It works fine but it cost´s me a lot of time in the ISR, so the advantage of a quick hardware capture is almost gone! Thanks for your help Andi2011-05-17 03:21 AM
that only gives 1000 cycles time to process the interrupt, instead of the near 64K achievable, but that doesn't seem to be an issue on your case. for more performance try doing what I described in the first paragraph:
const x = 64; // enough? low = master_capture; high = low < x ? slave_current : slave_capture; probably the performance hit of the test will almost be hidden since otherwise there would be back-to-back peripheral accesses with cpu stalling. (the slave shouldn't be changing since we're after a capture with master between 0 and 63, and the interrupt latency should give the slave plenty of time to ripple.)