release/EM_CMSIS_P1_4.0.0/Device/SiliconLabs/EFM32TG/Source/GCC/startup_efm32tg.c

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