irq_arch.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Freie Universität Berlin
3  * 2020 Otto-von-Guericke-Universität Magdeburg
4  *
5  * This file is subject to the terms and conditions of the GNU Lesser
6  * General Public License v2.1. See the file LICENSE in the top level
7  * directory for more details.
8  */
9 
23 #ifndef IRQ_ARCH_H
24 #define IRQ_ARCH_H
25 
26 #include <stdbool.h>
27 #include <msp430.h>
28 #include "irq.h"
29 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33 
34 /*
35  * gcc warns for missing NOPs before/after interrupt enable/disable.
36  * so I added the NOP instructions, even though they might not be necessary
37  * due to following AND. // Kaspar
38  */
39 
40 extern volatile int __irq_is_in;
41 #define _GENERAL_INTERRUPT_ENABLE (0x0008)
42 
43 __attribute__((always_inline)) static inline unsigned int irq_disable(void)
44 {
45  unsigned int state;
46  __asm__ volatile(
47  "mov.w SR, %[state]" "\n\t"
48  "bic %[gie], SR" "\n\t"
49  "nop" "\n\t"
50  "and %[gie], %[state]" "\n\t"
51  : [state] "=r"(state)
52  : [gie] "i"(_GENERAL_INTERRUPT_ENABLE)
53  : "memory"
54  );
55 
56  return state;
57 }
58 
59 __attribute__((always_inline)) static inline unsigned int irq_enable(void)
60 {
61  unsigned int state;
62  __asm__ volatile(
63  "mov.w SR, %[state]" "\n\t"
64  "nop" "\n\t"
65  "bis %[gie], SR" "\n\t"
66  "nop" "\n\t"
67  "and %[gie], %[state]" "\n\t"
68  : [state] "=r"(state)
69  : [gie] "i"(_GENERAL_INTERRUPT_ENABLE)
70  : "memory"
71  );
72 
73  return state;
74 }
75 
76 __attribute__((always_inline)) static inline void irq_restore(unsigned int state)
77 {
78  __asm__ volatile(
79  "bis %[state], SR" "\n\t"
80  "nop" "\n\t"
81  : /* no outputs */
82  : [state] "r"(state)
83  : "memory"
84  );
85 }
86 
87 __attribute__((always_inline)) static inline bool irq_is_in(void)
88 {
89  return __irq_is_in;
90 }
91 
92 __attribute__((always_inline)) static inline bool irq_is_enabled(void)
93 {
94  unsigned int state;
95  __asm__ volatile(
96  "mov.w SR,%[state]" "\n\t"
97  : [state] "=r"(state)
98  : /* no inputs */
99  : "memory"
100  );
101 
102  return (state & GIE);
103 }
104 
105 #ifdef __cplusplus
106 }
107 #endif
108 
110 #endif /* IRQ_ARCH_H */
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)