106 lines
2.6 KiB
C++
106 lines
2.6 KiB
C++
|
|
/*
|
|||
|
|
* GpioPinDecoder.hpp
|
|||
|
|
*
|
|||
|
|
* Created on: 17 <EFBFBD><EFBFBD><EFBFBD>. 2019 <EFBFBD>.
|
|||
|
|
* 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; //<2F><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 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];// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 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_ */
|