1 /* -----------------------------------------------------------------------------
2 * Copyright (c) 2013 - 2015 ARM Ltd.
3 *
4 * This software is provided 'as-is', without any express or implied warranty.
5 * In no event will the authors be held liable for any damages arising from
6 * the use of this software. Permission is granted to anyone to use this
7 * software for any purpose, including commercial applications, and to alter
8 * it and redistribute it freely, subject to the following restrictions:
9 *
10 * 1. The origin of this software must not be misrepresented; you must not
11 * claim that you wrote the original software. If you use this software in
12 * a product, an acknowledgment in the product documentation would be
13 * appreciated but is not required.
14 *
15 * 2. Altered source versions must be plainly marked as such, and must not be
16 * misrepresented as being the original software.
17 *
18 * 3. This notice may not be removed or altered from any source distribution.
19 *
20 * $Date: 26. August 2015
21 * $Revision: V5.0.1
22 *
23 * Project: NXP LPC18xx System initialization
24 * -------------------------------------------------------------------------- */
25
26 #include "LPC18xx.h"
27
28 /*----------------------------------------------------------------------------
29 This file configures the clocks as follows:
30 -----------------------------------------------------------------------------
31 Clock Unit | Output clock | Source clock | Note
32 -----------------------------------------------------------------------------
33 PLL0USB | 480 MHz | XTAL | External crystal @ 12 MHz
34 -----------------------------------------------------------------------------
35 PLL1 | 180 MHz | XTAL | External crystal @ 12 MHz
36 -----------------------------------------------------------------------------
37 CPU | 180 MHz | PLL1 | CPU Clock == BASE_M4_CLK
38 -----------------------------------------------------------------------------
39 IDIV A | 60 MHz | PLL1 | To the USB1 peripheral
40 -----------------------------------------------------------------------------
41 IDIV B | 25 MHz | ENET_TX_CLK | ENET_TX_CLK @ 50MHz
42 -----------------------------------------------------------------------------
43 IDIV C | 12 MHz | IRC | Internal oscillator @ 12 MHz
44 -----------------------------------------------------------------------------
45 IDIV D | 12 MHz | IRC | Internal oscillator @ 12 MHz
46 -----------------------------------------------------------------------------
47 IDIV E | 5.3 MHz | PLL1 | To the LCD controller
48 -----------------------------------------------------------------------------*/
49
50
51 /*----------------------------------------------------------------------------
52 Clock source selection definitions (do not change)
53 *----------------------------------------------------------------------------*/
54 #define CLK_SRC_32KHZ 0x00
55 #define CLK_SRC_IRC 0x01
56 #define CLK_SRC_ENET_RX 0x02
57 #define CLK_SRC_ENET_TX 0x03
58 #define CLK_SRC_GP_CLKIN 0x04
59 #define CLK_SRC_XTAL 0x06
60 #define CLK_SRC_PLL0U 0x07
61 #define CLK_SRC_PLL0A 0x08
62 #define CLK_SRC_PLL1 0x09
63 #define CLK_SRC_IDIVA 0x0C
64 #define CLK_SRC_IDIVB 0x0D
65 #define CLK_SRC_IDIVC 0x0E
66 #define CLK_SRC_IDIVD 0x0F
67 #define CLK_SRC_IDIVE 0x10
68
69
70 /*----------------------------------------------------------------------------
71 Define external input frequency values
72 *----------------------------------------------------------------------------*/
73 #define CLK_32KHZ 32768UL /* 32 kHz oscillator frequency */
74 #define CLK_IRC 12000000UL /* Internal oscillator frequency */
75 #define CLK_ENET_RX 50000000UL /* Ethernet Rx frequency */
76 #define CLK_ENET_TX 50000000UL /* Ethernet Tx frequency */
77 #define CLK_GP_CLKIN 12000000UL /* General purpose clock input freq. */
78 #define CLK_XTAL 12000000UL /* Crystal oscilator frequency */
79
80
81 /*----------------------------------------------------------------------------
82 Define clock sources
83 *----------------------------------------------------------------------------*/
84 #define PLL1_CLK_SEL CLK_SRC_XTAL /* PLL1 input clock: XTAL */
85 #define PLL0USB_CLK_SEL CLK_SRC_XTAL /* PLL0USB input clock: XTAL */
86 #define IDIVA_CLK_SEL CLK_SRC_PLL1 /* IDIVA input clock: PLL1 */
87 #define IDIVB_CLK_SEL CLK_SRC_ENET_TX /* IDIVB input clock: ENET TX */
88 #define IDIVC_CLK_SEL CLK_SRC_IRC /* IDIVC input clock: IRC */
89 #define IDIVD_CLK_SEL CLK_SRC_IRC /* IDIVD input clock: IRC */
90 #define IDIVE_CLK_SEL CLK_SRC_PLL1 /* IDIVD input clock: PLL1 */
91
92
93 /*----------------------------------------------------------------------------
94 Configure integer divider values
95 *----------------------------------------------------------------------------*/
96 #define IDIVA_IDIV 2 /* Divide input clock by 3 */
97 #define IDIVB_IDIV 1 /* Divide input clock by 2 */
98 #define IDIVC_IDIV 0 /* Divide input clock by 1 */
99 #define IDIVD_IDIV 0 /* Divide input clock by 1 */
100 #define IDIVE_IDIV 33 /* Divide input clock by 34 */
101
102
103 /*----------------------------------------------------------------------------
104 Define CPU clock input
105 *----------------------------------------------------------------------------*/
106 #define CPU_CLK_SEL CLK_SRC_PLL1 /* Default CPU clock source is PLL1 */
107
108
109 /*----------------------------------------------------------------------------
110 Configure external memory controller options
111 *----------------------------------------------------------------------------*/
112 #define USE_EXT_STAT_MEM_CS0 1 /* Use ext. static memory with CS0 */
113 #define USE_EXT_DYN_MEM_CS0 1 /* Use ext. dynamic memory with CS0 */
114
115
116 /*----------------------------------------------------------------------------
117 * Configure PLL1
118 *----------------------------------------------------------------------------
119 * Integer mode:
120 * - PLL1_DIRECT = 0 (Post divider enabled)
121 * - PLL1_FBSEL = 1 (Feedback divider runs from PLL output)
122 * - Output frequency:
123 * FCLKOUT = (FCLKIN / N) * M
124 * FCCO = FCLKOUT * 2 * P
125 *
126 * Non-integer:
127 * - PLL1_DIRECT = 0 (Post divider enabled)
128 * - PLL1_FBSEL = 0 (Feedback divider runs from CCO clock)
129 * - Output frequency:
130 * FCLKOUT = (FCLKIN / N) * M / (2 * P)
131 * FCCO = FCLKOUT * 2 * P
132 *
133 * Direct mode:
134 * - PLL1_DIRECT = 1 (Post divider disabled)
135 * - PLL1_FBSEL = dont care (Feedback divider runs from CCO clock)
136 * - Output frequency:
137 * FCLKOUT = (FCLKIN / N) * M
138 * FCCO = FCLKOUT
139 *
140 *----------------------------------------------------------------------------
141 * PLL1 requirements:
142 * | Frequency | Minimum | Maximum | Note |
143 * | FCLKIN | 1MHz | 25MHz | Clock source is external crystal |
144 * | FCLKIN | 1MHz | 50MHz | |
145 * | FCCO | 156MHz | 320MHz | |
146 * | FCLKOUT | 9.75MHz | 320MHz | |
147 *----------------------------------------------------------------------------
148 * Configuration examples:
149 * | Fclkout | Fcco | N | M | P | DIRECT | FBSEL | BYPASS |
150 * | 36MHz | 288MHz | 1 | 24 | 4 | 0 | 0 | 0 |
151 * | 72MHz | 288MHz | 1 | 24 | 2 | 0 | 0 | 0 |
152 * | 100MHz | 200MHz | 3 | 50 | 1 | 0 | 0 | 0 |
153 * | 120MHz | 240MHz | 1 | 20 | 1 | 0 | 0 | 0 |
154 * | 160MHz | 160MHz | 3 | 40 | x | 1 | 0 | 0 |
155 * | 180MHz | 180MHz | 1 | 15 | x | 1 | 0 | 0 |
156 *----------------------------------------------------------------------------
157 * Relations beetwen PLL dividers and definitions:
158 * N = PLL1_NSEL + 1, M = PLL1_MSEL + 1, P = 2 ^ PLL1_PSEL
159 *----------------------------------------------------------------------------*/
160
161 /* PLL1 output clock: 180MHz, Fcco: 180MHz, N = 1, M = 15, P = x */
162 #define PLL1_NSEL 0 /* Range [0 - 3]: Pre-divider ratio N */
163 #define PLL1_MSEL 14 /* Range [0 - 255]: Feedback-divider ratio M */
164 #define PLL1_PSEL 0 /* Range [0 - 3]: Post-divider ratio P */
165
166 #define PLL1_BYPASS 0 /* 0: Use PLL, 1: PLL is bypassed */
167 #define PLL1_DIRECT 1 /* 0: Use PSEL, 1: Don't use PSEL */
168 #define PLL1_FBSEL 0 /* 0: FCCO is used as PLL feedback */
169 /* 1: FCLKOUT is used as PLL feedback */
170
171
172 /*----------------------------------------------------------------------------
173 * Configure PLL0USB
174 *----------------------------------------------------------------------------
175 *
176 * Normal operating mode without post-divider and without pre-divider
177 * - PLL0USB_DIRECTI = 1
178 * - PLL0USB_DIRECTO = 1
179 * - PLL0USB_BYPASS = 0
180 * - Output frequency:
181 * FOUT = FIN * 2 * M
182 * FCCO = FOUT
183 *
184 * Normal operating mode with post-divider and without pre-divider
185 * - PLL0USB_DIRECTI = 1
186 * - PLL0USB_DIRECTO = 0
187 * - PLL0USB_BYPASS = 0
188 * - Output frequency:
189 * FOUT = FIN * (M / P)
190 * FCCO = FOUT * 2 * P
191 *
192 * Normal operating mode without post-divider and with pre-divider
193 * - PLL0USB_DIRECTI = 0
194 * - PLL0USB_DIRECTO = 1
195 * - PLL0USB_BYPASS = 0
196 * - Output frequency:
197 * FOUT = FIN * 2 * M / N
198 * FCCO = FOUT
199 *
200 * Normal operating mode with post-divider and with pre-divider
201 * - PLL0USB_DIRECTI = 0
202 * - PLL0USB_DIRECTO = 0
203 * - PLL0USB_BYPASS = 0
204 * - Output frequency:
205 * FOUT = FIN * M / (P * N)
206 * FCCO = FOUT * 2 * P
207 *----------------------------------------------------------------------------
208 * PLL0 requirements:
209 * | Frequency | Minimum | Maximum | Note |
210 * | FCLKIN | 14kHz | 25MHz | Clock source is external crystal |
211 * | FCLKIN | 14kHz | 150MHz | |
212 * | FCCO | 275MHz | 550MHz | |
213 * | FCLKOUT | 4.3MHz | 550MHz | |
214 *----------------------------------------------------------------------------
215 * Configuration examples:
216 * | Fclkout | Fcco | N | M | P | DIRECTI | DIRECTO | BYPASS |
217 * | 120MHz | 480MHz | x | 20 | 2 | 1 | 0 | 0 |
218 * | 480MHz | 480MHz | 1 | 20 | 1 | 1 | 1 | 0 |
219 *----------------------------------------------------------------------------*/
220
221 /* PLL0USB output clock: 480MHz, Fcco: 480MHz, N = 1, M = 20, P = 1 */
222 #define PLL0USB_N 1 /* Range [1 - 256]: Pre-divider */
223 #define PLL0USB_M 20 /* Range [1 - 2^15]: Feedback-divider */
224 #define PLL0USB_P 1 /* Range [1 - 32]: Post-divider */
225
226 #define PLL0USB_DIRECTI 1 /* 0: Use N_DIV, 1: Don't use N_DIV */
227 #define PLL0USB_DIRECTO 1 /* 0: Use P_DIV, 1: Don't use P_DIV */
228 #define PLL0USB_BYPASS 0 /* 0: Use PLL, 1: PLL is bypassed */
229
230
231 /*----------------------------------------------------------------------------
232 End of configuration
233 *----------------------------------------------------------------------------*/
234
235 /* PLL0 Setting Check */
236 #if (PLL0USB_BYPASS == 0)
237 #if (PLL0USB_CLK_SEL == CLK_SRC_XTAL)
238 #define PLL0USB_CLKIN CLK_XTAL
239 #else
240 #define PLL0USB_CLKIN CLK_IRC
241 #endif
242
243 #if ((PLL0USB_DIRECTI == 1) && (PLL0USB_DIRECTO == 1)) /* Mode 1a */
244 #define PLL0USB_FOUT (PLL0USB_CLKIN * 2 * PLL0USB_M)
245 #define PLL0USB_FCCO (PLL0USB_FOUT)
246 #elif ((PLL0USB_DIRECTI == 1) && (PLL0USB_DIRECTO == 0)) /* Mode 1b */
247 #define PLL0USB_FOUT (PLL0USB_CLKIN * PLL0USB_M / PLL0USB_P)
248 #define PLL0USB_FCCO (PLL0USB_FOUT * 2 * PLL0USB_P)
249 #elif ((PLL0USB_DIRECTI == 0) && (PLL0USB_DIRECTO == 1)) /* Mode 1c */
250 #define PLL0USB_FOUT (PLL0USB_CLKIN * 2 * PLL0USB_M / PLL0USB_N)
251 #define PLL0USB_FCCO (PLL0USB_FOUT)
252 #else /* Mode 1d */
253 #define PLL0USB_FOUT (PLL0USB_CLKIN * PLL0USB_M / (PLL0USB_P * PLL0USB_N))
254 #define PLL0USB_FCCO (PLL0USB_FOUT * 2 * PLL0USB_P)
255 #endif
256
257 #if (PLL0USB_FCCO < 275000000UL || PLL0USB_FCCO > 550000000UL)
258 #error "PLL0USB Fcco frequency out of range! (275MHz >= Fcco <= 550MHz)"
259 #endif
260 #if (PLL0USB_FOUT < 4300000UL || PLL0USB_FOUT > 550000000UL)
261 #error "PLL0USB output frequency out of range! (4.3MHz >= Fclkout <= 550MHz)"
262 #endif
263 #endif
264
265 /* PLL1 Setting Check */
266 #if (PLL1_BYPASS == 0)
267 #if (PLL1_CLK_SEL == CLK_SRC_XTAL)
268 #define PLL1_CLKIN CLK_XTAL
269 #else
270 #define PLL1_CLKIN CLK_IRC
271 #endif
272
273 #if (PLL1_DIRECT == 1) /* Direct Mode */
274 #define PLL1_FCCO ((PLL1_MSEL + 1) * (PLL1_CLKIN / (PLL1_NSEL + 1)))
275 #define PLL1_FOUT ((PLL1_MSEL + 1) * (PLL1_CLKIN / (PLL1_NSEL + 1)))
276 #elif (PLL1_FBSEL == 1) /* Integer Mode */
277 #define PLL1_FCCO ((2 * (1 << PLL1_PSEL)) * (PLL1_MSEL + 1) * (PLL1_CLKIN / (PLL1_NSEL + 1)))
278 #define PLL1_FOUT ((PLL1_MSEL + 1) * (PLL1_CLKIN / (PLL1_NSEL + 1)))
279 #else /* Noninteger Mode */
280 #define PLL1_FCCO ((PLL1_MSEL + 1) * (PLL1_CLKIN / (PLL1_NSEL + 1)))
281 #define PLL1_FOUT (PLL1_FCCO / (2 * (1 << PLL1_PSEL)))
282 #endif
283 #if (PLL1_FCCO < 156000000UL || PLL1_FCCO > 320000000UL)
284 #error "PLL1 Fcco frequency out of range! (156MHz >= Fcco <= 320MHz)"
285 #endif
286 #if (PLL1_FOUT < 9750000UL || PLL1_FOUT > 204000000UL)
287 #error "PLL1 output frequency out of range! (9.75MHz >= Fclkout <= 204MHz)"
288 #endif
289 #endif
290
291
292 /*----------------------------------------------------------------------------
293 System Core Clock variable
294 *----------------------------------------------------------------------------*/
295 uint32_t SystemCoreClock = CLK_IRC; /* System Clock Frequency (Core Clock) */
296
297
298 /******************************************************************************
299 * SetClock
300 ******************************************************************************/
SetClock(void)301 void SetClock (void) {
302 uint32_t x, i;
303 uint32_t selp, seli;
304
305 /* Set flash wait states to maximum */
306 LPC_EMC->STATICWAITRD0 = 0x1F;
307
308 /* Switch BASE_M3_CLOCK to IRC */
309 LPC_CGU->BASE_M3_CLK = (0x01 << 11) | /* Autoblock En */
310 (CLK_SRC_IRC << 24) ; /* Set clock source */
311
312 /* Configure input to crystal oscilator */
313 LPC_CGU->XTAL_OSC_CTRL = (0 << 0) | /* Enable oscillator-pad */
314 (0 << 1) | /* Operation with crystal connected */
315 (0 << 2) ; /* Low-frequency mode */
316
317 /* Wait ~250us @ 12MHz */
318 for (i = 1500; i; i--);
319
320 #if (USE_SPIFI)
321 /* configure SPIFI clk to IRC via IDIVA (later IDIVA is configured to PLL1/3) */
322 LPC_CGU->IDIVA_CTRL = (0 << 0) | /* Disable Power-down */
323 (0 << 2) | /* IDIV */
324 (1 << 11) | /* Autoblock En */
325 (CLK_SRC_IRC << 24) ; /* Clock source */
326
327 LPC_CGU->BASE_SPIFI_CLK = (0 << 0) | /* Disable Power-down */
328 (0 << 2) | /* IDIV */
329 (1 << 11) | /* Autoblock En */
330 (CLK_SRC_IDIVA << 24) ; /* Clock source */
331 #endif
332
333 /*----------------------------------------------------------------------------
334 PLL1 Setup
335 *----------------------------------------------------------------------------*/
336 /* Power down PLL */
337 LPC_CGU->PLL1_CTRL |= 1;
338
339 #if ((PLL1_FOUT > 110000000UL) && (CPU_CLK_SEL == CLK_SRC_PLL1))
340 /* To run at full speed, CPU must first run at an intermediate speed */
341 LPC_CGU->PLL1_CTRL = (0 << 0) | /* PLL1 Enabled */
342 (PLL1_BYPASS << 1) | /* CCO out sent to post-dividers */
343 (PLL1_FBSEL << 6) | /* PLL output used as feedback */
344 (0 << 7) | /* Direct on/off */
345 (PLL1_PSEL << 8) | /* PSEL */
346 (0 << 11)| /* Autoblock Disabled */
347 (PLL1_NSEL << 12)| /* NSEL */
348 (PLL1_MSEL << 16)| /* MSEL */
349 (PLL1_CLK_SEL << 24); /* Clock source */
350 /* Wait for lock */
351 while (!(LPC_CGU->PLL1_STAT & 1));
352
353 /* CPU base clock is in the mid frequency range before final clock set */
354 LPC_CGU->BASE_M3_CLK = (0x01 << 11) | /* Autoblock En */
355 (0x09 << 24) ; /* Clock source: PLL1 */
356
357 /* Max. BASE_M3_CLK frequency here is 102MHz, wait at least 20us */
358 for (i = 1050; i; i--); /* Wait minimum 2100 cycles */
359 #endif
360 /* Configure PLL1 */
361 LPC_CGU->PLL1_CTRL = (0 << 0) | /* PLL1 Enabled */
362 (PLL1_BYPASS << 1) | /* CCO out sent to post-dividers */
363 (PLL1_FBSEL << 6) | /* PLL output used as feedback */
364 (PLL1_DIRECT << 7) | /* Direct on/off */
365 (PLL1_PSEL << 8) | /* PSEL */
366 (1 << 11)| /* Autoblock En */
367 (PLL1_NSEL << 12)| /* NSEL */
368 (PLL1_MSEL << 16)| /* MSEL */
369 (PLL1_CLK_SEL << 24); /* Clock source */
370
371 /* Wait for lock */
372 while (!(LPC_CGU->PLL1_STAT & 1));
373
374 /* Set CPU base clock source */
375 LPC_CGU->BASE_M3_CLK = (0x01 << 11) | /* Autoblock En */
376 (CPU_CLK_SEL << 24) ; /* Set clock source */
377
378 /*----------------------------------------------------------------------------
379 PLL0USB Setup
380 *----------------------------------------------------------------------------*/
381
382 /* Power down PLL0USB */
383 LPC_CGU->PLL0USB_CTRL |= 1;
384
385 /* M divider */
386 x = 0x00004000;
387 switch (PLL0USB_M) {
388 case 0: x = 0xFFFFFFFF;
389 break;
390 case 1: x = 0x00018003;
391 break;
392 case 2: x = 0x00010003;
393 break;
394 default:
395 for (i = PLL0USB_M; i <= 0x8000; i++) {
396 x = (((x ^ (x >> 1)) & 1) << 14) | ((x >> 1) & 0x3FFF);
397 }
398 }
399
400 if (PLL0USB_M < 60) selp = (PLL0USB_M >> 1) + 1;
401 else selp = 31;
402
403 if (PLL0USB_M > 16384) seli = 1;
404 else if (PLL0USB_M > 8192) seli = 2;
405 else if (PLL0USB_M > 2048) seli = 4;
406 else if (PLL0USB_M >= 501) seli = 8;
407 else if (PLL0USB_M >= 60) seli = 4 * (1024 / (PLL0USB_M + 9));
408 else seli = (PLL0USB_M & 0x3C) + 4;
409 LPC_CGU->PLL0USB_MDIV = (selp << 17) |
410 (seli << 22) |
411 (x << 0);
412
413 /* N divider */
414 x = 0x80;
415 switch (PLL0USB_N) {
416 case 0: x = 0xFFFFFFFF;
417 break;
418 case 1: x = 0x00000302;
419 break;
420 case 2: x = 0x00000202;
421 break;
422 default:
423 for (i = PLL0USB_N; i <= 0x0100; i++) {
424 x =(((x ^ (x >> 2) ^ (x >> 3) ^ (x >> 4)) & 1) << 7) | ((x >> 1) & 0x7F);
425 }
426 }
427 LPC_CGU->PLL0USB_NP_DIV = (x << 12);
428
429 /* P divider */
430 x = 0x10;
431 switch (PLL0USB_P) {
432 case 0: x = 0xFFFFFFFF;
433 break;
434 case 1: x = 0x00000062;
435 break;
436 case 2: x = 0x00000042;
437 break;
438 default:
439 for (i = PLL0USB_P; i <= 0x200; i++) {
440 x = (((x ^ (x >> 2)) & 1) << 4) | ((x >> 1) &0x0F);
441 }
442 }
443 LPC_CGU->PLL0USB_NP_DIV |= x;
444
445 LPC_CGU->PLL0USB_CTRL = (PLL0USB_CLK_SEL << 24) | /* Clock source sel */
446 (1 << 11) | /* Autoblock En */
447 (1 << 4 ) | /* PLL0USB clock en */
448 (PLL0USB_DIRECTO << 3 ) | /* Direct output */
449 (PLL0USB_DIRECTI << 2 ) | /* Direct input */
450 (PLL0USB_BYPASS << 1 ) | /* PLL bypass */
451 (0 << 0 ) ; /* PLL0USB Enabled */
452 while (!(LPC_CGU->PLL0USB_STAT & 1));
453
454
455 /*----------------------------------------------------------------------------
456 Integer divider Setup
457 *----------------------------------------------------------------------------*/
458
459 /* Configure integer dividers */
460 LPC_CGU->IDIVA_CTRL = (0 << 0) | /* Disable Power-down */
461 (IDIVA_IDIV << 2) | /* IDIV */
462 (1 << 11) | /* Autoblock En */
463 (IDIVA_CLK_SEL << 24) ; /* Clock source */
464
465 LPC_CGU->IDIVB_CTRL = (0 << 0) | /* Disable Power-down */
466 (IDIVB_IDIV << 2) | /* IDIV */
467 (1 << 11) | /* Autoblock En */
468 (IDIVB_CLK_SEL << 24) ; /* Clock source */
469
470 LPC_CGU->IDIVC_CTRL = (0 << 0) | /* Disable Power-down */
471 (IDIVC_IDIV << 2) | /* IDIV */
472 (1 << 11) | /* Autoblock En */
473 (IDIVC_CLK_SEL << 24) ; /* Clock source */
474
475 LPC_CGU->IDIVD_CTRL = (0 << 0) | /* Disable Power-down */
476 (IDIVD_IDIV << 2) | /* IDIV */
477 (1 << 11) | /* Autoblock En */
478 (IDIVD_CLK_SEL << 24) ; /* Clock source */
479
480 LPC_CGU->IDIVE_CTRL = (0 << 0) | /* Disable Power-down */
481 (IDIVE_IDIV << 2) | /* IDIV */
482 (1 << 11) | /* Autoblock En */
483 (IDIVE_CLK_SEL << 24) ; /* Clock source */
484 }
485
486
487 /*----------------------------------------------------------------------------
488 Approximate delay function (must be used after SystemCoreClockUpdate() call)
489 *----------------------------------------------------------------------------*/
490 #define CPU_NANOSEC(x) (((uint64_t)(x) * SystemCoreClock)/1000000000)
491
WaitUs(uint32_t us)492 static void WaitUs (uint32_t us) {
493 uint32_t cyc = us * CPU_NANOSEC(1000)/4;
494 while(cyc--);
495 }
496
497
498 /*----------------------------------------------------------------------------
499 External Memory Controller Definitions
500 *----------------------------------------------------------------------------*/
501 #define SDRAM_ADDR_BASE 0x28000000 /* SDRAM base address */
502 /* Write Mode register macro */
503 #define WR_MODE(x) (*((volatile uint32_t *)(SDRAM_ADDR_BASE | (x))))
504
505 /* Pin Settings: Glith filter DIS, Input buffer EN, Fast Slew Rate, No Pullup */
506 #define EMC_PIN_SET ((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4))
507 #define EMC_NANOSEC(ns, freq, div) (((uint64_t)(ns) * ((freq)/((div)+1)))/1000000000)
508
509 #define EMC_CLK_DLY_TIM_2 (0x7777) /* 3.5 ns delay for the EMC clock out */
510 #define EMC_CLK_DLY_TIM_0 (0x0000) /* No delay for the EMC clock out */
511
512 typedef void (*emcdivby2) (volatile uint32_t *creg6, volatile uint32_t *emcdiv, uint32_t cfg);
513
514 const uint16_t emcdivby2_opc[] = {
515 0x6803, /* LDR R3,[R0,#0] ; Load CREG6 */
516 0xF443,0x3380, /* ORR R3,R3,#0x10000 ; Set Divided by 2 */
517 0x6003, /* STR R3,[R0,#0] ; Store CREG6 */
518 0x600A, /* STR R2,[R1,#0] ; EMCDIV_CFG = cfg */
519 0x684B, /* loop LDR R3,[R1,#4] ; Load EMCDIV_STAT */
520 0x07DB, /* LSLS R3,R3,#31 ; Check EMCDIV_STAT.0 */
521 0xD0FC, /* BEQ loop ; Jump if 0 */
522 0x4770, /* BX LR ; Exit */
523 0,
524 };
525
526 #define emcdivby2_szw ((sizeof(emcdivby2_opc)+3)/4)
527 #define emcdivby2_ram 0x10000000
528
529 /*----------------------------------------------------------------------------
530 Initialize external memory controller
531 *----------------------------------------------------------------------------*/
532
SystemInit_ExtMemCtl(void)533 void SystemInit_ExtMemCtl (void) {
534 uint32_t emcdivby2_buf[emcdivby2_szw];
535 uint32_t div, n;
536
537 /* Select and enable EMC branch clock */
538 LPC_CCU1->CLK_M3_EMC_CFG = (1 << 2) | (1 << 1) | 1;
539 while (!(LPC_CCU1->CLK_M3_EMC_STAT & 1));
540
541 /* Set EMC clock output delay */
542 if (SystemCoreClock < 80000000UL) {
543 LPC_SCU->EMCDELAYCLK = EMC_CLK_DLY_TIM_0; /* No EMC clock out delay */
544 }
545 else {
546 LPC_SCU->EMCDELAYCLK = EMC_CLK_DLY_TIM_2; /* 2.0 ns EMC clock out delay */
547 }
548
549 /* Configure EMC port pins */
550 LPC_SCU->SFSP1_0 = EMC_PIN_SET | 2; /* P1_0: A5 */
551 LPC_SCU->SFSP1_1 = EMC_PIN_SET | 2; /* P1_1: A6 */
552 LPC_SCU->SFSP1_2 = EMC_PIN_SET | 2; /* P1_2: A7 */
553 LPC_SCU->SFSP1_3 = EMC_PIN_SET | 3; /* P1_3: OE */
554 LPC_SCU->SFSP1_4 = EMC_PIN_SET | 3; /* P1_4: BLS0 */
555 LPC_SCU->SFSP1_5 = EMC_PIN_SET | 3; /* P1_5: CS0 */
556 LPC_SCU->SFSP1_6 = EMC_PIN_SET | 3; /* P1_6: WE */
557 LPC_SCU->SFSP1_7 = EMC_PIN_SET | 3; /* P1_7: D0 */
558 LPC_SCU->SFSP1_8 = EMC_PIN_SET | 3; /* P1_8: D1 */
559 LPC_SCU->SFSP1_9 = EMC_PIN_SET | 3; /* P1_9: D2 */
560 LPC_SCU->SFSP1_10 = EMC_PIN_SET | 3; /* P1_10: D3 */
561 LPC_SCU->SFSP1_11 = EMC_PIN_SET | 3; /* P1_11: D4 */
562 LPC_SCU->SFSP1_12 = EMC_PIN_SET | 3; /* P1_12: D5 */
563 LPC_SCU->SFSP1_13 = EMC_PIN_SET | 3; /* P1_13: D6 */
564 LPC_SCU->SFSP1_14 = EMC_PIN_SET | 3; /* P1_14: D7 */
565
566 LPC_SCU->SFSP2_0 = EMC_PIN_SET | 2; /* P2_0: A13 */
567 LPC_SCU->SFSP2_1 = EMC_PIN_SET | 2; /* P2_1: A12 */
568 LPC_SCU->SFSP2_2 = EMC_PIN_SET | 2; /* P2_2: A11 */
569 LPC_SCU->SFSP2_6 = EMC_PIN_SET | 2; /* P2_6: A10 */
570 LPC_SCU->SFSP2_7 = EMC_PIN_SET | 3; /* P2_7: A9 */
571 LPC_SCU->SFSP2_8 = EMC_PIN_SET | 3; /* P2_8: A8 */
572 LPC_SCU->SFSP2_9 = EMC_PIN_SET | 3; /* P2_9: A0 */
573 LPC_SCU->SFSP2_10 = EMC_PIN_SET | 3; /* P2_10: A1 */
574 LPC_SCU->SFSP2_11 = EMC_PIN_SET | 3; /* P2_11: A2 */
575 LPC_SCU->SFSP2_12 = EMC_PIN_SET | 3; /* P2_12: A3 */
576 LPC_SCU->SFSP2_13 = EMC_PIN_SET | 3; /* P2_13: A4 */
577
578 LPC_SCU->SFSP5_0 = EMC_PIN_SET | 2; /* P5_0: D12 */
579 LPC_SCU->SFSP5_1 = EMC_PIN_SET | 2; /* P5_1: D13 */
580 LPC_SCU->SFSP5_2 = EMC_PIN_SET | 2; /* P5_2: D14 */
581 LPC_SCU->SFSP5_3 = EMC_PIN_SET | 2; /* P5_3: D15 */
582 LPC_SCU->SFSP5_4 = EMC_PIN_SET | 2; /* P5_4: D8 */
583 LPC_SCU->SFSP5_5 = EMC_PIN_SET | 2; /* P5_5: D9 */
584 LPC_SCU->SFSP5_6 = EMC_PIN_SET | 2; /* P5_6: D10 */
585 LPC_SCU->SFSP5_7 = EMC_PIN_SET | 2; /* P5_7: D11 */
586
587 LPC_SCU->SFSP6_1 = EMC_PIN_SET | 1; /* P6_1: DYCS1 */
588 LPC_SCU->SFSP6_2 = EMC_PIN_SET | 1; /* P6_3: CKEOUT1 */
589 LPC_SCU->SFSP6_3 = EMC_PIN_SET | 3; /* P6_3: CS1 */
590 LPC_SCU->SFSP6_4 = EMC_PIN_SET | 3; /* P6_4: CAS */
591 LPC_SCU->SFSP6_5 = EMC_PIN_SET | 3; /* P6_5: RAS */
592 LPC_SCU->SFSP6_6 = EMC_PIN_SET | 1; /* P6_6: BLS1 */
593 LPC_SCU->SFSP6_7 = EMC_PIN_SET | 1; /* P6_7: A15 */
594 LPC_SCU->SFSP6_8 = EMC_PIN_SET | 1; /* P6_8: A14 */
595 LPC_SCU->SFSP6_9 = EMC_PIN_SET | 3; /* P6_9: DYCS0 */
596 LPC_SCU->SFSP6_10 = EMC_PIN_SET | 3; /* P6_10: DQMOUT1 */
597 LPC_SCU->SFSP6_11 = EMC_PIN_SET | 3; /* P6_11: CKEOUT0 */
598 LPC_SCU->SFSP6_12 = EMC_PIN_SET | 3; /* P6_12: DQMOUT0 */
599
600 LPC_SCU->SFSPA_4 = EMC_PIN_SET | 3; /* PA_4: A23 */
601
602 LPC_SCU->SFSPD_0 = EMC_PIN_SET | 2; /* PD_0: DQMOUT2 */
603 LPC_SCU->SFSPD_1 = EMC_PIN_SET | 2; /* PD_1: CKEOUT2 */
604 LPC_SCU->SFSPD_2 = EMC_PIN_SET | 2; /* PD_2: D16 */
605 LPC_SCU->SFSPD_3 = EMC_PIN_SET | 2; /* PD_3: D17 */
606 LPC_SCU->SFSPD_4 = EMC_PIN_SET | 2; /* PD_4: D18 */
607 LPC_SCU->SFSPD_5 = EMC_PIN_SET | 2; /* PD_5: D19 */
608 LPC_SCU->SFSPD_6 = EMC_PIN_SET | 2; /* PD_6: D20 */
609 LPC_SCU->SFSPD_7 = EMC_PIN_SET | 2; /* PD_7: D21 */
610 LPC_SCU->SFSPD_8 = EMC_PIN_SET | 2; /* PD_8: D22 */
611 LPC_SCU->SFSPD_9 = EMC_PIN_SET | 2; /* PD_9: D23 */
612 LPC_SCU->SFSPD_10 = EMC_PIN_SET | 2; /* PD_10: BLS3 */
613 LPC_SCU->SFSPD_11 = EMC_PIN_SET | 2; /* PD_11: CS3 */
614 LPC_SCU->SFSPD_12 = EMC_PIN_SET | 2; /* PD_12: CS2 */
615 LPC_SCU->SFSPD_13 = EMC_PIN_SET | 2; /* PD_13: BLS2 */
616 LPC_SCU->SFSPD_14 = EMC_PIN_SET | 2; /* PD_14: DYCS2 */
617 LPC_SCU->SFSPD_15 = EMC_PIN_SET | 2; /* PD_15: A17 */
618 LPC_SCU->SFSPD_16 = EMC_PIN_SET | 2; /* PD_16: A16 */
619
620 LPC_SCU->SFSPE_0 = EMC_PIN_SET | 3; /* PE_0: A18 */
621 LPC_SCU->SFSPE_1 = EMC_PIN_SET | 3; /* PE_1: A19 */
622 LPC_SCU->SFSPE_2 = EMC_PIN_SET | 3; /* PE_2: A20 */
623 LPC_SCU->SFSPE_3 = EMC_PIN_SET | 3; /* PE_3: A21 */
624 LPC_SCU->SFSPE_4 = EMC_PIN_SET | 3; /* PE_4: A22 */
625 LPC_SCU->SFSPE_5 = EMC_PIN_SET | 3; /* PE_5: D24 */
626 LPC_SCU->SFSPE_6 = EMC_PIN_SET | 3; /* PE_6: D25 */
627 LPC_SCU->SFSPE_7 = EMC_PIN_SET | 3; /* PE_7: D26 */
628 LPC_SCU->SFSPE_8 = EMC_PIN_SET | 3; /* PE_8: D27 */
629 LPC_SCU->SFSPE_9 = EMC_PIN_SET | 3; /* PE_9: D28 */
630 LPC_SCU->SFSPE_10 = EMC_PIN_SET | 3; /* PE_10: D29 */
631 LPC_SCU->SFSPE_11 = EMC_PIN_SET | 3; /* PE_11: D30 */
632 LPC_SCU->SFSPE_12 = EMC_PIN_SET | 3; /* PE_12: D31 */
633 LPC_SCU->SFSPE_13 = EMC_PIN_SET | 3; /* PE_13: DQMOUT3 */
634 LPC_SCU->SFSPE_14 = EMC_PIN_SET | 3; /* PE_14: DYCS3 */
635 LPC_SCU->SFSPE_15 = EMC_PIN_SET | 3; /* PE_15: CKEOUT3 */
636
637 LPC_EMC->CONTROL = 0x00000001; /* EMC Enable */
638 LPC_EMC->CONFIG = 0x00000000; /* Little-endian, Clock Ratio 1:1 */
639
640 div = 0;
641 if (SystemCoreClock > 120000000UL) {
642 /* Use EMC clock divider and EMC clock output delay */
643 div = 1;
644 /* Following code must be executed in RAM to ensure stable operation */
645 /* LPC_CCU1->CLK_M3_EMCDIV_CFG = (1 << 5) | (1 << 2) | (1 << 1) | 1; */
646 /* LPC_CREG->CREG6 |= (1 << 16); // EMC_CLK_DIV divided by 2 */
647 /* while (!(LPC_CCU1->CLK_M3_EMCDIV_STAT & 1)); */
648
649 /* This code configures EMC clock divider and is executed in RAM */
650 for (n = 0; n < emcdivby2_szw; n++) {
651 emcdivby2_buf[n] = *((uint32_t *)emcdivby2_ram + n);
652 *((uint32_t *)emcdivby2_ram + n) = *((uint32_t *)emcdivby2_opc + n);
653 }
654 __ISB();
655 ((emcdivby2 )(emcdivby2_ram+1))(&LPC_CREG->CREG6, &LPC_CCU1->CLK_M3_EMCDIV_CFG, (1 << 5) | (1 << 2) | (1 << 1) | 1);
656 for (n = 0; n < emcdivby2_szw; n++) {
657 *((uint32_t *)emcdivby2_ram + n) = emcdivby2_buf[n];
658 }
659 }
660
661 /* Configure EMC clock-out pins */
662 LPC_SCU->SFSCLK_0 = EMC_PIN_SET | 0; /* CLK0 */
663 LPC_SCU->SFSCLK_1 = EMC_PIN_SET | 0; /* CLK1 */
664 LPC_SCU->SFSCLK_2 = EMC_PIN_SET | 0; /* CLK2 */
665 LPC_SCU->SFSCLK_3 = EMC_PIN_SET | 0; /* CLK3 */
666
667 /* Static memory configuration (chip select 0) */
668 #if (USE_EXT_STAT_MEM_CS0)
669 LPC_EMC->STATICCONFIG0 = (1 << 7) | /* Byte lane state: use WE signal */
670 (2 << 0) | /* Memory width 32-bit */
671 (1 << 3); /* Async page mode enable */
672
673 LPC_EMC->STATICWAITOEN0 = (0 << 0) ; /* Wait output enable: No delay */
674
675 LPC_EMC->STATICWAITPAG0 = 2;
676
677 /* Set Static Memory Read Delay for 90ns External NOR Flash */
678 LPC_EMC->STATICWAITRD0 = 1 + EMC_NANOSEC(90, SystemCoreClock, div);
679 LPC_EMC->STATICCONFIG0 |= (1 << 19) ; /* Enable buffer */
680 #endif
681
682 /* Dynamic memory configuration (chip select 0) */
683 #if (USE_EXT_DYN_MEM_CS0)
684
685 /* Set Address mapping: 128Mb(4Mx32), 4 banks, row len = 12, column len = 8 */
686 LPC_EMC->DYNAMICCONFIG0 = (1 << 14) | /* AM[14] = 1 */
687 (0 << 12) | /* AM[12] = 0 */
688 (2 << 9) | /* AM[11:9] = 2 */
689 (2 << 7) ; /* AM[8:7] = 2 */
690
691 LPC_EMC->DYNAMICRASCAS0 = 0x00000303; /* Latency: RAS 3, CAS 3 CCLK cyc.*/
692 LPC_EMC->DYNAMICREADCONFIG = 0x00000001; /* Command delayed by 1/2 CCLK */
693
694 LPC_EMC->DYNAMICRP = EMC_NANOSEC (20, SystemCoreClock, div);
695 LPC_EMC->DYNAMICRAS = EMC_NANOSEC (42, SystemCoreClock, div);
696 LPC_EMC->DYNAMICSREX = EMC_NANOSEC (63, SystemCoreClock, div);
697 LPC_EMC->DYNAMICAPR = EMC_NANOSEC (70, SystemCoreClock, div);
698 LPC_EMC->DYNAMICDAL = EMC_NANOSEC (70, SystemCoreClock, div);
699 LPC_EMC->DYNAMICWR = EMC_NANOSEC (30, SystemCoreClock, div);
700 LPC_EMC->DYNAMICRC = EMC_NANOSEC (63, SystemCoreClock, div);
701 LPC_EMC->DYNAMICRFC = EMC_NANOSEC (63, SystemCoreClock, div);
702 LPC_EMC->DYNAMICXSR = EMC_NANOSEC (63, SystemCoreClock, div);
703 LPC_EMC->DYNAMICRRD = EMC_NANOSEC (14, SystemCoreClock, div);
704 LPC_EMC->DYNAMICMRD = EMC_NANOSEC (30, SystemCoreClock, div);
705
706 WaitUs (100);
707 LPC_EMC->DYNAMICCONTROL = 0x00000183; /* Issue NOP command */
708 WaitUs (10);
709 LPC_EMC->DYNAMICCONTROL = 0x00000103; /* Issue PALL command */
710 WaitUs (1);
711 LPC_EMC->DYNAMICCONTROL = 0x00000183; /* Issue NOP command */
712 WaitUs (1);
713 LPC_EMC->DYNAMICREFRESH = EMC_NANOSEC( 200, SystemCoreClock, div) / 16 + 1;
714 WaitUs (10);
715 LPC_EMC->DYNAMICREFRESH = EMC_NANOSEC(15625, SystemCoreClock, div) / 16 + 1;
716 WaitUs (10);
717 LPC_EMC->DYNAMICCONTROL = 0x00000083; /* Issue MODE command */
718
719 /* Mode register: Burst Length: 4, Burst Type: Sequential, CAS Latency: 3 */
720 WR_MODE(((3 << 4) | 2) << 12);
721
722 WaitUs (10);
723 LPC_EMC->DYNAMICCONTROL = 0x00000002; /* Issue NORMAL command */
724 LPC_EMC->DYNAMICCONFIG0 |= (1 << 19); /* Enable buffer */
725 #endif
726 }
727
728
729 /*----------------------------------------------------------------------------
730 Measure frequency using frequency monitor
731 *----------------------------------------------------------------------------*/
MeasureFreq(uint32_t clk_sel)732 uint32_t MeasureFreq (uint32_t clk_sel) {
733 uint32_t fcnt, rcnt, fout;
734
735 /* Set register values */
736 LPC_CGU->FREQ_MON &= ~(1 << 23); /* Stop frequency counters */
737 LPC_CGU->FREQ_MON = (clk_sel << 24) | 511; /* RCNT == 511 */
738 LPC_CGU->FREQ_MON |= (1 << 23); /* Start RCNT and FCNT */
739 while (LPC_CGU->FREQ_MON & (1 << 23)) {
740 fcnt = (LPC_CGU->FREQ_MON >> 9) & 0x3FFF;
741 rcnt = (LPC_CGU->FREQ_MON ) & 0x01FF;
742 if (fcnt == 0 && rcnt == 0) {
743 return (0); /* No input clock present */
744 }
745 }
746 fcnt = (LPC_CGU->FREQ_MON >> 9) & 0x3FFF;
747 fout = fcnt * (12000000U/511U); /* FCNT * (IRC_CLK / RCNT) */
748
749 return (fout);
750 }
751
752
753 /*----------------------------------------------------------------------------
754 Get PLL1 (divider and multiplier) parameters
755 *----------------------------------------------------------------------------*/
GetPLL1Param(void)756 static __inline uint32_t GetPLL1Param (void) {
757 uint32_t ctrl;
758 uint32_t p;
759 uint32_t div, mul;
760
761 ctrl = LPC_CGU->PLL1_CTRL;
762 div = ((ctrl >> 12) & 0x03) + 1;
763 mul = ((ctrl >> 16) & 0xFF) + 1;
764 p = 1 << ((ctrl >> 8) & 0x03);
765
766 if (ctrl & (1 << 1)) {
767 /* Bypass = 1, PLL1 input clock sent to post-dividers */
768 if (ctrl & (1 << 7)) {
769 div *= (2*p);
770 }
771 }
772 else {
773 /* Direct and integer mode */
774 if (((ctrl & (1 << 7)) == 0) && ((ctrl & (1 << 6)) == 0)) {
775 /* Non-integer mode */
776 div *= (2*p);
777 }
778 }
779 return ((div << 8) | (mul));
780 }
781
782
783 /*----------------------------------------------------------------------------
784 Get input clock source for specified clock generation block
785 *----------------------------------------------------------------------------*/
GetClkSel(uint32_t clk_src)786 int32_t GetClkSel (uint32_t clk_src) {
787 uint32_t reg;
788 int32_t clk_sel = -1;
789
790 switch (clk_src) {
791 case CLK_SRC_IRC:
792 case CLK_SRC_ENET_RX:
793 case CLK_SRC_ENET_TX:
794 case CLK_SRC_GP_CLKIN:
795 return (clk_src);
796
797 case CLK_SRC_32KHZ:
798 return ((LPC_CREG->CREG0 & 0x0A) != 0x02) ? (-1) : (CLK_SRC_32KHZ);
799 case CLK_SRC_XTAL:
800 return (LPC_CGU->XTAL_OSC_CTRL & 1) ? (-1) : (CLK_SRC_XTAL);
801
802 case CLK_SRC_PLL0U: reg = LPC_CGU->PLL0USB_CTRL; break;
803 case CLK_SRC_PLL0A: reg = LPC_CGU->PLL0AUDIO_CTRL; break;
804 case CLK_SRC_PLL1: reg = (LPC_CGU->PLL1_STAT & 1) ? (LPC_CGU->PLL1_CTRL) : (0); break;
805
806 case CLK_SRC_IDIVA: reg = LPC_CGU->IDIVA_CTRL; break;
807 case CLK_SRC_IDIVB: reg = LPC_CGU->IDIVB_CTRL; break;
808 case CLK_SRC_IDIVC: reg = LPC_CGU->IDIVC_CTRL; break;
809 case CLK_SRC_IDIVD: reg = LPC_CGU->IDIVD_CTRL; break;
810 case CLK_SRC_IDIVE: reg = LPC_CGU->IDIVE_CTRL; break;
811
812 default:
813 return (clk_sel);
814 }
815 if (!(reg & 1)) {
816 clk_sel = (reg >> 24) & 0x1F;
817 }
818 return (clk_sel);
819 }
820
821
822 /*----------------------------------------------------------------------------
823 Get clock frequency for specified clock source
824 *----------------------------------------------------------------------------*/
GetClockFreq(uint32_t clk_src)825 uint32_t GetClockFreq (uint32_t clk_src) {
826 uint32_t tmp;
827 uint32_t mul = 1;
828 uint32_t div = 1;
829 uint32_t main_freq = 0;
830 int32_t clk_sel = clk_src;
831
832 do {
833 switch (clk_sel) {
834 case CLK_SRC_32KHZ: main_freq = CLK_32KHZ; break;
835 case CLK_SRC_IRC: main_freq = CLK_IRC; break;
836 case CLK_SRC_ENET_RX: main_freq = CLK_ENET_RX; break;
837 case CLK_SRC_ENET_TX: main_freq = CLK_ENET_TX; break;
838 case CLK_SRC_GP_CLKIN: main_freq = CLK_GP_CLKIN; break;
839 case CLK_SRC_XTAL: main_freq = CLK_XTAL; break;
840
841 case CLK_SRC_IDIVA: div *= ((LPC_CGU->IDIVA_CTRL >> 2) & 0x3) + 1; break;
842 case CLK_SRC_IDIVB: div *= ((LPC_CGU->IDIVB_CTRL >> 2) & 0x3) + 1; break;
843 case CLK_SRC_IDIVC: div *= ((LPC_CGU->IDIVC_CTRL >> 2) & 0x3) + 1; break;
844 case CLK_SRC_IDIVD: div *= ((LPC_CGU->IDIVD_CTRL >> 2) & 0x3) + 1; break;
845 case CLK_SRC_IDIVE: div *= ((LPC_CGU->IDIVE_CTRL >> 2) & 0x3) + 1; break;
846
847 case CLK_SRC_PLL0U: /* Not implemented */ break;
848 case CLK_SRC_PLL0A: /* Not implemented */ break;
849
850 case CLK_SRC_PLL1:
851 tmp = GetPLL1Param ();
852 mul *= (tmp ) & 0xFF; /* PLL input clock multiplier */
853 div *= (tmp >> 8) & 0xFF; /* PLL input clock divider */
854 break;
855
856 default:
857 return (0); /* Clock not running or not supported */
858 }
859 if (main_freq == 0) {
860 clk_sel = GetClkSel (clk_sel);
861 }
862 }
863 while (main_freq == 0);
864
865 return ((main_freq * mul) / div);
866 }
867
868
869 /*----------------------------------------------------------------------------
870 System Core Clock update
871 *----------------------------------------------------------------------------*/
SystemCoreClockUpdate(void)872 void SystemCoreClockUpdate (void) {
873 /* Check BASE_M3_CLK connection */
874 uint32_t base_src = (LPC_CGU->BASE_M3_CLK >> 24) & 0x1F;
875
876 /* Update core clock frequency */
877 SystemCoreClock = GetClockFreq (base_src);
878 }
879
880
881 extern uint32_t __Vectors; /* see startup_LPC18xx.s */
882
883 /*----------------------------------------------------------------------------
884 Initialize the system
885 *----------------------------------------------------------------------------*/
SystemInit(void)886 void SystemInit (void) {
887 /* Disable SysTick timer */
888 SysTick->CTRL &= ~(SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk);
889
890 /* Set vector table pointer */
891 SCB->VTOR = ((uint32_t)(&__Vectors)) & 0xFFF00000UL;
892
893 /* Configure PLL0 and PLL1, connect CPU clock to selected clock source */
894 SetClock();
895
896 /* Update SystemCoreClock variable */
897 SystemCoreClockUpdate();
898
899 /* Configure External Memory Controller */
900 SystemInit_ExtMemCtl ();
901 }
902