diff options
Diffstat (limited to 'cc3200/hal/startup_gcc.c')
| -rw-r--r-- | cc3200/hal/startup_gcc.c | 418 |
1 files changed, 418 insertions, 0 deletions
diff --git a/cc3200/hal/startup_gcc.c b/cc3200/hal/startup_gcc.c new file mode 100644 index 000000000..30831eb88 --- /dev/null +++ b/cc3200/hal/startup_gcc.c @@ -0,0 +1,418 @@ +//***************************************************************************** +// startup_gcc.c +// +// Startup code for use with GCC. +// +// Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ +// +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +#include <stdint.h> +#include "inc/hw_nvic.h" +#include "inc/hw_types.h" +#include "fault_registers.h" + +//***************************************************************************** +// +// The following are constructs created by the linker, indicating where the +// the "data" and "bss" segments reside in memory. The initializers for the +// for the "data" segment resides immediately following the "text" segment. +// +//***************************************************************************** +extern uint32_t _data; +extern uint32_t _edata; +extern uint32_t _bss; +extern uint32_t _ebss; +extern uint32_t _estack; +extern uint32_t __init_data; + +//***************************************************************************** +// +// Forward declaration of the default fault handlers. +// +//***************************************************************************** +void ResetISR(void); +static void NmiSR(void) __attribute__( ( naked ) ); +static void FaultISR( void ) __attribute__( ( naked ) ); +static void IntDefaultHandler(void) __attribute__( ( naked ) ); +static void BusFaultHandler(void) __attribute__( ( naked ) ); +void HardFault_HandlerC(unsigned long *hardfault_args); + +//***************************************************************************** +// +// External declaration for the freeRTOS handlers +// +//***************************************************************************** +#ifdef USE_FREERTOS +extern void vPortSVCHandler(void); +extern void xPortPendSVHandler(void); +extern void xPortSysTickHandler(void); +#endif + +//***************************************************************************** +// +// The entry point for the application. +// +//***************************************************************************** +extern int main(void); + +//***************************************************************************** +// +// The vector table. Note that the proper constructs must be placed on this to +// ensure that it ends up at physical address 0x0000.0000. +// +//***************************************************************************** +__attribute__ ((section(".intvecs"))) +void (* const g_pfnVectors[256])(void) = +{ + (void (*)(void))((uint32_t)&_estack), // The initial stack pointer + ResetISR, // The reset handler + NmiSR, // The NMI handler + FaultISR, // The hard fault handler + IntDefaultHandler, // The MPU fault handler + BusFaultHandler, // The bus fault handler + IntDefaultHandler, // The usage fault handler + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved +#ifdef USE_FREERTOS + vPortSVCHandler, // SVCall handler +#else + IntDefaultHandler, // SVCall handler +#endif + IntDefaultHandler, // Debug monitor handler + 0, // Reserved +#ifdef USE_FREERTOS + xPortPendSVHandler, // The PendSV handler + xPortSysTickHandler, // The SysTick handler +#else + IntDefaultHandler, // The PendSV handler + IntDefaultHandler, // The SysTick handler +#endif + IntDefaultHandler, // GPIO Port A + IntDefaultHandler, // GPIO Port B + IntDefaultHandler, // GPIO Port C + IntDefaultHandler, // GPIO Port D + 0, // Reserved + IntDefaultHandler, // UART0 Rx and Tx + IntDefaultHandler, // UART1 Rx and Tx + 0, // Reserved + IntDefaultHandler, // I2C0 Master and Slave + 0,0,0,0,0, // Reserved + IntDefaultHandler, // ADC Channel 0 + IntDefaultHandler, // ADC Channel 1 + IntDefaultHandler, // ADC Channel 2 + IntDefaultHandler, // ADC Channel 3 + IntDefaultHandler, // Watchdog Timer + IntDefaultHandler, // Timer 0 subtimer A + IntDefaultHandler, // Timer 0 subtimer B + IntDefaultHandler, // Timer 1 subtimer A + IntDefaultHandler, // Timer 1 subtimer B + IntDefaultHandler, // Timer 2 subtimer A + IntDefaultHandler, // Timer 2 subtimer B + 0,0,0,0, // Reserved + IntDefaultHandler, // Flash + 0,0,0,0,0, // Reserved + IntDefaultHandler, // Timer 3 subtimer A + IntDefaultHandler, // Timer 3 subtimer B + 0,0,0,0,0,0,0,0,0, // Reserved + IntDefaultHandler, // uDMA Software Transfer + IntDefaultHandler, // uDMA Error + 0,0,0,0,0,0,0,0,0,0, // Reserved + 0,0,0,0,0,0,0,0,0,0, // Reserved + 0,0,0,0,0,0,0,0,0,0, // Reserved + 0,0,0,0,0,0,0,0,0,0, // Reserved + 0,0,0,0,0,0,0,0,0,0, // Reserved + 0,0,0,0,0,0,0,0,0,0, // Reserved + 0,0,0,0,0,0,0,0,0,0, // Reserved + 0,0,0,0,0,0,0,0,0,0, // Reserved + 0,0,0,0,0,0,0,0,0,0, // Reserved + 0,0,0,0,0,0,0,0,0,0, // Reserved + IntDefaultHandler, // SHA + 0,0, // Reserved + IntDefaultHandler, // AES + 0, // Reserved + IntDefaultHandler, // DES + 0,0,0,0,0, // Reserved + IntDefaultHandler, // SDHost + 0, // Reserved + IntDefaultHandler, // I2S + 0, // Reserved + IntDefaultHandler, // Camera + 0,0,0,0,0,0,0, // Reserved + IntDefaultHandler, // NWP to APPS Interrupt + IntDefaultHandler, // Power, Reset and Clock module + 0,0, // Reserved + IntDefaultHandler, // Shared SPI + IntDefaultHandler, // Generic SPI + IntDefaultHandler, // Link SPI + 0,0,0,0,0,0,0,0,0,0, // Reserved + 0,0,0,0,0,0,0,0,0,0, // Reserved + 0,0,0,0,0,0,0,0,0,0, // Reserved + 0,0,0,0,0,0,0,0,0,0, // Reserved + 0,0,0,0,0,0,0,0,0,0, // Reserved + 0,0,0,0,0,0,0,0,0,0, // Reserved + 0,0 // Reserved +}; + + + +//***************************************************************************** +// +// This is the code that gets called when the processor first starts execution +// following a reset event. Only the absolutely necessary set is performed, +// after which the application supplied entry() routine is called. Any fancy +// actions (such as making decisions based on the reset cause register, and +// resetting the bits in that register) are left solely in the hands of the +// application. +// +//***************************************************************************** + +void ResetISR(void) +{ +#if defined(DEBUG) && !defined(BOOTLOADER) + // + // Fill the main stack with a known value so that + // we can measure the main stack high water mark + // + __asm volatile + ( + "ldr r0, =_stack \n" + "ldr r1, =_estack \n" + "mov r2, #0x55555555 \n" + ".thumb_func \n" + "fill_loop: \n" + "cmp r0, r1 \n" + "it lt \n" + "strlt r2, [r0], #4 \n" + "blt fill_loop \n" + ); +#endif + + // Get the initial stack pointer location from the vector table + // and write this value to the msp register + __asm volatile + ( + "ldr r0, =_text \n" + "ldr r0, [r0] \n" + "msr msp, r0 \n" + ); + + { + uint32_t *pui32Src, *pui32Dest; + + // + // Copy the data segment initializers + // + pui32Src = &__init_data; + for(pui32Dest = &_data; pui32Dest < &_edata; ) + { + *pui32Dest++ = *pui32Src++; + } + + // + // Zero fill the bss segment. + // + __asm volatile + ( + "ldr r0, =_bss \n" + "ldr r1, =_ebss \n" + "mov r2, #0 \n" + ".thumb_func \n" + "zero_loop: \n" + "cmp r0, r1 \n" + "it lt \n" + "strlt r2, [r0], #4 \n" + "blt zero_loop \n" + ); + } + + // + // Call the application's entry point. + // + main(); +} + +//***************************************************************************** +// +// This is the code that gets called when the processor receives a NMI. This +// simply enters an infinite loop, preserving the system state for examination +// by a debugger. +// +//***************************************************************************** + +static void NmiSR(void) +{ +#ifdef DEBUG + // Break into the debugger + __asm volatile ("bkpt #0 \n"); +#endif + + // + // Enter an infinite loop. + // + for ( ; ; ) + { + } +} + +//***************************************************************************** +// +// This is the code that gets called when the processor receives a hard fault +// interrupt. This simply enters an infinite loop, preserving the system state +// for examination by a debugger. +// +//***************************************************************************** + +static void FaultISR(void) +{ + /* + * Get the appropriate stack pointer, depending on our mode, + * and use it as the parameter to the C handler. This function + * will never return + */ + + __asm volatile + ( + "movs r0, #4 \n" + "mov r1, lr \n" + "tst r0, r1 \n" + "beq _msp \n" + "mrs r0, psp \n" + "b HardFault_HandlerC \n" + "_msp: \n" + "mrs r0, msp \n" + "b HardFault_HandlerC \n" + ) ; +} + +//***************************************************************************** +// +// This is the code that gets called when the processor receives an unexpected +// interrupt. This simply enters an infinite loop, preserving the system state +// for examination by a debugger. +// +//***************************************************************************** + +static void BusFaultHandler(void) +{ +#ifdef DEBUG + // Break into the debugger + __asm volatile ("bkpt #0 \n"); +#endif + + // + // Enter an infinite loop. + // + for ( ; ; ) + { + } +} + +//***************************************************************************** +// +// This is the code that gets called when the processor receives an unexpected +// interrupt. This simply enters an infinite loop, preserving the system state +// for examination by a debugger. +// +//***************************************************************************** +static void IntDefaultHandler(void) +{ +#ifdef DEBUG + // Break into the debugger + __asm volatile ("bkpt #0 \n"); +#endif + + // + // Enter an infinite loop. + // + for ( ; ; ) + { + } +} + + +//*********************************************************************************** +// HardFaultHandler_C: +// This is called from the HardFault_HandlerAsm with a pointer the Fault stack +// as the parameter. We can then read the values from the stack and place them +// into local variables for ease of reading. +// We then read the various Fault Status and Address Registers to help decode +// cause of the fault. +// The function ends with a BKPT instruction to force control back into the debugger +//*********************************************************************************** +void HardFault_HandlerC(uint32_t *pulFaultStackAddress) +{ + volatile uint32_t r0 ; + volatile uint32_t r1 ; + volatile uint32_t r2 ; + volatile uint32_t r3 ; + volatile uint32_t r12 ; + volatile uint32_t lr ; + volatile uint32_t pc ; + volatile uint32_t psr ; + volatile _CFSR_t _CFSR ; + volatile _HFSR_t _HFSR ; + volatile uint32_t _BFAR ; + + + r0 = pulFaultStackAddress[0]; + r1 = pulFaultStackAddress[1]; + r2 = pulFaultStackAddress[2]; + r3 = pulFaultStackAddress[3]; + r12 = pulFaultStackAddress[4]; + lr = pulFaultStackAddress[5]; + pc = pulFaultStackAddress[6]; + psr = pulFaultStackAddress[7]; + + // Configurable Fault Status Register + // Consists of MMSR, BFSR and UFSR + _CFSR = (*((volatile _CFSR_t *)(0xE000ED28))); + // Hard Fault Status Register + _HFSR = (*((volatile _HFSR_t *)(0xE000ED2C))); + // Bus Fault Address Register + _BFAR = (*((volatile uint32_t *)(0xE000ED38))); + +#ifdef DEBUG + // Break into the debugger + __asm volatile ("bkpt #0 \n"); +#endif + + for ( ; ; ) + { + // Keep the compiler happy + (void)r0, (void)r1, (void)r2, (void)r3, (void)r12, (void)lr, (void)pc, (void)psr; + (void)_CFSR, (void)_HFSR, (void)_BFAR; + } +} + |
