Shop OBEX P1 Docs P2 Docs Learn Events
reality check on creating a millisecond resolution timer using ctra/ctrb — Parallax Forums

reality check on creating a millisecond resolution timer using ctra/ctrb

northcovenorthcove Posts: 49
edited 2009-05-18 17:57 in Propeller 1
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:

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

  • TimmooreTimmoore Posts: 1,031
    edited 2009-05-18 00:08
    I use this technique, though if I remember correctly it came from Phil and Rayman.
    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.
  • northcovenorthcove Posts: 49
    edited 2009-05-18 00:34
    Tim, good points and exactly the feedback I was hoping to receive.

    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!
  • TimmooreTimmoore Posts: 1,031
    edited 2009-05-18 01:25
    I have attached the timer object I use and the test code from when I first wrote it. I was right many of the ideas were·from Rayman and Phil.
    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.
  • northcovenorthcove Posts: 49
    edited 2009-05-18 17:57
    Thanks for that. Nice implementation. One recommendation: have Init take local timezone.
Sign In or Register to comment.