Nut/OS  5.0.5
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