|
| 1 | +/* |
| 2 | +* This is port of Dean Camera's ATOMIC_BLOCK macros for AVR to ARM Cortex M3 |
| 3 | +* v1.0 |
| 4 | +* Mark Pendrith, Nov 27, 2012. |
| 5 | +* |
| 6 | +* From Mark: |
| 7 | +* >When I ported the macros I emailed Dean to ask what attribution would be |
| 8 | +* >appropriate, and here is his response: |
| 9 | +* > |
| 10 | +* >>Mark, |
| 11 | +* >>I think it's great that you've ported the macros; consider them |
| 12 | +* >>public domain, to do with whatever you wish. I hope you find them useful. |
| 13 | +* >> |
| 14 | +* >>Cheers! |
| 15 | +* >>- Dean |
| 16 | +*/ |
| 17 | + |
| 18 | +#ifndef _CORTEX_M3_ATOMIC_H_ |
| 19 | +#define _CORTEX_M3_ATOMIC_H_ |
| 20 | + |
| 21 | +static __inline__ uint32_t __get_primask(void) \ |
| 22 | +{ uint32_t primask = 0; \ |
| 23 | + __asm__ volatile ("MRS %[result], PRIMASK\n\t":[result]"=r"(primask)::); \ |
| 24 | + return primask; } // returns 0 if interrupts enabled, 1 if disabled |
| 25 | + |
| 26 | +static __inline__ void __set_primask(uint32_t setval) \ |
| 27 | +{ __asm__ volatile ("MSR PRIMASK, %[value]\n\t""dmb\n\t""dsb\n\t""isb\n\t"::[value]"r"(setval):); \ |
| 28 | + __asm__ volatile ("" ::: "memory");} |
| 29 | + |
| 30 | +static __inline__ uint32_t __iSeiRetVal(void) \ |
| 31 | +{ __asm__ volatile ("CPSIE i\n\t""dmb\n\t""dsb\n\t""isb\n\t"); \ |
| 32 | + __asm__ volatile ("" ::: "memory"); return 1; } |
| 33 | + |
| 34 | +static __inline__ uint32_t __iCliRetVal(void) \ |
| 35 | +{ __asm__ volatile ("CPSID i\n\t""dmb\n\t""dsb\n\t""isb\n\t"); \ |
| 36 | + __asm__ volatile ("" ::: "memory"); return 1; } |
| 37 | + |
| 38 | +static __inline__ void __iSeiParam(const uint32_t *__s) \ |
| 39 | +{ __asm__ volatile ("CPSIE i\n\t""dmb\n\t""dsb\n\t""isb\n\t"); \ |
| 40 | + __asm__ volatile ("" ::: "memory"); (void)__s; } |
| 41 | + |
| 42 | +static __inline__ void __iCliParam(const uint32_t *__s) \ |
| 43 | +{ __asm__ volatile ("CPSID i\n\t""dmb\n\t""dsb\n\t""isb\n\t"); \ |
| 44 | + __asm__ volatile ("" ::: "memory"); (void)__s; } |
| 45 | + |
| 46 | +static __inline__ void __iRestore(const uint32_t *__s) \ |
| 47 | +{ __set_primask(*__s); __asm__ volatile ("dmb\n\t""dsb\n\t""isb\n\t"); \ |
| 48 | + __asm__ volatile ("" ::: "memory"); } |
| 49 | + |
| 50 | + |
| 51 | +#define ATOMIC_BLOCK(type) \ |
| 52 | +for ( type, __ToDo = __iCliRetVal(); __ToDo ; __ToDo = 0 ) |
| 53 | + |
| 54 | +#define ATOMIC_RESTORESTATE \ |
| 55 | +uint32_t primask_save __attribute__((__cleanup__(__iRestore))) = __get_primask() |
| 56 | + |
| 57 | +#define ATOMIC_FORCEON \ |
| 58 | +uint32_t primask_save __attribute__((__cleanup__(__iSeiParam))) = 0 |
| 59 | + |
| 60 | +#define NONATOMIC_BLOCK(type) \ |
| 61 | +for ( type, __ToDo = __iSeiRetVal(); __ToDo ; __ToDo = 0 ) |
| 62 | + |
| 63 | +#define NONATOMIC_RESTORESTATE \ |
| 64 | +uint32_t primask_save __attribute__((__cleanup__(__iRestore))) = __get_primask() |
| 65 | + |
| 66 | +#define NONATOMIC_FORCEOFF \ |
| 67 | +uint32_t primask_save __attribute__((__cleanup__(__iCliParam))) = 0 |
| 68 | + |
| 69 | +#endif |
0 commit comments