avr/cpp/IO.h

Go to the documentation of this file.
00001 /**********************************************************************************************************************\
00002 
00003         C++ library for Atmel AVR microcontrollers
00004         Copyright (C) 2007 Lauri Kirikal, Mikk Leini, MT� TT� Robotiklubi
00005 
00006         This program is free software; you can redistribute it and/or
00007         modify it under the terms of the GNU General Public License
00008         as published by the Free Software Foundation; either version 2
00009         of the License, or (at your option) any later version.
00010 
00011         This program is distributed in the hope that it will be useful,
00012         but WITHOUT ANY WARRANTY; without even the implied warranty of
00013         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014         GNU General Public License for more details.
00015 
00016         You should have received a copy of the GNU General Public License
00017         along with this program; if not, write to the Free Software
00018         Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00019 
00020         See http://creativecommons.org/licenses/GPL/2.0/
00021 
00022         MT� TT� Robotiklubi  http://www.robotiklubi.ee robotiklubi@gmail.com
00023         Lauri Kirikal        laurikirikal@gmail.com
00024         Mikk Leini           mikk.leini@gmail.com
00025 
00026 \**********************************************************************************************************************/
00027 
00028 
00029 /**********************************************************************************************************************\
00030 
00031         AVRCppLib general IO functionality classes
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 // Compatibility test
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         } // SetBits
00059         
00060         template <class Register> inline void ClearBits(typename Register::Type flags)
00061         {
00062                 Register::Set(Register::Get() & ~flags);
00063                 
00064         } // ClearBits
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         } // SetBitsTo
00074         
00075         template <class Register> inline void ToggleBits(typename Register::Type flags)
00076         {
00077                 Register::Set(Register::Get() ^ flags);
00078                 
00079         } // ToggleBits
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         } // ChangeBits
00089         
00090         
00091         template <class Register> inline typename Register::Type SelectBits(typename Register::Type selection)
00092         {
00093                 return Register::Get() & selection;
00094                 
00095         } // IsBitsSet
00096         
00097         template <class Register> inline bool IsAnyBitSet(typename Register::Type flags)
00098         {
00099                 return SelectBits<Register>(flags) != 0 ? true : false;
00100                 
00101         } // IsBitsSet
00102         
00103         template <class Register> inline bool IsBitsSet(typename Register::Type flags)
00104         {
00105                 return SelectBits<Register>(flags) == flags ? true : false;
00106                 
00107         } // IsAllBitsSet
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                 }; // struct Register8
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                         }; // struct Low
00132                         
00133                         struct High : Register8<High>
00134                         {
00135                                 static inline reg8_t GetRegister() { return *(((volatile uint8_t *)(&Derived::GetRegister())) + 1); }
00136                                 
00137                         }; // struct High
00138                         
00139                         static inline reg16_t Get() { return Derived::GetRegister(); }
00140                         static inline void Set(uint16_t flags) { Derived::GetRegister() = flags; }
00141                         
00142                 }; // struct Register16
00143                 
00144         } // namespace Internal
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         }; // struct Port
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         }; // struct OutputPins
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         }; // struct InputPins
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         }; // struct Pins
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         }; // struct Bits
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         }; // struct BasicInterrupt
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         }; // struct Interrupt
00252         
00253 } // namespace AVRCpp
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 /* Universal PORT */
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 /* Universal DDR */
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 /* Universal PIN */
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 /* Include controller specific files */
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 } // namespace AVRCpp
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__

Generated on Sat Sep 15 23:41:05 2007 for AVR C++ Lib for ATmega64 by  doxygen 1.5.2
SourceForge.net Logo MTÜ TTÜ Robotiklubi