PLL stands for Phase Locked Loop and is used to generate clock pulse
given a reference clock input which is generally from a crystal
oscillator(or XTAL). Configuring and using PLL in lpc124x MCUs is pretty
simple and straight forward.
Lpc214x MCUs have 2 PLL blocks viz.
PPL0 and PLL1. PLL0 is used to generate the System Clock which goes to
CPU and on-chip peripherals while PPL1 is strictly for USB. PLL
interrupts are only available for PLL0 and not for PLL1. Input clock to
both the PLLs must be between 10Mhz to 25Mhz strictly. This input clock
is multiplied with a suitable multiplier and scaled accordingly. But
here we have a upper limit of 60Mhz which is the maximum frequency of
operation for lpc214x MCUs. PLLs also contain CCOs i.e current
controlled oscillators which we are not much concerned about … atleast
in the case of lpc214x MCUs. CCOs operate in range of 156Mhz to 320Mhz
and there is also a divider to force CCOs to remain in their range.
Basics
--------------------------------------------------------------------------------------------------------------------------------------------------
Lets define some symbols which are used in Datasheet and also which I’ll be using in this tutorial :
| FOSC | => frequency from the crystal oscillator(XTAL)/external clock | ||||||||
| FCCO | => frequency of the PLL Current Controlled Oscillator(CCO) | ||||||||
| CCLK | => PLL output frequency (CPU Clock) | ||||||||
| M | => PLL Multiplier value from the MSEL bits in the PLLCFG register | ||||||||
| P | => PLL Divider value from the PSEL bits in the PLLCFG register | ||||||||
| PCLK | => Peripheral Clock which is derived from CCLK |
--------------------------------------------------------------------------------------------------------------------------------------------------
Now , PLL output clock is given by the formula:
- CCLK = M x FOSC
- =or=
- CCLK = FCCO / (2 x P)
- FCCO = CCLK x 2 x P
- =or=
- FCCO = FOSC x M x 2 x P
--------------------------------------------------------------------------------------------------------------------------------------------------
Note from Datasheet:
The PLL inputs and settings must meet the following:
Setting-up and using PLL
1) PLLxCON:(x= PLL block 0 or 1) This is the PLL Control register used to enable and ‘connect’ the PLL. The first bit is used to ‘Enable’ PLL. The second bit is used to ‘Connect’ the PLL.
2) PLLxCGF: The multiplier and divider values are stored in this register. The 1st 5 bits (called MSEL) are used to store the Multiplier(M). Next 2 bits i.e 5,6 (called PSEL) are used to store the value of the Divider(P).
3) PLLxSTAT: This is a read only register and contains current status of PLL enable , connect , M and P values. You can read more about the bits in datasheet – page #37. We are more interested in the 10th bit of PLLxSTAT since it contains the lock status. When we setup and enable the PLL it takes a while for PLL to latch on the target frequency. After PLL has latched or locked to target frequency this bit becomes 1. Only after this we can connect PLL to the CPU. Hence , we need to wait for PLL to lock on to target frequency.
The Order of setting up PLLs is strictly as follows :
Calculating PLL Settings
#1) PLL0
Now , Since there is no point in running the MCU at lower speeds than 60Mhz (except in some situations) ill put a table giving values for M and P for different crystal frequencies i.e FOSC.
Here’s how :
Since we want FCCO in range 156Mhz to 320Mhz first substitute FCCO = 156 and we get P = 1.3. Now substituting the maximum value for FCCO i.e 320Mhz we get P = 2.67. Now , P must be an integer between 1.3 and 2.67. So we will use P=2.
Setting-up Peripheral Clock (PCLK)
The Peripheral Clock i.e. PCLK is derived from CPU Clock i.e. CCLK. The APB Divider decides the operating frequency of PCLK. The input to APB Divider is CCLK and output is PCLK.
By Default PCLK runs at 1/4th the speed of CCLK. To control APB Divider we have a register called
VPBDIV. The value in VPBDIV controls the division of CCLK to generate PCLK as shown below:
Example
- FOSC is in the range of 10 MHz to 25 MHz.
- CCLK is in the range of 10 MHz to Fmax (the maximum allowed frequency for the microcontroller – determined by the system microcontroller is embedded in).
- FCCO is in the range of 156 MHz to 320 MHz.
Setting-up and using PLL
Here
we’ll be focusing on PLL0. We’ll see PLL1 some other day since its not
required at this moment. Explaining the internal working of PLLs and
CCOs in detail is not in the scope of this tutorial. Here we are just
concerned about its usage rather than knowing its internals. To play
with PLLs we are given a Multiplier and a Divider which decide the
output frequency/clock form PLL block. But we must play cautiously with
PLLs since the CPU and other MCU peripherals operate on the clock
provided buy it. So if PLL is deliberately or accidentally
miss-configured the MCU may go nuts! Miss configuring it deliberately is
the sole responsibility of the user and not us ;P Now .. to handle the
accident part .. we have a got a FEED Sequence which needs to be issued
whenever we wanna configure PPL. You can visualize this by imagining PLL
to be enclosed in a safe or a locker. To access PLL we need to have a
key to open the safe in order to use or configure it. The key here is
the ‘Feed Sequence’. Feed Sequence is nothing but assignment of 2
particular ‘fixed’ values to a register related to the PLL block. This
register is called ‘PLL0FEED’. And those fixed values are 0xAA and 0×55
are ‘in order’!. Hence the code for feed sequence must be :
PLL0FEED = 0xAA;
PLL0FEED = 0x55;
PLL0FEED = 0x55;
Now , lets see the other PLL Registers we can use:
1) PLLxCON:(x= PLL block 0 or 1) This is the PLL Control register used to enable and ‘connect’ the PLL. The first bit is used to ‘Enable’ PLL. The second bit is used to ‘Connect’ the PLL.
Note #1:
Initially when the MCU boots-up it uses its internal RC Oscillator as
clock source. When the PLL is setup and enabled we must switch from
internal RC Oscillator to the PLL’s output clock. This is referred to as
‘Connecting’ the PLL. PLL is only connected when both ‘Enable’ and
‘Connect’ bits are 1 and a valid feed sequence is applied.
2) PLLxCGF: The multiplier and divider values are stored in this register. The 1st 5 bits (called MSEL) are used to store the Multiplier(M). Next 2 bits i.e 5,6 (called PSEL) are used to store the value of the Divider(P).
3) PLLxSTAT: This is a read only register and contains current status of PLL enable , connect , M and P values. You can read more about the bits in datasheet – page #37. We are more interested in the 10th bit of PLLxSTAT since it contains the lock status. When we setup and enable the PLL it takes a while for PLL to latch on the target frequency. After PLL has latched or locked to target frequency this bit becomes 1. Only after this we can connect PLL to the CPU. Hence , we need to wait for PLL to lock on to target frequency.
The Order of setting up PLLs is strictly as follows :
- Setup PLL
- Apply Feed Sequence
- Wait for PLL to lock and then Connect PLL
- Apply Feed Sequence.
Calculating PLL Settings
#1) PLL0
- Select the CPU Frequency. This selection may be based many factors and end application. On Chip peripheral devices may be running on a lower clock than the processor.
- Choose an oscillator frequency (FOSC). CCLK must be the whole (non-fractional) multiple of FOSC. Which leaves us with a few values of Xtal for the selected CPU frequency (CCLK).
- Calculate the value of M to configure the MSEL bits. M = CCLK / FOSC. M must be in the range of 1 to 32. The value written to the MSEL bits in PLLCFG is M − 1.
- Find a value for P to configure the PSEL bits, such that FCCO is within its defined frequency limits. FCCO is calculated using the equation given above. P must have one of the values 1, 2, 4, or 8.
| P | Value(binary) in PSEL Bit(5,6) |
| 1 | 00 |
| 2 | 01 |
| 4 | 10 |
| 8 | 11 |
Now , Since there is no point in running the MCU at lower speeds than 60Mhz (except in some situations) ill put a table giving values for M and P for different crystal frequencies i.e FOSC.
The Value of P depends on the selection of CCLK. So , for CCLK=60Mhz we get P=2 from the equation P = FCCO/(2xCCLK).
How did I get that ?
How did I get that ?
Here’s how :
Since we want FCCO in range 156Mhz to 320Mhz first substitute FCCO = 156 and we get P = 1.3. Now substituting the maximum value for FCCO i.e 320Mhz we get P = 2.67. Now , P must be an integer between 1.3 and 2.67. So we will use P=2.
| FOSC | M | Value in MSEL (M-1) | P | Value in PSEL | Final Value in PLL0CFG |
| 5Mhz | 12 | 11 = [0xB] | 2 | 01 | 0x2B |
| 10Mhz | 6 | 5 = [0x5] | 2 | 01 | 0×25 |
| 12Mhz | 5 | 4 = [0x4] | 2 | 01 | 0×24 |
| 15Mhz | 4 | 3 = [0x3] | 2 | 01 | 0×23 |
| 20Mhz | 3 | 2 = [0x2] | 2 | 01 | 0×22 |
Setting-up Peripheral Clock (PCLK)
The Peripheral Clock i.e. PCLK is derived from CPU Clock i.e. CCLK. The APB Divider decides the operating frequency of PCLK. The input to APB Divider is CCLK and output is PCLK.
By Default PCLK runs at 1/4th the speed of CCLK. To control APB Divider we have a register called
VPBDIV. The value in VPBDIV controls the division of CCLK to generate PCLK as shown below:
--------------------------------------------------------------------------------------------------------------------------------------------------
| VPBDIV=0×00; | APB bus clock (PCLK) is one fourth of the processor clock (CCLK) |
| VPBDIV=0×01; | APB bus clock (PCLK) is the same as the processor clock (CCLK) |
| VPBDIV=0×02; | APB bus clock (PCLK) is one half of the processor clock (CCLK) |
| VPBDIV=0×03; | Reserved. If this value is written to the APBDIV register, it has no effect (the previous setting is retained). |
--------------------------------------------------------------------------------------------------------------------------------------------------
Example
Now
, lets make it more simple and write a code to run MCU @ 60Mhz
(CCLK,PCLK) when input clock from Crystal is 12Mhz (which is.. in most
cases). If your development board has crystal of another frequency ,
then in that case , you need to change the values for multiplier(M) and divider(P) accordingly as per the equations.
Note #2: For PLLCFG register we have to use a value of (M-1) for MSEL Bits where M is the value obtained from the equations. For e.g. if we wanna use M=5 from the equation then we have to apply a value of (M-1)=(5-1)=4 to the register. Similarly we have to use a specific value for PSEL bits as mentioned in table 2. Hence for P=1 we have to assign 00 to PSEL , for P=2 we have to assign 01 to PSEL and so on.
--------------------------------------------------------------------------------------------------------------------------------------------------
#define PLOCK 0x00000400
#include <LPC214x.H>
void setupPLL0(void);
void feedSeq(void);
void connectPLL0(void);
int main(void)
{
setupPLL0();
feedSeq(); //sequence for locking PLL to desired freq.
connectPLL0();
feedSeq(); //sequence for connecting the PLL as system clock
//SysClock is now ticking @ 60Mhz!
VPBDIV = 0x01; // PCLK is same as CCLK i.e 60Mhz
while(1);
//return 0;
}
void setupPLL0(void)
{
PLL0CON = 0x01; // PPLE=1 & PPLC=0 so it will be enabled
// but not connected after FEED sequence
PLL0CFG = 0x24; // set the multipler to 5 (i.e actually 4)
// i.e 12x5 = 60 Mhz (M - 1 = 4)!!!
// Set P=2 since we want FCCO in range!!!
// So , Assign PSEL =01 in PLL0CFG as per the table.
}
void feedSeq(void)
{
PLL0FEED = 0xAA;
PLL0FEED = 0x55;
}
void connectPLL0(void)
{
// check whether PLL has locked on to the desired freq by reading the lock bit
// in the PPL0STAT register
while( !( PLL0STAT & PLOCK ));
// now enable(again) and connect
PLL0CON = 0x03;
}
#include <LPC214x.H>
void setupPLL0(void);
void feedSeq(void);
void connectPLL0(void);
int main(void)
{
setupPLL0();
feedSeq(); //sequence for locking PLL to desired freq.
connectPLL0();
feedSeq(); //sequence for connecting the PLL as system clock
//SysClock is now ticking @ 60Mhz!
VPBDIV = 0x01; // PCLK is same as CCLK i.e 60Mhz
while(1);
//return 0;
}
void setupPLL0(void)
{
PLL0CON = 0x01; // PPLE=1 & PPLC=0 so it will be enabled
// but not connected after FEED sequence
PLL0CFG = 0x24; // set the multipler to 5 (i.e actually 4)
// i.e 12x5 = 60 Mhz (M - 1 = 4)!!!
// Set P=2 since we want FCCO in range!!!
// So , Assign PSEL =01 in PLL0CFG as per the table.
}
void feedSeq(void)
{
PLL0FEED = 0xAA;
PLL0FEED = 0x55;
}
void connectPLL0(void)
{
// check whether PLL has locked on to the desired freq by reading the lock bit
// in the PPL0STAT register
while( !( PLL0STAT & PLOCK ));
// now enable(again) and connect
PLL0CON = 0x03;
}
--------------------------------------------------------------------------------------------------------------------------------------------------
No comments:
Post a Comment