]> git.sur5r.net Git - freertos/blob - Demo/CORTEX_MPU_LPC1768_GCC_RedSuite/src/cr_startup_lpc17.c
Add same additional tests and demos as already in the Rowley version.
[freertos] / Demo / CORTEX_MPU_LPC1768_GCC_RedSuite / src / cr_startup_lpc17.c
1 //*****************************************************************************\r
2 //   +--+       \r
3 //   | ++----+   \r
4 //   +-++    |  \r
5 //     |     |  \r
6 //   +-+--+  |   \r
7 //   | +--+--+  \r
8 //   +----+    Copyright (c) 2009 Code Red Technologies Ltd. \r
9 //\r
10 // Microcontroller Startup code for use with Red Suite\r
11 //\r
12 // Software License Agreement\r
13 // \r
14 // The software is owned by Code Red Technologies and/or its suppliers, and is \r
15 // protected under applicable copyright laws.  All rights are reserved.  Any \r
16 // use in violation of the foregoing restrictions may subject the user to criminal \r
17 // sanctions under applicable laws, as well as to civil liability for the breach \r
18 // of the terms and conditions of this license.\r
19 // \r
20 // THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED\r
21 // OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF\r
22 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.\r
23 // USE OF THIS SOFTWARE FOR COMMERCIAL DEVELOPMENT AND/OR EDUCATION IS SUBJECT\r
24 // TO A CURRENT END USER LICENSE AGREEMENT (COMMERCIAL OR EDUCATIONAL) WITH\r
25 // CODE RED TECHNOLOGIES LTD. \r
26 //\r
27 //*****************************************************************************\r
28 #define WEAK __attribute__ ((weak))\r
29 #define ALIAS(f) __attribute__ ((weak, alias (#f)))\r
30 \r
31 //*****************************************************************************\r
32 //\r
33 // Forward declaration of the default handlers.\r
34 //\r
35 //*****************************************************************************\r
36 void Reset_Handler(void);\r
37 void ResetISR(void) ALIAS(Reset_Handler);\r
38 static void NMI_Handler(void);\r
39 static void HardFault_Handler(void);\r
40 static void MemManage_Handler(void) __attribute__((naked));\r
41 static void BusFault_Handler(void) __attribute__((naked));\r
42 static void UsageFault_Handler(void) __attribute__((naked));\r
43 static void DebugMon_Handler(void);\r
44 \r
45 //*****************************************************************************\r
46 //\r
47 // Forward declaration of the specific IRQ handlers. These are aliased\r
48 // to the IntDefaultHandler, which is a 'forever' loop. When the application\r
49 // defines a handler (with the same name), this will automatically take \r
50 // precedence over these weak definitions\r
51 //\r
52 //*****************************************************************************\r
53 void WDT_IRQHandler(void) ALIAS(IntDefaultHandler);\r
54 void TIMER0_IRQHandler(void) ALIAS(IntDefaultHandler);\r
55 void TIMER1_IRQHandler(void) ALIAS(IntDefaultHandler);\r
56 void TIMER2_IRQHandler(void) ALIAS(IntDefaultHandler);\r
57 void TIMER3_IRQHandler(void) ALIAS(IntDefaultHandler);\r
58 void UART0_IRQHandler(void) ALIAS(IntDefaultHandler);\r
59 void UART1_IRQHandler(void) ALIAS(IntDefaultHandler);\r
60 void UART2_IRQHandler(void) ALIAS(IntDefaultHandler);\r
61 void UART3_IRQHandler(void) ALIAS(IntDefaultHandler);\r
62 void PWM1_IRQHandler(void) ALIAS(IntDefaultHandler);\r
63 void I2C0_IRQHandler(void) ALIAS(IntDefaultHandler);\r
64 void I2C1_IRQHandler(void) ALIAS(IntDefaultHandler);\r
65 void I2C2_IRQHandler(void) ALIAS(IntDefaultHandler);\r
66 void SPI_IRQHandler(void) ALIAS(IntDefaultHandler);\r
67 void SSP0_IRQHandler(void) ALIAS(IntDefaultHandler);\r
68 void SSP1_IRQHandler(void) ALIAS(IntDefaultHandler);\r
69 void PLL0_IRQHandler(void) ALIAS(IntDefaultHandler);\r
70 void RTC_IRQHandler(void) ALIAS(IntDefaultHandler);\r
71 void EINT0_IRQHandler(void) ALIAS(IntDefaultHandler);\r
72 void EINT1_IRQHandler(void) ALIAS(IntDefaultHandler);\r
73 void EINT2_IRQHandler(void) ALIAS(IntDefaultHandler);\r
74 void EINT3_IRQHandler(void) ALIAS(IntDefaultHandler);\r
75 void ADC_IRQHandler(void) ALIAS(IntDefaultHandler);\r
76 void BOD_IRQHandler(void) ALIAS(IntDefaultHandler);\r
77 void USB_IRQHandler(void) ALIAS(IntDefaultHandler);\r
78 void CAN_IRQHandler(void) ALIAS(IntDefaultHandler);\r
79 void DMA_IRQHandler(void) ALIAS(IntDefaultHandler);\r
80 void I2S_IRQHandler(void) ALIAS(IntDefaultHandler);\r
81 void ENET_IRQHandler(void) ALIAS(IntDefaultHandler);\r
82 void RIT_IRQHandler(void) ALIAS(IntDefaultHandler);\r
83 void MCPWM_IRQHandler(void) ALIAS(IntDefaultHandler);\r
84 void QEI_IRQHandler(void) ALIAS(IntDefaultHandler);\r
85 void PLL1_IRQHandler(void) ALIAS(IntDefaultHandler);\r
86 \r
87 extern void xPortSysTickHandler(void);\r
88 extern void xPortPendSVHandler(void);\r
89 extern void vPortSVCHandler( void );\r
90 \r
91 \r
92 //*****************************************************************************\r
93 //\r
94 // The entry point for the C++ library startup\r
95 //\r
96 //*****************************************************************************\r
97 extern WEAK void __libc_init_array(void);\r
98 \r
99 //*****************************************************************************\r
100 //\r
101 // The entry point for the application.\r
102 // __main() is the entry point for redlib based applications\r
103 // main() is the entry point for newlib based applications\r
104 //\r
105 //*****************************************************************************\r
106 extern WEAK void __main(void);\r
107 extern WEAK void main(void);\r
108 //*****************************************************************************\r
109 //\r
110 // External declaration for the pointer to the stack top from the Linker Script\r
111 //\r
112 //*****************************************************************************\r
113 extern void _vStackTop;\r
114 \r
115 //*****************************************************************************\r
116 //\r
117 // The vector table.\r
118 // This relies on the linker script to place at correct location in memory.\r
119 //\r
120 //*****************************************************************************\r
121 __attribute__ ((section(".isr_vector")))\r
122 void (* const g_pfnVectors[])(void) =\r
123 {\r
124         // Core Level - CM3\r
125         (void *)&_vStackTop,                                    // The initial stack pointer\r
126         Reset_Handler,                                                  // The reset handler\r
127         NMI_Handler,                                                    // The NMI handler\r
128         HardFault_Handler,                                              // The hard fault handler\r
129         MemManage_Handler,                                              // The MPU fault handler\r
130         BusFault_Handler,                                               // The bus fault handler\r
131         UsageFault_Handler,                                             // The usage fault handler\r
132         0,                                                                              // Reserved\r
133         0,                                                                              // Reserved\r
134         0,                                                                              // Reserved\r
135         0,                                                                              // Reserved\r
136         vPortSVCHandler,                        // SVCall handler\r
137         DebugMon_Handler,                                               // Debug monitor handler\r
138         0,                                                                              // Reserved\r
139         xPortPendSVHandler,                     // The PendSV handler\r
140         xPortSysTickHandler,                    // The SysTick handler\r
141 \r
142         // Chip Level - LPC17\r
143         WDT_IRQHandler,                                                 // 16, 0x40 - WDT\r
144         TIMER0_IRQHandler,                                              // 17, 0x44 - TIMER0\r
145         TIMER1_IRQHandler,                                              // 18, 0x48 - TIMER1\r
146         TIMER2_IRQHandler,                                              // 19, 0x4c - TIMER2\r
147         TIMER3_IRQHandler,                                              // 20, 0x50 - TIMER3\r
148         UART0_IRQHandler,                                               // 21, 0x54 - UART0\r
149         UART1_IRQHandler,                                               // 22, 0x58 - UART1\r
150         UART2_IRQHandler,                                               // 23, 0x5c - UART2\r
151         UART3_IRQHandler,                                               // 24, 0x60 - UART3\r
152         PWM1_IRQHandler,                                                // 25, 0x64 - PWM1\r
153         I2C0_IRQHandler,                                                // 26, 0x68 - I2C0\r
154         I2C1_IRQHandler,                                                // 27, 0x6c - I2C1\r
155         I2C2_IRQHandler,                                                // 28, 0x70 - I2C2\r
156         SPI_IRQHandler,                                                 // 29, 0x74 - SPI\r
157         SSP0_IRQHandler,                                                // 30, 0x78 - SSP0\r
158         SSP1_IRQHandler,                                                // 31, 0x7c - SSP1\r
159         PLL0_IRQHandler,                                                // 32, 0x80 - PLL0 (Main PLL)\r
160         RTC_IRQHandler,                                                 // 33, 0x84 - RTC\r
161         EINT0_IRQHandler,                                               // 34, 0x88 - EINT0\r
162         EINT1_IRQHandler,                                               // 35, 0x8c - EINT1\r
163         EINT2_IRQHandler,                                               // 36, 0x90 - EINT2\r
164         EINT3_IRQHandler,                                               // 37, 0x94 - EINT3\r
165         ADC_IRQHandler,                                                 // 38, 0x98 - ADC\r
166         BOD_IRQHandler,                                                 // 39, 0x9c - BOD\r
167         USB_IRQHandler,                                                 // 40, 0xA0 - USB\r
168         CAN_IRQHandler,                                                 // 41, 0xa4 - CAN\r
169         DMA_IRQHandler,                                                 // 42, 0xa8 - GP DMA\r
170         I2S_IRQHandler,                                                 // 43, 0xac - I2S\r
171         ENET_IRQHandler,                                // Ethernet.\r
172         RIT_IRQHandler,                                                 // 45, 0xb4 - RITINT\r
173         MCPWM_IRQHandler,                                               // 46, 0xb8 - Motor Control PWM\r
174         QEI_IRQHandler,                                                 // 47, 0xbc - Quadrature Encoder\r
175         PLL1_IRQHandler,                                                // 48, 0xc0 - PLL1 (USB PLL)\r
176 };\r
177 \r
178 //*****************************************************************************\r
179 //\r
180 // The following are constructs created by the linker, indicating where the\r
181 // the "data" and "bss" segments reside in memory.  The initializers for the\r
182 // for the "data" segment resides immediately following the "text" segment.\r
183 //\r
184 //*****************************************************************************\r
185 extern unsigned long _etext;\r
186 extern unsigned long _data;\r
187 extern unsigned long _edata;\r
188 extern unsigned long _bss;\r
189 extern unsigned long _ebss;\r
190 extern unsigned long __privileged_data_start__;\r
191 extern unsigned long __privileged_data_end__;\r
192 \r
193 //*****************************************************************************\r
194 // Reset entry point for your code.\r
195 // Sets up a simple runtime environment and initializes the C/C++\r
196 // library.\r
197 //\r
198 //*****************************************************************************\r
199 void Reset_Handler(void)\r
200 {\r
201     unsigned long *pulSrc, *pulDest;\r
202 \r
203     //\r
204     // Copy the data segment initializers from flash to SRAM.\r
205     //\r
206     pulSrc = &_etext;\r
207     for(pulDest = &_data; pulDest < &_edata; )\r
208     {\r
209         *pulDest++ = *pulSrc++;\r
210     }\r
211 \r
212     //\r
213     // Zero fill the bss segment.  This is done with inline assembly since this\r
214     // will clear the value of pulDest if it is not kept in a register.\r
215     //\r
216     __asm("    ldr     r0, =_bss\n"\r
217           "    ldr     r1, =_ebss\n"\r
218           "    mov     r2, #0\n"\r
219           "    .thumb_func\n"\r
220           "zero_loop_bss:\n"\r
221           "        cmp     r0, r1\n"\r
222           "        it      lt\n"\r
223           "        strlt   r2, [r0], #4\n"\r
224           "        blt     zero_loop_bss");\r
225     \r
226     \r
227     //\r
228     // Call C++ library initilisation, if present\r
229     //\r
230         if (__libc_init_array)\r
231                 __libc_init_array() ;\r
232 \r
233         //\r
234         // Call the application's entry point.\r
235         // __main() is the entry point for redlib based applications (which calls main())\r
236         // main() is the entry point for newlib based applications\r
237         //\r
238         if (__main)\r
239                 __main() ;\r
240         else\r
241                 main() ;\r
242 \r
243         //\r
244         // main() shouldn't return, but if it does, we'll just enter an infinite loop \r
245         //\r
246         while (1) {\r
247                 ;\r
248         }\r
249 }\r
250 \r
251 //*****************************************************************************\r
252 //\r
253 // This is the code that gets called when the processor receives a NMI.  This\r
254 // simply enters an infinite loop, preserving the system state for examination\r
255 // by a debugger.\r
256 //\r
257 //*****************************************************************************\r
258 static void NMI_Handler(void)\r
259 {\r
260     while(1)\r
261     {\r
262     }\r
263 }\r
264 \r
265 static void HardFault_Handler(void)\r
266 {\r
267         for( ;; );\r
268 }\r
269 \r
270 void pop_registers_from_fault_stack(unsigned int * hardfault_args)\r
271 {\r
272 unsigned int stacked_r0;\r
273 unsigned int stacked_r1;\r
274 unsigned int stacked_r2;\r
275 unsigned int stacked_r3;\r
276 unsigned int stacked_r12;\r
277 unsigned int stacked_lr;\r
278 unsigned int stacked_pc;\r
279 unsigned int stacked_psr;\r
280 \r
281         stacked_r0 = ((unsigned long) hardfault_args[0]);\r
282         stacked_r1 = ((unsigned long) hardfault_args[1]);\r
283         stacked_r2 = ((unsigned long) hardfault_args[2]);\r
284         stacked_r3 = ((unsigned long) hardfault_args[3]);\r
285 \r
286         stacked_r12 = ((unsigned long) hardfault_args[4]);\r
287         stacked_lr = ((unsigned long) hardfault_args[5]);\r
288         stacked_pc = ((unsigned long) hardfault_args[6]);\r
289         stacked_psr = ((unsigned long) hardfault_args[7]);\r
290 \r
291         /* Inspect stacked_pc to locate the offending instruction. */\r
292         for( ;; );\r
293 }\r
294 \r
295 static void MemManage_Handler(void)\r
296 {\r
297         __asm volatile\r
298         (\r
299                 " tst lr, #4                                                                            \n"\r
300                 " ite eq                                                                                        \n"\r
301                 " mrseq r0, msp                                                                         \n"\r
302                 " mrsne r0, psp                                                                         \n"\r
303                 " ldr r1, [r0, #24]                                                                     \n"\r
304                 " ldr r2, handler2_address_const                                                \n"\r
305                 " bx r2                                                                                         \n"\r
306                 " handler2_address_const: .word pop_registers_from_fault_stack  \n"\r
307         );\r
308 }\r
309 \r
310 static void BusFault_Handler(void)\r
311 {\r
312         __asm volatile\r
313         (\r
314                 " tst lr, #4                                                                            \n"\r
315                 " ite eq                                                                                        \n"\r
316                 " mrseq r0, msp                                                                         \n"\r
317                 " mrsne r0, psp                                                                         \n"\r
318                 " ldr r1, [r0, #24]                                                                     \n"\r
319                 " ldr r2, handler3_address_const                                                \n"\r
320                 " bx r2                                                                                         \n"\r
321                 " handler3_address_const: .word pop_registers_from_fault_stack  \n"\r
322         );\r
323 }\r
324 \r
325 static void UsageFault_Handler(void)\r
326 {\r
327         __asm volatile\r
328         (\r
329                 " tst lr, #4                                                                            \n"\r
330                 " ite eq                                                                                        \n"\r
331                 " mrseq r0, msp                                                                         \n"\r
332                 " mrsne r0, psp                                                                         \n"\r
333                 " ldr r1, [r0, #24]                                                                     \n"\r
334                 " ldr r2, handler4_address_const                                                \n"\r
335                 " bx r2                                                                                         \n"\r
336                 " handler4_address_const: .word pop_registers_from_fault_stack  \n"\r
337         );\r
338 }\r
339 \r
340 static void DebugMon_Handler(void)\r
341 {\r
342     while(1)\r
343     {\r
344     }\r
345 }\r
346 \r
347 //*****************************************************************************\r
348 //\r
349 // Processor ends up here if an unexpected interrupt occurs or a handler\r
350 // is not present in the application code.\r
351 //\r
352 //*****************************************************************************\r
353 static void IntDefaultHandler(void)\r
354 {\r
355     //\r
356     // Go into an infinite loop.\r
357     //\r
358     while(1)\r
359     {\r
360     }\r
361 }\r