00001 /* 00002 * @file startup_efm32zg.c 00003 * @brief CMSIS Compatible EFM32ZG startup file in C. 00004 * Should be used with GCC 'GNU Tools ARM Embedded' 00005 * @version 4.0.0 00006 * Date: 12 June 2014 00007 * 00008 */ 00009 /* Copyright (c) 2011 - 2014 ARM LIMITED 00010 00011 All rights reserved. 00012 Redistribution and use in source and binary forms, with or without 00013 modification, are permitted provided that the following conditions are met: 00014 - Redistributions of source code must retain the above copyright 00015 notice, this list of conditions and the following disclaimer. 00016 - Redistributions in binary form must reproduce the above copyright 00017 notice, this list of conditions and the following disclaimer in the 00018 documentation and/or other materials provided with the distribution. 00019 - Neither the name of ARM nor the names of its contributors may be used 00020 to endorse or promote products derived from this software without 00021 specific prior written permission. 00022 * 00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00024 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00025 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00026 ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE 00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00029 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00030 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00031 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00032 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00033 POSSIBILITY OF SUCH DAMAGE. 00034 ---------------------------------------------------------------------------*/ 00035 00036 00037 #include <stdint.h> 00038 00039 /*---------------------------------------------------------------------------- 00040 Linker generated Symbols 00041 *----------------------------------------------------------------------------*/ 00042 extern uint32_t __etext; 00043 extern uint32_t __data_start__; 00044 extern uint32_t __data_end__; 00045 extern uint32_t __copy_table_start__; 00046 extern uint32_t __copy_table_end__; 00047 extern uint32_t __zero_table_start__; 00048 extern uint32_t __zero_table_end__; 00049 extern uint32_t __bss_start__; 00050 extern uint32_t __bss_end__; 00051 extern uint32_t __StackTop; 00052 00053 /*---------------------------------------------------------------------------- 00054 Exception / Interrupt Handler Function Prototype 00055 *----------------------------------------------------------------------------*/ 00056 typedef void( *pFunc )( void ); 00057 00058 00059 /*---------------------------------------------------------------------------- 00060 External References 00061 *----------------------------------------------------------------------------*/ 00062 #ifndef __START 00063 extern void _start(void) __attribute__((noreturn)); /* Pre Main (C library entry point) */ 00064 #else 00065 extern int __START(void) __attribute__((noreturn)); /* main entry point */ 00066 #endif 00067 00068 #ifndef __NO_SYSTEM_INIT 00069 extern void SystemInit (void); /* CMSIS System Initialization */ 00070 #endif 00071 00072 00073 /*---------------------------------------------------------------------------- 00074 Internal References 00075 *----------------------------------------------------------------------------*/ 00076 void Default_Handler(void); /* Default empty handler */ 00077 void Reset_Handler(void); /* Reset Handler */ 00078 00079 00080 /*---------------------------------------------------------------------------- 00081 User Initial Stack & Heap 00082 *----------------------------------------------------------------------------*/ 00083 #ifndef __STACK_SIZE 00084 #define __STACK_SIZE 0x00000400 00085 #endif 00086 static uint8_t stack[__STACK_SIZE] __attribute__ ((aligned(8), used, section(".stack"))); 00087 00088 #ifndef __HEAP_SIZE 00089 #define __HEAP_SIZE 0x00000000 00090 #endif 00091 #if __HEAP_SIZE > 0 00092 static uint8_t heap[__HEAP_SIZE] __attribute__ ((aligned(8), used, section(".heap"))); 00093 #endif 00094 00095 00096 /*---------------------------------------------------------------------------- 00097 Exception / Interrupt Handler 00098 *----------------------------------------------------------------------------*/ 00099 /* Cortex-M Processor Exceptions */ 00100 void NMI_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); 00101 void HardFault_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); 00102 void SVC_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); 00103 void PendSV_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); 00104 void SysTick_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); 00105 00106 /* Part Specific Interrupts */ 00107 void DMA_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); 00108 void GPIO_EVEN_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); 00109 void TIMER0_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); 00110 void ACMP0_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); 00111 void ADC0_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); 00112 void I2C0_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); 00113 void GPIO_ODD_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); 00114 void TIMER1_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); 00115 void USART1_RX_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); 00116 void USART1_TX_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); 00117 void LEUART0_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); 00118 void PCNT0_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); 00119 void RTC_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); 00120 void CMU_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); 00121 void VCMP_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); 00122 void MSC_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); 00123 void AES_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler"))); 00124 00125 00126 00127 /*---------------------------------------------------------------------------- 00128 Exception / Interrupt Vector table 00129 *----------------------------------------------------------------------------*/ 00130 const pFunc __Vectors[] __attribute__ ((section(".vectors"))) = { 00131 /* Cortex-M Exception Handlers */ 00132 (pFunc)&__StackTop, /* Initial Stack Pointer */ 00133 Reset_Handler, /* Reset Handler */ 00134 NMI_Handler, /* NMI Handler */ 00135 HardFault_Handler, /* Hard Fault Handler */ 00136 Default_Handler, /* Reserved */ 00137 Default_Handler, /* Reserved */ 00138 Default_Handler, /* Reserved */ 00139 Default_Handler, /* Reserved */ 00140 Default_Handler, /* Reserved */ 00141 Default_Handler, /* Reserved */ 00142 Default_Handler, /* Reserved */ 00143 SVC_Handler, /* SVCall Handler */ 00144 Default_Handler, /* Reserved */ 00145 Default_Handler, /* Reserved */ 00146 PendSV_Handler, /* PendSV Handler */ 00147 SysTick_Handler, /* SysTick Handler */ 00148 00149 /* External interrupts */ 00150 DMA_IRQHandler, /* 0 - DMA */ 00151 GPIO_EVEN_IRQHandler, /* 1 - GPIO_EVEN */ 00152 TIMER0_IRQHandler, /* 2 - TIMER0 */ 00153 ACMP0_IRQHandler, /* 3 - ACMP0 */ 00154 ADC0_IRQHandler, /* 4 - ADC0 */ 00155 I2C0_IRQHandler, /* 5 - I2C0 */ 00156 GPIO_ODD_IRQHandler, /* 6 - GPIO_ODD */ 00157 TIMER1_IRQHandler, /* 7 - TIMER1 */ 00158 USART1_RX_IRQHandler, /* 8 - USART1_RX */ 00159 USART1_TX_IRQHandler, /* 9 - USART1_TX */ 00160 LEUART0_IRQHandler, /* 10 - LEUART0 */ 00161 PCNT0_IRQHandler, /* 11 - PCNT0 */ 00162 RTC_IRQHandler, /* 12 - RTC */ 00163 CMU_IRQHandler, /* 13 - CMU */ 00164 VCMP_IRQHandler, /* 14 - VCMP */ 00165 MSC_IRQHandler, /* 15 - MSC */ 00166 AES_IRQHandler, /* 16 - AES */ 00167 00168 }; 00169 00170 00171 /*---------------------------------------------------------------------------- 00172 Reset Handler called on controller reset 00173 *----------------------------------------------------------------------------*/ 00174 void Reset_Handler(void) { 00175 uint32_t *pSrc, *pDest; 00176 uint32_t *pTable __attribute__((unused)); 00177 00178 #ifndef __NO_SYSTEM_INIT 00179 SystemInit(); 00180 #endif 00181 00182 /* Firstly it copies data from read only memory to RAM. There are two schemes 00183 * to copy. One can copy more than one sections. Another can only copy 00184 * one section. The former scheme needs more instructions and read-only 00185 * data to implement than the latter. 00186 * Macro __STARTUP_COPY_MULTIPLE is used to choose between two schemes. */ 00187 00188 #ifdef __STARTUP_COPY_MULTIPLE 00189 /* Multiple sections scheme. 00190 * 00191 * Between symbol address __copy_table_start__ and __copy_table_end__, 00192 * there are array of triplets, each of which specify: 00193 * offset 0: LMA of start of a section to copy from 00194 * offset 4: VMA of start of a section to copy to 00195 * offset 8: size of the section to copy. Must be multiply of 4 00196 * 00197 * All addresses must be aligned to 4 bytes boundary. 00198 */ 00199 pTable = &__copy_table_start__; 00200 00201 for (; pTable < &__copy_table_end__; pTable = pTable + 3) 00202 { 00203 pSrc = (uint32_t*)*(pTable + 0); 00204 pDest = (uint32_t*)*(pTable + 1); 00205 for (; pDest < (uint32_t*)(*(pTable + 1) + *(pTable + 2)) ; ) 00206 { 00207 *pDest++ = *pSrc++; 00208 } 00209 } 00210 #else 00211 /* Single section scheme. 00212 * 00213 * The ranges of copy from/to are specified by following symbols 00214 * __etext: LMA of start of the section to copy from. Usually end of text 00215 * __data_start__: VMA of start of the section to copy to 00216 * __data_end__: VMA of end of the section to copy to 00217 * 00218 * All addresses must be aligned to 4 bytes boundary. 00219 */ 00220 pSrc = &__etext; 00221 pDest = &__data_start__; 00222 00223 for ( ; pDest < &__data_end__ ; ) 00224 { 00225 *pDest++ = *pSrc++; 00226 } 00227 #endif /*__STARTUP_COPY_MULTIPLE */ 00228 00229 /* This part of work usually is done in C library startup code. Otherwise, 00230 * define this macro to enable it in this startup. 00231 * 00232 * There are two schemes too. One can clear multiple BSS sections. Another 00233 * can only clear one section. The former is more size expensive than the 00234 * latter. 00235 * 00236 * Define macro __STARTUP_CLEAR_BSS_MULTIPLE to choose the former. 00237 * Otherwise efine macro __STARTUP_CLEAR_BSS to choose the later. 00238 */ 00239 #ifdef __STARTUP_CLEAR_BSS_MULTIPLE 00240 /* Multiple sections scheme. 00241 * 00242 * Between symbol address __copy_table_start__ and __copy_table_end__, 00243 * there are array of tuples specifying: 00244 * offset 0: Start of a BSS section 00245 * offset 4: Size of this BSS section. Must be multiply of 4 00246 */ 00247 pTable = &__zero_table_start__; 00248 00249 for (; pTable < &__zero_table_end__; pTable = pTable + 2) 00250 { 00251 pDest = (uint32_t*)*(pTable + 0); 00252 for (; pDest < (uint32_t*)(*(pTable + 0) + *(pTable + 1)) ; ) 00253 { 00254 *pDest++ = 0; 00255 } 00256 } 00257 #elif defined (__STARTUP_CLEAR_BSS) 00258 /* Single BSS section scheme. 00259 * 00260 * The BSS section is specified by following symbols 00261 * __bss_start__: start of the BSS section. 00262 * __bss_end__: end of the BSS section. 00263 * 00264 * Both addresses must be aligned to 4 bytes boundary. 00265 */ 00266 pDest = &__bss_start__; 00267 00268 for ( ; pDest < &__bss_end__ ; ) 00269 { 00270 *pDest++ = 0ul; 00271 } 00272 #endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */ 00273 00274 #ifndef __START 00275 #define __START _start 00276 #endif 00277 __START(); 00278 } 00279 00280 00281 /*---------------------------------------------------------------------------- 00282 Default Handler for Exceptions / Interrupts 00283 *----------------------------------------------------------------------------*/ 00284 void Default_Handler(void) 00285 { 00286 while(1); 00287 } 00288