system_LPC11xx.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. /**************************************************************************//**
  2. * @file system_LPC11xx.c
  3. * @brief CMSIS Cortex-M0 Device Peripheral Access Layer Source File
  4. * for the NXP LPC11xx Device Series
  5. * @version V1.00
  6. * @date 17. November 2009
  7. *
  8. * @note
  9. * Copyright (C) 2009 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. #include <stdint.h>
  25. #include "LPC11xx.h"
  26. /*
  27. //-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
  28. */
  29. /*--------------------- Clock Configuration ----------------------------------
  30. //
  31. // <e> Clock Configuration
  32. // <e1> System Clock Setup
  33. // <e2> System Oscillator Enable
  34. // <o3.1> Select System Oscillator Frequency Range
  35. // <0=> 1 - 20 MHz
  36. // <1=> 15 - 25 MHz
  37. // </e2>
  38. // <e4> Watchdog Oscillator Enable
  39. // <o5.0..4> Select Divider for Fclkana
  40. // <0=> 2 <1=> 4 <2=> 6 <3=> 8
  41. // <4=> 10 <5=> 12 <6=> 14 <7=> 16
  42. // <8=> 18 <9=> 20 <10=> 22 <11=> 24
  43. // <12=> 26 <13=> 28 <14=> 30 <15=> 32
  44. // <16=> 34 <17=> 36 <18=> 38 <19=> 40
  45. // <20=> 42 <21=> 44 <22=> 46 <23=> 48
  46. // <24=> 50 <25=> 52 <26=> 54 <27=> 56
  47. // <28=> 58 <29=> 60 <30=> 62 <31=> 64
  48. // <o5.5..8> Select Watchdog Oscillator Analog Frequency (Fclkana)
  49. // <0=> Disabled
  50. // <1=> 0.5 MHz
  51. // <2=> 0.8 MHz
  52. // <3=> 1.1 MHz
  53. // <4=> 1.4 MHz
  54. // <5=> 1.6 MHz
  55. // <6=> 1.8 MHz
  56. // <7=> 2.0 MHz
  57. // <8=> 2.2 MHz
  58. // <9=> 2.4 MHz
  59. // <10=> 2.6 MHz
  60. // <11=> 2.7 MHz
  61. // <12=> 2.9 MHz
  62. // <13=> 3.1 MHz
  63. // <14=> 3.2 MHz
  64. // <15=> 3.4 MHz
  65. // </e4>
  66. // <o6> Select Input Clock for sys_pllclkin (Register: SYSPLLCLKSEL)
  67. // <0=> IRC Oscillator
  68. // <1=> System Oscillator
  69. // <2=> WDT Oscillator
  70. // <3=> Invalid
  71. // <e7> Use System PLL
  72. // <i> F_pll = M * F_in
  73. // <i> F_in must be in the range of 10 MHz to 25 MHz
  74. // <o8.0..4> M: PLL Multiplier Selection
  75. // <1-32><#-1>
  76. // <o8.5..6> P: PLL Divider Selection
  77. // <0=> 2
  78. // <1=> 4
  79. // <2=> 8
  80. // <3=> 16
  81. // <o8.7> DIRECT: Direct CCO Clock Output Enable
  82. // <o8.8> BYPASS: PLL Bypass Enable
  83. // </e7>
  84. // <o9> Select Input Clock for Main clock (Register: MAINCLKSEL)
  85. // <0=> IRC Oscillator
  86. // <1=> Input Clock to System PLL
  87. // <2=> WDT Oscillator
  88. // <3=> System PLL Clock Out
  89. // </e1>
  90. // <o10.0..7> System AHB Divider <0-255>
  91. // <i> 0 = is disabled
  92. // <o11.0> SYS Clock Enable
  93. // <o11.1> ROM Clock Enable
  94. // <o11.2> RAM Clock Enable
  95. // <o11.3> FLASHREG Flash Register Interface Clock Enable
  96. // <o11.4> FLASHARRAY Flash Array Access Clock Enable
  97. // <o11.5> I2C Clock Enable
  98. // <o11.6> GPIO Clock Enable
  99. // <o11.7> CT16B0 Clock Enable
  100. // <o11.8> CT16B1 Clock Enable
  101. // <o11.9> CT32B0 Clock Enable
  102. // <o11.10> CT32B1 Clock Enable
  103. // <o11.11> SSP0 Clock Enable
  104. // <o11.12> UART Clock Enable
  105. // <o11.13> ADC Clock Enable
  106. // <o11.15> WDT Clock Enable
  107. // <o11.16> IOCON Clock Enable
  108. // <o11.18> SSP1 Clock Enable
  109. //
  110. // <o12.0..7> SSP0 Clock Divider <0-255>
  111. // <i> 0 = is disabled
  112. // <o13.0..7> UART Clock Divider <0-255>
  113. // <i> 0 = is disabled
  114. // <o14.0..7> SSP1 Clock Divider <0-255>
  115. // <i> 0 = is disabled
  116. // </e>
  117. */
  118. #define CLOCK_SETUP 1
  119. #define SYSCLK_SETUP 1
  120. #define SYSOSC_SETUP 1
  121. #define SYSOSCCTRL_Val 0x00000000
  122. #define WDTOSC_SETUP 0
  123. #define WDTOSCCTRL_Val 0x000000A0
  124. #define SYSPLLCLKSEL_Val 0x00000001
  125. #define SYSPLL_SETUP 1
  126. #define SYSPLLCTRL_Val 0x00000023
  127. #define MAINCLKSEL_Val 0x00000003
  128. #define SYSAHBCLKDIV_Val 0x00000001
  129. #define AHBCLKCTRL_Val 0x0001005F
  130. #define SSP0CLKDIV_Val 0x00000001
  131. #define UARTCLKDIV_Val 0x00000001
  132. #define SSP1CLKDIV_Val 0x00000001
  133. /*--------------------- Memory Mapping Configuration -------------------------
  134. //
  135. // <e> Memory Mapping
  136. // <o1.0..1> System Memory Remap (Register: SYSMEMREMAP)
  137. // <0=> Bootloader mapped to address 0
  138. // <1=> RAM mapped to address 0
  139. // <2=> Flash mapped to address 0
  140. // <3=> Flash mapped to address 0
  141. // </e>
  142. */
  143. #define MEMMAP_SETUP 0
  144. #define SYSMEMREMAP_Val 0x00000001
  145. /*
  146. //-------- <<< end of configuration section >>> ------------------------------
  147. */
  148. /*----------------------------------------------------------------------------
  149. Check the register settings
  150. *----------------------------------------------------------------------------*/
  151. #define CHECK_RANGE(val, min, max) ((val < min) || (val > max))
  152. #define CHECK_RSVD(val, mask) (val & mask)
  153. /* Clock Configuration -------------------------------------------------------*/
  154. #if (CHECK_RSVD((SYSOSCCTRL_Val), ~0x00000003))
  155. #error "SYSOSCCTRL: Invalid values of reserved bits!"
  156. #endif
  157. #if (CHECK_RSVD((WDTOSCCTRL_Val), ~0x000001FF))
  158. #error "WDTOSCCTRL: Invalid values of reserved bits!"
  159. #endif
  160. #if (CHECK_RANGE((SYSPLLCLKSEL_Val), 0, 2))
  161. #error "SYSPLLCLKSEL: Value out of range!"
  162. #endif
  163. #if (CHECK_RSVD((SYSPLLCTRL_Val), ~0x000001FF))
  164. #error "SYSPLLCTRL: Invalid values of reserved bits!"
  165. #endif
  166. #if (CHECK_RSVD((MAINCLKSEL_Val), ~0x00000003))
  167. #error "MAINCLKSEL: Invalid values of reserved bits!"
  168. #endif
  169. #if (CHECK_RANGE((SYSAHBCLKDIV_Val), 0, 255))
  170. #error "SYSAHBCLKDIV: Value out of range!"
  171. #endif
  172. #if (CHECK_RSVD((AHBCLKCTRL_Val), ~0x0001FFFF))
  173. #error "AHBCLKCTRL: Invalid values of reserved bits!"
  174. #endif
  175. #if (CHECK_RANGE((SSP0CLKDIV_Val), 0, 255))
  176. #error "SSP0CLKDIV: Value out of range!"
  177. #endif
  178. #if (CHECK_RANGE((UARTCLKDIV_Val), 0, 255))
  179. #error "UARTCLKDIV: Value out of range!"
  180. #endif
  181. #if (CHECK_RANGE((SSP1CLKDIV_Val), 0, 255))
  182. #error "SSP1CLKDIV: Value out of range!"
  183. #endif
  184. #if (CHECK_RSVD((SYSMEMREMAP_Val), ~0x00000003))
  185. #error "SYSMEMREMAP: Invalid values of reserved bits!"
  186. #endif
  187. /*----------------------------------------------------------------------------
  188. DEFINES
  189. *----------------------------------------------------------------------------*/
  190. /*----------------------------------------------------------------------------
  191. Define clocks
  192. *----------------------------------------------------------------------------*/
  193. #define __XTAL (12000000UL) /* Oscillator frequency */
  194. #define __SYS_OSC_CLK ( __XTAL) /* Main oscillator frequency */
  195. #define __IRC_OSC_CLK (12000000UL) /* Internal RC oscillator frequency */
  196. #define __FREQSEL ((WDTOSCCTRL_Val >> 5) & 0x0F)
  197. #define __DIVSEL (((WDTOSCCTRL_Val & 0x1F) << 1) + 2)
  198. #if (CLOCK_SETUP) /* Clock Setup */
  199. #if (SYSCLK_SETUP) /* System Clock Setup */
  200. #if (WDTOSC_SETUP) /* Watchdog Oscillator Setup*/
  201. #if (__FREQSEL == 0)
  202. #define __WDT_OSC_CLK ( 400000 / __DIVSEL)
  203. #elif (__FREQSEL == 1)
  204. #define __WDT_OSC_CLK ( 500000 / __DIVSEL)
  205. #elif (__FREQSEL == 2)
  206. #define __WDT_OSC_CLK ( 800000 / __DIVSEL)
  207. #elif (__FREQSEL == 3)
  208. #define __WDT_OSC_CLK (1100000 / __DIVSEL)
  209. #elif (__FREQSEL == 4)
  210. #define __WDT_OSC_CLK (1400000 / __DIVSEL)
  211. #elif (__FREQSEL == 5)
  212. #define __WDT_OSC_CLK (1600000 / __DIVSEL)
  213. #elif (__FREQSEL == 6)
  214. #define __WDT_OSC_CLK (1800000 / __DIVSEL)
  215. #elif (__FREQSEL == 7)
  216. #define __WDT_OSC_CLK (2000000 / __DIVSEL)
  217. #elif (__FREQSEL == 8)
  218. #define __WDT_OSC_CLK (2200000 / __DIVSEL)
  219. #elif (__FREQSEL == 9)
  220. #define __WDT_OSC_CLK (2400000 / __DIVSEL)
  221. #elif (__FREQSEL == 10)
  222. #define __WDT_OSC_CLK (2600000 / __DIVSEL)
  223. #elif (__FREQSEL == 11)
  224. #define __WDT_OSC_CLK (2700000 / __DIVSEL)
  225. #elif (__FREQSEL == 12)
  226. #define __WDT_OSC_CLK (2900000 / __DIVSEL)
  227. #elif (__FREQSEL == 13)
  228. #define __WDT_OSC_CLK (3100000 / __DIVSEL)
  229. #elif (__FREQSEL == 14)
  230. #define __WDT_OSC_CLK (3200000 / __DIVSEL)
  231. #else
  232. #define __WDT_OSC_CLK (3400000 / __DIVSEL)
  233. #endif
  234. #else
  235. #define __WDT_OSC_CLK (1600000 / 2)
  236. #endif // WDTOSC_SETUP
  237. /* sys_pllclkin calculation */
  238. #if ((SYSPLLCLKSEL_Val & 0x03) == 0)
  239. #define __SYS_PLLCLKIN (__IRC_OSC_CLK)
  240. #elif ((SYSPLLCLKSEL_Val & 0x03) == 1)
  241. #define __SYS_PLLCLKIN (__SYS_OSC_CLK)
  242. #elif ((SYSPLLCLKSEL_Val & 0x03) == 2)
  243. #define __SYS_PLLCLKIN (__WDT_OSC_CLK)
  244. #else
  245. #define __SYS_PLLCLKIN (0)
  246. #endif
  247. #if (SYSPLL_SETUP) /* System PLL Setup */
  248. #define __SYS_PLLCLKOUT (__SYS_PLLCLKIN * ((SYSPLLCTRL_Val & 0x01F) + 1))
  249. #else
  250. #define __SYS_PLLCLKOUT (__SYS_PLLCLKIN * (1))
  251. #endif // SYSPLL_SETUP
  252. /* main clock calculation */
  253. #if ((MAINCLKSEL_Val & 0x03) == 0)
  254. #define __MAIN_CLOCK (__IRC_OSC_CLK)
  255. #elif ((MAINCLKSEL_Val & 0x03) == 1)
  256. #define __MAIN_CLOCK (__SYS_PLLCLKIN)
  257. #elif ((MAINCLKSEL_Val & 0x03) == 2)
  258. #define __MAIN_CLOCK (__WDT_OSC_CLK)
  259. #elif ((MAINCLKSEL_Val & 0x03) == 3)
  260. #define __MAIN_CLOCK (__SYS_PLLCLKOUT)
  261. #else
  262. #define __MAIN_CLOCK (0)
  263. #endif
  264. #define __SYSTEM_CLOCK (__MAIN_CLOCK / SYSAHBCLKDIV_Val)
  265. #else // SYSCLK_SETUP
  266. #if (SYSAHBCLKDIV_Val == 0)
  267. #define __SYSTEM_CLOCK (0)
  268. #else
  269. #define __SYSTEM_CLOCK (__XTAL / SYSAHBCLKDIV_Val)
  270. #endif
  271. #endif // SYSCLK_SETUP
  272. #else
  273. #define __SYSTEM_CLOCK (__XTAL)
  274. #endif // CLOCK_SETUP
  275. /*----------------------------------------------------------------------------
  276. Clock Variable definitions
  277. *----------------------------------------------------------------------------*/
  278. uint32_t SystemCoreClock = __SYSTEM_CLOCK;/*!< System Clock Frequency (Core Clock)*/
  279. /*----------------------------------------------------------------------------
  280. Clock functions
  281. *----------------------------------------------------------------------------*/
  282. void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */
  283. {
  284. uint32_t wdt_osc = 0;
  285. /* Determine clock frequency according to clock register values */
  286. switch ((LPC_SYSCON->WDTOSCCTRL >> 5) & 0x0F) {
  287. case 0: wdt_osc = 400000; break;
  288. case 1: wdt_osc = 500000; break;
  289. case 2: wdt_osc = 800000; break;
  290. case 3: wdt_osc = 1100000; break;
  291. case 4: wdt_osc = 1400000; break;
  292. case 5: wdt_osc = 1600000; break;
  293. case 6: wdt_osc = 1800000; break;
  294. case 7: wdt_osc = 2000000; break;
  295. case 8: wdt_osc = 2200000; break;
  296. case 9: wdt_osc = 2400000; break;
  297. case 10: wdt_osc = 2600000; break;
  298. case 11: wdt_osc = 2700000; break;
  299. case 12: wdt_osc = 2900000; break;
  300. case 13: wdt_osc = 3100000; break;
  301. case 14: wdt_osc = 3200000; break;
  302. case 15: wdt_osc = 3400000; break;
  303. }
  304. wdt_osc /= ((LPC_SYSCON->WDTOSCCTRL & 0x1F) << 1) + 2;
  305. switch (LPC_SYSCON->MAINCLKSEL & 0x03) {
  306. case 0: /* Internal RC oscillator */
  307. SystemCoreClock = __IRC_OSC_CLK;
  308. break;
  309. case 1: /* Input Clock to System PLL */
  310. switch (LPC_SYSCON->SYSPLLCLKSEL & 0x03) {
  311. case 0: /* Internal RC oscillator */
  312. SystemCoreClock = __IRC_OSC_CLK;
  313. break;
  314. case 1: /* System oscillator */
  315. SystemCoreClock = __SYS_OSC_CLK;
  316. break;
  317. case 2: /* WDT Oscillator */
  318. SystemCoreClock = wdt_osc;
  319. break;
  320. case 3: /* Reserved */
  321. SystemCoreClock = 0;
  322. break;
  323. }
  324. break;
  325. case 2: /* WDT Oscillator */
  326. SystemCoreClock = wdt_osc;
  327. break;
  328. case 3: /* System PLL Clock Out */
  329. switch (LPC_SYSCON->SYSPLLCLKSEL & 0x03) {
  330. case 0: /* Internal RC oscillator */
  331. if (LPC_SYSCON->SYSPLLCTRL & 0x180) {
  332. SystemCoreClock = __IRC_OSC_CLK;
  333. } else {
  334. SystemCoreClock = __IRC_OSC_CLK * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1);
  335. }
  336. break;
  337. case 1: /* System oscillator */
  338. if (LPC_SYSCON->SYSPLLCTRL & 0x180) {
  339. SystemCoreClock = __SYS_OSC_CLK;
  340. } else {
  341. SystemCoreClock = __SYS_OSC_CLK * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1);
  342. }
  343. break;
  344. case 2: /* WDT Oscillator */
  345. if (LPC_SYSCON->SYSPLLCTRL & 0x180) {
  346. SystemCoreClock = wdt_osc;
  347. } else {
  348. SystemCoreClock = wdt_osc * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1);
  349. }
  350. break;
  351. case 3: /* Reserved */
  352. SystemCoreClock = 0;
  353. break;
  354. }
  355. break;
  356. }
  357. SystemCoreClock /= LPC_SYSCON->SYSAHBCLKDIV;
  358. }
  359. /**
  360. * Initialize the system
  361. *
  362. * @param none
  363. * @return none
  364. *
  365. * @brief Setup the microcontroller system.
  366. * Initialize the System.
  367. */
  368. void SystemInit (void)
  369. {
  370. #if (CLOCK_SETUP) /* Clock Setup */
  371. #if (SYSCLK_SETUP) /* System Clock Setup */
  372. #if (SYSOSC_SETUP) /* System Oscillator Setup */
  373. uint32_t i;
  374. LPC_SYSCON->PDRUNCFG &= ~(1 << 5); /* Power-up System Osc */
  375. LPC_SYSCON->SYSOSCCTRL = SYSOSCCTRL_Val;
  376. for (i = 0; i < 200; i++) __NOP();
  377. LPC_SYSCON->SYSPLLCLKSEL = SYSPLLCLKSEL_Val; /* Select PLL Input */
  378. LPC_SYSCON->SYSPLLCLKUEN = 0x01; /* Update Clock Source */
  379. LPC_SYSCON->SYSPLLCLKUEN = 0x00; /* Toggle Update Register */
  380. LPC_SYSCON->SYSPLLCLKUEN = 0x01;
  381. while (!(LPC_SYSCON->SYSPLLCLKUEN & 0x01)); /* Wait Until Updated */
  382. #if (SYSPLL_SETUP) /* System PLL Setup */
  383. LPC_SYSCON->SYSPLLCTRL = SYSPLLCTRL_Val;
  384. LPC_SYSCON->PDRUNCFG &= ~(1 << 7); /* Power-up SYSPLL */
  385. while (!(LPC_SYSCON->SYSPLLSTAT & 0x01)); /* Wait Until PLL Locked */
  386. #endif
  387. #endif
  388. #if (WDTOSC_SETUP) /* Watchdog Oscillator Setup*/
  389. LPC_SYSCON->WDTOSCCTRL = WDTOSCCTRL_Val;
  390. LPC_SYSCON->PDRUNCFG &= ~(1 << 6); /* Power-up WDT Clock */
  391. #endif
  392. LPC_SYSCON->MAINCLKSEL = MAINCLKSEL_Val; /* Select PLL Clock Output */
  393. LPC_SYSCON->MAINCLKUEN = 0x01; /* Update MCLK Clock Source */
  394. LPC_SYSCON->MAINCLKUEN = 0x00; /* Toggle Update Register */
  395. LPC_SYSCON->MAINCLKUEN = 0x01;
  396. while (!(LPC_SYSCON->MAINCLKUEN & 0x01)); /* Wait Until Updated */
  397. #endif
  398. LPC_SYSCON->SYSAHBCLKDIV = SYSAHBCLKDIV_Val;
  399. LPC_SYSCON->SYSAHBCLKCTRL = AHBCLKCTRL_Val;
  400. LPC_SYSCON->SSP0CLKDIV = SSP0CLKDIV_Val;
  401. LPC_SYSCON->UARTCLKDIV = UARTCLKDIV_Val;
  402. LPC_SYSCON->SSP1CLKDIV = SSP1CLKDIV_Val;
  403. #endif
  404. #if (MEMMAP_SETUP || MEMMAP_INIT) /* Memory Mapping Setup */
  405. LPC_SYSCON->SYSMEMREMAP = SYSMEMREMAP_Val;
  406. #endif
  407. }