1 //*****************************************************************************
\r
2 // LPC11Uxx Microcontroller Startup code for use with LPCXpresso IDE
\r
5 //*****************************************************************************
\r
7 // Copyright(C) NXP Semiconductors, 2013-2014
\r
8 // All rights reserved.
\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
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
30 //*****************************************************************************
\r
32 #if defined (__cplusplus)
\r
34 #error Redlib does not support C++
\r
36 //*****************************************************************************
\r
38 // The entry point for the C++ library startup
\r
40 //*****************************************************************************
\r
42 extern void __libc_init_array(void);
\r
47 #define WEAK __attribute__ ((weak))
\r
48 #define ALIAS(f) __attribute__ ((weak, alias (#f)))
\r
50 //*****************************************************************************
\r
51 #if defined (__cplusplus)
\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
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
70 //*****************************************************************************
\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
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
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
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
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
126 extern int main(void);
\r
128 //*****************************************************************************
\r
130 // External declaration for the pointer to the stack top from the Linker Script
\r
132 //*****************************************************************************
\r
133 extern void _vStackTop(void);
\r
135 //*****************************************************************************
\r
136 #if defined (__cplusplus)
\r
139 //*****************************************************************************
\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
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
159 SVC_Handler, // SVCall handler
\r
162 PendSV_Handler, // The PendSV handler
\r
163 SysTick_Handler, // The SysTick handler
\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
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
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
211 for (loop = 0; loop < len; loop = loop + 4)
\r
212 *pulDest++ = *pulSrc++;
\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
219 for (loop = 0; loop < len; loop = loop + 4)
\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
235 //*****************************************************************************
\r
236 // Reset entry point for your code.
\r
237 // Sets up a simple runtime environment and initializes the C/C++
\r
239 //*****************************************************************************
\r
240 __attribute__ ((section(".after_vectors")))
\r
247 // Copy the data sections from flash to SRAM.
\r
249 unsigned int LoadAddr, ExeAddr, SectionLen;
\r
250 unsigned int *SectionTableAddr;
\r
252 // Load base address of Global Section Table
\r
253 SectionTableAddr = &__data_section_table;
\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
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
270 #if defined (__USE_CMSIS) || defined (__USE_LPCOPEN)
\r
274 #if defined (__cplusplus)
\r
276 // Call C++ library initialisation
\r
278 __libc_init_array();
\r
281 #if defined (__REDLIB__)
\r
282 // Call the Redlib library, which in turn calls main()
\r
288 // main() shouldn't return, but if it does, we'll just enter an infinite loop
\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
306 __attribute__ ((section(".after_vectors")))
\r
307 void HardFault_Handler(void)
\r
313 __attribute__ ((section(".after_vectors")))
\r
314 void SVC_Handler(void)
\r
320 __attribute__ ((section(".after_vectors")))
\r
321 void PendSV_Handler(void)
\r
327 __attribute__ ((section(".after_vectors")))
\r
328 void SysTick_Handler(void)
\r
335 //*****************************************************************************
\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
340 //*****************************************************************************
\r
341 __attribute__ ((section(".after_vectors")))
\r
342 void IntDefaultHandler(void)
\r