/* * GpioPinDecoder.hpp * * Created on: 17 янв. 2019 г. * Author: maksimenko */ #ifndef SOURCE_DRIVER_GPIOPINDECODER_H_ #define SOURCE_DRIVER_GPIOPINDECODER_H_ #include "../peripheral/IGpio.hh" namespace driver { template class GpioPinDecoder { public: typedef unsigned short Id; GpioPinDecoder( peripheral::IGpio * gpios[resolution], bool input_inverse, Id default_pin ); ~GpioPinDecoder() = default; peripheral::IGpio * grab( Id id ); private: struct Decoder { void set( Id pin_num ) { address = pin_num; for( int bit_pos = 0; bit_pos < resolution; bit_pos++ ) { out.mGpio[bit_pos]->write( bool(address & ( 1 << bit_pos )) xor invert ); } } void clear() { set( default_address ); } bool read( Id pin_num ) const { return pin_num == address; } GpioPinDecoder & out; short address; const short default_address; //этот адрес устанавливается при выполнении clear() const bool invert; Decoder( GpioPinDecoder & gpio_decoder, Id default_address, bool invert ) : out(gpio_decoder), default_address(default_address), invert(invert), address(default_address) {} }; Decoder decoder; struct PinDecoder : public peripheral::IGpio { Id mId; Decoder * mDecoder; void set() override { mDecoder->set( mId ); } void clear() override { mDecoder->clear(); } bool read() const override { return mDecoder->read( mId ); } void write(bool value) override { value ? set() : clear(); } void toggle() override { write( not read() ); } PinDecoder( Id mId, Decoder * mDecoder) : mId(mId), mDecoder(mDecoder) {} PinDecoder() : mId(0), mDecoder(nullptr) {} //!todo: }; static const Id pin_count = 1 << resolution; PinDecoder pins[pin_count]; peripheral::IGpio * mGpio[resolution];// Хранилище адресных индексов GPIO }; } // namespace driver template inline driver::GpioPinDecoder::GpioPinDecoder( peripheral::IGpio * gpios[resolution], bool input_inverse, Id default_pin ) : decoder( *this, default_pin, input_inverse ) { for(Id i = 0; i < resolution; i++) mGpio[i] = gpios[i]; for(Id i = 0; i < pin_count; i++) pins[i] = PinDecoder( i, &decoder); } template inline peripheral::IGpio * driver::GpioPinDecoder::grab( Id id ) { return id < pin_count ? &pins[static_cast(id)] : nullptr; } #endif /* SOURCE_PERIPHERAL_GPIOPINDECODER_HPP_ */