diff options
-rw-r--r-- | libmaple/exc.S | 40 | ||||
-rw-r--r-- | libmaple/util.c | 50 | ||||
-rw-r--r-- | libmaple/util.h | 1 |
3 files changed, 58 insertions, 33 deletions
diff --git a/libmaple/exc.S b/libmaple/exc.S index d01e3d5..823bbc5 100644 --- a/libmaple/exc.S +++ b/libmaple/exc.S @@ -48,40 +48,50 @@ .globl __exc_busfault .globl __exc_usagefault -/* TODO: Fix this up. */ +.code 16 .thumb_func __exc_nmi: mov r0, #1 + b __default_exc .thumb_func __exc_hardfault: mov r0, #2 + b __default_exc .thumb_func __exc_memmanage: mov r0, #3 + b __default_exc .thumb_func __exc_busfault: mov r0, #4 + b __default_exc .thumb_func __exc_usagefault: mov r0, #5 + b __default_exc -__default: - ldr r1, CPSR_MASK @ Set default CPSR - push {r1} - ldr r1, TARGET_PC @ Set target pc - push {r1} - sub sp, sp, #24 @ Don't care - ldr r1, EXC_RETURN @ Return to thread mode - mov lr, r1 - bx lr @ Exception exit - - .align 4 - CPSR_MASK: .word 0x61000000 - EXC_RETURN: .word 0xFFFFFFF9 - TARGET_PC: .word throb +.thumb_func +__default_exc: + ldr r2, NVIC_CCR @ Enabling returning to thread mode from an + mov r1 ,#1 @ exception. See flag NONEBASETHRDENA. + str r1, [r2] + cpsid i @ Disable global interrupts + ldr r1, CPSR_MASK @ Set default CPSR + push {r1} + ldr r1, TARGET_PC @ Set target pc + push {r1} + sub sp, sp, #24 @ Don't care + ldr r1, EXC_RETURN @ Return to thread mode + mov lr, r1 + bx lr @ Exception exit +.align 4 +CPSR_MASK: .word 0x61000000 +EXC_RETURN: .word 0xFFFFFFF9 +TARGET_PC: .word __error +NVIC_CCR: .word 0xE000ED14 @ NVIC configuration control register diff --git a/libmaple/util.c b/libmaple/util.c index 481cd60..3408a2e 100644 --- a/libmaple/util.c +++ b/libmaple/util.c @@ -49,14 +49,14 @@ #define HAVE_ERROR_LED #endif -/* Error assert + fade */ -void _fail(const char* file, int line, const char* exp) { - int32 slope = 1; - uint32 CC = 0x0000; - uint32 TOP_CNT = 0x02FF; - uint32 i = 0; - - /* Turn off interrupts */ +/** + * @brief Disables all peripheral interrupts except USB and fades the + * error LED. + * + * Called from exc.S with global interrupts disabled. + */ +void __error(void) { + /* Turn off peripheral interrupts */ nvic_irq_disable_all(); /* Turn off timers */ @@ -68,6 +68,24 @@ void _fail(const char* file, int line, const char* exp) { /* Turn off all usarts */ usart_disable_all(); + /* Turn the USB interrupt back on so the bootloader keeps on functioning */ + nvic_irq_enable(NVIC_INT_USBHP); + nvic_irq_enable(NVIC_INT_USBLP); + + /* Reenable global interrupts */ + nvic_globalirq_enable(); + throb(); +} + +/** + * @brief Prints an error message on a uart upon a failed assertion + * and error throbs. + * @param file Source file of failed assertion + * @param line Source line of failed assertion + * @param exp String representation of failed assertion + * @sideeffect Turns of all peripheral interrupts except USB. + */ +void _fail(const char* file, int line, const char* exp) { /* Initialize the error usart */ gpio_set_mode(ERROR_TX_PORT, ERROR_TX_PIN, GPIO_MODE_AF_OUTPUT_PP); usart_init(ERROR_USART_NUM, ERROR_USART_BAUD); @@ -82,19 +100,15 @@ void _fail(const char* file, int line, const char* exp) { usart_putc(ERROR_USART_NUM, '\n'); usart_putc(ERROR_USART_NUM, '\r'); -#ifdef HAVE_ERROR_LED - /* Turn on the error LED */ - gpio_set_mode(ERROR_LED_PORT, ERROR_LED_PIN, GPIO_MODE_OUTPUT_PP); -#endif - - /* Turn the USB interrupt back on so the bootloader keeps on functioning */ - nvic_irq_enable(NVIC_INT_USBHP); - nvic_irq_enable(NVIC_INT_USBLP); - /* Error fade */ - throb(); + __error(); } + +/** + * @brief Fades the error LED on and off + * @sideeffect Sets output push-pull on ERROR_LED_PIN. + */ void throb(void) { #ifdef HAVE_ERROR_LED int32 slope = 1; diff --git a/libmaple/util.h b/libmaple/util.h index 28ce970..fb524c2 100644 --- a/libmaple/util.h +++ b/libmaple/util.h @@ -79,6 +79,7 @@ extern "C"{ #define __write(reg, value) (*(volatile uint32*)(reg) = (value)) #define IS_POWER_OF_TWO(v) (v && !(v & (v - 1))) +void __error(void); void _fail(const char*, int, const char*); void throb(void); |