Contiki 2.6

low_level_init.c

00001 /**************************************************
00002  *
00003  * This module contains the function `__low_level_init', a function
00004  * that is called before the `main' function of the program.  Normally
00005  * low-level initializations - such as setting the prefered interrupt
00006  * level or setting the watchdog - can be performed here.
00007  *
00008  * Note that this function is called before the data segments are
00009  * initialized, this means that this function cannot rely on the
00010  * values of global or static variables.
00011  *
00012  * When this function returns zero, the startup code will inhibit the
00013  * initialization of the data segments. The result is faster startup,
00014  * the drawback is that neither global nor static data will be
00015  * initialized.
00016  *
00017  * Copyright 1999-2004 IAR Systems. All rights reserved.
00018  * Customized by STMicroelectronics for STM32W
00019  *
00020  **************************************************/
00021 
00022 #include PLATFORM_HEADER
00023 
00024 #ifdef __cplusplus
00025 extern "C" {
00026 #endif
00027 
00028 #pragma language=extended
00029 
00030 #include "hal/micro/cortexm3/memmap.h"
00031 __root __no_init const HalFixedAddressTableType halFixedAddressTable @ __FAT__;
00032 
00033 extern const HalVectorTableType __vector_table[];
00034 extern void  halInternalSwitchToXtal(void);
00035 
00036 #define IAP_BOOTLOADER_APP_SWITCH_SIGNATURE  0xb001204d
00037 #define IAP_BOOTLOADER_MODE_UART  0
00038 
00039 __interwork int __low_level_init(void);
00040 
00041 static void setStackPointer(int32u address)
00042 {
00043   asm("MOVS SP, r0");
00044 }
00045 
00046 static const int16u blOffset[] = {
00047   0x0715 - 0x03ad - 0x68,
00048   0x0719 - 0x03ad - 0x6C
00049 };
00050 
00051 
00052 __interwork int __low_level_init(void)
00053 {
00054   //Ensure there is enough margin on VREG_1V8 for stable RAM reads by
00055   //setting it to a code of 6.  VREG_1V2 can be left at its reset value.
00056   VREG = 0x00000307;
00057   
00058   // This code should be careful about the use of local variables in case the
00059   // reset type happens to be a deep sleep reset.  If the reset is not from
00060   // deep sleep, then locals can be freely used
00061 
00062   //When the Cortex-M3 exits reset, interrupts are enable.  Explicitely
00063   //disable them immediately using the standard set PRIMASK instruction.
00064   //Injecting an assembly instruction this early does not effect optimization.
00065   asm("CPSID i");
00066 
00067   //It is quite possible that when the Cortex-M3 begins executing code the
00068   //Core Reset Vector Catch is still left enabled.  Because this VC would
00069   //cause us to halt at reset if another reset event tripped, we should
00070   //clear it as soon as possible.  If a debugger wants to halt at reset,
00071   //it will set this bit again.
00072   DEBUG_EMCR &= ~DEBUG_EMCR_VC_CORERESET;
00073 
00074   //Configure flash access for optimal current consumption early
00075   //during boot to save as much current as we can.
00076   FLASH_ACCESS = (FLASH_ACCESS_PREFETCH_EN          |
00077                   (1<<FLASH_ACCESS_CODE_LATENCY_BIT));
00078 
00079   ////---- Always remap the vector table ----////
00080   // We might be coming from a bootloader at the base of flash, or even in the
00081   //  NULL_BTL case, the BAT/AAT will be at the beginning of the image
00082   SCS_VTOR = (int32u)__vector_table;
00083 
00084   ////---- Always Configure Interrupt Priorities ----////
00085   //The STM32W support 5 bits of priority configuration.
00086   //  The cortex allows this to be further divided into preemption and a
00087   //  "tie-breaker" sub-priority.
00088   //We configure a scheme that allows for 3 bits (8 values) of preemption and
00089   //   2 bits (4 values) of tie-breaker by using the value 4 in PRIGROUP.
00090   //The value 0x05FA0000 is a special key required to write to this register.
00091   SCS_AIRCR = (0x05FA0000 | (4 <<SCS_AIRCR_PRIGROUP_BIT));
00092     
00093   //A few macros to help with interrupt priority configuration.  Really only 
00094   //  uses 6 of the possible levels, and ignores the tie-breaker sub-priority
00095   //  for now.
00096   //Don't forget that the priority level values need to be shifted into the
00097   //  top 5 bits of the 8 bit priority fields. (hence the <<3)
00098   //
00099   // NOTE: The ATOMIC and DISABLE_INTERRUPTS macros work by setting the 
00100   //       current priority to a value of 12, which still allows CRITICAL and 
00101   //       HIGH priority interrupts to fire, while blocking MED and LOW.
00102   //       If a different value is desired, spmr.s79 will need to be edited.
00103   #define CRITICAL (0  <<3)
00104   #define HIGH     (8  <<3)
00105   #define MED      (16 <<3)
00106   #define LOW      (28 <<3)
00107   #define NONE     (31 <<3)
00108 
00109   //With optimization turned on, the compiler will indentify all the values
00110   //and variables used here as constants at compile time and will truncate
00111   //this entire block of code to 98 bytes, comprised of 7 load-load-store
00112   //operations.
00113                     //vect00 is fixed                        //Stack pointer
00114                     //vect01 is fixed                        //Reset Vector
00115                     //vect02 is fixed                        //NMI Handler
00116                     //vect03 is fixed                        //Hard Fault Handler
00117   SCS_SHPR_7to4   = ((CRITICAL <<SCS_SHPR_7to4_PRI_4_BIT) |  //Memory Fault Handler 
00118                      (CRITICAL <<SCS_SHPR_7to4_PRI_5_BIT) |  //Bus Fault Handler
00119                      (CRITICAL <<SCS_SHPR_7to4_PRI_6_BIT) |  //Usage Fault Handler
00120                      (NONE <<SCS_SHPR_7to4_PRI_7_BIT));      //Reserved
00121   SCS_SHPR_11to8  = ((NONE <<SCS_SHPR_11to8_PRI_8_BIT)  |    //Reserved
00122                      (NONE <<SCS_SHPR_11to8_PRI_9_BIT)  |    //Reserved
00123                      (NONE <<SCS_SHPR_11to8_PRI_10_BIT) |    //Reserved
00124                      (HIGH <<SCS_SHPR_11to8_PRI_11_BIT));    //SVCall Handler
00125   SCS_SHPR_15to12 = ((MED  <<SCS_SHPR_15to12_PRI_12_BIT) |   //Debug Monitor Handler
00126                      (NONE <<SCS_SHPR_15to12_PRI_13_BIT) |   //Reserved
00127                      (HIGH <<SCS_SHPR_15to12_PRI_14_BIT) |   //PendSV Handler
00128                      (MED  <<SCS_SHPR_15to12_PRI_15_BIT));   //SysTick Handler
00129   NVIC_IPR_3to0   = ((MED  <<NVIC_IPR_3to0_PRI_0_BIT) |      //Timer 1 Handler
00130                      (MED  <<NVIC_IPR_3to0_PRI_1_BIT) |      //Timer 2 Handler
00131                      (HIGH <<NVIC_IPR_3to0_PRI_2_BIT) |      //Management Handler
00132                      (MED  <<NVIC_IPR_3to0_PRI_3_BIT));      //BaseBand Handler
00133   NVIC_IPR_7to4   = ((MED  <<NVIC_IPR_7to4_PRI_4_BIT) |      //Sleep Timer Handler
00134                      (MED  <<NVIC_IPR_7to4_PRI_5_BIT) |      //SC1 Handler
00135                      (MED  <<NVIC_IPR_7to4_PRI_6_BIT) |      //SC2 Handler
00136                      (MED  <<NVIC_IPR_7to4_PRI_7_BIT));      //Security Handler
00137   NVIC_IPR_11to8  = ((MED  <<NVIC_IPR_11to8_PRI_8_BIT)  |    //MAC Timer Handler
00138                      (MED  <<NVIC_IPR_11to8_PRI_9_BIT)  |    //MAC TX Handler
00139                      (MED  <<NVIC_IPR_11to8_PRI_10_BIT) |    //MAC RX Handler
00140                      (MED  <<NVIC_IPR_11to8_PRI_11_BIT));    //ADC Handler
00141   NVIC_IPR_15to12 = ((MED  <<NVIC_IPR_15to12_PRI_12_BIT) |   //GPIO IRQA Handler
00142                      (MED  <<NVIC_IPR_15to12_PRI_13_BIT) |   //GPIO IRQB Handler
00143                      (MED  <<NVIC_IPR_15to12_PRI_14_BIT) |   //GPIO IRQC Handler
00144                      (MED  <<NVIC_IPR_15to12_PRI_15_BIT));   //GPIO IRQD Handler
00145   NVIC_IPR_19to16 = ((LOW  <<NVIC_IPR_19to16_PRI_16_BIT));   //Debug Handler
00146                     //vect33 not implemented
00147                     //vect34 not implemented
00148                     //vect35 not implemented
00149 
00150   ////---- Always Configure System Handlers Control and Configuration ----////
00151   SCS_CCR = SCS_CCR_DIV_0_TRP_MASK;
00152   SCS_SHCSR = ( SCS_SHCSR_USGFAULTENA_MASK
00153                 | SCS_SHCSR_BUSFAULTENA_MASK
00154                 | SCS_SHCSR_MEMFAULTENA_MASK );
00155 
00156 
00157   if((RESET_EVENT&RESET_DSLEEP) == RESET_DSLEEP) {
00158     //Since the 13 NVIC registers above are fixed values, they are restored
00159     //above (where they get set anyways during normal boot sequences) instead
00160     //of inside of the halInternalSleep code:
00161 
00162     void halTriggerContextRestore(void);
00163     extern volatile boolean halPendSvSaveContext;
00164     halPendSvSaveContext = 0;       //0 means restore context
00165     SCS_ICSR |= SCS_ICSR_PENDSVSET; //pend halPendSvIsr to enable later
00166     halTriggerContextRestore();     //sets MSP, enables interrupts
00167     //if the context restore worked properly, we should never return here
00168     while(1) { ; }
00169   }
00170 
00171   //USART bootloader software activation check
00172   if ((*((int32u *)RAM_BOTTOM) == IAP_BOOTLOADER_APP_SWITCH_SIGNATURE) && (*((int8u *)(RAM_BOTTOM+4)) == IAP_BOOTLOADER_MODE_UART)){
00173        int8u cut = *(volatile int8u *) 0x08040798;
00174        int16u offset = 0;
00175        typedef void (*EntryPoint)(void);     
00176        offset = (halFixedAddressTable.baseTable.version == 3) ? blOffset[cut - 2] : 0;
00177        *((int32u *)RAM_BOTTOM) = 0;
00178        if (offset) {
00179          halInternalSwitchToXtal();
00180        }
00181        EntryPoint entryPoint = (EntryPoint)(*(int32u *)(FIB_BOTTOM+4) - offset);
00182        setStackPointer(*(int32u *)FIB_BOTTOM);
00183        entryPoint();
00184   }
00185 
00186   INTERRUPTS_OFF();
00187   asm("CPSIE i");
00188 
00189   /*==================================*/
00190   /* Choose if segment initialization */
00191   /* should be done or not.           */
00192   /* Return: 0 to omit seg_init       */
00193   /*         1 to run seg_init        */
00194   /*==================================*/
00195   return 1;
00196 }
00197 
00198 #pragma language=default
00199 
00200 #ifdef __cplusplus
00201 }
00202 #endif