diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc
index b50a6e7..4b7b893 100644
--- a/qgroundcontrol.qrc
+++ b/qgroundcontrol.qrc
@@ -167,6 +167,7 @@
src/QmlControls/QGroundControlQmlGlobal.json
src/MissionManager/RallyPoint.FactMetaData.json
src/MissionManager/Survey.FactMetaData.json
+ src/comm/USBBoardInfo.json
src/comm/APMArduCopterMockLink.params
diff --git a/src/VehicleSetup/Bootloader.h b/src/VehicleSetup/Bootloader.h
index 522f528..9703f44 100644
--- a/src/VehicleSetup/Bootloader.h
+++ b/src/VehicleSetup/Bootloader.h
@@ -61,15 +61,15 @@ public:
bool reboot(QextSerialPort* port);
// Supported bootloader board ids
- static const int boardIDPX4FMUV1 = 5; ///< PX4 V1 board, as from USB PID
- static const int boardIDPX4FMUV2 = 9; ///< PX4 V2 board, as from USB PID
- static const int boardIDPX4FMUV4 = 11; ///< PX4 V4 board, as from USB PID
- static const int boardIDPX4Flow = 6; ///< PX4 Flow board, as from USB PID
- static const int boardIDAeroCore = 98; ///< Gumstix AeroCore board, as from USB PID
- static const int boardID3DRRadio = 78; ///< 3DR Radio. This is an arbitrary value unrelated to the PID
- static const int boardIDMINDPXFMUV2 = 88; ///< MindPX V2 board, as from USB PID
- static const int boardIDTAPV1 = 64; ///< TAP V1 board, as from USB PID
- static const int boardIDASCV1 = 65; ///< ASC V1 board, as from USB PID
+ static const int boardIDPX4FMUV1 = 5; ///< PX4 V1 board, as from USB PID
+ static const int boardIDPX4FMUV2 = 9; ///< PX4 V2 board, as from USB PID
+ static const int boardIDPX4FMUV4 = 11; ///< PX4 V4 board, as from USB PID
+ static const int boardIDPX4Flow = 6; ///< PX4 Flow board, as from USB PID
+ static const int boardIDAeroCore = 98; ///< Gumstix AeroCore board, as from USB PID
+ static const int boardID3DRRadio = 78; ///< 3DR Radio. This is an arbitrary value unrelated to the PID
+ static const int boardIDMINDPXFMUV2 = 88; ///< MindPX V2 board, as from USB PID
+ static const int boardIDTAPV1 = 64; ///< TAP V1 board, as from USB PID
+ static const int boardIDASCV1 = 65; ///< ASC V1 board, as from USB PID
signals:
/// @brief Signals progress indicator for long running bootloader utility routines
diff --git a/src/VehicleSetup/FirmwareUpgrade.qml b/src/VehicleSetup/FirmwareUpgrade.qml
index 55df893..8ab41cc 100644
--- a/src/VehicleSetup/FirmwareUpgrade.qml
+++ b/src/VehicleSetup/FirmwareUpgrade.qml
@@ -97,7 +97,7 @@ QGCView {
} else {
// We end up here when we detect a board plugged in after we've started upgrade
statusTextArea.append(highlightPrefix + qsTr("Found device") + highlightSuffix + ": " + controller.boardType)
- if (controller.boardType == "Pixhawk" || controller.boardType == "AeroCore" || controller.boardType == "PX4 Flow" || controller.boardType == "PX4 FMU V1" || controller.boardType == "MindPX" || controller.boardType == "TAP V1" || controller.boardType == "ASC V1") {
+ if (controller.pixhawkBoard || controller.px4FlowBoard) {
showDialog(pixhawkFirmwareSelectDialogComponent, title, qgcView.showDialogDefaultWidth, StandardButton.Ok | StandardButton.Cancel)
}
}
@@ -124,7 +124,7 @@ QGCView {
anchors.fill: parent
property bool showFirmwareTypeSelection: _advanced.checked
- property bool px4Flow: controller.boardType == "PX4 Flow"
+ property bool px4Flow: controller.px4FlowBoard
function updatePX4VersionDisplay() {
var versionString = ""
diff --git a/src/VehicleSetup/FirmwareUpgradeController.cc b/src/VehicleSetup/FirmwareUpgradeController.cc
index ef24f1d..0105b80 100644
--- a/src/VehicleSetup/FirmwareUpgradeController.cc
+++ b/src/VehicleSetup/FirmwareUpgradeController.cc
@@ -116,43 +116,14 @@ void FirmwareUpgradeController::cancel(void)
_threadController->cancel();
}
-void FirmwareUpgradeController::_foundBoard(bool firstAttempt, const QSerialPortInfo& info, int boardType)
+void FirmwareUpgradeController::_foundBoard(bool firstAttempt, const QSerialPortInfo& info, int boardType, QString boardName)
{
_foundBoardInfo = info;
_foundBoardType = (QGCSerialPortInfo::BoardType_t)boardType;
+ _foundBoardTypeName = boardName;
+ _startFlashWhenBootloaderFound = false;
- switch (boardType) {
- case QGCSerialPortInfo::BoardTypePX4FMUV1:
- _foundBoardTypeName = "PX4 FMU V1";
- _startFlashWhenBootloaderFound = false;
- break;
- case QGCSerialPortInfo::BoardTypePX4FMUV2:
- case QGCSerialPortInfo::BoardTypePX4FMUV4:
- _foundBoardTypeName = "Pixhawk";
- _startFlashWhenBootloaderFound = false;
- break;
- case QGCSerialPortInfo::BoardTypeAeroCore:
- _foundBoardTypeName = "AeroCore";
- _startFlashWhenBootloaderFound = false;
- break;
- case QGCSerialPortInfo::BoardTypeMINDPXFMUV2:
- _foundBoardTypeName = "MindPX";
- _startFlashWhenBootloaderFound = false;
- break;
- case QGCSerialPortInfo::BoardTypeTAPV1:
- _foundBoardTypeName = "TAP V1";
- _startFlashWhenBootloaderFound = false;
- break;
- case QGCSerialPortInfo::BoardTypeASCV1:
- _foundBoardTypeName = "ASC V1";
- _startFlashWhenBootloaderFound = false;
- break;
- case QGCSerialPortInfo::BoardTypePX4Flow:
- _foundBoardTypeName = "PX4 Flow";
- _startFlashWhenBootloaderFound = false;
- break;
- case QGCSerialPortInfo::BoardTypeSikRadio:
- _foundBoardTypeName = "SiK Radio";
+ if (_foundBoardType == QGCSerialPortInfo::BoardTypeSiKRadio) {
if (!firstAttempt) {
// Radio always flashes latest firmware, so we can start right away without
// any further user input.
@@ -161,12 +132,10 @@ void FirmwareUpgradeController::_foundBoard(bool firstAttempt, const QSerialPort
StableFirmware,
DefaultVehicleFirmware);
}
- break;
}
- qCDebug(FirmwareUpgradeLog) << _foundBoardType;
+ qCDebug(FirmwareUpgradeLog) << _foundBoardType << _foundBoardTypeName;
emit boardFound();
- _loadAPMVersions(_foundBoardType);
}
@@ -197,6 +166,8 @@ void FirmwareUpgradeController::_foundBootloader(int bootloaderVersion, int boar
if (_startFlashWhenBootloaderFound) {
flash(_startFlashWhenBootloaderFoundFirmwareIdentity);
}
+
+ _loadAPMVersions(_bootloaderBoardID);
}
@@ -463,48 +434,6 @@ QHash* FirmwareUpgradeCo
}
}
-QHash* FirmwareUpgradeController::_firmwareHashForBoardType(QGCSerialPortInfo::BoardType_t boardType)
-{
- int boardId = Bootloader::boardIDPX4FMUV2;
-
- switch (boardType) {
- case QGCSerialPortInfo::BoardTypePX4FMUV1:
- boardId = Bootloader::boardIDPX4FMUV1;
- break;
- case QGCSerialPortInfo::BoardTypePX4FMUV2:
- boardId = Bootloader::boardIDPX4FMUV2;
- break;
- case QGCSerialPortInfo::BoardTypePX4FMUV4:
- boardId = Bootloader::boardIDPX4FMUV4;
- break;
- case QGCSerialPortInfo::BoardTypeAeroCore:
- boardId = Bootloader::boardIDAeroCore;
- break;
- case QGCSerialPortInfo::BoardTypeMINDPXFMUV2:
- boardId = Bootloader::boardIDMINDPXFMUV2;
- break;
- case QGCSerialPortInfo::BoardTypeTAPV1:
- boardId = Bootloader::boardIDTAPV1;
- break;
- case QGCSerialPortInfo::BoardTypeASCV1:
- boardId = Bootloader::boardIDASCV1;
- break;
- case QGCSerialPortInfo::BoardTypePX4Flow:
- boardId = Bootloader::boardIDPX4Flow;
- break;
- case QGCSerialPortInfo::BoardTypeSikRadio:
- boardId = Bootloader::boardID3DRRadio;
- break;
- default:
- qWarning() << "Internal error: invalid board type for flashing" << boardType;
- boardId = Bootloader::boardIDPX4FMUV2;
- break;
- }
-
- return _firmwareHashForBoardId(boardId);
-}
-
-
/// @brief Prompts the user to select a firmware file if needed and moves the state machine to the next state.
void FirmwareUpgradeController::_getFirmwareFile(FirmwareIdentifier firmwareId)
{
@@ -697,11 +626,11 @@ void FirmwareUpgradeController::_eraseComplete(void)
_eraseTimer.stop();
}
-void FirmwareUpgradeController::_loadAPMVersions(QGCSerialPortInfo::BoardType_t boardType)
+void FirmwareUpgradeController::_loadAPMVersions(uint32_t bootloaderBoardID)
{
_apmVersionMap.clear();
- QHash* prgFirmware = _firmwareHashForBoardType(boardType);
+ QHash* prgFirmware = _firmwareHashForBoardId(bootloaderBoardID);
foreach (FirmwareIdentifier firmwareId, prgFirmware->keys()) {
if (firmwareId.autopilotStackType == AutoPilotStackAPM) {
@@ -740,7 +669,7 @@ void FirmwareUpgradeController::_apmVersionDownloadFinished(QString remoteFile,
// In order to determine the firmware and vehicle type for this file we find the matching entry in the firmware list
- QHash* prgFirmware = _firmwareHashForBoardType(_foundBoardType);
+ QHash* prgFirmware = _firmwareHashForBoardId(_bootloaderBoardID);
QString remotePath = QFileInfo(remoteFile).path();
foreach (FirmwareIdentifier firmwareId, prgFirmware->keys()) {
diff --git a/src/VehicleSetup/FirmwareUpgradeController.h b/src/VehicleSetup/FirmwareUpgradeController.h
index 29b4f7d..b39fdab 100644
--- a/src/VehicleSetup/FirmwareUpgradeController.h
+++ b/src/VehicleSetup/FirmwareUpgradeController.h
@@ -96,6 +96,8 @@ public:
Q_PROPERTY(QString boardPort READ boardPort NOTIFY boardFound)
Q_PROPERTY(QString boardDescription READ boardDescription NOTIFY boardFound)
Q_PROPERTY(QString boardType MEMBER _foundBoardTypeName NOTIFY boardFound)
+ Q_PROPERTY(bool pixhawkBoard READ pixhawkBoard NOTIFY boardFound)
+ Q_PROPERTY(bool px4FlowBoard READ px4FlowBoard NOTIFY boardFound)
Q_PROPERTY(FirmwareType_t selectedFirmwareType READ selectedFirmwareType WRITE setSelectedFirmwareType NOTIFY selectedFirmwareTypeChanged)
Q_PROPERTY(QStringList apmAvailableVersions READ apmAvailableVersions NOTIFY apmAvailableVersionsChanged)
Q_PROPERTY(QString px4StableVersion READ px4StableVersion NOTIFY px4StableVersionChanged)
@@ -142,6 +144,9 @@ public:
QString px4StableVersion(void) { return _px4StableVersion; }
QString px4BetaVersion(void) { return _px4BetaVersion; }
+ bool pixhawkBoard(void) const { return _foundBoardType == QGCSerialPortInfo::BoardTypePixhawk; }
+ bool px4FlowBoard(void) const { return _foundBoardType == QGCSerialPortInfo::BoardTypePX4Flow; }
+
signals:
void boardFound(void);
void noBoardFound(void);
@@ -158,7 +163,7 @@ private slots:
void _firmwareDownloadProgress(qint64 curr, qint64 total);
void _firmwareDownloadFinished(QString remoteFile, QString localFile);
void _firmwareDownloadError(QString errorMsg);
- void _foundBoard(bool firstAttempt, const QSerialPortInfo& portInfo, int boardType);
+ void _foundBoard(bool firstAttempt, const QSerialPortInfo& portInfo, int boardType, QString boardName);
void _noBoardFound(void);
void _boardGone();
void _foundBootloader(int bootloaderVersion, int boardID, int flashSize);
@@ -180,9 +185,8 @@ private:
void _downloadFirmware(void);
void _appendStatusLog(const QString& text, bool critical = false);
void _errorCancel(const QString& msg);
- void _loadAPMVersions(QGCSerialPortInfo::BoardType_t boardType);
+ void _loadAPMVersions(uint32_t bootloaderBoardID);
QHash* _firmwareHashForBoardId(int boardId);
- QHash* _firmwareHashForBoardType(QGCSerialPortInfo::BoardType_t boardType);
void _determinePX4StableVersion(void);
QString _portName;
diff --git a/src/VehicleSetup/PX4FirmwareUpgradeThread.cc b/src/VehicleSetup/PX4FirmwareUpgradeThread.cc
index 532ca38..28797e1 100644
--- a/src/VehicleSetup/PX4FirmwareUpgradeThread.cc
+++ b/src/VehicleSetup/PX4FirmwareUpgradeThread.cc
@@ -86,14 +86,15 @@ void PX4FirmwareUpgradeThreadWorker::_findBoardOnce(void)
QGCSerialPortInfo portInfo;
QGCSerialPortInfo::BoardType_t boardType;
+ QString boardName;
- if (_findBoardFromPorts(portInfo, boardType)) {
+ if (_findBoardFromPorts(portInfo, boardType, boardName)) {
if (!_foundBoard) {
_foundBoard = true;
_foundBoardPortInfo = portInfo;
- emit foundBoard(_findBoardFirstAttempt, portInfo, boardType);
+ emit foundBoard(_findBoardFirstAttempt, portInfo, boardType, boardName);
if (!_findBoardFirstAttempt) {
- if (boardType == QGCSerialPortInfo::BoardTypeSikRadio) {
+ if (boardType == QGCSerialPortInfo::BoardTypeSiKRadio) {
_3drRadioForceBootloader(portInfo);
return;
} else {
@@ -116,18 +117,20 @@ void PX4FirmwareUpgradeThreadWorker::_findBoardOnce(void)
_timerRetry->start();
}
-bool PX4FirmwareUpgradeThreadWorker::_findBoardFromPorts(QGCSerialPortInfo& portInfo, QGCSerialPortInfo::BoardType_t& boardType)
+bool PX4FirmwareUpgradeThreadWorker::_findBoardFromPorts(QGCSerialPortInfo& portInfo, QGCSerialPortInfo::BoardType_t& boardType, QString& boardName)
{
foreach (QGCSerialPortInfo info, QGCSerialPortInfo::availablePorts()) {
+ info.getBoardInfo(boardType, boardName);
+
qCDebug(FirmwareUpgradeVerboseLog) << "Serial Port --------------";
- qCDebug(FirmwareUpgradeVerboseLog) << "\tboard type" << info.boardType();
+ qCDebug(FirmwareUpgradeVerboseLog) << "\tboard type" << boardType;
+ qCDebug(FirmwareUpgradeVerboseLog) << "\tboard name" << boardName;
qCDebug(FirmwareUpgradeVerboseLog) << "\tport name:" << info.portName();
qCDebug(FirmwareUpgradeVerboseLog) << "\tdescription:" << info.description();
qCDebug(FirmwareUpgradeVerboseLog) << "\tsystem location:" << info.systemLocation();
qCDebug(FirmwareUpgradeVerboseLog) << "\tvendor ID:" << info.vendorIdentifier();
qCDebug(FirmwareUpgradeVerboseLog) << "\tproduct ID:" << info.productIdentifier();
- boardType = info.boardType();
if (info.canFlash()) {
portInfo = info;
return true;
diff --git a/src/VehicleSetup/PX4FirmwareUpgradeThread.h b/src/VehicleSetup/PX4FirmwareUpgradeThread.h
index cff6130..018249c 100644
--- a/src/VehicleSetup/PX4FirmwareUpgradeThread.h
+++ b/src/VehicleSetup/PX4FirmwareUpgradeThread.h
@@ -43,7 +43,7 @@ public:
signals:
void updateProgress(int curr, int total);
- void foundBoard(bool firstAttempt, const QGCSerialPortInfo& portInfo, int type);
+ void foundBoard(bool firstAttempt, const QGCSerialPortInfo& portInfo, int type, QString boardName);
void noBoardFound(void);
void boardGone(void);
void foundBootloader(int bootloaderVersion, int boardID, int flashSize);
@@ -64,7 +64,7 @@ private slots:
void _cancel(void);
private:
- bool _findBoardFromPorts(QGCSerialPortInfo& portInfo, QGCSerialPortInfo::BoardType_t& boardType);
+ bool _findBoardFromPorts(QGCSerialPortInfo& portInfo, QGCSerialPortInfo::BoardType_t& boardType, QString& boardName);
bool _findBootloader(const QGCSerialPortInfo& portInfo, bool radioMode, bool errorOnNotFound);
void _3drRadioForceBootloader(const QGCSerialPortInfo& portInfo);
bool _erase(void);
@@ -107,7 +107,7 @@ public:
signals:
/// @brief Emitted by the find board process when it finds a board.
- void foundBoard(bool firstAttempt, const QGCSerialPortInfo &portInfo, int boardType);
+ void foundBoard(bool firstAttempt, const QGCSerialPortInfo &portInfo, int boardType, QString boardName);
void noBoardFound(void);
@@ -142,7 +142,7 @@ signals:
void _cancel(void);
private slots:
- void _foundBoard(bool firstAttempt, const QGCSerialPortInfo& portInfo, int type) { emit foundBoard(firstAttempt, portInfo, type); }
+ void _foundBoard(bool firstAttempt, const QGCSerialPortInfo& portInfo, int type, QString name) { emit foundBoard(firstAttempt, portInfo, type, name); }
void _noBoardFound(void) { emit noBoardFound(); }
void _boardGone(void) { emit boardGone(); }
void _foundBootloader(int bootloaderVersion, int boardID, int flashSize) { emit foundBootloader(bootloaderVersion, boardID, flashSize); }
diff --git a/src/comm/LinkManager.cc b/src/comm/LinkManager.cc
index dc6c496..68d31c1 100644
--- a/src/comm/LinkManager.cc
+++ b/src/comm/LinkManager.cc
@@ -524,9 +524,10 @@ void LinkManager::_updateAutoConnectLinks(void)
// Save port name
currentPorts << portInfo.systemLocation();
- QGCSerialPortInfo::BoardType_t boardType = portInfo.boardType();
+ QGCSerialPortInfo::BoardType_t boardType;
+ QString boardName;
- if (boardType != QGCSerialPortInfo::BoardTypeUnknown) {
+ if (portInfo.getBoardInfo(boardType, boardName)) {
if (portInfo.isBootloader()) {
// Don't connect to bootloader
qCDebug(LinkManagerLog) << "Waiting for bootloader to finish" << portInfo.systemLocation();
@@ -547,51 +548,25 @@ void LinkManager::_updateAutoConnectLinks(void)
_autoconnectWaitList.remove(portInfo.systemLocation());
switch (boardType) {
- case QGCSerialPortInfo::BoardTypePX4FMUV1:
- case QGCSerialPortInfo::BoardTypePX4FMUV2:
- case QGCSerialPortInfo::BoardTypePX4FMUV4:
+ case QGCSerialPortInfo::BoardTypePixhawk:
if (_autoconnectPixhawk) {
- pSerialConfig = new SerialConfiguration(tr("Pixhawk on %1 (AutoConnect)").arg(portInfo.portName().trimmed()));
- pSerialConfig->setUsbDirect(true);
- }
- break;
- case QGCSerialPortInfo::BoardTypeAeroCore:
- if (_autoconnectPixhawk) {
- pSerialConfig = new SerialConfiguration(tr("AeroCore on %1 (AutoConnect)").arg(portInfo.portName().trimmed()));
- pSerialConfig->setUsbDirect(true);
- }
- break;
- case QGCSerialPortInfo::BoardTypeMINDPXFMUV2:
- if (_autoconnectPixhawk) {
- pSerialConfig = new SerialConfiguration(tr("MindPX on %1 (AutoConnect)").arg(portInfo.portName().trimmed()));
- pSerialConfig->setUsbDirect(true);
- }
- break;
- case QGCSerialPortInfo::BoardTypeTAPV1:
- if (_autoconnectPixhawk) {
- pSerialConfig = new SerialConfiguration(tr("TAP on %1 (AutoConnect)").arg(portInfo.portName().trimmed()));
- pSerialConfig->setUsbDirect(true);
- }
- break;
- case QGCSerialPortInfo::BoardTypeASCV1:
- if (_autoconnectPixhawk) {
- pSerialConfig = new SerialConfiguration(tr("ASC on %1 (AutoConnect)").arg(portInfo.portName().trimmed()));
+ pSerialConfig = new SerialConfiguration(tr("%1 on %2 (AutoConnect)").arg(boardName).arg(portInfo.portName().trimmed()));
pSerialConfig->setUsbDirect(true);
}
break;
case QGCSerialPortInfo::BoardTypePX4Flow:
if (_autoconnectPX4Flow) {
- pSerialConfig = new SerialConfiguration(tr("PX4Flow on %1 (AutoConnect)").arg(portInfo.portName().trimmed()));
+ pSerialConfig = new SerialConfiguration(tr("%1 on %2 (AutoConnect)").arg(boardName).arg(portInfo.portName().trimmed()));
}
break;
- case QGCSerialPortInfo::BoardTypeSikRadio:
+ case QGCSerialPortInfo::BoardTypeSiKRadio:
if (_autoconnect3DRRadio) {
- pSerialConfig = new SerialConfiguration(tr("SiK Radio on %1 (AutoConnect)").arg(portInfo.portName().trimmed()));
+ pSerialConfig = new SerialConfiguration(tr("%1 on %2 (AutoConnect)").arg(boardName).arg(portInfo.portName().trimmed()));
}
break;
- case QGCSerialPortInfo::BoardTypeLibrePilot:
+ case QGCSerialPortInfo::BoardTypeOpenPilot:
if (_autoconnectLibrePilot) {
- pSerialConfig = new SerialConfiguration(tr("LibrePilot on %1 (AutoConnect)").arg(portInfo.portName().trimmed()));
+ pSerialConfig = new SerialConfiguration(tr("%1 on %2 (AutoConnect)").arg(boardName).arg(portInfo.portName().trimmed()));
}
break;
#ifndef __mobile__
@@ -609,7 +584,7 @@ void LinkManager::_updateAutoConnectLinks(void)
if (pSerialConfig) {
qCDebug(LinkManagerLog) << "New auto-connect port added: " << pSerialConfig->name() << portInfo.systemLocation();
- pSerialConfig->setBaud(boardType == QGCSerialPortInfo::BoardTypeSikRadio ? 57600 : 115200);
+ pSerialConfig->setBaud(boardType == QGCSerialPortInfo::BoardTypeSiKRadio ? 57600 : 115200);
pSerialConfig->setDynamic(true);
pSerialConfig->setPortName(portInfo.systemLocation());
_sharedAutoconnectConfigurations.append(SharedLinkConfigurationPointer(pSerialConfig));
diff --git a/src/comm/QGCSerialPortInfo.cc b/src/comm/QGCSerialPortInfo.cc
index c8c0b79..eec24e6 100644
--- a/src/comm/QGCSerialPortInfo.cc
+++ b/src/comm/QGCSerialPortInfo.cc
@@ -9,33 +9,37 @@
#include "QGCSerialPortInfo.h"
+#include "JsonHelper.h"
+
+#include
+#include
+#include
+#include
QGC_LOGGING_CATEGORY(QGCSerialPortInfoLog, "QGCSerialPortInfoLog")
-static const struct VIDPIDMapInfo_s {
- int vendorId;
- int productId;
- QGCSerialPortInfo::BoardType_t boardType;
- const char * boardString;
-} s_rgVIDPIDMappings[] = {
- { QGCSerialPortInfo::px4VendorId, QGCSerialPortInfo::pixhawkFMUV4ProductId, QGCSerialPortInfo::BoardTypePX4FMUV4, "Found PX4 FMU V4" },
- { QGCSerialPortInfo::px4VendorId, QGCSerialPortInfo::pixhawkFMUV2ProductId, QGCSerialPortInfo::BoardTypePX4FMUV2, "Found PX4 FMU V2" },
- { QGCSerialPortInfo::px4VendorId, QGCSerialPortInfo::pixhawkFMUV2OldBootloaderProductId, QGCSerialPortInfo::BoardTypePX4FMUV2, "Found PX4 FMU V2"},
- { QGCSerialPortInfo::px4VendorId, QGCSerialPortInfo::pixhawkFMUV1ProductId, QGCSerialPortInfo::BoardTypePX4FMUV1, "Found PX4 FMU V1" },
- { QGCSerialPortInfo::px4VendorId, QGCSerialPortInfo::px4FlowProductId, QGCSerialPortInfo::BoardTypePX4Flow, "Found PX4 Flow" },
- { QGCSerialPortInfo::px4VendorId, QGCSerialPortInfo::AeroCoreProductId, QGCSerialPortInfo::BoardTypeAeroCore, "Found AeroCore" },
- { QGCSerialPortInfo::px4VendorId, QGCSerialPortInfo::MindPXFMUV2ProductId, QGCSerialPortInfo::BoardTypeMINDPXFMUV2,"Found MindPX FMU V2" },
- { QGCSerialPortInfo::px4VendorId, QGCSerialPortInfo::TAPV1ProductId, QGCSerialPortInfo::BoardTypeTAPV1, "Found TAP V1" },
- { QGCSerialPortInfo::px4VendorId, QGCSerialPortInfo::ASCV1ProductId, QGCSerialPortInfo::BoardTypeASCV1, "Found ASC V1" },
- { QGCSerialPortInfo::threeDRRadioVendorId, QGCSerialPortInfo::threeDRRadioProductId, QGCSerialPortInfo::BoardTypeSikRadio, "Found SiK Radio" },
- { QGCSerialPortInfo::siLabsRadioVendorId, QGCSerialPortInfo::siLabsRadioProductId, QGCSerialPortInfo::BoardTypeSikRadio, "Found SiK Radio" },
- { QGCSerialPortInfo::ubloxRTKVendorId, QGCSerialPortInfo::ubloxRTKProductId, QGCSerialPortInfo::BoardTypeRTKGPS, "Found RTK GPS" },
- { QGCSerialPortInfo::openpilotVendorId, QGCSerialPortInfo::revolutionProductId, QGCSerialPortInfo::BoardTypeLibrePilot, "Found OP Revolution" },
- { QGCSerialPortInfo::openpilotVendorId, QGCSerialPortInfo::oplinkProductId, QGCSerialPortInfo::BoardTypeLibrePilot, "Found OP OPLink" },
- { QGCSerialPortInfo::openpilotVendorId, QGCSerialPortInfo::sparky2ProductId, QGCSerialPortInfo::BoardTypeLibrePilot, "Found TL Sparky2" },
- { QGCSerialPortInfo::openpilotVendorId, QGCSerialPortInfo::CC3DProductId, QGCSerialPortInfo::BoardTypeLibrePilot, "Found OP CC3D" },
+bool QGCSerialPortInfo::_jsonLoaded = false;
+const char* QGCSerialPortInfo::_jsonFileTypeValue = "USBBoardInfo";
+const char* QGCSerialPortInfo::_jsonBoardInfoKey = "boardInfo";
+const char* QGCSerialPortInfo::_jsonBoardFallbackKey = "boardFallback";
+const char* QGCSerialPortInfo::_jsonVendorIDKey = "vendorID";
+const char* QGCSerialPortInfo::_jsonProductIDKey = "productID";
+const char* QGCSerialPortInfo::_jsonBoardClassKey = "boardClass";
+const char* QGCSerialPortInfo::_jsonNameKey = "name";
+const char* QGCSerialPortInfo::_jsonRegExpKey = "regExp";
+const char* QGCSerialPortInfo::_jsonAndroidOnlyKey = "androidOnly";
+
+const QGCSerialPortInfo::BoardClassString2BoardType_t QGCSerialPortInfo::_rgBoardClass2BoardType[] = {
+ { "Pixhawk", QGCSerialPortInfo::BoardTypePixhawk },
+ { "PX4 Flow", QGCSerialPortInfo::BoardTypePX4Flow },
+ { "RTK GPS", QGCSerialPortInfo::BoardTypeRTKGPS },
+ { "SiK Radio", QGCSerialPortInfo::BoardTypeSiKRadio },
+ { "OpenPilot", QGCSerialPortInfo::BoardTypeOpenPilot },
};
+QList QGCSerialPortInfo::_boardInfoList;
+QList QGCSerialPortInfo::_boardFallbackList;
+
QGCSerialPortInfo::QGCSerialPortInfo(void) :
QSerialPortInfo()
{
@@ -48,67 +52,198 @@ QGCSerialPortInfo::QGCSerialPortInfo(const QSerialPort & port) :
}
-QGCSerialPortInfo::BoardType_t QGCSerialPortInfo::boardType(void) const
+void QGCSerialPortInfo::_loadJsonData(void)
{
- if (isNull()) {
- return BoardTypeUnknown;
+ if (_jsonLoaded) {
+ return;
+ }
+ _jsonLoaded = true;
+
+ QFile file(QStringLiteral(":/json/USBBoardInfo.json"));
+
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ qWarning() << "Unable to open board info json:" << file.errorString();
+ return;
+ }
+
+ QByteArray bytes = file.readAll();
+
+ QJsonParseError jsonParseError;
+ QJsonDocument jsonDoc(QJsonDocument::fromJson(bytes, &jsonParseError));
+ if (jsonParseError.error != QJsonParseError::NoError) {
+ qWarning() << "Unable to parse board info json:" << jsonParseError.errorString();
+ return;
+ }
+ QJsonObject json = jsonDoc.object();
+
+ int fileVersion;
+ QString errorString;
+ if (!JsonHelper::validateQGCJsonFile(json,
+ _jsonFileTypeValue, // expected file type
+ 1, // minimum supported version
+ 1, // maximum supported version
+ fileVersion,
+ errorString)) {
+ qWarning() << errorString;
+ return;
+ }
+
+ // Validate root object keys
+ QList rootKeyInfoList = {
+ { _jsonBoardInfoKey, QJsonValue::Array, true },
+ { _jsonBoardFallbackKey, QJsonValue::Array, true },
+ };
+ if (!JsonHelper::validateKeys(json, rootKeyInfoList, errorString)) {
+ qWarning() << errorString;
+ return;
+ }
+
+ // Load board info used to detect known board from vendor/product id
+
+ QList boardKeyInfoList = {
+ { _jsonVendorIDKey, QJsonValue::Double, true },
+ { _jsonProductIDKey, QJsonValue::Double, true },
+ { _jsonBoardClassKey, QJsonValue::String, true },
+ { _jsonNameKey, QJsonValue::String, true },
+ };
+
+ QJsonArray rgBoardInfo = json[_jsonBoardInfoKey].toArray();
+ for (int i=0; i fallbackKeyInfoList = {
+ { _jsonRegExpKey, QJsonValue::String, true },
+ { _jsonBoardClassKey, QJsonValue::String, true },
+ { _jsonAndroidOnlyKey, QJsonValue::Bool, false },
+ };
- if (vendorIdentifier() == pIDMap->vendorId && productIdentifier() == pIDMap->productId) {
- boardType = pIDMap->boardType;
- qCDebug(QGCSerialPortInfoLog) << pIDMap->boardString;
+ QJsonArray rgBoardFallback = json[_jsonBoardFallbackKey].toArray();
+ for (int i=0; i QGCSerialPortInfo::availablePorts(void)
{
QList list;
@@ -120,34 +255,34 @@ QList QGCSerialPortInfo::availablePorts(void)
return list;
}
-bool QGCSerialPortInfo::boardTypePixhawk(void) const
-{
- BoardType_t boardType = this->boardType();
-
- return boardType == BoardTypePX4FMUV1 || boardType == BoardTypePX4FMUV2
- || boardType == BoardTypePX4FMUV4 || boardType == BoardTypeAeroCore
- || boardType == BoardTypeMINDPXFMUV2 || boardType == BoardTypeTAPV1
- || boardType == BoardTypeASCV1;
-}
-
bool QGCSerialPortInfo::isBootloader(void) const
{
- // FIXME: Check SerialLink bootloade detect code which is different
- return boardTypePixhawk() && description().contains("BL");
+ BoardType_t boardType;
+ QString name;
+
+ if (getBoardInfo(boardType, name)) {
+ // FIXME: Check SerialLink bootloade detect code which is different
+ return boardType == BoardTypePixhawk && description().contains("BL");
+ } else {
+ return false;
+ }
}
bool QGCSerialPortInfo::canFlash(void)
{
- BoardType_t boardType = this->boardType();
- switch(boardType){
- case QGCSerialPortInfo::BoardTypeUnknown:
- case QGCSerialPortInfo::BoardTypeRTKGPS:
- case QGCSerialPortInfo::BoardTypeLibrePilot:
- return false;
- default:
- return true;
+ BoardType_t boardType;
+ QString name;
+ if (getBoardInfo(boardType, name)) {
+ switch(boardType){
+ case QGCSerialPortInfo::BoardTypePixhawk:
+ case QGCSerialPortInfo::BoardTypePX4Flow:
+ case QGCSerialPortInfo::BoardTypeSiKRadio:
+ return true;
+ default:
+ return false;
+ }
+ } else {
+ return false;
}
-
-
}
diff --git a/src/comm/QGCSerialPortInfo.h b/src/comm/QGCSerialPortInfo.h
index 9609a4f..51f2728 100644
--- a/src/comm/QGCSerialPortInfo.h
+++ b/src/comm/QGCSerialPortInfo.h
@@ -27,25 +27,19 @@ class QGCSerialPortInfo : public QSerialPortInfo
{
public:
typedef enum {
- BoardTypePX4FMUV1,
- BoardTypePX4FMUV2,
- BoardTypePX4FMUV4,
+ BoardTypePixhawk,
+ BoardTypeSiKRadio,
BoardTypePX4Flow,
- BoardTypeSikRadio,
- BoardTypeAeroCore,
+ BoardTypeOpenPilot,
BoardTypeRTKGPS,
- BoardTypeMINDPXFMUV2,
- BoardTypeTAPV1,
- BoardTypeASCV1,
- BoardTypeLibrePilot,
BoardTypeUnknown
} BoardType_t;
// Vendor and products ids for the boards we care about
- static const int px4VendorId = 9900; ///< Vendor ID for Pixhawk board (V2 and V1) and PX4 Flow
-
- static const int pixhawkFMUV4ProductId = 18; ///< Product ID for Pixhawk V2 board
+ static const int px4VendorId = 9900; ///< Vendor ID for all Pixhawk boards and PX4 Flow
+ static const int pixhawkFMUV4ProductId = 18; ///< Product ID for Pixhawk V4 board
+ static const int pixhawkFMUV4ProProductId = 19; ///< Product ID for Pixhawk V4 Pro board
static const int pixhawkFMUV2ProductId = 17; ///< Product ID for Pixhawk V2 board
static const int pixhawkFMUV2OldBootloaderProductId = 22; ///< Product ID for Bootloader on older Pixhawk V2 boards
static const int pixhawkFMUV1ProductId = 16; ///< Product ID for PX4 FMU V1 board
@@ -79,18 +73,51 @@ public:
/// Override of QSerialPortInfo::availablePorts
static QList availablePorts(void);
- BoardType_t boardType(void) const;
+ bool getBoardInfo(BoardType_t& boardType, QString& name) const;
/// @return true: we can flash this board type
bool canFlash(void);
- /// @return true: board is a Pixhawk board
- bool boardTypePixhawk(void) const;
-
/// @return true: Board is currently in bootloader
bool isBootloader(void) const;
private:
+ typedef struct {
+ const char* classString;
+ BoardType_t boardType;
+ } BoardClassString2BoardType_t;
+
+ typedef struct {
+ int vendorId;
+ int productId;
+ BoardType_t boardType;
+ QString name;
+ } BoardInfo_t;
+
+ typedef struct {
+ QString regExp;
+ BoardType_t boardType;
+ bool androidOnly;
+ } BoardFallback_t;
+
+ static void _loadJsonData(void);
+ static BoardType_t _boardClassStringToType(const QString& boardClass);
+ static QString _boardTypeToString(BoardType_t boardType);
+
+ static bool _jsonLoaded;
+ static const char* _jsonFileTypeValue;
+ static const char* _jsonBoardInfoKey;
+ static const char* _jsonBoardFallbackKey;
+ static const char* _jsonVendorIDKey;
+ static const char* _jsonProductIDKey;
+ static const char* _jsonBoardClassKey;
+ static const char* _jsonNameKey;
+ static const char* _jsonRegExpKey;
+ static const char* _jsonAndroidOnlyKey;
+
+ static const BoardClassString2BoardType_t _rgBoardClass2BoardType[BoardTypeUnknown];
+ static QList _boardInfoList;
+ static QList _boardFallbackList;
};
#endif
diff --git a/src/comm/USBBoardInfo.json b/src/comm/USBBoardInfo.json
new file mode 100644
index 0000000..1050c89
--- /dev/null
+++ b/src/comm/USBBoardInfo.json
@@ -0,0 +1,50 @@
+{
+ "comment": "AutoConnect usb board info",
+
+ "version": 1,
+ "fileType": "USBBoardInfo",
+ "groundStation": "QGroundControl",
+
+ "boardInfo": [
+ { "vendorID": 9900, "productID": 16, "boardClass": "Pixhawk", "name": "PX4 FMU V1" },
+ { "vendorID": 9900, "productID": 17, "boardClass": "Pixhawk", "name": "PX4 FMU V2" },
+ { "vendorID": 9900, "productID": 18, "boardClass": "Pixhawk", "name": "PX4 FMU V4" },
+ { "vendorID": 9900, "productID": 22, "boardClass": "Pixhawk", "name": "PX4 FMU V2", "comment": "Bootloader on older Pixhawk V2 boards" },
+ { "vendorID": 9900, "productID": 4097, "boardClass": "Pixhawk", "name": "AeroCore" },
+ { "vendorID": 9900, "productID": 48, "boardClass": "Pixhawk", "name": "MindPX FMU V2" },
+ { "vendorID": 9900, "productID": 64, "boardClass": "Pixhawk", "name": "TAP V1" },
+ { "vendorID": 9900, "productID": 65, "boardClass": "Pixhawk", "name": "ASC V1" },
+
+ { "vendorID": 9900, "productID": 21, "boardClass": "PX4 Flow", "name": "PX4 Flow" },
+
+ { "vendorID": 1027, "productID": 24597, "boardClass": "SiK Radio", "name": "SiK Radio", "comment": "3DR Radio" },
+ { "vendorID": 4292, "productID": 600000, "boardClass": "SiK Radio", "name": "SiK Radio", "comment": "SILabs Radio" },
+
+ { "vendorID": 546, "productID": 424, "boardClass": "RTK GPS", "name": "RTK GPS", "comment": "Ublox RTK GPS" },
+
+ { "vendorID": 8352, "productID": 16732, "boardClass": "OpenPilot", "name": "OpenPilot OPLink" },
+ { "vendorID": 8352, "productID": 16733, "boardClass": "OpenPilot", "name": "OpenPilot CC3D" },
+ { "vendorID": 8352, "productID": 16734, "boardClass": "OpenPilot", "name": "OpenPilot Revolution" },
+ { "vendorID": 8352, "productID": 16848, "boardClass": "OpenPilot", "name": "Taulabs Sparky2" }
+ ],
+
+ "boardFallback": [
+ { "regExp": "^PX4 FMU v4.x$", "boardClass": "Pixhawk" },
+ { "regExp": "^PX4 BL FMU v4.x$", "boardClass": "Pixhawk" },
+ { "regExp": "^PX4 FMU v2.x$", "boardClass": "Pixhawk" },
+ { "regExp": "^PX4 BL FMU v2.x$", "boardClass": "Pixhawk" },
+ { "regExp": "^PX4 FMU v1.x$", "boardClass": "Pixhawk" },
+ { "regExp": "^PX4 BL FMU v1.x$", "boardClass": "Pixhawk" },
+ { "regExp": "^MindPX FMU v2.x$", "boardClass": "Pixhawk" },
+ { "regExp": "^MindPX FMU v2.x$", "boardClass": "Pixhawk" },
+ { "regExp": "^MindPX BL FMU v2.x$", "boardClass": "Pixhawk" },
+ { "regExp": "^PX4 TAP v1.x$", "boardClass": "Pixhawk" },
+ { "regExp": "^PX4 BL TAP v1.x$", "boardClass": "Pixhawk" },
+ { "regExp": "^PX4 ASC v1.x$", "boardClass": "Pixhawk" },
+ { "regExp": "^PX4 BL ASC v1.x$", "boardClass": "Pixhawk" },
+ { "regExp": "^PX4 FMU", "boardClass": "Pixhawk" },
+ { "regExp": "PX4.*Flow", "boardClass": "PX4 Flow" },
+ { "regExp": "^FT231X USB UART$", "boardClass": "SiK Radio" },
+ { "regExp": "USB UART$", "boardClass": "SiK Radio", "androidOnly": true, "comment": "Very broad fallback, too dangerous for non-android" }
+ ]
+}