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

#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;
}