From f2c5217c5de9bf317063dd03fecfaad165ffeb04 Mon Sep 17 00:00:00 2001 From: Mike Ryan Date: Sun, 1 Dec 2019 14:47:52 -0800 Subject: [PATCH] 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). --- firmware/bluetooth_rxtx/Makefile | 1 + firmware/bluetooth_rxtx/bluetooth_rxtx.c | 3 + firmware/bluetooth_rxtx/fault.c | 115 +++++++++++++++++++++++ firmware/common/lpc17.h | 8 +- 4 files changed, 123 insertions(+), 4 deletions(-) create mode 100644 firmware/bluetooth_rxtx/fault.c diff --git a/firmware/bluetooth_rxtx/Makefile b/firmware/bluetooth_rxtx/Makefile index 82d5434..d940d8b 100644 --- a/firmware/bluetooth_rxtx/Makefile +++ b/firmware/bluetooth_rxtx/Makefile @@ -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 \ diff --git a/firmware/bluetooth_rxtx/bluetooth_rxtx.c b/firmware/bluetooth_rxtx/bluetooth_rxtx.c index 288212c..1fce5e4 100644 --- a/firmware/bluetooth_rxtx/bluetooth_rxtx.c +++ b/firmware/bluetooth_rxtx/bluetooth_rxtx.c @@ -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); diff --git a/firmware/bluetooth_rxtx/fault.c b/firmware/bluetooth_rxtx/fault.c new file mode 100644 index 0000000..2583a13 --- /dev/null +++ b/firmware/bluetooth_rxtx/fault.c @@ -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(); + } +} diff --git a/firmware/common/lpc17.h b/firmware/common/lpc17.h index 5f0fbae..1a92e59 100644 --- a/firmware/common/lpc17.h +++ b/firmware/common/lpc17.h @@ -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 */