firmware: enable fault handler that blink LEDs

In order to facilitate debugging, this patch implements fault handlers
that blink all three LEDs a certain number of times based on the nature
of the fault. The blinking pattern indicates which of the four major
fault types was triggered along with the subtype (example: usage fault
with divide by zero will blink five times followed by one).
This commit is contained in:
Mike Ryan
2019-12-01 14:47:52 -08:00
parent fdf2700657
commit f2c5217c5d
4 changed files with 123 additions and 4 deletions
+1
View File
@@ -18,6 +18,7 @@ SRC = $(TARGET).c \
ego.c \
debug_uart.c \
tinyprintf.c \
fault.c \
$(LIBS_PATH)/usb_serial.c \
$(LIBS_PATH)/serial_fifo.c \
$(LIBS_PATH)/LPC17xx_Startup.c \
+3
View File
@@ -2569,6 +2569,9 @@ void led_specan()
int main()
{
// enable all fault handlers (see fault.c)
SCB_SHCSR = (1 << 18) | (1 << 17) | (1 << 16);
ubertooth_init();
clkn_init();
ubertooth_usb_init(vendor_request_handler);
+115
View File
@@ -0,0 +1,115 @@
/*
* Copyright 2019 Mike Ryan
*
* This file is part of Project Ubertooth and is released under the
* terms of the GPL. Refer to COPYING for more information.
*/
#include "ubertooth.h"
// delay for about 30 ms (very rough)
static void delay_30ms(void) {
volatile int i;
for (i = 0; i < 3000000; ++i)
;
}
// flash LEDs a certain number of times
static void flash_leds(int count) {
int i;
for (i = 0; i < count; ++i) {
USRLED_SET;
RXLED_SET;
TXLED_SET;
delay_30ms();
USRLED_CLR;
RXLED_CLR;
TXLED_CLR;
delay_30ms();
}
delay_30ms();
delay_30ms();
delay_30ms();
}
void HardFault_Handler(void) {
uint32_t val = SCB_HFSR;
while (1) {
flash_leds(2);
if (val & (1 << 1)) {
flash_leds(3); // vector table read
} else if (val & (1 << 30)) {
flash_leds(4); // forced (should never happen)
}
delay_30ms();
delay_30ms();
delay_30ms();
}
}
void MemManagement_Handler(void) {
int i;
int offset[5] = { 7, 4, 3, 1, 0 };
uint8_t mmsr = SCB_MMSR;
while (1) {
flash_leds(3);
for (i = 0; i < 5; ++i) {
if (mmsr & (1 << offset[i])) {
flash_leds(i+1);
break;
}
}
delay_30ms();
delay_30ms();
delay_30ms();
}
}
void BusFault_Handler(void) {
int i;
int offset[6] = { 7, 4, 3, 2, 1, 0 };
uint8_t bfsr = SCB_BFSR;
while (1) {
flash_leds(4);
for (i = 0; i < 6; ++i) {
if (bfsr & (1 << offset[i])) {
flash_leds(i+1);
break;
}
}
delay_30ms();
delay_30ms();
delay_30ms();
}
}
void UsageFault_Handler(void) {
int i;
int offset[6] = { 9, 8, 3, 2, 1, 0 };
uint16_t ufsr = SCB_UFSR;
while (1) {
flash_leds(5);
for (i = 0; i < 6; ++i) {
if (ufsr & (1 << offset[i])) {
flash_leds(i+1);
break;
}
}
delay_30ms();
delay_30ms();
delay_30ms();
}
}
+4 -4
View File
@@ -575,11 +575,11 @@
#define SCB_SHPR1 LPC17_REG(0xE000ED18) /* System Handler Priority - register 1 */
#define SCB_SHPR2 LPC17_REG(0xE000ED1C) /* System Handler Priority - register 2 */
#define SCB_SHPR3 LPC17_REG(0xE000ED20) /* System Handler Priority - register 3 */
#define SCB_SHCRS LPC17_REG(0xE000ED24) /* System Handler Control and State Register */
#define SCB_SHCSR LPC17_REG(0xE000ED24) /* System Handler Control and State Register */
#define SCB_CFSR LPC17_REG(0xE000ED28) /* Configurable Fault Status Register */
//#define SCB_MMSR LPC17_REG(0xE000ED28) /* Memory Management Fault Status Register (CFSR sub-register) */
//#define SCB_BFSR LPC17_REG(0xE000ED29) /* Bus Fault Status Register (CFSR sub-register) */
//#define SCB_UFSR LPC17_REG(0xE000ED2A) /* Usage Fault Status Register (CFSR sub-register) */
#define SCB_MMSR LPC17_REG8(0xE000ED28) /* Memory Management Fault Status Register (CFSR sub-register) */
#define SCB_BFSR LPC17_REG8(0xE000ED29) /* Bus Fault Status Register (CFSR sub-register) */
#define SCB_UFSR LPC17_REG16(0xE000ED2A) /* Usage Fault Status Register (CFSR sub-register) */
#define SCB_HFSR LPC17_REG(0xE000ED2C) /* Hard Fault Status Register */
#define SCB_MMFAR LPC17_REG(0xE000ED34) /* Memory Management Fault Address Register */
#define SCB_BFAR LPC17_REG(0xE000ED38) /* Bus Fault Address Register */