Nut/OS  4.10.3
API Reference
atom.h
Go to the documentation of this file.
00001 
00035 /*
00036  * $Log: atom.h,v $
00037  *
00038  */
00039 
00040 /*
00041         WHEN CHANGING PLEASE NOTICE:
00042         Errata 41.5.5.5 reads:
00043         "Need two NOPs instruction after instructions masking interrupts
00044         The instructions following in the pipeline the instruction masking the interrupt through SR
00045         may behave abnormally.
00046         Fix/Workaround
00047         Place two NOPs instructions after each SSRF or MTSR instruction setting IxM or GM in SR."
00048 */
00049 
00050 #ifndef _SYS_ATOM_H_
00051 #error "Do not include this file directly. Use sys/atom.h instead!"
00052 #endif
00053 
00054 #if (__GNUC__ && __AVR32__)
00055 
00056 #include <avr32/io.h>
00057 
00058 #if defined(NUT_CRITICAL_NESTING)
00059 
00060 #if defined(NUT_CRITICAL_NESTING_STACK)
00061 
00062 // This doesn't work right now. Not sure how to fix yet.
00063 // but this is unreacheable since critical neasting can't be enabled in the configurator
00064 // for AVR32
00065 #error Not Working
00066 #define NutEnterCritical()               \
00067 {                                        \
00068         register int temp_;                  \
00069         __asm__ volatile (                       \
00070         "mfsr    r10, %[SR]"                "\n\t" \
00071         "pushm   r10"     "\n\t"        \
00072         "ssrf    %[SR_GM_OFFSET]"     "\n\t"        \
00073         : [temp] "=r" (temp_) \
00074         : [SR] "i" (AVR32_SR), \
00075           [SR_GM_OFFSET] "i" (AVR32_SR_GM_OFFSET) \
00076         : "memory", "cc", "r10"); \
00077 }
00078 
00079 #define NutExitCritical() \
00080 { \
00081         register int temp_; \
00082         __asm__ volatile (             \
00083         "popm    r10"                                     "\n\t" \
00084         "andl    r10, LO(%[SR_GM_MASK])"               "\n\t" \
00085         "andh    r10, HI(%[SR_GM_MASK])"               "\n\t" \
00086         "cp.w    r10, 0"                               "\n\t" \
00087         "breq   LABEL_INT_SKIP_ENABLE_INTERRUPTS_%[LINE]" "\n\t" \
00088         "csrf   %[SR_GM_OFFSET]"                          "\n\t" \
00089         "LABEL_INT_SKIP_SAVE_CONTEXT_%[LINE]:"            "\n\t" \
00090         : [temp] "=r" (temp_)                                    \
00091         : [SR_GM_OFFSET] "i" (AVR32_SR_GM_OFFSET),               \
00092           [SR_GM_MASK]   "i" (AVR32_SR_GM_MASK),                 \
00093           [LINE] "i" (__LINE__)                                  \
00094         : "memory", "cc", "r10");                                \
00095 }
00096 
00097 #else /* NUT_CRITICAL_NESTING_STACK */
00098 
00099 // If we ever enable critical nesting, implement me.
00100 #error Not implemented
00101 extern unsigned int critical_nesting_level;
00102 
00103 #define NutEnterCritical()
00104 
00105 #define NutExitCritical()
00106 
00107 #endif /* NUT_CRITICAL_NESTING_STACK */
00108 
00109 #else /* NUT_CRITICAL_NESTING */
00110 
00111 #define NutEnterCritical() \
00112 {                                 \
00113         __asm__ __volatile__ (        \
00114         "ssrf\t%0"      "\n\t"        \
00115         "nop"               "\n\t"        \
00116         "nop"           "\n\t"        \
00117         :: "i" (AVR32_SR_GM_OFFSET)   \
00118         : "memory");                              \
00119 }
00120 
00121 #define NutExitCritical()         \
00122 {                                 \
00123         __asm__ __volatile__ (        \
00124         "csrf\t%0"      "\n\t"        \
00125     :: "i" (AVR32_SR_GM_OFFSET)   \
00126         : "memory");                              \
00127 }
00128 
00129 #endif /* NUT_CRITICAL_NESTING */
00130 
00131 #define NutJumpOutCritical()    NutExitCritical()
00132 
00133 #endif