137 lines
3.6 KiB
C++
137 lines
3.6 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_ */
|