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__