system_LPC43xx.c 42 KB

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