cr_startup_lpc5410x-m0.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. //*****************************************************************************
  2. // LPC5410x M0 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 - CM0plus
  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. 0, // Reserved
  166. 0, // Reserved
  167. 0, // Reserved
  168. 0, // Reserved
  169. 0, // Reserved
  170. 0, // Reserved
  171. 0, // Reserved
  172. SVC_Handler, // SVCall handler
  173. 0, // Reserved
  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. ".syntax unified\t\n"
  270. ".set cpu_ctrl, 0x40000300\t\n"
  271. ".set coproc_boot, 0x40000304\t\n"
  272. ".set coproc_stack, 0x40000308\t\n"
  273. "MOVS R5, #1\t\n"
  274. "LDR R0, =0xE000ED00\t\n"
  275. "LDR R1, [R0]\t\n" // READ CPUID register
  276. "LDR R2,=0x410CC601\t\n" // CM0 R0p1 identifier
  277. "EORS R1,R1,R2\t\n" // XOR to see if we are C0
  278. "LDR R3, =cpu_ctrl\t\n" // get address of CPU_CTRL
  279. "LDR R1,[R3]\t\n" // read cpu_ctrl reg into R1
  280. "BEQ.N cm0_boot\t\n"
  281. "cm4_boot:\t\n"
  282. "LDR R0,=coproc_boot\t\n" // coproc boot address
  283. "LDR R0,[R0]\t\n" // get address to branch to
  284. "MOVS R0,R0\t\n" // Check if 0
  285. "BEQ.N check_master_m4\t\n" // if zero in boot reg, we just branch to real reset
  286. "BX R0\t\n" // otherwise, we branch to boot address
  287. "commonboot:\t\n"
  288. "LDR R0, =ResetISR2\t\n" // Jump to 'real' reset handler
  289. "BX R0\t\n"
  290. "cm0_boot:\t\n"
  291. "LDR R0,=coproc_boot\t\n" // coproc boot address
  292. "LDR R0,[R0]\t\n" // get address to branch to
  293. "MOVS R0,R0\t\n" // Check if 0
  294. "BEQ.N check_master_m0\t\n" // if zero in boot reg, we just branch to real reset
  295. "LDR R1,=coproc_stack\t\n" // pickup coprocesor stackpointer (from syscon CPSTACK)
  296. "LDR R1,[R1]\t\n"
  297. "MOV SP,R1\t\n"
  298. "BX R0\t\n" // goto boot address
  299. "check_master_m0:\t\n"
  300. "ANDS R1,R1,R5\t\n" // bit test bit0
  301. "BEQ.N commonboot\t\n" // if we get 0, that means we are masters
  302. "B.N goto_sleep_pending_reset\t\n" // Otherwise, there is no startup vector for slave, so we go to sleep
  303. "check_master_m4:\t\n"
  304. "ANDS R1,R1,R5\t\n" // bit test bit0
  305. "BNE.N commonboot\t\n" // if we get 1, that means we are masters
  306. "goto_sleep_pending_reset:\t\n"
  307. "MOV SP,R5\t\n" // load 0x1 into SP so that any stacking (eg on NMI) will not cause us to wakeup
  308. // and write to uninitialised Stack area (instead it will LOCK us up before we cause damage)
  309. // this code should only be reached if debugger bypassed ROM or we changed master without giving
  310. // correct start address, the only way out of this is through a debugger change of SP and PC
  311. "sleepo:\t\n"
  312. "WFI\t\n" // go to sleep
  313. "B.N sleepo\t\n"
  314. ".syntax divided\t\n"
  315. );
  316. }
  317. __attribute__ ((section(".after_vectors.reset")))
  318. void ResetISR2(void) {
  319. #else
  320. __attribute__ ((section(".after_vectors.reset")))
  321. void ResetISR(void) {
  322. #endif
  323. // If this is not the CM0+ core...
  324. #if !defined (CORE_M0PLUS)
  325. // If this is not a slave project...
  326. #if !defined (__MULTICORE_M0SLAVE) && \
  327. !defined (__MULTICORE_M4SLAVE)
  328. // Optionally enable RAM banks that may be off by default at reset
  329. #if !defined (DONT_ENABLE_DISABLED_RAMBANKS)
  330. volatile unsigned int *SYSCON_SYSAHBCLKCTRL0 = (unsigned int *) 0x400000c0;
  331. // Ensure that SRAM2(4) bit in SYSAHBCLKCTRL0 are set
  332. *SYSCON_SYSAHBCLKCTRL0 |= (1 << 4);
  333. #endif
  334. #endif
  335. #endif
  336. //
  337. // Copy the data sections from flash to SRAM.
  338. //
  339. unsigned int LoadAddr, ExeAddr, SectionLen;
  340. unsigned int *SectionTableAddr;
  341. // Load base address of Global Section Table
  342. SectionTableAddr = &__data_section_table;
  343. // Copy the data sections from flash to SRAM.
  344. while (SectionTableAddr < &__data_section_table_end) {
  345. LoadAddr = *SectionTableAddr++;
  346. ExeAddr = *SectionTableAddr++;
  347. SectionLen = *SectionTableAddr++;
  348. data_init(LoadAddr, ExeAddr, SectionLen);
  349. }
  350. // At this point, SectionTableAddr = &__bss_section_table;
  351. // Zero fill the bss segment
  352. while (SectionTableAddr < &__bss_section_table_end) {
  353. ExeAddr = *SectionTableAddr++;
  354. SectionLen = *SectionTableAddr++;
  355. bss_init(ExeAddr, SectionLen);
  356. }
  357. #if !defined (__USE_LPCOPEN)
  358. // LPCOpen init code deals with VTOR initialisation
  359. unsigned int * pSCB_VTOR = (unsigned int *) 0xE000ED08;
  360. if ((unsigned int *) g_pfnVectors != (unsigned int *) 0x00000000) {
  361. // CMSIS : SCB->VTOR = <address of vector table>
  362. *pSCB_VTOR = (unsigned int) g_pfnVectors;
  363. }
  364. #endif
  365. #if defined (__USE_CMSIS) || defined (__USE_LPCOPEN)
  366. SystemInit();
  367. #endif
  368. #if defined (__cplusplus)
  369. //
  370. // Call C++ library initialisation
  371. //
  372. __libc_init_array();
  373. #endif
  374. #if defined (__REDLIB__)
  375. // Call the Redlib library, which in turn calls main()
  376. __main();
  377. #else
  378. main();
  379. #endif
  380. //
  381. // main() shouldn't return, but if it does, we'll just enter an infinite loop
  382. //
  383. while (1) {
  384. ;
  385. }
  386. }
  387. //*****************************************************************************
  388. // Default exception handlers. Override the ones here by defining your own
  389. // handler routines in your application code.
  390. //*****************************************************************************
  391. __attribute__ ((section(".after_vectors")))
  392. void NMI_Handler(void)
  393. { while(1) {}
  394. }
  395. __attribute__ ((section(".after_vectors")))
  396. void HardFault_Handler(void)
  397. { while(1) {}
  398. }
  399. __attribute__ ((section(".after_vectors")))
  400. void SVC_Handler(void)
  401. { while(1) {}
  402. }
  403. __attribute__ ((section(".after_vectors")))
  404. void PendSV_Handler(void)
  405. { while(1) {}
  406. }
  407. __attribute__ ((section(".after_vectors")))
  408. void SysTick_Handler(void)
  409. { while(1) {}
  410. }
  411. //*****************************************************************************
  412. //
  413. // Processor ends up here if an unexpected interrupt occurs or a specific
  414. // handler is not present in the application code.
  415. //
  416. //*****************************************************************************
  417. __attribute__ ((section(".after_vectors")))
  418. void IntDefaultHandler(void)
  419. { while(1) {}
  420. }