I have inherited some code from someone for the LPC1768. In the PLL initialisation he has some really ugly code that jumps to a reset vector if the PLL's registers aren't set to the correct values and just tries again until it works. I'm just not having that as a valid way of working (quite aside from having gotos in C), it just can't be the right way of initialising the peripheral.
However, if I do not follow this reset procedure, I simply cannot get the PLLSTAT register to hold anything other than 0 and I'm stuck waiting for the PLL initialise, which it never does. The IAR examples show you how to set up all peripherals other than, as far as I can see, the PLL, so I can't go and look there for help.
I printed out 4.5.13 of the user manual and followed the nine steps, but never get past the PLL being initialised. Anyone able to help please? I have the code below.
If anyone has a snippet of the relevant part of the code that works for them it would be useful too. As far as I can see I have no forgotten to initialise something else necessary, but maybe that's all it is?
Thanks a lot.
------------------------------------------------------------------------------------
// Step 1 - Disconnect PLL
LPC_SC->PLL0CON &= ~CLKPWR_PLL0CON_CONNECT; // Disconnect PLL0
LPC_SC->PLL0FEED |= 0xAA;
LPC_SC->PLL0FEED |= 0x55;
// Step 2 - Disable PLL
LPC_SC->PLL0CON &= ~CLKPWR_PLL0CON_ENABLE; // Disable PLL0
LPC_SC->PLL0FEED |= 0xAA;
LPC_SC->PLL0FEED |= 0x55;
// step 3 - Change clock divisor
LPC_SC->CCLKCFG = 0x02; //Set the divider (to 3-see calcs below)
// Step 4 - Change the clock source
LPC_SC->SCS &= 0x00000060; //Set up the external clock. We have a 12MHz Xtal - Set B4 low
LPC_SC->SCS |= 0x00000020; //Start EXTOSC
while(!LPC_SC->SCS & 0x00000040); //And wait for it to become stable
//Select XTAL as the clock source input to PLL
LPC_SC->CLKSRCSEL = CLKPWR_CLKSRCSEL_CLKSRC_MAINOSC;
// Step 5 - Write to PLL0CFG, this sets multiply and divide values.
// 12MHz crystal giving 96MHz clock
// Target PLL output would therefore be 288MHz
// Maths is ((Ctarg)288*1000000*1)/(2*(XTAL)12*1000000)=12=0x0C
// This gives us a divider of 1 and a multiplier of (N-1,M-1)0x0B
LPC_SC->PLL0CFG = 0x0B;
LPC_SC->PLL0FEED |= 0xAA;
LPC_SC->PLL0FEED |= 0x55;
// Step 6 - Enable PLL
LPC_SC->PLL0CON = CLKPWR_PLL0CON_ENABLE;
LPC_SC->PLL0FEED |= 0xAA;
LPC_SC->PLL0FEED |= 0x55;
// Step 7 - already done in step 3
// Step 8 - Wait for PLL to lock
while ((LPC_SC->PLL0STAT & CLKPWR_PLL0STAT_PLOCK) == 0); <---always stuck here
// Step 10 - Connect the system clock to the PLL
LPC_SC->PLL0CON |= CLKPWR_PLL0CON_CONNECT; // Connect PLL0 now it is locked
LPC_SC->PLL0FEED |= 0xAA;
LPC_SC->PLL0FEED |= 0x55;
I would recommend that you look at the LPC17xx example code we have available for download from:
<a href="http://www.lpcware.com/node/11538/129">http://www.lpcware.com/node/11538/129</a>
Take a look at the system_LPC17xx.c file for details.
The only thing I could see as a potential problem were the statements:
LPC_SC->PLL0FEED |= 0xAA;
LPC_SC->PLL0FEED |= 0x55;
Note that the PLL0FEED register is a write-only register, so the feed sequence should be:
LPC_SC->PLL0FEED = 0xAA;
LPC_SC->PLL0FEED = 0x55;