irq_arch.h
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2014 Freie Universität Berlin
3  * SPDX-FileCopyrightText: 2020 Otto-von-Guericke-Universität Magdeburg
4  * SPDX-License-Identifier: LGPL-2.1-only
5  */
6 
7 #pragma once
8 
22 #include <stdbool.h>
23 #include <msp430.h>
24 #include "irq.h"
25 
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 
30 /*
31  * gcc warns for missing NOPs before/after interrupt enable/disable.
32  * so I added the NOP instructions, even though they might not be necessary
33  * due to following AND. // Kaspar
34  */
35 
36 extern volatile int __irq_is_in;
37 #define _GENERAL_INTERRUPT_ENABLE (0x0008)
38 
39 __attribute__((always_inline)) static inline unsigned int irq_disable(void)
40 {
41  unsigned int state;
42  __asm__ volatile(
43  "mov.w SR, %[state]" "\n\t"
44  "bic %[gie], SR" "\n\t"
45  "nop" "\n\t"
46  "and %[gie], %[state]" "\n\t"
47  : [state] "=r"(state)
48  : [gie] "i"(_GENERAL_INTERRUPT_ENABLE)
49  : "memory"
50  );
51 
52  return state;
53 }
54 
55 __attribute__((always_inline)) static inline unsigned int irq_enable(void)
56 {
57  unsigned int state;
58  __asm__ volatile(
59  "mov.w SR, %[state]" "\n\t"
60  "nop" "\n\t"
61  "bis %[gie], SR" "\n\t"
62  "nop" "\n\t"
63  "and %[gie], %[state]" "\n\t"
64  : [state] "=r"(state)
65  : [gie] "i"(_GENERAL_INTERRUPT_ENABLE)
66  : "memory"
67  );
68 
69  return state;
70 }
71 
72 __attribute__((always_inline)) static inline void irq_restore(unsigned int state)
73 {
74  __asm__ volatile(
75  "bis %[state], SR" "\n\t"
76  "nop" "\n\t"
77  : /* no outputs */
78  : [state] "r"(state)
79  : "memory"
80  );
81 }
82 
83 __attribute__((always_inline)) static inline bool irq_is_in(void)
84 {
85  return __irq_is_in;
86 }
87 
88 __attribute__((always_inline)) static inline bool irq_is_enabled(void)
89 {
90  unsigned int state;
91  __asm__ volatile(
92  "mov.w SR,%[state]" "\n\t"
93  : [state] "=r"(state)
94  : /* no inputs */
95  : "memory"
96  );
97 
98  return (state & GIE);
99 }
100 
101 #ifdef __cplusplus
102 }
103 #endif
104 
MAYBE_INLINE void irq_restore(unsigned state)
This function restores the IRQ disable bit in the status register to the value contained within passe...
MAYBE_INLINE unsigned irq_disable(void)
This function sets the IRQ disable bit in the status register.
MAYBE_INLINE bool irq_is_enabled(void)
Test if IRQs are currently enabled.
MAYBE_INLINE unsigned irq_enable(void)
This function clears the IRQ disable bit in the status register.
MAYBE_INLINE bool irq_is_in(void)
Check whether called from interrupt service routine.
IRQ driver interface.
volatile int __irq_is_in
The current ISR state (inside or not)