avr/cpp/DiverseIO.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 #ifndef __AVR_CPP_DIVERSE_IO_H__
00029 #define __AVR_CPP_DIVERSE_IO_H__
00030 
00031 #include "IO.h"
00032 
00033 #ifdef __DOXYGEN__
00034 // To save space in documentation
00035 #define EXCLUDE_STATE_WATCH_PINS
00036 #define EXCLUDE_GROUND_PULL_PINS
00037 #endif
00038 
00039 /**********************************************************************************************************************\
00040 
00041         AVRCppLib miscellaneous IO pins functionality classes
00042 
00043 \**********************************************************************************************************************/
00044 
00045 namespace AVRCpp
00046 {
00047 
00048 
00049 /**********************************************************************************************************************\
00050 
00051         Multi-port input and output pins
00052 
00053 \**********************************************************************************************************************/
00054 
00055 #ifndef EXCLUDE_MULTI_PORT_PINS
00056 
00057 template <      class Port0, uint8_t flags0,
00058                         class Port1, uint8_t flags1,
00059                         class Port2 = PortB, uint8_t flags2 = 0,
00060                         class Port3 = PortB, uint8_t flags3 = 0,
00061                         class Port4 = PortB, uint8_t flags4 = 0,
00062                         class Port5 = PortB, uint8_t flags5 = 0,
00063                         class Port6 = PortB, uint8_t flags6 = 0,
00064                         class Port7 = PortB, uint8_t flags7 = 0 >
00065 
00066 class MultiPortInputPins
00067 {
00068 protected:
00069 
00070         typedef typename Port0::Input Pins0;
00071         typedef typename Port1::Input Pins1;
00072         typedef typename Port2::Input Pins2;
00073         typedef typename Port3::Input Pins3;
00074         typedef typename Port4::Input Pins4;
00075         typedef typename Port5::Input Pins5;
00076         typedef typename Port6::Input Pins6;
00077         typedef typename Port7::Input Pins7;
00078 
00079 public:
00080 
00081         static inline void InitInput()
00082         {
00083                 if (flags0) Port0::SetAsInput(flags0);
00084                 if (flags1) Port1::SetAsInput(flags1);
00085                 if (flags2) Port2::SetAsInput(flags2);
00086                 if (flags3) Port3::SetAsInput(flags3);
00087                 if (flags4) Port4::SetAsInput(flags4);
00088                 if (flags5) Port5::SetAsInput(flags5);
00089                 if (flags6) Port6::SetAsInput(flags6);
00090                 if (flags7) Port7::SetAsInput(flags7);
00091                 
00092         } // InitInput
00093 
00094         static inline void InitDefaultInput()
00095         {
00096                 if (flags0) Port0::SetAsTriStateInput(flags0);
00097                 if (flags1) Port1::SetAsTriStateInput(flags1);
00098                 if (flags2) Port2::SetAsTriStateInput(flags2);
00099                 if (flags3) Port3::SetAsTriStateInput(flags3);
00100                 if (flags4) Port4::SetAsTriStateInput(flags4);
00101                 if (flags5) Port5::SetAsTriStateInput(flags5);
00102                 if (flags6) Port6::SetAsTriStateInput(flags6);
00103                 if (flags7) Port7::SetAsTriStateInput(flags7);
00104                 
00105         } // InitDefaultInput
00106 
00107         static inline bool IsAnySet()
00108         {
00109                 return          (flags0 ? IsAnyBitSet<Pins0>(flags0) : false)
00110                                 ||      (flags1 ? IsAnyBitSet<Pins1>(flags1) : false)
00111                                 ||      (flags2 ? IsAnyBitSet<Pins2>(flags2) : false)
00112                                 ||      (flags3 ? IsAnyBitSet<Pins3>(flags3) : false)
00113                                 ||      (flags4 ? IsAnyBitSet<Pins4>(flags4) : false)
00114                                 ||      (flags5 ? IsAnyBitSet<Pins5>(flags5) : false)
00115                                 ||      (flags6 ? IsAnyBitSet<Pins6>(flags6) : false)
00116                                 ||      (flags7 ? IsAnyBitSet<Pins7>(flags7) : false);
00117                 
00118         } // IsSet
00119         
00120         static inline bool IsSet()
00121         {
00122                 return          (flags0 ? IsBitsSet<Pins0>(flags0) : true)
00123                                 &&      (flags1 ? IsBitsSet<Pins1>(flags1) : true)
00124                                 &&      (flags2 ? IsBitsSet<Pins2>(flags2) : true)
00125                                 &&      (flags3 ? IsBitsSet<Pins3>(flags3) : true)
00126                                 &&      (flags4 ? IsBitsSet<Pins4>(flags4) : true)
00127                                 &&      (flags5 ? IsBitsSet<Pins5>(flags5) : true)
00128                                 &&      (flags6 ? IsBitsSet<Pins6>(flags6) : true)
00129                                 &&      (flags7 ? IsBitsSet<Pins7>(flags7) : true);
00130                 
00131         } // IsAllSet
00132 
00133 }; // class MultiPortInputPins
00134 
00135 
00136 template <      class Port0, uint8_t flags0,
00137                         class Port1, uint8_t flags1,
00138                         class Port2 = PortB, uint8_t flags2 = 0,
00139                         class Port3 = PortB, uint8_t flags3 = 0,
00140                         class Port4 = PortB, uint8_t flags4 = 0,
00141                         class Port5 = PortB, uint8_t flags5 = 0,
00142                         class Port6 = PortB, uint8_t flags6 = 0,
00143                         class Port7 = PortB, uint8_t flags7 = 0 >
00144 
00145 class MultiPortOutputPins
00146 {
00147 protected:
00148 
00149         typedef typename Port0::Output Pins0;
00150         typedef typename Port1::Output Pins1;
00151         typedef typename Port2::Output Pins2;
00152         typedef typename Port3::Output Pins3;
00153         typedef typename Port4::Output Pins4;
00154         typedef typename Port5::Output Pins5;
00155         typedef typename Port6::Output Pins6;
00156         typedef typename Port7::Output Pins7;
00157 
00158 public:
00159 
00160         static inline void InitOutput()
00161         {
00162                 if (flags0) Port0::SetAsOutput(flags0);
00163                 if (flags1) Port1::SetAsOutput(flags1);
00164                 if (flags2) Port2::SetAsOutput(flags2);
00165                 if (flags3) Port3::SetAsOutput(flags3);
00166                 if (flags4) Port4::SetAsOutput(flags4);
00167                 if (flags5) Port5::SetAsOutput(flags5);
00168                 if (flags6) Port6::SetAsOutput(flags6);
00169                 if (flags7) Port7::SetAsOutput(flags7);
00170                 
00171         } // InitOutput
00172 
00173         static inline void Close()
00174         {
00175                 if (flags0) Port0::SetAsTriStateInput(flags0);
00176                 if (flags1) Port1::SetAsTriStateInput(flags1);
00177                 if (flags2) Port2::SetAsTriStateInput(flags2);
00178                 if (flags3) Port3::SetAsTriStateInput(flags3);
00179                 if (flags4) Port4::SetAsTriStateInput(flags4);
00180                 if (flags5) Port5::SetAsTriStateInput(flags5);
00181                 if (flags6) Port6::SetAsTriStateInput(flags6);
00182                 if (flags7) Port7::SetAsTriStateInput(flags7);
00183                 
00184         } // Close
00185 
00186         static inline void Set()
00187         {
00188                 if (flags0) SetBits<Pins0>(flags0);
00189                 if (flags1) SetBits<Pins1>(flags1);
00190                 if (flags2) SetBits<Pins2>(flags2);
00191                 if (flags3) SetBits<Pins3>(flags3);
00192                 if (flags4) SetBits<Pins4>(flags4);
00193                 if (flags5) SetBits<Pins5>(flags5);
00194                 if (flags6) SetBits<Pins6>(flags6);
00195                 if (flags7) SetBits<Pins7>(flags7);
00196                 
00197         } // Set
00198 
00199         static inline void SetTo(bool value)
00200         {
00201                 if (flags0) SetBitsTo<Pins0>(flags0, value);
00202                 if (flags1) SetBitsTo<Pins1>(flags1, value);
00203                 if (flags2) SetBitsTo<Pins2>(flags2, value);
00204                 if (flags3) SetBitsTo<Pins3>(flags3, value);
00205                 if (flags4) SetBitsTo<Pins4>(flags4, value);
00206                 if (flags5) SetBitsTo<Pins5>(flags5, value);
00207                 if (flags6) SetBitsTo<Pins6>(flags6, value);
00208                 if (flags7) SetBitsTo<Pins7>(flags7, value);
00209 
00210         } // SetTo
00211 
00212         static inline void Clear()
00213         {
00214                 if (flags0) ClearBits<Pins0>(flags0);
00215                 if (flags1) ClearBits<Pins1>(flags1);
00216                 if (flags2) ClearBits<Pins2>(flags2);
00217                 if (flags3) ClearBits<Pins3>(flags3);
00218                 if (flags4) ClearBits<Pins4>(flags4);
00219                 if (flags5) ClearBits<Pins5>(flags5);
00220                 if (flags6) ClearBits<Pins6>(flags6);
00221                 if (flags7) ClearBits<Pins7>(flags7);
00222                 
00223         } // Clear
00224 
00225         static inline void Toggle()
00226         {
00227                 if (flags0) ToggleBits<Pins0>(flags0);
00228                 if (flags1) ToggleBits<Pins1>(flags1);
00229                 if (flags2) ToggleBits<Pins2>(flags2);
00230                 if (flags3) ToggleBits<Pins3>(flags3);
00231                 if (flags4) ToggleBits<Pins4>(flags4);
00232                 if (flags5) ToggleBits<Pins5>(flags5);
00233                 if (flags6) ToggleBits<Pins6>(flags6);
00234                 if (flags7) ToggleBits<Pins7>(flags7);
00235                 
00236         } // Toggle
00237 
00238         static inline bool IsAnySet()
00239         {
00240                 return          (flags0 ? IsAnyBitSet<Pins0>(flags0) : false)
00241                                 ||      (flags1 ? IsAnyBitSet<Pins1>(flags1) : false)
00242                                 ||      (flags2 ? IsAnyBitSet<Pins2>(flags2) : false)
00243                                 ||      (flags3 ? IsAnyBitSet<Pins3>(flags3) : false)
00244                                 ||      (flags4 ? IsAnyBitSet<Pins4>(flags4) : false)
00245                                 ||      (flags5 ? IsAnyBitSet<Pins5>(flags5) : false)
00246                                 ||      (flags6 ? IsAnyBitSet<Pins6>(flags6) : false)
00247                                 ||      (flags7 ? IsAnyBitSet<Pins7>(flags7) : false);
00248                 
00249         } // IsSet
00250         
00251         static inline bool IsSet()
00252         {
00253                 return          (flags0 ? IsBitsSet<Pins0>(flags0) : true)
00254                                 &&      (flags1 ? IsBitsSet<Pins1>(flags1) : true)
00255                                 &&      (flags2 ? IsBitsSet<Pins2>(flags2) : true)
00256                                 &&      (flags3 ? IsBitsSet<Pins3>(flags3) : true)
00257                                 &&      (flags4 ? IsBitsSet<Pins4>(flags4) : true)
00258                                 &&      (flags5 ? IsBitsSet<Pins5>(flags5) : true)
00259                                 &&      (flags6 ? IsBitsSet<Pins6>(flags6) : true)
00260                                 &&      (flags7 ? IsBitsSet<Pins7>(flags7) : true);
00261                 
00262         } // IsAllSet
00263 
00264 }; // class MultiPortOutputPins
00265 
00266 
00267 template <      class InputPins0,
00268                         class InputPins1,
00269                         class InputPins2 = InputPins<PortB, 0>,
00270                         class InputPins3 = InputPins<PortB, 0>,
00271                         class InputPins4 = InputPins<PortB, 0>,
00272                         class InputPins5 = InputPins<PortB, 0>,
00273                         class InputPins6 = InputPins<PortB, 0>,
00274                         class InputPins7 = InputPins<PortB, 0> >
00275 
00276 class CombinedInputPins : public MultiPortInputPins <   typename InputPins0::MyPort, InputPins0::myFlags,
00277                                                                                                                 typename InputPins1::MyPort, InputPins1::myFlags,
00278                                                                                                                 typename InputPins2::MyPort, InputPins2::myFlags,
00279                                                                                                                 typename InputPins3::MyPort, InputPins3::myFlags,
00280                                                                                                                 typename InputPins4::MyPort, InputPins4::myFlags,
00281                                                                                                                 typename InputPins5::MyPort, InputPins5::myFlags,
00282                                                                                                                 typename InputPins6::MyPort, InputPins6::myFlags,
00283                                                                                                                 typename InputPins7::MyPort, InputPins7::myFlags > {};
00284 
00285 template <      class OutputPins0,
00286                         class OutputPins1,
00287                         class OutputPins2 = OutputPins<PortB, 0>,
00288                         class OutputPins3 = OutputPins<PortB, 0>,
00289                         class OutputPins4 = OutputPins<PortB, 0>,
00290                         class OutputPins5 = OutputPins<PortB, 0>,
00291                         class OutputPins6 = OutputPins<PortB, 0>,
00292                         class OutputPins7 = OutputPins<PortB, 0> >
00293 
00294 class CombinedOutputPins : public MultiPortOutputPins < typename OutputPins0::MyPort, OutputPins0::myFlags,
00295                                                                                                                 typename OutputPins1::MyPort, OutputPins1::myFlags,
00296                                                                                                                 typename OutputPins2::MyPort, OutputPins2::myFlags,
00297                                                                                                                 typename OutputPins3::MyPort, OutputPins3::myFlags,
00298                                                                                                                 typename OutputPins4::MyPort, OutputPins4::myFlags,
00299                                                                                                                 typename OutputPins5::MyPort, OutputPins5::myFlags,
00300                                                                                                                 typename OutputPins6::MyPort, OutputPins6::myFlags,
00301                                                                                                                 typename OutputPins7::MyPort, OutputPins7::myFlags > {};
00302 
00303 #endif // ifndef EXCLUDE_MULTI_PORT_PINS
00304 
00305 
00306 /**********************************************************************************************************************\
00307 
00308         Input pins with state change watcher
00309 
00310 \**********************************************************************************************************************/
00311 
00312 #ifndef EXCLUDE_STATE_WATCH_PINS
00313 
00314 template <class InputPinsClass> class StateWatchInputPins : public InputPinsClass
00315 {
00316 protected:
00317 
00318         bool prevState;
00319 
00320 public:
00321 
00322         inline void InitInput()
00323         {
00324                 InputPinsClass::InitInput();
00325                 prevState = InputPinsClass::IsSet();
00326 
00327         } // InitInput
00328 
00329         inline void InitDefaultInput()
00330         {
00331                 InputPinsClass::InitDefaultInput();
00332                 prevState = InputPinsClass::IsSet();
00333 
00334         } // InitDefaultInput
00335 
00336         inline void Reset() { prevState = InputPinsClass::IsSet(); }
00337 
00338         inline bool HasChanged(bool doNotReset = false)
00339         {
00340                 bool now = InputPinsClass::IsSet();
00341 
00342                 if (now != prevState)
00343                 {
00344                     if (!doNotReset) prevState = now;
00345                         return true;
00346                 }
00347 
00348                 return false;
00349 
00350         } // HasChanged
00351 
00352 }; // class StateWatchInputPins
00353 
00354 #define __DECLARE_STATE_WATCH_PORT_INPUT_PIN__(pinNr) \
00355         template <class PortClass> class StateWatchInputPin ## pinNr : public StateWatchInputPins<InputPins<PortClass, _P ## pinNr> > {}
00356 
00357 __DECLARE_STATE_WATCH_PORT_INPUT_PIN__(0);
00358 __DECLARE_STATE_WATCH_PORT_INPUT_PIN__(1);
00359 __DECLARE_STATE_WATCH_PORT_INPUT_PIN__(2);
00360 __DECLARE_STATE_WATCH_PORT_INPUT_PIN__(3);
00361 __DECLARE_STATE_WATCH_PORT_INPUT_PIN__(4);
00362 __DECLARE_STATE_WATCH_PORT_INPUT_PIN__(5);
00363 __DECLARE_STATE_WATCH_PORT_INPUT_PIN__(6);
00364 __DECLARE_STATE_WATCH_PORT_INPUT_PIN__(7);
00365 
00366 #undef __DECLARE_STATE_WATCH_PORT_INPUT_PIN__
00367 
00368 #endif // #ifndef EXCLUDE_STATE_WATCH_PINS
00369 
00370 
00371 /**********************************************************************************************************************\
00372 
00373         Output pins with only ground pulled or loose output
00374 
00375 \**********************************************************************************************************************/
00376 
00377 #ifndef EXCLUDE_GROUND_PULL_PINS
00378 
00379 template <class OutputPinsClass> class GroundPullOutputPins : public OutputPinsClass
00380 {
00381 public:
00382         static inline void Pull()
00383     {
00384         OutputPinsClass::InitOutput();
00385         OutputPinsClass::Clear();
00386         }
00387         
00388         static inline void Release()
00389         {
00390                 OutputPinsClass::Close();
00391         }
00392 
00393     static inline void PullTo(bool bDown)
00394     {
00395         if (bDown)
00396                 {
00397                 OutputPinsClass::InitOutput();
00398                 OutputPinsClass::Clear();
00399         } else {
00400                 OutputPinsClass::Close();
00401         }
00402         }
00403 }; // class GroundPullOutputPins
00404 
00405 #define __DECLARE_ROUND_PULL_PORT_PIN__(pinNr) \
00406         template <class PortClass> class GroundPullOutputPin ## pinNr : public GroundPullOutputPins<OutputPins<PortClass, _P ## pinNr> > {}
00407 
00408 __DECLARE_ROUND_PULL_PORT_PIN__(0);
00409 __DECLARE_ROUND_PULL_PORT_PIN__(1);
00410 __DECLARE_ROUND_PULL_PORT_PIN__(2);
00411 __DECLARE_ROUND_PULL_PORT_PIN__(3);
00412 __DECLARE_ROUND_PULL_PORT_PIN__(4);
00413 __DECLARE_ROUND_PULL_PORT_PIN__(5);
00414 __DECLARE_ROUND_PULL_PORT_PIN__(6);
00415 __DECLARE_ROUND_PULL_PORT_PIN__(7);
00416 
00417 #undef __DECLARE_ROUND_PULL_PORT_PIN__
00418 
00419 #endif // #ifndef EXCLUDE_GROUND_PULL_PINS
00420 
00421 
00422 /**********************************************************************************************************************\
00423 
00424         Bitmask handling classes
00425 
00426 \**********************************************************************************************************************/
00427 
00428 #ifndef EXCLUDE_FLAGS_BUFFER
00429 
00430 template <typename T> class FlagsBuffer
00431 {
00432 protected:
00433 
00434         T flags;
00435 
00436 public:
00437 
00438         FlagsBuffer() : flags(0) {}
00439         FlagsBuffer(T initFlags) : flags(initFlags) {}
00440         
00441         inline void Set(T value) { flags = value; }
00442         inline T Get() { return flags; }
00443         inline void SetBits(T flagsSet) { flags |= flagsSet; }
00444         inline void ClearBits(T flagsCleared) { flags &= ~flagsCleared; }
00445         inline void ToggleBits(T flagsToggled) { flags ^= flagsToggled; }
00446         inline T SelectBits(T flagsSelected) { return flags & flagsSelected; }
00447         inline bool IsBitsSet(T flagsTested) { return SelectBits(flagsTested) != 0 ? true : false; }
00448         template<class Register> inline void FromRegister() { flags = Register::Get(); }
00449         template<class Register> inline void IntoRegister() { Register::Set(flags); }
00450 
00451         inline void ChangeBits(T selection, T value)
00452         {
00453                 T tmp = flags & ~selection;
00454                 
00455                 value &= selection;
00456                 flags = tmp + value;
00457                 
00458         } // ChangeBits
00459         
00460 }; // class FlagsBuffer
00461 
00462 
00463 class FlagsBuffer8 : public     FlagsBuffer<uint8_t>
00464 {
00465 public:
00466 
00467         FlagsBuffer8() :FlagsBuffer<uint8_t>() {}
00468         FlagsBuffer8(uint8_t initFlags) : FlagsBuffer<uint8_t>(initFlags) {}
00469 
00470 }; // class FlagsBuffer8
00471 
00472 
00473 class FlagsBuffer16     : public FlagsBuffer<uint16_t>
00474 {
00475 public:
00476 
00477         FlagsBuffer16() :FlagsBuffer<uint16_t>() {}
00478         FlagsBuffer16(uint16_t initFlags) : FlagsBuffer<uint16_t>(initFlags) {}
00479 
00480 }; // class FlagsBuffer16
00481 
00482 #endif // ifndef EXCLUDE_FLAGS_BUFFER
00483 
00484 
00485 /**********************************************************************************************************************\
00486 
00487         Base class (struct) for desired register bit handling
00488 
00489 \**********************************************************************************************************************/
00490 
00491 #ifndef EXCLUDE_BIT_NUMBERS
00492 
00493 #define __DECLARE_BIT_NUMBER__(bitNr) \
00494         template <class RegisterClass> struct Bit ## bitNr : Bits<RegisterClass, _P ## bitNr> {}
00495 
00496 __DECLARE_BIT_NUMBER__(0);
00497 __DECLARE_BIT_NUMBER__(1);
00498 __DECLARE_BIT_NUMBER__(2);
00499 __DECLARE_BIT_NUMBER__(3);
00500 __DECLARE_BIT_NUMBER__(4);
00501 __DECLARE_BIT_NUMBER__(5);
00502 __DECLARE_BIT_NUMBER__(6);
00503 __DECLARE_BIT_NUMBER__(7);
00504 
00505 #undef __DECLARE_BIT_NUMBER__
00506 
00507 #endif // ifndef EXCLUDE_BIT_NUMBERS
00508 
00509 
00510 /**********************************************************************************************************************/
00511 
00512 } // namespace AVRCpp
00513 
00514 
00515 /**********************************************************************************************************************/
00516 
00517 #endif // ifndef __AVR_CPP_DIVERSE_IO_H__

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