// Copyright 2009 Olivier Gillet. // // Author: Olivier Gillet (ol.gillet@gmail.com) // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // ----------------------------------------------------------------------------- // // Templates for using full ports or half-ports for parallel output #ifndef AVRLIB_PARALLEL_H_ #define AVRLIB_PARALLEL_H_ #include #include "avrlib/gpio.h" namespace avrlib { enum ParallelPortMode { PARALLEL_BYTE, PARALLEL_NIBBLE_HIGH, PARALLEL_NIBBLE_LOW, PARALLEL_TRIPLE_HIGHEST, PARALLEL_TRIPLE_HIGH, PARALLEL_TRIPLE_LOW, PARALLEL_DOUBLE_HIGH, PARALLEL_DOUBLE_MIDHIGH, PARALLEL_DOUBLE_MIDLOW, PARALLEL_DOUBLE_LOW }; template struct ShiftMasks { enum Masks { mask = 0xff, shift = 0 }; }; template<> struct ShiftMasks { enum Masks { mask = 0xf0, shift = 4, }; }; template<> struct ShiftMasks { enum Masks { mask = 0x0f, shift = 0, }; }; template<> struct ShiftMasks { enum Masks { mask = 0xe0, shift = 5, }; }; template<> struct ShiftMasks { enum Masks { mask = 0x38, shift = 3, }; }; template<> struct ShiftMasks { enum Masks { mask = 0x07, shift = 0, }; }; template<> struct ShiftMasks { enum Masks { mask = 0xc0, shift = 6, }; }; template<> struct ShiftMasks { enum Masks { mask = 0x30, shift = 4, }; }; template<> struct ShiftMasks { enum Masks { mask = 0x0c, shift = 2, }; }; template<> struct ShiftMasks { enum Masks { mask = 0x03, shift = 0, }; }; template struct ParallelPort { typedef ShiftMasks Masks; // Mode change. static inline void set_mode(uint8_t mode) { uint8_t preserve = (*Port::Mode::ptr() & ~Masks::mask); if (mode == DIGITAL_INPUT) { *Port::Mode::ptr() = preserve; } else if (mode == DIGITAL_OUTPUT) { *Port::Mode::ptr() = preserve | Masks::mask; } } static inline void Write(uint8_t value) { uint8_t preserve = *Port::Output::ptr() & ~Masks::mask; *Port::Output::ptr() = preserve | (value << Masks::shift); } static inline void EnablePullUpResistors() { uint8_t preserve = *Port::Output::ptr(); *Port::Output::ptr() = preserve | Masks::mask; } static inline uint8_t Read() { return (*Port::Input::ptr() & Masks::mask) >> Masks::shift; } }; } // namespace avrlib #endif // AVRLIB_PARALLEL_H_