106 lines
2.7 KiB
C++
106 lines
2.7 KiB
C++
/*
|
||
* 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<unsigned short resolution>
|
||
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<unsigned short resolution>
|
||
inline driver::GpioPinDecoder<resolution>::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<unsigned short resolution>
|
||
inline peripheral::IGpio * driver::GpioPinDecoder<resolution>::grab( Id id ) {
|
||
|
||
return id < pin_count ? &pins[static_cast<short>(id)] : nullptr;
|
||
|
||
}
|
||
|
||
#endif /* SOURCE_PERIPHERAL_GPIOPINDECODER_HPP_ */
|