| LPCOpen Platform v1.03 LPCOpen Platform for NXP LPC Microcontrollers

- Main Page
- Modules
- Data Structures
- Files
- Related Pages

- File List
- Globals

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
clock_18xx_43xx.c
Go to the documentation of this file.
1 /*
2 * @brief LPC18xx/43xx clock driver
3 *
4 * @note
5 * Copyright(C) NXP Semiconductors, 2012
6 * All rights reserved.
7 *
8 * @par
9 * Software that is described herein is for illustrative purposes only
10 * which provides customers with programming information regarding the
11 * LPC products. This software is supplied "AS IS" without any warranties of
12 * any kind, and NXP Semiconductors and its licenser disclaim any and
13 * all warranties, express or implied, including all implied warranties of
14 * merchantability, fitness for a particular purpose and non-infringement of
15 * intellectual property rights. NXP Semiconductors assumes no responsibility
16 * or liability for the use of the software, conveys no license or rights under any
17 * patent, copyright, mask work right, or any other intellectual property rights in
18 * or to any products. NXP Semiconductors reserves the right to make changes
19 * in the software without notification. NXP Semiconductors also makes no
20 * representation or warranty that such application will be suitable for the
21 * specified use without further testing or modification.
22 *
23 * @par
24 * Permission to use, copy, modify, and distribute this software and its
25 * documentation is hereby granted, under NXP Semiconductors' and its
26 * licensor's relevant copyrights in the software, without fee, provided that it
27 * is used in conjunction with NXP Semiconductors microcontrollers. This
28 * copyright, permission, and disclaimer notice must appear in all copies of
29 * this code.
30 */
31
32 #include "chip.h"
33
34 /*****************************************************************************
35 * Private types/enumerations/variables
36 ****************************************************************************/
37
38 /* Maps a peripheral clock to it's base clock */
39 typedef struct {
40 CHIP_CCU_CLK_T clkstart;
41 CHIP_CCU_CLK_T clkend;
42 CHIP_CGU_BASE_CLK_T clkbase;
43 } CLK_PERIPH_TO_BASE_T;
44 static const CLK_PERIPH_TO_BASE_T periph_to_base[] = {
45 {CLK_APB3_BUS, CLK_APB3_CAN0, CLK_BASE_APB3},
46 {CLK_APB1_BUS, CLK_APB1_CAN1, CLK_BASE_APB1},
47 {CLK_SPIFI, CLK_SPIFI, CLK_BASE_SPIFI},
48 {CLK_MX_BUS, CLK_MX_QEI, CLK_BASE_MX},
49 #if 0
50 #if defined(CHIP_LPC43XX)
51 {CLK_PERIPH_BUS, CLK_PERIPH_SGPIO, CLK_BASE_PERIPH},
52 #endif
53 {CLK_USB0, CLK_USB0, CLK_BASE_USB0},
54 {CLK_USB1, CLK_USB1, CLK_BASE_USB1},
55 #if defined(CHIP_LPC43XX)
56 {CLK_SPI, CLK_SPI, CLK_BASE_SPI},
57 {CLK_VADC, CLK_VADC, CLK_BASE_VADC},
58 #endif
59 {CLK_APLL, CLK_APLL, CLK_BASE_APLL},
60 {CLK_APB2_UART3, CLK_APB2_UART3, CLK_BASE_UART3},
61 {CLK_APB2_UART2, CLK_APB2_UART2, CLK_BASE_UART2},
62 {CLK_APB2_UART1, CLK_APB2_UART1, CLK_BASE_UART1},
63 {CLK_APB2_UART0, CLK_APB2_UART0, CLK_BASE_UART0},
64 {CLK_APB2_SSP1, CLK_APB2_SSP1, CLK_BASE_SSP1},
65 {CLK_APB2_SSP0, CLK_APB2_SSP0, CLK_BASE_SSP0},
66 {CLK_APB2_SDIO, CLK_APB2_SDIO, CLK_BASE_SDIO},
67 {CLK_CCU2_LAST, CLK_CCU2_LAST, CLK_BASE_NONE}
68 #endif
69 };
70
71 /*****************************************************************************
72 * Public types/enumerations/variables
73 ****************************************************************************/
74
75 /*****************************************************************************
76 * Private functions
77 ****************************************************************************/
78
79 /* Test PLL input values for a specific frequency range */
80 static uint32_t Chip_Clock_TestMainPLLMultiplier(uint32_t InputHz, uint32_t TestMult, uint32_t MinHz, uint32_t MaxHz)
81 {
82 uint32_t TestHz = TestMult * InputHz;
83
84 if ((TestHz < MinHz) || (TestHz > MAX_CLOCK_FREQ) || (TestHz > MaxHz)) {
85 TestHz = 0;
86 }
87
88 return TestHz;
89 }
90
91 /* Returns clock rate out of a divider */
92 static uint32_t Chip_Clock_GetDivRate(CHIP_CGU_CLKIN_T clock, CHIP_CGU_IDIV_T divider)
93 {
94 CHIP_CGU_CLKIN_T input;
95 uint32_t div;
96
97 input = Chip_Clock_GetDividerSource(divider);
98 div = Chip_Clock_GetDividerDivisor(divider);
99 return Chip_Clock_GetClockInputHz(input) / (div + 1);
100 }
101
102 /* Finds the base clock for the peripheral clock */
103 static CHIP_CGU_BASE_CLK_T Chip_Clock_FindBaseClock(CHIP_CCU_CLK_T clk)
104 {
105 CHIP_CGU_BASE_CLK_T baseclk = CLK_BASE_NONE;
106 int i = 0;
107
108 while ((baseclk == CLK_BASE_NONE) && (periph_to_base[i].clkbase != baseclk)) {
109 if ((clk >= periph_to_base[i].clkstart) && (clk <= periph_to_base[i].clkend)) {
110 baseclk = periph_to_base[i].clkbase;
111 }
112 else {
113 i++;
114 }
115 }
116
117 return baseclk;
118 }
119
120 /*****************************************************************************
121 * Public functions
122 ****************************************************************************/
123
124 /* Enables the crystal oscillator */
125 void Chip_Clock_EnableCrystal(void)
126 {
127 uint32_t OldCrystalConfig = LPC_CGU->XTAL_OSC_CTRL;
128
129 /* Clear bypass mode */
130 OldCrystalConfig &= (~2);
131 if (OldCrystalConfig != LPC_CGU->XTAL_OSC_CTRL) {
132 LPC_CGU->XTAL_OSC_CTRL = OldCrystalConfig;
133 }
134
135 /* Enable crystal oscillator */
136 OldCrystalConfig &= (~1);
137 if (CRYSTAL_MAIN_FREQ_IN >= 20000000) {
138 OldCrystalConfig |= 4; /* Set high frequency mode */
139
140 }
141 LPC_CGU->XTAL_OSC_CTRL = OldCrystalConfig;
142 }
143
144 /* Disables the crystal oscillator */
145 void Chip_Clock_DisableCrystal(void)
146 {
147 /* Disable crystal oscillator */
148 LPC_CGU->XTAL_OSC_CTRL &= (~1);
149 }
150
151 /* Configures the main PLL */
152 uint32_t Chip_Clock_SetupMainPLLHz(CHIP_CGU_CLKIN_T Input, uint32_t MinHz, uint32_t DesiredHz, uint32_t MaxHz)
153 {
154 uint32_t freqin = Chip_Clock_GetClockInputHz(Input);
155 uint32_t Mult, LastMult, MultEnd;
156 uint32_t freqout, freqout2;
157
158 if (DesiredHz != 0xFFFFFFFF) {
159 /* Test DesiredHz rounded down */
160 Mult = DesiredHz / freqin;
161 freqout = Chip_Clock_TestMainPLLMultiplier(freqin, Mult, MinHz, MaxHz);
162
163 /* Test DesiredHz rounded up */
164 Mult++;
165 freqout2 = Chip_Clock_TestMainPLLMultiplier(freqin, Mult, MinHz, MaxHz);
166
167 if (freqout && !freqout2) { /* rounding up is no good? set first multiplier */
168 Mult--;
169 return Chip_Clock_SetupMainPLLMult(Input, Mult);
170 }
171 if (!freqout && freqout2) { /* didn't work until rounded up? set 2nd multiplier */
172 return Chip_Clock_SetupMainPLLMult(Input, Mult);
173 }
174
175 if (freqout && freqout2) { /* either multiplier okay? choose closer one */
176 if ((DesiredHz - freqout) > (freqout2 - DesiredHz)) {
177 Mult--;
178 return Chip_Clock_SetupMainPLLMult(Input, Mult);
179 }
180 else {
181 return Chip_Clock_SetupMainPLLMult(Input, Mult);
182 }
183 }
184 }
185
186 /* Neither multiplier okay? Try to start at MinHz and increment.
187 This should find the highest multiplier that is still good */
188 Mult = MinHz / freqin;
189 MultEnd = MaxHz / freqin;
190 LastMult = 0;
191 while (1) {
192 freqout = Chip_Clock_TestMainPLLMultiplier(freqin, Mult, MinHz, MaxHz);
193
194 if (freqout) {
195 LastMult = Mult;
196 }
197
198 if (Mult >= MultEnd) {
199 break;
200 }
201 Mult++;
202 }
203
204 if (LastMult) {
205 return Chip_Clock_SetupMainPLLMult(Input, LastMult);
206 }
207
208 return 0;
209 }
210
211 /* Directly set the PLL multipler */
212 uint32_t Chip_Clock_SetupMainPLLMult(CHIP_CGU_CLKIN_T Input, uint32_t mult)
213 {
214 uint32_t freq = Chip_Clock_GetClockInputHz(Input);
215 uint32_t msel = 0, nsel = 0, psel = 0, pval = 1;
216 uint32_t PLLReg = LPC_CGU->PLL1_CTRL;
217
218 freq *= mult;
219 msel = mult - 1;
220
221 PLLReg &= ~(0x1F << 24);/* clear input source bits */
222 PLLReg |= Input << 24; /* set input source bits to parameter */
223
224 /* Clear other PLL input bits */
225 PLLReg &= ~((1 << 6) | /* FBSEL */
226 (1 << 1) | /* BYPASS */
227 (1 << 7) | /* DIRECT */
228 (0x03 << 8) | (0xFF << 16) | (0x03 << 12)); /* PSEL, MSEL, NSEL- divider ratios */
229
230 if (freq < 156000000) {
231 /* psel is encoded such that 0=1, 1=2, 2=4, 3=8 */
232 while ((2 * (pval) * freq) < 156000000) {
233 psel++;
234 pval *= 2;
235 }
236
237 PLLReg |= (msel << 16) | (nsel << 12) | (psel << 8) | (1 << 6); /* dividers + FBSEL */
238 }
239 else if (freq < 320000000) {
240 PLLReg |= (msel << 16) | (nsel << 12) | (psel << 8) | (1 << 7) | (1 << 6); /* dividers + DIRECT + FBSEL */
241 }
242 else {
243 Chip_Clock_DisableMainPLL();
244 return 0;
245 }
246 LPC_CGU->PLL1_CTRL = PLLReg & ~(1 << 0);
247
248 return freq;
249 }
250
251 /* Returns the frequency of the main PLL */
252 uint32_t Chip_Clock_GetMainPLLHz(void)
253 {
254 uint32_t PLLReg = LPC_CGU->PLL1_CTRL;
255 uint32_t freq = Chip_Clock_GetClockInputHz((CHIP_CGU_CLKIN_T) ((PLLReg >> 24) & 0xF));
256 uint32_t msel, nsel, psel, direct, fbsel;
257 uint32_t m, n, p;
258 const uint8_t ptab[] = {1, 2, 4, 8};
259
260 /* No lock? */
261 if (!(LPC_CGU->PLL1_STAT & 1)) {
262 return 0;
263 }
264
265 msel = (PLLReg >> 16) & 0xFF;
266 nsel = (PLLReg >> 12) & 0x3;
267 psel = (PLLReg >> 8) & 0x3;
268 direct = (PLLReg >> 7) & 0x1;
269 fbsel = (PLLReg >> 6) & 0x1;
270
271 m = msel + 1;
272 n = nsel + 1;
273 p = ptab[psel];
274
275 if (direct || fbsel) {
276 return m * (freq / n);
277 }
278
279 return (m / (2 * p)) * (freq / n);
280 }
281
282 /* Disables the main PLL */
283 void Chip_Clock_DisableMainPLL(void)
284 {
285 /* power down main PLL */
286 LPC_CGU->PLL1_CTRL |= 1;
287 }
288
289 /* Disables the main PLL */
290 void Chip_Clock_EnableMainPLL(void)
291 {
292 /* power down main PLL */
293 LPC_CGU->PLL1_CTRL &= ~1;
294 }
295
296 /* Returns the lock status of the main PLL */
297 bool Chip_Clock_MainPLLLocked(void)
298 {
299 /* Return true if locked */
300 return (bool) (LPC_CGU->PLL1_STAT & 1);
301 }
302
303 /* Sets up a CGU clock divider and it's input clock */
304 void Chip_Clock_SetDivider(CHIP_CGU_IDIV_T Divider, CHIP_CGU_CLKIN_T Input, uint32_t Divisor)
305 {
306 uint32_t reg = LPC_CGU->IDIV_CTRL[Divider];
307
308 Divisor--;
309
310 if (Input != CLKINPUT_PD) {
311 /* Mask off bits that need to changes */
312 reg &= ~((0x1F << 24) | 1 | (0xF << 2));
313
314 /* Enable autoblocking, clear PD, and set clock source & divisor */
315 LPC_CGU->IDIV_CTRL[Divider] = reg | (1 << 11) | (Input << 24) | (Divisor << 2);
316 }
317 else {
318 LPC_CGU->IDIV_CTRL[Divider] = reg | 1; /* Power down this divider */
319 }
320 }
321
322 /* Gets a CGU clock divider source */
323 CHIP_CGU_CLKIN_T Chip_Clock_GetDividerSource(CHIP_CGU_IDIV_T Divider)
324 {
325 uint32_t reg = LPC_CGU->IDIV_CTRL[Divider];
326
327 if (reg & 1) { /* divider is powered down */
328 return CLKINPUT_PD;
329 }
330
331 return (CHIP_CGU_CLKIN_T) ((reg >> 24) & 0x1F);
332 }
333
334 /* Gets a CGU clock divider divisor */
335 uint32_t Chip_Clock_GetDividerDivisor(CHIP_CGU_IDIV_T Divider)
336 {
337 return (CHIP_CGU_CLKIN_T) ((LPC_CGU->IDIV_CTRL[Divider] >> 2) & 0xF);
338 }
339
340 /* Returns the frequency of the specified input clock source */
341 uint32_t Chip_Clock_GetClockInputHz(CHIP_CGU_CLKIN_T input)
342 {
343 uint32_t rate = 0;
344
345 switch (input) {
346 case CLKIN_32K:
347 rate = CRYSTAL_32K_FREQ_IN;
348 break;
349
350 case CLKIN_IRC:
351 rate = CGU_IRC_FREQ;
352 break;
353
354 case CLKIN_ENET_RX:
355 #if defined(USE_RMII)
356 /* In RMII mode, this clock is not attached */
357 #else
358 /* MII mode requires 25MHz clock */
359 rate = 25000000;
360 #endif
361 break;
362
363 case CLKIN_ENET_TX:
364 #if defined(USE_RMII)
365 /* MII mode requires 50MHz clock */
366 rate = 50000000;
367 #else
368 /* MII mode requires 25MHz clock */
369 rate = 25000000;
370 #endif
371 break;
372
373 case CLKIN_CLKIN:
374 #if defined(EXTERNAL_CLKIN_FREQ_IN)
375 rate = EXTERNAL_CLKIN_FREQ_IN;
376 #else
377 /* Assume no clock in if a rate wasn't defined */
378 #endif
379 break;
380
381 case CLKIN_CRYSTAL:
382 rate = CRYSTAL_MAIN_FREQ_IN;
383 break;
384
385 case CLKIN_USBPLL:
386 rate = CGU_USB_PLL_RATE;
387 break;
388
389 case CLKIN_AUDIOPLL:
390 rate = CGU_AUDIO_PLL_RATE;
391 break;
392
393 case CLKIN_MAINPLL:
394 rate = Chip_Clock_GetMainPLLHz();
395 break;
396
397 case CLKIN_IDIVA:
398 rate = Chip_Clock_GetDivRate(input, CLK_IDIV_A);
399 break;
400
401 case CLKIN_IDIVB:
402 rate = Chip_Clock_GetDivRate(input, CLK_IDIV_B);
403 break;
404
405 case CLKIN_IDIVC:
406 rate = Chip_Clock_GetDivRate(input, CLK_IDIV_C);
407 break;
408
409 case CLKIN_IDIVD:
410 rate = Chip_Clock_GetDivRate(input, CLK_IDIV_D);
411 break;
412
413 case CLKIN_IDIVE:
414 rate = Chip_Clock_GetDivRate(input, CLK_IDIV_E);
415 break;
416
417 case CLKINPUT_PD:
418 rate = 0;
419 break;
420
421 default:
422 break;
423 }
424
425 return rate;
426 }
427
428 /* Returns the frequency of the specified base clock source */
429 uint32_t Chip_Clock_GetBaseClocktHz(CHIP_CGU_BASE_CLK_T clock)
430 {
431 return Chip_Clock_GetClockInputHz(Chip_Clock_GetBaseClock(clock));
432 }
433
434 /* Sets a CGU Base Clock clock source */
435 void Chip_Clock_SetBaseClock(CHIP_CGU_BASE_CLK_T BaseClock, CHIP_CGU_CLKIN_T Input, bool autoblocken, bool powerdn)
436 {
437 uint32_t reg = LPC_CGU->BASE_CLK[BaseClock];
438
439 if (BaseClock < CLK_BASE_NONE) {
440 if (Input != CLKINPUT_PD) {
441 /* Mask off fields we plan to update */
442 reg &= ~((0x1F << 24) | 1 | (1 << 11));
443
444 if (autoblocken) {
445 reg |= (1 << 11);
446 }
447 if (powerdn) {
448 reg |= (1 << 0);
449 }
450
451 /* Set clock source */
452 reg |= (Input << 24);
453
454 LPC_CGU->BASE_CLK[BaseClock] = reg;
455 }
456 }
457 else {
458 LPC_CGU->BASE_CLK[BaseClock] = reg | 1; /* Power down this base clock */
459 }
460 }
461
462 /* Reads CGU Base Clock clock source information */
463 void Chip_Clock_GetBaseClockOpts(CHIP_CGU_BASE_CLK_T BaseClock, CHIP_CGU_CLKIN_T *Input, bool *autoblocken,
464 bool *powerdn)
465 {
466 uint32_t reg = LPC_CGU->BASE_CLK[BaseClock];
467 CHIP_CGU_CLKIN_T ClkIn = (CHIP_CGU_CLKIN_T) ((reg >> 24) & 0x1F );
468
469 if (BaseClock < CLK_BASE_NONE) {
470 /* Get settings */
471 *Input = ClkIn;
472 *autoblocken = (reg & (1 << 11)) ? true : false;
473 *powerdn = (reg & (1 << 0)) ? true : false;
474 }
475 else {
476 *Input = CLKINPUT_PD;
477 *powerdn = true;
478 *autoblocken = true;
479 }
480 }
481
482 /*Enables a base clock source */
483 void Chip_Clock_EnableBaseClock(CHIP_CGU_BASE_CLK_T BaseClock)
484 {
485 if (BaseClock < CLK_BASE_NONE) {
486 LPC_CGU->BASE_CLK[BaseClock] &= ~1;
487 }
488 }
489
490 /* Disables a base clock source */
491 void Chip_Clock_DisableBaseClock(CHIP_CGU_BASE_CLK_T BaseClock)
492 {
493 if (BaseClock < CLK_BASE_NONE) {
494 LPC_CGU->BASE_CLK[BaseClock] |= 1;
495 }
496 }
497
498 /* Returns base clock enable state */
499 bool Chip_Clock_IsBaseClockEnabled(CHIP_CGU_BASE_CLK_T BaseClock)
500 {
501 bool enabled;
502
503 if (BaseClock < CLK_BASE_NONE) {
504 enabled = (bool) ((LPC_CGU->BASE_CLK[BaseClock] & 1) == 0);
505 }
506 else {
507 enabled = false;
508 }
509
510 return enabled;
511 }
512
513 /* Gets a CGU Base Clock clock source */
514 CHIP_CGU_CLKIN_T Chip_Clock_GetBaseClock(CHIP_CGU_BASE_CLK_T BaseClock)
515 {
516 uint32_t reg;
517
518 if (BaseClock >= CLK_BASE_NONE) {
519 return CLKINPUT_PD;
520 }
521
522 reg = LPC_CGU->BASE_CLK[BaseClock];
523
524 /* base clock is powered down? */
525 if (reg & 1) {
526 return CLKINPUT_PD;
527 }
528
529 return (CHIP_CGU_CLKIN_T) ((reg >> 24) & 0x1F);
530 }
531
532 /* Enables a peripheral clock and sets clock states */
533 void Chip_Clock_EnableOpts(CHIP_CCU_CLK_T clk, bool autoen, bool wakeupen, int div)
534 {
535 uint32_t reg = 1;
536
537 if (autoen) {
538 reg |= (1 << 1);
539 }
540 if (wakeupen) {
541 reg |= (1 << 2);
542 }
543
544 /* Not all clocks support a divider, but we won't check that here. Only
545 dividers of 1 and 2 are allowed. Assume 1 if not 2 */
546 if (div == 2) {
547 reg |= (1 << 5);
548 }
549
550 /* Setup peripheral clock and start running */
551 if (clk >= CLK_CCU2_START) {
552 LPC_CCU2->CLKCCU[clk - CLK_CCU2_START].CFG = reg;
553 }
554 else {
555 LPC_CCU1->CLKCCU[clk].CFG = reg;
556 }
557 }
558
559 /* Enables a peripheral clock */
560 void Chip_Clock_Enable(CHIP_CCU_CLK_T clk)
561 {
562 /* Start peripheral clock running */
563 if (clk >= CLK_CCU2_START) {
564 LPC_CCU2->CLKCCU[clk - CLK_CCU2_START].CFG |= 1;
565 }
566 else {
567 LPC_CCU1->CLKCCU[clk].CFG |= 1;
568 }
569 }
570
571 /* Disables a peripheral clock */
572 void Chip_Clock_Disable(CHIP_CCU_CLK_T clk)
573 {
574 /* Stop peripheral clock */
575 if (clk >= CLK_CCU2_START) {
576 LPC_CCU2->CLKCCU[clk - CLK_CCU2_START].CFG &= ~1;
577 }
578 else {
579 LPC_CCU1->CLKCCU[clk].CFG &= ~1;
580 }
581 }
582
588 void Chip_Clock_StartPowerDown(void)
589 {
590 /* Set Power Down bit */
591 LPC_CCU1->PM = 1;
592 LPC_CCU2->PM = 1;
593 }
594
599 void Chip_Clock_ClearPowerDown(void)
600 {
601 /* Clear Power Down bit */
602 LPC_CCU1->PM = 0;
603 LPC_CCU2->PM = 0;
604 }
605
606 /* Returns a peripheral clock rate */
607 uint32_t Chip_Clock_GetRate(CHIP_CCU_CLK_T clk)
608 {
609 CHIP_CGU_BASE_CLK_T baseclk;
610 uint32_t reg, div, rate;
611
612 /* Get CCU config register for clock */
613 if (clk >= CLK_CCU2_START) {
614 reg = LPC_CCU2->CLKCCU[clk - CLK_CCU2_START].CFG;
615 }
616 else {
617 reg = LPC_CCU1->CLKCCU[clk].CFG;
618 }
619
620 /* Is the clock enabled? */
621 if (reg & 1) {
622 /* Get base clock for this peripheral clock */
623 baseclk = Chip_Clock_FindBaseClock(clk);
624
625 /* Get base clock rate */
626 rate = Chip_Clock_GetBaseClocktHz(baseclk);
627
628 /* Get divider for this clock */
629 if (((reg >> 5) & 0x7) == 0) {
630 div = 1;
631 }
632 else {
633 div = 2;/* No other dividers supported */
634
635 }
636 rate = rate / div;
637 }
638 else {
639 rate = 0;
640 }
641
642 return rate;
643 }
644
645 /* Sets up the audio or USB PLL */
646 void Chip_Clock_SetupPLL(CHIP_CGU_CLKIN_T Input, CHIP_CGU_USB_AUDIO_PLL_T pllnum,
647 const CGU_USBAUDIO_PLL_SETUP_T *pPLLSetup)
648 {
649 uint32_t reg = pPLLSetup->ctrl | (Input << 24);
650 /* Setup from passed values */
651 LPC_CGU->PLL[pllnum].PLL_CTRL = reg;
652 LPC_CGU->PLL[pllnum].PLL_MDIV = pPLLSetup->mdiv;
653 LPC_CGU->PLL[pllnum].PLL_NP_DIV = pPLLSetup->ndiv;
654
655 /* Fractional divider is for audio PLL only */
656 if (pllnum == pllnum) {
657 LPC_CGU->PLL0AUDIO_FRAC = pPLLSetup->fract;
658 }
659 }
660
661 /* Enables the audio or USB PLL */
662 void Chip_Clock_EnablePLL(CHIP_CGU_USB_AUDIO_PLL_T pllnum)
663 {
664 LPC_CGU->PLL[pllnum].PLL_CTRL &= ~1;
665 }
666
667 /* Disables the audio or USB PLL */
668 void Chip_Clock_DisablePLL(CHIP_CGU_USB_AUDIO_PLL_T pllnum)
669 {
670 LPC_CGU->PLL[pllnum].PLL_CTRL |= 1;
671 }
672
673 /* Returns the PLL status */
674 uint32_t Chip_Clock_GetPLLStatus(CHIP_CGU_USB_AUDIO_PLL_T pllnum)
675 {
676 return LPC_CGU->PLL[pllnum].PLL_STAT;
677 }