/* * PinIO.h * * Created on: 18 èþë. 2019 ã. * Author: titov */ #ifndef SOURCE_DRIVER_PINIO_H_ #define SOURCE_DRIVER_PINIO_H_ #include "../peripheral/IGpio.hh" #include #include namespace driver { template class PinIO : public peripheral::IGpio { public: typedef unsigned short Id; struct Input { PortType data; }; struct Output { PortType engaged; PortType data; }; PinIO( Id id, bool default_state, const volatile Input & input, volatile Output & output ); void write(bool) override; void set() override; void clear() override; void toggle() override; bool read() const override; private: const volatile Input & input; volatile Output & output; const PortType mask; }; } #include #include struct BadPinId : public std::exception { uint16_t id; std::size_t port_size; BadPinId( uint16_t id, std::size_t port_size ) : id(id), port_size(port_size) {} const char * what() const noexcept { return "PinIO: id"; } }; struct EngagedPinId : public std::exception { uint16_t id; std::size_t port_size; EngagedPinId( uint16_t id, std::size_t port_size ) : id(id), port_size(port_size) {} const char * what() const noexcept { return "PinIO: engaged"; } }; template inline driver::PinIO::PinIO( Id id, bool default_state, const volatile Input & input, volatile Output & output ) : input(input), output(output), mask( static_cast(1) << id ) { if( not mask ) throw BadPinId( id, sizeof(PortType) ); if( output.engaged & mask ) throw EngagedPinId( id, sizeof(PortType) ); write( default_state ); output.engaged |= mask; } template inline void driver::PinIO::write( bool state ) { output.data = state ? output.data | mask : output.data & ~mask; } template inline void driver::PinIO::set() { output.data |= mask; } template inline void driver::PinIO::clear() { output.data &= ~mask; } template inline void driver::PinIO::toggle() { output.data ^= mask; } template inline bool driver::PinIO::read() const { return input.data & mask; } #endif /* SOURCE_DRIVER_PINIO_H_ */