OCFreaks!

LPC214x PLL Tutorial for Cpu and Peripheral Clock

Introduction

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

[Table 1]

Now , PLL output clock is given by the formula:
  • CCLK = M x FOSC
    =or=
  • CCLK = FCCO / (2 x P)

CCO output clock is given by:

  • 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:
  • 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 0x55 are ‘in order’!. Hence the code for feed sequence must be :


PLL0FEED = 0xAA;
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 :
  1. Setup PLL
  2. Apply Feed Sequence
  3. Wait for PLL to lock and then Connect PLL
  4. Apply Feed Sequence

Note that we have to apply Feed Sequence strictly as mentioned above.

Calculating PLL0 Settings

  1. 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.
  2. 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).
  3. 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.
  4. 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.

Values of PSEL for P are :

P Value(binary) in PSEL Bit(5,6)
1 00
2 01
4 10
8 11

[Table 2]

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 ? 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 0x25
12Mhz 5 4 = [0x4] 2 01 0x24
15Mhz 4 3 = [0x3] 2 01 0x23
20Mhz 3 2 = [0x2] 2 01 0x22

[Table 3]


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=0x00; APB bus clock (PCLK) is one fourth of the processor clock (CCLK)
VPBDIV=0x01; APB bus clock (PCLK) is the same as the processor clock (CCLK)
VPBDIV=0x02; APB bus clock (PCLK) is one half of the processor clock (CCLK)
VPBDIV=0x03; 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 want to 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..

/*
(c) Umang Gajera - www.ocfreaks.com
This e.g. shows how to set up , initialize 
and connect PLL0 to get CCLK & PCLK @ 60Mhz
Assumption : Input freq of 12MHZ from Crystal.
*/

#define PLOCK 0x400 //10th bit = 1

#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;
} 

Exit mobile version