/* * SpiPortRoutineOperation.hpp * * Created on: 17 июл. 2019 г. * Author: titov */ #ifndef SOURCE_DRIVER_SPIPORTROUTINEOPERATION_HPP_ #define SOURCE_DRIVER_SPIPORTROUTINEOPERATION_HPP_ #include "../peripheral/ISerialPort.hh" #include #include namespace driver { template class SpiPortRoutineOperation { public: SpiPortRoutineOperation(peripheral::ISerialPort & port, const void * in_frame, void * out_frame, std::size_t frame_size, Latency & latency ); /*! \brief Перегрузка оператор вызова * \detail Декарирование последовательного вызова функции чтения и записи и перехода между ними * \return Признак успешного завершения операции обмена данными по линии SPI */ bool operator()(); private: enum { SEND, RECEIVE } op; private: bool routine_send(); bool routine_receive(); protected: peripheral::ISerialPort & port; const void * const in; void * const out; const std::size_t frame_size; Latency & latency; }; template struct SpiOperationPack : public SpiPortRoutineOperation { Frame output; // inline driver::SpiPortRoutineOperation::SpiPortRoutineOperation( peripheral::ISerialPort & port, const void * in_frame, void * out_frame, std::size_t frame_size, Latency & latency ) : port(port), in(in_frame), out(out_frame), latency(latency), frame_size(frame_size), op(SEND) {} template bool driver::SpiPortRoutineOperation::operator()() { bool routine_report = false; switch(op) { case SEND: { if( routine_send() ) { op = RECEIVE; } } break; case RECEIVE: { if( routine_receive() ) { op = SEND; routine_report = true; } } break; } return routine_report; } template bool driver::SpiPortRoutineOperation::routine_send() { bool result = false; if( port.transmite(in, frame_size) ) { result = true; } else ++latency; return result; } template bool driver::SpiPortRoutineOperation::routine_receive() { bool result = false; if( port.receive(out) ) { latency = 0; result = true; } else ++latency; return result; } template inline driver::SpiOperationPack::SpiOperationPack( peripheral::ISerialPort & port, std::size_t frame_size, Frame in_frame, Latency & latency) : SpiPortRoutineOperation( port, &input, &output, frame_size, latency ), input(in_frame), frame_size( frame_size) { } template inline driver::SpiOperationPack::SpiOperationPack( const SpiOperationPack & rh ) : SpiPortRoutineOperation( rh.port, &input, &output, rh.frame_size, rh.latency ), input( rh.input ), output( rh.output ), frame_size( rh.frame_size ) {} //template //inline SpiOperationPack & driver::SpiOperationPack::operator =( // const SpiOperationPack & rh ) { // // // //} #endif /* SOURCE_DRIVER_SPIPORTROUTINEOPERATION_HPP_ */