nes-proj/arch/cpu/cc13xx-cc26xx/dev/startup_cc13xx_cc26xx_gcc.c

328 lines
11 KiB
C
Raw Normal View History

/*
* Copyright (c) 2017, Texas Instruments Incorporated
* All rights reserved.
*
* 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.
*/
//*****************************************************************************
//
// Check if compiler is GNU Compiler
//
//*****************************************************************************
#if !(defined(__GNUC__))
#error "startup_cc13xx_cc26xx_gcc.c: Unsupported compiler!"
#endif
#include <string.h>
#include <ti/devices/DeviceFamily.h>
#include DeviceFamily_constructPath(inc/hw_types.h)
#include DeviceFamily_constructPath(driverlib/interrupt.h)
#include DeviceFamily_constructPath(driverlib/setup.h)
//*****************************************************************************
//
// Forward declaration of the default fault handlers.
//
//*****************************************************************************
void resetISR(void);
static void nmiISR(void);
static void faultISR(void);
static void defaultHandler(void);
static void busFaultHandler(void);
//*****************************************************************************
//
// External declaration for the reset handler that is to be called when the
// processor is started
//
//*****************************************************************************
extern void _c_int00(void);
//*****************************************************************************
//
// The entry point for the application.
//
//*****************************************************************************
extern int main(void);
//*****************************************************************************
//
// linker variable that marks the top of stack.
//
//*****************************************************************************
extern unsigned long _stack_end;
//*****************************************************************************
//
// 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(".resetVecs"))) __attribute__ ((used))
2018-07-24 10:16:53 +00:00
static void(*const resetVectors[16]) (void) =
{
(void (*)(void))((uint32_t)&_stack_end),
2018-07-24 10:16:53 +00:00
/* The initial stack pointer */
resetISR, /* The reset handler */
nmiISR, /* The NMI handler */
faultISR, /* The hard fault handler */
defaultHandler, /* The MPU fault handler */
busFaultHandler, /* The bus fault handler */
defaultHandler, /* The usage fault handler */
0, /* Reserved */
0, /* Reserved */
0, /* Reserved */
0, /* Reserved */
defaultHandler, /* SVCall handler */
defaultHandler, /* Debug monitor handler */
0, /* Reserved */
defaultHandler, /* The PendSV handler */
defaultHandler /* The SysTick handler */
};
//*****************************************************************************
//
// The following are arrays of pointers to constructor functions that need to
// be called during startup to initialize global objects.
//
//*****************************************************************************
extern void (*__init_array_start[])(void);
extern void (*__init_array_end[])(void);
//*****************************************************************************
//
// The following global variable is required for C++ support.
//
//*****************************************************************************
void *__dso_handle = (void *)&__dso_handle;
//*****************************************************************************
//
// 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 __bss_start__;
extern uint32_t __bss_end__;
extern uint32_t __data_load__;
extern uint32_t __data_start__;
extern uint32_t __data_end__;
//
//*****************************************************************************
//
// Initialize the .data and .bss sections and copy the first 16 vectors from
// the read-only/reset table to the runtime RAM table. Fill the remaining
// vectors with a stub. This vector table will be updated at runtime.
//
//*****************************************************************************
//
void localProgramStart(void)
{
uint32_t *bs;
uint32_t *be;
uint32_t *dl;
uint32_t *ds;
uint32_t *de;
uint32_t count;
uint32_t i;
2018-07-24 10:16:53 +00:00
#if defined(__ARM_ARCH_7EM__) && defined(__VFP_FP__) && !defined(__SOFTFP__)
volatile uint32_t *pui32Cpacr = (uint32_t *)0xE000ED88;
/* Enable Coprocessor Access Control (CPAC) */
*pui32Cpacr |= (0xF << 20);
#endif
IntMasterDisable();
/* Final trim of device */
SetupTrimDevice();
/* initiailize .bss to zero */
bs = &__bss_start__;
be = &__bss_end__;
while(bs < be) {
*bs = 0;
bs++;
}
/* relocate the .data section */
dl = &__data_load__;
ds = &__data_start__;
de = &__data_end__;
if(dl != ds) {
while(ds < de) {
*ds = *dl;
dl++;
ds++;
}
}
/* Run any constructors */
count = (uint32_t)(__init_array_end - __init_array_start);
for(i = 0; i < count; i++) {
__init_array_start[i]();
}
2018-07-24 10:16:53 +00:00
/* Call the application's entry point. */
main();
2018-07-24 10:16:53 +00:00
/* If we ever return signal Error */
faultISR();
}
//*****************************************************************************
//
// 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 __attribute__((naked)) resetISR(void)
{
__asm__ __volatile__
(
"movw r0, #:lower16:resetVectors \n"
"movt r0, #:upper16:resetVectors \n"
"ldr r0, [r0] \n"
"mov sp, r0 \n"
"bl localProgramStart \n"
);
}
//*****************************************************************************
//
// 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
nmiISR(void)
{
/* Enter an infinite loop. */
2018-07-24 10:16:53 +00:00
while(1) {
}
2018-07-10 18:29:46 +00:00
}
//*****************************************************************************
//
// This is the code that gets called when the processor receives a fault
// interrupt. This simply enters an infinite loop, preserving the system state
// for examination by a debugger.
//
//*****************************************************************************
void
debugHardfault(uint32_t *sp)
{
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;
(void)(r0 = sp[0]);
(void)(r1 = sp[1]);
(void)(r2 = sp[2]);
(void)(r3 = sp[3]);
(void)(r12 = sp[4]);
(void)(lr = sp[5]);
(void)(pc = sp[6]);
(void)(psr = sp[7]);
while(1);
}
static void
faultISR(void)
{
__asm__ __volatile__
2018-07-10 18:29:46 +00:00
(
"tst lr, #4 \n"
"ite eq \n"
"mrseq r0, msp \n"
"mrsne r0, psp \n"
"b debugHardfault \n"
2018-07-10 18:29:46 +00:00
);
}
//*****************************************************************************
//
// 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.
//
//*****************************************************************************
volatile int x__;
static void
busFaultHandler(void)
{
x__ = 0;
/* Enter an infinite loop. */
2018-07-24 10:16:53 +00:00
while(1) {
}
}
//*****************************************************************************
//
// 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
defaultHandler(void)
{
/* Enter an infinite loop. */
2018-07-24 10:16:53 +00:00
while(1) {
}
}
//*****************************************************************************
//
// This function is called by __libc_fini_array which gets called when exit()
// is called. In order to support exit(), an empty _fini() stub function is
// required.
//
//*****************************************************************************
void _fini(void)
{
2018-07-24 10:16:53 +00:00
/* Function body left empty intentionally */
}