MotorControlModuleSDFM_TMS3.../Projects/EFC_Communication/UMLibrary/driver/SlipCommunication.hh
2024-06-07 11:12:56 +03:00

224 lines
8.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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