Not getting the right Frequency...
Posted: Mon Aug 29, 2011 6:14 pm
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.