1 /***************************************************************************//**
2  * @file
3  * @brief CMSIS Compatible EFM32GG11B startup file in C.
4  *        Should be used with GCC 'GNU Tools ARM Embedded'
5  *******************************************************************************
6  * # License
7  *
8  * The licensor of this software is Silicon Laboratories Inc. Your use of this
9  * software is governed by the terms of Silicon Labs Master Software License
10  * Agreement (MSLA) available at
11  * www.silabs.com/about-us/legal/master-software-license-agreement. This
12  * software is Third Party Software licensed by Silicon Labs from a third party
13  * and is governed by the sections of the MSLA applicable to Third Party
14  * Software and the additional terms set forth below.
15  *
16  ******************************************************************************/
17 /*
18  * Copyright (c) 2009-2018 Arm Limited. All rights reserved.
19  *
20  * SPDX-License-Identifier: Apache-2.0
21  *
22  * Licensed under the Apache License, Version 2.0 (the License); you may
23  * not use this file except in compliance with the License.
24  * You may obtain a copy of the License at
25  *
26  * www.apache.org/licenses/LICENSE-2.0
27  *
28  * Unless required by applicable law or agreed to in writing, software
29  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
30  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31  * See the License for the specific language governing permissions and
32  * limitations under the License.
33  */
34 
35 #include <stdbool.h>
36 #include "em_device.h"        /* The correct device header file. */
37 
38 /*----------------------------------------------------------------------------
39  * Linker generated Symbols
40  *----------------------------------------------------------------------------*/
41 extern uint32_t __etext;
42 extern uint32_t __data_start__;
43 extern uint32_t __data_end__;
44 extern uint32_t __copy_table_start__;
45 extern uint32_t __copy_table_end__;
46 extern uint32_t __zero_table_start__;
47 extern uint32_t __zero_table_end__;
48 extern uint32_t __bss_start__;
49 extern uint32_t __bss_end__;
50 extern uint32_t __StackTop;
51 
52 /*----------------------------------------------------------------------------
53  * External References
54  *----------------------------------------------------------------------------*/
55 #ifndef __START
56 extern void  _start(void) __attribute__((noreturn));    /* Pre Main (C library entry point) */
57 #else
58 extern int  __START(void) __attribute__((noreturn));    /* main entry point */
59 #endif
60 
61 #ifndef __NO_SYSTEM_INIT
62 extern void SystemInit(void);             /* CMSIS System Initialization      */
63 #endif
64 
65 /*----------------------------------------------------------------------------
66  * Internal References
67  *----------------------------------------------------------------------------*/
68 void Default_Handler(void);                          /* Default empty handler */
69 void Reset_Handler(void);                            /* Reset Handler */
70 
71 /*----------------------------------------------------------------------------
72  * User Initial Stack & Heap
73  *----------------------------------------------------------------------------*/
74 #ifndef __STACK_SIZE
75 #define __STACK_SIZE    0x00000400
76 #endif
77 static uint8_t stack[__STACK_SIZE] __attribute__ ((aligned(8), used, section(".stack")));
78 
79 #ifndef __HEAP_SIZE
80 #define __HEAP_SIZE    0x00000C00
81 #endif
82 #if __HEAP_SIZE > 0
83 static uint8_t heap[__HEAP_SIZE]   __attribute__ ((aligned(8), used, section(".heap")));
84 #endif
85 
86 /*----------------------------------------------------------------------------
87  * Exception / Interrupt Handler
88  *----------------------------------------------------------------------------*/
89 /* Cortex-M Processor Exceptions */
90 void NMI_Handler(void)               __attribute__ ((weak, alias("Default_Handler")));
91 void HardFault_Handler(void)         __attribute__ ((weak, alias("Default_Handler")));
92 void MemManage_Handler(void)         __attribute__ ((weak, alias("Default_Handler")));
93 void BusFault_Handler(void)          __attribute__ ((weak, alias("Default_Handler")));
94 void UsageFault_Handler(void)        __attribute__ ((weak, alias("Default_Handler")));
95 void DebugMon_Handler(void)          __attribute__ ((weak, alias("Default_Handler")));
96 void SVC_Handler(void)               __attribute__ ((weak, alias("Default_Handler")));
97 void PendSV_Handler(void)            __attribute__ ((weak, alias("Default_Handler")));
98 void SysTick_Handler(void)           __attribute__ ((weak, alias("Default_Handler")));
99 /* Provide a dummy value for the sl_app_properties symbol. */
100 void sl_app_properties(void);     /* Prototype to please MISRA checkers. */
101 void sl_app_properties(void)         __attribute__ ((weak, alias("Default_Handler")));
102 
103 /* Part Specific Interrupts */
104 
105 void EMU_IRQHandler(void)            __attribute__ ((weak, alias("Default_Handler")));
106 void WDOG0_IRQHandler(void)          __attribute__ ((weak, alias("Default_Handler")));
107 void LDMA_IRQHandler(void)           __attribute__ ((weak, alias("Default_Handler")));
108 void GPIO_EVEN_IRQHandler(void)      __attribute__ ((weak, alias("Default_Handler")));
109 void SMU_IRQHandler(void)            __attribute__ ((weak, alias("Default_Handler")));
110 void TIMER0_IRQHandler(void)         __attribute__ ((weak, alias("Default_Handler")));
111 void USART0_RX_IRQHandler(void)      __attribute__ ((weak, alias("Default_Handler")));
112 void USART0_TX_IRQHandler(void)      __attribute__ ((weak, alias("Default_Handler")));
113 void ACMP0_IRQHandler(void)          __attribute__ ((weak, alias("Default_Handler")));
114 void ADC0_IRQHandler(void)           __attribute__ ((weak, alias("Default_Handler")));
115 void IDAC0_IRQHandler(void)          __attribute__ ((weak, alias("Default_Handler")));
116 void I2C0_IRQHandler(void)           __attribute__ ((weak, alias("Default_Handler")));
117 void I2C1_IRQHandler(void)           __attribute__ ((weak, alias("Default_Handler")));
118 void GPIO_ODD_IRQHandler(void)       __attribute__ ((weak, alias("Default_Handler")));
119 void TIMER1_IRQHandler(void)         __attribute__ ((weak, alias("Default_Handler")));
120 void TIMER2_IRQHandler(void)         __attribute__ ((weak, alias("Default_Handler")));
121 void TIMER3_IRQHandler(void)         __attribute__ ((weak, alias("Default_Handler")));
122 void USART1_RX_IRQHandler(void)      __attribute__ ((weak, alias("Default_Handler")));
123 void USART1_TX_IRQHandler(void)      __attribute__ ((weak, alias("Default_Handler")));
124 void USART2_RX_IRQHandler(void)      __attribute__ ((weak, alias("Default_Handler")));
125 void USART2_TX_IRQHandler(void)      __attribute__ ((weak, alias("Default_Handler")));
126 void UART0_RX_IRQHandler(void)       __attribute__ ((weak, alias("Default_Handler")));
127 void UART0_TX_IRQHandler(void)       __attribute__ ((weak, alias("Default_Handler")));
128 void UART1_RX_IRQHandler(void)       __attribute__ ((weak, alias("Default_Handler")));
129 void UART1_TX_IRQHandler(void)       __attribute__ ((weak, alias("Default_Handler")));
130 void LEUART0_IRQHandler(void)        __attribute__ ((weak, alias("Default_Handler")));
131 void LEUART1_IRQHandler(void)        __attribute__ ((weak, alias("Default_Handler")));
132 void LETIMER0_IRQHandler(void)       __attribute__ ((weak, alias("Default_Handler")));
133 void PCNT0_IRQHandler(void)          __attribute__ ((weak, alias("Default_Handler")));
134 void PCNT1_IRQHandler(void)          __attribute__ ((weak, alias("Default_Handler")));
135 void PCNT2_IRQHandler(void)          __attribute__ ((weak, alias("Default_Handler")));
136 void RTCC_IRQHandler(void)           __attribute__ ((weak, alias("Default_Handler")));
137 void CMU_IRQHandler(void)            __attribute__ ((weak, alias("Default_Handler")));
138 void MSC_IRQHandler(void)            __attribute__ ((weak, alias("Default_Handler")));
139 void CRYPTO0_IRQHandler(void)        __attribute__ ((weak, alias("Default_Handler")));
140 void CRYOTIMER_IRQHandler(void)      __attribute__ ((weak, alias("Default_Handler")));
141 void FPUEH_IRQHandler(void)          __attribute__ ((weak, alias("Default_Handler")));
142 void USART3_RX_IRQHandler(void)      __attribute__ ((weak, alias("Default_Handler")));
143 void USART3_TX_IRQHandler(void)      __attribute__ ((weak, alias("Default_Handler")));
144 void USART4_RX_IRQHandler(void)      __attribute__ ((weak, alias("Default_Handler")));
145 void USART4_TX_IRQHandler(void)      __attribute__ ((weak, alias("Default_Handler")));
146 void WTIMER0_IRQHandler(void)        __attribute__ ((weak, alias("Default_Handler")));
147 void WTIMER1_IRQHandler(void)        __attribute__ ((weak, alias("Default_Handler")));
148 void WTIMER2_IRQHandler(void)        __attribute__ ((weak, alias("Default_Handler")));
149 void WTIMER3_IRQHandler(void)        __attribute__ ((weak, alias("Default_Handler")));
150 void I2C2_IRQHandler(void)           __attribute__ ((weak, alias("Default_Handler")));
151 void VDAC0_IRQHandler(void)          __attribute__ ((weak, alias("Default_Handler")));
152 void TIMER4_IRQHandler(void)         __attribute__ ((weak, alias("Default_Handler")));
153 void TIMER5_IRQHandler(void)         __attribute__ ((weak, alias("Default_Handler")));
154 void TIMER6_IRQHandler(void)         __attribute__ ((weak, alias("Default_Handler")));
155 void USART5_RX_IRQHandler(void)      __attribute__ ((weak, alias("Default_Handler")));
156 void USART5_TX_IRQHandler(void)      __attribute__ ((weak, alias("Default_Handler")));
157 void CSEN_IRQHandler(void)           __attribute__ ((weak, alias("Default_Handler")));
158 void LESENSE_IRQHandler(void)        __attribute__ ((weak, alias("Default_Handler")));
159 void EBI_IRQHandler(void)            __attribute__ ((weak, alias("Default_Handler")));
160 void ACMP2_IRQHandler(void)          __attribute__ ((weak, alias("Default_Handler")));
161 void ADC1_IRQHandler(void)           __attribute__ ((weak, alias("Default_Handler")));
162 void LCD_IRQHandler(void)            __attribute__ ((weak, alias("Default_Handler")));
163 void SDIO_IRQHandler(void)           __attribute__ ((weak, alias("Default_Handler")));
164 void ETH_IRQHandler(void)            __attribute__ ((weak, alias("Default_Handler")));
165 void CAN0_IRQHandler(void)           __attribute__ ((weak, alias("Default_Handler")));
166 void CAN1_IRQHandler(void)           __attribute__ ((weak, alias("Default_Handler")));
167 void USB_IRQHandler(void)            __attribute__ ((weak, alias("Default_Handler")));
168 void RTC_IRQHandler(void)            __attribute__ ((weak, alias("Default_Handler")));
169 void WDOG1_IRQHandler(void)          __attribute__ ((weak, alias("Default_Handler")));
170 void LETIMER1_IRQHandler(void)       __attribute__ ((weak, alias("Default_Handler")));
171 void TRNG0_IRQHandler(void)          __attribute__ ((weak, alias("Default_Handler")));
172 void QSPI0_IRQHandler(void)          __attribute__ ((weak, alias("Default_Handler")));
173 
174 /*----------------------------------------------------------------------------
175  * Exception / Interrupt Vector table
176  *----------------------------------------------------------------------------*/
177 extern const tVectorEntry __Vectors[];
178 const tVectorEntry        __Vectors[] __attribute__ ((section(".vectors"))) = {
179   /* Cortex-M Exception Handlers */
180   { .topOfStack = &__StackTop },              /* Initial Stack Pointer */
181   { Reset_Handler             },              /* Reset Handler */
182   { NMI_Handler               },              /* NMI Handler */
183   { HardFault_Handler         },              /* Hard Fault Handler */
184   { MemManage_Handler         },              /* MPU Fault Handler */
185   { BusFault_Handler          },              /* Bus Fault Handler */
186   { UsageFault_Handler        },              /* Usage Fault Handler */
187   { Default_Handler           },              /* Reserved */
188   { Default_Handler           },              /* Reserved */
189   { Default_Handler           },              /* Reserved */
190   { Default_Handler           },              /* Reserved */
191   { SVC_Handler               },              /* SVCall Handler */
192   { DebugMon_Handler          },              /* Debug Monitor Handler */
193   { sl_app_properties         },              /* Application properties*/
194   { PendSV_Handler            },              /* PendSV Handler */
195   { SysTick_Handler           },              /* SysTick Handler */
196 
197   /* External interrupts */
198 
199   { EMU_IRQHandler            },              /* 0 */
200   { WDOG0_IRQHandler          },              /* 1 */
201   { LDMA_IRQHandler           },              /* 2 */
202   { GPIO_EVEN_IRQHandler      },              /* 3 */
203   { SMU_IRQHandler            },              /* 4 */
204   { TIMER0_IRQHandler         },              /* 5 */
205   { USART0_RX_IRQHandler      },              /* 6 */
206   { USART0_TX_IRQHandler      },              /* 7 */
207   { ACMP0_IRQHandler          },              /* 8 */
208   { ADC0_IRQHandler           },              /* 9 */
209   { IDAC0_IRQHandler          },              /* 10 */
210   { I2C0_IRQHandler           },              /* 11 */
211   { I2C1_IRQHandler           },              /* 12 */
212   { GPIO_ODD_IRQHandler       },              /* 13 */
213   { TIMER1_IRQHandler         },              /* 14 */
214   { TIMER2_IRQHandler         },              /* 15 */
215   { TIMER3_IRQHandler         },              /* 16 */
216   { USART1_RX_IRQHandler      },              /* 17 */
217   { USART1_TX_IRQHandler      },              /* 18 */
218   { USART2_RX_IRQHandler      },              /* 19 */
219   { USART2_TX_IRQHandler      },              /* 20 */
220   { UART0_RX_IRQHandler       },              /* 21 */
221   { UART0_TX_IRQHandler       },              /* 22 */
222   { UART1_RX_IRQHandler       },              /* 23 */
223   { UART1_TX_IRQHandler       },              /* 24 */
224   { LEUART0_IRQHandler        },              /* 25 */
225   { LEUART1_IRQHandler        },              /* 26 */
226   { LETIMER0_IRQHandler       },              /* 27 */
227   { PCNT0_IRQHandler          },              /* 28 */
228   { PCNT1_IRQHandler          },              /* 29 */
229   { PCNT2_IRQHandler          },              /* 30 */
230   { RTCC_IRQHandler           },              /* 31 */
231   { CMU_IRQHandler            },              /* 32 */
232   { MSC_IRQHandler            },              /* 33 */
233   { CRYPTO0_IRQHandler        },              /* 34 */
234   { CRYOTIMER_IRQHandler      },              /* 35 */
235   { FPUEH_IRQHandler          },              /* 36 */
236   { USART3_RX_IRQHandler      },              /* 37 */
237   { USART3_TX_IRQHandler      },              /* 38 */
238   { USART4_RX_IRQHandler      },              /* 39 */
239   { USART4_TX_IRQHandler      },              /* 40 */
240   { WTIMER0_IRQHandler        },              /* 41 */
241   { WTIMER1_IRQHandler        },              /* 42 */
242   { WTIMER2_IRQHandler        },              /* 43 */
243   { WTIMER3_IRQHandler        },              /* 44 */
244   { I2C2_IRQHandler           },              /* 45 */
245   { VDAC0_IRQHandler          },              /* 46 */
246   { TIMER4_IRQHandler         },              /* 47 */
247   { TIMER5_IRQHandler         },              /* 48 */
248   { TIMER6_IRQHandler         },              /* 49 */
249   { USART5_RX_IRQHandler      },              /* 50 */
250   { USART5_TX_IRQHandler      },              /* 51 */
251   { CSEN_IRQHandler           },              /* 52 */
252   { LESENSE_IRQHandler        },              /* 53 */
253   { EBI_IRQHandler            },              /* 54 */
254   { ACMP2_IRQHandler          },              /* 55 */
255   { ADC1_IRQHandler           },              /* 56 */
256   { LCD_IRQHandler            },              /* 57 */
257   { SDIO_IRQHandler           },              /* 58 */
258   { ETH_IRQHandler            },              /* 59 */
259   { CAN0_IRQHandler           },              /* 60 */
260   { CAN1_IRQHandler           },              /* 61 */
261   { USB_IRQHandler            },              /* 62 */
262   { RTC_IRQHandler            },              /* 63 */
263   { WDOG1_IRQHandler          },              /* 64 */
264   { LETIMER1_IRQHandler       },              /* 65 */
265   { TRNG0_IRQHandler          },              /* 66 */
266   { QSPI0_IRQHandler          },              /* 67 */
267 };
268 
269 /*----------------------------------------------------------------------------
270  * Reset Handler called on controller reset
271  *----------------------------------------------------------------------------*/
Reset_Handler(void)272 void Reset_Handler(void)
273 {
274   uint32_t *pSrc, *pDest;
275   uint32_t start, end;
276   uint32_t tableStart __attribute__((unused));
277   uint32_t tableEnd   __attribute__((unused));
278 
279 #ifndef __NO_SYSTEM_INIT
280   SystemInit();
281 #endif
282 
283 /*  Firstly it copies data from read only memory to RAM. There are two schemes
284  *  to copy. One can copy more than one sections. Another can only copy
285  *  one section.  The former scheme needs more instructions and read-only
286  *  data to implement than the latter.
287  *  Macro __STARTUP_COPY_MULTIPLE is used to choose between two schemes.  */
288 
289 #ifdef __STARTUP_COPY_MULTIPLE
290 /*  Multiple sections scheme.
291  *
292  *  Between symbol address __copy_table_start__ and __copy_table_end__,
293  *  there are array of triplets, each of which specify:
294  *    offset 0: LMA of start of a section to copy from
295  *    offset 4: VMA of start of a section to copy to
296  *    offset 8: size of the section to copy. Must be multiply of 4
297  *
298  *  All addresses must be aligned to 4 bytes boundary.
299  */
300   tableStart = (uint32_t) &__copy_table_start__;
301   tableEnd   = (uint32_t) &__copy_table_end__;
302 
303   for (; tableStart < tableEnd; tableStart += 12U) {
304     pSrc  = (uint32_t *) (*(uint32_t *) tableStart);
305     start = *(uint32_t *) (tableStart + 4U);
306     end   = *(uint32_t *) (tableStart + 8U) + start;
307     pDest = (uint32_t *) start;
308     for (; start < end; start += 4U) {
309       *pDest++ = *pSrc++;
310     }
311   }
312 #else
313 /*  Single section scheme.
314  *
315  *  The ranges of copy from/to are specified by following symbols
316  *    __etext: LMA of start of the section to copy from. Usually end of text
317  *    __data_start__: VMA of start of the section to copy to
318  *    __data_end__: VMA of end of the section to copy to
319  *
320  *  All addresses must be aligned to 4 bytes boundary.
321  */
322   pSrc  = &__etext;
323   pDest = &__data_start__;
324   start = (uint32_t) &__data_start__;
325   end   = (uint32_t) &__data_end__;
326 
327   for (; start < end; start += 4U) {
328     *pDest++ = *pSrc++;
329   }
330 #endif /*__STARTUP_COPY_MULTIPLE */
331 
332 /*  This part of work usually is done in C library startup code. Otherwise,
333  *  define this macro to enable it in this startup.
334  *
335  *  There are two schemes too. One can clear multiple BSS sections. Another
336  *  can only clear one section. The former is more size expensive than the
337  *  latter.
338  *
339  *  Define macro __STARTUP_CLEAR_BSS_MULTIPLE to choose the former.
340  *  Otherwise efine macro __STARTUP_CLEAR_BSS to choose the later.
341  */
342 #ifdef __STARTUP_CLEAR_BSS_MULTIPLE
343 /*  Multiple sections scheme.
344  *
345  *  Between symbol address __zero_table_start__ and __zero_table_end__,
346  *  there are array of tuples specifying:
347  *    offset 0: Start of a BSS section
348  *    offset 4: Size of this BSS section. Must be multiply of 4
349  */
350   tableStart = (uint32_t) &__zero_table_start__;
351   tableEnd   = (uint32_t) &__zero_table_end__;
352 
353   for (; tableStart < tableEnd; tableStart += 8U) {
354     start = *(uint32_t *) tableStart;
355     end   = *(uint32_t *) (tableStart + 4U) + start;
356     pDest = (uint32_t *) start;
357     for (; start < end; start += 4U) {
358       *pDest++ = 0UL;
359     }
360   }
361 #elif defined (__STARTUP_CLEAR_BSS)
362 /*  Single BSS section scheme.
363  *
364  *  The BSS section is specified by following symbols
365  *    __bss_start__: start of the BSS section.
366  *    __bss_end__: end of the BSS section.
367  *
368  *  Both addresses must be aligned to 4 bytes boundary.
369  */
370   pDest = &__bss_start__;
371   start = (uint32_t) &__bss_start__;
372   end   = (uint32_t) &__bss_end__;
373 
374   for (; start < end; start += 4U) {
375     *pDest++ = 0UL;
376   }
377 #endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */
378 
379 #ifndef __START
380 #define __START    _start
381 #endif
382   __START();
383 }
384 
385 /*----------------------------------------------------------------------------
386  * Default Handler for Exceptions / Interrupts
387  *----------------------------------------------------------------------------*/
Default_Handler(void)388 void Default_Handler(void)
389 {
390   while (true) {
391   }
392 }
393