/* * Copyright (c) by BlackMark 2015-2016 * Date 05/01/2016 * Version 2.3 */ #ifndef INOUT_H #define INOUT_H #include #include #define AVR_DIP40 defined (__AVR_ATmega32A__) || defined (__AVR_ATmega644P__) || defined (__AVR_ATmega1284P__) #define AVR_DIP28 defined (__AVR_ATmega8__) || defined (__AVR_ATmega168A__) || defined (__AVR_ATmega328P__) #define AVR_DIP8 defined (__AVR_ATtiny13A__) #if AVR_DIP40 #define PORT_PINA &PINA #define PORT_DDRA &DDRA #define PORT_PORTA &PORTA #else #define PORT_PINA nullptr #define PORT_DDRA nullptr #define PORT_PORTA nullptr #endif #if AVR_DIP40 || AVR_DIP28 || AVR_DIP8 #define PORT_PINB &PINB #define PORT_DDRB &DDRB #define PORT_PORTB &PORTB #else #define PORT_PINB nullptr #define PORT_DDRB nullptr #define PORT_PORTB nullptr #endif #if AVR_DIP40 || AVR_DIP28 #define PORT_PINC &PINC #define PORT_DDRC &DDRC #define PORT_PORTC &PORTC #else #define PORT_PINC nullptr #define PORT_DDRC nullptr #define PORT_PORTC nullptr #endif #if AVR_DIP40 || AVR_DIP28 #define PORT_PIND &PIND #define PORT_DDRD &DDRD #define PORT_PORTD &PORTD #else #define PORT_PIND nullptr #define PORT_DDRD nullptr #define PORT_PORTD nullptr #endif class InOut { public: enum class Pin { P_NONE = -1, #if AVR_DIP40 P_A0 = 0x00, P_A1 = 0x01, P_A2 = 0x02, P_A3 = 0x03, P_A4 = 0x04, P_A5 = 0x05, P_A6 = 0x06, P_A7 = 0x07, #endif #if AVR_DIP40 || AVR_DIP28 || AVR_DIP8 P_B0 = 0x10, P_B1 = 0x11, P_B2 = 0x12, P_B3 = 0x13, P_B4 = 0x14, P_B5 = 0x15, #endif #if AVR_DIP40 || AVR_DIP28 P_B6 = 0x16, P_B7 = 0x17, P_C0 = 0x20, P_C1 = 0x21, P_C2 = 0x22, P_C3 = 0x23, P_C4 = 0x24, P_C5 = 0x25, P_C6 = 0x26, #endif #if AVR_DIP40 P_C7 = 0x27, #endif #if AVR_DIP40 || AVR_DIP28 P_D0 = 0x30, P_D1 = 0x31, P_D2 = 0x32, P_D3 = 0x33, P_D4 = 0x34, P_D5 = 0x35, P_D6 = 0x36, P_D7 = 0x37, #endif }; enum class Dir { D_IN = 0, D_OUT = 1 }; enum class Type { T_PIN = 0, T_DDR = 1, T_PORT = 2 }; static volatile uint8_t* getPort( Pin enmPin, Type enmType ); static uint8_t getPin( Pin enmPin ); static void setPinDirection( Pin enmPin, Dir enmDir, bool bPullup = true ); static bool readPin( Pin enmPin ); static void writePin( Pin enmPin, bool bValue ); static uint8_t readPort( Pin enmPortPin ); static void writePort( Pin enmPortPin, uint8_t ui8Value ); ////////////////////////////////////////////////////////////////////////// static inline void setPinDirection( volatile uint8_t* vpui8Port, uint8_t ui8Pin, Dir enmDir ) { if( enmDir == Dir::D_OUT ) { *vpui8Port |= ( 1 << ui8Pin ); } else { *vpui8Port &= ~( 1 << ui8Pin ); } } ////////////////////////////////////////////////////////////////////////// static inline bool readPin( volatile uint8_t* vpui8Port, uint8_t ui8Pin ) { if( ( ( *vpui8Port ) >> ui8Pin ) & 1 ) { return true; } return false; } ////////////////////////////////////////////////////////////////////////// static inline void writePin( volatile uint8_t* vpui8Port, uint8_t ui8Pin, bool bValue ) { if( bValue ) { *vpui8Port |= ( 1 << ui8Pin ); } else { *vpui8Port &= ~( 1 << ui8Pin ); } } ////////////////////////////////////////////////////////////////////////// static inline void setPortDirection( volatile uint8_t* vpui8Port, Dir enmDir ) { *vpui8Port = ( ( enmDir == InOut::Dir::D_OUT ) ? ( 0xFF ) : ( 0x00 ) ); } ////////////////////////////////////////////////////////////////////////// static inline uint8_t readPort( volatile uint8_t* vpui8Port ) { return *vpui8Port; } ////////////////////////////////////////////////////////////////////////// static inline void writePort( volatile uint8_t* vpui8Port, uint8_t ui8Value ) { *vpui8Port = ui8Value; } }; ////////////////////////////////////////////////////////////////////////// class InOutPin { private: volatile uint8_t* m_vpui8Input; volatile uint8_t* m_vpui8Dir; volatile uint8_t* m_vpui8Output; uint8_t m_ui8Pin; public: InOutPin(); InOutPin( InOut::Pin enmPin ); ~InOutPin(); void setPin( InOut::Pin enmPin ); ////////////////////////////////////////////////////////////////////////// inline void setDirection( InOut::Dir enmDir, bool bPullup = true ) { if( !m_vpui8Dir || !m_vpui8Output ) { return; } InOut::setPinDirection( m_vpui8Dir, m_ui8Pin, enmDir ); if( enmDir == InOut::Dir::D_IN && bPullup ) { InOut::writePin( m_vpui8Output, m_ui8Pin, true ); } else if( enmDir == InOut::Dir::D_IN && !bPullup ) { InOut::writePin( m_vpui8Output, m_ui8Pin, false ); } } ////////////////////////////////////////////////////////////////////////// inline bool read() { if( !m_vpui8Input ) { return false; } return InOut::readPin( m_vpui8Input, m_ui8Pin ); } ////////////////////////////////////////////////////////////////////////// inline void write( bool bValue ) { if( !m_vpui8Output ) { return; } InOut::writePin( m_vpui8Output, m_ui8Pin, bValue ); } }; ////////////////////////////////////////////////////////////////////////// class InOutPort { private: volatile uint8_t* m_vpui8Input; volatile uint8_t* m_vpui8Dir; volatile uint8_t* m_vpui8Output; public: InOutPort(); InOutPort( InOut::Pin enmPortPin ); ~InOutPort(); void setPort( InOut::Pin enmPortPin ); ////////////////////////////////////////////////////////////////////////// inline void setDirection( InOut::Dir enmDir, bool bPullup = true ) { if( !m_vpui8Dir || !m_vpui8Output ) { return; } InOut::setPortDirection( m_vpui8Dir, enmDir ); if( enmDir == InOut::Dir::D_IN && bPullup ) { InOut::writePort( m_vpui8Output, 0xFF ); } else if( enmDir == InOut::Dir::D_IN && !bPullup ) { InOut::writePort( m_vpui8Output, 0x00 ); } } ////////////////////////////////////////////////////////////////////////// inline uint8_t read() { if( !m_vpui8Input ) { return 0; } return InOut::readPort( m_vpui8Input ); } ////////////////////////////////////////////////////////////////////////// inline void write( uint8_t ui8Value ) { if( !m_vpui8Output ) { return; } InOut::writePort( m_vpui8Output, ui8Value ); } }; #endif