137 lines
3.8 KiB
C++
137 lines
3.8 KiB
C++
/*
|
||
* SpiPortRoutineOperation.hpp
|
||
*
|
||
* Created on: 17 июл. 2019 г.
|
||
* Author: titov
|
||
*/
|
||
|
||
#ifndef SOURCE_DRIVER_SPIPORTROUTINEOPERATION_HPP_
|
||
#define SOURCE_DRIVER_SPIPORTROUTINEOPERATION_HPP_
|
||
|
||
#include "../peripheral/ISerialPort.hh"
|
||
|
||
#include <cstddef>
|
||
#include <stdint.h>
|
||
|
||
namespace driver {
|
||
|
||
template<typename Latency = uint16_t>
|
||
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<typename Frame, typename Latency>
|
||
struct SpiOperationPack : public SpiPortRoutineOperation<Latency> {
|
||
|
||
Frame output; //<!Фрейм получаемый из порта.
|
||
Frame input; //<!Фрейм отправляемый в порт.
|
||
|
||
std::size_t frame_size;
|
||
|
||
SpiOperationPack( peripheral::ISerialPort & port, std::size_t frame_size, Frame in_frame, Latency & latency );
|
||
SpiOperationPack( const SpiOperationPack & rh );
|
||
SpiOperationPack & operator=( const SpiOperationPack & rh ) = delete;
|
||
};
|
||
|
||
}
|
||
|
||
template<typename Latency>
|
||
inline driver::SpiPortRoutineOperation<Latency>::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<typename Latency>
|
||
bool driver::SpiPortRoutineOperation<Latency>::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<typename Latency>
|
||
bool driver::SpiPortRoutineOperation<Latency>::routine_send() {
|
||
bool result = false;
|
||
|
||
if( port.transmite(in, frame_size) ) {
|
||
result = true;
|
||
} else
|
||
++latency;
|
||
|
||
return result;
|
||
}
|
||
|
||
template<typename Latency>
|
||
bool driver::SpiPortRoutineOperation<Latency>::routine_receive() {
|
||
bool result = false;
|
||
|
||
if( port.receive(out) ) {
|
||
latency = 0;
|
||
result = true;
|
||
} else
|
||
++latency;
|
||
|
||
return result;
|
||
}
|
||
|
||
template<typename Frame, typename Latency>
|
||
inline driver::SpiOperationPack<Frame, Latency>::SpiOperationPack(
|
||
peripheral::ISerialPort & port, std::size_t frame_size, Frame in_frame, Latency & latency) : SpiPortRoutineOperation<Latency>( port, &input, &output, frame_size, latency ),
|
||
input(in_frame), frame_size(
|
||
frame_size)
|
||
{
|
||
}
|
||
|
||
template<typename Frame, typename Latency>
|
||
inline driver::SpiOperationPack<Frame, Latency>::SpiOperationPack(
|
||
const SpiOperationPack & rh ) : SpiPortRoutineOperation<Latency>( rh.port, &input, &output, rh.frame_size, rh.latency ),
|
||
input( rh.input ), output( rh.output ), frame_size( rh.frame_size ) {}
|
||
|
||
//template<typename Frame, typename Latency>
|
||
//inline SpiOperationPack & driver::SpiOperationPack<Frame, Latency>::operator =(
|
||
// const SpiOperationPack & rh ) {
|
||
//
|
||
//
|
||
//
|
||
//}
|
||
|
||
#endif /* SOURCE_DRIVER_SPIPORTROUTINEOPERATION_HPP_ */
|