118 lines
2.4 KiB
C++
118 lines
2.4 KiB
C++
/*
|
||
* PinIO.h
|
||
*
|
||
* Created on: 18 июл. 2019 г.
|
||
* Author: titov
|
||
*/
|
||
|
||
#ifndef SOURCE_DRIVER_PINIO_H_
|
||
#define SOURCE_DRIVER_PINIO_H_
|
||
|
||
#include "../peripheral/IGpio.hh"
|
||
|
||
#include <cstddef>
|
||
#include <stdint.h>
|
||
|
||
namespace driver {
|
||
|
||
template<typename PortType>
|
||
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 <exception>
|
||
#include <cstddef>
|
||
|
||
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<typename PortType>
|
||
inline driver::PinIO<PortType>::PinIO( Id id, bool default_state, const volatile Input & input, volatile Output & output ) :
|
||
input(input), output(output), mask( static_cast<PortType>(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<typename PortType>
|
||
inline void driver::PinIO<PortType>::write( bool state ) {
|
||
|
||
output.data = state ? output.data | mask : output.data & ~mask;
|
||
|
||
}
|
||
|
||
template<typename PortType>
|
||
inline void driver::PinIO<PortType>::set() {
|
||
|
||
output.data |= mask;
|
||
|
||
}
|
||
|
||
template<typename PortType>
|
||
inline void driver::PinIO<PortType>::clear() {
|
||
|
||
output.data &= ~mask;
|
||
|
||
}
|
||
|
||
template<typename PortType>
|
||
inline void driver::PinIO<PortType>::toggle() {
|
||
|
||
output.data ^= mask;
|
||
|
||
}
|
||
|
||
template<typename PortType>
|
||
inline bool driver::PinIO<PortType>::read() const {
|
||
|
||
return input.data & mask;
|
||
|
||
}
|
||
|
||
#endif /* SOURCE_DRIVER_PINIO_H_ */
|