Shop OBEX P1 Docs P2 Docs Learn Events
Newbie trying to understand clkfreq — Parallax Forums

Newbie trying to understand clkfreq

Tony B.Tony B. Posts: 356
edited 2009-09-09 06:18 in Propeller 1
I am trying to understand the program attched to this post.· The program is from the Spin Stamp for BOE-BOT object from the propeller object exchange.· I am wrestling with understanding how I know the value of clkfreq.· I found a helpful chart on page 175 oif the Propeller Manual V1.0 in which clkfreq has a value of 1000.· When I use that value the program works out.· Does clkfreq always have a value of 1000 no matter the _clkmode and ·_xinfreq settings?· IF they are related, how?· Thanks for the help

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tony

Comments

  • KyeKye Posts: 2,200
    edited 2009-09-09 02:01
    clkfreq usually equals whatever value you specificy in the constant section for your code. For most users clkfreq is 80_000_000 MHZ.

    ...

    CON

    _clkfreq = 80_000_000
    _clkmode = xtal1 + pll16x

    ...

    Pretty good rule of thumb to include that in all your top level objects or life will be a pain when nothing works.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Nyamekye,
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-09-09 02:25
    Kye said...
    For most users clkfreq is 80_000_000 MHZ.
    If only! (I think you meant Hz.) smile.gif

    -Phil
  • Gunstar1Gunstar1 Posts: 18
    edited 2009-09-09 03:36
    No, you are misunderstanding what it is doing.

    I am new too, but from what I understand is that clkfreq is the number of ticks per second.

    In your specific code you have 10 MHz (10,000,000 Hz) times the PLL number which is 8, which is 80,000,000 ticks per second. So in this case clkfreq=80,000,000

    The code then takes clkfreq/1000 (which is called "pause") then multiplies "pause" by 20... which is the same as saying clkfreq divided by 50
    80,000,000 / 1000 * 20 = 1,600,000
    OR
    80,000,000 / 50 = 1,600,000 (which just means you want it to wait 1/50th of a second)

    The thing to remember is that clkfreq is the total number of ticks per second, cnt is the current count of ticks. In 1 second, cnt will have counted up to clkfreq.

    Examples:
    waitcnt(clkfreq + cnt) means to wait for 1 second. You are saying wait until 1 second's worth of ticks has been counted before continuing.
    waitcnt(clkfreq / 2 + cnt) means to wait for .5 seconds. Wait until half of 1 second's worth of ticks has been counted before continuting.
    waitcnt(clkfreq / 4 + cnt) means to wait for .25 seconds
    waitcnt(clkfreq * 2 + cnt) means to wait for 2 seconds
  • W9GFOW9GFO Posts: 4,010
    edited 2009-09-09 04:14
    T Bill said...
    I am wrestling with understanding how I know the value of clkfreq. I found a helpful chart on page 175 oif the Propeller Manual V1.0 in which clkfreq has a value of 1000. When I use that value the program works out. Does clkfreq always have a value of 1000 no matter the _clkmode and _xinfreq settings? IF they are related, how? Thanks for the help

    CON
                                           
      _clkmode        = xtal1 + pll8x
      _xinfreq        = 10_000_000
    
    



    clkfreq = _clkmode * _xinfreq

    Clkfreq is the number of clock cycles per second. So clkfreq really equals one second - always.

    If you want 1 millisecond you divide clkfreq by 1,000. This is a much better approach than calling 1 millisecond "80_000".

    waitcnt(clkfreq/1000 + cnt)
    waitcnt(80_000 + cnt)
    



    Those two are exactly the same so long as the clock frequency is 80mhz. If you need to change the clock frequency for some reason (low power) the top one will still be 1 mS but the bottom would change to be 2 mS.

    Rich H

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    The Servo Boss, a 12 channel servo tester kit from Gadget Gangster.
  • ElectricAyeElectricAye Posts: 4,561
    edited 2009-09-09 04:38
    Gunstar1 said...
    ....
    The thing to remember is that clkfreq is the total number of ticks per second, cnt is the current count of ticks. In 1 second, cnt will have counted up to clkfreq.....

    Actually, I think what you meant to say is this: in one second the cnt will increment itself clkfreq number of ticks. After waiting 1 second, the value of cnt is NOT necessarily going to be the value of the clkfreq. The value of cnt itself is something like an odometer that is always running as the Propeller is running. Once the cnt reaches 2,147,483,647, it "rolls over" and starts counting all over again. So waitcnt() is useable because you are telling the Propeller to wait until the value inside the parentheses has reached cnt plus some desired number of ticks.
  • Gunstar1Gunstar1 Posts: 18
    edited 2009-09-09 04:47
    ElectricAye said...
    Gunstar1 said...
    ....
    The thing to remember is that clkfreq is the total number of ticks per second, cnt is the current count of ticks. In 1 second, cnt will have counted up to clkfreq.....

    Actually, I think what you meant to say is this: in one second the cnt will increment itself clkfreq number of ticks. After waiting 1 second, the value of cnt is NOT necessarily going to be the value of the clkfreq. The value of cnt itself is something like an odometer that is always running as the Propeller is running. Once the cnt reaches 2,147,483,647, it "rolls over" and starts counting all over again. So waitcnt() is useable because you are telling the Propeller to wait until the value inside the parentheses has reached cnt plus some desired number of ticks.
    Yes, that is what I meant.

    (The roll over starts at -2,147,483,648)
  • BradCBradC Posts: 2,601
    edited 2009-09-09 05:01
    Gunstar1 said...
    Nwaitcnt(clkfreq * 2 + cnt) means to wait for 2 seconds

    If you re-write that as (cnt + clkfreq * 2) you will get slightly more accurate timing.

    In a simplistic fashion, the variables are pushed on to the stack left to right, so by doing it your way you have the extra delay of the (clkfreq*2) calculation prior to reading and storing the
    value of cnt. If you make cnt the leftmost variable, it will *always* be read and stored first. This just makes your timing calculation slightly more accurate (probably in the order of 20-50uS) depending on the complexity of the calculation.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    lt's not particularly silly, is it?
  • W9GFOW9GFO Posts: 4,010
    edited 2009-09-09 05:35
    Here's what the Propeller manual has to say about that;
    The Propeller Manual said...

    Related to this, when using WAITCNT in Spin code as shown above, make sure to write the
    Value expression the same way we did: in the form “offset + cnt” as opposed to
    “cnt + offset.” This is because the Spin interpreter will evaluate this expression from left
    to right, and each intermediate evaluation within an expression takes time to perform. If cnt
    were at the start of the expression, the System Counter would be read first then the rest of the
    expression would be evaluated, taking an unknown amount of cycles and making our cnt
    value quite old by the time the final result is calculated. However, having cnt as the last
    value in the WAITCNT expression ensures a fixed amount of overhead (cycles) between reading
    the System Counter and activating the wait hardware. In fact, the interpreter takes 381 cycles
    of final overhead when the command is written in the form waitcnt(offset + cnt). This
    means the value of offset must always be at least 381 to avoid unexpectedly long delays.

    Rich H

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    The Servo Boss, a 12 channel servo tester kit from Gadget Gangster.

    Post Edited (W9GFO) : 9/9/2009 6:10:01 AM GMT
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-09-09 05:53
    BUT ... (cnt + whatever) is dangerous if your 'whatever' is small. In this case it can happen that your counter is already bigger when SPIN finished the calculation. Then you'll have to wait for ~50 seconds.
    In general there is min. number of 'whatever' that you can use in SPIN, as in SPIN waitcnt plus the calculations have a runtime and the cnt-difference you use must always be bigger or equal to the runtime, so that you don't miss the calculated counter value. I bet someone of the gurus here can remember the min. value .. I can't (was it around 600?). One can easyly test it.

    Just wanted to mention this little pitfall, so that you can't say "Never heard of that ;o)" in case it happens to you that the waitcnt actually waits for ~50 seconds.
  • W9GFOW9GFO Posts: 4,010
    edited 2009-09-09 06:09
    MagIO2 said...
    I bet someone of the gurus here can remember the min. value ...

    No guru required. Look two posts up ^^^^

    Rich H

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    The Servo Boss, a 12 channel servo tester kit from Gadget Gangster.
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-09-09 06:18
    Yep ... I needed a bit to long to drop those vew lines ... that's why I like the propeller ... it has no interrupts ... in opposite to me ;o)

    But Brads point is still valid. Doing it the other way around·adds a little accuracy. Doing it in PASM adds a lot of accuracy. As always the solution depends on your needs.

    Post Edited (MagIO2) : 9/9/2009 6:25:32 AM GMT
Sign In or Register to comment.