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 
10 #pragma once
11 
25 #include <stdbool.h>
26 #include <msp430.h>
27 #include "irq.h"
28 
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32 
33 /*
34  * gcc warns for missing NOPs before/after interrupt enable/disable.
35  * so I added the NOP instructions, even though they might not be necessary
36  * due to following AND. // Kaspar
37  */
38 
39 extern volatile int __irq_is_in;
40 #define _GENERAL_INTERRUPT_ENABLE (0x0008)
41 
42 __attribute__((always_inline)) static inline unsigned int irq_disable(void)
43 {
44  unsigned int state;
45  __asm__ volatile(
46  "mov.w SR, %[state]" "\n\t"
47  "bic %[gie], SR" "\n\t"
48  "nop" "\n\t"
49  "and %[gie], %[state]" "\n\t"
50  : [state] "=r"(state)
51  : [gie] "i"(_GENERAL_INTERRUPT_ENABLE)
52  : "memory"
53  );
54 
55  return state;
56 }
57 
58 __attribute__((always_inline)) static inline unsigned int irq_enable(void)
59 {
60  unsigned int state;
61  __asm__ volatile(
62  "mov.w SR, %[state]" "\n\t"
63  "nop" "\n\t"
64  "bis %[gie], SR" "\n\t"
65  "nop" "\n\t"
66  "and %[gie], %[state]" "\n\t"
67  : [state] "=r"(state)
68  : [gie] "i"(_GENERAL_INTERRUPT_ENABLE)
69  : "memory"
70  );
71 
72  return state;
73 }
74 
75 __attribute__((always_inline)) static inline void irq_restore(unsigned int state)
76 {
77  __asm__ volatile(
78  "bis %[state], SR" "\n\t"
79  "nop" "\n\t"
80  : /* no outputs */
81  : [state] "r"(state)
82  : "memory"
83  );
84 }
85 
86 __attribute__((always_inline)) static inline bool irq_is_in(void)
87 {
88  return __irq_is_in;
89 }
90 
91 __attribute__((always_inline)) static inline bool irq_is_enabled(void)
92 {
93  unsigned int state;
94  __asm__ volatile(
95  "mov.w SR,%[state]" "\n\t"
96  : [state] "=r"(state)
97  : /* no inputs */
98  : "memory"
99  );
100 
101  return (state & GIE);
102 }
103 
104 #ifdef __cplusplus
105 }
106 #endif
107 
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)