CF/BF - Fix HoTT telemetry.
[betaflight.git] / src / main / fc / fc_hardfaults.c
blob5164cc00ff2e865166720db95d68fa87966472a1
1 /*
2 * This file is part of Cleanflight.
4 * Cleanflight is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * Cleanflight is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
18 #include <stdbool.h>
19 #include <stdint.h>
21 #include "platform.h"
23 #include "drivers/light_led.h"
24 #include "drivers/system.h"
25 #include "drivers/transponder_ir.h"
27 #include "fc/fc_init.h"
29 #include "flight/mixer.h"
31 #ifdef DEBUG_HARDFAULTS
32 //from: https://mcuoneclipse.com/2012/11/24/debugging-hard-faults-on-arm-cortex-m/
33 /**
34 * hard_fault_handler_c:
35 * This is called from the HardFault_HandlerAsm with a pointer the Fault stack
36 * as the parameter. We can then read the values from the stack and place them
37 * into local variables for ease of reading.
38 * We then read the various Fault Status and Address Registers to help decode
39 * cause of the fault.
40 * The function ends with a BKPT instruction to force control back into the debugger
42 void hard_fault_handler_c(unsigned long *hardfault_args)
44 volatile unsigned long stacked_r0 ;
45 volatile unsigned long stacked_r1 ;
46 volatile unsigned long stacked_r2 ;
47 volatile unsigned long stacked_r3 ;
48 volatile unsigned long stacked_r12 ;
49 volatile unsigned long stacked_lr ;
50 volatile unsigned long stacked_pc ;
51 volatile unsigned long stacked_psr ;
52 volatile unsigned long _CFSR ;
53 volatile unsigned long _HFSR ;
54 volatile unsigned long _DFSR ;
55 volatile unsigned long _AFSR ;
56 volatile unsigned long _BFAR ;
57 volatile unsigned long _MMAR ;
59 stacked_r0 = ((unsigned long)hardfault_args[0]) ;
60 stacked_r1 = ((unsigned long)hardfault_args[1]) ;
61 stacked_r2 = ((unsigned long)hardfault_args[2]) ;
62 stacked_r3 = ((unsigned long)hardfault_args[3]) ;
63 stacked_r12 = ((unsigned long)hardfault_args[4]) ;
64 stacked_lr = ((unsigned long)hardfault_args[5]) ;
65 stacked_pc = ((unsigned long)hardfault_args[6]) ;
66 stacked_psr = ((unsigned long)hardfault_args[7]) ;
68 // Configurable Fault Status Register
69 // Consists of MMSR, BFSR and UFSR
70 _CFSR = (*((volatile unsigned long *)(0xE000ED28))) ;
72 // Hard Fault Status Register
73 _HFSR = (*((volatile unsigned long *)(0xE000ED2C))) ;
75 // Debug Fault Status Register
76 _DFSR = (*((volatile unsigned long *)(0xE000ED30))) ;
78 // Auxiliary Fault Status Register
79 _AFSR = (*((volatile unsigned long *)(0xE000ED3C))) ;
81 // Read the Fault Address Registers. These may not contain valid values.
82 // Check BFARVALID/MMARVALID to see if they are valid values
83 // MemManage Fault Address Register
84 _MMAR = (*((volatile unsigned long *)(0xE000ED34))) ;
85 // Bus Fault Address Register
86 _BFAR = (*((volatile unsigned long *)(0xE000ED38))) ;
88 __asm("BKPT #0\n") ; // Break into the debugger
91 #else
92 void HardFault_Handler(void)
94 LED2_ON;
96 #ifndef USE_OSD_SLAVE
97 // fall out of the sky
98 uint8_t requiredStateForMotors = SYSTEM_STATE_CONFIG_LOADED | SYSTEM_STATE_MOTORS_READY;
99 if ((systemState & requiredStateForMotors) == requiredStateForMotors) {
100 stopMotors();
102 #endif
104 #ifdef TRANSPONDER
105 // prevent IR LEDs from burning out.
106 uint8_t requiredStateForTransponder = SYSTEM_STATE_CONFIG_LOADED | SYSTEM_STATE_TRANSPONDER_ENABLED;
107 if ((systemState & requiredStateForTransponder) == requiredStateForTransponder) {
108 transponderIrDisable();
110 #endif
112 LED1_OFF;
113 LED0_OFF;
115 while (1) {
116 #ifdef LED2
117 delay(50);
118 LED2_TOGGLE;
119 #endif
122 #endif