You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
156 lines
4.8 KiB
156 lines
4.8 KiB
#include "qt_serial_datachannel.hpp"
|
|
|
|
//
|
|
|
|
#include <QtSerialPort/QSerialPort>
|
|
#include <QtSerialPort/QSerialPortInfo>
|
|
|
|
#pragma comment(lib, "ws2_32.lib")
|
|
|
|
#include "logger.hpp"
|
|
|
|
using namespace iflytop;
|
|
using namespace std;
|
|
|
|
#define TAG "QTDataChannel"
|
|
|
|
void QTDataChannel::init() {
|
|
m_thread.reset(new thread([this]() {
|
|
while (true) {
|
|
if (m_isOpen) {
|
|
uint8_t rx[1024] = {0};
|
|
int rx_cnt = com_receive(rx, 1024);
|
|
if (rx_cnt != 0) {
|
|
ZLOGI(TAG, "rx %s ", zhex2str(rx, rx_cnt).c_str());
|
|
if (m_rxcb) m_rxcb(rx, rx_cnt);
|
|
}
|
|
this_thread::sleep_for(chrono::microseconds(1));
|
|
} else {
|
|
this_thread::sleep_for(chrono::microseconds(1000));
|
|
}
|
|
}
|
|
}));
|
|
}
|
|
bool QTDataChannel::open() {
|
|
char portnamebuf[256] = {0};
|
|
sprintf(portnamebuf, "\\\\.\\%s", m_name.c_str());
|
|
m_CommHandler = CreateFileA(portnamebuf, // port name
|
|
GENERIC_READ | GENERIC_WRITE, // Read/Write
|
|
0, // No Sharing
|
|
NULL, // No Security
|
|
OPEN_EXISTING, // Open existing port only
|
|
0, // Non Overlapped I/O
|
|
NULL); // Null for Comm Devices
|
|
if (m_CommHandler == INVALID_HANDLE_VALUE) {
|
|
ZLOGI(TAG, "Error in opening serial port");
|
|
return false;
|
|
}
|
|
DCB p;
|
|
memset(&p, 0, sizeof(p));
|
|
p.DCBlength = sizeof(p);
|
|
p.BaudRate = m_baudRate; // 波特率
|
|
|
|
switch (m_dataBits) {
|
|
case QSerialPort::Data5:
|
|
p.ByteSize = 5;
|
|
break;
|
|
case QSerialPort::Data6:
|
|
p.ByteSize = 6;
|
|
break;
|
|
case QSerialPort::Data7:
|
|
p.ByteSize = 7;
|
|
break;
|
|
case QSerialPort::Data8:
|
|
p.ByteSize = 8;
|
|
break;
|
|
default:
|
|
p.ByteSize = 8;
|
|
break;
|
|
}
|
|
|
|
// QSerialPort::NoParity = 0,
|
|
// QSerialPort::EvenParity = 2,
|
|
// QSerialPort::OddParity = 3,
|
|
// QSerialPort::SpaceParity = 4,
|
|
// QSerialPort::MarkParity = 5,
|
|
// QSerialPort::UnknownParity = -1
|
|
|
|
switch (m_parity) // 校验位
|
|
{
|
|
case QSerialPort::NoParity:
|
|
p.Parity = NOPARITY; // 无校验
|
|
break;
|
|
case QSerialPort::EvenParity:
|
|
p.Parity = EVENPARITY; // 奇校验
|
|
break;
|
|
case QSerialPort::OddParity:
|
|
p.Parity = ODDPARITY; // 偶校验
|
|
break;
|
|
case QSerialPort::MarkParity:
|
|
p.Parity = MARKPARITY; // 标记校验
|
|
break;
|
|
default:
|
|
p.Parity = NOPARITY; // 无校验
|
|
}
|
|
|
|
switch (m_stopBits) // 停止位
|
|
{
|
|
case QSerialPort::OneStop:
|
|
p.StopBits = ONESTOPBIT; // 1位停止位
|
|
break;
|
|
case QSerialPort::OneAndHalfStop:
|
|
p.StopBits = TWOSTOPBITS; // 2位停止位
|
|
break;
|
|
case QSerialPort::TwoStop:
|
|
p.StopBits = ONE5STOPBITS; // 1.5位停止位
|
|
break;
|
|
default:
|
|
p.StopBits = ONESTOPBIT; // 无校验
|
|
}
|
|
|
|
if (!SetCommState(m_CommHandler, &p)) {
|
|
// 设置参数失败
|
|
CloseHandle(m_CommHandler);
|
|
return false;
|
|
}
|
|
m_isOpen = true;
|
|
return true;
|
|
}
|
|
|
|
void QTDataChannel::close() {
|
|
CloseHandle(m_CommHandler);
|
|
m_isOpen = false;
|
|
}
|
|
|
|
bool QTDataChannel::isOpen() { return m_isOpen; }
|
|
bool QTDataChannel::send(const uint8_t *data, size_t len) {
|
|
ZLOGI(TAG, "send %s", zhex2str(data, len).c_str());
|
|
|
|
DWORD dwBytesWrite = len;
|
|
BOOL bWriteStat = WriteFile(m_CommHandler, // 串口句柄
|
|
(char *)data, // 数据首地址
|
|
dwBytesWrite, // 要发送的数据字节数
|
|
&dwBytesWrite, // DWORD*,用来接收返回成功发送的数据字节数
|
|
NULL); // NULL为同步发送,OVERLAPPED*为异步发送
|
|
return dwBytesWrite;
|
|
}
|
|
void QTDataChannel::regRxListener(function<void(uint8_t *data, size_t len)> cb) { m_rxcb = cb; }
|
|
|
|
int QTDataChannel::com_receive(uint8_t *rxbuf, int rxbufsize) {
|
|
COMMTIMEOUTS TimeOuts;
|
|
GetCommTimeouts(m_CommHandler, &TimeOuts);
|
|
TimeOuts.ReadIntervalTimeout = 0; // 读间隔超时
|
|
TimeOuts.ReadTotalTimeoutMultiplier = 0; // 读时间系数
|
|
TimeOuts.ReadTotalTimeoutConstant = 1; // 读时间常量
|
|
SetCommTimeouts(m_CommHandler, &TimeOuts);
|
|
|
|
// PurgeComm(m_CommHandler, PURGE_RXCLEAR);
|
|
|
|
DWORD wCount = rxbufsize; // 成功读取的数据字节数
|
|
BOOL bReadStat = ReadFile(m_CommHandler, // 串口句柄
|
|
rxbuf, // 数据首地址
|
|
wCount, // 要读取的数据最大字节数
|
|
&wCount, // DWORD*,用来接收返回成功读取的数据字节数
|
|
NULL);
|
|
return wCount;
|
|
}
|