release/EM_CMSIS_P1_4.0.0/Device/SiliconLabs/EFM32ZG/Source/GCC/startup_efm32zg.c

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