From 2ada510c3aab06b25ca8ee6f8cf91901d872a519 Mon Sep 17 00:00:00 2001 From: zhaohe Date: Wed, 7 Aug 2024 16:18:28 +0800 Subject: [PATCH] update --- CMakeLists.txt | 5 +- app_protocols/transmit_disfection_protocol | 2 +- app_protocols/zscanprotocol | 2 +- .../transmit_disinfection_can_master.cpp | 0 .../transmit_disinfection_can_master.hpp | 60 ++++++ src/main.cpp | 2 + src/protocol/waveshare_can/waveshare_can.cpp | 167 +++++++++++++++ src/protocol/waveshare_can/waveshare_can.hpp | 112 ++++++++++ .../zscanprotocol_com/zscanprotocol_com.cpp | 226 +++++++++++++++++++++ .../zscanprotocol_com/zscanprotocol_com.hpp | 107 ++++++++++ src/zqui/base/appbuilder.hpp | 3 +- src/zqui/channelmgr/channelmgr.hpp | 4 +- src/zqui/channelmgr/qt_serial_datachannel.cpp | 18 +- src/zqui/channelmgr/qt_serial_datachannel.hpp | 10 +- src/zqui/zqui/mainwindow.h | 4 - src/zqui/zqui/zqui.hpp | 3 +- 16 files changed, 702 insertions(+), 23 deletions(-) create mode 100644 src/app/transmit_disinfection/transmit_disinfection_can_master.cpp create mode 100644 src/app/transmit_disinfection/transmit_disinfection_can_master.hpp create mode 100644 src/protocol/waveshare_can/waveshare_can.cpp create mode 100644 src/protocol/waveshare_can/waveshare_can.hpp create mode 100644 src/protocol/zscanprotocol_com/zscanprotocol_com.cpp create mode 100644 src/protocol/zscanprotocol_com/zscanprotocol_com.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ca9613..70f4512 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,19 +18,18 @@ find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets SerialPort Charts Concurre include_directories(libxsync/include) include_directories(src) include_directories(./) +include_directories(./app_protocols/) include_directories(libzqt) add_compile_options(-Wall ) - - file(GLOB_RECURSE APPSRC # src/*.cpp # src/*.c # src/*.ui # src/*.h # src/*.hpp # -) +) set(PROJECT_SOURCES ${APPSRC} diff --git a/app_protocols/transmit_disfection_protocol b/app_protocols/transmit_disfection_protocol index fe4173b..6573835 160000 --- a/app_protocols/transmit_disfection_protocol +++ b/app_protocols/transmit_disfection_protocol @@ -1 +1 @@ -Subproject commit fe4173bbfefd7d6648fbea94717605764b4e7594 +Subproject commit 6573835a56f8b1dd2aa1311b6f6136bcc0d182bd diff --git a/app_protocols/zscanprotocol b/app_protocols/zscanprotocol index a72ab76..5161e29 160000 --- a/app_protocols/zscanprotocol +++ b/app_protocols/zscanprotocol @@ -1 +1 @@ -Subproject commit a72ab76f401598ef36a95107a4298292b6c36d8e +Subproject commit 5161e29f77f08d1e1bea60827b0ee937fa7943bf diff --git a/src/app/transmit_disinfection/transmit_disinfection_can_master.cpp b/src/app/transmit_disinfection/transmit_disinfection_can_master.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/app/transmit_disinfection/transmit_disinfection_can_master.hpp b/src/app/transmit_disinfection/transmit_disinfection_can_master.hpp new file mode 100644 index 0000000..df7628f --- /dev/null +++ b/src/app/transmit_disinfection/transmit_disinfection_can_master.hpp @@ -0,0 +1,60 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +#include "protocol/zscanprotocol_com/zscanprotocol_com.hpp" +#include "zqui/zqui/zqui.hpp" + +namespace iflytop { +using namespace std; + +class TransmitDisinfectionCanMaster { + TransmitDisinfectionCanMaster() {} + + WaveshareCan *m_channel = nullptr; + + uint8_t m_rxcache[1024] = {0}; + int32_t m_rxlen = 0; + bool m_rxcache_is_full = false; + + mutex lock_; + + unique_ptr m_thread; + + RxReceiptContext m_rxReceiptContext; + mutex m_rxReceiptContext_lock; + + /******************************************************************************* + * TX CONTEXT * + *******************************************************************************/ + mutex m_tx_lock; + uint8_t m_txbuf[1024] = {0}; + int32_t m_rxsize = 0; + uint8_t m_txindex = 0; + + CanPacketRxBuffer m_rxbuf[255]; + + on_raw_data_t on_rx_raw; + + uint8_t m_receipt_cache[1024]; + zcanbus_packet_t *m_receipt_frame = (zcanbus_packet_t *)m_receipt_cache; + size_t m_receipt_len = 0; + + ecode2str_t m_ecode2str; + + public: + void initialize(QTSerialChannel *ch); +}; + +} // namespace iflytop diff --git a/src/main.cpp b/src/main.cpp index 8670711..00fc091 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -28,6 +28,8 @@ // #include // +//#pragma comment(lib, "ws2_32.lib") +// #define TAG "Main" using namespace std; using namespace iflytop; diff --git a/src/protocol/waveshare_can/waveshare_can.cpp b/src/protocol/waveshare_can/waveshare_can.cpp new file mode 100644 index 0000000..4297e4a --- /dev/null +++ b/src/protocol/waveshare_can/waveshare_can.cpp @@ -0,0 +1,167 @@ +#include "waveshare_can.hpp" + +using namespace iflytop; +using namespace std; +#define CANUSB_TTY_BAUD_RATE_DEFAULT 2000000 + +#define TAG "WaveshareCan" + +static int generate_checksum(const unsigned char* data, int data_len) { + int i, checksum; + + checksum = 0; + for (i = 0; i < data_len; i++) { + checksum += data[i]; + } + + return checksum & 0xff; +} + +static bool isHeader(uint8_t* data) { + if (data[0] == 0xAA && data[1] == 0x55) { + return true; + } + return false; +} + +void WaveshareCan::initialize(QTSerialChannel* serialch) { m_ch = serialch; } + +bool WaveshareCan::regFrameCB(frame_callback_t framecb) { + m_frame_callback = framecb; + // ChannelMgr::ins()->serialCh; + + m_ch->regRxListener([this](uint8_t* data, size_t len) { + { + lock_guard lock(lock_); + if (len + m_rxlen > sizeof(m_rxcache)) { + m_rxlen = 0; + } + memcpy(m_rxcache + m_rxlen, data, len); + m_rxlen += len; + } + }); + m_thread.reset(new thread([this]() { + while (true) { + this_thread::sleep_for(chrono::milliseconds(1)); + + { + lock_guard lock(lock_); + // 1.找头部 + int32_t headerpos = -1; + for (int32_t i = 0; i < m_rxlen - 1; i++) { + if (isHeader(m_rxcache + i)) { + headerpos = i; + break; + } + } + + if (headerpos == -1) { + continue; + } + + // 将包头移动到缓存头部 + if (headerpos != 0) { + memmove(m_rxcache, m_rxcache + headerpos, m_rxlen - headerpos); + m_rxlen = m_rxlen - headerpos; + continue; + } + + if (m_rxlen < 20) continue; + + onReceivePacket(m_rxcache, 20); + memmove(m_rxcache, m_rxcache + 20, m_rxlen - 20); + m_rxlen = m_rxlen - 20; + } + } + })); +} +void WaveshareCan::setCanpPrameter(CANUSB_SPEED speed, CANUSB_MODE mode, CANUSB_FRAME frame) { + int cmd_frame_len; + unsigned char cmd_frame[20]; + + cmd_frame_len = 0; + cmd_frame[0] = 0xaa; + cmd_frame[1] = 0x55; + cmd_frame[2] = 0x02; // 0x02:用固定20字节协议收发数据 0x12-设置用可变协议收发数据 + cmd_frame[3] = speed; // speed + cmd_frame[4] = frame; // 帧类型 + cmd_frame[5] = 0; /* Filter ID not handled. */ + cmd_frame[6] = 0; /* Filter ID not handled. */ + cmd_frame[7] = 0; /* Filter ID not handled. */ + cmd_frame[8] = 0; /* Filter ID not handled. */ + cmd_frame[9] = 0; /* Mask ID not handled. */ + cmd_frame[10] = 0; /* Mask ID not handled. */ + cmd_frame[11] = 0; /* Mask ID not handled. */ + cmd_frame[12] = 0; /* Mask ID not handled. */ + cmd_frame[13] = mode; // 模式 + cmd_frame[14] = 0x01; // 是否自动重发 + cmd_frame[15] = 0; // 占位,备用 + cmd_frame[16] = 0; // 占位,备用 + cmd_frame[17] = 0; // 占位,备用 + cmd_frame[18] = 0; // 占位,备用 + cmd_frame[19] = generate_checksum(&cmd_frame[2], 17); + + if (!m_ch->isOpen()) { + throw zexception(ke_channel_is_close, "channel is not open"); + } + m_ch->send(cmd_frame, 20); +} + +bool WaveshareCan::sendframe(CANUSB_FRAME frametype, uint32_t id, unsigned char data[], int data_length_code) { + int data_frame_len = 0; + unsigned char data_frame[20] = {0x00}; + waveshare_can_packet_t* packet = (waveshare_can_packet_t*)data_frame; + + packet->packet_header0 = 0xaa; + packet->packet_header1 = 0x55; + packet->type = 0x01; // 数据 + packet->frame_type = frametype; + packet->frame_format = 0x01; // 数据帧 + packet->frame_id_data_1 = id & 0xff; + packet->frame_id_data_2 = (id >> 8) & 0xff; + packet->frame_id_data_3 = (id >> 16) & 0xff; + packet->frame_id_data_4 = (id >> 24) & 0xff; + packet->frame_data_length = data_length_code; + packet->frame_data_1 = data[0]; + packet->frame_data_2 = data[1]; + packet->frame_data_3 = data[2]; + packet->frame_data_4 = data[3]; + packet->frame_data_5 = data[4]; + packet->frame_data_6 = data[5]; + packet->frame_data_7 = data[6]; + packet->frame_data_8 = data[7]; + packet->reserve = 0; + packet->check_code = generate_checksum(&data_frame[2], 17); + + QTSerialChannel* ch = &ChannelMgr::ins()->serialCh; + + if (!ch->isOpen()) { + throw zexception(ke_channel_is_close, "channel is not open"); + } + + ZLOGI(TAG, "tx 0x%08x, %s", id, zhex2str(data, data_length_code).c_str()); + ch->send(data_frame, 20); + + return true; +} + +int WaveshareCan::onReceivePacket(uint8_t* data, size_t len) { + waveshare_can_packet_t* rxpacket = (waveshare_can_packet_t*)data; + + can_rx_frame_t canframe; + canframe.dlc = rxpacket->frame_data_length; + canframe.id = rxpacket->frame_id_data_1 | ((uint32_t)rxpacket->frame_id_data_2 << 8) | ((uint32_t)rxpacket->frame_id_data_3 << 16) | ((uint32_t)rxpacket->frame_id_data_4 << 24); + + canframe.data[0] = rxpacket->frame_data_1; + canframe.data[1] = rxpacket->frame_data_2; + canframe.data[2] = rxpacket->frame_data_3; + canframe.data[3] = rxpacket->frame_data_4; + canframe.data[4] = rxpacket->frame_data_5; + canframe.data[5] = rxpacket->frame_data_6; + canframe.data[6] = rxpacket->frame_data_7; + canframe.data[7] = rxpacket->frame_data_8; + + if (m_frame_callback) { + m_frame_callback(&canframe); + } +} diff --git a/src/protocol/waveshare_can/waveshare_can.hpp b/src/protocol/waveshare_can/waveshare_can.hpp new file mode 100644 index 0000000..db10abb --- /dev/null +++ b/src/protocol/waveshare_can/waveshare_can.hpp @@ -0,0 +1,112 @@ +#pragma once + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "zqui/zqui/zqui.hpp" +namespace iflytop { +#define CANUSB_TTY_BAUD_RATE_DEFAULT 2000000 + +typedef enum { + CANUSB_SPEED_1000000 = 0x01, + CANUSB_SPEED_800000 = 0x02, + CANUSB_SPEED_500000 = 0x03, + CANUSB_SPEED_400000 = 0x04, + CANUSB_SPEED_250000 = 0x05, + CANUSB_SPEED_200000 = 0x06, + CANUSB_SPEED_125000 = 0x07, + CANUSB_SPEED_100000 = 0x08, + CANUSB_SPEED_50000 = 0x09, + CANUSB_SPEED_20000 = 0x0a, + CANUSB_SPEED_10000 = 0x0b, + CANUSB_SPEED_5000 = 0x0c, +} CANUSB_SPEED; + +typedef enum { + CANUSB_MODE_NORMAL = 0x00, + CANUSB_MODE_LOOPBACK = 0x01, + CANUSB_MODE_SILENT = 0x02, + CANUSB_MODE_LOOPBACK_SILENT = 0x03, +} CANUSB_MODE; + +typedef enum { + CANUSB_FRAME_STANDARD = 0x01, + CANUSB_FRAME_EXTENDED = 0x02, +} CANUSB_FRAME; + +typedef enum { + CANUSB_INJECT_PAYLOAD_MODE_RANDOM = 0, + CANUSB_INJECT_PAYLOAD_MODE_INCREMENTAL = 1, + CANUSB_INJECT_PAYLOAD_MODE_FIXED = 2, +} CANUSB_PAYLOAD_MODE; + +typedef struct { + uint8_t packet_header0; + uint8_t packet_header1; + uint8_t type; + uint8_t frame_type; + uint8_t frame_format; + uint8_t frame_id_data_1; + uint8_t frame_id_data_2; + uint8_t frame_id_data_3; + uint8_t frame_id_data_4; + uint8_t frame_data_length; + uint8_t frame_data_1; + uint8_t frame_data_2; + uint8_t frame_data_3; + uint8_t frame_data_4; + uint8_t frame_data_5; + uint8_t frame_data_6; + uint8_t frame_data_7; + uint8_t frame_data_8; + uint8_t reserve; + uint8_t check_code; +} waveshare_can_packet_t; + +class WaveshareCan { + public: + typedef struct { + uint32_t id; + uint8_t dlc; + uint8_t data[8]; + } can_rx_frame_t; + + typedef function frame_callback_t; + + private: + unique_ptr m_thread; + frame_callback_t m_frame_callback; + mutex lock_; + + uint8_t m_rxcache[1024] = {0}; + uint8_t m_rxlen = 0; + + QTSerialChannel* m_ch; + + public: + void initialize(QTSerialChannel* ch); + bool regFrameCB(frame_callback_t framecb); + + void setCanpPrameter(CANUSB_SPEED speed, CANUSB_MODE mode, CANUSB_FRAME frame); + bool sendStdframe(uint32_t id, unsigned char data[], int data_length_code) { return sendframe(CANUSB_FRAME_STANDARD, id, data, data_length_code); } + bool sendExtframe(uint32_t id, unsigned char data[], int data_length_code) { return sendframe(CANUSB_FRAME_EXTENDED, id, data, data_length_code); } + bool sendframe(CANUSB_FRAME frame, uint32_t id, unsigned char data[], int data_length_code); + + private: + int onReceivePacket(uint8_t* data, size_t len); +}; + +} // namespace iflytop diff --git a/src/protocol/zscanprotocol_com/zscanprotocol_com.cpp b/src/protocol/zscanprotocol_com/zscanprotocol_com.cpp new file mode 100644 index 0000000..7dfe4eb --- /dev/null +++ b/src/protocol/zscanprotocol_com/zscanprotocol_com.cpp @@ -0,0 +1,226 @@ +#include "zscanprotocol_com.hpp" + +#include + +using namespace iflytop; +#define TAG "ZScanProtocolCom" + +#define DEFUALT_OVERTIME 30 + +void ZScanProtocolCom::updateChannelConfig() { m_channel->setCanpPrameter(CANUSB_SPEED_500000, CANUSB_MODE_NORMAL, CANUSB_FRAME_EXTENDED); } + +void ZScanProtocolCom::initialize(QTSerialChannel *serialCh) { // + m_channel = new WaveshareCan(); + m_channel->initialize(serialCh); + + m_channel->regFrameCB([this](WaveshareCan::can_rx_frame_t *canframe) { // + ZLOGI(TAG, "can rx: 0x%08x %d %s", canframe->id, canframe->dlc, zhex2str(canframe->data, canframe->dlc).c_str()); + + /** + * @brief 消息格式 + * + * [2] [3bit] [8bit] [8bit] [8bit] + * , from frameNum frameId + */ + + zcanid_t *canid = (zcanid_t *)&canframe->id; + + uint8_t from = canid->from; + uint8_t to = canid->to; + uint8_t nframe = (canid->frameNumAndFrameId & 0xf0) >> 4; + uint8_t frameId = canid->frameNumAndFrameId & 0x0f; + CanPacketRxBuffer *rxbuf = nullptr; + + // ZLOGI(TAG, "from:%d to:%d frameNum:%d ", canid->from, canid->to, canid->frameNumAndFrameId); + + rxbuf = findRxBuff(from); + if (!rxbuf) { + ZLOGE(TAG, "board[%d] packetId[%d] find rx buff fail", from, frameId); + return; + } + + if (frameId == 0) { + rxbuf->rxdataSize = 0; + rxbuf->rxPacketNum = 0; + rxbuf->from = from; + rxbuf->to = to; + } + // ZLOGI(TAG, "rx packet %d %d /%d", rxbuf->rxPacketNum, frameId,nframe); + + if (rxbuf->rxPacketNum != frameId) { + ZLOGE(TAG, "lost subpacket from %d", from); + rxbuf->rxPacketNum = 0; + rxbuf->rxdataSize = 0; + return; + } + + memcpy(rxbuf->rxdata + rxbuf->rxdataSize, canframe->data, canframe->dlc); + rxbuf->rxdataSize += canframe->dlc; + rxbuf->rxPacketNum++; + + if (nframe == frameId + 1) { + processRxPacket(from, to, rxbuf->rxdata, rxbuf->rxdataSize); + } + + }); +} + +void ZScanProtocolCom::sendframe(int32_t from, int32_t to, uint8_t *frame, size_t len) { + if (on_rx_raw) on_rx_raw(kcmd, from, to, (uint8_t *)frame, len); + + uint8_t *packet = (uint8_t *)frame; + + int npacket = len / 8 + (len % 8 == 0 ? 0 : 1); + if (npacket > 255) { + throw zexception(ke_invalid_packet_format, "channel is not open"); + return; + } + int finalpacketlen = len % 8 == 0 ? 8 : len % 8; + + for (uint8_t i = 0; i < npacket; i++) { + if (i == npacket - 1) { + sendsubframe(from, to, npacket, i, packet + i * 8, finalpacketlen); + } else { + sendsubframe(from, to, npacket, i, packet + i * 8, 8); + } + } +} +void ZScanProtocolCom::sendsubframe(int32_t from, int32_t to, int npacket, int packetIndex, uint8_t *packet, size_t len) { + uint32_t canid; + uint8_t candata[8]; + uint8_t cantxlen; + + zcanid_t *zcanid = (zcanid_t *)&canid; + zcanid->from = from; + zcanid->to = to; + zcanid->frameNumAndFrameId = (npacket << 4) | packetIndex; + + memcpy(candata, packet, len); + cantxlen = len; + + m_channel->sendExtframe(canid, candata, cantxlen); +} +void ZScanProtocolCom::processRxPacket(int32_t from, int32_t to, uint8_t *data, size_t len) { + zcanbus_packet_t *frame = (zcanbus_packet_t *)data; + + if (frame->ptype == kreceipt || frame->ptype == kerror_receipt) { + if (on_rx_raw) on_rx_raw((packet_type_t)frame->ptype, from, to, (uint8_t *)frame, len); + if (frame->index == m_rxReceiptContext.waittingIndex) { + lock_guard lock(m_rxReceiptContext_lock); + m_rxReceiptContext.receiptIsReady = true; + m_rxReceiptContext.receiptLen = len; + memcpy(m_rxReceiptContext.receipt, frame, len); + } else { + return; + } + + } else if (frame->ptype == kcmd) { + if (on_rx_raw) on_rx_raw((packet_type_t)frame->ptype, from, to, (uint8_t *)frame, len); + } else if (frame->ptype == kreport) { + if (on_rx_raw) on_rx_raw((packet_type_t)frame->ptype, from, to, (uint8_t *)frame, len); + } else { + ZLOGE(TAG, "unknow packet type %d", frame->ptype); + } +} + +CanPacketRxBuffer *ZScanProtocolCom::findRxBuff(int deviceId) { + for (uint32_t i = 0; i < ZARRAY_SIZE(m_rxbuf); i++) { + if (m_rxbuf[i].id == deviceId) { + return &m_rxbuf[i]; + } + + if (m_rxbuf[i].id == 0) { + m_rxbuf[i].id = deviceId; + return &m_rxbuf[i]; + } + } + + ZASSERT(0); + return nullptr; +} + +void ZScanProtocolCom::callcmd(int32_t to, int32_t cmdid, uint8_t *param, int32_t paramLen, int32_t overtime) { + m_txindex++; + if (m_txindex < 200) m_txindex = 200; + + zcanbus_packet_t *frame = (zcanbus_packet_t *)m_txbuf; + frame->ptype = kcmd; + frame->index = m_txindex; + frame->function_id = cmdid; + + if (paramLen != 0) memcpy(frame->params, param, paramLen); + + { + lock_guard lock(m_rxReceiptContext_lock); + m_rxReceiptContext.waittingIndex = m_txindex; + m_rxReceiptContext.waittingForReceipt = true; + m_rxReceiptContext.receiptIsReady = false; + m_rxReceiptContext.receiptLen = 0; + } + + sendframe(1, to, (uint8_t *)frame, paramLen + sizeof(zcanbus_packet_t)); + bool rxreceipt = false; + + for (int32_t i = 0; i < overtime; i++) { + { + lock_guard lock(m_rxReceiptContext_lock); + /** + * @brief 接收到回执 + */ + if (m_rxReceiptContext.receiptIsReady) { + memcpy(m_receipt_cache, m_rxReceiptContext.receipt, m_rxReceiptContext.receiptLen); + m_receipt_len = m_rxReceiptContext.receiptLen; + rxreceipt = true; + // if (m_on_raw_data_cb) m_on_raw_data_cb(kcmd_receipt, (uint8_t *)rx, *rxlen); + break; + } + } + this_thread::sleep_for(chrono::milliseconds(1)); + } + + if (!rxreceipt) { + throw zexception(kerr_overtime, "overtime"); + } + + if (m_receipt_frame->ptype == kerror_receipt) { + int32_t ecode = *(int32_t *)m_receipt_frame->params; + throw zexception(ecode, ecode2str(ecode)); + } + return; +} +void ZScanProtocolCom::callcmd0(int32_t to, int32_t cmdid, int32_t overtime) { callcmd(to, cmdid, nullptr, 0, overtime); } +void ZScanProtocolCom::callcmd1(int32_t device_id, int32_t cmdid, int32_t param0, int32_t overtime) { + int32_t param[4]; + param[0] = param0; + callcmd(device_id, cmdid, (uint8_t *)param, 4, overtime); +} +void ZScanProtocolCom::callcmd2(int32_t device_id, int32_t cmdid, int32_t param0, int32_t param1, int32_t overtime) { + int32_t param[4]; + param[0] = param0; + param[1] = param1; + callcmd(device_id, cmdid, (uint8_t *)param, 8, overtime); +} +void ZScanProtocolCom::callcmd3(int32_t device_id, int32_t cmdid, int32_t param0, int32_t param1, int32_t param2, int32_t overtime) { + int32_t param[4]; + param[0] = param0; + param[1] = param1; + param[2] = param2; + callcmd(device_id, cmdid, (uint8_t *)param, 12, overtime); +} +void ZScanProtocolCom::callcmd4(int32_t to, int32_t cmdid, int32_t param0, int32_t param1, int32_t param2, int32_t param3, int32_t overtime) { + int32_t param[4]; + param[0] = param0; + param[1] = param1; + param[2] = param2; + param[3] = param3; + callcmd(to, cmdid, (uint8_t *)param, 16, overtime); +} + +void ZScanProtocolCom::sendraw(int32_t from, int32_t to, uint8_t *data, size_t len) { sendframe(from, to, data, len); } + +string ZScanProtocolCom::ecode2str(int ecode) { + if (m_ecode2str) { + return m_ecode2str(ecode); + } + return "Ecode(" + to_string(ecode) + ")"; +} diff --git a/src/protocol/zscanprotocol_com/zscanprotocol_com.hpp b/src/protocol/zscanprotocol_com/zscanprotocol_com.hpp new file mode 100644 index 0000000..234ffc1 --- /dev/null +++ b/src/protocol/zscanprotocol_com/zscanprotocol_com.hpp @@ -0,0 +1,107 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +#include "app_protocols/zscanprotocol/zscanprotocol.hpp" +#include "protocol/waveshare_can/waveshare_can.hpp" +#include "zqui/zqui/zqui.hpp" + +namespace iflytop { +using namespace std; + +typedef function on_raw_data_t; + +typedef function ecode2str_t; + +class RxReceiptContext { + public: + bool waittingForReceipt; + bool receiptIsReady; + uint8_t waittingIndex; + uint8_t receipt[1024]; + size_t receiptLen; +}; + +class CanPacketRxBuffer { + public: + int32_t id = 0; + uint8_t from = 0; + uint8_t to = 0; + + uint8_t rxdata[2048] = {0}; + int rxdataSize = 0; + + int rxPacketNum = 0; +}; + +class ZScanProtocolCom { + ZScanProtocolCom() {} + + WaveshareCan *m_channel = nullptr; + + uint8_t m_rxcache[1024] = {0}; + int32_t m_rxlen = 0; + bool m_rxcache_is_full = false; + + mutex lock_; + + unique_ptr m_thread; + + RxReceiptContext m_rxReceiptContext; + mutex m_rxReceiptContext_lock; + + /******************************************************************************* + * TX CONTEXT * + *******************************************************************************/ + mutex m_tx_lock; + uint8_t m_txbuf[1024] = {0}; + int32_t m_rxsize = 0; + uint8_t m_txindex = 0; + + CanPacketRxBuffer m_rxbuf[255]; + + on_raw_data_t on_rx_raw; + + uint8_t m_receipt_cache[1024]; + zcanbus_packet_t *m_receipt_frame = (zcanbus_packet_t *)m_receipt_cache; + size_t m_receipt_len = 0; + + ecode2str_t m_ecode2str; + + public: + void initialize(QTSerialChannel *ch); + void regOnRawData(on_raw_data_t cb) { on_rx_raw = cb; } + void regEcdoe2Str(ecode2str_t cb) { m_ecode2str = cb; } + void updateChannelConfig(); + + void callcmd(int32_t to, int32_t cmdid, uint8_t *param, int32_t paramLen, int32_t overtime = 100); + void callcmd0(int32_t to, int32_t cmdid, int32_t overtime = 100); + void callcmd1(int32_t to, int32_t cmdid, int32_t param0, int32_t overtime = 100); + void callcmd2(int32_t to, int32_t cmdid, int32_t param0, int32_t param1, int32_t overtime = 100); + void callcmd3(int32_t to, int32_t cmdid, int32_t param0, int32_t param1, int32_t param2, int32_t overtime = 100); + void callcmd4(int32_t to, int32_t cmdid, int32_t param0, int32_t param1, int32_t param2, int32_t param3, int32_t overtime = 100); + + void sendraw(int32_t from, int32_t to, uint8_t *data, size_t len); + + private: + void sendframe(int32_t from, int32_t to, uint8_t *frame, size_t len); + void sendsubframe(int32_t from, int32_t to, int npacket, int packetIndex, uint8_t *packet, size_t len); + void processRxPacket(int32_t from, int32_t to, uint8_t *data, size_t len); + + private: + CanPacketRxBuffer *findRxBuff(int deviceId); + string ecode2str(int ecode); +}; + +} // namespace iflytop diff --git a/src/zqui/base/appbuilder.hpp b/src/zqui/base/appbuilder.hpp index b5f9e24..8c108e9 100644 --- a/src/zqui/base/appbuilder.hpp +++ b/src/zqui/base/appbuilder.hpp @@ -8,8 +8,9 @@ typedef std::function appbuilder_fn_t; class AppBuilder { public: - appbuilder_fn_t buiderfn; string appName; + appbuilder_fn_t buiderfn; + AppBuilder(const string &appName, appbuilder_fn_t builderfn) : appName(appName), buiderfn(builderfn) {} diff --git a/src/zqui/channelmgr/channelmgr.hpp b/src/zqui/channelmgr/channelmgr.hpp index f1605ef..91bb635 100644 --- a/src/zqui/channelmgr/channelmgr.hpp +++ b/src/zqui/channelmgr/channelmgr.hpp @@ -13,9 +13,7 @@ #include // -#include -// -#include + // #include "qt_serial_datachannel.hpp" diff --git a/src/zqui/channelmgr/qt_serial_datachannel.cpp b/src/zqui/channelmgr/qt_serial_datachannel.cpp index f38439d..1ec0001 100644 --- a/src/zqui/channelmgr/qt_serial_datachannel.cpp +++ b/src/zqui/channelmgr/qt_serial_datachannel.cpp @@ -5,14 +5,18 @@ #include #include -#pragma comment(lib, "ws2_32.lib") +// +#include +// +#include + +//#pragma comment(lib, "ws2_32.lib") #include "zqui/base/logger.hpp" using namespace iflytop; using namespace std; - #define TAG "QTDataChannel" void QTSerialChannel::init() { @@ -115,18 +119,20 @@ bool QTSerialChannel::open() { return false; } m_isOpen = true; + if (m_onStateChange) m_onStateChange(true); return true; } void QTSerialChannel::close() { CloseHandle(m_CommHandler); m_isOpen = false; + if (m_onStateChange) m_onStateChange(false); } bool QTSerialChannel::isOpen() { return m_isOpen; } bool QTSerialChannel::send(const uint8_t *data, size_t len) { DWORD dwBytesWrite = len; - BOOL bWriteStat = WriteFile(m_CommHandler, // 串口句柄 + WriteFile(m_CommHandler, // 串口句柄 (char *)data, // 数据首地址 dwBytesWrite, // 要发送的数据字节数 &dwBytesWrite, // DWORD*,用来接收返回成功发送的数据字节数 @@ -146,10 +152,14 @@ int QTSerialChannel::com_receive(uint8_t *rxbuf, int rxbufsize) { // PurgeComm(m_CommHandler, PURGE_RXCLEAR); DWORD wCount = rxbufsize; // 成功读取的数据字节数 - BOOL bReadStat = ReadFile(m_CommHandler, // 串口句柄 + ReadFile(m_CommHandler, // 串口句柄 rxbuf, // 数据首地址 wCount, // 要读取的数据最大字节数 &wCount, // DWORD*,用来接收返回成功读取的数据字节数 NULL); return wCount; } + +void QTSerialChannel::regOnStateChange(function cb) { // + m_onStateChange = cb; +} diff --git a/src/zqui/channelmgr/qt_serial_datachannel.hpp b/src/zqui/channelmgr/qt_serial_datachannel.hpp index 52a13bb..44037ee 100644 --- a/src/zqui/channelmgr/qt_serial_datachannel.hpp +++ b/src/zqui/channelmgr/qt_serial_datachannel.hpp @@ -13,9 +13,6 @@ #include // -#include -// -#include // #include #include @@ -40,9 +37,10 @@ class QTSerialChannel { unique_ptr m_thread; uint32_t m_baudRate; - HANDLE m_CommHandler; + void *m_CommHandler; - bool m_isOpen = false; + bool m_isOpen = false; + function m_onStateChange; public: void init(); @@ -54,6 +52,8 @@ class QTSerialChannel { bool open(); void close(); + void regOnStateChange(function cb); + void setBaudRate(qint32 baudRate) { m_baudRate = baudRate; } qint32 baudRate() const { return m_baudRate; } diff --git a/src/zqui/zqui/mainwindow.h b/src/zqui/zqui/mainwindow.h index 8b563ea..ae59ca9 100644 --- a/src/zqui/zqui/mainwindow.h +++ b/src/zqui/zqui/mainwindow.h @@ -36,10 +36,6 @@ class MainWindow; } QT_END_NAMESPACE -enum { - -} MainWindowsSerialBaundrateIndex_t; - class MainWindow : public QMainWindow { Q_OBJECT diff --git a/src/zqui/zqui/zqui.hpp b/src/zqui/zqui/zqui.hpp index aac262f..1076e3c 100644 --- a/src/zqui/zqui/zqui.hpp +++ b/src/zqui/zqui/zqui.hpp @@ -2,7 +2,8 @@ #include "zqui/base/base.hpp" // - +#include "zqui/channelmgr/channelmgr.hpp" +// #include "mainwindow.h" #include "appnavibar.h"