/* * pll0_run * ------------------------ * Starts the pll, waits for lock and * connects the system clock. * psel is low 2 bits of U8 * msel is low 5 bits of U8 * other bits are ignored. * Reference: User manual LPC314x p 40 * PLLCFG(0or1) PLL Configuration Register 7 | 6 5 | 4 0 | 0 | PSEL | MSEL | Only write 0 to bit 7 PSEL PLL Divider value PMUL PLL Multiplier value From the spec: LPC214x User Manual p39 If Fosc is 12Mhz (Olimex lpc2148 uses 12Mhz)... Then only two settings will keep these restraints: 10Mhz <= CCLK <= 60Mhz 156Mhz <= Fcco <= 320Mhz CCLK P M PSEL MSEL Fcco Fosc 48Mhz 2 4 1 3 192Mhz 12Mhz 12Mhz 8 1 3 0 192Mhz 12Mhz CCLK = M x Fosc Fcco = M x 2 x P Example: pll0_run(0x1,0x3) CCLK = 48Mhz, Fcco 192Mhz pll0_run(0x3, 0x0) CCLK = 12Mhz, Fcco 192Mhz APBDIV: 00 APB bus is 0.25 CCLK (reset value) 01 APB == CCLK 10 APB bus is 0.50 CCLK 11 NO EFFECT, SETTING UNCHANGED */ void pll0_run(U8 psel, U8 msel, U8 apbdiv) { U8 mselMask = 0x1f; U8 pselMask = 0x03; U8 apbdivMask = 0x03; // set the multiplier and divider values PLL0CFG = (0<<7) | ((psel&pselMask)<<5) | (msel&mselMask); // enable the pll. PLL0CON=0x1; pll0_feed(); // wait for pll lock while( ! (PLL0STAT & (0x1<<10)) ); // connect the pll to the system clock PLL0CON=0x3; pll0_feed(); // MAM // 0x2: Fully enabled. 0x4: 4 CCLK's fetch. write_MAM(0x2,0x4); // Peripheral clock divider? apbdiv &= apbdivMask; write_APBDIV(apbdiv); }
/* Initialize the PLL0. By using 12M oscillator, this set N to 1 and M to 12. PLL0 output frequency is 288MHz. CPU devider is set to 4 to get a 72M CPU clock. */ void pll0_init() { /* disconnect pll0 */ writeb(readb(PLL0CON) & ~0x02, PLL0CON); pll0_feed(); /* disable ppl0 */ writeb(readb(PLL0CON) & ~0x01, PLL0CON); pll0_feed(); /* N=1 M=12 */ writel(0x0000000B, PLL0CFG); pll0_feed(); /* Enable pll0. */ writeb(0x01, PLL0CON); pll0_feed(); /* set CPU clock devider to 4. */ writeb(0x04, CCLKSEL); /* wait the pll to lock. */ while(!(readl(PLL0STAT)&0x04000000)); /* connect pll0 */ writeb(0x03, PLL0CON); pll0_feed(); }