1 /***********************************************************************
2 * $Id: system_LPC43xx.c 8389 2011-10-19 13:53:14Z nxp28536 $
4 * Project: LPC43xx Common
7 * CMSIS Cortex-M4 Device Peripheral Access Layer Source File
8 * for the NXP LPC43xx Device Series
10 ***********************************************************************
11 * Software that is described herein is for illustrative purposes only
12 * which provides customers with programming information regarding the
13 * products. This software is supplied "AS IS" without any warranties.
14 * NXP Semiconductors assumes no responsibility or liability for the
15 * use of the software, conveys no license or title under any patent,
16 * copyright, or mask work right to the product. NXP Semiconductors
17 * reserves the right to make changes in the software without
18 * notification. NXP Semiconductors also make no representation or
19 * warranty that such application will be suitable for the specified
20 * use without further testing or modification.
21 **********************************************************************/
29 #include "LPC43xx_M0.h"
37 /*--------------------- Clock Configuration ----------------------------------*/
40 #define FLASHCFG_Val 0x0000303A
42 /*----------------------------------------------------------------------------
43 Check the register settings
44 *----------------------------------------------------------------------------*/
45 #define CHECK_RANGE(val, min, max) ((val < min) || (val > max))
46 #define CHECK_RSVD(val, mask) (val & mask)
48 /* Clock Configuration -------------------------------------------------------*/
49 #if (CHECK_RSVD((SCS_Val), ~0x00000030))
50 #error "SCS: Invalid values of reserved bits!"
53 #if (CHECK_RANGE((CLKSRCSEL_Val), 0, 2))
54 #error "CLKSRCSEL: Value out of range!"
57 #if (CHECK_RSVD((PLL0CFG_Val), ~0x00FF7FFF))
58 #error "PLL0CFG: Invalid values of reserved bits!"
61 #if (CHECK_RSVD((PLL1CFG_Val), ~0x0000007F))
62 #error "PLL1CFG: Invalid values of reserved bits!"
65 #if ((CCLKCFG_Val != 0) && (((CCLKCFG_Val - 1) % 2)))
66 #error "CCLKCFG: CCLKSEL field does not contain only odd values or 0!"
69 #if (CHECK_RSVD((USBCLKCFG_Val), ~0x0000000F))
70 #error "USBCLKCFG: Invalid values of reserved bits!"
73 #if (CHECK_RSVD((PCLKSEL0_Val), 0x000C0C00))
74 #error "PCLKSEL0: Invalid values of reserved bits!"
77 #if (CHECK_RSVD((PCLKSEL1_Val), 0x03000300))
78 #error "PCLKSEL1: Invalid values of reserved bits!"
81 #if (CHECK_RSVD((PCONP_Val), 0x10100821))
82 #error "PCONP: Invalid values of reserved bits!"
85 #if (CHECK_RSVD((CLKOUTCFG_Val), ~0x000001FF))
86 #error "CLKOUTCFG: Invalid values of reserved bits!"
89 /* Flash Accelerator Configuration -------------------------------------------*/
90 #if (CHECK_RSVD((FLASHCFG_Val), ~0x0000F07F))
91 #error "FLASHCFG: Invalid values of reserved bits!"
95 /*----------------------------------------------------------------------------
97 *----------------------------------------------------------------------------*/
98 uint32_t XtalFrequency = 0;
99 uint32_t PL160M_0Frequency = 0;
100 uint32_t PL160M_1Frequency = 0;
101 uint32_t PL160M_2Frequency = 0;
102 uint32_t PL550Frequency = 0;
103 uint32_t PL550FracFrequency = 0; //New in Falcon
104 uint32_t IDIVAFrequency = 0;
105 uint32_t IDIVBFrequency = 0;
106 uint32_t IDIVCFrequency = 0;
107 uint32_t IDIVDFrequency = 0;
108 uint32_t IDIVEFrequency = 0;
109 uint32_t USB1Frequency = 0;
110 uint32_t M4Frequency = 0;
111 uint32_t SPIFIFrequency = 0;
112 uint32_t SPIFrequency = 0;
113 uint32_t EnetRxFrequency = 0;
114 uint32_t EnetTxFrequency = 0;
115 uint32_t EXTFrequency = 0;
116 uint32_t VPB1Frequency = 0;
117 uint32_t VPB3Frequency = 0;
118 uint32_t LCDFrequency = 0;
119 uint32_t SCIFrequency = 0;
120 uint32_t VADCFrequency = 0;
121 uint32_t SDIOFrequency = 0;
122 uint32_t SSP0Frequency = 0;
123 uint32_t SSP1Frequency = 0;
124 uint32_t UART0Frequency = 0;
125 uint32_t UART1Frequency = 0;
126 uint32_t UART2Frequency = 0;
127 uint32_t UART3Frequency = 0;
128 uint32_t OUTFrequency = 0;
129 uint32_t AOTESTFrequency = 0;
130 uint32_t ISOFrequency = 0;
131 uint32_t BSRFrequency = 0;
132 uint32_t CLK_TESTFrequency = 0;
133 uint32_t APLLFrequency = 0;
134 uint32_t SPARE0Frequency = 0;
135 uint32_t SPARE1Frequency = 0;
138 * Initialize the system
143 * @brief Setup the microcontroller system.
146 void SystemInit(void)
148 // M4 runs on IRC by default
149 M4Frequency = IRC_OSC;
150 XtalFrequency = XTAL_FREQ;
151 EXTFrequency = EXT_FREQ;
157 * @param target PLL, source clock, division
160 * @brief Setup a clock
162 void SetClock(CLKBASE_Type target_clk, CLKSRC_Type src_clk, CLKDIV_Type div)
164 volatile uint32_t target_clk_adr;
165 volatile uint8_t auto_block=TRUE;
168 EnableSourceClk(src_clk);
172 case(DIV1): // Divide by 1 == no division
175 LPC_CGU->IDIVA_CTRL = (src_clk<<24) | (1<<2) | AUTO_BLOCK;
176 IDIVAFrequency = GetClockFrequency(src_clk)/2;
177 src_clk = SRC_IDIV_0; // Set new src_clk for target_clk
180 LPC_CGU->IDIVB_CTRL = (src_clk<<24) | (3<<2) |AUTO_BLOCK;
181 IDIVBFrequency = GetClockFrequency(src_clk)/4;
182 src_clk = SRC_IDIV_1; // Set new src_clk for target_clk
185 LPC_CGU->IDIVC_CTRL = (src_clk<<24) | (7<<2) |AUTO_BLOCK;
186 IDIVCFrequency = GetClockFrequency(src_clk)/8;
187 src_clk = SRC_IDIV_2; // Set new src_clk for target_clk
190 LPC_CGU->IDIVD_CTRL = (src_clk<<24) | (15<<2) |AUTO_BLOCK;
191 IDIVDFrequency = GetClockFrequency(src_clk)/16;
192 src_clk = SRC_IDIV_3; // Set new src_clk for target_clk
195 LPC_CGU->IDIVE_CTRL = (src_clk<<24) | (255<<2) |AUTO_BLOCK; // MAX 128? IDIV bit 2:9 = 7 bits = 127 max
196 IDIVEFrequency = GetClockFrequency(src_clk)/256;
197 src_clk = SRC_IDIV_4; // Set new src_clk for target_clk
203 src_freq = GetClockFrequency(src_clk);
209 LPC_SCU->SFSCLK_0 = 1; // function 1; CGU clk out, diable pull down, disable pull-up
215 XtalFrequency = (uint32_t) src_clk; // convert target clock directly to frequency
220 EnetRxFrequency = (uint32_t) src_clk; // convert target clock directly to frequency
225 EnetTxFrequency = (uint32_t) src_clk; // convert target clock directly to frequency
230 USB1Frequency = src_freq;
235 M4Frequency = src_freq;
238 case(BASE_SPIFI_CLK):
240 SPIFIFrequency = src_freq;
245 SPIFrequency = src_freq;
248 case(BASE_PHY_RX_CLK):
250 EnetRxFrequency = src_freq;
253 case(BASE_PHY_TX_CLK):
255 EnetTxFrequency = src_freq;
260 VPB1Frequency = src_freq;
265 VPB3Frequency = src_freq;
270 LCDFrequency = src_freq;
273 case (BASE_VADC_CLK) :
275 VADCFrequency = src_freq;
280 SDIOFrequency = src_freq;
285 SSP0Frequency = src_freq;
290 SSP1Frequency = src_freq;
293 case(BASE_UART0_CLK):
295 UART0Frequency = src_freq;
298 case(BASE_UART1_CLK):
300 UART1Frequency = src_freq;
303 case(BASE_UART2_CLK):
305 UART2Frequency = src_freq;
308 case(BASE_UART3_CLK):
310 UART3Frequency = src_freq;
313 case(BASE_AOTEST_CLK):
315 AOTESTFrequency = src_freq;
320 ISOFrequency = src_freq;
325 BSRFrequency = src_freq;
330 CLK_TESTFrequency = src_freq;
333 case(BASE_APLL_CLK): //New in Falcon
335 APLLFrequency = src_freq;
338 case(BASE_SPARE0_CLK): //New in Falcon
340 SPARE0Frequency = src_freq;
343 case(BASE_SPARE1_CLK): //New in Falcon
345 SPARE1Frequency = src_freq;
354 target_clk_adr = (uint32_t) &LPC_CGU->IDIVA_CTRL + (target_clk-2)*4;
355 *(uint32_t *)target_clk_adr = (src_clk<<24) | (auto_block<<11);
360 * Get Clock Frequency
362 * @param source clock
365 * @brief returns the current frequency of a base clock
367 uint32_t GetClockFrequency(CLKSRC_Type src_clk)
375 case(SRC_ENET_RX_CLK):
376 return EnetRxFrequency;
377 case(SRC_ENET_TX_CLK):
378 return EnetTxFrequency;
382 return XtalFrequency;
384 return PL550Frequency;
385 case(SRC_PL550M_FRAC): //New in Falcon
386 return PL550FracFrequency;
388 return PL160M_0Frequency;
390 return PL160M_1Frequency;
392 return PL160M_2Frequency;
394 return IDIVAFrequency;
396 return IDIVBFrequency;
398 return IDIVCFrequency;
400 return IDIVDFrequency;
402 return IDIVEFrequency;
411 * @param source clock, desired frequency
414 * @brief Setup the PL160M PLL
415 * If frequency equals 0 then disable PLL
416 * Integer mode only (fbsel=1, direct=0)
417 * Fclkout = M * Fclkin/N
418 * Fcc0 = 2 * P * Fclkout = 2 * P * M * Fclkin/N
419 * msel+1 = feedback-divider value M (1 to 2^15)
420 * nsel+1 = pre-divider value N (1 to 2^8)
421 * psel+1 = post-divider value P(x2) (1 to 2^5)
423 void SetPL160M(CLKSRC_Type src_clk, uint32_t mult)
425 uint32_t msel=0, nsel=0, psel=0, pval=1;
427 // EnableSourceClk(src_clk);
431 LPC_CGU->PLL1_CTRL |= PD_ENABLE; // Power down PLL
432 DisableSourceClk(src_clk);
436 EnableSourceClk(src_clk);
441 PL160M_0Frequency = mult * RTC_CLK;
444 PL160M_0Frequency = mult * IRC_OSC;
446 case(SRC_ENET_RX_CLK):
447 PL160M_0Frequency = mult * EnetRxFrequency;
449 case(SRC_ENET_TX_CLK):
450 PL160M_0Frequency = mult * EnetTxFrequency;
453 PL160M_0Frequency = mult * EXTFrequency;
456 PL160M_0Frequency = mult * XtalFrequency;
459 PL160M_0Frequency = mult * IRC_OSC;
463 // CCO must be in range of 156 - 320 MHz
464 // Increase P if FCCO is too low.
466 //psel is encoded such that 0=1, 1=2, 2=4, 3=8
467 while(2*(pval)*PL160M_0Frequency < 156000000) {
471 // if(2*(pval)*PL160M_0Frequency > 320000000) {
472 // THIS IS OUT OF RANGE!!!
473 // HOW DO WE ASSERT IN SAMPLE CODE?
476 LPC_CGU->PLL1_CTRL = (src_clk<<24) | (msel<<16) | (nsel<<12) | (psel<<8) | FBSEL;
477 while((LPC_CGU->PLL1_STAT&1) == 0x0); // Wait for PLL lock
482 * Set PLL USB (PL550M)
487 * @brief Setup the USB PLL to 480 MHz
488 * If enable equals 0 then disable PLL
489 * Only clock sources IRC and XTAL are valid
490 * Mode1a only: Normal operating mode without post- and pre-divider
491 * Fclkout = 2 * M * Fclkin
492 * msel+1 = feedback-divider value M (1 to 2^15)
494 void SetPLLUSB(CLKSRC_Type src_clk, uint8_t enable)
498 LPC_CGU->PLL0USB_CTRL |= PD_ENABLE; // Power down PLL
502 // Setup PLL550 to generate 480MHz from 12 MHz crystal
503 LPC_CGU->PLL0USB_CTRL |= PD_ENABLE; // Power down PLL
505 LPC_CGU->PLL0USB_NP_DIV = (98<<0) | (514<<12);
506 // SELP SELI SELR MDEC
507 LPC_CGU->PLL0USB_MDIV = (0xB<<17)|(0x10<<22)|(0<<28)|(0x7FFA<<0);
508 LPC_CGU->PLL0USB_CTRL =(SRC_XTAL<<24) | (0x3<<2) | CLKEN;
510 // Set the USB0 clock source to PLL550 (480MHz)
511 LPC_CGU->BASE_USB0_CLK = (0<<0) | (1<<11) | (SRC_PL550M_0<<24);
513 while((LPC_CGU->PLL0USB_STAT&1) == 0x0); // Wait for PLL lock
516 PL550Frequency = 480000000UL;
520 * Enable source clock pheripheral
522 * @param clock source
525 * @brief Enable clock specific peripherals
527 void EnableSourceClk(CLKSRC_Type src_clk)
530 const uint32_t PlainEnable = (0x2 << 3); /* no pull up, no pull down (plain) */
533 if(src_clk == SRC_OSC32K)
535 LPC_CREG->CREG0 &= ~((1<<3)|(1<<2)); // Active mode of 32 KHz osc and release reset
536 LPC_CREG->CREG0 |= (1<<1)|(1<<0); // Enable 32 kHz & 1 kHz on osc32k
538 if(src_clk == SRC_ENET_RX_CLK)scu_pinmux(0xC ,0 , PlainEnable, FUNC3); // enet_rx_clk on PC_0 func 3
539 if(src_clk == SRC_ENET_TX_CLK)scu_pinmux(0x1 ,19, PlainEnable, FUNC0); // enet_tx_clk on P1_19 func 0
540 if(src_clk == SRC_XTAL && (LPC_CGU->XTAL_OSC_CTRL&0x1))
542 LPC_CGU->XTAL_OSC_CTRL &= ~(1<<0); // Enable Xo50M
543 for(i=0;i<0xFFFF;i++);
548 * Disable source clock pheripheral
550 * @param clock source
553 * @brief Disable clock specific peripherals
555 void DisableSourceClk(CLKSRC_Type src_clk)
558 const uint32_t PlainEnable = (0x2 << 3); /* no pull up, no pull down (plain) */
560 if(src_clk == SRC_OSC32K)
562 LPC_CREG->CREG0 &= ~((1<<1)|(1<<0)); // Disable 32 kHz & 1 kHz on osc32k
563 LPC_CREG->CREG0 |= ((1<<3)|(1<<2)); // osc32k in power down and in reset mode
565 if(src_clk == SRC_ENET_RX_CLK)scu_pinmux(0xC ,0 , PlainEnable, FUNC0); // nc on PC_0 func 0
566 if(src_clk == SRC_ENET_TX_CLK)scu_pinmux(0x1 ,19, PlainEnable, FUNC2); // nc on P1_19 func 2
567 if(src_clk == SRC_XTAL)
569 LPC_CGU->XTAL_OSC_CTRL = (1<<0); // Disable Xo50M
570 for(i=0;i<0xFFFF;i++);