224 lines
6.7 KiB
C++
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_ */
|