//***************************************************************************** // +--+ // | ++----+ // +-++ | // | | // +-+--+ | // | +--+--+ // +----+ Copyright (c) 2009-12 Code Red Technologies Ltd. // // Microcontroller Startup code for use with Red Suite // // Version : 120126 // // Software License Agreement // // The software is owned by Code Red Technologies and/or its suppliers, and is // protected under applicable copyright laws. All rights are reserved. Any // use in violation of the foregoing restrictions may subject the user to criminal // sanctions under applicable laws, as well as to civil liability for the breach // of the terms and conditions of this license. // // THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED // OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. // USE OF THIS SOFTWARE FOR COMMERCIAL DEVELOPMENT AND/OR EDUCATION IS SUBJECT // TO A CURRENT END USER LICENSE AGREEMENT (COMMERCIAL OR EDUCATIONAL) WITH // CODE RED TECHNOLOGIES LTD. // //***************************************************************************** #if defined (__cplusplus) #ifdef __REDLIB__ #error Redlib does not support C++ #else //***************************************************************************** // // The entry point for the C++ library startup // //***************************************************************************** extern "C" { extern void __libc_init_array(void); } #endif #endif #define WEAK __attribute__ ((weak)) #define ALIAS(f) __attribute__ ((weak, alias (#f))) // Code Red - if CMSIS is being used, then SystemInit() routine // will be called by startup code rather than in application's main() #if defined (__USE_CMSIS) #include "system_LM3S.h" #endif //***************************************************************************** #if defined (__cplusplus) extern "C" { #endif #include "FreeRTOS.h" #include "stdint.h" //***************************************************************************** // // Forward declaration of the default handlers. These are aliased. // When the application defines a handler (with the same name), this will // automatically take precedence over these weak definitions // //***************************************************************************** void ResetISR(void); WEAK void NMI_Handler(void); //WEAK void HardFault_Handler(void); static void HardFault_Handler( void ) __attribute__( ( naked ) ); WEAK void MemManage_Handler(void); WEAK void BusFault_Handler(void); WEAK void UsageFault_Handler(void); //WEAK void SVC_Handler(void); WEAK void DebugMon_Handler(void); //WEAK void PendSV_Handler(void); //void SysTickHandler(void); WEAK void IntDefaultHandler(void); extern void UARTprintf(const char *pcString, ...); extern void SENSOR_TimerISR(void); extern void ROTARY_MotorPWMTimer_ISR(void); extern void ROTARY_MotorTimer2_ISR(void); extern void LINEAR_MotorPWMTimer_ISR(void); extern void LINEAR_MotorTimer2_ISR(void); extern void CONT_TIMER_ISR(void); extern void WatchdogIntHandler_ISR(void); extern void THERMISTOR_ADC_Sampler_ISR(void); extern void SENSOR_ADC_Sampler_ISR(void); //extern void I2C_GPIO_Interupt_ISR(void); extern void I2C_CHIP1_GPIO_Interupt_ISR(void); // This is for reading REPM mechanical Switches extern void I2C_CHIP2_GPIO_Interupt_ISR(void); // This is for reading TFA reflective, move and stop sensors extern void I2C_ISR(void); extern void ARCNET_Interupt_ISR(void); extern void Switch_Interupt_ISR(void); extern void PRINTHEAD_ContLongTimer_ISR(void); extern void PRINTHEAD_ContShortTimer_ISR(void); extern void PRINTHEAD_PWRControlISR(void); extern void USB0DeviceIntHandler(void); extern void x_Int_TPU0A( void ); extern void x_Int_TPU1A( void ); extern void x_Int_TPU2A( void ); extern void UART0_ISR (void); // Test code extern void SENSOR_TestTimerISR(void); extern void TickTimerMasterCounter_ISR (void); //PN /* * * */ //***************************************************************************** // // External declarations for the interrupt handlers used by the application. // //***************************************************************************** extern void xPortSysTickHandler(void); extern void xPortPendSVHandler(void); extern void vPortSVCHandler( void ); //***************************************************************************** // // The entry point for the application. // __main() is the entry point for Redlib based applications // main() is the entry point for Newlib based applications // //***************************************************************************** #if defined (__REDLIB__) extern void __main(void); #endif extern int main(void); //***************************************************************************** // // External declaration for the pointer to the stack top from the Linker Script // //***************************************************************************** extern void _vStackTop(void); //***************************************************************************** #if defined (__cplusplus) } // extern "C" #endif //***************************************************************************** // // The vector table. Note that the proper constructs must be placed on this to // ensure that it ends up at physical address 0x0000.0000. // //***************************************************************************** extern void (* const g_pfnVectors[])(void); __attribute__ ((section(".isr_vector"))) void (* const g_pfnVectors[])(void) = { // &_vStackTop, // The initial stack pointer ResetISR, // The reset handler NMI_Handler, // The NMI handler HardFault_Handler, // The hard fault handler MemManage_Handler, // The MPU fault handler BusFault_Handler, // The bus fault handler UsageFault_Handler, // The usage fault handler 0, // Reserved 0, // Reserved 0, // Reserved 0, // Reserved vPortSVCHandler, // SVCall handler DebugMon_Handler, // Debug monitor handler 0, // Reserved xPortPendSVHandler, // The PendSV handler xPortSysTickHandler, // The SysTick handler // Chip Level IntDefaultHandler, // GPIO Port A IntDefaultHandler, // GPIO Port B IntDefaultHandler, // GPIO Port C IntDefaultHandler, // GPIO Port D IntDefaultHandler, // GPIO Port E UART0_ISR, // UART0 Rx and Tx IntDefaultHandler, // UART1 Rx and Tx IntDefaultHandler, // SSI Rx and Tx I2C_ISR, // I2C Master and Slave IntDefaultHandler, // PWM Fault LINEAR_MotorPWMTimer_ISR, // PWM Generator 0 IntDefaultHandler, // PWM Generator 1 IntDefaultHandler, // PWM Generator 2 IntDefaultHandler, // Quadrature Encoder SENSOR_ADC_Sampler_ISR, // ADC Sequence 0 IntDefaultHandler, // ADC Sequence 1 THERMISTOR_ADC_Sampler_ISR, // ADC Sequence 2 IntDefaultHandler, // ADC Sequence 3 WatchdogIntHandler_ISR, // Watchdog timer ROTARY_MotorTimer2_ISR, // Timer 0 subtimer A LINEAR_MotorTimer2_ISR, // Timer 0 subtimer B SENSOR_TimerISR, // Timer 1 subtimer A IntDefaultHandler, // Timer 1 subtimer B PRINTHEAD_ContLongTimer_ISR, // Timer 2 subtimer A PRINTHEAD_ContShortTimer_ISR, // Timer 2 subtimer B IntDefaultHandler, // Analog Comparator 0 IntDefaultHandler, // Analog Comparator 1 IntDefaultHandler, // Analog Comparator 2 IntDefaultHandler, // System Control (PLL, OSC, BO) IntDefaultHandler, // FLASH Control IntDefaultHandler, // GPIO Port F IntDefaultHandler, // GPIO Port G IntDefaultHandler, // GPIO Port H IntDefaultHandler, // UART2 Rx and Tx IntDefaultHandler, // SSI1 Rx and Tx x_Int_TPU2A, // Timer 3 subtimer A IntDefaultHandler, // Timer 3 subtimer B IntDefaultHandler, // I2C1 Master and Slave IntDefaultHandler, // Quadrature Encoder 1 IntDefaultHandler, // CAN0 IntDefaultHandler, // CAN1// 0, // Reserved IntDefaultHandler, // Ethernet IntDefaultHandler, // Hibernate USB0DeviceIntHandler, // USB0 ROTARY_MotorPWMTimer_ISR, // PWM Generator 3 IntDefaultHandler, // uDMA Software Transfer IntDefaultHandler, // uDMA Error IntDefaultHandler, // ADC1 Sequence 0 IntDefaultHandler, // ADC1 Sequence 1 IntDefaultHandler, // ADC1 Sequence 2 IntDefaultHandler, // ADC1 Sequence 3 IntDefaultHandler, // I2S0 IntDefaultHandler, // External Bus Interface 0 IntDefaultHandler // GPIO Port J }; /* extern void (* const g_pfnVectors[])(void); __attribute__ ((section(".isr_vector"))) void (* const g_pfnVectors[])(void) = { // &_vStackTop, // The initial stack pointer ResetISR, // The reset handler NMI_Handler, // The NMI handler HardFault_Handler, // The hard fault handler MemManage_Handler, // The MPU fault handler BusFault_Handler, // The bus fault handler UsageFault_Handler, // The usage fault handler 0, // Reserved 0, // Reserved 0, // Reserved 0, // Reserved SVC_Handler, // SVCall handler DebugMon_Handler, // Debug monitor handler 0, // Reserved PendSV_Handler, // The PendSV handler SysTickHandler, // The SysTick handler // Chip Level IntDefaultHandler, // GPIO Port A IntDefaultHandler, // GPIO Port B IntDefaultHandler, // GPIO Port C IntDefaultHandler, // GPIO Port D IntDefaultHandler, // GPIO Port E UART0_ISR, // UART0 Rx and Tx IntDefaultHandler, // UART1 Rx and Tx IntDefaultHandler, // SSI Rx and Tx I2C_ISR, // I2C Master and Slave IntDefaultHandler, // PWM Fault LINEAR_MotorPWMTimer_ISR, // PWM Generator 0 IntDefaultHandler, // PWM Generator 1 IntDefaultHandler, // PWM Generator 2 IntDefaultHandler, // Quadrature Encoder SENSOR_ADC_Sampler_ISR, // ADC Sequence 0 IntDefaultHandler, // ADC Sequence 1 THERMISTOR_ADC_Sampler_ISR, // ADC Sequence 2 IntDefaultHandler, // ADC Sequence 3 WatchdogIntHandler_ISR, // Watchdog timer ROTARY_MotorTimer2_ISR, // Timer 0 subtimer A LINEAR_MotorTimer2_ISR, // Timer 0 subtimer B SENSOR_TimerISR, // Timer 1 subtimer A IntDefaultHandler, // Timer 1 subtimer B PRINTHEAD_ContLongTimer_ISR, // Timer 2 subtimer A PRINTHEAD_ContShortTimer_ISR, // Timer 2 subtimer B IntDefaultHandler, // Analog Comparator 0 IntDefaultHandler, // Analog Comparator 1 IntDefaultHandler, // Analog Comparator 2 IntDefaultHandler, // System Control (PLL, OSC, BO) IntDefaultHandler, // FLASH Control IntDefaultHandler, // GPIO Port F IntDefaultHandler, // GPIO Port G IntDefaultHandler, // GPIO Port H IntDefaultHandler, // UART2 Rx and Tx IntDefaultHandler, // SSI1 Rx and Tx PRINTHEAD_PWRControlISR, // Timer 3 subtimer A IntDefaultHandler, // Timer 3 subtimer B IntDefaultHandler, // I2C1 Master and Slave IntDefaultHandler, // Quadrature Encoder 1 IntDefaultHandler, // CAN0 IntDefaultHandler, // CAN1 0, // Reserved IntDefaultHandler, // Ethernet IntDefaultHandler, // Hibernate USB0DeviceIntHandler, // USB0 ROTARY_MotorPWMTimer_ISR, // PWM Generator 3 IntDefaultHandler, // uDMA Software Transfer IntDefaultHandler, // uDMA Error IntDefaultHandler, // ADC1 Sequence 0 IntDefaultHandler, // ADC1 Sequence 1 IntDefaultHandler, // ADC1 Sequence 2 IntDefaultHandler, // ADC1 Sequence 3 IntDefaultHandler, // I2S0 IntDefaultHandler, // External Bus Interface 0 IntDefaultHandler // GPIO Port J }; */ //***************************************************************************** // Functions to carry out the initialization of RW and BSS data sections. These // are written as separate functions rather than being inlined within the // ResetISR() function in order to cope with MCUs with multiple banks of // memory. //***************************************************************************** __attribute__ ((section(".after_vectors"))) void data_init(unsigned int romstart, unsigned int start, unsigned int len) { unsigned int *pulDest = (unsigned int*) start; unsigned int *pulSrc = (unsigned int*) romstart; unsigned int loop; for (loop = 0; loop < len; loop = loop + 4) *pulDest++ = *pulSrc++; } __attribute__ ((section(".after_vectors"))) void bss_init(unsigned int start, unsigned int len) { unsigned int *pulDest = (unsigned int*) start; unsigned int loop; for (loop = 0; loop < len; loop = loop + 4) *pulDest++ = 0; } #ifndef USE_OLD_STYLE_DATA_BSS_INIT //***************************************************************************** // The following symbols are constructs generated by the linker, indicating // the location of various points in the "Global Section Table". This table is // created by the linker via the Code Red managed linker script mechanism. It // contains the load address, execution address and length of each RW data // section and the execution and length of each BSS (zero initialized) section. //***************************************************************************** extern unsigned int __data_section_table; extern unsigned int __data_section_table_end; extern unsigned int __bss_section_table; extern unsigned int __bss_section_table_end; #else //***************************************************************************** // The following symbols are constructs generated by the linker, indicating // the load address, execution address and length of the RW data section and // the execution and length of the BSS (zero initialized) section. // Note that these symbols are not normally used by the managed linker script // mechanism in Red Suite/LPCXpresso 3.6 (Windows) and LPCXpresso 3.8 (Linux). // They are provide here simply so this startup code can be used with earlier // versions of Red Suite which do not support the more advanced managed linker // script mechanism introduced in the above version. To enable their use, // define "USE_OLD_STYLE_DATA_BSS_INIT". //***************************************************************************** extern unsigned int _etext; extern unsigned int _data; extern unsigned int _edata; extern unsigned int _bss; extern unsigned int _ebss; #endif //***************************************************************************** // Reset entry point for your code. // Sets up a simple runtime environment and initializes the C/C++ // library. // //***************************************************************************** void ResetISR(void) { #ifndef USE_OLD_STYLE_DATA_BSS_INIT // // Copy the data sections from flash to SRAM. // unsigned int LoadAddr, ExeAddr, SectionLen; unsigned int *SectionTableAddr; // Load base address of Global Section Table SectionTableAddr = &__data_section_table; // Copy the data sections from flash to SRAM. while (SectionTableAddr < &__data_section_table_end) { LoadAddr = *SectionTableAddr++; ExeAddr = *SectionTableAddr++; SectionLen = *SectionTableAddr++; data_init(LoadAddr, ExeAddr, SectionLen); } // At this point, SectionTableAddr = &__bss_section_table; // Zero fill the bss segment while (SectionTableAddr < &__bss_section_table_end) { ExeAddr = *SectionTableAddr++; SectionLen = *SectionTableAddr++; bss_init(ExeAddr, SectionLen); } #else // Use Old Style Data and BSS section initialization. // This will only initialize a single RAM bank. unsigned int * LoadAddr, *ExeAddr, *EndAddr, SectionLen; // Copy the data segment from flash to SRAM. LoadAddr = &_etext; ExeAddr = &_data; EndAddr = &_edata; SectionLen = (void*)EndAddr - (void*)ExeAddr; data_init((unsigned int)LoadAddr, (unsigned int)ExeAddr, SectionLen); // Zero fill the bss segment ExeAddr = &_bss; EndAddr = &_ebss; SectionLen = (void*)EndAddr - (void*)ExeAddr; bss_init ((unsigned int)ExeAddr, SectionLen); #endif #ifdef __USE_CMSIS SystemInit(); #endif #if defined (__cplusplus) // // Call C++ library initialisation // __libc_init_array(); #endif #if defined (__REDLIB__) // Call the Redlib library, which in turn calls main() __main(); #else main(); #endif // // main() shouldn't return, but if it does, we'll just enter an infinite loop // while (1) { ; } } //***************************************************************************** // Default exception handlers. Override the ones here by defining your own // handler routines in your application code. //***************************************************************************** void NMI_Handler(void) { //Will enter an infinite loop. //This will cause the watchdog to trip and cause a RESET within 2 seconds. // // Enter an infinite loop. // while(1) { UARTprintf("\n NMI Handler Encountered - Looping Endlessly"); } } /* void HardFault_Handler(void) { while(1) { UARTprintf("\n Hard Fault Encountered - Looping Endlessly"); } } */ /* The fault handler implementation calls a function called prvGetRegistersFromStack(). */ static void HardFault_Handler(void) { __asm volatile ( " tst lr, #4 \n" " ite eq \n" " mrseq r0, msp \n" " mrsne r0, psp \n" " ldr r1, [r0, #24] \n" " ldr r2, handler2_address_const \n" " bx r2 \n" " handler2_address_const: .word prvGetRegistersFromStack \n" ); } void prvGetRegistersFromStack( uint32_t *pulFaultStackAddress ) { /* These are volatile to try and prevent the compiler/linker optimising them away as the variables never actually get used. If the debugger won't show the values of the variables, make them global my moving their declaration outside of this function. */ volatile uint32_t r0; volatile uint32_t r1; volatile uint32_t r2; volatile uint32_t r3; volatile uint32_t r12; volatile uint32_t lr; /* Link register. */ volatile uint32_t pc; /* Program counter. */ volatile uint32_t psr;/* Program status register. */ r0 = pulFaultStackAddress[ 0 ]; r1 = pulFaultStackAddress[ 1 ]; r2 = pulFaultStackAddress[ 2 ]; r3 = pulFaultStackAddress[ 3 ]; r12 = pulFaultStackAddress[ 4 ]; lr = pulFaultStackAddress[ 5 ]; pc = pulFaultStackAddress[ 6 ]; psr = pulFaultStackAddress[ 7 ]; /* When the following line is hit, the variables contain the register values. */ for( ;; ) ; } void MemManage_Handler(void) { while(1) { UARTprintf("\n Memory Management Handler Encountered - Looping Endlessly"); } } void BusFault_Handler(void) { while(1) { UARTprintf("\n Bus Fault Encountered - Looping Endlessly"); } } void UsageFault_Handler(void) { while(1) { UARTprintf("\n Usage Fault Encountered - Looping Endlessly"); } } /* void SVC_Handler(void) { while(1) { UARTprintf("\n SVC Handler Encountered - Looping Endlessly"); } } */ void DebugMon_Handler(void) { while(1) { UARTprintf("\n DebugMon Handler Encountered - Looping Endlessly"); } } /* void PendSV_Handler(void) { while(1) { UARTprintf("\n PendSV Handler Encountered - Looping Endlessly"); } } */ /*void SysTick_Handler(void) { while(1) { } } */ //***************************************************************************** // // Processor ends up here if an unexpected interrupt occurs or a specific // handler is not present in the application code. // //***************************************************************************** void IntDefaultHandler(void) { while(1) { UARTprintf("\n IntDefault Handler Encountered - Looping Endlessly"); } }