-
-
Notifications
You must be signed in to change notification settings - Fork 350
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(simu): cross-platform connection of host serial ports to simu ra…
…dio (#5584)
- Loading branch information
Showing
22 changed files
with
789 additions
and
808 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
/* | ||
* Copyright (C) EdgeTX | ||
* | ||
* Based on code named | ||
* opentx - https://github.com/opentx/opentx | ||
* th9x - http://code.google.com/p/th9x | ||
* er9x - http://code.google.com/p/er9x | ||
* gruvin9x - http://code.google.com/p/gruvin9x | ||
* | ||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License version 2 as | ||
* published by the Free Software Foundation. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
*/ | ||
|
||
#include "hostserialconnector.h" | ||
#include <QMessageBox> | ||
|
||
HostSerialConnector::HostSerialConnector(QObject *parent, SimulatorInterface *simulator) | ||
: simulator(simulator) | ||
{ | ||
for (int i = 0; i < MAX_HOST_SERIAL; i++) { | ||
hostAuxPorts[i] = nullptr; | ||
hostAuxPortsEncoding[i] = SERIAL_ENCODING_8N1; | ||
hostAuxPortsBaudRate[i] = 9600; | ||
hostAuxPortsOpen[i] = false; | ||
} | ||
} | ||
|
||
HostSerialConnector::~HostSerialConnector() | ||
{ | ||
for (int i = 0; i < MAX_HOST_SERIAL; i++) { | ||
if (hostAuxPorts[i] != nullptr) { | ||
hostAuxPorts[i]->close(); | ||
hostAuxPorts[i]->deleteLater(); | ||
} | ||
} | ||
} | ||
|
||
QString HostSerialConnector::getConnectedSerialPortName(int index) | ||
{ | ||
if (index >= MAX_HOST_SERIAL) | ||
return QString(""); | ||
|
||
QMutexLocker locker(&hostAuxPortsMutex); | ||
|
||
QSerialPort * port = hostAuxPorts[index]; | ||
if (port == nullptr) | ||
return QString(""); | ||
|
||
return port->portName(); | ||
} | ||
|
||
void HostSerialConnector::connectSerialPort(int index, QString portName) | ||
{ | ||
if (index >= MAX_HOST_SERIAL) | ||
return; | ||
|
||
QMutexLocker locker(&hostAuxPortsMutex); | ||
|
||
QSerialPort * port = hostAuxPorts[index]; | ||
if (port != nullptr) { | ||
port->close(); | ||
port->deleteLater(); | ||
} | ||
|
||
if (portName.isEmpty()) { | ||
hostAuxPorts[index] = nullptr; | ||
return; | ||
} | ||
|
||
port = new QSerialPort(portName, this); | ||
hostAuxPorts[index] = port; | ||
|
||
setSerialEncoding(index, hostAuxPortsEncoding[index]); | ||
setSerialBaudRate(index, hostAuxPortsBaudRate[index]); | ||
|
||
connect(port, &QSerialPort::readyRead, [this, index, port]() { | ||
QByteArray data = port->readAll(); | ||
simulator->receiveAuxSerialData(index, data); | ||
}); | ||
|
||
if (hostAuxPortsOpen[index]) | ||
serialStart(index); | ||
} | ||
|
||
void HostSerialConnector::sendSerialData(const quint8 index, const QByteArray & data) | ||
{ | ||
if (index >= MAX_HOST_SERIAL) | ||
return; | ||
|
||
QMutexLocker locker(&hostAuxPortsMutex); | ||
|
||
QSerialPort * port = hostAuxPorts[index]; | ||
if (port == nullptr) | ||
return; | ||
|
||
port->write(data); | ||
} | ||
|
||
void HostSerialConnector::setSerialEncoding(const quint8 index, const quint8 encoding) | ||
{ | ||
if (index >= MAX_HOST_SERIAL) | ||
return; | ||
|
||
QMutexLocker locker(&hostAuxPortsMutex); | ||
|
||
hostAuxPortsEncoding[index] = encoding; | ||
|
||
QSerialPort * port = hostAuxPorts[index]; | ||
if (port == nullptr) | ||
return; | ||
|
||
switch(encoding) { | ||
case SERIAL_ENCODING_8N1: | ||
port->setDataBits(QSerialPort::Data8); | ||
port->setParity(QSerialPort::NoParity); | ||
port->setStopBits(QSerialPort::OneStop); | ||
break; | ||
case SERIAL_ENCODING_8E2: | ||
port->setDataBits(QSerialPort::Data8); | ||
port->setParity(QSerialPort::EvenParity); | ||
port->setStopBits(QSerialPort::TwoStop); | ||
break; | ||
default: | ||
// Do nothing, QSerialPort can't do SERIAL_ENCODING_PXX1_PWM | ||
break; | ||
} | ||
} | ||
|
||
void HostSerialConnector::setSerialBaudRate(const quint8 index, const quint32 baudrate) | ||
{ | ||
if (index >= MAX_HOST_SERIAL) | ||
return; | ||
|
||
QMutexLocker locker(&hostAuxPortsMutex); | ||
|
||
hostAuxPortsBaudRate[index] = baudrate; | ||
|
||
QSerialPort * port = hostAuxPorts[index]; | ||
if (port == nullptr) | ||
return; | ||
|
||
if (!port->setBaudRate(baudrate)) | ||
qDebug() << "Failed to set baudrate"; | ||
} | ||
|
||
void HostSerialConnector::serialStart(const quint8 index) | ||
{ | ||
if (index >= MAX_HOST_SERIAL) | ||
return; | ||
|
||
QMutexLocker locker(&hostAuxPortsMutex); | ||
|
||
hostAuxPortsOpen[index] = true; | ||
|
||
QSerialPort * port = hostAuxPorts[index]; | ||
if (port == nullptr) | ||
return; | ||
|
||
if (port->open(QIODevice::ReadWrite)) | ||
qDebug() << "Opened host serial " << index; | ||
else | ||
QMessageBox::warning(nullptr, tr("Host Serial Error"), port->errorString(), QMessageBox::Cancel, QMessageBox::Cancel); | ||
} | ||
|
||
void HostSerialConnector::serialStop(const quint8 index) | ||
{ | ||
if (index >= MAX_HOST_SERIAL) | ||
return; | ||
|
||
QMutexLocker locker(&hostAuxPortsMutex); | ||
|
||
hostAuxPortsOpen[index] = false; | ||
|
||
QSerialPort * port = hostAuxPorts[index]; | ||
if (port == nullptr) | ||
return; | ||
|
||
port->close(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* | ||
* Copyright (C) EdgeTX | ||
* | ||
* Based on code named | ||
* opentx - https://github.com/opentx/opentx | ||
* th9x - http://code.google.com/p/th9x | ||
* er9x - http://code.google.com/p/er9x | ||
* gruvin9x - http://code.google.com/p/gruvin9x | ||
* | ||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License version 2 as | ||
* published by the Free Software Foundation. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include "simulatorinterface.h" | ||
|
||
#include <QSerialPort> | ||
#include <QMutex> | ||
|
||
#define MAX_HOST_SERIAL 2 | ||
|
||
class HostSerialConnector : public QObject | ||
{ | ||
Q_OBJECT | ||
|
||
public: | ||
explicit HostSerialConnector(QObject * parent, SimulatorInterface * simulator); | ||
~HostSerialConnector(); | ||
|
||
QString getConnectedSerialPortName(int index); | ||
|
||
public slots: | ||
void connectSerialPort(int index, QString portName); | ||
void sendSerialData(const quint8 index, const QByteArray & data); | ||
void setSerialEncoding(const quint8 index, const quint8 encoding); | ||
void setSerialBaudRate(const quint8 index, const quint32 baudrate); | ||
void serialStart(const quint8 index); | ||
void serialStop(const quint8 index); | ||
|
||
private: | ||
SimulatorInterface * simulator; | ||
|
||
QRecursiveMutex hostAuxPortsMutex; | ||
QSerialPort * hostAuxPorts[MAX_HOST_SERIAL]; | ||
quint8 hostAuxPortsEncoding[MAX_HOST_SERIAL]; | ||
quint32 hostAuxPortsBaudRate[MAX_HOST_SERIAL]; | ||
bool hostAuxPortsOpen[MAX_HOST_SERIAL]; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/* | ||
* Copyright (C) EdgeTX | ||
* | ||
* Based on code named | ||
* opentx - https://github.com/opentx/opentx | ||
* th9x - http://code.google.com/p/th9x | ||
* er9x - http://code.google.com/p/er9x | ||
* gruvin9x - http://code.google.com/p/gruvin9x | ||
* | ||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License version 2 as | ||
* published by the Free Software Foundation. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
*/ | ||
|
||
#include "serialportsdialog.h" | ||
#include "ui_serialportsdialog.h" | ||
|
||
SerialPortsDialog::SerialPortsDialog(QWidget *parent, SimulatorInterface *simulator, HostSerialConnector *connector) : | ||
QDialog(parent), | ||
simulator(simulator), | ||
connector(connector), | ||
ui(new Ui::SerialPortsDialog) | ||
{ | ||
ui->setupUi(this); | ||
|
||
aux1 = connector->getConnectedSerialPortName(0); | ||
aux2 = connector->getConnectedSerialPortName(1); | ||
|
||
populateSerialPortCombo(ui->aux1Combo, aux1); | ||
populateSerialPortCombo(ui->aux2Combo, aux2); | ||
|
||
ui->aux1Combo->setEnabled(simulator->getCapability(SimulatorInterface::Capability::CAP_SERIAL_AUX1)); | ||
ui->aux2Combo->setEnabled(simulator->getCapability(SimulatorInterface::Capability::CAP_SERIAL_AUX2)); | ||
} | ||
|
||
SerialPortsDialog::~SerialPortsDialog() | ||
{ | ||
delete ui; | ||
} | ||
|
||
void SerialPortsDialog::populateSerialPortCombo(QComboBox * cb, QString currentPortName) | ||
{ | ||
cb->clear(); | ||
cb->addItem(tr("Not Assigned"), ""); | ||
if (currentPortName == "") { | ||
cb->setCurrentIndex(0); | ||
} | ||
|
||
const auto serialPortInfos = QSerialPortInfo::availablePorts(); | ||
for (int i = 0; i < serialPortInfos.size(); i++) { | ||
const auto portInfo = serialPortInfos[i]; | ||
cb->addItem(portInfo.portName(), portInfo.portName()); | ||
if (portInfo.portName() == currentPortName) | ||
cb->setCurrentIndex(i + 1); | ||
} | ||
} | ||
|
||
void SerialPortsDialog::on_cancelButton_clicked() | ||
{ | ||
this->reject(); | ||
} | ||
|
||
void SerialPortsDialog::on_okButton_clicked() | ||
{ | ||
this->accept(); | ||
} | ||
|
||
void SerialPortsDialog::on_refreshButton_clicked() | ||
{ | ||
populateSerialPortCombo(ui->aux1Combo, aux1); | ||
populateSerialPortCombo(ui->aux2Combo, aux2); | ||
} | ||
|
||
void SerialPortsDialog::on_aux1Combo_currentIndexChanged(int index) | ||
{ | ||
aux1 = ui->aux1Combo->itemData(index).toString(); | ||
} | ||
|
||
void SerialPortsDialog::on_aux2Combo_currentIndexChanged(int index) | ||
{ | ||
aux2 = ui->aux2Combo->itemData(index).toString(); | ||
} |
Oops, something went wrong.