diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 1cc7b603e08aca89b3df794cfe5bab1721c7022a..b3ba1acf4d8fc9551c8fbcdd7156a19b46265439 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -302,6 +302,7 @@ WindowsBuild { !iOSBuild { HEADERS += \ + src/comm/QGCSerialPortInfo.h \ src/comm/SerialLink.h \ src/ui/SerialConfigurationWindow.h \ } @@ -407,6 +408,7 @@ SOURCES += \ !iOSBuild { SOURCES += \ + src/comm/QGCSerialPortInfo.cc \ src/comm/SerialLink.cc \ src/ui/SerialConfigurationWindow.cc \ } diff --git a/src/VehicleSetup/FirmwareUpgradeController.cc b/src/VehicleSetup/FirmwareUpgradeController.cc index 9019f58a3a42729b44997062f4e42d42f6a8577a..eb1eb35bb5f14fbcc2536b1c897ee4c23537de5e 100644 --- a/src/VehicleSetup/FirmwareUpgradeController.cc +++ b/src/VehicleSetup/FirmwareUpgradeController.cc @@ -109,23 +109,23 @@ void FirmwareUpgradeController::_foundBoard(bool firstAttempt, const QSerialPort { _foundBoardInfo = info; switch (type) { - case FoundBoardPX4FMUV1: + case QGCSerialPortInfo::BoardTypePX4FMUV1: _foundBoardType = "PX4 FMU V1"; _startFlashWhenBootloaderFound = false; break; - case FoundBoardPX4FMUV2: + case QGCSerialPortInfo::BoardTypePX4FMUV2: _foundBoardType = "Pixhawk"; _startFlashWhenBootloaderFound = false; break; - case FoundBoardAeroCore: + case QGCSerialPortInfo::BoardTypeAeroCore: _foundBoardType = "AeroCore"; _startFlashWhenBootloaderFound = false; break; - case FoundBoardPX4Flow: + case QGCSerialPortInfo::BoardTypePX4Flow: _foundBoardType = "PX4 Flow"; _startFlashWhenBootloaderFound = false; break; - case FoundBoard3drRadio: + case QGCSerialPortInfo::BoardType3drRadio: _foundBoardType = "3DR Radio"; if (!firstAttempt) { // Radio always flashes latest firmware, so we can start right away without diff --git a/src/VehicleSetup/PX4FirmwareUpgradeThread.cc b/src/VehicleSetup/PX4FirmwareUpgradeThread.cc index 58d29e385509cc7cb9fc94608296e09a73d123b9..3df01ced8f452746b70d87140ca443b94a8505a6 100644 --- a/src/VehicleSetup/PX4FirmwareUpgradeThread.cc +++ b/src/VehicleSetup/PX4FirmwareUpgradeThread.cc @@ -29,10 +29,8 @@ #include "Bootloader.h" #include "QGCLoggingCategory.h" #include "QGC.h" -#include "SerialPortIds.h" #include -#include #include #include @@ -99,8 +97,8 @@ void PX4FirmwareUpgradeThreadWorker::_findBoardOnce(void) { qCDebug(FirmwareUpgradeLog) << "_findBoardOnce"; - QSerialPortInfo portInfo; - PX4FirmwareUpgradeFoundBoardType_t boardType; + QGCSerialPortInfo portInfo; + QGCSerialPortInfo::BoardType_t boardType; if (_findBoardFromPorts(portInfo, boardType)) { if (!_foundBoard) { @@ -108,7 +106,7 @@ void PX4FirmwareUpgradeThreadWorker::_findBoardOnce(void) _foundBoardPortInfo = portInfo; emit foundBoard(_findBoardFirstAttempt, portInfo, boardType); if (!_findBoardFirstAttempt) { - if (boardType == FoundBoard3drRadio) { + if (boardType == QGCSerialPortInfo::BoardType3drRadio) { _3drRadioForceBootloader(portInfo); return; } else { @@ -131,11 +129,9 @@ void PX4FirmwareUpgradeThreadWorker::_findBoardOnce(void) _timerRetry->start(); } -bool PX4FirmwareUpgradeThreadWorker::_findBoardFromPorts(QSerialPortInfo& portInfo, PX4FirmwareUpgradeFoundBoardType_t& type) +bool PX4FirmwareUpgradeThreadWorker::_findBoardFromPorts(QGCSerialPortInfo& portInfo, QGCSerialPortInfo::BoardType_t& boardType) { - bool found = false; - - foreach (QSerialPortInfo info, QSerialPortInfo::availablePorts()) { + foreach (QGCSerialPortInfo info, QGCSerialPortInfo::availablePorts()) { qCDebug(FirmwareUpgradeLog) << "Serial Port --------------"; qCDebug(FirmwareUpgradeLog) << "\tport name:" << info.portName(); qCDebug(FirmwareUpgradeLog) << "\tdescription:" << info.description(); @@ -143,55 +139,8 @@ bool PX4FirmwareUpgradeThreadWorker::_findBoardFromPorts(QSerialPortInfo& portIn qCDebug(FirmwareUpgradeLog) << "\tvendor ID:" << info.vendorIdentifier(); qCDebug(FirmwareUpgradeLog) << "\tproduct ID:" << info.productIdentifier(); - if (!info.portName().isEmpty()) { - switch (info.vendorIdentifier()) { - case SerialPortIds::px4VendorId: - if (info.productIdentifier() == SerialPortIds::pixhawkFMUV2ProductId || info.productIdentifier() == SerialPortIds::pixhawkFMUV2OldBootloaderProductId) { - qCDebug(FirmwareUpgradeLog) << "Found PX4 FMU V2"; - type = FoundBoardPX4FMUV2; - found = true; - } else if (info.productIdentifier() == SerialPortIds::pixhawkFMUV1ProductId) { - qCDebug(FirmwareUpgradeLog) << "Found PX4 FMU V1"; - type = FoundBoardPX4FMUV1; - found = true; - } else if (info.productIdentifier() == SerialPortIds::px4FlowProductId) { - qCDebug(FirmwareUpgradeLog) << "Found PX4 Flow"; - type = FoundBoardPX4Flow; - found = true; - } else if (info.productIdentifier() == SerialPortIds::AeroCoreProductId) { - qCDebug(FirmwareUpgradeLog) << "Found AeroCore"; - type = FoundBoardAeroCore; - found = true; - } - break; - case SerialPortIds::threeDRRadioVendorId: - if (info.productIdentifier() == SerialPortIds::threeDRRadioProductId) { - qCDebug(FirmwareUpgradeLog) << "Found 3DR Radio"; - type = FoundBoard3drRadio; - found = true; - } - break; - } - if (!found) { - // 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. - if (info.description() == "PX4 FMU v2.x" || info.description() == "PX4 BL FMU v2.x") { - qCDebug(FirmwareUpgradeLog) << "Found PX4 FMU V2 (by name matching fallback)"; - type = FoundBoardPX4FMUV2; - found = true; - } else if (info.description() == "PX4 FMU v1.x" || info.description() == "PX4 BL FMU v1.x") { - qCDebug(FirmwareUpgradeLog) << "Found PX4 FMU V1 (by name matching fallback)"; - type = FoundBoardPX4FMUV1; - found = true; - } else if (info.description().startsWith("PX4 FMU")) { - qCDebug(FirmwareUpgradeLog) << "Found PX4 FMU, assuming V2 (by name matching fallback)"; - type = FoundBoardPX4FMUV2; - found = true; - } - } - } - - if (found) { + boardType = info.boardType(); + if (boardType != QGCSerialPortInfo::BoardTypeUnknown) { portInfo = info; return true; } @@ -200,7 +149,7 @@ bool PX4FirmwareUpgradeThreadWorker::_findBoardFromPorts(QSerialPortInfo& portIn return false; } -void PX4FirmwareUpgradeThreadWorker::_3drRadioForceBootloader(const QSerialPortInfo& portInfo) +void PX4FirmwareUpgradeThreadWorker::_3drRadioForceBootloader(const QGCSerialPortInfo& portInfo) { // First make sure we can't get the bootloader @@ -257,7 +206,7 @@ void PX4FirmwareUpgradeThreadWorker::_3drRadioForceBootloader(const QSerialPortI _findBootloader(portInfo, true /* radio mode */, true /* errorOnNotFound */); } -bool PX4FirmwareUpgradeThreadWorker::_findBootloader(const QSerialPortInfo& portInfo, bool radioMode, bool errorOnNotFound) +bool PX4FirmwareUpgradeThreadWorker::_findBootloader(const QGCSerialPortInfo& portInfo, bool radioMode, bool errorOnNotFound) { qCDebug(FirmwareUpgradeLog) << "_findBootloader"; diff --git a/src/VehicleSetup/PX4FirmwareUpgradeThread.h b/src/VehicleSetup/PX4FirmwareUpgradeThread.h index 758c11431b7cca5eed50ec252c679c4ee256fad5..944df23d2b9086c9829f3ca8c44582513dc91e40 100644 --- a/src/VehicleSetup/PX4FirmwareUpgradeThread.h +++ b/src/VehicleSetup/PX4FirmwareUpgradeThread.h @@ -30,25 +30,17 @@ #include "Bootloader.h" #include "FirmwareImage.h" +#include "QGCSerialPortInfo.h" #include #include #include #include -#include #include "qextserialport.h" #include -typedef enum { - FoundBoardPX4FMUV1, - FoundBoardPX4FMUV2, - FoundBoardPX4Flow, - FoundBoard3drRadio, - FoundBoardAeroCore -} PX4FirmwareUpgradeFoundBoardType_t; - class PX4FirmwareUpgradeThreadController; /// @brief Used to run bootloader commands on a seperate thread. These routines are mainly meant to to be called @@ -64,7 +56,7 @@ public: signals: void updateProgress(int curr, int total); - void foundBoard(bool firstAttempt, const QSerialPortInfo& portInfo, int type); + void foundBoard(bool firstAttempt, const QGCSerialPortInfo& portInfo, int type); void noBoardFound(void); void boardGone(void); void foundBootloader(int bootloaderVersion, int boardID, int flashSize); @@ -85,9 +77,9 @@ private slots: void _cancel(void); private: - bool _findBoardFromPorts(QSerialPortInfo& portInfo, PX4FirmwareUpgradeFoundBoardType_t& type); - bool _findBootloader(const QSerialPortInfo& portInfo, bool radioMode, bool errorOnNotFound); - void _3drRadioForceBootloader(const QSerialPortInfo& portInfo); + bool _findBoardFromPorts(QGCSerialPortInfo& portInfo, QGCSerialPortInfo::BoardType_t& boardType); + bool _findBootloader(const QGCSerialPortInfo& portInfo, bool radioMode, bool errorOnNotFound); + void _3drRadioForceBootloader(const QGCSerialPortInfo& portInfo); bool _erase(void); PX4FirmwareUpgradeThreadController* _controller; @@ -100,7 +92,7 @@ private: bool _foundBoard; ///< true: board is currently connected bool _findBoardFirstAttempt; ///< true: this is our first try looking for a board - QSerialPortInfo _foundBoardPortInfo; ///< port info for found board + QGCSerialPortInfo _foundBoardPortInfo; ///< port info for found board }; /// @brief Provides methods to interact with the bootloader. The commands themselves are signalled @@ -128,7 +120,7 @@ public: signals: /// @brief Emitted by the find board process when it finds a board. - void foundBoard(bool firstAttempt, const QSerialPortInfo &portInfo, int type); + void foundBoard(bool firstAttempt, const QGCSerialPortInfo &portInfo, int boardType); void noBoardFound(void); @@ -163,7 +155,7 @@ signals: void _cancel(void); private slots: - void _foundBoard(bool firstAttempt, const QSerialPortInfo& portInfo, int type) { emit foundBoard(firstAttempt, portInfo, type); } + void _foundBoard(bool firstAttempt, const QGCSerialPortInfo& portInfo, int type) { emit foundBoard(firstAttempt, portInfo, type); } 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/LinkInterface.h b/src/comm/LinkInterface.h index 68bcf9f27a2c6cba7e380a8afb80fbcafc98e12d..63ce51d784a697d7e233966e63939ae2f178ba2c 100644 --- a/src/comm/LinkInterface.h +++ b/src/comm/LinkInterface.h @@ -125,6 +125,9 @@ public: /// set into the link when it is added to LinkManager uint8_t getMavlinkChannel(void) const { Q_ASSERT(_mavlinkChannelSet); return _mavlinkChannel; } + /// @return true: "sh /etc/init.d/rc.usb" must be sent on link to start mavlink + virtual bool requiresUSBMavlinkStart(void) const { return false; } + // These are left unimplemented in order to cause linker errors which indicate incorrect usage of // connect/disconnect on link directly. All connect/disconnect calls should be made through LinkManager. bool connect(void); diff --git a/src/comm/LinkManager.cc b/src/comm/LinkManager.cc index 0378b62b5d22ded9eaba33109ea3675f966fb3d0..9a8ef0ede6cfb524d2b3bb785042866b6b6ea477 100644 --- a/src/comm/LinkManager.cc +++ b/src/comm/LinkManager.cc @@ -34,18 +34,13 @@ This file is part of the QGROUNDCONTROL project #include #ifndef __ios__ -#ifdef __android__ -#include "qserialportinfo.h" -#else -#include -#endif +#include "QGCSerialPortInfo.h" #endif #include "LinkManager.h" #include "MainWindow.h" #include "QGCMessageBox.h" #include "QGCApplication.h" -#include "SerialPortIds.h" #include "QGCApplication.h" QGC_LOGGING_CATEGORY(LinkManagerLog, "LinkManagerLog") @@ -489,9 +484,9 @@ void LinkManager::_updateConfigurationList(void) } bool saveList = false; QStringList currentPorts; - QList portList = QSerialPortInfo::availablePorts(); + QList portList = QGCSerialPortInfo::availablePorts(); // Iterate Comm Ports - foreach (QSerialPortInfo portInfo, portList) { + foreach (QGCSerialPortInfo portInfo, portList) { #if 0 // Too noisy for most logging, so turn on as needed qCDebug(LinkManagerLog) << "-----------------------------------------------------"; @@ -504,8 +499,15 @@ void LinkManager::_updateConfigurationList(void) #endif // Save port name currentPorts << portInfo.systemLocation(); - // Is this a PX4 and NOT in bootloader mode? - if (portInfo.vendorIdentifier() == SerialPortIds::px4VendorId && !portInfo.description().contains("BL")) { + + QGCSerialPortInfo::BoardType_t boardType = portInfo.boardType(); + + if (boardType != QGCSerialPortInfo::BoardTypeUnknown) { + if (portInfo.isBootloader()) { + // Don't connect to bootloader + continue; + } + SerialConfiguration* pSerial = _findSerialConfiguration(portInfo.systemLocation()); if (pSerial) { //-- If this port is configured make sure it has the preferred flag set @@ -514,45 +516,34 @@ void LinkManager::_updateConfigurationList(void) saveList = true; } } else { - // Lets create a new Serial configuration automatically - if (portInfo.description() == "AeroCore") { + switch (boardType) { + case QGCSerialPortInfo::BoardTypePX4FMUV1: + case QGCSerialPortInfo::BoardTypePX4FMUV2: + pSerial = new SerialConfiguration(QString("Pixhawk on %1").arg(portInfo.portName().trimmed())); + break; + case QGCSerialPortInfo::BoardTypeAeroCore: pSerial = new SerialConfiguration(QString("AeroCore on %1").arg(portInfo.portName().trimmed())); - } else if (portInfo.description().contains("PX4Flow")) { + break; + case QGCSerialPortInfo::BoardTypePX4Flow: pSerial = new SerialConfiguration(QString("PX4Flow on %1").arg(portInfo.portName().trimmed())); - } else if (portInfo.description().contains("PX4")) { - pSerial = new SerialConfiguration(QString("Pixhawk on %1").arg(portInfo.portName().trimmed())); - } else { - continue; - } - pSerial->setDynamic(true); - pSerial->setPreferred(true); - pSerial->setBaud(115200); - pSerial->setPortName(portInfo.systemLocation()); - addLinkConfiguration(pSerial); - saveList = true; - } - } - // Is this an FTDI Chip? It could be a 3DR Modem - if (portInfo.vendorIdentifier() == SerialPortIds::threeDRRadioVendorId && portInfo.productIdentifier() == SerialPortIds::threeDRRadioProductId) { - SerialConfiguration* pSerial = _findSerialConfiguration(portInfo.systemLocation()); - if (pSerial) { - //-- If this port is configured make sure it has the preferred flag set, unless someone else already has it set. - if(!pSerial->isPreferred() && !saveList) { - pSerial->setPreferred(true); - saveList = true; + break; + case QGCSerialPortInfo::BoardType3drRadio: + pSerial = new SerialConfiguration(QString("3DR Radio on %1").arg(portInfo.portName().trimmed())); + default: + qWarning() << "Internal error"; + break; } - } else { - // Lets create a new Serial configuration automatically (an assumption at best) - pSerial = new SerialConfiguration(QString("3DR Radio on %1").arg(portInfo.portName().trimmed())); + + pSerial->setBaud(boardType == QGCSerialPortInfo::BoardType3drRadio ? 57600 : 115200); pSerial->setDynamic(true); pSerial->setPreferred(true); - pSerial->setBaud(57600); pSerial->setPortName(portInfo.systemLocation()); addLinkConfiguration(pSerial); saveList = true; } } } + // Now we go through the current configuration list and make sure any dynamic config has gone away QList _confToDelete; foreach (LinkConfiguration* pLink, _linkConfigurations) { diff --git a/src/comm/MAVLinkProtocol.cc b/src/comm/MAVLinkProtocol.cc index 42c3552ce5a3c87bc8642781f03f1e7578704a2c..af6b42128508fdc6f354cfcff86fca3611302ac0 100644 --- a/src/comm/MAVLinkProtocol.cc +++ b/src/comm/MAVLinkProtocol.cc @@ -200,14 +200,16 @@ void MAVLinkProtocol::_linkStatusChanged(LinkInterface* link, bool connected) // Use the same shared pointer as LinkManager _connectedLinks.append(_linkMgr->sharedPointerForLink(link)); - // Send command to start MAVLink - // XXX hacky but safe - // Start NSH - const char init[] = {0x0d, 0x0d, 0x0d, 0x0d}; - link->writeBytes(init, sizeof(init)); - const char* cmd = "sh /etc/init.d/rc.usb\n"; - link->writeBytes(cmd, strlen(cmd)); - link->writeBytes(init, 4); + if (link->requiresUSBMavlinkStart()) { + // Send command to start MAVLink + // XXX hacky but safe + // Start NSH + const char init[] = {0x0d, 0x0d, 0x0d, 0x0d}; + link->writeBytes(init, sizeof(init)); + const char* cmd = "sh /etc/init.d/rc.usb\n"; + link->writeBytes(cmd, strlen(cmd)); + link->writeBytes(init, 4); + } } else { bool found = false; for (int i=0; i<_connectedLinks.count(); i++) { diff --git a/src/comm/MockLink.cc b/src/comm/MockLink.cc index 5d5f5c71923fddbd261ce8b075640220b26600b6..d265ee2615bd108c320c873fe3276ccc650ef63a 100644 --- a/src/comm/MockLink.cc +++ b/src/comm/MockLink.cc @@ -83,7 +83,7 @@ MockLink::MockLink(MockConfiguration* config) , _vehicleSystemId(128) // FIXME: Pull from eventual parameter manager , _vehicleComponentId(200) // FIXME: magic number? , _inNSH(false) - , _mavlinkStarted(false) + , _mavlinkStarted(true) , _mavBaseMode(MAV_MODE_FLAG_MANUAL_INPUT_ENABLED | MAV_MODE_FLAG_CUSTOM_MODE_ENABLED) , _mavState(MAV_STATE_STANDBY) , _firmwareType(MAV_AUTOPILOT_PX4) @@ -336,10 +336,13 @@ void MockLink::_handleIncomingNSHBytes(const char* bytes, int cBytes) if (cBytes > 0) { qDebug() << "NSH:" << (const char*)bytes; +#if 0 + // MockLink not quite ready to handle this correctly yet if (strncmp(bytes, "sh /etc/init.d/rc.usb\n", cBytes) == 0) { // This is the mavlink start command _mavlinkStarted = true; } +#endif } } diff --git a/src/comm/QGCSerialPortInfo.cc b/src/comm/QGCSerialPortInfo.cc new file mode 100644 index 0000000000000000000000000000000000000000..9b5ad4e95794b9a48f8d0e00392ba6ca61db5177 --- /dev/null +++ b/src/comm/QGCSerialPortInfo.cc @@ -0,0 +1,115 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2015 QGROUNDCONTROL PROJECT + + This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + + ======================================================================*/ + +#include "QGCSerialPortInfo.h" + +QGC_LOGGING_CATEGORY(QGCSerialPortInfoLog, "QGCSerialPortInfoLog") + +QGCSerialPortInfo::QGCSerialPortInfo(void) : + QSerialPortInfo() +{ + +} + +QGCSerialPortInfo::QGCSerialPortInfo(const QSerialPort & port) : + QSerialPortInfo(port) +{ + +} + +QGCSerialPortInfo::BoardType_t QGCSerialPortInfo::boardType(void) const +{ + if (isNull()) { + return BoardTypeUnknown; + } + + BoardType_t boardType = BoardTypeUnknown; + + switch (vendorIdentifier()) { + case px4VendorId: + if (productIdentifier() == pixhawkFMUV2ProductId || productIdentifier() == pixhawkFMUV2OldBootloaderProductId) { + qCDebug(QGCSerialPortInfoLog) << "Found PX4 FMU V2"; + boardType = BoardTypePX4FMUV2; + } else if (productIdentifier() == pixhawkFMUV1ProductId) { + qCDebug(QGCSerialPortInfoLog) << "Found PX4 FMU V1"; + boardType = BoardTypePX4FMUV1; + } else if (productIdentifier() == px4FlowProductId) { + qCDebug(QGCSerialPortInfoLog) << "Found PX4 Flow"; + boardType = BoardTypePX4Flow; + } else if (productIdentifier() == AeroCoreProductId) { + qCDebug(QGCSerialPortInfoLog) << "Found AeroCore"; + boardType = BoardTypeAeroCore; + } + break; + case threeDRRadioVendorId: + if (productIdentifier() == threeDRRadioProductId) { + qCDebug(QGCSerialPortInfoLog) << "Found 3DR Radio"; + boardType = BoardType3drRadio; + } + break; + } + + 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. + if (description() == "PX4 FMU v2.x" || description() == "PX4 BL FMU v2.x") { + qCDebug(QGCSerialPortInfoLog) << "Found PX4 FMU V2 (by name matching fallback)"; + boardType = BoardTypePX4FMUV2; + } else if (description() == "PX4 FMU v1.x" || description() == "PX4 BL FMU v1.x") { + qCDebug(QGCSerialPortInfoLog) << "Found PX4 FMU V1 (by name matching fallback)"; + boardType = BoardTypePX4FMUV1; + } else if (description().startsWith("PX4 FMU")) { + qCDebug(QGCSerialPortInfoLog) << "Found PX4 FMU, assuming V2 (by name matching fallback)"; + boardType = BoardTypePX4FMUV2; + } else if (description() == "FT231X USB UART") { + qCDebug(QGCSerialPortInfoLog) << "Found possible Radio (by name matching fallback)"; + boardType = BoardType3drRadio; + } + } + + return boardType; +} + +QList QGCSerialPortInfo::availablePorts(void) +{ + QList list; + + foreach(QSerialPortInfo portInfo, QSerialPortInfo::availablePorts()) { + list << *((QGCSerialPortInfo*)&portInfo); + } + + return list; +} + +bool QGCSerialPortInfo::boardTypePixhawk(void) const +{ + BoardType_t boardType = this->boardType(); + + return boardType == BoardTypePX4FMUV1 || boardType == BoardTypePX4FMUV2 || boardType == BoardTypeAeroCore; +} + +bool QGCSerialPortInfo::isBootloader(void) const +{ + // FIXME: Check SerialLink bootloade detect code which is different + return boardTypePixhawk() && description().contains("BL"); +} diff --git a/src/SerialPortIds.h b/src/comm/QGCSerialPortInfo.h similarity index 63% rename from src/SerialPortIds.h rename to src/comm/QGCSerialPortInfo.h index f08ed5d9e44525d5a0aa6f1cb487ae5ef0cd4b1e..1fa6e311456733252163af5c18807c9a630902ac 100644 --- a/src/SerialPortIds.h +++ b/src/comm/QGCSerialPortInfo.h @@ -21,13 +21,35 @@ ======================================================================*/ -#ifndef SerialPortIds_H -#define SerialPortIds_H +#ifndef QGCSerialPortInfo_H +#define QGCSerialPortInfo_H -// SerialPortInfo Vendor and Product Ids for known boards -class SerialPortIds { +#ifdef __android__ + #include "qserialportinfo.h" +#else + #include +#endif + +#include "QGCLoggingCategory.h" + +Q_DECLARE_LOGGING_CATEGORY(QGCSerialPortInfoLog) +/// QGC's version of Qt QSerialPortInfo. It provides additional information about board types +/// that QGC cares about. +class QGCSerialPortInfo : public QSerialPortInfo +{ public: + typedef enum { + BoardTypePX4FMUV1, + BoardTypePX4FMUV2, + BoardTypePX4Flow, + BoardType3drRadio, + BoardTypeAeroCore, + 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 pixhawkFMUV2ProductId = 17; ///< Product ID for Pixhawk V2 board @@ -40,6 +62,21 @@ public: static const int threeDRRadioVendorId = 1027; ///< Vendor ID for 3DR Radio static const int threeDRRadioProductId = 24597; ///< Product ID for 3DR Radio + + QGCSerialPortInfo(void); + QGCSerialPortInfo(const QSerialPort & port); + + /// Override of QSerialPortInfo::availablePorts + static QList availablePorts(void); + + BoardType_t boardType(void) const; + + /// @return true: board is a Pixhawk board + bool boardTypePixhawk(void) const; + + /// @return true: Board is currently in bootloader + bool isBootloader(void) const; + }; #endif diff --git a/src/comm/SerialLink.cc b/src/comm/SerialLink.cc index 4541f893db30e8db0c3fd3b3fc3e9f6225f36e9c..a19296ac1685b1e2cac2dfa126070295e6f23da5 100644 --- a/src/comm/SerialLink.cc +++ b/src/comm/SerialLink.cc @@ -15,10 +15,8 @@ #ifdef __android__ #include "qserialport.h" -#include "qserialportinfo.h" #else #include -#include #endif #include "SerialLink.h" @@ -26,6 +24,7 @@ #include "MG.h" #include "QGCLoggingCategory.h" #include "QGCApplication.h" +#include "QGCSerialPortInfo.h" QGC_LOGGING_CATEGORY(SerialLinkLog, "SerialLinkLog") @@ -380,6 +379,15 @@ LinkConfiguration* SerialLink::getLinkConfiguration() return _config; } +bool SerialLink::requiresUSBMavlinkStart(void) const +{ + if (_port) { + return QGCSerialPortInfo(*_port).boardTypePixhawk(); + } else { + return false; + } +} + //-------------------------------------------------------------------------- //-- SerialConfiguration diff --git a/src/comm/SerialLink.h b/src/comm/SerialLink.h index fbbeeea39e8f7d97f1a538a708d1671cf07a4c78..49baceaadd56478106a35316868f98011a735dc6 100644 --- a/src/comm/SerialLink.h +++ b/src/comm/SerialLink.h @@ -119,7 +119,8 @@ public: void requestReset(); bool isConnected() const; qint64 getConnectionSpeed() const; - + bool requiresUSBMavlinkStart(void) const; + // These are left unimplemented in order to cause linker errors which indicate incorrect usage of // connect/disconnect on link directly. All connect/disconnect calls should be made through LinkManager. bool connect(void); diff --git a/src/main.cc b/src/main.cc index e104854cc30c49fdf945884845c055850eec5bd2..2de8233a8047c6f6b9a1785c0ed718c4b6a5ad32 100644 --- a/src/main.cc +++ b/src/main.cc @@ -33,13 +33,13 @@ This file is part of the QGROUNDCONTROL project #include #include -#ifndef __mobile__ - #include -#endif - #include "QGCApplication.h" #include "MainWindow.h" +#ifndef __mobile__ + #include "QGCSerialPortInfo.h" +#endif + #ifdef QT_DEBUG #ifndef __mobile__ #include "UnitTest.h" @@ -58,7 +58,7 @@ This file is part of the QGROUNDCONTROL project #endif #ifndef __mobile__ -Q_DECLARE_METATYPE(QSerialPortInfo) + Q_DECLARE_METATYPE(QGCSerialPortInfo) #endif #ifdef Q_OS_WIN @@ -138,7 +138,7 @@ int main(int argc, char *argv[]) #endif qRegisterMetaType(); #ifndef __mobile__ - qRegisterMetaType(); + qRegisterMetaType(); #endif // We statically link our own QtLocation plugin