LPCOpen Platform  v1.03
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
cr_startup_8xx.c
Go to the documentation of this file.
1 // *****************************************************************************
2 // +--+
3 // | ++----+
4 // +-++ |
5 // | |
6 // +-+--+ |
7 // | +--+--+
8 // +----+ Copyright (c) 2012 Code Red Technologies Ltd.
9 //
10 // LPC8xx Microcontroller Startup code for use with Red Suite
11 //
12 // Version : 121107
13 //
14 // Software License Agreement
15 //
16 // The software is owned by Code Red Technologies and/or its suppliers, and is
17 // protected under applicable copyright laws. All rights are reserved. Any
18 // use in violation of the foregoing restrictions may subject the user to criminal
19 // sanctions under applicable laws, as well as to civil liability for the breach
20 // of the terms and conditions of this license.
21 //
22 // THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
23 // OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
24 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
25 // USE OF THIS SOFTWARE FOR COMMERCIAL DEVELOPMENT AND/OR EDUCATION IS SUBJECT
26 // TO A CURRENT END USER LICENSE AGREEMENT (COMMERCIAL OR EDUCATIONAL) WITH
27 // CODE RED TECHNOLOGIES LTD.
28 //
29 // *****************************************************************************
30 #if defined(__cplusplus)
31 #ifdef __REDLIB__
32 #error Redlib does not support C++
33 #else
34 // *****************************************************************************
35 //
36 // The entry point for the C++ library startup
37 //
38 // *****************************************************************************
39 extern "C" {
40 extern void __libc_init_array(void);
41 
42 }
43 #endif
44 #endif
45 
46 #define WEAK __attribute__ ((weak))
47 #define ALIAS(f) __attribute__ ((weak, alias(# f)))
48 
49 // #if defined (__USE_CMSIS)
50 // #include "LPC8xx.h"
51 // #endif
52 
53 // *****************************************************************************
54 #if defined(__cplusplus)
55 extern "C" {
56 #endif
57 
58 // *****************************************************************************
59 //
60 // Forward declaration of the default handlers. These are aliased.
61 // When the application defines a handler (with the same name), this will
62 // automatically take precedence over these weak definitions
63 //
64 // *****************************************************************************
65 void ResetISR(void);
66 WEAK void NMI_Handler(void);
67 WEAK void HardFault_Handler(void);
68 WEAK void SVC_Handler(void);
69 WEAK void PendSV_Handler(void);
70 WEAK void SysTick_Handler(void);
71 WEAK void IntDefaultHandler(void);
72 
73 // *****************************************************************************
74 //
75 // Forward declaration of the specific IRQ handlers. These are aliased
76 // to the IntDefaultHandler, which is a 'forever' loop. When the application
77 // defines a handler (with the same name), this will automatically take
78 // precedence over these weak definitions
79 //
80 // *****************************************************************************
81 void SPI0_IRQHandler(void) ALIAS(IntDefaultHandler);
82 void SPI1_IRQHandler(void) ALIAS(IntDefaultHandler);
83 void UART0_IRQHandler(void) ALIAS(IntDefaultHandler);
84 void UART1_IRQHandler(void) ALIAS(IntDefaultHandler);
85 void UART2_IRQHandler(void) ALIAS(IntDefaultHandler);
86 void I2C_IRQHandler(void) ALIAS(IntDefaultHandler);
87 void SCT_IRQHandler(void) ALIAS(IntDefaultHandler);
88 void MRT_IRQHandler(void) ALIAS(IntDefaultHandler);
89 void CMP_IRQHandler(void) ALIAS(IntDefaultHandler);
90 void WDT_IRQHandler(void) ALIAS(IntDefaultHandler);
91 void BOD_IRQHandler(void) ALIAS(IntDefaultHandler);
92 void FLASH_IRQHandler(void) ALIAS(IntDefaultHandler);
93 void WKT_IRQHandler(void) ALIAS(IntDefaultHandler);
94 void PININT0_IRQHandler(void) ALIAS(IntDefaultHandler);
95 void PININT1_IRQHandler(void) ALIAS(IntDefaultHandler);
96 void PININT2_IRQHandler(void) ALIAS(IntDefaultHandler);
97 void PININT3_IRQHandler(void) ALIAS(IntDefaultHandler);
98 void PININT4_IRQHandler(void) ALIAS(IntDefaultHandler);
99 void PININT5_IRQHandler(void) ALIAS(IntDefaultHandler);
100 void PININT6_IRQHandler(void) ALIAS(IntDefaultHandler);
101 void PININT7_IRQHandler(void) ALIAS(IntDefaultHandler);
102 
103 // *****************************************************************************
104 //
105 // The entry point for the application.
106 // __main() is the entry point for Redlib based applications
107 // main() is the entry point for Newlib based applications
108 //
109 // *****************************************************************************
110 #if defined(__REDLIB__)
111 extern void __main(void);
112 
113 #endif
114 extern int main(void);
115 
116 // *****************************************************************************
117 //
118 // External declaration for the pointer to the stack top from the Linker Script
119 //
120 // *****************************************************************************
121 extern void _vStackTop(void);
122 
123 // *****************************************************************************
124 #if defined(__cplusplus)
125 } // extern "C"
126 #endif
127 // *****************************************************************************
128 //
129 // The vector table.
130 // This relies on the linker script to place at correct location in memory.
131 //
132 // *****************************************************************************
133 extern void(*const g_pfnVectors[]) (void);
134 __attribute__ ((section(".isr_vector")))
135 void(*const g_pfnVectors[]) (void) = {
136  // Core Level - CM0plus
137  &_vStackTop,// The initial stack pointer
138  ResetISR, // The reset handler
139  NMI_Handler, // The NMI handler
140  HardFault_Handler, // The hard fault handler
141  0, // Reserved
142  0, // Reserved
143  0, // Reserved
144  0, // Reserved
145  0, // Reserved
146  0, // Reserved
147  0, // Reserved
148  SVC_Handler, // SVCall handler
149  0, // Reserved
150  0, // Reserved
151  PendSV_Handler, // The PendSV handler
152  SysTick_Handler, // The SysTick handler
153 
154  // Chip Level - LPC8xx
155  SPI0_IRQHandler, // SPI0 controller
156  SPI1_IRQHandler, // SPI1 controller
157  0, // Reserved
158  UART0_IRQHandler, // UART0
159  UART1_IRQHandler, // UART1
160  UART2_IRQHandler, // UART2
161  0, // Reserved
162  0, // Reserved
163  I2C_IRQHandler, // I2C controller
164  SCT_IRQHandler, // Smart Counter Timer
165  MRT_IRQHandler, // Multi-Rate Timer
166  CMP_IRQHandler, // Comparator
167  WDT_IRQHandler, // Watchdog
168  BOD_IRQHandler, // Brown Out Detect
169  FLASH_IRQHandler, // FLASH
170  WKT_IRQHandler, // Wakeup timer
171  0, // Reserved
172  0, // Reserved
173  0, // Reserved
174  0, // Reserved
175  0, // Reserved
176  0, // Reserved
177  0, // Reserved
178  0, // Reserved
179  PININT0_IRQHandler, // PIO INT0
180  PININT1_IRQHandler, // PIO INT1
181  PININT2_IRQHandler, // PIO INT2
182  PININT3_IRQHandler, // PIO INT3
183  PININT4_IRQHandler, // PIO INT4
184  PININT5_IRQHandler, // PIO INT5
185  PININT6_IRQHandler, // PIO INT6
186  PININT7_IRQHandler, // PIO INT7
187 }; /* End of g_pfnVectors */
188 
189 // *****************************************************************************
190 // Functions to carry out the initialization of RW and BSS data sections. These
191 // are written as separate functions rather than being inlined within the
192 // ResetISR() function in order to cope with MCUs with multiple banks of
193 // memory.
194 // *****************************************************************************
195 __attribute__ ((section(".after_vectors")))
196 void data_init(unsigned int romstart, unsigned int start, unsigned int len) {
197  unsigned int *pulDest = (unsigned int *) start;
198  unsigned int *pulSrc = (unsigned int *) romstart;
199  unsigned int loop;
200  for (loop = 0; loop < len; loop = loop + 4) {
201  *pulDest++ = *pulSrc++;
202  }
203 }
204 
205 __attribute__ ((section(".after_vectors")))
206 void bss_init(unsigned int start, unsigned int len) {
207  unsigned int *pulDest = (unsigned int *) start;
208  unsigned int loop;
209  for (loop = 0; loop < len; loop = loop + 4) {
210  *pulDest++ = 0;
211  }
212 }
213 
214 // *****************************************************************************
215 // The following symbols are constructs generated by the linker, indicating
216 // the location of various points in the "Global Section Table". This table is
217 // created by the linker via the Code Red managed linker script mechanism. It
218 // contains the load address, execution address and length of each RW data
219 // section and the execution and length of each BSS (zero initialized) section.
220 // *****************************************************************************
221 extern unsigned int __data_section_table;
222 extern unsigned int __data_section_table_end;
223 extern unsigned int __bss_section_table;
224 extern unsigned int __bss_section_table_end;
225 
226 // *****************************************************************************
227 // Reset entry point for your code.
228 // Sets up a simple runtime environment and initializes the C/C++
229 // library.
230 // *****************************************************************************
231 __attribute__ ((section(".after_vectors")))
232 void
233 ResetISR(void) {
234 
235  //
236  // Copy the data sections from flash to SRAM.
237  //
238  unsigned int LoadAddr, ExeAddr, SectionLen;
239  unsigned int *SectionTableAddr;
240 
241  // Load base address of Global Section Table
242  SectionTableAddr = &__data_section_table;
243 
244  // Copy the data sections from flash to SRAM.
245  while (SectionTableAddr < &__data_section_table_end) {
246  LoadAddr = *SectionTableAddr++;
247  ExeAddr = *SectionTableAddr++;
248  SectionLen = *SectionTableAddr++;
249  data_init(LoadAddr, ExeAddr, SectionLen);
250  }
251  // At this point, SectionTableAddr = &__bss_section_table;
252  // Zero fill the bss segment
253  while (SectionTableAddr < &__bss_section_table_end) {
254  ExeAddr = *SectionTableAddr++;
255  SectionLen = *SectionTableAddr++;
256  bss_init(ExeAddr, SectionLen);
257  }
258  extern void SystemInit(void);
259 
260  SystemInit();
261 
262 #if defined(__cplusplus)
263  //
264  // Call C++ library initialisation
265  //
266  __libc_init_array();
267 #endif
268 
269 #if defined(__REDLIB__)
270  // Call the Redlib library, which in turn calls main()
271  __main();
272 #else
273  main();
274 #endif
275 
276  //
277  // main() shouldn't return, but if it does, we'll just enter an infinite loop
278  //
279  while (1) {}
280 }
281 
282 // *****************************************************************************
283 // Default exception handlers. Override the ones here by defining your own
284 // handler routines in your application code.
285 // *****************************************************************************
286 __attribute__ ((section(".after_vectors")))
287 void NMI_Handler(void)
288 {
289  while (1) {}
290 }
291 
292 __attribute__ ((section(".after_vectors")))
293 void HardFault_Handler(void)
294 {
295  while (1) {}
296 }
297 
298 __attribute__ ((section(".after_vectors")))
299 void SVCall_Handler(void)
300 {
301  while (1) {}
302 }
303 
304 __attribute__ ((section(".after_vectors")))
305 void PendSV_Handler(void)
306 {
307  while (1) {}
308 }
309 
310 __attribute__ ((section(".after_vectors")))
311 void SysTick_Handler(void)
312 {
313  while (1) {}
314 }
315 
316 // *****************************************************************************
317 //
318 // Processor ends up here if an unexpected interrupt occurs or a specific
319 // handler is not present in the application code.
320 //
321 // *****************************************************************************
322 __attribute__ ((section(".after_vectors")))
323 void IntDefaultHandler(void)
324 {
325  while (1) {}
326 }