an asynchronous open procedure

This commit is contained in:
Kevin Matz 2023-04-16 21:13:11 -04:00
parent eb25959c08
commit a34ada6da5
3 changed files with 25 additions and 32 deletions

View File

@ -30,6 +30,10 @@ DmxWidget::DmxWidget(QObject *parent)
{ {
connect(this, &DmxWidget::serialDataRead, this, &DmxWidget::parseMessageBuffer); connect(this, &DmxWidget::serialDataRead, this, &DmxWidget::parseMessageBuffer);
connect(port_, &QSerialPort::errorOccurred, this, &DmxWidget::serialErrorOccured); connect(port_, &QSerialPort::errorOccurred, this, &DmxWidget::serialErrorOccured);
connect(port_, &QSerialPort::readyRead, this, [this]() {
message_rx_buffer_.append(port_->readAll());
emit serialDataRead();
});
} }
@ -41,46 +45,32 @@ DmxWidget::~DmxWidget()
void DmxWidget::open() void DmxWidget::open()
{ {
if (!port_->open(QIODeviceBase::ReadWrite)) auto wait_for = [this](bool &reply) {
return; reply = false; // reset the reply state variale
ENTTEC::Widget::open(); for (int i = 0; i < 10; i++) { // serial reply may not be first in the read buffer
port_->waitForReadyRead(100); // wait for the port read buffer to have content
qInfo() << "Port opened on" << port_->portName(); if (reply)
break; // break the loop if a reply was received
getSerialNumber();
getParameters(0);
if (port_->waitForReadyRead(500) && port_->bytesAvailable() >= 19)
{
char snhead[] = {ENTTEC::Pro::START_DELIMITER,
ENTTEC::Pro::OpGetWidgetSerial,
0x04, 0x00}; // expect 4 bytes of message data
message_rx_buffer_.append(port_->readAll());
if (!message_rx_buffer_.startsWith(snhead))
{
message_rx_buffer_.clear();
close();
return;
} }
parseMessageBuffer(); return reply;
} };
else
{
close();
return;
}
connect(port_, &QSerialPort::readyRead, this, [this]() { if (!port_->open(QIODeviceBase::ReadWrite)) // open the port
message_rx_buffer_.append(port_->readAll()); return;
emit serialDataRead(); ENTTEC::Widget::open(); // open the base class widget
});
emit connectedChanged(isConnected()); getSerialNumber(); // request a serial number
getParameters(0); // get the metadata while we're here
if (wait_for(reply_serial)) // widget is found if a serial number reply is received
emit connectedChanged(isConnected());
else
close();
} }
void DmxWidget::close() void DmxWidget::close()
{ {
port_->close(); port_->close();
disconnect(port_, &QSerialPort::readyRead, nullptr, nullptr);
ENTTEC::Widget::close(); ENTTEC::Widget::close();
emit connectedChanged(isConnected()); emit connectedChanged(isConnected());
} }

View File

@ -754,6 +754,7 @@ void Widget::rxMsgGetWidgetSerialReply(std::shared_ptr<Pro::MsgGetWidgetSerialRe
{ {
std::scoped_lock lock(mtx_metadata_); std::scoped_lock lock(mtx_metadata_);
serial_number = msg->serial; serial_number = msg->serial;
reply_serial = true;
} }

View File

@ -125,6 +125,8 @@ protected:
std::vector<uint8_t> user_configuration; //!< User defined configuration data. std::vector<uint8_t> user_configuration; //!< User defined configuration data.
OperatingMode usb_mode; //!< The side of the USB the widget is acting on. OperatingMode usb_mode; //!< The side of the USB the widget is acting on.
bool reply_serial; //!< receiving a serialnumber will set to true
private: private:
void rxMsgHello(); void rxMsgHello();
void rxMsgReprogramFirmware(); void rxMsgReprogramFirmware();