MotorControlModuleSDFM_TMS3.../Projects/EFC_Application/UMLibrary/driver/SpiPortRoutineOperation.hpp

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