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 
00029 
00030 
00031 
00032 
00033 
00034 
00035 #ifndef __AVR_CPP_IO_H__
00036 #define __AVR_CPP_IO_H__
00037 
00038 #include <avr/io.h>
00039 
00040 #ifndef __cplusplus
00041 #error "IO.h needs C++ compiler."
00042 #else
00043 
00044 
00045 #if !(defined(__AVR__) && __GNUC__ == 4 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ == 2)
00046 #warning "AVR C++ Lib is tested on avr-gcc (GCC) 4.1.2 (WinAVR 20070525). You are not using this compiler. AVR C++ Lib may not work properly."
00047 #endif
00048 
00049 namespace AVRCpp
00050 {
00051         typedef volatile uint16_t & reg16_t;
00052         typedef volatile uint8_t & reg8_t;
00053         
00054         template <class Register> inline void SetBits(typename Register::Type flags)
00055         {
00056                 Register::Set(Register::Get() | flags);
00057                 
00058         } 
00059         
00060         template <class Register> inline void ClearBits(typename Register::Type flags)
00061         {
00062                 Register::Set(Register::Get() & ~flags);
00063                 
00064         } 
00065         
00066         template <class Register> inline void SetBitsTo(typename Register::Type flags, bool value)
00067         {
00068                 if (value)
00069                         SetBits<Register>(flags);
00070                 else
00071                         ClearBits<Register>(flags);
00072                 
00073         } 
00074         
00075         template <class Register> inline void ToggleBits(typename Register::Type flags)
00076         {
00077                 Register::Set(Register::Get() ^ flags);
00078                 
00079         } 
00080         
00081         template <class Register> inline void ChangeBits(typename Register::Type selection, typename Register::Type value)
00082         {
00083                 typename Register::Type tmp = Register::Get() & ~selection;
00084                 
00085                 value &= selection;
00086                 Register::Set(tmp + value);
00087                 
00088         } 
00089         
00090         
00091         template <class Register> inline typename Register::Type SelectBits(typename Register::Type selection)
00092         {
00093                 return Register::Get() & selection;
00094                 
00095         } 
00096         
00097         template <class Register> inline bool IsAnyBitSet(typename Register::Type flags)
00098         {
00099                 return SelectBits<Register>(flags) != 0 ? true : false;
00100                 
00101         } 
00102         
00103         template <class Register> inline bool IsBitsSet(typename Register::Type flags)
00104         {
00105                 return SelectBits<Register>(flags) == flags ? true : false;
00106                 
00107         } 
00108         
00109         
00110         namespace Internal
00111         {
00112                 template <class Derived> struct Register8
00113                 {
00114                         typedef uint8_t Type;
00115                         typedef reg8_t RegType;
00116                         
00117                         static inline reg8_t Get() { return Derived::GetRegister(); }
00118                         static inline void Set(uint8_t flags) { Derived::GetRegister() = flags; }
00119                         
00120                 }; 
00121                 
00122                 template <class Derived> struct Register16
00123                 {
00124                         typedef uint16_t Type;
00125                         typedef reg16_t RegType;
00126                         
00127                         struct Low : Register8<Low>
00128                         {
00129                                 static inline reg8_t GetRegister() { return (reg8_t)Derived::GetRegister(); } 
00130                                 
00131                         }; 
00132                         
00133                         struct High : Register8<High>
00134                         {
00135                                 static inline reg8_t GetRegister() { return *(((volatile uint8_t *)(&Derived::GetRegister())) + 1); }
00136                                 
00137                         }; 
00138                         
00139                         static inline reg16_t Get() { return Derived::GetRegister(); }
00140                         static inline void Set(uint16_t flags) { Derived::GetRegister() = flags; }
00141                         
00142                 }; 
00143                 
00144         } 
00145         
00146         
00147 #define __DECLARE_8BIT_REGISTER__(registerName) \
00148         struct _ ## registerName : Internal::Register8<_ ## registerName> { static inline reg8_t GetRegister() { return registerName; } }
00149 
00150 #define __DECLARE_16BIT_REGISTER__(registerName) \
00151         struct _ ## registerName : Internal::Register16<_ ## registerName> { static inline reg16_t GetRegister() { return registerName; } }
00152         
00153         
00154         template <typename DDRReg, typename PORTReg, typename PINReg> struct Port
00155         {
00156                 typedef PORTReg Output;
00157                 typedef PINReg Input;
00158                 
00159                 static inline void SetAsTriStateInput(uint8_t flags) { ClearBits<PORTReg>(flags), ClearBits<DDRReg>(flags); }
00160                 static inline void SetAsInput(uint8_t flags) { SetBits<PORTReg>(flags), ClearBits<DDRReg>(flags); }
00161                 static inline void SetAsOutput(uint8_t flags) { SetBits<DDRReg>(flags); }
00162                 static inline bool IsOutput(uint8_t flags) { return IsBitsSet<DDRReg>(flags); }
00163                 static inline bool IsInput(uint8_t flags) { return !IsOutput(); }
00164                 static inline bool IsPulledUpInput(uint8_t flags) { return IsBitsSet<PORTReg>(flags) && !IsBitsSet<DDRReg>(flags); }
00165                 static inline bool IsTriStateInput(uint8_t flags) { return !IsBitsSet<PORTReg>(flags) && !IsBitsSet<DDRReg>(flags); }
00166 
00167         }; 
00168         
00169         template <class PortClass, uint8_t flags> struct OutputPins
00170         {
00171                 typedef PortClass MyPort;
00172                 typedef typename MyPort::Output Pins;
00173                 
00174                 static const uint8_t myFlags = flags;
00175                 
00176                 static inline void InitOutput() { MyPort::SetAsOutput(flags); }
00177                 static inline void Close() { MyPort::SetAsTriStateInput(flags); }
00178                 static inline void Set() { SetBits<Pins>(flags); }
00179                 static inline void SetTo(bool value) { SetBitsTo<Pins>(flags, value); }
00180                 static inline void Toggle() { ToggleBits<Pins>(flags); }
00181                 static inline void Clear() { ClearBits<Pins>(flags); }
00182                 static inline bool IsAnySet() { return IsAnyBitSet<Pins>(flags); }
00183                 static inline bool IsSet() { return IsBitsSet<Pins>(flags); }
00184                 
00185         }; 
00186         
00187         template <class PortClass, uint8_t flags> struct InputPins
00188         {
00189                 typedef PortClass MyPort;
00190                 typedef typename MyPort::Input Pins;
00191                 
00192                 static const uint8_t myFlags = flags;
00193                 
00194                 static inline void InitInput() { MyPort::SetAsInput(flags); }
00195                 static inline void InitDefaultInput() { MyPort::SetAsTriStateInput(flags); }
00196                 static inline bool IsAnySet() { return IsAnyBitSet<Pins>(flags); }
00197                 static inline bool IsSet() { return IsBitsSet<Pins>(flags); }
00198                 
00199         }; 
00200         
00201         template <class PortClass, uint8_t flags> struct Pins
00202         {
00203                 typedef InputPins<PortClass, flags> Input;
00204                 typedef OutputPins<PortClass, flags> Output;
00205 
00206                 static inline bool IsOutput() { return PortClass::IsOutput(flags); }
00207                 static inline bool IsInput() { return PortClass::IsInput(flags); }
00208                 static inline bool IsPulledUpInput() { return PortClass::IsPulledUpInput(flags); }
00209                 static inline bool IsTriStateInput() { return PortClass::IsTriStateInput(flags); }
00210                 
00211         }; 
00212         
00213         
00214 #define __DECLARE_PORT__(portLetter) \
00215         typedef struct Port<_DDR ## portLetter, _PORT ## portLetter, _PIN ## portLetter> Port ## portLetter
00216 
00217 #define __DECLARE_PORT_PIN__(pinNr) \
00218         template <class PortClass> struct InputPin ## pinNr : InputPins<PortClass, _P ## pinNr> {}; \
00219         template <class PortClass> struct OutputPin ## pinNr : OutputPins<PortClass, _P ## pinNr> {}; \
00220         template <class PortClass> struct Pin ## pinNr : Pins<PortClass, _P ## pinNr> {}
00221         
00222         
00223         template <class Register, uint16_t bitFlags> struct Bits
00224         {
00225                 static inline void Set() { SetBits<Register>(bitFlags); }
00226                 static inline void Clear() { ClearBits<Register>(bitFlags); }
00227                 static inline void Toggle() { ToggleBits<Register>(bitFlags); }
00228                 static inline bool IsAnySet() { return IsAnyBitSet<Register>(bitFlags); }
00229                 static inline bool IsSet() { return IsBitsSet<Register>(bitFlags); }
00230                 static inline void SetTo(bool value) { SetBitsTo<Register>(bitFlags, value); }
00231                 static inline void Change(typename Register::Type value) { ChangeBits<Register>(bitFlags, value); }
00232                 static inline typename Register::Type Select() { return SelectBits<Register>(bitFlags); }
00233                 
00234         }; 
00235         
00236         
00237         template <class EnableBit> struct BasicInterrupt
00238         {
00239                 static inline void Enable() { EnableBit::Set(); }
00240                 static inline void Disable() { EnableBit::Clear(); }
00241                 static inline bool IsEnabled() { return EnableBit::IsSet(); }
00242                 
00243         }; 
00244         
00245         
00246         template <class EnableBit, class FlagBit> struct Interrupt : BasicInterrupt<EnableBit>
00247         {
00248                 static inline void ClearFlag() { FlagBit::Set(); }
00249                 static inline bool IsTriggered() { return FlagBit::IsSet(); }
00250                 
00251         }; 
00252         
00253 } 
00254 
00255 #define __INTERRUPT_HANDLER_SUPPORT__ \
00256                 static void Evoke(); \
00257                 template <class DelegateType> static DelegateType & Me(); \
00258                 template <class ControllerType> static ControllerType & Controller();
00259 
00260 #define __DECLARE_BASIC_INTERRUPT__(interruptName, enableBitStart, enableBitEnd) \
00261                 struct interruptName ## Interrupt : BasicInterrupt<enableBitStart, enableBitEnd> { __INTERRUPT_HANDLER_SUPPORT__ }
00262 
00263 #define __DECLARE_INTERRUPT__(interruptName, enableBitStart, enableBitEnd, flagBitStart, flagBitEnd) \
00264                 struct interruptName ## Interrupt : Interrupt<enableBitStart, enableBitEnd, flagBitStart, flagBitEnd> { __INTERRUPT_HANDLER_SUPPORT__ }
00265 
00266 
00267 
00268 #define _P7             0x80
00269 #define _P6             0x40
00270 #define _P5             0x20
00271 #define _P4             0x10
00272 #define _P3             0x08
00273 #define _P2             0x04
00274 #define _P1             0x02
00275 #define _P0             0x01
00276 
00277 
00278 #define _DD7    0x80
00279 #define _DD6    0x40
00280 #define _DD5    0x20
00281 #define _DD4    0x10
00282 #define _DD3    0x08
00283 #define _DD2    0x04
00284 #define _DD1    0x02
00285 #define _DD0    0x01
00286 
00287 
00288 #define _PIN7   0x80
00289 #define _PIN6   0x40
00290 #define _PIN5   0x20
00291 #define _PIN4   0x10
00292 #define _PIN3   0x08
00293 #define _PIN2   0x04
00294 #define _PIN1   0x02
00295 #define _PIN0   0x01
00296 
00297 
00298 #if defined(__AVR_AT90USB1287__)
00299 #include "at90usb1287/IO.h"
00300 #elif defined(__AVR_ATmega128__)
00301 #include "atmega128/IO.h"
00302 #elif defined(__AVR_ATmega64__)
00303 #include "atmega64/IO.h"
00304 #elif defined(__AVR_ATmega8__)
00305 #include "atmega8/IO.h"
00306 #elif defined(__AVR_ATmega8515__)
00307 #include "atmega8515/IO.h"
00308 #elif defined(__AVR_ATmega88__)
00309 #include "atmega88/IO.h"
00310 #elif defined(__AVR_ATmega48__)
00311 #include "atmega48/IO.h"
00312 #elif defined(__AVR_ATmega168__)
00313 #include "atmega168/IO.h"
00314 #elif defined(__AVR_ATmega164P__)
00315 #include "atmega164p/IO.h"
00316 #elif defined(__AVR_ATmega324P__)
00317 #include "atmega324p/IO.h"
00318 #elif defined(__AVR_ATmega644P__)
00319 #include "atmega644p/IO.h"
00320 #elif defined(__AVR_ATmega644__)
00321 #include "atmega644/IO.h"
00322 #else
00323 #error "Device is not selected or selected device is not supported."
00324 #endif
00325 
00326 namespace AVRCpp
00327 {       
00328         __DECLARE_PORT_PIN__(0);
00329         __DECLARE_PORT_PIN__(1);
00330         __DECLARE_PORT_PIN__(2);
00331         __DECLARE_PORT_PIN__(3);
00332         __DECLARE_PORT_PIN__(4);
00333         __DECLARE_PORT_PIN__(5);
00334         __DECLARE_PORT_PIN__(6);
00335         __DECLARE_PORT_PIN__(7);
00336 
00337 } 
00338 
00339 #ifndef __DOXYGEN__
00340 
00341 #undef __DECLARE_PORT__
00342 #undef __DECLARE_PORT_PIN__
00343 #undef __DECLARE_8BIT_REGISTER__
00344 #undef __DECLARE_16BIT_REGISTER__
00345 
00346 #endif // ifndef __DOXYGEN__
00347 
00348 #endif // ifdef __cplusplus
00349 
00350 #endif // ifndef __AVR_CPP_IO_H__