/* * Copyright (C) 2014 Freie Universität Berlin, Hinnerk van Bruinehsen * 2018 RWTH Aachen, Josua Arndt * 2020 Otto-von-Guericke-Universität Magdeburg * 2021 Gerson Fernando Budke * * 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 * directory for more details. */ /** * @ingroup cpu_avr8_common * @{ * * @file * @brief Implementation of the kernels irq interface * * @author Hauke Petersen * @author Hinnerk van Bruinehsen * @author Josua Arndt * @author Marian Buschsieweke * @author Gerson Fernando Budke * */ #ifndef IRQ_ARCH_H #define IRQ_ARCH_H #include #include #include #include "cpu.h" #ifdef __cplusplus extern "C" { #endif /** * @brief Disable all maskable interrupts */ __attribute__((always_inline)) static inline unsigned int irq_disable(void) { uint8_t mask; __asm__ volatile( "in %[dest], __SREG__" "\n\t" "cli" "\n\t" : [dest] "=r"(mask) : /* no inputs */ : "memory" ); return mask; } /** * @brief Enable all maskable interrupts */ __attribute__((always_inline)) static inline unsigned int irq_enable(void) { uint8_t mask; __asm__ volatile( "in %[dest], __SREG__" "\n\t" "sei" "\n\t" : [dest] "=r"(mask) : /* no inputs */ : "memory" ); return mask; } /** * @brief Restore the state of the IRQ flags */ __attribute__((always_inline)) static inline void irq_restore(unsigned int _state) { uint8_t state = (uint8_t)_state; /* * Implementation in pseudo-code: * * disable_irqs(); * if (state & BIT7) { * enable_irqs(); * } * * This takes 3 CPU Cycles if BIT7 is set (IRQs are enabled), otherwise 2. */ __asm__ volatile( "cli" "\n\t" "sbrc %[state], 7" "\n\t" "sei" "\n\t" : /* no outputs */ : [state] "r"(state) : "memory" ); } /** * @brief See if the current context is inside an ISR */ __attribute__((always_inline)) static inline int irq_is_in(void) { uint8_t state = avr8_get_state(); return (state & AVR8_STATE_FLAG_ISR); } #ifdef __cplusplus } #endif /** @} */ #endif /* IRQ_ARCH_H */