Not getting the right Frequency...
Not getting the right Frequency...
I'm implementing some code to verify the frequency of the board i'm playing with. Have tried to adapt some routines from Olimex C code. But result is not good.
Below are 2 modules: 1) SYS.MOD gets frequency of board CPU / Periphery. 2) Test program to display some relevant values. Board is LPC2378-STK.
However I always end up with SystemClock = 6Mhz and RCClock = 15000 kHz. Which is no good..
Anybody an idea?
MODULE SYS;
IMPORT SYSTEM, LPC := LPC2378, Out;
CONST
HZ* = 1; KHZ* = 1000*HZ; MHZ* = 1000*KHZ;
(* Available PCLK offsets on LPC2378 *)
WDTPCLKOffset* =0; TIMER0PCLKOffset* =2; TIMER1PCLKOffset* =4; UART0PCLKOffset* =6;
UART1PCLKOffset* =8; PWM0PCLKOffset* =10; PWM1PCLKOffset* =12; I2C0PCLKOffset* =14;
SPIPCLKOffset* =16; RTCPCLKOffset* =18; SSP1PCLKOffset* =20; DACPCLKOffset* =22;
ADCPCLKOffset* =24; CAN1PCLKOffset* =26; CAN2PCLKOffset* =28; ACFPCLKOffset* =30;
BATRAMPCLKOffset* =32; GPIOPCLKOffset* =34; PCBPCLKOffset* =36; I2C1PCLKOffset* =38;
SSP0PCLKOffset* =42; TIMER2PCLKOffset* =44; TIMER3PCLKOffset* =46; UART2PCLKOffset* =48;
UART3PCLKOffset* =50; I2C2PCLKOffset* =52; I2SPCLKOffset* =54; MCIPCLKOffset* =56;
PCLKPCLKOffset* =60;
(*************************************************************************
* Function Name: SYS.GetFsclk
* Parameters: none
* Return: Integer
*
* Description: return Sclk [Hz]
*
*************************************************************************)
PROCEDURE GetFsclk*() : INTEGER;
CONST
IntRCOscFreq= 4*MHZ;
MainOscFreq = 12*MHZ;
RTCOscFreq = 32768*HZ;
PLLEBit = 24; PLLCBit = 25;
VAR
Mul, Div, Osc, Fsclk, cfgClk : INTEGER;
bits : SET;
BEGIN
SYSTEM.GET(LPC.PLLSTAT, bits);
IF (PLLCBit IN bits) & (PLLEBit IN bits) THEN
(* when PLL is connected *)
Mul := SYSTEM.VAL(INTEGER, bits * {14..0}) + 1;
Div := LSR(SYSTEM.VAL(INTEGER, bits * {23..16}), 16) + 1;
ELSE
Mul := 1; Div := 1;
END;
(* Find clk source *)
SYSTEM.GET(LPC.CLKSRCSEL, Fsclk);
Fsclk := Fsclk MOD 4; (* Only interessed in bits 0 and 1 *)
CASE Fsclk OF
0: Osc := IntRCOscFreq;
| 1: Osc := MainOscFreq;
| 2: Osc := RTCOscFreq;
| 3: Osc := 0; (* reserved value, so not relevant *)
END;
(* Calculate system frequency *)
SYSTEM.GET(LPC.CCLKCFG, cfgClk);
Fsclk := Osc*Mul*2;
Fsclk := Fsclk DIV (Div*(cfgClk+1));
Out.String("Mul="); Out.Int(Mul, 0); Out.String(",Div="); Out.Int(Mul, 0);
Out.String(",Osc="); Out.Int(Osc, 0); Out.Ln;
RETURN Fsclk
END GetFsclk;
(*************************************************************************
* Function Name: SYS.GetFpclk
* Parameters: Periphery As enumerated in the above defined const list
* Return: Integer
*
* Description: return Pclk [Hz]
*
*************************************************************************)
PROCEDURE GetFpclk*(Periphery : INTEGER) : INTEGER;
VAR
Fpclk, Reg, Val: INTEGER;
BEGIN
IF Periphery < 32 THEN
Reg := LPC.PCLKSEL0
ELSE
Reg := LPC.PCLKSEL1
END;
SYSTEM.GET(Reg, Val);
Periphery := Periphery MOD 32;
Val := LSR(Val, Periphery) MOD 4;
Fpclk := GetFsclk();
(* find peripheral appropriate periphery divider *)
CASE Val OF
0 : Fpclk := Fpclk DIV 4;
| 1 : (* None *)
| 2 : Fpclk := Fpclk DIV 2;
| 3 : Fpclk := Fpclk DIV 8;
END;
RETURN Fpclk
END GetFpclk;
END SYS.
MODULE TestSYS;
IMPORT Out, SYS, Main;
VAR
f : INTEGER;
BEGIN
f := SYS.GetFsclk();
Out.String("SystemClock = "); Out.Int(f DIV SYS.MHZ, 0); Out.String("MHz"); Out.Ln;
f := SYS.GetFpclk(SYS.RTCPCLKOffset);
Out.String("RTCClock = "); Out.Int(f DIV SYS.KHZ, 0); Out.String("KHz"); Out.Ln;
END TestSYS.
Below are 2 modules: 1) SYS.MOD gets frequency of board CPU / Periphery. 2) Test program to display some relevant values. Board is LPC2378-STK.
However I always end up with SystemClock = 6Mhz and RCClock = 15000 kHz. Which is no good..
Anybody an idea?
MODULE SYS;
IMPORT SYSTEM, LPC := LPC2378, Out;
CONST
HZ* = 1; KHZ* = 1000*HZ; MHZ* = 1000*KHZ;
(* Available PCLK offsets on LPC2378 *)
WDTPCLKOffset* =0; TIMER0PCLKOffset* =2; TIMER1PCLKOffset* =4; UART0PCLKOffset* =6;
UART1PCLKOffset* =8; PWM0PCLKOffset* =10; PWM1PCLKOffset* =12; I2C0PCLKOffset* =14;
SPIPCLKOffset* =16; RTCPCLKOffset* =18; SSP1PCLKOffset* =20; DACPCLKOffset* =22;
ADCPCLKOffset* =24; CAN1PCLKOffset* =26; CAN2PCLKOffset* =28; ACFPCLKOffset* =30;
BATRAMPCLKOffset* =32; GPIOPCLKOffset* =34; PCBPCLKOffset* =36; I2C1PCLKOffset* =38;
SSP0PCLKOffset* =42; TIMER2PCLKOffset* =44; TIMER3PCLKOffset* =46; UART2PCLKOffset* =48;
UART3PCLKOffset* =50; I2C2PCLKOffset* =52; I2SPCLKOffset* =54; MCIPCLKOffset* =56;
PCLKPCLKOffset* =60;
(*************************************************************************
* Function Name: SYS.GetFsclk
* Parameters: none
* Return: Integer
*
* Description: return Sclk [Hz]
*
*************************************************************************)
PROCEDURE GetFsclk*() : INTEGER;
CONST
IntRCOscFreq= 4*MHZ;
MainOscFreq = 12*MHZ;
RTCOscFreq = 32768*HZ;
PLLEBit = 24; PLLCBit = 25;
VAR
Mul, Div, Osc, Fsclk, cfgClk : INTEGER;
bits : SET;
BEGIN
SYSTEM.GET(LPC.PLLSTAT, bits);
IF (PLLCBit IN bits) & (PLLEBit IN bits) THEN
(* when PLL is connected *)
Mul := SYSTEM.VAL(INTEGER, bits * {14..0}) + 1;
Div := LSR(SYSTEM.VAL(INTEGER, bits * {23..16}), 16) + 1;
ELSE
Mul := 1; Div := 1;
END;
(* Find clk source *)
SYSTEM.GET(LPC.CLKSRCSEL, Fsclk);
Fsclk := Fsclk MOD 4; (* Only interessed in bits 0 and 1 *)
CASE Fsclk OF
0: Osc := IntRCOscFreq;
| 1: Osc := MainOscFreq;
| 2: Osc := RTCOscFreq;
| 3: Osc := 0; (* reserved value, so not relevant *)
END;
(* Calculate system frequency *)
SYSTEM.GET(LPC.CCLKCFG, cfgClk);
Fsclk := Osc*Mul*2;
Fsclk := Fsclk DIV (Div*(cfgClk+1));
Out.String("Mul="); Out.Int(Mul, 0); Out.String(",Div="); Out.Int(Mul, 0);
Out.String(",Osc="); Out.Int(Osc, 0); Out.Ln;
RETURN Fsclk
END GetFsclk;
(*************************************************************************
* Function Name: SYS.GetFpclk
* Parameters: Periphery As enumerated in the above defined const list
* Return: Integer
*
* Description: return Pclk [Hz]
*
*************************************************************************)
PROCEDURE GetFpclk*(Periphery : INTEGER) : INTEGER;
VAR
Fpclk, Reg, Val: INTEGER;
BEGIN
IF Periphery < 32 THEN
Reg := LPC.PCLKSEL0
ELSE
Reg := LPC.PCLKSEL1
END;
SYSTEM.GET(Reg, Val);
Periphery := Periphery MOD 32;
Val := LSR(Val, Periphery) MOD 4;
Fpclk := GetFsclk();
(* find peripheral appropriate periphery divider *)
CASE Val OF
0 : Fpclk := Fpclk DIV 4;
| 1 : (* None *)
| 2 : Fpclk := Fpclk DIV 2;
| 3 : Fpclk := Fpclk DIV 8;
END;
RETURN Fpclk
END GetFpclk;
END SYS.
MODULE TestSYS;
IMPORT Out, SYS, Main;
VAR
f : INTEGER;
BEGIN
f := SYS.GetFsclk();
Out.String("SystemClock = "); Out.Int(f DIV SYS.MHZ, 0); Out.String("MHz"); Out.Ln;
f := SYS.GetFpclk(SYS.RTCPCLKOffset);
Out.String("RTCClock = "); Out.Int(f DIV SYS.KHZ, 0); Out.String("KHz"); Out.Ln;
END TestSYS.
Re: Not getting the right Frequency...
Forgot to mention that it seams the PLL is not locked, because Mul and Div always return 1.
-
- Site Admin
- Posts: 516
- Joined: Fri Dec 31, 2010 12:30 pm
- Contact:
Re: Not getting the right Frequency...
Post your message again with the original code formatting preserved - it's difficult to comprehend without it.
To preserve the formatting, select your code after pasting it into your message and click on the 'Code' pushbutton beneathe the Subject line. If you do that, instead of:
IF (PLLCBit IN bits) & (PLLEBit IN bits) THEN
(* when PLL is connected *)
Mul := SYSTEM.VAL(INTEGER, bits * {14..0}) + 1;
Div := LSR(SYSTEM.VAL(INTEGER, bits * {23..16}), 16) + 1;
ELSE
Mul := 1; Div := 1;
END;
you will see:
To preserve the formatting, select your code after pasting it into your message and click on the 'Code' pushbutton beneathe the Subject line. If you do that, instead of:
IF (PLLCBit IN bits) & (PLLEBit IN bits) THEN
(* when PLL is connected *)
Mul := SYSTEM.VAL(INTEGER, bits * {14..0}) + 1;
Div := LSR(SYSTEM.VAL(INTEGER, bits * {23..16}), 16) + 1;
ELSE
Mul := 1; Div := 1;
END;
you will see:
Code: Select all
IF (PLLCBit IN bits) & (PLLEBit IN bits) THEN
(* when PLL is connected *)
Mul := SYSTEM.VAL(INTEGER, bits * {14..0}) + 1;
Div := LSR(SYSTEM.VAL(INTEGER, bits * {23..16}), 16) + 1;
ELSE
Mul := 1; Div := 1;
END;
Re: Not getting the right Frequency...
Ok, Here we go again...
And the second part:
Code: Select all
MODULE SYS;
IMPORT SYSTEM, LPC := LPC2378, Out;
CONST
HZ* = 1; KHZ* = 1000*HZ; MHZ* = 1000*KHZ;
(* Available PCLK offsets on LPC2378 *)
WDTPCLKOffset* =0; TIMER0PCLKOffset* =2; TIMER1PCLKOffset* =4; UART0PCLKOffset* =6;
UART1PCLKOffset* =8; PWM0PCLKOffset* =10; PWM1PCLKOffset* =12; I2C0PCLKOffset* =14;
SPIPCLKOffset* =16; RTCPCLKOffset* =18; SSP1PCLKOffset* =20; DACPCLKOffset* =22;
ADCPCLKOffset* =24; CAN1PCLKOffset* =26; CAN2PCLKOffset* =28; ACFPCLKOffset* =30;
BATRAMPCLKOffset* =32; GPIOPCLKOffset* =34; PCBPCLKOffset* =36; I2C1PCLKOffset* =38;
SSP0PCLKOffset* =42; TIMER2PCLKOffset* =44; TIMER3PCLKOffset* =46; UART2PCLKOffset* =48;
UART3PCLKOffset* =50; I2C2PCLKOffset* =52; I2SPCLKOffset* =54; MCIPCLKOffset* =56;
PCLKPCLKOffset* =60;
(*************************************************************************
* Function Name: SYS.GetFsclk
* Parameters: none
* Return: Integer
*
* Description: return Sclk [Hz]
*
*************************************************************************)
PROCEDURE GetFsclk*() : INTEGER;
CONST
IntRCOscFreq= 4*MHZ;
MainOscFreq = 12*MHZ;
RTCOscFreq = 32768*HZ;
PLLEBit = 24; PLLCBit = 25;
VAR
Mul, Div, Osc, Fsclk, cfgClk : INTEGER;
bits : SET;
BEGIN
SYSTEM.GET(LPC.PLLSTAT, bits);
IF (PLLCBit IN bits) & (PLLEBit IN bits) THEN
(* when PLL is connected *)
Mul := SYSTEM.VAL(INTEGER, bits * {14..0}) + 1;
Div := LSR(SYSTEM.VAL(INTEGER, bits * {23..16}), 16) + 1;
ELSE
Mul := 1; Div := 1;
END;
(* Find clk source *)
SYSTEM.GET(LPC.CLKSRCSEL, Fsclk);
Fsclk := Fsclk MOD 4; (* Only interessed in bits 0 and 1 *)
CASE Fsclk OF
0: Osc := IntRCOscFreq;
| 1: Osc := MainOscFreq;
| 2: Osc := RTCOscFreq;
| 3: Osc := 0; (* reserved value, so not relevant *)
END;
(* Calculate system frequency *)
SYSTEM.GET(LPC.CCLKCFG, cfgClk);
Fsclk := Osc*Mul*2;
Fsclk := Fsclk DIV (Div*(cfgClk+1));
Out.String("Mul="); Out.Int(Mul, 0); Out.String(",Div="); Out.Int(Mul, 0);
Out.String(",Osc="); Out.Int(Osc, 0); Out.Ln;
RETURN Fsclk
END GetFsclk;
(*************************************************************************
* Function Name: SYS.GetFpclk
* Parameters: Periphery As enumerated in the above defined const list
* Return: Integer
*
* Description: return Pclk [Hz]
*
*************************************************************************)
PROCEDURE GetFpclk*(Periphery : INTEGER) : INTEGER;
VAR
Fpclk, Reg, Val: INTEGER;
BEGIN
IF Periphery < 32 THEN
Reg := LPC.PCLKSEL0
ELSE
Reg := LPC.PCLKSEL1
END;
SYSTEM.GET(Reg, Val);
Periphery := Periphery MOD 32;
Val := LSR(Val, Periphery) MOD 4;
Fpclk := GetFsclk();
(* find peripheral appropriate periphery divider *)
CASE Val OF
0 : Fpclk := Fpclk DIV 4;
| 1 : (* None *)
| 2 : Fpclk := Fpclk DIV 2;
| 3 : Fpclk := Fpclk DIV 8;
END;
RETURN Fpclk
END GetFpclk;
END SYS.
Code: Select all
MODULE TestSYS;
IMPORT Out, SYS, Main;
VAR
f : INTEGER;
BEGIN
f := SYS.GetFsclk();
Out.String("SystemClock = "); Out.Int(f DIV SYS.MHZ, 0); Out.String("MHz"); Out.Ln;
f := SYS.GetFpclk(SYS.RTCPCLKOffset);
Out.String("RTCClock = "); Out.Int(f DIV SYS.KHZ, 0); Out.String("KHz"); Out.Ln;
END TestSYS.
-
- Site Admin
- Posts: 516
- Joined: Fri Dec 31, 2010 12:30 pm
- Contact:
Re: Not getting the right Frequency...
The value of m must be less than n when you use a SET range {m .. n}
i.e. m .. n is a shorthand for m, m+1, ... , n-1, n.
Currently the compiler does not object but as a result of this report we will modify it so that it reports an error message when this error is detected in the future.
When I changed the statements in your example from:
to:
the resulting output was:
Mul=12,Div=12,Osc=12000000
SystemClock = 72MHz
Mul=12,Div=12,Osc=12000000
RTCClock = 18000KHz
i.e. m .. n is a shorthand for m, m+1, ... , n-1, n.
Currently the compiler does not object but as a result of this report we will modify it so that it reports an error message when this error is detected in the future.
When I changed the statements in your example from:
Code: Select all
Mul := SYSTEM.VAL(INTEGER, bits * {14..0}) + 1;
Div := LSR(SYSTEM.VAL(INTEGER, bits * {23..16}), 16) + 1;
Code: Select all
Mul := SYSTEM.VAL(INTEGER, bits * {0..14}) + 1;
Div := LSR(SYSTEM.VAL(INTEGER, bits * {16..23}), 16) + 1;
Mul=12,Div=12,Osc=12000000
SystemClock = 72MHz
Mul=12,Div=12,Osc=12000000
RTCClock = 18000KHz
Re: Not getting the right Frequency...
Thanks, problem has been solved.
A reason why I did this: The NXP doc always works from MSB to LSB so I reflected this in code.
On the other side.. I -THOUGHT I had tested this in onther testcode, but didn't bump into it.
Couldn't find any evidence that the range MUST be from low..high
Thanks anyway for pointing this out!
A reason why I did this: The NXP doc always works from MSB to LSB so I reflected this in code.
On the other side.. I -THOUGHT I had tested this in onther testcode, but didn't bump into it.
Couldn't find any evidence that the range MUST be from low..high
Thanks anyway for pointing this out!