-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHardfaultTrace.c
More file actions
93 lines (87 loc) · 2.81 KB
/
Copy pathHardfaultTrace.c
File metadata and controls
93 lines (87 loc) · 2.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include "HALAL/HardFault/HardfaultTrace.h"
#ifdef NUCLEO
#define REPS 200000
#endif
#ifdef BOARD
#define REPS 800000 // Three times faster because the board frequency
#endif
#ifndef HARDFAULT_BOOT_BLINK_CYCLES
#define HARDFAULT_BOOT_BLINK_CYCLES 8U
#endif
#ifndef HARDFAULT_CHECK_BLOCKING
#define HARDFAULT_CHECK_BLOCKING 1
#endif
extern GPIO_TypeDef* ports_hard_fault[];
extern uint16_t pins_hard_fault[];
extern uint8_t hard_fault_leds_count;
extern uint8_t _hf_log[];
static void LED_Blink();
static void LED_init(void);
static void EnableGPIOClock(GPIO_TypeDef* port);
static void InitGPIO_Output(GPIO_TypeDef* port, uint16_t pin);
static void delay();
__attribute__((optimize("O0"))) static void delay() {
for (volatile uint64_t i = 0; i < REPS; i++) {
__NOP();
}
}
static void LED_Blink() {
for (volatile int i = 0; i < hard_fault_leds_count; i++) {
LL_GPIO_TogglePin(ports_hard_fault[i], pins_hard_fault[i]);
}
delay();
}
static void LED_init(void) {
for (int i = 0; i < hard_fault_leds_count; i++) {
EnableGPIOClock(ports_hard_fault[i]);
InitGPIO_Output(ports_hard_fault[i], pins_hard_fault[i]);
}
}
void Hard_fault_check(void) {
if (*(volatile uint32_t*)HF_FLASH_ADDR == HF_FLAG_VALUE) {
volatile HardFaultLog log;
memcpy(&log, (void*)HF_FLASH_ADDR, sizeof(HardFaultLog));
#ifdef DEBUG
__asm__ __volatile__("bkpt 1");
#endif
if (hard_fault_leds_count == 0U) {
return;
}
LED_init();
#if HARDFAULT_CHECK_BLOCKING
while (1) {
LED_Blink();
}
#else
for (uint32_t i = 0; i < HARDFAULT_BOOT_BLINK_CYCLES; i++) {
LED_Blink();
}
#endif
}
}
static void EnableGPIOClock(GPIO_TypeDef* port) {
if (port == GPIOA)
LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOA);
else if (port == GPIOB)
LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOB);
else if (port == GPIOC)
LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOC);
else if (port == GPIOD)
LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOD);
else if (port == GPIOE)
LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOE);
else if (port == GPIOF)
LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOF);
else if (port == GPIOG)
LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOG);
else if (port == GPIOJ)
LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOJ);
else if (port == GPIOK)
LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOK);
}
static void InitGPIO_Output(GPIO_TypeDef* port, uint16_t pin) {
LL_GPIO_SetPinMode(port, pin, LL_GPIO_MODE_OUTPUT);
LL_GPIO_SetPinOutputType(port, pin, LL_GPIO_OUTPUT_PUSHPULL);
LL_GPIO_SetPinSpeed(port, pin, LL_GPIO_SPEED_FREQ_LOW);
LL_GPIO_SetPinPull(port, pin, LL_GPIO_PULL_NO);
}