16 changed files with 702 additions and 23 deletions
-
5CMakeLists.txt
-
2app_protocols/transmit_disfection_protocol
-
2app_protocols/zscanprotocol
-
0src/app/transmit_disinfection/transmit_disinfection_can_master.cpp
-
60src/app/transmit_disinfection/transmit_disinfection_can_master.hpp
-
2src/main.cpp
-
167src/protocol/waveshare_can/waveshare_can.cpp
-
112src/protocol/waveshare_can/waveshare_can.hpp
-
226src/protocol/zscanprotocol_com/zscanprotocol_com.cpp
-
107src/protocol/zscanprotocol_com/zscanprotocol_com.hpp
-
3src/zqui/base/appbuilder.hpp
-
4src/zqui/channelmgr/channelmgr.hpp
-
18src/zqui/channelmgr/qt_serial_datachannel.cpp
-
10src/zqui/channelmgr/qt_serial_datachannel.hpp
-
4src/zqui/zqui/mainwindow.h
-
3src/zqui/zqui/zqui.hpp
@ -1 +1 @@ |
|||
Subproject commit fe4173bbfefd7d6648fbea94717605764b4e7594 |
|||
Subproject commit 6573835a56f8b1dd2aa1311b6f6136bcc0d182bd |
@ -1 +1 @@ |
|||
Subproject commit a72ab76f401598ef36a95107a4298292b6c36d8e |
|||
Subproject commit 5161e29f77f08d1e1bea60827b0ee937fa7943bf |
@ -0,0 +1,60 @@ |
|||
#pragma once
|
|||
#include <fstream>
|
|||
#include <functional>
|
|||
#include <iostream>
|
|||
#include <list>
|
|||
#include <map>
|
|||
#include <memory>
|
|||
#include <mutex>
|
|||
#include <set>
|
|||
#include <sstream>
|
|||
#include <string>
|
|||
#include <thread>
|
|||
#include <vector>
|
|||
|
|||
//
|
|||
#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<thread> 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
|
@ -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<mutex> 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<mutex> 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); |
|||
} |
|||
} |
@ -0,0 +1,112 @@ |
|||
#pragma once
|
|||
|
|||
#include <stdint.h>
|
|||
#include <stdio.h>
|
|||
#include <windows.h>
|
|||
|
|||
#include <fstream>
|
|||
#include <functional>
|
|||
#include <iostream>
|
|||
#include <list>
|
|||
#include <map>
|
|||
#include <memory>
|
|||
#include <set>
|
|||
#include <sstream>
|
|||
#include <string>
|
|||
#include <thread>
|
|||
#include <vector>
|
|||
|
|||
#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<void(can_rx_frame_t*)> frame_callback_t; |
|||
|
|||
private: |
|||
unique_ptr<thread> 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
|
@ -0,0 +1,226 @@ |
|||
#include "zscanprotocol_com.hpp"
|
|||
|
|||
#include <stdarg.h>
|
|||
|
|||
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<mutex> 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<mutex> 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<mutex> 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) + ")"; |
|||
} |
@ -0,0 +1,107 @@ |
|||
#pragma once
|
|||
#include <fstream>
|
|||
#include <functional>
|
|||
#include <iostream>
|
|||
#include <list>
|
|||
#include <map>
|
|||
#include <memory>
|
|||
#include <mutex>
|
|||
#include <set>
|
|||
#include <sstream>
|
|||
#include <string>
|
|||
#include <thread>
|
|||
#include <vector>
|
|||
|
|||
//
|
|||
#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<void(packet_type_t type, uint8_t from, uint8_t to, uint8_t *hex, uint32_t hexlen)> on_raw_data_t; |
|||
|
|||
typedef function<string(int ecode)> 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<thread> 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
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue