MS_001 and US_001 would change if the crystal changed from 5MHz to 6.25 MHz?
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
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
Just use clkfreq.
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?
_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.
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.
Yes, speeds things up. In busy loops this can be important.
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
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.
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.
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.
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
Chuck,
You are confusing _clkmode with clkfreq and xtal1 with _xinfreq. is not because _clkmode is $408, not 80_000_000, and xtal1 is $8, not 5_000_000.