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