Browse Source

Merge pull request #7319 from DonLakeFlyer/ChibiOSBootloader

Full ChibiOS bootloader support, plus autoconnect for ChibiOS builds
QGC4.4
Don Gagne 6 years ago committed by GitHub
parent
commit
47d1f9f98c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      ChangeLog.md
  2. 2
      src/AutoPilotPlugins/Common/SetupPage.qml
  3. 13
      src/Vehicle/Vehicle.cc
  4. 4
      src/Vehicle/Vehicle.h
  5. 2
      src/VehicleSetup/Bootloader.h
  6. 39
      src/VehicleSetup/FirmwareUpgrade.qml
  7. 111
      src/VehicleSetup/FirmwareUpgradeController.cc
  8. 1
      src/VehicleSetup/PX4FirmwareUpgradeThread.cc
  9. 94
      src/comm/QGCSerialPortInfo.cc
  10. 8
      src/comm/QGCSerialPortInfo.h
  11. 19
      src/comm/USBBoardInfo.json

3
ChangeLog.md

@ -6,12 +6,11 @@ Note: This file only contains high level features or important fixes. @@ -6,12 +6,11 @@ Note: This file only contains high level features or important fixes.
### 3.6.0 - Daily Build
* Improved support for flashing/connecting to ChibiOS bootloaders boards.
* Making the camera API available to all firmwares, not just PX4.
* ArduPilot: Support configurable mavlink stream rates. Available from Settings/Mavlink page.
* Major rewrite and bug fix pass through Structure Scan. Previous version had such bad problems that it can no longer be supported. Plans with Structure Scan will need to be recreated. New QGC will not load old Structure Scan plans.
* Major rewrite and bug fix pass through Structure Scan. Previous version had such bad problems that it can no longer be supported. Plans with Structure Scan will need to be recreated. New QGC will not load old Structure Scan plans.
### 3.5.1 - Not yet released
* Fix tile set count but in OfflineMaps which would cause image and elevation tile set to have incorrect counts and be incorrectly marked as download incomplete.

2
src/AutoPilotPlugins/Common/SetupPage.qml

@ -86,7 +86,7 @@ QGCView { @@ -86,7 +86,7 @@ QGCView {
anchors.right: parent.right
wrapMode: Text.WordWrap
text: pageDescription
visible: !ScreenTools.isShortScreen
visible: pageDescription !== "" && !ScreenTools.isShortScreen
}
}
}

13
src/Vehicle/Vehicle.cc

@ -3849,6 +3849,19 @@ int Vehicle::versionCompare(int major, int minor, int patch) @@ -3849,6 +3849,19 @@ int Vehicle::versionCompare(int major, int minor, int patch)
return _firmwarePlugin->versionCompare(this, major, minor, patch);
}
#if !defined(NO_ARDUPILOT_DIALECT)
void Vehicle::flashBootloader(void)
{
sendMavCommand(defaultComponentId(),
MAV_CMD_FLASH_BOOTLOADER,
true, // show error
0, 0, 0, 0, // param 1-4 not used
290876); // magic number
}
#endif
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

4
src/Vehicle/Vehicle.h

@ -756,6 +756,10 @@ public: @@ -756,6 +756,10 @@ public:
/// @param percent 0-no power, 100-full power
Q_INVOKABLE void motorTest(int motor, int percent);
#if !defined(NO_ARDUPILOT_DIALECT)
Q_INVOKABLE void flashBootloader(void);
#endif
bool guidedModeSupported (void) const;
bool pauseVehicleSupported (void) const;
bool orbitModeSupported (void) const;

2
src/VehicleSetup/Bootloader.h

@ -64,7 +64,7 @@ public: @@ -64,7 +64,7 @@ public:
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 boardIDPX4FMUV4PRO = 13; ///< PX4 V4PRO board, as from USB PID
static const int boardIDPX4FMUV4PRO = 13; ///< PX4 V4PRO board, as from USB PID
static const int boardIDPX4FMUV5 = 50; ///< PX4 V5 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

39
src/VehicleSetup/FirmwareUpgrade.qml

