Timing blocks of code with waitms in SPIN2
jay_harlow
Posts: 43
I'm using a P2 Eval board, revision C,
I'm expecting to see:
` set command mode.started: 30_000_000 microseconds
something just over 30 seconds
instead, I'm seeing
` set command mode.started: 1 microseconds
Code taken from the P2 Spin manual
{Object_Title_and_Purpose}
CON
_clkfreq = 250_000_000
_txpin = 16 + 6
PUB main() | time
time := getct()
pinlow(_txpin)
waitms(30_000)
pinfloat(_txpin)
time := getct() - time
time := muldiv64(time, 1_000_000, clkfreq)
debug("set command mode.started: ", sdec(time), " microseconds")
Comments
At 250 MHz, the number of ticks elapsed will exceed 32 bits in a bit over 16 seconds. So getct() alone will not be useful for timing intervals longer than that.
In addition to Eric's point about the getct() delta, the waitms() instruction is limited by the clock speed. This is from an article I wrote for Nuts & Volts magazine.
(https://www.nutsvolts.com/magazine/article/an-introduction-to-the-parallax-propeller-2)
For a 250MHz clock, the maximum delay will be about 8.589 seconds, or 8_589 milliseconds, or 8_589_934 microseconds (yes, I tested)
The -40 accounts for the getct() instruction time. I have timing constants at the top of my programs that look like this:
@JonnyMac @cgracey : Does the standard PNut waitms() not handle long waits? It's not hard to make it work right up to 2 billion milliseconds (~23 days) by just waiting 1 second at a time, with the last one being a fractional second. With a bit of care about signed/unsigned arithmetic that can be doubled.
The current interpreter gets the clock frequency, divides by 1000 (waitms) or 1000000 (waitus) and then multiplies that by the user parameter for use by waitct. it's not ideal, but it's what we have.
What do you think?
sample code of my stopwatch object. call sw.reset at the beginning of the code you want tested; use sw.elapsed at the end of the code you want tested...
The stop watch object
I wrote similar code a couple years ago -- before getms() was available in Spin2. Seeing your code I got mine back out and did a clean-up, especially as I have a new project coming that needs long-duration timing. What you call reset(), I call start(), and I allow an offset. In the P1 version of this code I have found it convenient to set a negative time duration and then while checking look for the timer to be 0 or higher. This object has delay routines that will break the ~10 second (at 200MHz) limit of the waitms() and waitus() instructions.
I run my P2 projects at 200MHz, hence the constants in the program that make calculating duration easy.
You might find some of this useful.