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 
12 #pragma once
13 
29 #include <stdbool.h>
30 #include <stdint.h>
31 #include <stdio.h>
32 #include <stdint.h>
33 #include "cpu.h"
34 
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38 
42 __attribute__((always_inline)) static inline unsigned int irq_disable(void)
43 {
44  uint8_t mask;
45  __asm__ volatile(
46  "in %[dest], __SREG__" "\n\t"
47  "cli" "\n\t"
48  : [dest] "=r"(mask)
49  : /* no inputs */
50  : "memory"
51  );
52  return mask;
53 }
54 
58 __attribute__((always_inline)) static inline unsigned int irq_enable(void)
59 {
60  uint8_t mask;
61  __asm__ volatile(
62  "in %[dest], __SREG__" "\n\t"
63  "sei" "\n\t"
64  : [dest] "=r"(mask)
65  : /* no inputs */
66  : "memory"
67  );
68  return mask;
69 }
70 
74 __attribute__((always_inline)) static inline void irq_restore(unsigned int _state)
75 {
76  uint8_t state = (uint8_t)_state;
77  /*
78  * Implementation in pseudo-code:
79  *
80  * disable_irqs();
81  * if (state & BIT7) {
82  * enable_irqs();
83  * }
84  *
85  * This takes 3 CPU Cycles if BIT7 is set (IRQs are enabled), otherwise 2.
86  */
87  __asm__ volatile(
88  "cli" "\n\t"
89  "sbrc %[state], 7" "\n\t"
90  "sei" "\n\t"
91  : /* no outputs */
92  : [state] "r"(state)
93  : "memory"
94  );
95 }
96 
100 __attribute__((always_inline)) static inline bool irq_is_in(void)
101 {
102  bool is_in = avr8_state_irq_count > 0;
103 
104  __asm__ volatile ("" : : : "memory");
105 
106  return is_in;
107 }
108 
112 __attribute__((always_inline)) static inline bool irq_is_enabled(void)
113 {
114  uint8_t mask;
115  __asm__ volatile(
116  "in %[dest], __SREG__" "\n\t"
117  : [dest] "=r"(mask)
118  : /* no inputs */
119  : "memory"
120  );
121  return mask & (1 << 7);
122 }
123 
147 #define AVR8_ISR(vector, function, ...) \
148  ISR(vector, ISR_BLOCK) \
149  { \
150  avr8_enter_isr(); \
151  function(__VA_ARGS__); \
152  avr8_exit_isr(); \
153  }
154 
155 #ifdef __cplusplus
156 }
157 #endif
158 
static unsigned int irq_disable(void)
Disable all maskable interrupts.
Definition: irq_arch.h:42
static void irq_restore(unsigned int _state)
Restore the state of the IRQ flags.
Definition: irq_arch.h:74
static bool irq_is_enabled(void)
Test if interrupts are currently enabled.
Definition: irq_arch.h:112
static bool irq_is_in(void)
See if the current context is inside an ISR.
Definition: irq_arch.h:100
static unsigned int irq_enable(void)
Enable all maskable interrupts.
Definition: irq_arch.h:58
stdio wrapper to extend the C libs stdio
Native CPU header.
#define avr8_state_irq_count
Definition for SRAM.