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

224 lines
6.7 KiB
C++

/*
* SlipCommunication.h
*
* Created on: 31 ìàðòà 2017 ã.
* Author: titov
*/
#ifndef SOURCES_DRIVERS_SLIPCOMMUNICATION_H_
#define SOURCES_DRIVERS_SLIPCOMMUNICATION_H_
#include "../driver/IDataLink.hh"
#include "../driver/ISlipCommunication.hh"
#include "../peripheral/IUartPort.hh"
#include "../driver/IDiscreteOutput.hh"
#include "../systemic/IProcess.hh"
#include "../systemic/Timer.hh"
#include "../common/CircularBuffer.hpp"
#include "../common/Crc.hh"
#include <cstddef>
#include <stdint.h>
namespace driver {
//todo: depricated!!!!
class SlipCommunication : public ISlipCommunication, public systemic::IProcess {
private:
//!Ñòðóêòóðà îïèñàíèÿ ðåæèìà ïðèåìà áàéò.
struct TReceiveMode {
enum ID {
HEAD = 0, //!<Ïðèåì çàãîëîâêà.
DATA = 1, //!<Ïðèåì äàííûõ.
CRC16 = 2, //!<Ïðèåì êîíòðîëüíîé ñóììû.
STOP = 3, //!<Îæèäàíèå êîíöà ïàêåòà.
SLEEP = 4 //!<Ïðîïóñê âñåõ äàííûõ.
};
};
//!Ñòðóêòóðà îïèñûâàåò êîäû ñëèï-ïàêåòà.
struct TSlipDecode {
enum BYTECODE {
DB = 0x00DB,
DC = 0x00DC,
DD = 0x00DD,
C0 = 0x00C0
};
static const unsigned short END = 0xC0C0;
static const unsigned short ERROR = 0xFFC0;
static const unsigned short NOTBYTE = 0xDBDB;
};
static const int head_size = 5; //!<Ðàçìåð áóôåðà äëÿ çàãîëîâêà.
//!Ñòðóêòóðà îïèñûâàåò äàííûå çàãîëîâêà ïàêåòà.
struct THead {
unsigned short packet_size; //! Ñëîâî ðàçìåðà ïàêåòà.
unsigned short packet_id; //! Ñëîâî èäåíòèôèêàòîð ïàêåòà.
unsigned short hw_address; //! Àäðåñóåìûé àáîíåíò.
THead() : packet_size(0), packet_id(0), hw_address(0) {}
void deserialize(char (& buff)[head_size]);
};
//!Ìàêñèìàëüíûé ðàçìåð äàííûõ â áàéòàõ äëÿ âõîäÿùåãî ïàêåòà.
int max_datasize;
//!Àäðåñ íà øèíå.
unsigned short hw_address;
SlipCommunication & operator=(const SlipCommunication &);
SlipCommunication(SlipCommunication &);
bool packet_start = false;
private:
static const std::size_t rx_buffer = 128;
peripheral::IUartPort & bus; //!<Øèíà ïåðåäà÷è äàííûõ.
driver::IDiscreteOutput & de; //!<Ïèí âûáîðà íàïðàâëåíèÿ ïåðåäà÷è äàííûõ.
systemic::Timer timeout; //!<Òàéìàóò äëÿ ïðèíÿòèÿ áàéò
unsigned int error_count;
const unsigned int max_error;
bool bus_enable;
//TODO: Äðåâíèé öðö.
Crc<16, 0x1021, 0xFFFF, false, false, 0> crc16rec; //!<Êîíòðîëüíàÿ ñóììà äëÿ ïðèíÿòûõ äàííûõ
Crc<16, 0x1021, 0xFFFF, false, false, 0> crc16send; //!<Êîíòðëüíàÿ ñóììà äëÿ îòïðàâëÿåìûõ äàííûõ
//!Êîëè÷åñòâî ïîëó÷åííûõ ïàêåòîâ.
int incoming_packet;
//!Ðåæèì ïðèåìà.
TReceiveMode::ID receive_mode;
//!Áàéò-çàìåíèòåëü ïðèíÿò.
bool byte_db_recived;
//!Äàííûå ãîòîâû.
bool data_ready;
//Äåøèôðîâàíûå çàãîëîâîê è êîíòðîëüíàÿ ñóììà.
THead packet_head; //!<Çàãîëîâîê.
unsigned int packet_crc16; //!<Êîíòðîëüíàÿ ñóììà äàííûõ.
//Áóôåð çàãîëîâêà.
int count_head_byte; //!<Êîëè÷åñòâî ïðèíÿòûõ áàéò çàãîëîâêà.
char head_buff[head_size]; //!<Áóôåð äëÿ çàãîëîâêà.
//Áóôåð äàííûõ.
int count_data_byte; //!<Êîëè÷åñòâî ïðèíÿòûõ áàéò äàííûõ.
//TODO: Öèðêóëÿðíûé áóôåð âìåñòå ñ îáúåêòîì.
int totalRecLength; //!<Êîëè÷åñòâî îñòàâøèõñÿ íå ñ÷èòàííûõ áàéò.
CircularBuffer<rx_buffer> receiveBuffer; //!<Áóôåð ïðèíèìàåìûõ äàííûõ
//Áóôåð êîíòðîëüíîé ñóììû.
int count_crc16_byte; //!<Êîëè÷åñòâî ïðèíÿòûõ áàéò êîíòðîëüíîé ñóììû.
static const int crc16_size = 2; //!<Ðàçìåð áóôåðà äëÿ êîíòðîëüíîé ñóììû.
char crc16_buff[crc16_size]; //!<Áóôåð äëÿ êîíòðîëüíîé ñóììû.
private:
void recieve_restart(); //!<Ïåðåõîä â îæèäàíèå íîâîãî ñîîáùåíèÿ.
void create_packet(); //!<Ôîðìèðîâàíèå ïàêåòà.
bool packet_end() const; //!Ïðèçíàê îêîí÷àíèÿ ïðèåìà ïàêåòà. \return Äàííûå ñîáðàíû.
bool data_collection(char byte); //!Ñáîð âõîäÿùèõ áàéò äëÿ ïàêåòà. \return Äàííûå ñîáðàíû.
/*!\brief Ôóíêöèÿ äåêîäèðîâàíèÿ slip ïðîòîêîëà.
* \return Äåêîäèðîâàííûé áàéò èëè ñïåöèàëüíîå ñîñòîÿíèå.*/
unsigned short slip_decode(char byte);
/*!\brief Îáðàáîòêà íîâîãî ïðèíÿòîãî áàéòà.
* \return Ïðèçíàê çàâåðøåíèÿ ïðèåìà òåêóùåãî ïàêåòà.*/
bool byte_processing(char byte);
/*!\brief Ôóíêöèÿ êîäèðîâàíèÿ â slip è îòïðàâêè áàéòà.
* \return Ïðèçíàê óñïåøíîé îòïðàâêè áàéòà. */
bool slip_send(char byte);
/*!\brief Ôóíêöèÿ îòïðàâêè ñëîâà áåç ïîäñ÷åòà CRC16.
* \return Ïðèçíàê óñïåøíîé îòïðàâêè áàéòà.*/
bool send_word_without_crc(unsigned short word);
/*!\brief Ôóíêöèÿ îòïðàâêè áàéòà c ïîäñ÷åòîì CRC16.
* \return Ïðèçíàê óñïåøíîé îòïðàâêè áàéòà.*/
bool send_byte_with_crc(unsigned char byte);
/*!\brief Ôóíêöèÿ îòïðàâêè ñëîâà c ïîäñ÷åòîì CRC16.
* \return Ïðèçíàê óñïåøíîé îòïðàâêè ñëîâà.*/
bool send_word_with_crc(unsigned short word);
/*!\brief Ôóíêöèÿ ïîëó÷åíèÿ î÷åðåäíîãî ñëîâà èç áóôåðà.
* \return Ñëîâî èç áóôåðà.*/
unsigned short recieve_word();
/*!\brief Ôóíêöèÿ ïîëó÷åíèÿ î÷åðåäíîãî ñëîâà èç áóôåðà.
* \return Ñëîâî èç áóôåðà.*/
char recieve_byte();
void deserialize_crc16(); //!<Ôîðìèðîâàíèå êîíòðîëüíîé ñóììû èç ïðèíÿòûõ áàéò.
/*!\brief Ôóíêöèÿ ïðèåìà äàííûõ, ïîòîêîì.
* \return Ïðèçíàê ïðèåìà äàííûõ.*/
bool recieve_data(char * data, short length);
/*!\brief Ôóíêöèÿ îòïðàâëåíèÿ ïàêåòà, öåëèêîì.
* \return Ïðèçíàê îòïðàâêè ïàêåòà.*/
bool send_packet(unsigned short id, const char * data, short length);
/*!\brief Ôóíêöèÿ ñáðîñà îòïðàâëÿåìûõ áàéò. */
void send_reset();
/*!\brief Ôóíêöèÿ îòïðàâëåíèÿ áàéòà, ïîòîêîì.
* \param[in] byte - áàéò äëÿ îòïðàâêè.
* \param[in] first_data - ïðèçíàê îòïðàâêè ïåðâîé ïàðòèè äàííûõ, â ñëó÷àå åñëè îòïðàâëÿåòñÿ ïàêåò áåç çàãîëîâêà.
* \return Ïðèçíàê îòïðàâêè äàííûõ. */
bool send_byte(unsigned short byte, bool first_data = false);
public:
std::pair<bool, unsigned short> isPacketAvailable() const;
std::size_t packetSize() const { return packet_head.packet_size; }
/*!\brief Ôóíêöèÿ îòïðàâëåíèÿ çàãîëîâî÷íûõ äàííûõ.
* \param[in] id Òèï ñîîáùåíèÿ.
* \param[in] size Ðàçìåð ïîëÿ äàííûõ, â áàéò.
* \return Ïðèçíàê îòïðàâêè äàííûõ.*/
bool sendHead(unsigned short id, unsigned short size) noexcept;
bool send( const char * data, std::size_t size );
bool receive( char * data, std::size_t size );
/*!\brief Ôóíêöèÿ ñáðîñà ïðèíÿòûõ äàííûõ.
**/
void recieveReset();
/*!\brief Ôóíêöèÿ îòïðàâëåíèÿ êîíöà ïàêåòà.
* \return Ïðèçíàê îòïðàâêè äàííûõ.*/
bool sendEnd() noexcept;
bool isPacketSent() const;
std::size_t transmitBuffCapacity() const { return ( bus.transmitBuffCapacity() / 2 ) - 5 - 3; }
std::size_t receiveBuffCapacity() const { return rx_buffer; }
public:
SlipCommunication(
peripheral::IUartPort & bus,
driver::IDiscreteOutput & de = driver::getDummyOutput()
);
virtual ~SlipCommunication();
void setAddress(unsigned short address);
virtual void process();
};
}
#endif /* SOURCES_DRIVERS_SLIPCOMMUNICATION_H_ */