MotorControlModuleSDFM_TMS3.../Projects/EFC_Application/UMLibrary/driver/PinIO.hh

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_ */