irq_arch.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Freie Universität Berlin, Hinnerk van Bruinehsen
3  * 2018 RWTH Aachen, Josua Arndt <jarndt@ias.rwth-aachen.de>
4  * 2020 Otto-von-Guericke-Universität Magdeburg
5  * 2021-2023 Gerson Fernando Budke
6  *
7  * This file is subject to the terms and conditions of the GNU Lesser
8  * General Public License v2.1. See the file LICENSE in the top level
9  * directory for more details.
10  */
11 
27 #ifndef IRQ_ARCH_H
28 #define IRQ_ARCH_H
29 
30 #include <stdbool.h>
31 #include <stdint.h>
32 #include <stdio.h>
33 #include <stdint.h>
34 #include "cpu.h"
35 
36 #ifdef __cplusplus
37 extern "C" {
38 #endif
39 
43 __attribute__((always_inline)) static inline unsigned int irq_disable(void)
44 {
45  uint8_t mask;
46  __asm__ volatile(
47  "in %[dest], __SREG__" "\n\t"
48  "cli" "\n\t"
49  : [dest] "=r"(mask)
50  : /* no inputs */
51  : "memory"
52  );
53  return mask;
54 }
55 
59 __attribute__((always_inline)) static inline unsigned int irq_enable(void)
60 {
61  uint8_t mask;
62  __asm__ volatile(
63  "in %[dest], __SREG__" "\n\t"
64  "sei" "\n\t"
65  : [dest] "=r"(mask)
66  : /* no inputs */
67  : "memory"
68  );
69  return mask;
70 }
71 
75 __attribute__((always_inline)) static inline void irq_restore(unsigned int _state)
76 {
77  uint8_t state = (uint8_t)_state;
78  /*
79  * Implementation in pseudo-code:
80  *
81  * disable_irqs();
82  * if (state & BIT7) {
83  * enable_irqs();
84  * }
85  *
86  * This takes 3 CPU Cycles if BIT7 is set (IRQs are enabled), otherwise 2.
87  */
88  __asm__ volatile(
89  "cli" "\n\t"
90  "sbrc %[state], 7" "\n\t"
91  "sei" "\n\t"
92  : /* no outputs */
93  : [state] "r"(state)
94  : "memory"
95  );
96 }
97 
101 __attribute__((always_inline)) static inline bool irq_is_in(void)
102 {
103  bool is_in = avr8_state_irq_count > 0;
104 
105  __asm__ volatile ("" : : : "memory");
106 
107  return is_in;
108 }
109 
113 __attribute__((always_inline)) static inline bool irq_is_enabled(void)
114 {
115  uint8_t mask;
116  __asm__ volatile(
117  "in %[dest], __SREG__" "\n\t"
118  : [dest] "=r"(mask)
119  : /* no inputs */
120  : "memory"
121  );
122  return mask & (1 << 7);
123 }
124 
148 #define AVR8_ISR(vector, function, ...) \
149  ISR(vector, ISR_BLOCK) \
150  { \
151  avr8_enter_isr(); \
152  function(__VA_ARGS__); \
153  avr8_exit_isr(); \
154  }
155 
156 #ifdef __cplusplus
157 }
158 #endif
159 
161 #endif /* IRQ_ARCH_H */
static unsigned int irq_disable(void)
Disable all maskable interrupts.
Definition: irq_arch.h:43
static void irq_restore(unsigned int _state)
Restore the state of the IRQ flags.
Definition: irq_arch.h:75
static bool irq_is_enabled(void)
Test if interrupts are currently enabled.
Definition: irq_arch.h:113
static bool irq_is_in(void)
See if the current context is inside an ISR.
Definition: irq_arch.h:101
static unsigned int irq_enable(void)
Enable all maskable interrupts.
Definition: irq_arch.h:59
Native CPU header.
#define avr8_state_irq_count
Definition for SRAM.
stdio wrapper to extend the C libs stdio