Is is possible that the constants used for the delay calculations are incorrect?
I think the steps for each of the different loop types should be 3, 770, 197122 and 50463234, not 3, 770, 196355 and 50070530.
Is is possible that the constants used for the delay calculations are incorrect?
I think the steps for each of the different loop types should be 3, 770, 197122 and 50463234, not 3, 770, 196355 and 50070530.
Hi,
Sorry for a so late answer, I forgot monitoring the forum ;-)
As I'm not the primary author, I never check if formula were right.
Why do you think its are wrong?
Do you made some simulation or calculation?
I'll check the formula quickly.
Regards
I ran the code in the MPLAB IDE on a MSWindows machine. I have not checked the last value 50463234. I think there is a pattern to the numbers e.g.
3*256+2=>770
770*256+2=>197122
197122*256+2=>50463234
If the pattern is valid then the code could be rewritten to generate the divisors as needed and hence remove these hardcoded numbers.
I'm not sure this pattern is fully valid, but I agree with you, the code is really wrong, I tested it with gpsim :-(
I'm working to fix this but I get some difficulties with the 3 counters delay (of course, the 4 counters delay isn't yet writen :-)), because I want to write a very accurate delay.
Finally, I can confirm you were right ;-)
The pattern is right but it is insufficient to write a formula.
And I discovered exceptions to managed: if a counter is calculated to be zero (so, no loop), this is a problem because 0 clearly means 256!!
Either I'll release a 0.2.5 to fix this problem, but some delays can't be compute, either I'll release a 0.3.0 if I rewrite all the code to be able to provide 3 machine cycles accurate delays.
I have a spreadsheet where I have analysed the code sizes for various delays that might be of some use to you. I have determined a pattern in the no of cycles versus no of loops required. I have written a Ruby program and also an assembly macro that will generate the code given the required number of cycles, accurate to the cycle. It adds 'goto $+1' and 'nop' instructions to get the exact number of cycles. If you would any of this let me know how I can get it to you. I've included the macro below. I've tested quite a few boundary cases but only with online=0.
DELAY_CYCLES MACRO cyc,inline,cblockstart
if inline==0
Delay#v(cyc)
endif
variable levels
local n,loopincdelay,loopmaxdelay
n=cyc
if inline==0
n=n-4 ;Use 4 cycles for call and return
endif
levels=0
if n>=10
levels=1
loopincdelay=3
n2=10
while (n2+256*loopincdelay<n-2) && levels<4
levels=levels+1
n2=n2+4
loopincdelay=loopincdelay*256+2
endw
LOCAL levelx,cblockloc,count
cblockloc=cblockstart
levelx=0
while levelx<levels
levelx+=1
endw
n-=4*levels ;take off min cycles
levelx=levels
while levelx>0
cblock cblockloc+levelx-1
count#v(levelx)
endc
count=n/loopincdelay+1
if count>=256
clrf count#v(levelx)
n+=1 ; Add back one we saved
count=256
else
movlw count
movwf count#v(levelx)
endif
n=n-(count-1)*loopincdelay
loopincdelay=(loopincdelay-2)/256
levelx-=1
endw
if n>3
goto $+2
n=n-4
endif
LOCAL Delay_Loop
Delay_Loop
levelx=1
WHILE levelx<=levels
decfsz count#v(levelx),f
goto Delay_Loop
levelx+=1
ENDW
else
levels=0
endif
WHILE n>=2
goto $+1
n-=2
ENDW
if n>=1
nop
n-=1
endif
if inline==0
return
endif
ENDM
To use it:
DELAY_CYCLES 50463247,0,0x20
Log in to post a comment.