voidFLASH_ECC_Fault_Handler(void) { __asm volatile( "MOVS R0, #4 \n"// Load immediate value 4 into R0 to test the LR bit. "MOV R1, LR \n"// Copy Link Register (LR) into R1. "TST R1, R0 \n"// Test if bit2 of LR is set. "BNE get_psp \n"// If bit2 is set, use Process Stack Pointer (PSP). "MRS R0, MSP \n"// Otherwise, load Main Stack Pointer (MSP) into R0. "B c_handler \n"// Branch to call the C fault handler. "get_psp: \n" "MRS R0, PSP \n"// Load Process Stack Pointer (PSP) into R0. "c_handler: \n" "LDR R2, =FLASH_ECC_Fault_Handler_C \n"// Load to FLASH_ECC_Fault_Handler_C to R2 "BX R2 \n"// jump address in R2 ); }
/* Clear ECC error flag, EFM->ECCERR_ADDR will be cleared at the same time. */ EFM->STS = EFM_STS_UNRECOVERR_MASK;
/* The sector containing the ECC error address MUST be erased to fix the error. */ if (error_addr >= TEST_DATA_START_ADDR && error_addr <= TEST_DATA_END_ADDR) { FLASH_DRV_EraseSector(FLASH_INST, error_addr & ~(FEATURE_EFM_MAIN_ARRAY_SECTOR_SIZE - 1), FEATURE_EFM_MAIN_ARRAY_SECTOR_SIZE); PRINTF("Erased the sector containing the ECC error address.\r\n"); } else { // Do nothing for the location of the program } }
voidHardFault_Callback(hw_stackframe_t *fault_stack) { /* Note: The handling of your own hardfault can be done here. The following code is just an example of how to access the fault stack. */ /* Note: Debug output inserted just for demo clarity. */ PRINTF("HardFault Callback. Fault Stack:\r\n"); PRINTF("R0: 0x%x\r\n", fault_stack->r0); PRINTF("R1: 0x%x\r\n", fault_stack->r1); PRINTF("R2: 0x%x\r\n", fault_stack->r2); PRINTF("R3: 0x%x\r\n", fault_stack->r3); PRINTF("R12: 0x%x\r\n", fault_stack->r12); PRINTF("LR: 0x%x\r\n", fault_stack->lr); PRINTF("PC: 0x%x\r\n", fault_stack->pc); PRINTF("PSR: 0x%x\r\n", fault_stack->psr);
/* Reset for default exception handling in HardFault */ PRINTF("System Software Reset.\r\n"); SystemSoftwareReset(); }