Merge pull request #11198 from SteveCEvans/sce_rc2
[betaflight.git] / src / main / fc / hardfaults.c
blob964523678de270df1f54938064cca5608143d3b7
1 /*
2 * This file is part of Cleanflight and Betaflight.
4 * Cleanflight and Betaflight are free software. You can redistribute
5 * this software and/or modify this software under the terms of the
6 * GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option)
8 * any later version.
10 * Cleanflight and Betaflight are distributed in the hope that they
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software.
18 * If not, see <http://www.gnu.org/licenses/>.
21 #include <stdbool.h>
22 #include <stdint.h>
24 #include "platform.h"
26 #include "drivers/light_led.h"
27 #include "drivers/time.h"
28 #include "drivers/transponder_ir.h"
30 #include "fc/init.h"
32 #include "flight/mixer.h"
34 #ifdef STM32F7
35 void MemManage_Handler(void)
37 LED2_ON;
39 // fall out of the sky
40 uint8_t requiredStateForMotors = SYSTEM_STATE_CONFIG_LOADED | SYSTEM_STATE_MOTORS_READY;
41 if ((systemState & requiredStateForMotors) == requiredStateForMotors) {
42 stopMotors();
45 #ifdef USE_TRANSPONDER
46 // prevent IR LEDs from burning out.
47 uint8_t requiredStateForTransponder = SYSTEM_STATE_CONFIG_LOADED | SYSTEM_STATE_TRANSPONDER_ENABLED;
48 if ((systemState & requiredStateForTransponder) == requiredStateForTransponder) {
49 transponderIrDisable();
51 #endif
53 LED1_OFF;
54 LED0_OFF;
56 while (1) {
57 delay(500);
58 LED2_TOGGLE;
59 delay(50);
60 LED2_TOGGLE;
63 #endif
65 #ifdef DEBUG_HARDFAULTS
66 //from: https://mcuoneclipse.com/2012/11/24/debugging-hard-faults-on-arm-cortex-m/
67 /**
68 * hard_fault_handler_c:
69 * This is called from the HardFault_HandlerAsm with a pointer the Fault stack
70 * as the parameter. We can then read the values from the stack and place them
71 * into local variables for ease of reading.
72 * We then read the various Fault Status and Address Registers to help decode
73 * cause of the fault.
74 * The function ends with a BKPT instruction to force control back into the debugger
76 void hard_fault_handler_c(unsigned long *hardfault_args)
78 volatile unsigned long stacked_r0 ;
79 volatile unsigned long stacked_r1 ;
80 volatile unsigned long stacked_r2 ;
81 volatile unsigned long stacked_r3 ;
82 volatile unsigned long stacked_r12 ;
83 volatile unsigned long stacked_lr ;
84 volatile unsigned long stacked_pc ;
85 volatile unsigned long stacked_psr ;
86 volatile unsigned long _CFSR ;
87 volatile unsigned long _HFSR ;
88 volatile unsigned long _DFSR ;
89 volatile unsigned long _AFSR ;
90 volatile unsigned long _BFAR ;
91 volatile unsigned long _MMAR ;
93 stacked_r0 = ((unsigned long)hardfault_args[0]) ;
94 stacked_r1 = ((unsigned long)hardfault_args[1]) ;
95 stacked_r2 = ((unsigned long)hardfault_args[2]) ;
96 stacked_r3 = ((unsigned long)hardfault_args[3]) ;
97 stacked_r12 = ((unsigned long)hardfault_args[4]) ;
98 stacked_lr = ((unsigned long)hardfault_args[5]) ;
99 stacked_pc = ((unsigned long)hardfault_args[6]) ;
100 stacked_psr = ((unsigned long)hardfault_args[7]) ;
102 // Configurable Fault Status Register
103 // Consists of MMSR, BFSR and UFSR
104 _CFSR = (*((volatile unsigned long *)(0xE000ED28))) ;
106 // Hard Fault Status Register
107 _HFSR = (*((volatile unsigned long *)(0xE000ED2C))) ;
109 // Debug Fault Status Register
110 _DFSR = (*((volatile unsigned long *)(0xE000ED30))) ;
112 // Auxiliary Fault Status Register
113 _AFSR = (*((volatile unsigned long *)(0xE000ED3C))) ;
115 // Read the Fault Address Registers. These may not contain valid values.
116 // Check BFARVALID/MMARVALID to see if they are valid values
117 // MemManage Fault Address Register
118 _MMAR = (*((volatile unsigned long *)(0xE000ED34))) ;
119 // Bus Fault Address Register
120 _BFAR = (*((volatile unsigned long *)(0xE000ED38))) ;
122 __asm("BKPT #0\n") ; // Break into the debugger
125 #else
126 void HardFault_Handler(void)
128 LED0_ON;
129 LED1_ON;
130 LED2_ON;
132 // fall out of the sky
133 uint8_t requiredStateForMotors = SYSTEM_STATE_CONFIG_LOADED | SYSTEM_STATE_MOTORS_READY;
134 if ((systemState & requiredStateForMotors) == requiredStateForMotors) {
135 stopMotors();
138 #ifdef USE_TRANSPONDER
139 // prevent IR LEDs from burning out.
140 uint8_t requiredStateForTransponder = SYSTEM_STATE_CONFIG_LOADED | SYSTEM_STATE_TRANSPONDER_ENABLED;
141 if ((systemState & requiredStateForTransponder) == requiredStateForTransponder) {
142 transponderIrDisable();
144 #endif
146 LED0_OFF;
147 LED1_OFF;
148 LED2_OFF;
150 while (1) {
151 delay(50);
152 LED0_TOGGLE;
153 LED1_TOGGLE;
154 LED2_TOGGLE;
157 #endif