reality check on creating a millisecond resolution timer using ctra/ctrb
northcove
Posts: 49
Hi everybody,
I wish to create a millisecond-resolution timer that doesn't require its own cog (cogs are precious & finite resources!) Given the functionality of ctra/ctrb, this seems easy to do: accumulate phsa such that bit 31 toggles at 1kHz and then count those toggles using ctrb. Here's the code I have so far:
This code appears to do the job however I see several possible drawbacks:
- a pin is required for phsa[noparse][[/noparse]31] output
- accuracy is subject to crystal stability (probably okay for my application)
- there is a teensy error introduced because $80000000 cannot be evenly divided by clkfreq.
- the timer will roll over after 49.7 days.
- why don't any other timing classes in the obex use this technique...some impls create a cog that waitcnts to increment a counter.
Anybody have any recommendations?
Thanks,
Christopher
I wish to create a millisecond-resolution timer that doesn't require its own cog (cogs are precious & finite resources!) Given the functionality of ctra/ctrb, this seems easy to do: accumulate phsa such that bit 31 toggles at 1kHz and then count those toggles using ctrb. Here's the code I have so far:
con strobe_pin = 11 pub ms_timer_test dira [noparse][[/noparse] strobe_pin ]~~ 'set output for phsa[noparse][[/noparse]31] ctra [noparse][[/noparse] 30..26 ] := %00100 'output phsa[noparse][[/noparse]31] ctra [noparse][[/noparse] 5..0 ] := strobe_pin 'specify output pin frqa := $8000_0000 / ( clkfreq / 2_000 ) '1K Hz pos edge freq ctrb [noparse][[/noparse] 30..26 ]:= %01010 'count pos edges on pin ctrb [noparse][[/noparse] 5..0 ] := strobe_pin frqb := 1 'at this point phsb will be counting (approximately) milliseconds
This code appears to do the job however I see several possible drawbacks:
- a pin is required for phsa[noparse][[/noparse]31] output
- accuracy is subject to crystal stability (probably okay for my application)
- there is a teensy error introduced because $80000000 cannot be evenly divided by clkfreq.
- the timer will roll over after 49.7 days.
- why don't any other timing classes in the obex use this technique...some impls create a cog that waitcnts to increment a counter.
Anybody have any recommendations?
Thanks,
Christopher
Comments
You can remove the error from $80000000 by using a trick from Phil of using a frqa of 256 and then calculate ms by multiplying the phsb by $35AFE535
Other issues is the time is only available in that COG since the counters are only available there. I use an existing cog that is polling a bunch of stuff (sensors), to query the counters and store the time in hub memory for other cogs - you lose accuracy depending on the polling period do this. It also calculates seconds, etc so it doesn't have the 49.7 day roll over problem.
Like yourself I'm polling a bunch of stuff in the caller cog. It can also periodically copy phsb into hub memory for other cogs to read.
I can only hope that my project will run long enough between reboots that the rollover after 49.7 days will be an issue!
I added some extra stuff to correct for delays in updating counters across cogs - uses the diff of cnt value from the counter poll to the cnt when time is obtained to update the ms to higher accuracy.