]> git.gir.st - tmk_keyboard.git/blob - tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC15XX/system_LPC15xx.c
remove experimental return, cleanup slash_question key
[tmk_keyboard.git] / tmk_core / tool / mbed / mbed-sdk / libraries / mbed / targets / cmsis / TARGET_NXP / TARGET_LPC15XX / system_LPC15xx.c
1 /**************************************************************************//**
2 * @file system_LPC15xx.c
3 * @brief CMSIS Cortex-M3 Device System Source File for
4 * NXP LPC15xx Device Series
5 * @version V1.00
6 * @date 19. July 2013
7 *
8 * @note
9 * Copyright (C) 2013 ARM Limited. All rights reserved.
10 *
11 * @par
12 * ARM Limited (ARM) is supplying this software for use with Cortex-M
13 * processor based microcontrollers. This file can be freely distributed
14 * within development tools that are supporting such ARM based processors.
15 *
16 * @par
17 * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
18 * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
20 * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
21 * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
22 *
23 ******************************************************************************/
24
25
26 #include <stdint.h>
27 #include "LPC15xx.h"
28
29 /*
30 //-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
31 */
32
33 /*- SystemCoreClock Configuration -------------------------------------------*/
34 // <e0> SystemCoreClock Configuration
35 #define CLOCK_SETUP 1
36 //
37 // <h> System Oscillator Control (SYSOSCCTRL)
38 // <o.0> BYPASS: System Oscillator Bypass Enable
39 // <i> If enabled then PLL input (sys_osc_clk) is fed
40 // <i> directly from XTALIN and XTALOUT pins.
41 // <o.1> FREQRANGE: System Oscillator Frequency Range
42 // <i> Determines frequency range for Low-power oscillator.
43 // <0=> 1 - 20 MHz
44 // <1=> 15 - 25 MHz
45 // </h>
46 #define SYSOSCCTRL_Val 0x00000000 // Reset value: 0x000
47 //
48 // <o.0..1> System PLL Clock Source Select (SYSPLLCLKSEL)
49 // <0=> IRC Oscillator
50 // <1=> Crystal Oscillator (SYSOSC)
51 #define SYSPLLCLKSEL_Val 0x00000001 // Reset value: 0x000
52 //
53 // <e> Clock Configuration (Manual)
54 #define CLOCK_SETUP_REG 1
55 //
56 // <o.0..1> Main Clock Source Select A (MAINCLKSELA)
57 // <0=> IRC Oscillator
58 // <1=> System Oscillator
59 // <2=> WD Oscillator
60 #define MAINCLKSELA_Val 0x00000001 // Reset value: 0x000
61 //
62 // <o.0..1> Main Clock Source Select B (MAINCLKSELB)
63 // <0=> MAINCLKSELA
64 // <1=> System PLL Input
65 // <2=> System PLL Output
66 // <3=> RTC Oscillator
67 #define MAINCLKSELB_Val 0x00000002 // Reset value: 0x000
68 //
69 // <h> System PLL Setting (SYSPLLCTRL)
70 // <i> F_clkout = M * F_clkin = F_CCO / (2 * P)
71 // <i> F_clkin must be in the range of 10 MHz to 25 MHz
72 // <i> F_CCO must be in the range of 156 MHz to 320 MHz
73 // <o.0..5> MSEL: Feedback Divider Selection
74 // <i> M = MSEL + 1
75 // <0-31>
76 // <o.5..7> PSEL: Post Divider Selection
77 // <i> Post divider ratio P. Division ratio is 2 * P
78 // <0=> P = 1
79 // <1=> P = 2
80 // <2=> P = 4
81 // <3=> P = 8
82 // </h>
83 #define SYSPLLCTRL_Val 0x00000005 // Reset value: 0x000
84 //
85 // <o.0..7> System AHB Clock Divider (SYSAHBCLKDIV.DIV)
86 // <i> Divides main clock to provide system clock to core, memories, and peripherals.
87 // <i> 0 = is disabled
88 // <0-255>
89 #define SYSAHBCLKDIV_Val 0x00000001 // Reset value: 0x001
90 // </e>
91 //
92 // <e> Clock Configuration (via ROM PLL API)
93 #define CLOCK_SETUP_API 0
94 //
95 // <o> PLL API Mode Select
96 // <0=> Exact
97 // <1=> Less than or equal
98 // <2=> Greater than or equal
99 // <3=> As close as possible
100 #define PLL_API_MODE_Val 0
101 //
102 // <o> CPU Frequency [Hz] <1000000-72000000:1000>
103 #define PLL_API_FREQ_Val 72000000
104 // </e>
105 //
106 // <e> USB Clock Configuration
107 #define USB_CLOCK_SETUP 0
108 // <h> USB PLL Control (USBPLLCTRL)
109 // <i> F_clkout = M * F_clkin = F_CCO / (2 * P)
110 // <i> F_clkin must be in the range of 10 MHz to 25 MHz
111 // <i> F_CCO must be in the range of 156 MHz to 320 MHz
112 // <o.0..5> MSEL: Feedback Divider Selection
113 // <i> M = MSEL + 1
114 // <0-31>
115 // <o.7..6> PSEL: Post Divider Selection
116 // <i> Post divider ratio P. Division ratio is 2 * P
117 // <0=> P = 1
118 // <1=> P = 2
119 // <2=> P = 4
120 // <3=> P = 8
121 // </h>
122 #define USBPLLCTRL_Val 0x00000023 // Reset value: 0x000
123 //
124 // <o.0..1> USB PLL Clock Source Select (USBPLLCLKSEL.SEL)
125 // <0=> IRC Oscillator
126 // <1=> System Oscillator
127 #define USBPLLCLKSEL_Val 0x00000001 // Reset value: 0x000
128 //
129 // <o.0..1> USB Clock Source Select (USBCLKSEL.SEL)
130 // <0=> IRC Oscillator
131 // <1=> System Oscillator
132 // <2=> USB PLL out
133 // <3=> Main clock
134 #define USBCLKSEL_Val 0x00000002 // Reset value: 0x000
135 //
136 // <o.0..7> USB Clock Divider (USBCLKDIV.DIV)
137 // <i> Divides USB clock to 48 MHz.
138 // <i> 0 = is disabled
139 // <0-255>
140 #define USBCLKDIV_Val 0x00000001 // Reset Value: 0x001
141 // </e>
142 //
143 // <e> SCT Clock Configuration
144 #define SCT_CLOCK_SETUP 1
145 // <h> SCT PLL Control (SCTPLLCTRL)
146 // <i> F_clkout = M * F_clkin = F_CCO / (2 * P)
147 // <i> F_clkin must be in the range of 10 MHz to 25 MHz
148 // <i> F_CCO must be in the range of 156 MHz to 320 MHz
149 // <o.0..5> MSEL: Feedback Divider Selection
150 // <i> M = MSEL + 1
151 // <0-31>
152 // <o.7..6> PSEL: Post Divider Selection
153 // <i> Post divider ratio P. Division ratio is 2 * P
154 // <0=> P = 1
155 // <1=> P = 2
156 // <2=> P = 4
157 // <3=> P = 8
158 // </h>
159 #define SCTPLLCTRL_Val 0x00000005 // Reset value: 0x000
160 //
161 // <o.0..1> SCT PLL Clock Source Select (SCTPLLCLKSEL.SEL)
162 // <0=> IRC Oscillator
163 // <1=> System Oscillator
164 #define SCTPLLCLKSEL_Val 0x00000001 // Reset value: 0x000
165 // </e>
166 //
167 // </e>
168 //
169 // <o0>System Oscillator (XTAL) Frequency [Hz] <1000000-25000000>
170 // <i> XTAL frequency must be in the range of 1 MHz to 25 MHz
171 //
172 #define XTAL_CLK_Val 12000000
173
174 /*
175 //-------- <<< end of configuration section >>> ------------------------------
176 */
177
178 /*----------------------------------------------------------------------------
179 Define clocks
180 *----------------------------------------------------------------------------*/
181 #define __XTAL_CLK ( XTAL_CLK_Val) /* Oscillator freq */
182 #define __SYS_OSC_CLK ( __XTAL_CLK) /* System oscillator freq */
183 #define __IRC_OSC_CLK ( 12000000UL) /* Internal RC oscillator freq */
184 #define __RTC_OSC_CLK ( 32768UL) /* RTC oscillator freq */
185 #define __WDT_OSC_CLK ( 503000UL) /* WDT oscillator freq */
186
187 /*----------------------------------------------------------------------------
188 Check the register settings
189 *----------------------------------------------------------------------------*/
190 #define CHECK_RANGE(val, min, max) ((val < min) || (val > max))
191 #define CHECK_RSVD(val, mask) (val & mask)
192
193 #if (CHECK_RANGE((SYSOSCCTRL_Val), 0, 1))
194 #error "SYSOSCCTRL: Invalid values of reserved bits!"
195 #endif
196
197 #if (CHECK_RANGE((SYSPLLCLKSEL_Val), 0, 3))
198 #error "SYSPLLCLKSEL: Value out of range!"
199 #endif
200
201 #if (CHECK_RSVD((SYSPLLCTRL_Val), ~0x000000FF))
202 #error "SYSPLLCTRL: Invalid values of reserved bits!"
203 #endif
204
205 #if (CHECK_RANGE((MAINCLKSELA_Val), 0, 2))
206 #error "MAINCLKSELA: Invalid values of reserved bits!"
207 #endif
208
209 #if (CHECK_RSVD((MAINCLKSELB_Val), ~0x00000003))
210 #error "MAINCLKSELB: Invalid values of reserved bits!"
211 #endif
212
213 #if (CHECK_RANGE((SYSAHBCLKDIV_Val), 0, 255))
214 #error "SYSAHBCLKDIV: Value out of range!"
215 #endif
216
217 #if ( CLOCK_SETUP_REG == CLOCK_SETUP_API )
218 #error "You must select either manual or API based Clock Configuration!"
219 #endif
220
221 #if (CHECK_RANGE((USBPLLCLKSEL_Val), 0, 1))
222 #error "USBPLLCLKSEL: Value out of range!"
223 #endif
224
225 #if (CHECK_RSVD((USBPLLCTRL_Val), ~0x00000FF))
226 #error "USBPLLCTRL: Invalid values of reserved bits!"
227 #endif
228
229 #if (CHECK_RANGE((USBCLKSEL_Val), 0, 3))
230 #error "USBCLKSEL: Value out of range!"
231 #endif
232
233 #if (CHECK_RANGE((USBCLKDIV_Val), 0, 255))
234 #error "USBCLKDIV: Value out of range!"
235 #endif
236
237 #if (CHECK_RANGE((SCTPLLCLKSEL_Val), 0, 1))
238 #error "SCTPLLCLKSEL: Value out of range!"
239 #endif
240
241 #if (CHECK_RSVD((SCTPLLCTRL_Val), ~0x00000FF))
242 #error "SCTPLLCTRL: Invalid values of reserved bits!"
243 #endif
244
245 #if (CHECK_RANGE(XTAL_CLK_Val, 1000000, 25000000))
246 #error "XTAL frequency is out of bounds"
247 #endif
248
249 #if (CHECK_RANGE(PLL_API_MODE_Val, 0, 3))
250 #error "PLL API Mode Select not valid"
251 #endif
252
253 #if (CHECK_RANGE(PLL_API_FREQ_Val, 1000000, 72000000))
254 #error "CPU Frequency (API mode) not valid"
255 #endif
256
257
258
259 /*----------------------------------------------------------------------------
260 Calculate system core clock
261 *----------------------------------------------------------------------------*/
262 #if (CLOCK_SETUP) /* Clock Setup */
263
264 /* sys_pllclkin calculation */
265 #if ((SYSPLLCLKSEL_Val & 0x03) == 0)
266 #define __SYS_PLLCLKIN (__IRC_OSC_CLK)
267 #elif ((SYSPLLCLKSEL_Val & 0x03) == 1)
268 #define __SYS_PLLCLKIN (__SYS_OSC_CLK)
269 #else
270 #error "Oops"
271 #endif
272
273 #if (CLOCK_SETUP_REG == 1) /* Clock Setup via Register */
274
275 #if ((MAINCLKSELA_Val & 0x03) == 0)
276 #define __MAINA_CLOCK (__IRC_OSC_CLK)
277 #elif ((MAINCLKSELA_Val & 0x03) == 1)
278 #define __MAINA_CLOCK (__SYS_OSC_CLK)
279 #elif ((MAINCLKSELA_Val & 0x03) == 2)
280 #define __MAINA_CLOCK (__WDT_OSC_CLK)
281 #else
282 #error "Oops"
283 #endif
284
285 #define __SYS_PLLCLKOUT (__SYS_PLLCLKIN * ((SYSPLLCTRL_Val & 0x01F) + 1))
286
287 /* main clock calculation */
288 #if ((MAINCLKSELB_Val & 0x03) == 0)
289 #define __MAINB_CLOCK (__MAINA_CLOCK)
290 #elif ((MAINCLKSELB_Val & 0x03) == 1)
291 #define __MAINB_CLOCK (__SYS_PLLCLKIN)
292 #elif ((MAINCLKSELB_Val & 0x03) == 2)
293 #define __MAINB_CLOCK (__SYS_PLLCLKOUT)
294 #elif ((MAINCLKSELB_Val & 0x03) == 3)
295 #define __MAINB_CLOCK (__RTC_OSC_CLK)
296 #else
297 #error "Oops"
298 #endif
299
300 #define __SYSTEM_CLOCK (__MAINB_CLOCK / SYSAHBCLKDIV_Val)
301 #endif /* Clock Setup via Register */
302
303 #if (CLOCK_SETUP_API == 1) /* Clock Setup via ROM API */
304 #define __SYSTEM_CLOCK (PLL_API_FREQ_Val)
305 #endif /* Clock Setup via PLL API */
306
307 #else
308 #define __SYSTEM_CLOCK (__IRC_OSC_CLK)
309 #endif /* CLOCK_SETUP */
310
311
312
313 #if ((CLOCK_SETUP == 1) && (CLOCK_SETUP_API == 1)) /* PLL Setup via PLL API */
314 #include "power_api.h"
315
316 typedef struct _ROM {
317 const unsigned p_dev0;
318 const unsigned p_dev1;
319 const unsigned p_dev2;
320 const PWRD * pPWRD; /* ROM Power Management API */
321 const unsigned p_dev4;
322 const unsigned p_dev5;
323 const unsigned p_dev6;
324 const unsigned p_dev7;
325 } ROM;
326
327 /*----------------------------------------------------------------------------
328 PLL API Function
329 *----------------------------------------------------------------------------*/
330 static void setPLL(const uint32_t pllMode, const uint32_t pllInFreq, const uint32_t reqCpuFreq)
331 {
332 uint32_t cmd[5], res[5];
333 ROM ** rom = (ROM **) 0x03000200; /* pointer to power API calls */
334
335 cmd[0] = pllInFreq; /* PLL's input freq in KHz */
336 cmd[1] = reqCpuFreq; /* requested CPU freq in KHz */
337 cmd[2] = pllMode;
338 cmd[3] = 0; /* no timeout for PLL to lock */
339
340 /* Execute API call */
341 (*rom)->pPWRD->set_pll(cmd, res); /* call API function */
342 if ((res[0] != PLL_CMD_SUCCESS)){ /* in case of an error ... */
343 while(1); /* ... stay here */
344 }
345 }
346 #endif
347
348
349
350
351 /*----------------------------------------------------------------------------
352 Clock Variable definitions
353 *----------------------------------------------------------------------------*/
354 uint32_t SystemCoreClock = __SYSTEM_CLOCK; /* System Clock Frequency */
355
356
357 /*----------------------------------------------------------------------------
358 Clock functions
359 *----------------------------------------------------------------------------*/
360 void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */
361 {
362 /* Determine clock frequency according to clock register values */
363 switch (LPC_SYSCON->MAINCLKSELB & 0x03) {
364 case 0: /* MAINCLKSELA clock sel */
365 switch (LPC_SYSCON->MAINCLKSELA & 0x03) {
366 case 0: /* Internal RC oscillator */
367 SystemCoreClock = __IRC_OSC_CLK;
368 break;
369 case 1: /* System oscillator */
370 SystemCoreClock = __SYS_OSC_CLK;
371 break;
372 case 2: /* Watchdog oscillator */
373 SystemCoreClock = __WDT_OSC_CLK;
374 break;
375 case 3: /* Reserved */
376 SystemCoreClock = 0;
377 break;
378 }
379 break;
380 case 1: /* Input Clock to System PLL */
381 switch (LPC_SYSCON->SYSPLLCLKSEL & 0x03) {
382 case 0: /* Internal RC oscillator */
383 SystemCoreClock = __IRC_OSC_CLK;
384 break;
385 case 1: /* System oscillator */
386 SystemCoreClock = __SYS_OSC_CLK;
387 break;
388 case 2: /* Reserved */
389 case 3: /* Reserved */
390 SystemCoreClock = 0;
391 break;
392 }
393 break;
394 case 2: /* System PLL Clock Out */
395 switch (LPC_SYSCON->SYSPLLCLKSEL & 0x03) {
396 case 0: /* Internal RC oscillator */
397 SystemCoreClock = __IRC_OSC_CLK * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1);
398 break;
399 case 1: /* System oscillator */
400 SystemCoreClock = __SYS_OSC_CLK * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1);
401 break;
402 case 2: /* Reserved */
403 case 3: /* Reserved */
404 SystemCoreClock = 0;
405 break;
406 }
407 break;
408 case 3: /* WDT Oscillator */
409 SystemCoreClock = __WDT_OSC_CLK;
410 break;
411 }
412
413 SystemCoreClock /= LPC_SYSCON->SYSAHBCLKDIV;
414
415 }
416
417 /**
418 * Initialize the system
419 *
420 * @param none
421 * @return none
422 *
423 * @brief Setup the microcontroller system.
424 */
425 void SystemInit (void) {
426 #if (CLOCK_SETUP)
427 volatile uint32_t i;
428 #endif
429
430 #if (CLOCK_SETUP) /* Clock Setup */
431
432 #if ((SYSPLLCLKSEL_Val & 0x03) == 1)
433 LPC_SYSCON->SYSOSCCTRL = SYSOSCCTRL_Val;
434 LPC_SYSCON->PDRUNCFG &= ~(1 << 21); /* Power-up sysosc */
435 for (i = 0; i < 200; i++) __NOP(); /* Wait for osc to stabilize */
436 #endif
437
438 LPC_SYSCON->SYSPLLCLKSEL = SYSPLLCLKSEL_Val; /* Select PLL Input */
439
440 #if (CLOCK_SETUP_REG == 1) /* Clock Setup via Register */
441
442 #if (((MAINCLKSELA_Val & 0x03) == 1) )
443 LPC_SYSCON->SYSOSCCTRL = SYSOSCCTRL_Val;
444 LPC_SYSCON->PDRUNCFG &= ~(1 << 21); /* Power-up sysosc */
445 for (i = 0; i < 200; i++) __NOP(); /* Wait for osc to stabilize */
446 #endif
447
448 #if (((MAINCLKSELA_Val & 0x03) == 2) )
449 LPC_SYSCON->PDRUNCFG &= ~(1 << 20); /* Power-up WDT Clock */
450 for (i = 0; i < 200; i++) __NOP(); /* Wait for osc to stabilize */
451 #endif
452
453 #if ((MAINCLKSELB_Val & 0x03) == 3)
454 LPC_SYSCON->RTCOSCCTRL = (1 << 0); /* Enable 32 kHz output */
455 for (i = 0; i < 200; i++) __NOP(); /* Wait for osc to stabilize */
456 #endif
457
458 LPC_SYSCON->MAINCLKSELA = MAINCLKSELA_Val; /* select MAINCLKA clock */
459
460 #if ((MAINCLKSELB_Val & 0x03) == 2) /* Main Clock is PLL Out */
461 LPC_SYSCON->SYSPLLCTRL = SYSPLLCTRL_Val;
462 LPC_SYSCON->PDRUNCFG &= ~(1 << 22); /* Power-up SYSPLL */
463 while (!(LPC_SYSCON->SYSPLLSTAT & 0x01)); /* Wait Until PLL Locked */
464 #endif
465
466 LPC_SYSCON->MAINCLKSELB = MAINCLKSELB_Val; /* select Main clock */
467
468 LPC_SYSCON->SYSAHBCLKDIV = SYSAHBCLKDIV_Val;
469 #endif /* Clock Setup via Register */
470
471 #if (CLOCK_SETUP_API == 1) /* Clock Setup via PLL API */
472 // LPC_SYSCON->SYSPLLCLKSEL = 0x00; /* Use IRC */
473
474 LPC_SYSCON->MAINCLKSELB = (1 << 2); /* Select System PLL output */
475
476 LPC_SYSCON->SYSAHBCLKDIV = 1;
477
478 setPLL(PLL_API_MODE_Val, __SYS_PLLCLKIN / 1000, PLL_API_FREQ_Val / 1000);
479 #endif /* Clock Setup via PLL API */
480
481 #if (USB_CLOCK_SETUP == 1) /* USB clock is used */
482 LPC_SYSCON->PDRUNCFG &= ~(1 << 9); /* Power-up USB PHY */
483
484 #if ((USBCLKSEL_Val & 0x003) == 2) /* USB clock is USB PLL out */
485 LPC_SYSCON->PDRUNCFG &= ~(1 << 23); /* Power-up USB PLL */
486 LPC_SYSCON->USBPLLCLKSEL = USBPLLCLKSEL_Val; /* Select PLL Input */
487
488 LPC_SYSCON->USBPLLCTRL = USBPLLCTRL_Val;
489 while (!(LPC_SYSCON->USBPLLSTAT & 0x01)); /* Wait Until PLL Locked */
490
491 LPC_SYSCON->USBCLKSEL = 0x02; /* Select USB PLL */
492 #endif
493
494 LPC_SYSCON->USBCLKSEL = USBCLKSEL_Val; /* Select USB Clock */
495 LPC_SYSCON->USBCLKDIV = USBCLKDIV_Val; /* Set USB clock divider */
496
497 #else /* USB clock is not used */
498 LPC_SYSCON->PDRUNCFG |= (1 << 9); /* Power-down USB PHY */
499 LPC_SYSCON->PDRUNCFG |= (1 << 23); /* Power-down USB PLL */
500 #endif
501
502 #if (SCT_CLOCK_SETUP == 1) /* SCT clock is used */
503 LPC_SYSCON->PDRUNCFG &= ~(1 << 24); /* Power-up SCT PLL */
504 LPC_SYSCON->SCTPLLCLKSEL = SCTPLLCLKSEL_Val; /* Select PLL Input */
505
506 LPC_SYSCON->SCTPLLCTRL = SCTPLLCTRL_Val;
507 while (!(LPC_SYSCON->SCTPLLSTAT & 0x01)); /* Wait Until PLL Locked */
508 #else /* SCT clock is not used */
509 LPC_SYSCON->PDRUNCFG |= (1 << 24); /* Power-down SCT PLL */
510 #endif
511
512 #endif /* Clock Setup */
513
514
515 LPC_SYSCON->SYSAHBCLKCTRL0 |= (1UL << 12); /* enable clock for SWM */
516
517 }
Imprint / Impressum