Shop OBEX P1 Docs P2 Docs Learn Events
MS_001 and US_001 would change if the crystal changed from 5MHz to 6.25 MHz? — Parallax Forums

MS_001 and US_001 would change if the crystal changed from 5MHz to 6.25 MHz?

Chuck ThomasChuck Thomas Posts: 39
edited 2011-09-07 03:08 in Propeller 1
All,
I am trying to understand one of the constant blocks used by many. I was thinking that MS_001 and US_001 would change if the crystal changed from 5MHz to 6.25 MHz.

_clkmode = xtal1 + pll16x ' use crystal x 16
_xinfreq = 5_000_000 ' use 5MHz crystal (sys clock = 80 MHz)
' _xinfreq = 6_250_000 ' use 6.25MHz crystal (sys clock = 100 MHz)

CLK_FREQ = ((_clkmode - xtal1) >> 6) * _xinfreq ' >>6 divide by 1/64
' ((80MHz-5MHz)/64)*5MHz 75MHz/64= 1.171875MHz *5MHz = 5.859375MHz
' ((100MHz - 6.25MHz)/64)*6.25MHz 95MHz/64 1.484375*6.25 = 9.27734375 MHz
MS_001 = CLK_FREQ / 1_000
US_001 = CLK_FREQ / 1_000_000

Where am I not understanding correctly?
Not sure if my Shift right 6 is equal to divide by 64.
Is _clkmode - xtal1 equal to crystal x 16 or does this mean something else?
Error in my math.
With integer math MS/US_001 would be 1 before being multiplied by _xinfreq which would end up being 5 or 9.

Thank you,
Chuck

Comments

  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-09-05 14:17
    I don't think you need to go through the trouble of calculating the clock frequency.

    Just use clkfreq.
    MS_001 := clkfreq/1000
      US_001 := clkfreq/1000000
    

    clkfreq is calculated for you, if you set the timing constants correctly.

    Or am I missing the point of your question? (Which I frequently do.)

    Duane

    Edit, I think I am missing the point. You want to calculate these delays prior to runtime? I'm pretty sure this is also easy. It uses a different name that clkfreq but only slightly.

    2nd Edit: I tried to find a way to set MS_001 prior to runtime. I was not successful. Is there a reason not set these at runtime?
  • Mike GreenMike Green Posts: 23,101
    edited 2011-09-05 15:13
    A shift right by 6 is the same as a divide by 64 (2 ^ 6 = 64).

    _clkmode contains a number of coded bit fields in an 8-bit value. Look at the description in the Propeller Manual. There's a nice picture on page 28.

    The compiler stores the value of _clkfreq as a long in locations 0-3 of the binary program and the value of _clkmode as a byte in location 5. If necessary, it computes _clkfreq from _xinfreq and _clkmode. The actual clock mode register is set from location 5 by the program loader. CLKFREQ just fetches the long in locations 0-3 and CLKMODE just fetches the byte in location 5.
  • JonnyMacJonnyMac Posts: 9,235
    edited 2011-09-05 15:25
    I was thinking that MS_001 and US_001 would change if the crystal changed from 5MHz to 6.25 MHz.

    They do -- that's why I created that constant block (based on a bit of clever code by another forum member). I wanted compile time constants (versus run time calculations) for my programs. They work. I use them all the time in personal and professional projects. Keep in mind that your actual crystal must match the setting you specify in _xinfreq for your software to work.
    You want to calculate these delays prior to runtime?

    Yes, speeds things up. In busy loops this can be important.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-09-05 15:41
    Jon,

    Now this sounds very familiar. I'm betting I read a Spin Zone where you showed us how to do this.

    I found it. Propeller Time Spin Zone #7 (Nuts & Volts July, 2010).

    Duane
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2011-09-06 08:49
    Duane,

    Another place you may have seen this done is in the Propeller Tool library there is an object called, "Clock.spin" from 2006, which was written by Jeff Martin and provides the following:

    Provides clock timing functions to:
    • Set clock mode/frequency at run-time using the same clock setting constants as with _CLKMODE,
    • Pause execution in units of microseconds, milliseconds, or seconds,
    • Synchronize code to the start of time-windows in units of microseconds, milliseconds, or seconds.

    It's where I get my time-related reference material from as it's part of the Propeller Library.
  • Chuck ThomasChuck Thomas Posts: 39
    edited 2011-09-06 09:48
    Thanks for the input. I'll look up Mike's refence later tonight. What I am trying to do is understand how it works. According to my math and understanding of the programming it should not work. That is why I included the math to show my thinking.

    Duane thanks but I'm trying to understand how and why it works.

    Mike thanks I'll take a look at page 28 tonight.

    JohnnyMac Thanks and yes this has come from your code. I'm not trying to take credit. But is seems that the time would come up with a 5 or 9 instaead of 1ms/1us. 5ms/9ms

    Duane have read Spin #7 but it doesn't answer how it works.

    I understand this: waitcnt(cnt + (clkfreq >> 2)) basicaly one second divided by four.

    This is the point where I don't understand the second line.
    _clkmode = xtal1 + pll16x crystal time 16
    CLK_FREQ = ((_clkmode-xtal1)>>6)*_xinfreq

    CLK_FREQ = ((xtal1 + PLL16)-xtal1) which would give a freq of 80MHz or 100 MHz depending on crystal. Subtract xtal1 divide that by 64 then muliply by crystal freq.

    Thanks for your input. Hopefully you'll be able to show me my errors.
    Or is (_clkmode + pll16) - xtal1 someother value? Due to bit shifting. Again I need to check Mikes reference page.
  • JonnyMacJonnyMac Posts: 9,235
    edited 2011-09-06 10:38
    As I stated, I didn't come up with the CLK_FREQ calculation, either, but know that it works and testing is as simple as:
    term.dec(CLK_FREQ)
    

    And it always matches the runtime variable, clkfreq.

    Here's the skinny: Subtracting the XTAL1 value from _CLKMODE leaves us with the value of PLL16X which -- if you look in table 6.3.1 of the data sheet -- is %100_0000_0000. When you shift this value left by 6 you get 16; multiply that by the input frequency and Bob's your uncle. ;)
  • AribaAriba Posts: 2,690
    edited 2011-09-06 13:39
    This calculation of a constant for clock-freq works only with PLL modes. If you disable the PLL then you get zero as clk_freq.
    An improved version is this:

    CLK_FREQ = ((_clkmode-xtal1 #> 64)>>6)*_xinfreq

    but this still not works with RCFAST and such (because the compiler lets you not specify the right _xinfreq).

    Andy
  • mparkmpark Posts: 1,306
    edited 2011-09-07 03:08
    CLK_FREQ = ((_clkmode - xtal1) >> 6) * _xinfreq ' >>6 divide by 1/64
    ' ((80MHz-5MHz)/64)*5MHz 75MHz/64= 1.171875MHz *5MHz = 5.859375MHz
    ...
    Where am I not understanding correctly?

    Chuck,
    You are confusing _clkmode with clkfreq and xtal1 with _xinfreq.
    CLK_FREQ = ((_clkmode - xtal1) >> 6) * _xinfreq
    
    is not
    ' ((80MHz-5MHz)/64)*5MHz
    
    because _clkmode is $408, not 80_000_000, and xtal1 is $8, not 5_000_000.
Sign In or Register to comment.