Shop OBEX P1 Docs P2 Docs Learn Events
PASM code that runs with different clock frequencies — Parallax Forums

PASM code that runs with different clock frequencies

homosapienhomosapien Posts: 147
edited 2011-04-11 12:47 in Propeller 1
I am modifying some PASM code that I have so it will still run correctly even if the Prop's clock frequency is changed (also so this code can be used in different programs that might have different clock frequencies).

To figure out how to get the clock frequency and work with it, I was looking at the PASM code of the Parallax Mouse.spin object, which does exactly what I want:


nap                     rdlong  t,#0                    'get clkfreq
napshr                  shr     t,#18/16/13             'shr scales time
                        min     t,#3                    'ensure waitcnt won't snag
                        add     t,cnt                   'add cnt to time
                        waitcnt t,#0                    'wait until time elapses (nap)

nap_ret                 ret


My question is, what is the "shr t,#18/16/13 'shr scales time" line doing? It looks like it would shift t (the CLKFREQ) to the right by (18 divided by 16 divided by 13), which as far as I can tell would shift it right by 0. Am I missing something? What are these magic numbers 18,16, 13 anyhow?

Thanks.

Comments

  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-04-10 11:07
    'Good questions, all. You're right: the shift (as shown in your post) is vestigial and doesn't do anything, so the nap routine delays for one second plus overhead. I don't have the entire program in front of me, though, so maybe there's an explanation in the comments somewhere.

    -Phil
  • JasonDorieJasonDorie Posts: 1,930
    edited 2011-04-10 11:18
    Given that there's a label on that line of code, something else is probably modifying it on the fly, setting it to one of the three values mentioned based on some calculation with the clock rate. Look for another line of code that does a movs (or movd - I can never remember the order) to the napshr label. Those instructions will replace the source or destination values in an opcode.
  • homosapienhomosapien Posts: 147
    edited 2011-04-10 12:03
    Jason,

    You are correct, there are lines of code that makes that line do either a 18, 16 or 13 bit shift. The slashes were intended to show what might be inserted there, not divide-by symbols. My error in not posting all the code. By my calculations, these shifts would make a 122us, 15us and 3.8us delay.

    So I think this method of timing adjustment by getting the clockfreq and then doing a shift allows you to adjust the timing according to the clockfreq, but only in a rough manner. (ie, if I need a 104us delay for 9600 baudrate, the closest I could come would be to do a >>13, which would give me 122us. A 12 bit shift is 244us and an 14 bit shift is 61us). I suppose if I needed more accurate timing, the next best (ie minimal code) would be to resort to a lookup table.

    Does this sound right to you guys?
  • Mike GMike G Posts: 2,702
    edited 2011-04-10 12:22
    For baud rate, I usually use a bit ticks (a bit is this many ticks @ x baud) calculation, see FullDuplexSerial. The value _bitTicks is passed to PASM.
    _bitTicks := clkfreq / baudrate
    

    In PASM, I add the bit ticks to the current count, execute some code, then check to see if the cnt + bitticks is has occurred. Or you could just loop until...
  • Mike GreenMike Green Posts: 23,101
    edited 2011-04-10 12:49
    The I2C routines used in FemtoBasic do a similar precalculation. The Spin initialization routines for the PASM code compute several timing constants using CLKFREQ and store them as constants that are loaded into the cog when the cog is started.
  • homosapienhomosapien Posts: 147
    edited 2011-04-10 14:56
    hmmm, so I guess you guys are saying do any complicated math (division by anything other than 2^x) in SPIN and use the result in PASM - I Iike it.

    Thanks for the help.
  • ericballericball Posts: 774
    edited 2011-04-10 18:39
    homosapien wrote: »
    hmmm, so I guess you guys are saying do any complicated math (division by anything other than 2^x) in SPIN and use the result in PASM - I Iike it.

    Some of my video drivers recalculate values every frame based on LONG[0]. It requires some extra code but it means the drivers are completely dynamic and not dependent on any SPIN code. One caution with using SPIN code to do the calculations (which is easier) is to watch your precision. It's real easy to overflow or underflow the result. (The same is true for PASM, but it's easier to tweak the routine.) Just remember that CLKFREQ could be up to 2^27.
  • PerryPerry Posts: 253
    edited 2011-04-11 12:47
    The code quoted by "homosapien" is in the found in the standard Parallax Propeller keyboard driver.

    it's used like this
                            movs    napshr,#16              'pause ~16us
                            call    #nap
    

    I'd say the 18/16/13 is a reminder to the programmer of the values that might be used.
Sign In or Register to comment.