FlexBASIC feature request

I do this a lot:
Or is this the way to do it?:
Would there be problems with getcnt() rollover?
'set timeout to 5ms
timeout = timer + 5
do
if timer > timeout then exit do
loop
Or is this the way to do it?:
timeout = getcnt() + (clkfreq/200)
do
if getcnt() > timeout then exit do
loop
Would there be problems with getcnt() rollover?
Comments
timeout = clkfreq / 200 timestart = getcnt() do if getcnt() - timestart > timeout then exit do loop
This way even if the subtraction spans a rollover, the result will still be positive and compare properly against the timeout value.
I still need a general purpose ms timer as I like to monitor the response times of many actuators for diagnostic purposes.
One of my processes only needs a 1ms scan so I think I will increment a variable in that cog, after a waitcnt and use that as a reference
If I name it Timer:
Micromite BASIC has a 64bit ms counter which I would never have to worry about but I still zero it because I can
pub millis() : result | now0, now1, cf org getct now1 wc ' snapshot 64-bit cnt register getct now0 stalli ' hold interrupts during division rdlong cf, #$44 ' read ticks per second qdiv cf, ##1000 ' calc ticks per ms getqx cf allowi ' enable interrupts nop ' let interrupts be processed stalli setq now1 ' divide system counter by ticks/ms qdiv now0, cf getqx result allowi end
Since FlexBASIC allows inline assembly, you should be able to adjust this -- I don't know FlexBASIC well enough to do that. I have tested this method in Spin and it works (it's based on Chip's code getsec() code in the interpreter).function millis() as uinteger asm getct arg02 wc ' snapshot 64-bit cnt register getct arg01 stalli ' hold interrupts during division rdlong arg03, #$44 ' read ticks per second qdiv arg03, ##1000 ' calc ticks per ms getqx arg03 allowi ' enable interrupts nop ' let interrupts be processed stalli setq arg02 ' divide system counter by ticks/ms qdiv arg01, arg03 getqx result1 allowi end asm end function
It compiles, but always returns 0. Looking at the new listing I see why: the compiler replaces the getqx result1 line with mov result1, #0.005dc | ' function millis() as uinteger 005dc | _millis 005dc | ' 005dc | ' asm 005dc 1A FA 70 FD | getct arg02 wc 005e0 1A F8 60 FD | getct arg01 005e4 24 42 60 FD | stalli 005e8 44 FC 04 FB | rdlong arg03, #68 005ec 01 00 00 FF 005f0 E8 FD 14 FD | qdiv arg03, ##1000 005f4 18 FC 60 FD | getqx arg03 005f8 24 40 60 FD | allowi 005fc 00 00 00 00 | nop 00600 24 42 60 FD | stalli 00604 28 FA 60 FD | setq arg02 00608 7E F8 10 FD | qdiv arg01, arg03 0060c 24 40 60 FD | allowi 00610 00 EA 04 F6 | mov result1, #0 00614 | _millis_ret 00614 2D 00 64 FD | ret
I don't know why. It seems odd that the compiler would arbitrarily change inline assembly code. Maybe Eric can assist -- or even add the millis() function to FlexBASIC.
Hey Jon.
Isn't that solution still prone to falling into the rollover trap?
BTW, congrats on the excellent N&V article. If it was mentioned here then I missed it. I found the link on another forum.
The bonus was the comments section 😂😂😂. Some guy made a snide remark and I'm pretty sure the reply came from @ManAtWork, right? It was brilliant
As they say; the article needs to go viral
Using the 64-bit version of cnt gives you more range -- but you have to do this from assembly. You can use the lower half of cnt (getct() in the P2) if your events are very short. I run at 200MHz, so using the lower half of cnt means I have to access that register faster than every 21.4s, otherwise I will get a roll-over error.
I'm glad you enjoyed the article.
function millis() as uinteger dim as uinteger now1, now0 dim as uinteger cf dim as uinteger ms asm getct now1 wc ' snapshot 64-bit cnt register getct now0 rdlong cf, #20 ' read ticks per second qdiv cf, ##1000 ' calc ticks per ms getqx cf setq now1 ' divide system counter by ticks/ms qdiv now0, cf getqx ms end asm return ms end function
Once I defined local variables and looked in the right place for the system frequency (I checked the listing file for getsec()), it came together.Ironically, there is a builtin _getms() function, but I forgot to document it and/or provide an alias for BASIC. @Mickster : Jon's function above should work, or you could call "_getms()" (underscore at the beginning) which does the same thing: provides a 32 bit millisecond timer.
The next version of FlexBASIC will have a "getms()" function (no underscore). The underscore version will continue to be supported.
See this thread: http://forums.parallax.com/discussion/172453/free-running-timer-in-the-spin-interpreter-cog#latest
With FlexBASIC, you could probably do something similar by creating a timer cog with access methods that suited your needs. Given that the Flex system compiles to native PASM, you don't have the Spin cog like I do to install an ISR within.
@JonnyMac
Thanks guys, it's all looking great.
Away working right now. Didn't bring my Prop stuff (easily sidetracked)