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