I have seen in several places including the AM335 TRM that the PRU cycle register does not wrap. I am very surprised, as having a clock that wraps around is the basis for how other low level processors handle scheduling myriad events of varying frequencies.
In those processors, for each event that you want to schedule, you take the current clock setting and add however much time (except in cycles) that you want the event to occur. Then each event (or thread) watches that clock to see if the threshold has been passed. It doesn’t matter that the clock wraps, because you are just checking that you have indeed recently passed the threshold (subtracting the current clock from the scheduled results in a ‘positive’ number, or one less than U32/2.
I currently have a relatively complex scheduler programmed that I use to simulate crank/cam signals, with the crank pulses able to be crank domain or time domain, but I do this by creating my own clock, by keeping a register to which I add the appropriate number of cycles that were just required for each branch in the code. This is successful, but very tedious and messy. It also means that it must be written in assembly rather than C as you would otherwise not be able to guarantee that you are adding the correct number of cycles.
Are there other solutions that anyone knows of? Or is there a way to force CYCLE to wrap?
don’t know for sure, but wouldn’t it be documented?
not knowing how complex your scheduler is, this is difficult to know. BUT … here is the mechanism for a scheduler that I wrote (clpru asm) for micosecond timing issues:
step 0) … set up pwm signal at 20% duty cycle, 1 microsecond duration
feed pwm signal into pruin pin
segment code into pieces that run in < 1 microsecond (~200 instructions)
at end of segment, wait for pwm signal to go high,
3a) increment register
3b) execute segment
repeat step 3
if segments are TOO small and run in less than 200 nanoseconds, reduce the duty cycle of the pwm signal…
use an oscilloscope to VERIFY that your code segments execute in less than 1usd
this works well for me when using hc-sr04 ultrasonic sensors that require microsecond timing to be accurate.
also when refreshing servos (20 ms), the signal must be between 1ms and 2ms… if this is not accurate, the servo will vibrate / shudder / shake.
this mechanism allows me to run multiple machines / devices ( easily 4 servo’s and 2 hc-sr04 ) simultaneously… there is no need to block and wait as the GP register is kicked by the pwm signal, and wraps without warning or complaint.
beating a dead horse example: after refreshing a servo, set a gp register to 20000 ( or 20 * 1024 if you prefer a joyless life ) … for every pwm high, decrement this register. when register == 0 … do the refresh again.
I’ve also used the IEP timer ( 4.4.3 TRM ) … but this only works if not using the ethernet port. This solution is very close to the cycle register as it runs @200Mhz… the same speed as the cycle register as I understand it.