initial commit
[armstart-ibdap] / src / cr_startup_lpc11uxx.c
1 //*****************************************************************************\r
2 // LPC11Uxx Microcontroller Startup code for use with LPCXpresso IDE\r
3 //\r
4 // Version : 141204\r
5 //*****************************************************************************\r
6 //\r
7 // Copyright(C) NXP Semiconductors, 2013-2014\r
8 // All rights reserved.\r
9 //\r
10 // Software that is described herein is for illustrative purposes only\r
11 // which provides customers with programming information regarding the\r
12 // LPC products.  This software is supplied "AS IS" without any warranties of\r
13 // any kind, and NXP Semiconductors and its licensor disclaim any and\r
14 // all warranties, express or implied, including all implied warranties of\r
15 // merchantability, fitness for a particular purpose and non-infringement of\r
16 // intellectual property rights.  NXP Semiconductors assumes no responsibility\r
17 // or liability for the use of the software, conveys no license or rights under any\r
18 // patent, copyright, mask work right, or any other intellectual property rights in\r
19 // or to any products. NXP Semiconductors reserves the right to make changes\r
20 // in the software without notification. NXP Semiconductors also makes no\r
21 // representation or warranty that such application will be suitable for the\r
22 // specified use without further testing or modification.\r
23 //\r
24 // Permission to use, copy, modify, and distribute this software and its\r
25 // documentation is hereby granted, under NXP Semiconductors' and its\r
26 // licensor's relevant copyrights in the software, without fee, provided that it\r
27 // is used in conjunction with NXP Semiconductors microcontrollers.  This\r
28 // copyright, permission, and disclaimer notice must appear in all copies of\r
29 // this code.\r
30 //*****************************************************************************\r
31 \r
32 #if defined (__cplusplus)\r
33 #ifdef __REDLIB__\r
34 #error Redlib does not support C++\r
35 #else\r
36 //*****************************************************************************\r
37 //\r
38 // The entry point for the C++ library startup\r
39 //\r
40 //*****************************************************************************\r
41 extern "C" {\r
42     extern void __libc_init_array(void);\r
43 }\r
44 #endif\r
45 #endif\r
46 \r
47 #define WEAK __attribute__ ((weak))\r
48 #define ALIAS(f) __attribute__ ((weak, alias (#f)))\r
49 \r
50 //*****************************************************************************\r
51 #if defined (__cplusplus)\r
52 extern "C" {\r
53 #endif\r
54 \r
55 //*****************************************************************************\r
56 #if defined (__USE_CMSIS) || defined (__USE_LPCOPEN)\r
57 // Declaration of external SystemInit function\r
58 extern void SystemInit(void);\r
59 #endif\r
60 \r
61 // Patch the AEABI integer divide functions to use MCU's romdivide library\r
62 #ifdef __USE_ROMDIVIDE\r
63 // Location in memory that holds the address of the ROM Driver table\r
64 #define PTR_ROM_DRIVER_TABLE ((unsigned int *)(0x1FFF1FF8))\r
65 // Variables to store addresses of idiv and udiv functions within MCU ROM\r
66 unsigned int *pDivRom_idiv;\r
67 unsigned int *pDivRom_uidiv;\r
68 #endif\r
69 \r
70 //*****************************************************************************\r
71 //\r
72 // Forward declaration of the default handlers. These are aliased.\r
73 // When the application defines a handler (with the same name), this will \r
74 // automatically take precedence over these weak definitions\r
75 //\r
76 //*****************************************************************************\r
77      void ResetISR(void);\r
78 WEAK void NMI_Handler(void);\r
79 WEAK void HardFault_Handler(void);\r
80 WEAK void SVC_Handler(void);\r
81 WEAK void PendSV_Handler(void);\r
82 WEAK void SysTick_Handler(void);\r
83 WEAK void IntDefaultHandler(void);\r
84 //*****************************************************************************\r
85 //\r
86 // Forward declaration of the specific IRQ handlers. These are aliased\r
87 // to the IntDefaultHandler, which is a 'forever' loop. When the application\r
88 // defines a handler (with the same name), this will automatically take\r
89 // precedence over these weak definitions\r
90 //\r
91 //*****************************************************************************\r
92 void FLEX_INT0_IRQHandler (void) ALIAS(IntDefaultHandler);\r
93 void FLEX_INT1_IRQHandler (void) ALIAS(IntDefaultHandler);\r
94 void FLEX_INT2_IRQHandler (void) ALIAS(IntDefaultHandler);\r
95 void FLEX_INT3_IRQHandler (void) ALIAS(IntDefaultHandler);\r
96 void FLEX_INT4_IRQHandler (void) ALIAS(IntDefaultHandler);\r
97 void FLEX_INT5_IRQHandler (void) ALIAS(IntDefaultHandler);\r
98 void FLEX_INT6_IRQHandler (void) ALIAS(IntDefaultHandler);\r
99 void FLEX_INT7_IRQHandler (void) ALIAS(IntDefaultHandler);\r
100 void GINT0_IRQHandler (void) ALIAS(IntDefaultHandler);\r
101 void GINT1_IRQHandler (void) ALIAS(IntDefaultHandler);\r
102 void SSP1_IRQHandler (void) ALIAS(IntDefaultHandler);\r
103 void I2C_IRQHandler (void) ALIAS(IntDefaultHandler);\r
104 void TIMER16_0_IRQHandler (void) ALIAS(IntDefaultHandler);\r
105 void TIMER16_1_IRQHandler (void) ALIAS(IntDefaultHandler);\r
106 void TIMER32_0_IRQHandler (void) ALIAS(IntDefaultHandler);\r
107 void TIMER32_1_IRQHandler (void) ALIAS(IntDefaultHandler);\r
108 void SSP0_IRQHandler (void) ALIAS(IntDefaultHandler);\r
109 void UART_IRQHandler (void) ALIAS(IntDefaultHandler);\r
110 void USB_IRQHandler (void) ALIAS(IntDefaultHandler);\r
111 void USB_FIQHandler (void) ALIAS(IntDefaultHandler);\r
112 void ADC_IRQHandler (void) ALIAS(IntDefaultHandler);\r
113 void WDT_IRQHandler (void) ALIAS(IntDefaultHandler);\r
114 void BOD_IRQHandler (void) ALIAS(IntDefaultHandler);\r
115 void FMC_IRQHandler (void) ALIAS(IntDefaultHandler);\r
116 void USBWakeup_IRQHandler (void) ALIAS(IntDefaultHandler);\r
117 \r
118 //*****************************************************************************\r
119 // The entry point for the application.\r
120 // __main() is the entry point for redlib based applications\r
121 // main() is the entry point for newlib based applications\r
122 //*****************************************************************************\r
123 #if defined (__REDLIB__)\r
124 extern void __main(void);\r
125 #else\r
126 extern int main(void);\r
127 #endif\r
128 //*****************************************************************************\r
129 //\r
130 // External declaration for the pointer to the stack top from the Linker Script\r
131 //\r
132 //*****************************************************************************\r
133 extern void _vStackTop(void);\r
134 \r
135 //*****************************************************************************\r
136 #if defined (__cplusplus)\r
137 } // extern "C"\r
138 #endif\r
139 //*****************************************************************************\r
140 //\r
141 // The vector table.  Note that the proper constructs must be placed on this to\r
142 // ensure that it ends up at physical address 0x0000.0000.\r
143 //\r
144 //*****************************************************************************\r
145 extern void (* const g_pfnVectors[])(void);\r
146 __attribute__ ((section(".isr_vector")))\r
147 void (* const g_pfnVectors[])(void) = {\r
148     &_vStackTop,              // The initial stack pointer\r
149     ResetISR,                         // The reset handler\r
150     NMI_Handler,                      // The NMI handler\r
151     HardFault_Handler,                // The hard fault handler\r
152     0,                                // Reserved\r
153     0,                                // Reserved\r
154     0,                                // Reserved\r
155     0,                                // Reserved\r
156     0,                                // Reserved\r
157     0,                                // Reserved\r
158     0,                                // Reserved\r
159     SVC_Handler,                      // SVCall handler\r
160     0,                                // Reserved\r
161     0,                                // Reserved\r
162     PendSV_Handler,                   // The PendSV handler\r
163     SysTick_Handler,                  // The SysTick handler\r
164 \r
165     // LPC11U specific handlers\r
166     FLEX_INT0_IRQHandler,             //  0 - GPIO pin interrupt 0\r
167     FLEX_INT1_IRQHandler,             //  1 - GPIO pin interrupt 1\r
168     FLEX_INT2_IRQHandler,             //  2 - GPIO pin interrupt 2\r
169     FLEX_INT3_IRQHandler,             //  3 - GPIO pin interrupt 3\r
170     FLEX_INT4_IRQHandler,             //  4 - GPIO pin interrupt 4\r
171     FLEX_INT5_IRQHandler,             //  5 - GPIO pin interrupt 5\r
172     FLEX_INT6_IRQHandler,             //  6 - GPIO pin interrupt 6\r
173     FLEX_INT7_IRQHandler,             //  7 - GPIO pin interrupt 7\r
174     GINT0_IRQHandler,                 //  8 - GPIO GROUP0 interrupt\r
175     GINT1_IRQHandler,                 //  9 - GPIO GROUP1 interrupt\r
176     0,                                // 10 - Reserved\r
177     0,                                // 11 - Reserved\r
178     0,                                // 12 - Reserved\r
179     0,                                // 13 - Reserved\r
180     SSP1_IRQHandler,                  // 14 - SPI/SSP1 Interrupt\r
181     I2C_IRQHandler,                   // 15 - I2C0\r
182     TIMER16_0_IRQHandler,             // 16 - CT16B0 (16-bit Timer 0)\r
183     TIMER16_1_IRQHandler,             // 17 - CT16B1 (16-bit Timer 1)\r
184     TIMER32_0_IRQHandler,             // 18 - CT32B0 (32-bit Timer 0)\r
185     TIMER32_1_IRQHandler,             // 19 - CT32B1 (32-bit Timer 1)\r
186     SSP0_IRQHandler,                  // 20 - SPI/SSP0 Interrupt\r
187     UART_IRQHandler,                  // 21 - UART0\r
188     USB_IRQHandler,                   // 22 - USB IRQ\r
189     USB_FIQHandler,                   // 23 - USB FIQ\r
190     ADC_IRQHandler,                   // 24 - ADC (A/D Converter)\r
191     WDT_IRQHandler,                   // 25 - WDT (Watchdog Timer)\r
192     BOD_IRQHandler,                   // 26 - BOD (Brownout Detect)\r
193     FMC_IRQHandler,                   // 27 - IP2111 Flash Memory Controller\r
194     0,                                // 28 - Reserved\r
195     0,                                // 29 - Reserved\r
196     USBWakeup_IRQHandler,             // 30 - USB wake-up interrupt\r
197     0,                                // 31 - Reserved\r
198 };\r
199 \r
200 //*****************************************************************************\r
201 // Functions to carry out the initialization of RW and BSS data sections. These\r
202 // are written as separate functions rather than being inlined within the\r
203 // ResetISR() function in order to cope with MCUs with multiple banks of\r
204 // memory.\r
205 //*****************************************************************************\r
206 __attribute__ ((section(".after_vectors")))\r
207 void data_init(unsigned int romstart, unsigned int start, unsigned int len) {\r
208     unsigned int *pulDest = (unsigned int*) start;\r
209     unsigned int *pulSrc = (unsigned int*) romstart;\r
210     unsigned int loop;\r
211     for (loop = 0; loop < len; loop = loop + 4)\r
212         *pulDest++ = *pulSrc++;\r
213 }\r
214 \r
215 __attribute__ ((section(".after_vectors")))\r
216 void bss_init(unsigned int start, unsigned int len) {\r
217     unsigned int *pulDest = (unsigned int*) start;\r
218     unsigned int loop;\r
219     for (loop = 0; loop < len; loop = loop + 4)\r
220         *pulDest++ = 0;\r
221 }\r
222 \r
223 //*****************************************************************************\r
224 // The following symbols are constructs generated by the linker, indicating\r
225 // the location of various points in the "Global Section Table". This table is\r
226 // created by the linker via the Code Red managed linker script mechanism. It\r
227 // contains the load address, execution address and length of each RW data\r
228 // section and the execution and length of each BSS (zero initialized) section.\r
229 //*****************************************************************************\r
230 extern unsigned int __data_section_table;\r
231 extern unsigned int __data_section_table_end;\r
232 extern unsigned int __bss_section_table;\r
233 extern unsigned int __bss_section_table_end;\r
234 \r
235 //*****************************************************************************\r
236 // Reset entry point for your code.\r
237 // Sets up a simple runtime environment and initializes the C/C++\r
238 // library.\r
239 //*****************************************************************************\r
240 __attribute__ ((section(".after_vectors")))\r
241 void\r
242 ResetISR(void) {\r
243 \r
244 \r
245 \r
246     //\r
247     // Copy the data sections from flash to SRAM.\r
248     //\r
249     unsigned int LoadAddr, ExeAddr, SectionLen;\r
250     unsigned int *SectionTableAddr;\r
251 \r
252     // Load base address of Global Section Table\r
253     SectionTableAddr = &__data_section_table;\r
254 \r
255     // Copy the data sections from flash to SRAM.\r
256     while (SectionTableAddr < &__data_section_table_end) {\r
257         LoadAddr = *SectionTableAddr++;\r
258         ExeAddr = *SectionTableAddr++;\r
259         SectionLen = *SectionTableAddr++;\r
260         data_init(LoadAddr, ExeAddr, SectionLen);\r
261     }\r
262     // At this point, SectionTableAddr = &__bss_section_table;\r
263     // Zero fill the bss segment\r
264     while (SectionTableAddr < &__bss_section_table_end) {\r
265         ExeAddr = *SectionTableAddr++;\r
266         SectionLen = *SectionTableAddr++;\r
267         bss_init(ExeAddr, SectionLen);\r
268     }\r
269 \r
270 #if defined (__USE_CMSIS) || defined (__USE_LPCOPEN)\r
271     SystemInit();\r
272 #endif\r
273 \r
274 #if defined (__cplusplus)\r
275     //\r
276     // Call C++ library initialisation\r
277     //\r
278     __libc_init_array();\r
279 #endif\r
280 \r
281 #if defined (__REDLIB__)\r
282     // Call the Redlib library, which in turn calls main()\r
283     __main() ;\r
284 #else\r
285     main();\r
286 #endif\r
287     //\r
288     // main() shouldn't return, but if it does, we'll just enter an infinite loop\r
289     //\r
290     while (1) {\r
291         ;\r
292     }\r
293 }\r
294 \r
295 //*****************************************************************************\r
296 // Default exception handlers. Override the ones here by defining your own\r
297 // handler routines in your application code.\r
298 //*****************************************************************************\r
299 __attribute__ ((section(".after_vectors")))\r
300 void NMI_Handler(void)\r
301 {\r
302     while(1)\r
303     {\r
304     }\r
305 }\r
306 __attribute__ ((section(".after_vectors")))\r
307 void HardFault_Handler(void)\r
308 {\r
309     while(1)\r
310     {\r
311     }\r
312 }\r
313 __attribute__ ((section(".after_vectors")))\r
314 void SVC_Handler(void)\r
315 {\r
316     while(1)\r
317     {\r
318     }\r
319 }\r
320 __attribute__ ((section(".after_vectors")))\r
321 void PendSV_Handler(void)\r
322 {\r
323     while(1)\r
324     {\r
325     }\r
326 }\r
327 __attribute__ ((section(".after_vectors")))\r
328 void SysTick_Handler(void)\r
329 {\r
330     while(1)\r
331     {\r
332     }\r
333 }\r
334 \r
335 //*****************************************************************************\r
336 //\r
337 // Processor ends up here if an unexpected interrupt occurs or a specific\r
338 // handler is not present in the application code.\r
339 //\r
340 //*****************************************************************************\r
341 __attribute__ ((section(".after_vectors")))\r
342 void IntDefaultHandler(void)\r
343 {\r
344     while(1)\r
345     {\r
346     }\r
347 }\r
348 \r