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

224 lines
8.6 KiB
C++
Raw Normal View History

2024-06-07 11:12:56 +03:00
/*
* 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_ */