AskSin++
Atomic.h
1 
2 #ifndef __ATOMIC_H__
3 #define __ATOMIC_H__
4 
5 #ifdef ARDUINO
6  #include <Arduino.h>
7 
8 #if ARDUINO_ARCH_AVR
9  #include <util/atomic.h>
10 #else
11 
12 /*
13  * http://www.stm32duino.com/viewtopic.php?f=3&t=258&hilit=ATOMIC_BLOCK&start=10
14  */
15 
16 #ifdef __arm__
17 #ifndef _CORTEX_M3_ATOMIC_H_
18 #define _CORTEX_M3_ATOMIC_H_
19 
20 static __inline__ uint32_t __get_primask(void) \
21 { uint32_t primask = 0; \
22  __asm__ volatile ("MRS %[result], PRIMASK\n\t":[result]"=r"(primask)::); \
23  return primask; } // returns 0 if interrupts enabled, 1 if disabled
24 
25 static __inline__ void __set_primask(uint32_t setval) \
26 { __asm__ volatile ("MSR PRIMASK, %[value]\n\t""dmb\n\t""dsb\n\t""isb\n\t"::[value]"r"(setval):); \
27  __asm__ volatile ("" ::: "memory");}
28 
29 static __inline__ uint32_t __iSeiRetVal(void) \
30 { __asm__ volatile ("CPSIE i\n\t""dmb\n\t""dsb\n\t""isb\n\t"); \
31  __asm__ volatile ("" ::: "memory"); return 1; }
32 
33 static __inline__ uint32_t __iCliRetVal(void) \
34 { __asm__ volatile ("CPSID i\n\t""dmb\n\t""dsb\n\t""isb\n\t"); \
35  __asm__ volatile ("" ::: "memory"); return 1; }
36 
37 static __inline__ void __iSeiParam(const uint32_t *__s) \
38 { __asm__ volatile ("CPSIE i\n\t""dmb\n\t""dsb\n\t""isb\n\t"); \
39  __asm__ volatile ("" ::: "memory"); (void)__s; }
40 
41 static __inline__ void __iCliParam(const uint32_t *__s) \
42 { __asm__ volatile ("CPSID i\n\t""dmb\n\t""dsb\n\t""isb\n\t"); \
43  __asm__ volatile ("" ::: "memory"); (void)__s; }
44 
45 static __inline__ void __iRestore(const uint32_t *__s) \
46 { __set_primask(*__s); __asm__ volatile ("dmb\n\t""dsb\n\t""isb\n\t"); \
47  __asm__ volatile ("" ::: "memory"); }
48 
49 
50 #define ATOMIC_BLOCK(type) \
51 for ( type, __ToDo = __iCliRetVal(); __ToDo ; __ToDo = 0 )
52 
53 #define ATOMIC_RESTORESTATE \
54 uint32_t primask_save __attribute__((__cleanup__(__iRestore))) = __get_primask()
55 
56 #define ATOMIC_FORCEON \
57 uint32_t primask_save __attribute__((__cleanup__(__iSeiParam))) = 0
58 
59 #define NONATOMIC_BLOCK(type) \
60 for ( type, __ToDo = __iSeiRetVal(); __ToDo ; __ToDo = 0 )
61 
62 #define NONATOMIC_RESTORESTATE \
63 uint32_t primask_save __attribute__((__cleanup__(__iRestore))) = __get_primask()
64 
65 #define NONATOMIC_FORCEOFF \
66 uint32_t primask_save __attribute__((__cleanup__(__iCliParam))) = 0
67 
68 #endif
69 #endif
70 
71 #endif
72 
73 #else // ARDUINO
74 
75 #define ATOMIC_BLOCK(type)
76 #include <stdint.h>
77 
78 #endif
79 
80 #endif