From 7fcb2b718ec7149976b79333ded54d28a6594630 Mon Sep 17 00:00:00 2001 From: Kaspar Schleiser Date: Mon, 14 Sep 2015 00:27:27 +0200 Subject: [PATCH] cpu: atmega: implement irq_arch_in --- cpu/atmega2560/periph/gpio.c | 2 ++ cpu/atmega2560/periph/uart.c | 8 ++++++++ cpu/atmega_common/include/cpu.h | 28 ++++++++++++++++++++++++++-- cpu/atmega_common/irq_arch.c | 9 ++++----- 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/cpu/atmega2560/periph/gpio.c b/cpu/atmega2560/periph/gpio.c index 275e1dc7eb..610fa9936e 100644 --- a/cpu/atmega2560/periph/gpio.c +++ b/cpu/atmega2560/periph/gpio.c @@ -215,7 +215,9 @@ void gpio_write(gpio_t pin, int value) static inline void irq_handler(uint8_t pin_num) { + __enter_isr(); config[pin_num].cb(config[pin_num].arg); + __exit_isr(); } ISR(INT0_vect, ISR_BLOCK) diff --git a/cpu/atmega2560/periph/uart.c b/cpu/atmega2560/periph/uart.c index b68aeb1194..e2a1643e5c 100644 --- a/cpu/atmega2560/periph/uart.c +++ b/cpu/atmega2560/periph/uart.c @@ -276,44 +276,52 @@ int uart_write_blocking(uart_t uart, char data) #if UART_0_EN ISR(USART0_RX_vect, ISR_BLOCK) { + __enter_isr(); config[UART_0].rx_cb(config[UART_0].arg, UART0_DATA_REGISTER); if (sched_context_switch_request) { thread_yield(); } + __exit_isr(); } #endif /* UART_0_EN */ #if UART_1_EN ISR(USART1_RX_vect, ISR_BLOCK) { + __enter_isr(); config[UART_1].rx_cb(config[UART_1].arg, UART0_DATA_REGISTER); if (sched_context_switch_request) { thread_yield(); } + __exit_isr(); } #endif /* UART_1_EN */ #if UART_1_EN ISR(USART2_RX_vect, ISR_BLOCK) { + __enter_isr(); config[UART_2].rx_cb(config[UART_2].arg, UART0_DATA_REGISTER); if (sched_context_switch_request) { thread_yield(); } + __exit_isr(); } #endif /* UART_2_EN */ #if UART_2_EN ISR(USART2_RX_vect, ISR_BLOCK) { + __enter_isr(); config[UART_3].rx_cb(config[UART_3].arg, UART0_DATA_REGISTER); if (sched_context_switch_request) { thread_yield(); } + __exit_isr(); } #endif /* UART_3_EN */ #endif /* UART_0_EN || UART_1_EN |UART_2_EN| UART3 */ diff --git a/cpu/atmega_common/include/cpu.h b/cpu/atmega_common/include/cpu.h index 5af3727a4c..b7a83a9557 100644 --- a/cpu/atmega_common/include/cpu.h +++ b/cpu/atmega_common/include/cpu.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2014 Freie Universität Berlin, Hinnerk van Bruinehsen + * Copyright (C) 2015 Kaspar Schleiser + * 2014 Freie Universität Berlin, Hinnerk van Bruinehsen * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -20,14 +21,16 @@ * @author Stefan Pfeiffer * @author Hauke Petersen * @author Hinnerk van Bruinehsen + * @author Kaspar Schleiser */ #ifndef __ATMEGA_COMMON_H #define __ATMEGA_COMMON_H #include -#include +#include +#include #include "cpu_conf.h" /** @@ -43,6 +46,27 @@ extern "C" { #define eINT enableIRQ #define dINT disableIRQ +/** + * @brief global in-ISR state variable + */ +extern volatile uint8_t __in_isr; + +/** + * @brief Flag entering of an ISR + */ +static inline void __enter_isr(void) +{ + __in_isr = 1; +} + +/** + * @brief Flag exiting of an ISR + */ +static inline void __exit_isr(void) +{ + __in_isr = 0; +} + /** * @brief Initialization of the CPU */ diff --git a/cpu/atmega_common/irq_arch.c b/cpu/atmega_common/irq_arch.c index f494aff41f..61747c4b1d 100644 --- a/cpu/atmega_common/irq_arch.c +++ b/cpu/atmega_common/irq_arch.c @@ -20,6 +20,7 @@ */ #include +#include #include "arch/irq_arch.h" #include "cpu.h" @@ -29,6 +30,8 @@ static uint8_t __get_interrupt_state(void); static void __set_interrupt_state(uint8_t state); +volatile uint8_t __in_isr = 0; + __attribute__((always_inline)) static inline uint8_t __get_interrupt_state(void) { uint8_t sreg; @@ -84,9 +87,5 @@ void irq_arch_restore(unsigned int state) */ int irq_arch_in(void) { - /* - * TODO: find a way to implement this function (e.g. a static variable dis- or - * set and unset in each ISR) - */ - return 0; + return __in_isr; }