diff options
Diffstat (limited to 'c/src/lib/libbsp/arm/atsam/libraries/libchip/source/exceptions.c')
-rw-r--r-- | c/src/lib/libbsp/arm/atsam/libraries/libchip/source/exceptions.c | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/arm/atsam/libraries/libchip/source/exceptions.c b/c/src/lib/libbsp/arm/atsam/libraries/libchip/source/exceptions.c new file mode 100644 index 0000000000..cc5329f1da --- /dev/null +++ b/c/src/lib/libbsp/arm/atsam/libraries/libchip/source/exceptions.c @@ -0,0 +1,214 @@ +/* ---------------------------------------------------------------------------- */ +/* Atmel Microcontroller Software Support */ +/* SAM Software Package License */ +/* ---------------------------------------------------------------------------- */ +/* Copyright (c) 2015, Atmel Corporation */ +/* */ +/* All rights reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following condition is met: */ +/* */ +/* - Redistributions of source code must retain the above copyright notice, */ +/* this list of conditions and the disclaimer below. */ +/* */ +/* Atmel's name may not be used to endorse or promote products derived from */ +/* this software without specific prior written permission. */ +/* */ +/* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR */ +/* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE */ +/* DISCLAIMED. IN NO EVENT SHALL ATMEL 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. */ +/* ---------------------------------------------------------------------------- */ + +/** + * \file + * This file contains the default exception handlers. + * + * \note + * The exception handler has weak aliases. + * As they are weak aliases, any function with the same name will override + * this definition. + */ + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "chip.h" + +/*---------------------------------------------------------------------------- + * Exported functions + *----------------------------------------------------------------------------*/ + +/** + * \brief Default NMI interrupt handler. + */ +void NMI_Handler(void) +{ + printf("\r\n-E- Enter NMI_Handler!"); + + while (1); +} + +/** + * \brief This function back trace the stack to give exact address where fault + happened +**/ +__STATIC_INLINE uint32_t StackUnwind(void) +{ + uint32_t Fault_Add; + +#if defined (__CC_ARM) + uint32_t temp; + __ASM("mrs temp, msp "); + __ASM{ ldr Fault_Add, [temp, #28]} +#else + __ASM("mrs r0, msp "); + __ASM("ldr %0, [r0,#28]" : "=r" (Fault_Add)); +#endif + return Fault_Add; +} + +/** + * \brief If Other Faults are enabled then HardFault error will look for those + * errors to give more detail about fault +**/ +static void HardFault_reason(void) +{ + uint32_t CFSRValue; + TRACE_DEBUG("In Hard Fault Handler\n\r"); + TRACE_DEBUG("SCB->HFSR = 0x%08x\n\r", SCB->HFSR); + + if ((SCB->HFSR & SCB_HFSR_DEBUGEVT_Msk)) { + TRACE_DEBUG("Debug Event Hard Fault\n\r"); + TRACE_DEBUG("SCB->DFSR = 0x%08x\n", SCB->DFSR); + } + + if ((SCB->HFSR & SCB_HFSR_VECTTBL_Msk)) { + TRACE_DEBUG("Fault was due to vector table read on \ + exception processing\n\r"); + } + + // Forced HardFault + if ((SCB->HFSR & SCB_HFSR_FORCED_Msk)) { + TRACE_DEBUG("Forced Hard Fault\n\r"); + TRACE_DEBUG("SCB->CFSR = 0x%08x\n\r", SCB->CFSR); + + // Usage Fault + if ((SCB->CFSR & SCB_CFSR_USGFAULTSR_Msk)) { + CFSRValue = SCB->CFSR; + TRACE_DEBUG("Usage fault: "); + CFSRValue >>= SCB_CFSR_USGFAULTSR_Pos; + + if ((CFSRValue & (1 << 9))) + TRACE_DEBUG("Divide by zero\n\r"); + + if ((CFSRValue & (1 << 8))) + TRACE_DEBUG("Unaligned access error\n\r"); + + if ((CFSRValue & (1 << 3))) + TRACE_DEBUG("Coprocessor access error\n\r"); + + if ((CFSRValue & (1 << 2))) + TRACE_DEBUG("Integrity check error on EXC_RETURN\n\r"); + } + + // Bus Fault + if ((SCB->CFSR & SCB_CFSR_BUSFAULTSR_Msk)) { + CFSRValue = SCB->CFSR; + TRACE_DEBUG("Bus fault: "); + CFSRValue >>= SCB_CFSR_BUSFAULTSR_Pos; + + if ((CFSRValue & (1 << 7)) && (CFSRValue & (1 << 1))) { + TRACE_DEBUG("Precise data access error. Bus Fault Address \ + Register is: %x \n\r", SCB->BFAR); + } + + if ((CFSRValue & (1 << 4))) + TRACE_DEBUG("Bus fault has occurred on exception entry\n\r"); + + if ((CFSRValue & (1 << 3))) + TRACE_DEBUG("bus fault has occurred on exception return\n\r"); + + if ((CFSRValue & (1 << 2))) + TRACE_DEBUG("Imprecise data access error\n\r"); + + if ((CFSRValue & (1 << 0))) { + TRACE_DEBUG("This bit indicates a bus fault on an instruction \ + pre-fetch. \n\r"); + } + } + } + + // MemoryFault + if ((SCB->CFSR & SCB_CFSR_MEMFAULTSR_Msk)) { + CFSRValue = SCB->CFSR; + TRACE_DEBUG("Memory fault: "); + CFSRValue >>= SCB_CFSR_MEMFAULTSR_Pos; + + if ((CFSRValue & (1 << 9)) != 0) + TRACE_DEBUG("Divide by zero\n\r"); + } + + __ISB(); + __DMB(); + __ASM volatile("BKPT #01"); +} +/** + * \brief Default HardFault interrupt handler. + */ + +void HardFault_Handler(void) +{ + printf("\n\rHardFault at address 0X%x\n\r", (int)StackUnwind()); + __ISB(); + __DMB(); + HardFault_reason(); +} + +#ifndef MPU_EXAMPLE_FEATURE +/** + * \brief Default MemManage interrupt handler. + */ +void MemManage_Handler(void) +{ + printf("\n\rMemoryMemFault (MPU fault) at address 0X%x\n\r", + (int)StackUnwind()); + __ISB(); + __DMB(); + __ASM volatile("BKPT #01"); +} +#endif + +/** + * \brief Default BusFault interrupt handler. + */ +void BusFault_Handler(void) +{ + __ASM("nop"); + __ASM("nop"); + printf("\n\rBus Fault at address 0X%x\n\r", (int)StackUnwind()); + + __ISB(); + __DMB(); + __ASM volatile("BKPT #01"); +} + +/** + * \brief Default UsageFault interrupt handler. + */ +void UsageFault_Handler(void) +{ + printf("\r\nUsage fault at address 0X%x", (int)StackUnwind()); + + __ISB(); + __DMB(); + __ASM volatile("BKPT #01"); +} |