cr_startup_lpc5410x.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. //*****************************************************************************
  2. // LPC5410x Microcontroller Startup code for use with LPCXpresso IDE
  3. //
  4. // Version : 141022
  5. //*****************************************************************************
  6. //
  7. // Copyright(C) NXP Semiconductors, 2014
  8. // All rights reserved.
  9. //
  10. // Software that is described herein is for illustrative purposes only
  11. // which provides customers with programming information regarding the
  12. // LPC products. This software is supplied "AS IS" without any warranties of
  13. // any kind, and NXP Semiconductors and its licensor disclaim any and
  14. // all warranties, express or implied, including all implied warranties of
  15. // merchantability, fitness for a particular purpose and non-infringement of
  16. // intellectual property rights. NXP Semiconductors assumes no responsibility
  17. // or liability for the use of the software, conveys no license or rights under any
  18. // patent, copyright, mask work right, or any other intellectual property rights in
  19. // or to any products. NXP Semiconductors reserves the right to make changes
  20. // in the software without notification. NXP Semiconductors also makes no
  21. // representation or warranty that such application will be suitable for the
  22. // specified use without further testing or modification.
  23. //
  24. // Permission to use, copy, modify, and distribute this software and its
  25. // documentation is hereby granted, under NXP Semiconductors' and its
  26. // licensor's relevant copyrights in the software, without fee, provided that it
  27. // is used in conjunction with NXP Semiconductors microcontrollers. This
  28. // copyright, permission, and disclaimer notice must appear in all copies of
  29. // this code.
  30. //*****************************************************************************
  31. #if defined (__cplusplus)
  32. #ifdef __REDLIB__
  33. #error Redlib does not support C++
  34. #else
  35. //*****************************************************************************
  36. //
  37. // The entry point for the C++ library startup
  38. //
  39. //*****************************************************************************
  40. extern "C" {
  41. extern void __libc_init_array(void);
  42. }
  43. #endif
  44. #endif
  45. #define WEAK __attribute__ ((weak))
  46. #define ALIAS(f) __attribute__ ((weak, alias (#f)))
  47. //*****************************************************************************
  48. #if defined (__cplusplus)
  49. extern "C" {
  50. #endif
  51. //*****************************************************************************
  52. #if defined (__USE_CMSIS) || defined (__USE_LPCOPEN)
  53. // Declaration of external SystemInit function
  54. extern void SystemInit(void);
  55. #endif
  56. //*****************************************************************************
  57. //
  58. // Forward declaration of the default handlers. These are aliased.
  59. // When the application defines a handler (with the same name), this will
  60. // automatically take precedence over these weak definitions
  61. //
  62. //*****************************************************************************
  63. void ResetISR(void);
  64. #if defined (__MULTICORE_MASTER)
  65. void ResetISR2(void);
  66. #endif
  67. WEAK void NMI_Handler(void);
  68. WEAK void HardFault_Handler(void);
  69. WEAK void MemManage_Handler(void);
  70. WEAK void BusFault_Handler(void);
  71. WEAK void UsageFault_Handler(void);
  72. WEAK void SVC_Handler(void);
  73. WEAK void DebugMon_Handler(void);
  74. WEAK void PendSV_Handler(void);
  75. WEAK void SysTick_Handler(void);
  76. WEAK void IntDefaultHandler(void);
  77. //*****************************************************************************
  78. //
  79. // Forward declaration of the specific IRQ handlers. These are aliased
  80. // to the IntDefaultHandler, which is a 'forever' loop. When the application
  81. // defines a handler (with the same name), this will automatically take
  82. // precedence over these weak definitions
  83. //
  84. //*****************************************************************************
  85. // External Interrupts - Available on M0/M4
  86. void WDT_IRQHandler(void) ALIAS(IntDefaultHandler);
  87. void BOD_IRQHandler(void) ALIAS(IntDefaultHandler);
  88. void Reserved_IRQHandler(void) ALIAS(IntDefaultHandler);
  89. void DMA_IRQHandler(void) ALIAS(IntDefaultHandler);
  90. void GINT0_IRQHandler(void) ALIAS(IntDefaultHandler);
  91. void PIN_INT0_IRQHandler(void) ALIAS(IntDefaultHandler);
  92. void PIN_INT1_IRQHandler(void) ALIAS(IntDefaultHandler);
  93. void PIN_INT2_IRQHandler(void) ALIAS(IntDefaultHandler);
  94. void PIN_INT3_IRQHandler(void) ALIAS(IntDefaultHandler);
  95. void UTICK_IRQHandler(void) ALIAS(IntDefaultHandler);
  96. void MRT_IRQHandler(void) ALIAS(IntDefaultHandler);
  97. void CT32B0_IRQHandler(void) ALIAS(IntDefaultHandler);
  98. void CT32B1_IRQHandler(void) ALIAS(IntDefaultHandler);
  99. void CT32B2_IRQHandler(void) ALIAS(IntDefaultHandler);
  100. void CT32B3_IRQHandler(void) ALIAS(IntDefaultHandler);
  101. void CT32B4_IRQHandler(void) ALIAS(IntDefaultHandler);
  102. void SCT0_IRQHandler(void) ALIAS(IntDefaultHandler);
  103. void UART0_IRQHandler(void) ALIAS(IntDefaultHandler);
  104. void UART1_IRQHandler(void) ALIAS(IntDefaultHandler);
  105. void UART2_IRQHandler(void) ALIAS(IntDefaultHandler);
  106. void UART3_IRQHandler(void) ALIAS(IntDefaultHandler);
  107. void I2C0_IRQHandler(void) ALIAS(IntDefaultHandler);
  108. void I2C1_IRQHandler(void) ALIAS(IntDefaultHandler);
  109. void I2C2_IRQHandler(void) ALIAS(IntDefaultHandler);
  110. void SPI0_IRQHandler(void) ALIAS(IntDefaultHandler);
  111. void SPI1_IRQHandler(void) ALIAS(IntDefaultHandler);
  112. void ADC_SEQA_IRQHandler(void) ALIAS(IntDefaultHandler);
  113. void ADC_SEQB_IRQHandler(void) ALIAS(IntDefaultHandler);
  114. void ADC_THCMP_IRQHandler(void) ALIAS(IntDefaultHandler);
  115. void RTC_IRQHandler(void) ALIAS(IntDefaultHandler);
  116. void MAILBOX_IRQHandler(void) ALIAS(IntDefaultHandler);
  117. // External Interrupts - For M4 only
  118. void GINT1_IRQHandler(void) ALIAS(IntDefaultHandler);
  119. void PIN_INT4_IRQHandler(void) ALIAS(IntDefaultHandler);
  120. void PIN_INT5_IRQHandler(void) ALIAS(IntDefaultHandler);
  121. void PIN_INT6_IRQHandler(void) ALIAS(IntDefaultHandler);
  122. void PIN_INT7_IRQHandler(void) ALIAS(IntDefaultHandler);
  123. void SPI2_IRQHandler(void) ALIAS(IntDefaultHandler);
  124. void SPI3_IRQHandler(void) ALIAS(IntDefaultHandler);
  125. void RIT_IRQHandler(void) ALIAS(IntDefaultHandler);
  126. void Reserved41_IRQHandler(void) ALIAS(IntDefaultHandler);
  127. void Reserved42_IRQHandler(void) ALIAS(IntDefaultHandler);
  128. void Reserved43_IRQHandler(void) ALIAS(IntDefaultHandler);
  129. void Reserved44_IRQHandler(void) ALIAS(IntDefaultHandler);
  130. //*****************************************************************************
  131. //
  132. // The entry point for the application.
  133. // __main() is the entry point for Redlib based applications
  134. // main() is the entry point for Newlib based applications
  135. //
  136. //*****************************************************************************
  137. #if defined (__REDLIB__)
  138. extern void __main(void);
  139. #endif
  140. extern int main(void);
  141. //*****************************************************************************
  142. //
  143. // External declaration for the pointer to the stack top from the Linker Script
  144. //
  145. //*****************************************************************************
  146. extern void _vStackTop(void);
  147. //*****************************************************************************
  148. #if defined (__cplusplus)
  149. } // extern "C"
  150. #endif
  151. //*****************************************************************************
  152. //
  153. // The vector table.
  154. // This relies on the linker script to place at correct location in memory.
  155. //
  156. //*****************************************************************************
  157. extern void (* const g_pfnVectors[])(void);
  158. __attribute__ ((section(".isr_vector")))
  159. void (* const g_pfnVectors[])(void) = {
  160. // Core Level - CM3
  161. &_vStackTop, // The initial stack pointer
  162. ResetISR, // The reset handler
  163. NMI_Handler, // The NMI handler
  164. HardFault_Handler, // The hard fault handler
  165. MemManage_Handler, // The MPU fault handler
  166. BusFault_Handler, // The bus fault handler
  167. UsageFault_Handler, // The usage fault handler
  168. 0, // Reserved
  169. 0, // Reserved
  170. 0, // Reserved
  171. 0, // Reserved
  172. SVC_Handler, // SVCall handler
  173. DebugMon_Handler, // Debug monitor handler
  174. 0, // Reserved
  175. PendSV_Handler, // The PendSV handler
  176. SysTick_Handler, // The SysTick handler
  177. // External Interrupts - Available on M0/M4
  178. WDT_IRQHandler, // Watchdog
  179. BOD_IRQHandler, // Brown Out Detect
  180. Reserved_IRQHandler, // Reserved
  181. DMA_IRQHandler, // DMA Controller
  182. GINT0_IRQHandler, // GPIO Group0 Interrupt
  183. PIN_INT0_IRQHandler, // PIO INT0
  184. PIN_INT1_IRQHandler, // PIO INT1
  185. PIN_INT2_IRQHandler, // PIO INT2
  186. PIN_INT3_IRQHandler, // PIO INT3
  187. UTICK_IRQHandler, // UTICK timer
  188. MRT_IRQHandler, // Multi-Rate Timer
  189. CT32B0_IRQHandler, // Counter Timer 0
  190. CT32B1_IRQHandler, // Counter Timer 1
  191. CT32B2_IRQHandler, // Counter Timer 2
  192. CT32B3_IRQHandler, // Counter Timer 3
  193. CT32B4_IRQHandler, // Counter Timer 4
  194. SCT0_IRQHandler, // Smart Counter Timer
  195. UART0_IRQHandler, // UART0
  196. UART1_IRQHandler, // UART1
  197. UART2_IRQHandler, // UART2
  198. UART3_IRQHandler, // UART3
  199. I2C0_IRQHandler, // I2C0 controller
  200. I2C1_IRQHandler, // I2C1 controller
  201. I2C2_IRQHandler, // I2C2 controller
  202. SPI0_IRQHandler, // SPI0 controller
  203. SPI1_IRQHandler, // SPI1 controller
  204. ADC_SEQA_IRQHandler, // ADC SEQA
  205. ADC_SEQB_IRQHandler, // ADC SEQB
  206. ADC_THCMP_IRQHandler, // ADC THCMP and OVERRUN ORed
  207. RTC_IRQHandler, // RTC Timer
  208. Reserved_IRQHandler, // Reserved
  209. MAILBOX_IRQHandler, // Mailbox
  210. // External Interrupts - For M4 only
  211. GINT1_IRQHandler, // GPIO Group1 Interrupt
  212. PIN_INT4_IRQHandler, // PIO INT4
  213. PIN_INT5_IRQHandler, // PIO INT5
  214. PIN_INT6_IRQHandler, // PIO INT6
  215. PIN_INT7_IRQHandler, // PIO INT7
  216. SPI2_IRQHandler, // SPI2 controller
  217. SPI3_IRQHandler, // SPI3 controller
  218. 0, // Reserved
  219. RIT_IRQHandler, // RIT Timer
  220. Reserved41_IRQHandler, // Reserved
  221. Reserved42_IRQHandler, // Reserved
  222. Reserved43_IRQHandler, // Reserved
  223. Reserved44_IRQHandler, // Reserved
  224. }; /* End of g_pfnVectors */
  225. //*****************************************************************************
  226. // Functions to carry out the initialization of RW and BSS data sections. These
  227. // are written as separate functions rather than being inlined within the
  228. // ResetISR() function in order to cope with MCUs with multiple banks of
  229. // memory.
  230. //*****************************************************************************
  231. __attribute__ ((section(".after_vectors")))
  232. void data_init(unsigned int romstart, unsigned int start, unsigned int len) {
  233. unsigned int *pulDest = (unsigned int*) start;
  234. unsigned int *pulSrc = (unsigned int*) romstart;
  235. unsigned int loop;
  236. for (loop = 0; loop < len; loop = loop + 4)
  237. *pulDest++ = *pulSrc++;
  238. }
  239. __attribute__ ((section(".after_vectors")))
  240. void bss_init(unsigned int start, unsigned int len) {
  241. unsigned int *pulDest = (unsigned int*) start;
  242. unsigned int loop;
  243. for (loop = 0; loop < len; loop = loop + 4)
  244. *pulDest++ = 0;
  245. }
  246. //*****************************************************************************
  247. // The following symbols are constructs generated by the linker, indicating
  248. // the location of various points in the "Global Section Table". This table is
  249. // created by the linker via the Code Red managed linker script mechanism. It
  250. // contains the load address, execution address and length of each RW data
  251. // section and the execution and length of each BSS (zero initialized) section.
  252. //*****************************************************************************
  253. extern unsigned int __data_section_table;
  254. extern unsigned int __data_section_table_end;
  255. extern unsigned int __bss_section_table;
  256. extern unsigned int __bss_section_table_end;
  257. //*****************************************************************************
  258. // Reset entry point for your code.
  259. // Sets up a simple runtime environment and initializes the C/C++
  260. // library.
  261. //*****************************************************************************
  262. #if defined (__MULTICORE_MASTER)
  263. //#define cpu_ctrl 0x40000300
  264. //#define coproc_boot 0x40000304
  265. //#define set coproc_stack 0x40000308
  266. __attribute__ ((naked, section(".after_vectors.reset")))
  267. void ResetISR(void) {
  268. asm volatile(
  269. ".set cpu_ctrl, 0x40000300\t\n"
  270. ".set coproc_boot, 0x40000304\t\n"
  271. ".set coproc_stack, 0x40000308\t\n"
  272. "MOVS R5, #1\t\n"
  273. "LDR R0, =0xE000ED00\t\n"
  274. "LDR R1, [R0]\t\n" // READ CPUID register
  275. "LDR R2,=0x410CC601\t\n" // CM0 R0p1 identifier
  276. "EORS R1,R1,R2\t\n" // XOR to see if we are C0
  277. "LDR R3, =cpu_ctrl\t\n" // get address of CPU_CTRL
  278. "LDR R1,[R3]\t\n" // read cpu_ctrl reg into R1
  279. "BEQ.N cm0_boot\t\n"
  280. "cm4_boot:\t\n"
  281. "LDR R0,=coproc_boot\t\n" // coproc boot address
  282. "LDR R0,[R0]\t\n" // get address to branch to
  283. "MOVS R0,R0\t\n" // Check if 0
  284. "BEQ.N check_master_m4\t\n" // if zero in boot reg, we just branch to real reset
  285. "BX R0\t\n" // otherwise, we branch to boot address
  286. "commonboot:\t\n"
  287. "LDR R0, =ResetISR2\t\n" // Jump to 'real' reset handler
  288. "BX R0\t\n"
  289. "cm0_boot:\t\n"
  290. "LDR R0,=coproc_boot\t\n" // coproc boot address
  291. "LDR R0,[R0]\t\n" // get address to branch to
  292. "MOVS R0,R0\t\n" // Check if 0
  293. "BEQ.N check_master_m0\t\n" // if zero in boot reg, we just branch to real reset
  294. "LDR R1,=coproc_stack\t\n" // pickup coprocesor stackpointer (from syscon CPSTACK)
  295. "LDR R1,[R1]\t\n"
  296. "MOV SP,R1\t\n"
  297. "BX R0\t\n" // goto boot address
  298. "check_master_m0:\t\n"
  299. "ANDS R1,R1,R5\t\n" // bit test bit0
  300. "BEQ.N commonboot\t\n" // if we get 0, that means we are masters
  301. "B.N goto_sleep_pending_reset\t\n" // Otherwise, there is no startup vector for slave, so we go to sleep
  302. "check_master_m4:\t\n"
  303. "ANDS R1,R1,R5\t\n" // bit test bit0
  304. "BNE.N commonboot\t\n" // if we get 1, that means we are masters
  305. "goto_sleep_pending_reset:\t\n"
  306. "MOV SP,R5\t\n" // load 0x1 into SP so that any stacking (eg on NMI) will not cause us to wakeup
  307. // and write to uninitialised Stack area (instead it will LOCK us up before we cause damage)
  308. // this code should only be reached if debugger bypassed ROM or we changed master without giving
  309. // correct start address, the only way out of this is through a debugger change of SP and PC
  310. "sleepo:\t\n"
  311. "WFI\t\n" // go to sleep
  312. "B.N sleepo\t\n"
  313. );
  314. }
  315. __attribute__ ((section(".after_vectors.reset")))
  316. void ResetISR2(void) {
  317. #else
  318. __attribute__ ((section(".after_vectors.reset")))
  319. void ResetISR(void) {
  320. #endif
  321. // If this is not the CM0+ core...
  322. #if !defined (CORE_M0PLUS)
  323. // If this is not a slave project...
  324. #if !defined (__MULTICORE_M0SLAVE) && \
  325. !defined (__MULTICORE_M4SLAVE)
  326. // Optionally enable RAM banks that may be off by default at reset
  327. #if !defined (DONT_ENABLE_DISABLED_RAMBANKS)
  328. volatile unsigned int *SYSCON_SYSAHBCLKCTRL0 = (unsigned int *) 0x400000c0;
  329. // Ensure that SRAM2(4) bit in SYSAHBCLKCTRL0 are set
  330. *SYSCON_SYSAHBCLKCTRL0 |= (1 << 4);
  331. #endif
  332. #endif
  333. #endif
  334. //
  335. // Copy the data sections from flash to SRAM.
  336. //
  337. unsigned int LoadAddr, ExeAddr, SectionLen;
  338. unsigned int *SectionTableAddr;
  339. // Load base address of Global Section Table
  340. SectionTableAddr = &__data_section_table;
  341. // Copy the data sections from flash to SRAM.
  342. while (SectionTableAddr < &__data_section_table_end) {
  343. LoadAddr = *SectionTableAddr++;
  344. ExeAddr = *SectionTableAddr++;
  345. SectionLen = *SectionTableAddr++;
  346. data_init(LoadAddr, ExeAddr, SectionLen);
  347. }
  348. // At this point, SectionTableAddr = &__bss_section_table;
  349. // Zero fill the bss segment
  350. while (SectionTableAddr < &__bss_section_table_end) {
  351. ExeAddr = *SectionTableAddr++;
  352. SectionLen = *SectionTableAddr++;
  353. bss_init(ExeAddr, SectionLen);
  354. }
  355. #if !defined (__USE_LPCOPEN)
  356. // LPCOpen init code deals with FP and VTOR initialisation
  357. #if defined (__VFP_FP__) && !defined (__SOFTFP__)
  358. /*
  359. * Code to enable the Cortex-M4 FPU only included
  360. * if appropriate build options have been selected.
  361. * Code taken from Section 7.1, Cortex-M4 TRM (DDI0439C)
  362. */
  363. // CPACR is located at address 0xE000ED88
  364. asm("LDR.W R0, =0xE000ED88");
  365. // Read CPACR
  366. asm("LDR R1, [R0]");
  367. // Set bits 20-23 to enable CP10 and CP11 coprocessors
  368. asm(" ORR R1, R1, #(0xF << 20)");
  369. // Write back the modified value to the CPACR
  370. asm("STR R1, [R0]");
  371. #endif // (__VFP_FP__) && !(__SOFTFP__)
  372. // ******************************
  373. // Check to see if we are running the code from a non-zero
  374. // address (eg RAM, external flash), in which case we need
  375. // to modify the VTOR register to tell the CPU that the
  376. // vector table is located at a non-0x0 address.
  377. // Note that we do not use the CMSIS register access mechanism,
  378. // as there is no guarantee that the project has been configured
  379. // to use CMSIS.
  380. unsigned int * pSCB_VTOR = (unsigned int *) 0xE000ED08;
  381. if ((unsigned int *) g_pfnVectors != (unsigned int *) 0x00000000) {
  382. // CMSIS : SCB->VTOR = <address of vector table>
  383. *pSCB_VTOR = (unsigned int) g_pfnVectors;
  384. }
  385. #endif
  386. #if defined (__USE_CMSIS) || defined (__USE_LPCOPEN)
  387. SystemInit();
  388. #endif
  389. #if defined (__cplusplus)
  390. //
  391. // Call C++ library initialisation
  392. //
  393. __libc_init_array();
  394. #endif
  395. #if defined (__REDLIB__)
  396. // Call the Redlib library, which in turn calls main()
  397. __main();
  398. #else
  399. main();
  400. #endif
  401. //
  402. // main() shouldn't return, but if it does, we'll just enter an infinite loop
  403. //
  404. while (1) {
  405. ;
  406. }
  407. }
  408. //*****************************************************************************
  409. // Default exception handlers. Override the ones here by defining your own
  410. // handler routines in your application code.
  411. //*****************************************************************************
  412. __attribute__ ((section(".after_vectors")))
  413. void NMI_Handler(void) {
  414. while (1) {
  415. }
  416. }
  417. __attribute__ ((section(".after_vectors")))
  418. void HardFault_Handler(void) {
  419. while (1) {
  420. }
  421. }
  422. __attribute__ ((section(".after_vectors")))
  423. void SVC_Handler(void) {
  424. while (1) {
  425. }
  426. }
  427. __attribute__ ((section(".after_vectors")))
  428. void PendSV_Handler(void) {
  429. while (1) {
  430. }
  431. }
  432. __attribute__ ((section(".after_vectors")))
  433. void SysTick_Handler(void) {
  434. while (1) {
  435. }
  436. }
  437. //*****************************************************************************
  438. //
  439. // Processor ends up here if an unexpected interrupt occurs or a specific
  440. // handler is not present in the application code.
  441. //
  442. //*****************************************************************************
  443. __attribute__ ((section(".after_vectors")))
  444. void IntDefaultHandler(void) {
  445. while (1) {
  446. }
  447. }