release/EM_CMSIS_P1_4.0.0/Device/SiliconLabs/EFM32G/Source/GCC/startup_efm32g.c

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