non hardcoded micro seconds delay in pasm.

I think it's good to actually calculate how many ticks there are in a microsecond.
And not take for granted the prop is running at 80mhz and also that it could change during runtime.
Especially if you are writing a driver that should work at most clock speeds.
hint: delay122 is not exactly 122uS but close.
To get extact value of it calc 19531 /2 (rounded down) /80 = 122.0625 uS
And so on for the next values,
using previous rounded down value /2 (rounded down)/80
With a slow running prop the error can be larger, but can be calculated.
And not take for granted the prop is running at 80mhz and also that it could change during runtime.
Especially if you are writing a driver that should work at most clock speeds.
hint: delay122 is not exactly 122uS but close.
To get extact value of it calc 19531 /2 (rounded down) /80 = 122.0625 uS
And so on for the next values,
using previous rounded down value /2 (rounded down)/80
With a slow running prop the error can be larger, but can be calculated.
main rdlong delay244,#0 'get System Hz (how many ticks in 1sec) shr delay244,#12 'div by 4096 = 244 uS mov delay122,delay244 shr delay122,#1 'divide by 2 = 122 uS mov delay61,delay122 shr delay61,#1 'divide by 2 = 61 uS mov delay30,delay61 shr delay30,#1 'divide by 2 = 30.5 uS mov delay15,delay30 shr delay15,#1 'divide by 2 = 15 uS mov delay7,delay15 shr delay7,#1 'divide by 2 = 7.5 uS mov delay4,delay7 shr delay4,#1 'divide by 2 = 4 uS mov delay2,delay4 shr delay2,#1 'divide by 2 = 2 uS mov delay1,delay2 shr delay1,#1 'divide by 2 = 1 uS min delay1,#5 'never let it go below 5 ticks ' example: sometimes you have to add up a few delays to get the time you want. mov cnt,delay122 'prepare a 200us delay, letting Latch go low. add cnt,delay61 '122+61+15= 198 (~200) add cnt,delay15 andn outa,CLKpin 'set pin low add cnt, cnt 'add cnt to shadow cnt waitcnt cnt, delay244 'wait 200us, add 300us to cnt when done. add cnt, delay61 '244+61= 305 (~300) or outa,CLKpin 'set pin high. waitcnt cnt, #0 'wait 300uS ... ... delay244 res 1 delay122 res 1 delay61 res 1 delay30 res 1 delay15 res 1 delay7 res 1 delay4 res 1 delay2 res 1 delay1 res 1
Comments
Using clkfreq is not a hardcode! The compiler takes care of having the right value in it according to the clock-settings. The clock-frequency is a variable placed at the beginning of RAM. I don't remember what happens if you change the clock-settings on the fly - but worst case is that you have to maintain it with the code that changes the clock-settings.
What I also do not understand is, why don't you use 2^x values instead?
256, 128, 64, 32, 16, 8, 4, 2, 1
with these you can sum up any integer delay you want exactly!
that it can change at anytime even after the cog have started (you may trying to save power)
How could that cog update it's delays? to still be based on time (microseconds) and not hardcoded ticks.
Sure it does not happened often, maybe because most drivers are hardcoded at the time of compile.
I'm using 2^x values, but with integer math using shifts the values gets rounded down.
I calculated that I get these numbers after I do the first >12 (based on 80mhz)
19531.. ~244
9765.. ~122
4882.. ~61
2441.. ~30.5
1220.. ~15
610.. ~7.5
305.. ~4
152.. ~2
76.. ~1
But I think I will skip this checking and only check if system clock is below 10mhz and go to sleep (as user is probably running from battery)
and periodically check if back to faster mode, as my driver does not work at those slow speed anyway.
But how do I include clkfreq in pasm for in time of compile?
delay1 long clkfreq/1_000_000 'DOES NOT WORK (??)
This works:
But I guess the values are set during runtime?, that's better.
Are the locations modified just before the cog gets the data?
How good is spin math? as a large div and then mul could create rounding errors.