release/EM_CMSIS_P1_4.0.0/Device/SiliconLabs/EFM32HG/Source/GCC/startup_efm32hg.c

00001 /*
00002  * @file startup_efm32hg.c
00003  * @brief CMSIS Compatible EFM32HG 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   0x00000C00
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 void USART0_RX_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler")));
00125 void USART0_TX_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler")));
00126 void USB_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler")));
00127 void TIMER2_IRQHandler(void) __attribute__ ((weak, alias("Default_Handler")));
00128 
00129 
00130 
00131 /*----------------------------------------------------------------------------
00132   Exception / Interrupt Vector table
00133  *----------------------------------------------------------------------------*/
00134 const pFunc __Vectors[] __attribute__ ((section(".vectors"))) = {
00135   /* Cortex-M Exception Handlers */
00136   (pFunc)&__StackTop,                       /*      Initial Stack Pointer     */
00137   Reset_Handler,                            /*      Reset Handler             */
00138   NMI_Handler,                              /*      NMI Handler               */
00139   HardFault_Handler,                        /*      Hard Fault Handler        */
00140   Default_Handler,                          /*      Reserved                  */
00141   Default_Handler,                          /*      Reserved                  */
00142   Default_Handler,                          /*      Reserved                  */
00143   Default_Handler,                          /*      Reserved                  */
00144   Default_Handler,                          /*      Reserved                  */
00145   Default_Handler,                          /*      Reserved                  */
00146   Default_Handler,                          /*      Reserved                  */
00147   SVC_Handler,                              /*      SVCall Handler            */
00148   Default_Handler,                          /*      Reserved                  */
00149   Default_Handler,                          /*      Reserved                  */
00150   PendSV_Handler,                           /*      PendSV Handler            */
00151   SysTick_Handler,                          /*      SysTick Handler           */
00152 
00153   /* External interrupts */
00154   DMA_IRQHandler,                       /*  0 - DMA       */
00155   GPIO_EVEN_IRQHandler,                       /*  1 - GPIO_EVEN       */
00156   TIMER0_IRQHandler,                       /*  2 - TIMER0       */
00157   ACMP0_IRQHandler,                       /*  3 - ACMP0       */
00158   ADC0_IRQHandler,                       /*  4 - ADC0       */
00159   I2C0_IRQHandler,                       /*  5 - I2C0       */
00160   GPIO_ODD_IRQHandler,                       /*  6 - GPIO_ODD       */
00161   TIMER1_IRQHandler,                       /*  7 - TIMER1       */
00162   USART1_RX_IRQHandler,                       /*  8 - USART1_RX       */
00163   USART1_TX_IRQHandler,                       /*  9 - USART1_TX       */
00164   LEUART0_IRQHandler,                       /*  10 - LEUART0       */
00165   PCNT0_IRQHandler,                       /*  11 - PCNT0       */
00166   RTC_IRQHandler,                       /*  12 - RTC       */
00167   CMU_IRQHandler,                       /*  13 - CMU       */
00168   VCMP_IRQHandler,                       /*  14 - VCMP       */
00169   MSC_IRQHandler,                       /*  15 - MSC       */
00170   AES_IRQHandler,                       /*  16 - AES       */
00171   USART0_RX_IRQHandler,                       /*  17 - USART0_RX       */
00172   USART0_TX_IRQHandler,                       /*  18 - USART0_TX       */
00173   USB_IRQHandler,                       /*  19 - USB       */
00174   TIMER2_IRQHandler,                       /*  20 - TIMER2       */
00175 
00176 };
00177 
00178 
00179 /*----------------------------------------------------------------------------
00180   Reset Handler called on controller reset
00181  *----------------------------------------------------------------------------*/
00182 void Reset_Handler(void) {
00183   uint32_t *pSrc, *pDest;
00184   uint32_t *pTable __attribute__((unused));
00185 
00186 #ifndef __NO_SYSTEM_INIT
00187   SystemInit();
00188 #endif
00189 
00190 /*  Firstly it copies data from read only memory to RAM. There are two schemes
00191  *  to copy. One can copy more than one sections. Another can only copy
00192  *  one section.  The former scheme needs more instructions and read-only
00193  *  data to implement than the latter.
00194  *  Macro __STARTUP_COPY_MULTIPLE is used to choose between two schemes.  */
00195 
00196 #ifdef __STARTUP_COPY_MULTIPLE
00197 /*  Multiple sections scheme.
00198  *
00199  *  Between symbol address __copy_table_start__ and __copy_table_end__,
00200  *  there are array of triplets, each of which specify:
00201  *    offset 0: LMA of start of a section to copy from
00202  *    offset 4: VMA of start of a section to copy to
00203  *    offset 8: size of the section to copy. Must be multiply of 4
00204  *
00205  *  All addresses must be aligned to 4 bytes boundary.
00206  */
00207   pTable = &__copy_table_start__;
00208 
00209   for (; pTable < &__copy_table_end__; pTable = pTable + 3)
00210   {
00211     pSrc  = (uint32_t*)*(pTable + 0);
00212     pDest = (uint32_t*)*(pTable + 1);
00213     for (; pDest < (uint32_t*)(*(pTable + 1) + *(pTable + 2)) ; )
00214     {
00215       *pDest++ = *pSrc++;
00216     }
00217   }
00218 #else
00219 /*  Single section scheme.
00220  *
00221  *  The ranges of copy from/to are specified by following symbols
00222  *    __etext: LMA of start of the section to copy from. Usually end of text
00223  *    __data_start__: VMA of start of the section to copy to
00224  *    __data_end__: VMA of end of the section to copy to
00225  *
00226  *  All addresses must be aligned to 4 bytes boundary.
00227  */
00228   pSrc  = &__etext;
00229   pDest = &__data_start__;
00230 
00231   for ( ; pDest < &__data_end__ ; )
00232   {
00233     *pDest++ = *pSrc++;
00234   }
00235 #endif /*__STARTUP_COPY_MULTIPLE */
00236 
00237 /*  This part of work usually is done in C library startup code. Otherwise,
00238  *  define this macro to enable it in this startup.
00239  *
00240  *  There are two schemes too. One can clear multiple BSS sections. Another
00241  *  can only clear one section. The former is more size expensive than the
00242  *  latter.
00243  *
00244  *  Define macro __STARTUP_CLEAR_BSS_MULTIPLE to choose the former.
00245  *  Otherwise efine macro __STARTUP_CLEAR_BSS to choose the later.
00246  */
00247 #ifdef __STARTUP_CLEAR_BSS_MULTIPLE
00248 /*  Multiple sections scheme.
00249  *
00250  *  Between symbol address __copy_table_start__ and __copy_table_end__,
00251  *  there are array of tuples specifying:
00252  *    offset 0: Start of a BSS section
00253  *    offset 4: Size of this BSS section. Must be multiply of 4
00254  */
00255   pTable = &__zero_table_start__;
00256 
00257   for (; pTable < &__zero_table_end__; pTable = pTable + 2)
00258   {
00259     pDest = (uint32_t*)*(pTable + 0);
00260     for (; pDest < (uint32_t*)(*(pTable + 0) + *(pTable + 1)) ; )
00261     {
00262       *pDest++ = 0;
00263     }
00264   }
00265 #elif defined (__STARTUP_CLEAR_BSS)
00266 /*  Single BSS section scheme.
00267  *
00268  *  The BSS section is specified by following symbols
00269  *    __bss_start__: start of the BSS section.
00270  *    __bss_end__: end of the BSS section.
00271  *
00272  *  Both addresses must be aligned to 4 bytes boundary.
00273  */
00274   pDest = &__bss_start__;
00275 
00276   for ( ; pDest < &__bss_end__ ; )
00277   {
00278     *pDest++ = 0ul;
00279   }
00280 #endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */
00281 
00282 #ifndef __START
00283 #define __START _start
00284 #endif
00285   __START();
00286 }
00287 
00288 
00289 /*----------------------------------------------------------------------------
00290   Default Handler for Exceptions / Interrupts
00291  *----------------------------------------------------------------------------*/
00292 void Default_Handler(void)
00293 {
00294   while(1);
00295 }
00296