irq_arch.h
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2014 Freie Universität Berlin, Hinnerk van Bruinehsen
3  * SPDX-FileCopyrightText: 2018 RWTH Aachen, Josua Arndt <jarndt@ias.rwth-aachen.de>
4  * SPDX-FileCopyrightText: 2020 Otto-von-Guericke-Universität Magdeburg
5  * SPDX-FileCopyrightText: 2021-2023 Gerson Fernando Budke
6  * SPDX-License-Identifier: LGPL-2.1-only
7  */
8 
9 #pragma once
10 
26 #include <stdbool.h>
27 #include <stdint.h>
28 #include <stdio.h>
29 #include <stdint.h>
30 #include "cpu.h"
31 
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35 
39 __attribute__((always_inline)) static inline unsigned int irq_disable(void)
40 {
41  uint8_t mask;
42  __asm__ volatile(
43  "in %[dest], __SREG__" "\n\t"
44  "cli" "\n\t"
45  : [dest] "=r"(mask)
46  : /* no inputs */
47  : "memory"
48  );
49  return mask;
50 }
51 
55 __attribute__((always_inline)) static inline unsigned int irq_enable(void)
56 {
57  uint8_t mask;
58  __asm__ volatile(
59  "in %[dest], __SREG__" "\n\t"
60  "sei" "\n\t"
61  : [dest] "=r"(mask)
62  : /* no inputs */
63  : "memory"
64  );
65  return mask;
66 }
67 
71 __attribute__((always_inline)) static inline void irq_restore(unsigned int _state)
72 {
73  uint8_t state = (uint8_t)_state;
74  /*
75  * Implementation in pseudo-code:
76  *
77  * disable_irqs();
78  * if (state & BIT7) {
79  * enable_irqs();
80  * }
81  *
82  * This takes 3 CPU Cycles if BIT7 is set (IRQs are enabled), otherwise 2.
83  */
84  __asm__ volatile(
85  "cli" "\n\t"
86  "sbrc %[state], 7" "\n\t"
87  "sei" "\n\t"
88  : /* no outputs */
89  : [state] "r"(state)
90  : "memory"
91  );
92 }
93 
97 __attribute__((always_inline)) static inline bool irq_is_in(void)
98 {
99  bool is_in = avr8_state_irq_count > 0;
100 
101  __asm__ volatile ("" : : : "memory");
102 
103  return is_in;
104 }
105 
109 __attribute__((always_inline)) static inline bool irq_is_enabled(void)
110 {
111  uint8_t mask;
112  __asm__ volatile(
113  "in %[dest], __SREG__" "\n\t"
114  : [dest] "=r"(mask)
115  : /* no inputs */
116  : "memory"
117  );
118  return mask & (1 << 7);
119 }
120 
144 #define AVR8_ISR(vector, function, ...) \
145  ISR(vector, ISR_BLOCK) \
146  { \
147  avr8_enter_isr(); \
148  function(__VA_ARGS__); \
149  avr8_exit_isr(); \
150  }
151 
152 #ifdef __cplusplus
153 }
154 #endif
155 
static unsigned int irq_disable(void)
Disable all maskable interrupts.
Definition: irq_arch.h:39
static void irq_restore(unsigned int _state)
Restore the state of the IRQ flags.
Definition: irq_arch.h:71
static bool irq_is_enabled(void)
Test if interrupts are currently enabled.
Definition: irq_arch.h:109
static bool irq_is_in(void)
See if the current context is inside an ISR.
Definition: irq_arch.h:97
static unsigned int irq_enable(void)
Enable all maskable interrupts.
Definition: irq_arch.h:55
stdio wrapper to extend the C libs stdio
Native CPU header.
#define avr8_state_irq_count
Definition for SRAM.