@ -23,9 +23,14 @@ import QGroundControl.Controllers 1.0 @@ -23,9 +23,14 @@ import QGroundControl.Controllers 1.0
import QGroundControl.ScreenTools 1.0
SetupPage {
id: firmwarePage
pageComponent: firmwarePageComponent
pageName: "Firmware" // For building setup page title: 'Firmware Setup'
id: firmwarePage
pageComponent: firmwarePageComponent
pageName: qsTr("Firmware")
showAdvanced: _activeVehicle && _activeVehicle.apmFirmware
property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
signal cancelDialog
Component {
id: firmwarePageComponent
@ -40,7 +45,7 @@ SetupPage { @@ -40,7 +45,7 @@ SetupPage {
// a better way to hightlight them, or use less highlights.
// User visible strings
readonly property string title: "Firmware Setup" // Popup dialog title
readonly property string title: qsTr("Firmware Setup") // Popup dialog title
readonly property string highlightPrefix: "<font color=\"" + qgcPal.warningText + "\">"
readonly property string highlightSuffix: "</font>"
@ -124,8 +129,8 @@ SetupPage { @@ -124,8 +129,8 @@ SetupPage {
}
onError: {
hideDialog()
statusTextArea.append(flashFailText)
firmwarePage.cancelDialog()
}
}
@ -165,7 +170,11 @@ SetupPage { @@ -165,7 +170,11 @@ SetupPage {
px4FlightStackRadio2.text = qsTr("PX4 Flight Stack ") + versionString
}
Component.onCompleted: updatePX4VersionDisplay()
Component.onCompleted: {
firmwarePage.advanced = false
firmwarePage.showAdvanced = false
updatePX4VersionDisplay()
}
function accept() {
hideDialog()
@ -195,6 +204,12 @@ SetupPage { @@ -195,6 +204,12 @@ SetupPage {
cancelFlash()
}
Connections {
target: firmwarePage
onCancelDialog: reject()
}
ExclusiveGroup {
id: firmwareGroup
}
@ -438,8 +453,16 @@ SetupPage { @@ -438,8 +453,16 @@ SetupPage {
}
ProgressBar {
id: progressBar
Layout.preferredWidth: parent.width
id: progressBar
Layout.preferredWidth: parent.width
visible: !flashBootloaderButton.visible
}
QGCButton {
id: flashBootloaderButton
text: qsTr("Flash ChibiOS Bootloader")
visible: firmwarePage.advanced
onClicked: _activeVehicle.flashBootloader()
}
TextArea {

111
src/VehicleSetup/FirmwareUpgradeController.cc

@ -363,48 +363,44 @@ void FirmwareUpgradeController::_initFirmwareHash() @@ -363,48 +363,44 @@ void FirmwareUpgradeController::_initFirmwareHash()
// PX4 Firmwares
for (const FirmwareType_t& firmwareType: px4MapFirmwareTypeToDir.keys()) {
QString dir = px4MapFirmwareTypeToDir[firmwareType];
_rgFMUV5Firmware.insert (FirmwareIdentifier(AutoPilotStackPX4, firmwareType, DefaultVehicleFirmware), px4Url.arg(dir).arg("v5"));
_rgFMUV4PROFirmware.insert (FirmwareIdentifier(AutoPilotStackPX4, firmwareType, DefaultVehicleFirmware), px4Url.arg(dir).arg("v4pro"));
_rgFMUV4Firmware.insert (FirmwareIdentifier(AutoPilotStackPX4, firmwareType, DefaultVehicleFirmware), px4Url.arg(dir).arg("v4"));
_rgFMUV3Firmware.insert (FirmwareIdentifier(AutoPilotStackPX4, firmwareType, DefaultVehicleFirmware), px4Url.arg(dir).arg("v3"));
_rgPX4FMUV2Firmware.insert (FirmwareIdentifier(AutoPilotStackPX4, firmwareType, DefaultVehicleFirmware), px4Url.arg(dir).arg("v2"));
_rgFMUV5Firmware.insert (FirmwareIdentifier(AutoPilotStackPX4, firmwareType, DefaultVehicleFirmware), px4Url.arg(dir).arg("v5"));
_rgFMUV4PROFirmware.insert (FirmwareIdentifier(AutoPilotStackPX4, firmwareType, DefaultVehicleFirmware), px4Url.arg(dir).arg("v4pro"));
_rgFMUV4Firmware.insert (FirmwareIdentifier(AutoPilotStackPX4, firmwareType, DefaultVehicleFirmware), px4Url.arg(dir).arg("v4"));
_rgFMUV3Firmware.insert (FirmwareIdentifier(AutoPilotStackPX4, firmwareType, DefaultVehicleFirmware), px4Url.arg(dir).arg("v3"));
_rgPX4FMUV2Firmware.insert (FirmwareIdentifier(AutoPilotStackPX4, firmwareType, DefaultVehicleFirmware), px4Url.arg(dir).arg("v2"));
}
#if !defined(NO_ARDUPILOT_DIALECT)
// ArduPilot Firmwares
// ArduPilot non-ChibiOS Firmwares for direct board id to fmu mappings
for (const FirmwareType_t& firmwareType: apmMapFirmwareTypeToDir.keys()) {
QString firmwareTypeDir = apmMapFirmwareTypeToDir[firmwareType];
for (const FirmwareVehicleType_t& vehicleType: apmMapVehicleTypeToDir.keys()) {
QString vehicleTypeDir = apmMapVehicleTypeToDir[vehicleType];
QString px4Dir = apmMapVehicleTypeToPX4Dir[vehicleType];
QString filename = apmMapVehicleTypeToFilename[vehicleType];
_rgFMUV5Firmware.insert (FirmwareIdentifier(AutoPilotStackAPM, firmwareType, vehicleType), apmUrl.arg(vehicleTypeDir).arg(firmwareTypeDir).arg(px4Dir).arg(filename).arg("5"));
_rgFMUV4Firmware.insert (FirmwareIdentifier(AutoPilotStackAPM, firmwareType, vehicleType), apmUrl.arg(vehicleTypeDir).arg(firmwareTypeDir).arg(px4Dir).arg(filename).arg("4"));
_rgFMUV3Firmware.insert (FirmwareIdentifier(AutoPilotStackAPM, firmwareType, vehicleType), apmUrl.arg(vehicleTypeDir).arg(firmwareTypeDir).arg(px4Dir).arg(filename).arg("3"));
_rgFMUV5Firmware.insert (FirmwareIdentifier(AutoPilotStackAPM, firmwareType, vehicleType), apmUrl.arg(vehicleTypeDir).arg(firmwareTypeDir).arg(px4Dir).arg(filename).arg("5"));
_rgFMUV4Firmware.insert (FirmwareIdentifier(AutoPilotStackAPM, firmwareType, vehicleType), apmUrl.arg(vehicleTypeDir).arg(firmwareTypeDir).arg(px4Dir).arg(filename).arg("4"));
_rgFMUV3Firmware.insert (FirmwareIdentifier(AutoPilotStackAPM, firmwareType, vehicleType), apmUrl.arg(vehicleTypeDir).arg(firmwareTypeDir).arg(px4Dir).arg(filename).arg("3"));
_rgPX4FMUV2Firmware.insert (FirmwareIdentifier(AutoPilotStackAPM, firmwareType, vehicleType), apmUrl.arg(vehicleTypeDir).arg(firmwareTypeDir).arg(px4Dir).arg(filename).arg("2"));
}
}
#endif
#if !defined(NO_ARDUPILOT_DIALECT)
// ArduPilot ChibiOS Firmwares when board id is is a known type. These are added directly into the various board type hashes.
// ArduPilot ChibiOS Firmwares for direct board id to fmu mappings. Used when bootloader is not new ArduPilot bootloader.
for (const FirmwareType_t& firmwareType: apmMapFirmwareTypeToDir.keys()) {
QString firmwareTypeDir = apmMapFirmwareTypeToDir[firmwareType];
for (const FirmwareVehicleType_t& vehicleType: apmChibiOSMapVehicleTypeToDir.keys()) {
QString vehicleTypeDir = apmChibiOSMapVehicleTypeToDir[vehicleType];
QString fmuDir = apmChibiOSMapVehicleTypeToFmuDir[vehicleType];
QString filename = apmChibiOSMapVehicleTypeToFilename[vehicleType];
_rgFMUV5Firmware.insert (FirmwareIdentifier(AutoPilotStackAPM, firmwareType, vehicleType), apmChibiOSUrl.arg(vehicleTypeDir).arg(firmwareTypeDir).arg("5").arg(fmuDir).arg(filename));
_rgFMUV4Firmware.insert (FirmwareIdentifier(AutoPilotStackAPM, firmwareType, vehicleType), apmChibiOSUrl.arg(vehicleTypeDir).arg(firmwareTypeDir).arg("4").arg(fmuDir).arg(filename));
_rgFMUV3Firmware.insert (FirmwareIdentifier(AutoPilotStackAPM, firmwareType, vehicleType), apmChibiOSUrl.arg(vehicleTypeDir).arg(firmwareTypeDir).arg("3").arg(fmuDir).arg(filename));
_rgPX4FMUV2Firmware.insert (FirmwareIdentifier(AutoPilotStackAPM, firmwareType, vehicleType), apmChibiOSUrl.arg(vehicleTypeDir).arg(firmwareTypeDir).arg("2").arg(fmuDir).arg(filename));
_rgFMUV5Firmware.insert (FirmwareIdentifier(AutoPilotStackAPM, firmwareType, vehicleType), apmChibiOSUrl.arg(vehicleTypeDir).arg(firmwareTypeDir).arg("5").arg(fmuDir).arg(filename));
_rgFMUV4Firmware.insert (FirmwareIdentifier(AutoPilotStackAPM, firmwareType, vehicleType), apmChibiOSUrl.arg(vehicleTypeDir).arg(firmwareTypeDir).arg("4").arg(fmuDir).arg(filename));
_rgFMUV3Firmware.insert (FirmwareIdentifier(AutoPilotStackAPM, firmwareType, vehicleType), apmChibiOSUrl.arg(vehicleTypeDir).arg(firmwareTypeDir).arg("3").arg(fmuDir).arg(filename));
_rgPX4FMUV2Firmware.insert (FirmwareIdentifier(AutoPilotStackAPM, firmwareType, vehicleType), apmChibiOSUrl.arg(vehicleTypeDir).arg(firmwareTypeDir).arg("2").arg(fmuDir).arg(filename));
}
}
#endif
#if !defined(NO_ARDUPILOT_DIALECT)
// ArduPilot ChibiOS Firmwares when board id is an unknown type but follows ArduPilot port info naming conventions.
// This is only used if the board using the ArduPilot port naming scheme.
// This is only used if the board is using the new ArduPilot bootloader port naming scheme.
for (const FirmwareType_t& firmwareType: apmMapFirmwareTypeToDir.keys()) {
QString firmwareTypeDir = apmMapFirmwareTypeToDir[firmwareType];
for (const FirmwareVehicleType_t& vehicleType: apmChibiOSMapVehicleTypeToDir.keys()) {
@ -487,85 +483,75 @@ void FirmwareUpgradeController::_bootloaderSyncFailed(void) @@ -487,85 +483,75 @@ void FirmwareUpgradeController::_bootloaderSyncFailed(void)
QHash<FirmwareUpgradeController::FirmwareIdentifier, QString>* FirmwareUpgradeController::_firmwareHashForBoardId(int boardId)
{
QHash<FirmwareUpgradeController::FirmwareIdentifier, QString>* rgFirmware;
_rgFirmwareDynamic.clear();
switch (boardId) {
case Bootloader::boardIDPX4Flow:
rgFirmware = &_rgPX4FLowFirmware;
_rgFirmwareDynamic = _rgPX4FLowFirmware;
break;
case Bootloader::boardIDPX4FMUV2:
rgFirmware = &_rgPX4FMUV2Firmware;
_rgFirmwareDynamic = _rgPX4FMUV2Firmware;
break;
case Bootloader::boardIDPX4FMUV3:
rgFirmware = &_rgFMUV3Firmware;
_rgFirmwareDynamic = _rgFMUV3Firmware;
break;
case Bootloader::boardIDPX4FMUV4:
rgFirmware = &_rgFMUV4Firmware;
_rgFirmwareDynamic = _rgFMUV4Firmware;
break;
case Bootloader::boardIDPX4FMUV4PRO:
rgFirmware = &_rgFMUV4PROFirmware;
_rgFirmwareDynamic = _rgFMUV4PROFirmware;
break;
case Bootloader::boardIDPX4FMUV5:
rgFirmware = &_rgFMUV5Firmware;
_rgFirmwareDynamic = _rgFMUV5Firmware;
break;
case Bootloader::boardIDAeroCore:
rgFirmware = &_rgAeroCoreFirmware;
_rgFirmwareDynamic = _rgAeroCoreFirmware;
break;
case Bootloader::boardIDAUAVX2_1:
rgFirmware = &_rgAUAVX2_1Firmware;
_rgFirmwareDynamic = _rgAUAVX2_1Firmware;
break;
case Bootloader::boardIDMINDPXFMUV2:
rgFirmware = &_rgMindPXFMUV2Firmware;
_rgFirmwareDynamic = _rgMindPXFMUV2Firmware;
break;
case Bootloader::boardIDTAPV1:
rgFirmware = &_rgTAPV1Firmware;
_rgFirmwareDynamic = _rgTAPV1Firmware;
break;
case Bootloader::boardIDASCV1:
rgFirmware = &_rgASCV1Firmware;
_rgFirmwareDynamic = _rgASCV1Firmware;
break;
case Bootloader::boardIDCrazyflie2:
rgFirmware = &_rgCrazyflie2Firmware;
_rgFirmwareDynamic = _rgCrazyflie2Firmware;
break;
case Bootloader::boardIDOmnibusF4SD:
rgFirmware = &_rgOmnibusF4SDFirmware;
_rgFirmwareDynamic = _rgOmnibusF4SDFirmware;
break;
case Bootloader::boardIDNXPHliteV3:
rgFirmware = &_rgNXPHliteV3Firmware;
_rgFirmwareDynamic = _rgNXPHliteV3Firmware;
break;
case Bootloader::boardID3DRRadio:
rgFirmware = &_rg3DRRadioFirmware;
_rgFirmwareDynamic = _rg3DRRadioFirmware;
break;
default:
rgFirmware = Q_NULLPTR;
// Unknown board id
break;
}
if (rgFirmware) {
_rgFirmwareDynamic = *rgFirmware;
} else {
_rgFirmwareDynamic.clear();
}
// Check for ArduPilot ChibiOS bootloader
QStringList rgManufacturers = { QStringLiteral("ArduPilot"), QStringLiteral("Hex/ProfiCNC"), QStringLiteral("Holybro") };
QString apmDescriptionSuffix("-BL");
if (rgManufacturers.contains(_foundBoardInfo.manufacturer()) && _foundBoardInfo.description().endsWith(apmDescriptionSuffix)) {
// Board ios using a ChibiOS bootloader. Prefer naming scheme from that over board ids for ArduPilot entries.
// Special case handling for ArduPilot named ChibiOS board
if (_foundBoardInfo.manufacturer() == QStringLiteral("ArduPilot") || _foundBoardInfo.manufacturer() == QStringLiteral("Hex/ProfiCNC")) {
// Remove the ChibiOS by board id entries from the list
for (const FirmwareIdentifier& firmwareId: _rgFirmwareDynamic.keys()) {
switch (firmwareId.firmwareVehicleType) {
case CopterChibiOSFirmware:
case HeliChibiOSFirmware:
case PlaneChibiOSFirmware:
case RoverChibiOSFirmware:
case SubChibiOSFirmware:
_rgAPMChibiosReplaceNamedBoardFirmware.remove(firmwareId);
break;
default:
break;
}
// First remove the ChibiOS by board id entries from the list
for (const FirmwareIdentifier& firmwareId: _rgAPMChibiosReplaceNamedBoardFirmware.keys()) {
_rgFirmwareDynamic.remove(firmwareId);
}
// Add the ChibiOS by board description entries to the list
// Now add the ChibiOS by board description entries to the list
for (const FirmwareIdentifier& firmwareId: _rgAPMChibiosReplaceNamedBoardFirmware.keys()) {
QString namedUrl = _rgAPMChibiosReplaceNamedBoardFirmware[firmwareId];
_rgFirmwareDynamic.insert(firmwareId, namedUrl.replace(_apmBoardDescriptionReplaceText, _foundBoardInfo.description().left(_foundBoardInfo.description().length() - 3)));
_rgFirmwareDynamic.insert(firmwareId, namedUrl.replace(_apmBoardDescriptionReplaceText, _foundBoardInfo.description().left(_foundBoardInfo.description().length() - apmDescriptionSuffix.length())));
}
}
@ -577,21 +563,16 @@ void FirmwareUpgradeController::_getFirmwareFile(FirmwareIdentifier firmwareId) @@ -577,21 +563,16 @@ void FirmwareUpgradeController::_getFirmwareFile(FirmwareIdentifier firmwareId)
{
QHash<FirmwareIdentifier, QString>* prgFirmware = _firmwareHashForBoardId(static_cast<int>(_bootloaderBoardID));
if (!prgFirmware && firmwareId.firmwareType != CustomFirmware) {
_errorCancel(tr("Attempting to flash an unknown board type, you must select 'Custom firmware file'"));
return;
}
if (firmwareId.firmwareType == CustomFirmware) {
_firmwareFilename = QGCQFileDialog::getOpenFileName(nullptr, // Parent to main window
tr("Select Firmware File"), // Dialog Caption
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), // Initial directory
tr("Firmware Files (*.px4 *.bin *.ihx)")); // File filter
tr("Firmware Files (*.px4 *.apj *.bin *.ihx)")); // File filter
} else {
if (prgFirmware->contains(firmwareId)) {
_firmwareFilename = prgFirmware->value(firmwareId);
} else {
_errorCancel(tr("Unable to find specified firmware download location"));
_errorCancel(tr("Unable to find specified firmware for board type"));
return;
}
}

1
src/VehicleSetup/PX4FirmwareUpgradeThread.cc

@ -125,6 +125,7 @@ bool PX4FirmwareUpgradeThreadWorker::_findBoardFromPorts(QGCSerialPortInfo& port @@ -125,6 +125,7 @@ bool PX4FirmwareUpgradeThreadWorker::_findBoardFromPorts(QGCSerialPortInfo& port
qCDebug(FirmwareUpgradeVerboseLog) << "Serial Port --------------";
qCDebug(FirmwareUpgradeVerboseLog) << "\tboard type" << boardType;
qCDebug(FirmwareUpgradeVerboseLog) << "\tboard name" << boardName;
qCDebug(FirmwareUpgradeVerboseLog) << "\tmanufacturer:" << info.manufacturer();
qCDebug(FirmwareUpgradeVerboseLog) << "\tport name:" << info.portName();
qCDebug(FirmwareUpgradeVerboseLog) << "\tdescription:" << info.description();
qCDebug(FirmwareUpgradeVerboseLog) << "\tsystem location:" << info.systemLocation();

94
src/comm/QGCSerialPortInfo.cc

@ -18,16 +18,17 @@ @@ -18,16 +18,17 @@
QGC_LOGGING_CATEGORY(QGCSerialPortInfoLog, "QGCSerialPortInfoLog")
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";
bool QGCSerialPortInfo::_jsonLoaded = false;
const char* QGCSerialPortInfo::_jsonFileTypeValue = "USBBoardInfo";
const char* QGCSerialPortInfo::_jsonBoardInfoKey = "boardInfo";
const char* QGCSerialPortInfo::_jsonBoardDescriptionFallbackKey = "boardDescriptionFallback";
const char* QGCSerialPortInfo::_jsonBoardManufacturerFallbackKey = "boardManufacturerFallback";
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 },
@ -37,8 +38,9 @@ const QGCSerialPortInfo::BoardClassString2BoardType_t QGCSerialPortInfo::_rgBoar @@ -37,8 +38,9 @@ const QGCSerialPortInfo::BoardClassString2BoardType_t QGCSerialPortInfo::_rgBoar
{ "OpenPilot", QGCSerialPortInfo::BoardTypeOpenPilot },
};
QList<QGCSerialPortInfo::BoardInfo_t> QGCSerialPortInfo::_boardInfoList;
QList<QGCSerialPortInfo::BoardFallback_t> QGCSerialPortInfo::_boardFallbackList;
QList<QGCSerialPortInfo::BoardInfo_t> QGCSerialPortInfo::_boardInfoList;
QList<QGCSerialPortInfo::BoardRegExpFallback_t> QGCSerialPortInfo::_boardDescriptionFallbackList;
QList<QGCSerialPortInfo::BoardRegExpFallback_t> QGCSerialPortInfo::_boardManufacturerFallbackList;
QGCSerialPortInfo::QGCSerialPortInfo(void) :
QSerialPortInfo()
@ -90,8 +92,9 @@ void QGCSerialPortInfo::_loadJsonData(void) @@ -90,8 +92,9 @@ void QGCSerialPortInfo::_loadJsonData(void)
// Validate root object keys
QList<JsonHelper::KeyValidateInfo> rootKeyInfoList = {
{ _jsonBoardInfoKey, QJsonValue::Array, true },
{ _jsonBoardFallbackKey, QJsonValue::Array, true },
{ _jsonBoardInfoKey, QJsonValue::Array, true },
{ _jsonBoardDescriptionFallbackKey, QJsonValue::Array, true },
{ _jsonBoardManufacturerFallbackKey, QJsonValue::Array, true },
};
if (!JsonHelper::validateKeys(json, rootKeyInfoList, errorString)) {
qWarning() << errorString;
@ -143,7 +146,7 @@ void QGCSerialPortInfo::_loadJsonData(void) @@ -143,7 +146,7 @@ void QGCSerialPortInfo::_loadJsonData(void)
{ _jsonAndroidOnlyKey, QJsonValue::Bool, false },
};
QJsonArray rgBoardFallback = json[_jsonBoardFallbackKey].toArray();
QJsonArray rgBoardFallback = json[_jsonBoardDescriptionFallbackKey].toArray();
for (int i=0; i<rgBoardFallback.count(); i++) {
const QJsonValue& jsonValue = rgBoardFallback[i];
if (!jsonValue.isObject()) {
@ -157,17 +160,44 @@ void QGCSerialPortInfo::_loadJsonData(void) @@ -157,17 +160,44 @@ void QGCSerialPortInfo::_loadJsonData(void)
return;
}
BoardFallback_t boardFallback;
boardFallback.regExp = fallbackObject[_jsonRegExpKey].toString();
BoardRegExpFallback_t boardFallback;
boardFallback.regExp = fallbackObject[_jsonRegExpKey].toString();
boardFallback.androidOnly = fallbackObject[_jsonAndroidOnlyKey].toBool(false);
boardFallback.boardType = _boardClassStringToType(fallbackObject[_jsonBoardClassKey].toString());
boardFallback.boardType = _boardClassStringToType(fallbackObject[_jsonBoardClassKey].toString());
if (boardFallback.boardType == BoardTypeUnknown) {
qWarning() << "Bad board class" << fallbackObject[_jsonBoardClassKey].toString();
return;
}
_boardFallbackList.append(boardFallback);
_boardDescriptionFallbackList.append(boardFallback);
}
rgBoardFallback = json[_jsonBoardManufacturerFallbackKey].toArray();
for (int i=0; i<rgBoardFallback.count(); i++) {
const QJsonValue& jsonValue = rgBoardFallback[i];
if (!jsonValue.isObject()) {
qWarning() << "Entry in boardFallback array is not object";
return;
}
QJsonObject fallbackObject = jsonValue.toObject();
if (!JsonHelper::validateKeys(fallbackObject, fallbackKeyInfoList, errorString)) {
qWarning() << errorString;
return;
}
BoardRegExpFallback_t boardFallback;
boardFallback.regExp = fallbackObject[_jsonRegExpKey].toString();
boardFallback.androidOnly = fallbackObject[_jsonAndroidOnlyKey].toBool(false);
boardFallback.boardType = _boardClassStringToType(fallbackObject[_jsonBoardClassKey].toString());
if (boardFallback.boardType == BoardTypeUnknown) {
qWarning() << "Bad board class" << fallbackObject[_jsonBoardClassKey].toString();
return;
}
_boardManufacturerFallbackList.append(boardFallback);
}
}
@ -176,7 +206,6 @@ QGCSerialPortInfo::BoardType_t QGCSerialPortInfo::_boardClassStringToType(const @@ -176,7 +206,6 @@ QGCSerialPortInfo::BoardType_t QGCSerialPortInfo::_boardClassStringToType(const
for (size_t j=0; j<sizeof(_rgBoardClass2BoardType)/sizeof(_rgBoardClass2BoardType[0]); j++) {
if (boardClass == _rgBoardClass2BoardType[j].classString) {
return _rgBoardClass2BoardType[j].boardType;
break;
}
}
@ -196,7 +225,7 @@ bool QGCSerialPortInfo::getBoardInfo(QGCSerialPortInfo::BoardType_t& boardType, @@ -196,7 +225,7 @@ bool QGCSerialPortInfo::getBoardInfo(QGCSerialPortInfo::BoardType_t& boardType,
for (int i=0; i<_boardInfoList.count(); i++) {
const BoardInfo_t& boardInfo = _boardInfoList[i];
if (vendorIdentifier() == boardInfo.vendorId && productIdentifier() == boardInfo.productId) {
if (vendorIdentifier() == boardInfo.vendorId && (productIdentifier() == boardInfo.productId || boardInfo.productId == 0)) {
boardType = boardInfo.boardType;
name = boardInfo.name;
return true;
@ -204,10 +233,10 @@ bool QGCSerialPortInfo::getBoardInfo(QGCSerialPortInfo::BoardType_t& boardType, @@ -204,10 +233,10 @@ bool QGCSerialPortInfo::getBoardInfo(QGCSerialPortInfo::BoardType_t& boardType,
}
if (boardType == BoardTypeUnknown) {
// Fall back to port name matching which could lead to incorrect board mapping. But in some cases the
// vendor and product id do not come through correctly so this is used as a last chance detection method.
for (int i=0; i<_boardFallbackList.count(); i++) {
const BoardFallback_t& boardFallback = _boardFallbackList[i];
// Fall back to port description matching and then manufactrure name matching
for (int i=0; i<_boardDescriptionFallbackList.count(); i++) {
const BoardRegExpFallback_t& boardFallback = _boardDescriptionFallbackList[i];
if (description().contains(QRegExp(boardFallback.regExp, Qt::CaseInsensitive))) {
#ifndef __android
@ -220,6 +249,21 @@ bool QGCSerialPortInfo::getBoardInfo(QGCSerialPortInfo::BoardType_t& boardType, @@ -220,6 +249,21 @@ bool QGCSerialPortInfo::getBoardInfo(QGCSerialPortInfo::BoardType_t& boardType,
return true;
}
}
for (int i=0; i<_boardManufacturerFallbackList.count(); i++) {
const BoardRegExpFallback_t& boardFallback = _boardManufacturerFallbackList[i];
if (manufacturer().contains(QRegExp(boardFallback.regExp, Qt::CaseInsensitive))) {
#ifndef __android
if (boardFallback.androidOnly) {
continue;
}
#endif
boardType = boardFallback.boardType;
name = _boardTypeToString(boardType);
return true;
}
}
}
return false;

8
src/comm/QGCSerialPortInfo.h

@ -68,7 +68,7 @@ private: @@ -68,7 +68,7 @@ private:
QString regExp;
BoardType_t boardType;
bool androidOnly;
} BoardFallback_t;
} BoardRegExpFallback_t;
static void _loadJsonData(void);
static BoardType_t _boardClassStringToType(const QString& boardClass);
@ -77,7 +77,8 @@ private: @@ -77,7 +77,8 @@ private:
static bool _jsonLoaded;
static const char* _jsonFileTypeValue;
static const char* _jsonBoardInfoKey;
static const char* _jsonBoardFallbackKey;
static const char* _jsonBoardDescriptionFallbackKey;
static const char* _jsonBoardManufacturerFallbackKey;
static const char* _jsonVendorIDKey;
static const char* _jsonProductIDKey;
static const char* _jsonBoardClassKey;
@ -87,6 +88,7 @@ private: @@ -87,6 +88,7 @@ private:
static const BoardClassString2BoardType_t _rgBoardClass2BoardType[BoardTypeUnknown];
static QList<BoardInfo_t> _boardInfoList;
static QList<BoardFallback_t> _boardFallbackList;
static QList<BoardRegExpFallback_t> _boardDescriptionFallbackList;
static QList<BoardRegExpFallback_t> _boardManufacturerFallbackList;
};

19
src/comm/USBBoardInfo.json

@ -20,26 +20,29 @@ @@ -20,26 +20,29 @@
{ "vendorID": 9900, "productID": 22, "boardClass": "Pixhawk", "name": "Crazyflie 2" },
{ "vendorID": 9900, "productID": 1, "boardClass": "Pixhawk", "name": "Omnibus F4 SD" },
{ "vendorID": 8137, "productID": 28, "boardClass": "Pixhawk", "name": "PX4 NXPHlite v3.x" },
{ "vendorID": 1155, "productID": 22336, "boardClass": "Pixhawk", "name": "ArduPilot ChibiOS" },
{ "vendorID": 4617, "productID": 22336, "boardClass": "Pixhawk", "name": "ArduPilot ChibiOS" },
{ "vendorID": 12642, "productID": 0, "boardClass": "Pixhawk", "name": "Holybro" },
{ "vendorID": 9900, "productID": 21, "boardClass": "PX4 Flow", "name": "PX4 Flow" },
{ "vendorID": 1027, "productID": 24597, "boardClass": "SiK Radio", "name": "SiK Radio", "comment": "3DR Radio" },
{ "vendorID": 1027, "productID": 24577, "boardClass": "SiK Radio", "name": "SiK Radio", "comment": "3DR Radio on FTDI" },
{ "vendorID": 4292, "productID": 60000, "boardClass": "SiK Radio", "name": "SiK Radio", "comment": "SILabs Radio" },
{ "vendorID": 5446, "productID": 424, "boardClass": "RTK GPS", "name": "U-blox RTK GPS", "comment": "U-blox RTK GPS (M8P)" },
{ "vendorID": 5446, "productID": 425, "boardClass": "RTK GPS", "name": "U-blox RTK GPS", "comment": "U-blox RTK GPS (F9P)" },
{ "vendorID": 1317, "productID": 42151, "boardClass": "RTK GPS", "name": "Trimble RTK GPS", "comment": "Trimble RTK GPS" },
{ "vendorID": 5418, "productID": 34240, "boardClass": "RTK GPS", "name": "Septentrio RTK GPS", "comment": "Septentrio RTK GPS" },
{ "vendorID": 5446, "productID": 424, "boardClass": "RTK GPS", "name": "U-blox RTK GPS", "comment": "U-blox RTK GPS (M8P)" },
{ "vendorID": 5446, "productID": 425, "boardClass": "RTK GPS", "name": "U-blox RTK GPS", "comment": "U-blox RTK GPS (F9P)" },
{ "vendorID": 1317, "productID": 42151, "boardClass": "RTK GPS", "name": "Trimble RTK GPS" },
{ "vendorID": 5418, "productID": 34240, "boardClass": "RTK GPS", "name": "Septentrio 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": [
"boardDescriptionFallback": [
{ "regExp": "^PX4 FMU v5.x$", "boardClass": "Pixhawk" },
{ "regExp": "^PX4 BL FMU v5.x$", "boardClass": "Pixhawk" },
{ "regExp": "^PX4 FMU v4.x PRO$", "boardClass": "Pixhawk" },
@ -64,5 +67,11 @@ @@ -64,5 +67,11 @@
{ "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" }
],
"boardManufacturerFallback": [
{ "regExp": "^ArduPilot$", "boardClass": "Pixhawk" },
{ "regExp": "^Hex/ProfiCNC$", "boardClass": "Pixhawk" },
{ "regExp": "^Holybro$", "boardClass": "Pixhawk" }
]
}

Loading…
Cancel
Save