From 1897e73a4d26752a5fd2278966391e804f541677 Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Fri, 13 Jan 2017 13:58:33 -0800 Subject: [PATCH] AutoConnect list dried from json file --- qgroundcontrol.qrc | 1 + src/VehicleSetup/Bootloader.h | 18 +- src/VehicleSetup/FirmwareUpgrade.qml | 4 +- src/VehicleSetup/FirmwareUpgradeController.cc | 91 +----- src/VehicleSetup/FirmwareUpgradeController.h | 10 +- src/VehicleSetup/PX4FirmwareUpgradeThread.cc | 15 +- src/VehicleSetup/PX4FirmwareUpgradeThread.h | 8 +- src/comm/LinkManager.cc | 47 +-- src/comm/QGCSerialPortInfo.cc | 309 +++++++++++++----- src/comm/QGCSerialPortInfo.h | 59 +++- src/comm/USBBoardInfo.json | 50 +++ 11 files changed, 368 insertions(+), 244 deletions(-) create mode 100644 src/comm/USBBoardInfo.json diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index b50a6e7fb..4b7b89390 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 522f528b8..9703f44e0 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 55df89348..8ab41ccf2 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 ef24f1de4..0105b80aa 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 29b4f7d24..b39fdab30 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 532ca38df..28797e149 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 cff613019..018249cbc 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 dc6c49652..68d31c11f 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 c8c0b79c5..eec24e61d 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 9609a4fa1..51f272845 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 000000000..1050c8986 --- /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" } + ] +} -- 2.22.0