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

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
  1. #include "qt_serial_datachannel.hpp"
  2. //
  3. #include <QtSerialPort/QSerialPort>
  4. #include <QtSerialPort/QSerialPortInfo>
  5. #pragma comment(lib, "ws2_32.lib")
  6. #include "logger.hpp"
  7. using namespace iflytop;
  8. using namespace std;
  9. #define TAG "QTDataChannel"
  10. void QTDataChannel::init() {
  11. m_thread.reset(new thread([this]() {
  12. while (true) {
  13. if (m_isOpen) {
  14. uint8_t rx[1024] = {0};
  15. int rx_cnt = com_receive(rx, 1024);
  16. if (rx_cnt != 0) {
  17. ZLOGI(TAG, "rx %s ", zhex2str(rx, rx_cnt).c_str());
  18. if (m_rxcb) m_rxcb(rx, rx_cnt);
  19. }
  20. this_thread::sleep_for(chrono::microseconds(1));
  21. } else {
  22. this_thread::sleep_for(chrono::microseconds(1000));
  23. }
  24. }
  25. }));
  26. }
  27. bool QTDataChannel::open() {
  28. char portnamebuf[256] = {0};
  29. sprintf(portnamebuf, "\\\\.\\%s", m_name.c_str());
  30. m_CommHandler = CreateFileA(portnamebuf, // port name
  31. GENERIC_READ | GENERIC_WRITE, // Read/Write
  32. 0, // No Sharing
  33. NULL, // No Security
  34. OPEN_EXISTING, // Open existing port only
  35. 0, // Non Overlapped I/O
  36. NULL); // Null for Comm Devices
  37. if (m_CommHandler == INVALID_HANDLE_VALUE) {
  38. ZLOGI(TAG, "Error in opening serial port");
  39. return false;
  40. }
  41. DCB p;
  42. memset(&p, 0, sizeof(p));
  43. p.DCBlength = sizeof(p);
  44. p.BaudRate = m_baudRate; // 波特率
  45. switch (m_dataBits) {
  46. case QSerialPort::Data5:
  47. p.ByteSize = 5;
  48. break;
  49. case QSerialPort::Data6:
  50. p.ByteSize = 6;
  51. break;
  52. case QSerialPort::Data7:
  53. p.ByteSize = 7;
  54. break;
  55. case QSerialPort::Data8:
  56. p.ByteSize = 8;
  57. break;
  58. default:
  59. p.ByteSize = 8;
  60. break;
  61. }
  62. // QSerialPort::NoParity = 0,
  63. // QSerialPort::EvenParity = 2,
  64. // QSerialPort::OddParity = 3,
  65. // QSerialPort::SpaceParity = 4,
  66. // QSerialPort::MarkParity = 5,
  67. // QSerialPort::UnknownParity = -1
  68. switch (m_parity) // 校验位
  69. {
  70. case QSerialPort::NoParity:
  71. p.Parity = NOPARITY; // 无校验
  72. break;
  73. case QSerialPort::EvenParity:
  74. p.Parity = EVENPARITY; // 奇校验
  75. break;
  76. case QSerialPort::OddParity:
  77. p.Parity = ODDPARITY; // 偶校验
  78. break;
  79. case QSerialPort::MarkParity:
  80. p.Parity = MARKPARITY; // 标记校验
  81. break;
  82. default:
  83. p.Parity = NOPARITY; // 无校验
  84. }
  85. switch (m_stopBits) // 停止位
  86. {
  87. case QSerialPort::OneStop:
  88. p.StopBits = ONESTOPBIT; // 1位停止位
  89. break;
  90. case QSerialPort::OneAndHalfStop:
  91. p.StopBits = TWOSTOPBITS; // 2位停止位
  92. break;
  93. case QSerialPort::TwoStop:
  94. p.StopBits = ONE5STOPBITS; // 1.5位停止位
  95. break;
  96. default:
  97. p.StopBits = ONESTOPBIT; // 无校验
  98. }
  99. if (!SetCommState(m_CommHandler, &p)) {
  100. // 设置参数失败
  101. CloseHandle(m_CommHandler);
  102. return false;
  103. }
  104. m_isOpen = true;
  105. return true;
  106. }
  107. void QTDataChannel::close() {
  108. CloseHandle(m_CommHandler);
  109. m_isOpen = false;
  110. }
  111. bool QTDataChannel::isOpen() { return m_isOpen; }
  112. bool QTDataChannel::send(const uint8_t *data, size_t len) {
  113. ZLOGI(TAG, "send %s", zhex2str(data, len).c_str());
  114. DWORD dwBytesWrite = len;
  115. BOOL bWriteStat = WriteFile(m_CommHandler, // 串口句柄
  116. (char *)data, // 数据首地址
  117. dwBytesWrite, // 要发送的数据字节数
  118. &dwBytesWrite, // DWORD*,用来接收返回成功发送的数据字节数
  119. NULL); // NULL为同步发送,OVERLAPPED*为异步发送
  120. return dwBytesWrite;
  121. }
  122. void QTDataChannel::regRxListener(function<void(uint8_t *data, size_t len)> cb) { m_rxcb = cb; }
  123. int QTDataChannel::com_receive(uint8_t *rxbuf, int rxbufsize) {
  124. COMMTIMEOUTS TimeOuts;
  125. GetCommTimeouts(m_CommHandler, &TimeOuts);
  126. TimeOuts.ReadIntervalTimeout = 0; // 读间隔超时
  127. TimeOuts.ReadTotalTimeoutMultiplier = 0; // 读时间系数
  128. TimeOuts.ReadTotalTimeoutConstant = 1; // 读时间常量
  129. SetCommTimeouts(m_CommHandler, &TimeOuts);
  130. // PurgeComm(m_CommHandler, PURGE_RXCLEAR);
  131. DWORD wCount = rxbufsize; // 成功读取的数据字节数
  132. BOOL bReadStat = ReadFile(m_CommHandler, // 串口句柄
  133. rxbuf, // 数据首地址
  134. wCount, // 要读取的数据最大字节数
  135. &wCount, // DWORD*,用来接收返回成功读取的数据字节数
  136. NULL);
  137. return wCount;
  138. }