diff --git a/mainwindow.cpp b/mainwindow.cpp index 5c001c6..2be969e 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -45,7 +45,8 @@ static const uint32_t str2int(QString str) { return str.toUInt(nullptr, 10); } } -static QSerialPort G_SerialPort; +// static QSerialPort G_SerialPort; +// static QThread G_SerialPortThread; static QTDataChannel G_QTDataChannel; static const QString zaferror_to_str(zaf_error_code_t value) { @@ -113,14 +114,14 @@ void MainWindow::constructUI() { connect(ui->serialOpenKey, &QPushButton::clicked, this, [=](bool check) { // 打开串口 if (ui->serialOpenKey->text() == "打开") { - G_SerialPort.setPortName(ui->serialPortCB->currentText()); - if (G_SerialPort.open(QIODevice::ReadWrite)) { - G_SerialPort.setBaudRate(ui->serialBaudrateCB->currentText().toInt()); - G_SerialPort.setDataBits(QSerialPort::Data8); - G_SerialPort.setParity(QSerialPort::NoParity); - G_SerialPort.setFlowControl(QSerialPort::NoFlowControl); - G_SerialPort.setStopBits(QSerialPort::OneStop); - } else { + G_QTDataChannel.setPortName(ui->serialPortCB->currentText().toStdString()); + G_QTDataChannel.setBaudRate(ui->serialBaudrateCB->currentText().toInt()); + G_QTDataChannel.setDataBits(QSerialPort::Data8); + G_QTDataChannel.setParity(QSerialPort::NoParity); + G_QTDataChannel.setFlowControl(QSerialPort::NoFlowControl); + G_QTDataChannel.setStopBits(QSerialPort::OneStop); + + if (!G_QTDataChannel.open()) { QMessageBox::about(NULL, "提示", "串口无法打开,串口不存在或已被占用"); return; } @@ -130,7 +131,7 @@ void MainWindow::constructUI() { ui->serialPortCB->setEnabled(false); ui->serialPortRefreshKey->setEnabled(false); } else { - G_SerialPort.close(); + G_QTDataChannel.close(); ui->serialOpenKey->setText("打开"); ui->serialBaudrateCB->setEnabled(true); ui->serialPortCB->setEnabled(true); @@ -192,7 +193,10 @@ void MainWindow::constructUI() { } MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { - G_QTDataChannel.bind(&G_SerialPort); + // G_SerialPort.moveToThread(); + // QObject::connect(&G_SerialPortThread, &QThread::started, &G_SerialPort, &QSerialPort::open); + + G_QTDataChannel.init(); CLSTControler::ins()->initialize(&G_QTDataChannel); m_clstc = CLSTControler::ins(); diff --git a/mainwindow.ui b/mainwindow.ui index 3a9b67d..4f8c37d 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -432,12 +432,17 @@ - Tab 1 + 触发源配置 - Tab 2 + 光源配置 + + + + + 相机驱动配置 diff --git a/src/camera_light_src_timing_controller/clst_controler.cpp b/src/camera_light_src_timing_controller/clst_controler.cpp index 8fc4671..cf0b764 100644 --- a/src/camera_light_src_timing_controller/clst_controler.cpp +++ b/src/camera_light_src_timing_controller/clst_controler.cpp @@ -20,6 +20,7 @@ CLSTControler *CLSTControler::ins() { void CLSTControler::initialize(IDataChannel *channel) { // m_channel = channel; m_channel->regRxListener([this](uint8_t *data, size_t len) { + ZLOGI(TAG, "Rx1....."); { lock_guard lock(lock_); if (len + m_rxlen > sizeof(m_rxcache)) { @@ -100,7 +101,8 @@ void CLSTControler::processRxData(uint8_t *rx, uint32_t rxlen) { } } -void CLSTControler::processRxPacket(zaf_packet_header_t *packet) { // +void CLSTControler::processRxPacket(zaf_packet_header_t *packet) { + // // ZLOGI(TAG, "RX packet"); // ZLOGI(TAG, " type :%d", packet->packet_type); // ZLOGI(TAG, " index :%d", packet->index); @@ -109,6 +111,10 @@ void CLSTControler::processRxPacket(zaf_packet_header_t *packet) { // // for (uint32_t i = 0; i < packet->ndata; i++) { // ZLOGI(TAG, " data[%d]:%d", i, packet->data[i]); // } + ZLOGI(TAG, "Rx....."); + if (m_raw_data_cb) { + m_raw_data_cb(kuart_raw_rx, (uint8_t *)packet, sizeof(zaf_packet_header_t) + packet->ndata * 4 + 3); + } if (packet->packet_type == kzaf_packet_type_receipt) { lock_guard lock(m_rxReceiptContext_lock); if (m_rxReceiptContext.waittingForReceipt) { @@ -120,10 +126,6 @@ void CLSTControler::processRxPacket(zaf_packet_header_t *packet) { // m_rxReceiptContext.waittingForReceipt = false; } } - - if (m_raw_data_cb) { - m_raw_data_cb(kuart_raw_rx, (uint8_t *)packet, sizeof(zaf_packet_header_t) + packet->ndata * 4 + 3); - } } bool CLSTControler::ping() {} @@ -150,11 +152,13 @@ zaf_error_code_t CLSTControler::sendPacket(zaf_packet_header_t *packet, uint32_t if (m_raw_data_cb) { m_raw_data_cb(kuart_raw_tx, (uint8_t *)packet, sizeof(zaf_packet_header_t) + packet->ndata * 4 + 3); } + ZLOGI(TAG, "Tx....."); m_channel->send((uint8_t *)packet, len); for (size_t i = 0; i < overtime; i++) { { lock_guard lock(m_rxReceiptContext_lock); + ZLOGI(TAG, "wait for ready %d", m_rxReceiptContext.receiptIsReady); if (m_rxReceiptContext.receiptIsReady) { if (rxpacket->data[0] != 0) { return (zaf_error_code_t)rxpacket->data[0]; diff --git a/src/camera_light_src_timing_controller/qt_serial_datachannel.cpp b/src/camera_light_src_timing_controller/qt_serial_datachannel.cpp index c81b950..31f52d0 100644 --- a/src/camera_light_src_timing_controller/qt_serial_datachannel.cpp +++ b/src/camera_light_src_timing_controller/qt_serial_datachannel.cpp @@ -1,37 +1,153 @@ #include "qt_serial_datachannel.hpp" +// + #include #include +#pragma comment(lib, "ws2_32.lib") + #include "logger.hpp" using namespace iflytop; using namespace std; using namespace clst; -void QTDataChannel::bind(QSerialPort *serialPort) { // - m_serialPort = serialPort; - connect(m_serialPort, SIGNAL(readyRead()), this, SLOT(readyReadSlot())); +#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 %d bytes", rx_cnt); + if (m_rxcb) m_rxcb(rx, rx_cnt); + } + } + this_thread::sleep_for(chrono::milliseconds(1)); + } + })); } +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; // У + } -void QTDataChannel::readyReadSlot() { - if (!m_serialPort) return; + 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; // У + } - QByteArray data = m_serialPort->readAll(); - // ZLOGI("QTDataChannel", "RX %d", data.size()); - if (m_rxcb) m_rxcb((uint8_t *)data.data(), data.size()); + if (!SetCommState(m_CommHandler, &p)) { + // òʧ + CloseHandle(m_CommHandler); + return false; + } + m_isOpen = true; + return true; } -bool QTDataChannel::isOpen() { - if (!m_serialPort) return false; - return m_serialPort->isOpen(); +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) { - if (!m_serialPort) return false; + DWORD dwBytesWrite = len; + BOOL bWriteStat = WriteFile(m_CommHandler, // ھ + (char *)data, // ׵ַ + dwBytesWrite, // Ҫ͵ֽ + &dwBytesWrite, // DWORD*շسɹ͵ֽ + NULL); // NULLΪͬͣOVERLAPPED*Ϊ첽 + return dwBytesWrite; +} +void QTDataChannel::regRxListener(function cb) { m_rxcb = cb; } - QByteArray qdata; - qdata.append((char *)data, len); - m_serialPort->write(qdata); - return true; +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; } -void QTDataChannel::regRxListener(function cb) { m_rxcb = cb; } \ No newline at end of file diff --git a/src/camera_light_src_timing_controller/qt_serial_datachannel.hpp b/src/camera_light_src_timing_controller/qt_serial_datachannel.hpp index e48a084..3e9a4cd 100644 --- a/src/camera_light_src_timing_controller/qt_serial_datachannel.hpp +++ b/src/camera_light_src_timing_controller/qt_serial_datachannel.hpp @@ -12,6 +12,9 @@ #include #include // +#include +#include +// #include #include // @@ -27,23 +30,48 @@ using namespace std; typedef function device_state_cb_t; -class QTDataChannel : public QObject, public IDataChannel { - Q_OBJECT - +class QTDataChannel : public IDataChannel { function m_rxcb; - QSerialPort *m_serialPort = nullptr; - unique_ptr m_thread; + QSerialPort::DataBits m_dataBits; + QSerialPort::Parity m_parity; + QSerialPort::StopBits m_stopBits; + QSerialPort::FlowControl m_flowControl; + string m_name; + + unique_ptr m_thread; + + uint32_t m_baudRate; + HANDLE m_CommHandler; + + bool m_isOpen = false; public: - void bind(QSerialPort *serialPort); + void init(); virtual bool isOpen() override; virtual bool send(const uint8_t *data, size_t len) override; virtual void regRxListener(function cb) override; - public slots: - void readyReadSlot(); + bool open(); + void close(); + + bool setBaudRate(qint32 baudRate) { m_baudRate = baudRate; } + qint32 baudRate() const { return m_baudRate; } + + bool setPortName(string name) { m_name = name; } + bool setDataBits(QSerialPort::DataBits dataBits) { m_dataBits = dataBits; } + bool setParity(QSerialPort::Parity parity) { m_parity = parity; } + bool setStopBits(QSerialPort::StopBits stopBits) { m_stopBits = stopBits; } + bool setFlowControl(QSerialPort::FlowControl flowControl) { m_flowControl = flowControl; } + + QSerialPort::DataBits dataBits() const { return m_dataBits; } + QSerialPort::Parity parity() const { return m_parity; } + QSerialPort::StopBits stopBits() const { return m_stopBits; } + QSerialPort::FlowControl flowControl() const { return m_flowControl; } + + private: + int com_receive(uint8_t *rxbuf, int rxbufsize); }; } // namespace clst } // namespace iflytop \ No newline at end of file