diff --git a/src/generic/armcm_irq.c b/src/generic/armcm_irq.c new file mode 100644 index 00000000..64acdd89 --- /dev/null +++ b/src/generic/armcm_irq.c @@ -0,0 +1,58 @@ +// Definitions for irq enable/disable on ARM Cortex-M processors +// +// Copyright (C) 2017 Kevin O'Connor +// +// This file may be distributed under the terms of the GNU GPLv3 license. + +#include "irq.h" // irqstatus_t +#include "sched.h" // DECL_SHUTDOWN + +void +irq_disable(void) +{ + asm volatile("cpsid i" ::: "memory"); +} + +void +irq_enable(void) +{ + asm volatile("cpsie i" ::: "memory"); +} + +irqstatus_t +irq_save(void) +{ + irqstatus_t flag; + asm volatile("mrs %0, primask" : "=r" (flag) :: "memory"); + irq_disable(); + return flag; +} + +void +irq_restore(irqstatus_t flag) +{ + asm volatile("msr primask, %0" :: "r" (flag) : "memory"); +} + +// Clear the active irq if a shutdown happened in an irq handler +static void +clear_active_irq(void) +{ + uint32_t psr; + asm volatile("mrs %0, psr" : "=r" (psr)); + if (!(psr & 0x1ff)) + // Shutdown did not occur in an irq - nothing to do. + return; + // Clear active irq status + psr = 1<<24; // T-bit + uint32_t temp; + asm volatile( + " push { %1 }\n" + " adr %0, 1f\n" + " push { %0 }\n" + " push { r0, r1, r2, r3, r12, lr }\n" + " bx %2\n" + "1:\n" + : "=&r"(temp) : "r"(psr), "r"(0xfffffff9) : "cc"); +} +DECL_SHUTDOWN(clear_active_irq); diff --git a/src/sam3x8e/Makefile b/src/sam3x8e/Makefile index 48acfb5c..bf38846f 100644 --- a/src/sam3x8e/Makefile +++ b/src/sam3x8e/Makefile @@ -15,7 +15,8 @@ LDFLAGS-y += -T lib/cmsis-sam3x8e/source/gcc/sam3x8e_flash.ld LDFLAGS-y += --specs=nano.specs --specs=nosys.specs # Add source files -src-y += sam3x8e/main.c sam3x8e/timer.c sam3x8e/gpio.c generic/crc16_ccitt.c +src-y += sam3x8e/main.c sam3x8e/timer.c sam3x8e/gpio.c +src-y += generic/crc16_ccitt.c generic/armcm_irq.c src-y += ../lib/cmsis-sam3x8e/source/system_sam3xa.c src-y += ../lib/cmsis-sam3x8e/source/gcc/startup_sam3xa.c src-$(CONFIG_SERIAL) += sam3x8e/serial.c diff --git a/src/sam3x8e/gpio.c b/src/sam3x8e/gpio.c index ab7853c2..9b88a0ce 100644 --- a/src/sam3x8e/gpio.c +++ b/src/sam3x8e/gpio.c @@ -6,10 +6,10 @@ #include // uint32_t #include "autoconf.h" // CONFIG_CLOCK_FREQ +#include "board/irq.h" // irq_save #include "command.h" // shutdown #include "compiler.h" // ARRAY_SIZE #include "gpio.h" // gpio_out_setup -#include "irq.h" // irq_save #include "sam3x8e.h" // Pio #include "sched.h" // sched_shutdown diff --git a/src/sam3x8e/irq.h b/src/sam3x8e/irq.h deleted file mode 100644 index 26303195..00000000 --- a/src/sam3x8e/irq.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef __SAM3X8E_IRQ_H -#define __SAM3X8E_IRQ_H -// Definitions for irq enable/disable on ARM Cortex-M - -static inline void irq_disable(void) { - asm volatile("cpsid i" ::: "memory"); -} - -static inline void irq_enable(void) { - asm volatile("cpsie i" ::: "memory"); -} - -typedef unsigned long irqstatus_t; - -static inline irqstatus_t irq_save(void) { - irqstatus_t flag; - asm volatile("mrs %0, primask" : "=r" (flag) :: "memory"); - irq_disable(); - return flag; -} - -static inline void irq_restore(irqstatus_t flag) { - asm volatile("msr primask, %0" :: "r" (flag) : "memory"); -} - -#endif // irq.h diff --git a/src/sam3x8e/main.c b/src/sam3x8e/main.c index 3cf1b97c..9fa27297 100644 --- a/src/sam3x8e/main.c +++ b/src/sam3x8e/main.c @@ -4,7 +4,7 @@ // // This file may be distributed under the terms of the GNU GPLv3 license. -#include "board/misc.h" // console_get_input +#include "board/misc.h" // alloc_maxsize #include "sam3x8e.h" // WDT #include "sched.h" // sched_main @@ -29,34 +29,6 @@ watchdog_init(void) DECL_INIT(watchdog_init); -/**************************************************************** - * irq clearing on fault - ****************************************************************/ - -// Clear the active irq if a shutdown happened in an irq handler -static void -clear_active_irq(void) -{ - uint32_t psr; - asm volatile("mrs %0, psr" : "=r" (psr)); - if (!(psr & 0x1ff)) - // Shutdown did not occur in an irq - nothing to do. - return; - // Clear active irq status - psr = 1<<24; // T-bit - uint32_t temp; - asm volatile( - " push { %1 }\n" - " adr %0, 1f\n" - " push { %0 }\n" - " push { r0, r1, r2, r3, r12, lr }\n" - " bx %2\n" - "1:\n" - : "=&r"(temp) : "r"(psr), "r"(0xfffffff9) : "cc"); -} -DECL_SHUTDOWN(clear_active_irq); - - /**************************************************************** * misc functions ****************************************************************/ diff --git a/src/sam3x8e/serial.c b/src/sam3x8e/serial.c index 3532d5f3..9203385d 100644 --- a/src/sam3x8e/serial.c +++ b/src/sam3x8e/serial.c @@ -8,11 +8,11 @@ #include "autoconf.h" // CONFIG_SERIAL_BAUD #include "board/gpio.h" // gpio_peripheral #include "board/io.h" // readb +#include "board/irq.h" // irq_save #include "board/misc.h" // console_get_input #include "command.h" // DECL_CONSTANT #include "sam3x8e.h" // UART #include "sched.h" // DECL_INIT -#include "irq.h" // irq_save #define SERIAL_BUFFER_SIZE 96 static char receive_buf[SERIAL_BUFFER_SIZE]; diff --git a/src/sam3x8e/timer.c b/src/sam3x8e/timer.c index 667e9b65..bab2512f 100644 --- a/src/sam3x8e/timer.c +++ b/src/sam3x8e/timer.c @@ -5,9 +5,9 @@ // This file may be distributed under the terms of the GNU GPLv3 license. #include "autoconf.h" // CONFIG_CLOCK_FREQ +#include "board/irq.h" // irq_disable #include "board/misc.h" // timer_from_us #include "command.h" // shutdown -#include "irq.h" // irq_disable #include "sam3x8e.h" // TC0 #include "sched.h" // sched_timer_kick