delay calculations

grahamMc
2007-09-28
2013-04-24
  • grahamMc

    grahamMc - 2007-09-28

    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.

     
    • Alain Portal

      Alain Portal - 2007-10-09

      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

       
    • grahamMc

      grahamMc - 2007-10-10

      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.

       
    • Alain Portal

      Alain Portal - 2007-10-10

      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.

       
    • Alain Portal

      Alain Portal - 2007-10-13

      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.

       
    • grahamMc

      grahamMc - 2007-10-23

      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.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks