00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef __AVR_CPP_INTERRUPT_H__
00029 #define __AVR_CPP_INTERRUPT_H__
00030
00031 #include "IO.h"
00032 #include "Assembler.h"
00033
00034 #ifndef EXCLUDE_INTERRUPT_HANDLERS
00035
00036 #define INTERRUPT_HANDLER(interruptName) \
00037 extern "C" void interruptName ## _vect(void) __attribute__ ((signal)); \
00038 void interruptName ## _vect(void)
00039
00040 #define RECURSIVE_INTERRUPT_HANDLER(interruptName) \
00041 extern "C" void interruptName ## _vect(void) __attribute__ ((interrupt)); \
00042 void interruptName ## _vect(void)
00043
00044 #define EVOCABLE_INTERRUPT_HANDLER(interruptName) \
00045 extern "C" void interruptName ## _vect(void) __attribute__ ((signal)); \
00046 void interruptName ## _vect(void) { AVRCpp::interruptName ## _struct::Evoke(); } \
00047 void AVRCpp::interruptName ## _struct::Evoke(void)
00048
00049 #define EVOCABLE_RECURSIVE_INTERRUPT_HANDLER(interruptName) \
00050 extern "C" void interruptName ## _vect(void) __attribute__ ((interrupt)); \
00051 void interruptName ## _vect(void) { AVRCpp::interruptName ## _struct::Evoke(); } \
00052 void AVRCpp::interruptName ## _struct::Evoke(void)
00053
00054 #define EXCLUDE_INTERRUPT(interruptName) \
00055 extern "C" void interruptName ## _vect(void) __attribute__ ((naked)); \
00056 void interruptName ## _vect(void) { __asm__ __volatile__ ("reti" ::); }
00057
00058 #define __DELEGATE_HANDLER__(vector) \
00059 extern "C" void vector(void) __attribute__ ((signal)); \
00060 void vector (void)
00061
00062 #define USING_MULTI_DELEGATE(interruptName) \
00063 namespace AVRCpp { namespace interruptName ## _ns { namespace Internal { CppDelegate::MultiDelegate interruptName ## Delegate; } \
00064 void interruptName ## _struct::Evoke() { interruptName ## _ns::Internal::interruptName ## Delegate(); } \
00065 template <> CppDelegate::MultiDelegate & interruptName ## _struct::Me<CppDelegate::MultiDelegate>() { return interruptName ## _ns::Internal::interruptName ## Delegate; } } } \
00066 __DELEGATE_HANDLER__(interruptName ## _vect) { AVRCpp::interruptName ## _ns::Internal::interruptName ## Delegate(); }
00067
00068 #define USING_FAST_DELEGATE(interruptName) \
00069 namespace AVRCpp { namespace interruptName ## _ns { namespace Internal { CppDelegate::FastDelegate interruptName ## Delegate; } \
00070 void interruptName ## _struct::Evoke() { interruptName ## _ns::Internal::interruptName ## Delegate(); } \
00071 template <> CppDelegate::FastDelegate & interruptName ## _struct::Me<CppDelegate::FastDelegate>() { return interruptName ## _ns::Internal::interruptName ## Delegate; } } } \
00072 __DELEGATE_HANDLER__(interruptName ## _vect) { AVRCpp::interruptName ## _ns::Internal::interruptName ## Delegate(); }
00073
00074 #define USING_DATA_DELEGATE(interruptName, controllerName) \
00075 namespace AVRCpp { namespace interruptName ## _ns { namespace Internal { controllerName interruptName ## Controller; } \
00076 void interruptName ## _struct::Evoke() { interruptName ## _ns::Internal::interruptName ## Controller(); } \
00077 template <> CppDelegate::DataDelegate<controllerName> & interruptName ## _struct::Me<CppDelegate::DataDelegate<controllerName> >() { return interruptName ## _ns::Internal::interruptName ## Controller.Delegate(); } \
00078 template <> controllerName & interruptName ## _struct::Controller<controllerName>() { return (controllerName &)interruptName ## _ns::Internal::interruptName ## Controller; } } } \
00079 __DELEGATE_HANDLER__(interruptName ## _vect) { AVRCpp::interruptName ## _ns::Internal::interruptName ## Controller(); }
00080
00081
00082 #endif // ifndef EXCLUDE_INTERRUPT_HANDLERS
00083
00084
00112 #define INTERRUPT_SAFE for(AVRCpp::GlobalInterrupts::Internal::InterruptDisabler safeObject; !safeObject.IsFinished(); safeObject.Finished() )
00113
00114 namespace AVRCpp
00115 {
00116 namespace GlobalInterrupts
00117 {
00118 inline void Enable() { Assembler::SEI(); }
00119 inline void Disable() { Assembler::CLI(); }
00120 inline uint8_t IsEnabled() { return IsBitsSet<_SREG>(_SREG_I); }
00121 inline void WaitForInterrupt() { Assembler::SLEEP(); }
00122
00123 namespace Internal
00124 {
00125 class InterruptDisabler
00126 {
00127 private:
00128
00129 uint8_t sreg;
00130
00131 public:
00132
00133 InterruptDisabler()
00134 {
00135 sreg = SREG;
00136 sreg &= ~_SREG_C;
00137 GlobalInterrupts::Disable();
00138
00139 }
00140
00141 inline void Finished() { sreg |= _SREG_C; }
00142 inline bool IsFinished() { return sreg & _SREG_C; }
00143
00144 ~InterruptDisabler()
00145 {
00146 SREG = sreg;
00147
00148 }
00149
00150 };
00151
00152 }
00153
00154 }
00155
00156 }
00157
00158 #endif // ifndef __AVR_CPP_INTERRUPT_H__