kylemanna
12/29/2016 - 4:06 AM

sdk.patch

diff --git a/source/main.c b/source/main.c
index 3282694..8ab5c8d 100644
--- a/source/main.c
+++ b/source/main.c
@@ -107,3 +107,78 @@ int main(void)
 		/* something to use as a breakpoint stop while looping */
 	}
 }
+
+__attribute__((naked))
+void HardFault_HandlerAsm(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( ".syntax unified\n"
+			"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"
+			".syntax divided\n") ;
+}
+
+/**
+* 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(unsigned long *hardfault_args){
+	volatile unsigned long stacked_r0 = ((unsigned long)hardfault_args[0]);
+	volatile unsigned long stacked_r1 = ((unsigned long)hardfault_args[1]);
+	volatile unsigned long stacked_r2 = ((unsigned long)hardfault_args[2]);
+	volatile unsigned long stacked_r3 = ((unsigned long)hardfault_args[3]);
+	volatile unsigned long stacked_r12 = ((unsigned long)hardfault_args[4]);
+	volatile unsigned long stacked_lr = ((unsigned long)hardfault_args[5]);
+	volatile unsigned long stacked_pc = ((unsigned long)hardfault_args[6]);
+	volatile unsigned long stacked_psr = ((unsigned long)hardfault_args[7]);
+
+	// Configurable Fault Status Register
+	// Consists of MMSR, BFSR and UFSR
+	volatile unsigned long _CFSR = (*((volatile unsigned long *)(0xE000ED28)));
+	// Hard Fault Status Register
+	volatile unsigned long _HFSR = (*((volatile unsigned long *)(0xE000ED2C)));
+	// Debug Fault Status Register
+	volatile unsigned long _DFSR = (*((volatile unsigned long *)(0xE000ED30)));
+	// Auxiliary Fault Status Register
+	volatile unsigned long _AFSR = (*((volatile unsigned long *)(0xE000ED3C)));
+	// Read the Fault Address Registers. These may not contain valid values.
+	// Check BFARVALID/MMARVALID to see if they are valid values
+	// MemManage Fault Address Register
+	volatile unsigned long _MMAR = (*((volatile unsigned long *)(0xE000ED34)));
+	// Bus Fault Address Register
+	volatile unsigned long _BFAR = (*((volatile unsigned long *)(0xE000ED38)));
+
+	/* Silence unused variable warnings */
+	(void)stacked_r0;
+	(void)stacked_r1;
+	(void)stacked_r2;
+	(void)stacked_r3;
+	(void)stacked_r12;
+	(void)stacked_lr;
+	(void)stacked_pc;
+	(void)stacked_psr;
+	(void)_CFSR;
+	(void)_HFSR;
+	(void)_DFSR;
+	(void)_AFSR;
+	(void)_BFAR;
+	(void)_MMAR;
+
+	__asm("BKPT #0\n") ; // Break into the debugger
+}
diff --git a/devices/MKL27Z4/gcc/startup_MKL27Z4.S b/devices/MKL27Z4/gcc/startup_MKL27Z4.S
index 961af8d..b249b4b 100644
--- a/devices/MKL27Z4/gcc/startup_MKL27Z4.S
+++ b/devices/MKL27Z4/gcc/startup_MKL27Z4.S
@@ -47,7 +47,7 @@ __isr_vector:
     .long   __StackTop                                      /* Top of Stack */
     .long   Reset_Handler                                   /* Reset Handler */
     .long   NMI_Handler                                     /* NMI Handler*/
-    .long   HardFault_Handler                               /* Hard Fault Handler*/
+    .long   HardFault_HandlerAsm                            /* Hard Fault Handler*/
     .long   0                                               /* Reserved*/
     .long   0                                               /* Reserved*/
     .long   0                                               /* Reserved*/