How many counts does it take for the system counter, cnt, to roll over?
Hi all,
a simple question, the answer of which I can find nowhere in the literature.
According to my calculations, the system counter will roll over after reaching a cnt of 4294967295. Is this correct?
So cnt will go from 4294967295 to 0 as the system counter rolls over?
thanks,
Mark
Post Edited (ElectricAye) : 10/2/2008 9:21:37 PM GMT
a simple question, the answer of which I can find nowhere in the literature.
According to my calculations, the system counter will roll over after reaching a cnt of 4294967295. Is this correct?
So cnt will go from 4294967295 to 0 as the system counter rolls over?
thanks,
Mark
Post Edited (ElectricAye) : 10/2/2008 9:21:37 PM GMT

Comments
-Phil
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
'Still some PropSTICK Kit bare PCBs left!
I knew it was a 32-bit counter but I was afraid it would do something weird like roll over into negative numbers or something.
Carlos, where this roll over phenomenon gets tricky is when you are trying to synch several cogs. If you are using repeat loops in your cogs, for example, and you are incrementing time variables to determine when to do things in synch according to the cnt, if you're not careful, your cnt can roll over on you and do funny things. For example, if you increment a TimeVariable and it happens to exceed 4294967295 whatever the actual rollover value is (see below), then if you have a command that says waitcnt (TimeVariable), the program will never get beyond this point. [noparse][[/noparse]Edit: actually I think I'm wrong about this now that I read what's been written below...]
Mark
Post Edited (ElectricAye) : 10/3/2008 3:34:47 AM GMT
To recap, cnt goes from 0 -> ... -> $7FFF_FFFF (2147483647) -> $8000_0000 (-2147483648) -> ... -> $FFFF_FFFF (-1) -> 0.
Typically, when used with waitcnt, you're only worrying about equality, and the signed arithmetic issue just goes away.
-Phil
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
'Still some PropSTICK Kit bare PCBs left!
Post Edited (Phil Pilgrim (PhiPi)) : 10/2/2008 11:34:04 PM GMT
You mean·about 26 seconds if you are running the Propeller at an 80-MHz system clock, right?
I think newtime-oldtime will always give a positive result, as long as less than 53.69 seconds.
Not so. For example, -1 - 0 is still -1.
-Phil
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
'Still some PropSTICK Kit bare PCBs left!
·
That's true, but that's a case of rolling over after 53 seconds...
Ok, maybe you guys are right...· I guess I didn't appreciate that the difference was only good for 1/2 the range...
Post Edited (Rayman) : 10/3/2008 12:45:06 AM GMT
thanks,
Mark
Adding -1 to a number is the same as adding 2^32-1 because it's 32-bit math with no carry.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·"I have always wished that my computer would be as easy to use as my telephone.· My wish has come true.· I no longer know how to use my telephone."
- Bjarne Stroustrup
Post Edited (Ken Peterson) : 10/3/2008 2:30:53 AM GMT
If you didn't catch it from the above discussion; timing with CNT will always be correct, providing the roll-over is taken into account.
Using "WaitCnt( CLKFREQ / 1000 * ms + CNT )" will give whatever millisecond delay required with the roll-over effect taken into account.
and it will count 50 seconds. There's no 26 second limit. You can't count 54 seconds because clkfreq * 54 is greater than 2^32 (at 80 MHz).
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·"I have always wished that my computer would be as easy to use as my telephone.· My wish has come true.· I no longer know how to use my telephone."
- Bjarne Stroustrup
I'm a little confused. If my cnt happens to be just slightly less than 2^32 when it reaches waitcnt(clkfreq * 50 + cnt) , would not the program get stuck there forever because you are now asking it to wait for a value that the cnt will never achieve due to roll over????
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·"I have always wished that my computer would be as easy to use as my telephone.· My wish has come true.· I no longer know how to use my telephone."
- Bjarne Stroustrup
Thanks, Ken. Yes, I see what you mean. I keep getting confused about this register thing.
With the help of you and others, I think I'm now beginning to map out the continent of my confusion on this issue.
Mark
wooo - what a high-frequent responded threat !
OK once again my elapsed_time_msec-method
that takes care of the unsigned / signed and counter rollover-issues
and a democode showing how to wait AND do other things at THE SAME TIME
comments and sugestions for improvements are welcome
'this democode shows how to wait userdefined amounts of time WITHOUT stopping the whole cog 'you can do other things while waiting CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 VAR long timer1 long eTime1 long timer2 long timer3 PUB Main 'the FIRST PUB-Method inside a spinfile is ALWAYS the startpoint where the program starts to run timer1 := cnt 'make inital snapshot of systemcounter timer2 := cnt 'make inital snapshot of systemcounter timer3 := cnt 'make inital snapshot of systemcounter repeat 'do whatever you like inside this loop 'and what should be done with almost no delay 'the method elapsed_time_msec calculates the time that has gone since 'variable timer1 has set to the (former) value of systemcounter eTime1 := elapsed_time_msec(timer1) if eTime1 => 100 '<== this is the TimePeriod of millisecs that were "waited" 'before the code below is executed timer1 := cnt 'make new snapshot of systemcouner to set new startvalue ' code here what should be executed after the TimePeriod definded in the if condition above if elapsed_time_msec(timer2) => 200 timer2 := cnt 'make new snapshot of systemcouner to set new startvalue 'toggle LED2 or what ever if elapsed_time_msec(timer3) => 400 timer3 := cnt 'make new snapshot of systemcouner to set new startvalue 'toggle LED3 or what ever PUB elapsed_time_msec(p_TimeVar) | RightNow, ClockTicks 'can measure up to 26843 Milliseconds '(2147483647 CounterTicks / 80.000.000 Hz = 26843 Milliseconds) RightNow := cnt if RightNow < p_TimeVar ClockTicks := ||($FFFFFFFF - RightNow + p_TimeVar) else ClockTicks := ||(RightNow - p_TimeVar) result := ClockTicks / (clkfreq / 1_000) 'calculate milliseconds '################################################################################ 'explanation how it works ' SPIN treats longs as SIGNED longs this means bit-No 32 represents the sign "+-" ' the systemcounter thinks of the 32bits as UNsigned meaning bit 32 is ' just another bit of the number and NOT a sign "+-" ' if one or both values are negative it could happen ' that the result is negative too ' the command "||" calculates the absolute value of the SIGNED longs 'even if the systemcounter has wrapped around since the snapshot of 'systemcounter (value of parameter p_TimeVar), 'this method calculates the timedifference in the right way 'wrap-around example with easy numbers: counter maxvalue 1000 'p_TimeVar containing value 980 'time goes on counter wraps around from 1000 to 0 'time goes on 'RightNow containing 300. This means 20 ticks until maximum 1000 and 300 ticks 'since wrapping from 1000 to 0 in summary 320 ticks of time has gone 'this is calculated by MaxCounter - p_TimeVar + RightNow 'in numbers 1000 - 980 + 300 = 320 'the real systemcounter has 32bits max value 2^32 -1 = 4294967295 'hexadecimal $FFFFFFFF '################################################################################ 'end of PUB elapsed_time_msec(p_TimeVar) | RightNow, ClockTicksbest regards
Stefan
Post Edited (StefanL38) : 10/3/2008 4:36:22 AM GMT
Yes, it seems my simple question has had a lot of interesting answers (and still counting!).
Hey, thanks for posting this code. I'll have to study it tomorrow and grok how it works.
cheers,
Mark
WOW, now I see why this topic is causing some confusion!
So if you happen to be trying to synch some cogs using time variables and operators like > and =<, then methinks you could easily get into trouble.