Commit b0d62d6f authored by Don Gagne's avatar Don Gagne

Merge pull request #2218 from DonLakeFlyer/ACPortStuff

Auto-Connect port stuff
parents dc01aba6 4dd5c1de
...@@ -302,6 +302,7 @@ WindowsBuild { ...@@ -302,6 +302,7 @@ WindowsBuild {
!iOSBuild { !iOSBuild {
HEADERS += \ HEADERS += \
src/comm/QGCSerialPortInfo.h \
src/comm/SerialLink.h \ src/comm/SerialLink.h \
src/ui/SerialConfigurationWindow.h \ src/ui/SerialConfigurationWindow.h \
} }
...@@ -407,6 +408,7 @@ SOURCES += \ ...@@ -407,6 +408,7 @@ SOURCES += \
!iOSBuild { !iOSBuild {
SOURCES += \ SOURCES += \
src/comm/QGCSerialPortInfo.cc \
src/comm/SerialLink.cc \ src/comm/SerialLink.cc \
src/ui/SerialConfigurationWindow.cc \ src/ui/SerialConfigurationWindow.cc \
} }
......
...@@ -109,23 +109,23 @@ void FirmwareUpgradeController::_foundBoard(bool firstAttempt, const QSerialPort ...@@ -109,23 +109,23 @@ void FirmwareUpgradeController::_foundBoard(bool firstAttempt, const QSerialPort
{ {
_foundBoardInfo = info; _foundBoardInfo = info;
switch (type) { switch (type) {
case FoundBoardPX4FMUV1: case QGCSerialPortInfo::BoardTypePX4FMUV1:
_foundBoardType = "PX4 FMU V1"; _foundBoardType = "PX4 FMU V1";
_startFlashWhenBootloaderFound = false; _startFlashWhenBootloaderFound = false;
break; break;
case FoundBoardPX4FMUV2: case QGCSerialPortInfo::BoardTypePX4FMUV2:
_foundBoardType = "Pixhawk"; _foundBoardType = "Pixhawk";
_startFlashWhenBootloaderFound = false; _startFlashWhenBootloaderFound = false;
break; break;
case FoundBoardAeroCore: case QGCSerialPortInfo::BoardTypeAeroCore:
_foundBoardType = "AeroCore"; _foundBoardType = "AeroCore";
_startFlashWhenBootloaderFound = false; _startFlashWhenBootloaderFound = false;
break; break;
case FoundBoardPX4Flow: case QGCSerialPortInfo::BoardTypePX4Flow:
_foundBoardType = "PX4 Flow"; _foundBoardType = "PX4 Flow";
_startFlashWhenBootloaderFound = false; _startFlashWhenBootloaderFound = false;
break; break;
case FoundBoard3drRadio: case QGCSerialPortInfo::BoardType3drRadio:
_foundBoardType = "3DR Radio"; _foundBoardType = "3DR Radio";
if (!firstAttempt) { if (!firstAttempt) {
// Radio always flashes latest firmware, so we can start right away without // Radio always flashes latest firmware, so we can start right away without
......
...@@ -29,10 +29,8 @@ ...@@ -29,10 +29,8 @@
#include "Bootloader.h" #include "Bootloader.h"
#include "QGCLoggingCategory.h" #include "QGCLoggingCategory.h"
#include "QGC.h" #include "QGC.h"
#include "SerialPortIds.h"
#include <QTimer> #include <QTimer>
#include <QSerialPortInfo>
#include <QDebug> #include <QDebug>
#include <QSerialPort> #include <QSerialPort>
...@@ -99,8 +97,8 @@ void PX4FirmwareUpgradeThreadWorker::_findBoardOnce(void) ...@@ -99,8 +97,8 @@ void PX4FirmwareUpgradeThreadWorker::_findBoardOnce(void)
{ {
qCDebug(FirmwareUpgradeLog) << "_findBoardOnce"; qCDebug(FirmwareUpgradeLog) << "_findBoardOnce";
QSerialPortInfo portInfo; QGCSerialPortInfo portInfo;
PX4FirmwareUpgradeFoundBoardType_t boardType; QGCSerialPortInfo::BoardType_t boardType;
if (_findBoardFromPorts(portInfo, boardType)) { if (_findBoardFromPorts(portInfo, boardType)) {
if (!_foundBoard) { if (!_foundBoard) {
...@@ -108,7 +106,7 @@ void PX4FirmwareUpgradeThreadWorker::_findBoardOnce(void) ...@@ -108,7 +106,7 @@ void PX4FirmwareUpgradeThreadWorker::_findBoardOnce(void)
_foundBoardPortInfo = portInfo; _foundBoardPortInfo = portInfo;
emit foundBoard(_findBoardFirstAttempt, portInfo, boardType); emit foundBoard(_findBoardFirstAttempt, portInfo, boardType);
if (!_findBoardFirstAttempt) { if (!_findBoardFirstAttempt) {
if (boardType == FoundBoard3drRadio) { if (boardType == QGCSerialPortInfo::BoardType3drRadio) {
_3drRadioForceBootloader(portInfo); _3drRadioForceBootloader(portInfo);
return; return;
} else { } else {
...@@ -131,11 +129,9 @@ void PX4FirmwareUpgradeThreadWorker::_findBoardOnce(void) ...@@ -131,11 +129,9 @@ void PX4FirmwareUpgradeThreadWorker::_findBoardOnce(void)
_timerRetry->start(); _timerRetry->start();
} }
bool PX4FirmwareUpgradeThreadWorker::_findBoardFromPorts(QSerialPortInfo& portInfo, PX4FirmwareUpgradeFoundBoardType_t& type) bool PX4FirmwareUpgradeThreadWorker::_findBoardFromPorts(QGCSerialPortInfo& portInfo, QGCSerialPortInfo::BoardType_t& boardType)
{ {
bool found = false; foreach (QGCSerialPortInfo info, QGCSerialPortInfo::availablePorts()) {
foreach (QSerialPortInfo info, QSerialPortInfo::availablePorts()) {
qCDebug(FirmwareUpgradeLog) << "Serial Port --------------"; qCDebug(FirmwareUpgradeLog) << "Serial Port --------------";
qCDebug(FirmwareUpgradeLog) << "\tport name:" << info.portName(); qCDebug(FirmwareUpgradeLog) << "\tport name:" << info.portName();
qCDebug(FirmwareUpgradeLog) << "\tdescription:" << info.description(); qCDebug(FirmwareUpgradeLog) << "\tdescription:" << info.description();
...@@ -143,55 +139,8 @@ bool PX4FirmwareUpgradeThreadWorker::_findBoardFromPorts(QSerialPortInfo& portIn ...@@ -143,55 +139,8 @@ bool PX4FirmwareUpgradeThreadWorker::_findBoardFromPorts(QSerialPortInfo& portIn
qCDebug(FirmwareUpgradeLog) << "\tvendor ID:" << info.vendorIdentifier(); qCDebug(FirmwareUpgradeLog) << "\tvendor ID:" << info.vendorIdentifier();
qCDebug(FirmwareUpgradeLog) << "\tproduct ID:" << info.productIdentifier(); qCDebug(FirmwareUpgradeLog) << "\tproduct ID:" << info.productIdentifier();
if (!info.portName().isEmpty()) { boardType = info.boardType();
switch (info.vendorIdentifier()) { if (boardType != QGCSerialPortInfo::BoardTypeUnknown) {
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) {
portInfo = info; portInfo = info;
return true; return true;
} }
...@@ -200,7 +149,7 @@ bool PX4FirmwareUpgradeThreadWorker::_findBoardFromPorts(QSerialPortInfo& portIn ...@@ -200,7 +149,7 @@ bool PX4FirmwareUpgradeThreadWorker::_findBoardFromPorts(QSerialPortInfo& portIn
return false; return false;
} }
void PX4FirmwareUpgradeThreadWorker::_3drRadioForceBootloader(const QSerialPortInfo& portInfo) void PX4FirmwareUpgradeThreadWorker::_3drRadioForceBootloader(const QGCSerialPortInfo& portInfo)
{ {
// First make sure we can't get the bootloader // First make sure we can't get the bootloader
...@@ -257,7 +206,7 @@ void PX4FirmwareUpgradeThreadWorker::_3drRadioForceBootloader(const QSerialPortI ...@@ -257,7 +206,7 @@ void PX4FirmwareUpgradeThreadWorker::_3drRadioForceBootloader(const QSerialPortI
_findBootloader(portInfo, true /* radio mode */, true /* errorOnNotFound */); _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"; qCDebug(FirmwareUpgradeLog) << "_findBootloader";
......
...@@ -30,25 +30,17 @@ ...@@ -30,25 +30,17 @@
#include "Bootloader.h" #include "Bootloader.h"
#include "FirmwareImage.h" #include "FirmwareImage.h"
#include "QGCSerialPortInfo.h"
#include <QObject> #include <QObject>
#include <QThread> #include <QThread>
#include <QTimer> #include <QTimer>
#include <QTime> #include <QTime>
#include <QSerialPortInfo>
#include "qextserialport.h" #include "qextserialport.h"
#include <stdint.h> #include <stdint.h>
typedef enum {
FoundBoardPX4FMUV1,
FoundBoardPX4FMUV2,
FoundBoardPX4Flow,
FoundBoard3drRadio,
FoundBoardAeroCore
} PX4FirmwareUpgradeFoundBoardType_t;
class PX4FirmwareUpgradeThreadController; class PX4FirmwareUpgradeThreadController;
/// @brief Used to run bootloader commands on a seperate thread. These routines are mainly meant to to be called /// @brief Used to run bootloader commands on a seperate thread. These routines are mainly meant to to be called
...@@ -64,7 +56,7 @@ public: ...@@ -64,7 +56,7 @@ public:
signals: signals:
void updateProgress(int curr, int total); 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 noBoardFound(void);
void boardGone(void); void boardGone(void);
void foundBootloader(int bootloaderVersion, int boardID, int flashSize); void foundBootloader(int bootloaderVersion, int boardID, int flashSize);
...@@ -85,9 +77,9 @@ private slots: ...@@ -85,9 +77,9 @@ private slots:
void _cancel(void); void _cancel(void);
private: private:
bool _findBoardFromPorts(QSerialPortInfo& portInfo, PX4FirmwareUpgradeFoundBoardType_t& type); bool _findBoardFromPorts(QGCSerialPortInfo& portInfo, QGCSerialPortInfo::BoardType_t& boardType);
bool _findBootloader(const QSerialPortInfo& portInfo, bool radioMode, bool errorOnNotFound); bool _findBootloader(const QGCSerialPortInfo& portInfo, bool radioMode, bool errorOnNotFound);
void _3drRadioForceBootloader(const QSerialPortInfo& portInfo); void _3drRadioForceBootloader(const QGCSerialPortInfo& portInfo);
bool _erase(void); bool _erase(void);
PX4FirmwareUpgradeThreadController* _controller; PX4FirmwareUpgradeThreadController* _controller;
...@@ -100,7 +92,7 @@ private: ...@@ -100,7 +92,7 @@ private:
bool _foundBoard; ///< true: board is currently connected bool _foundBoard; ///< true: board is currently connected
bool _findBoardFirstAttempt; ///< true: this is our first try looking for a board 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 /// @brief Provides methods to interact with the bootloader. The commands themselves are signalled
...@@ -128,7 +120,7 @@ public: ...@@ -128,7 +120,7 @@ public:
signals: signals:
/// @brief Emitted by the find board process when it finds a board. /// @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); void noBoardFound(void);
...@@ -163,7 +155,7 @@ signals: ...@@ -163,7 +155,7 @@ signals:
void _cancel(void); void _cancel(void);
private slots: 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 _noBoardFound(void) { emit noBoardFound(); }
void _boardGone(void) { emit boardGone(); } void _boardGone(void) { emit boardGone(); }
void _foundBootloader(int bootloaderVersion, int boardID, int flashSize) { emit foundBootloader(bootloaderVersion, boardID, flashSize); } void _foundBootloader(int bootloaderVersion, int boardID, int flashSize) { emit foundBootloader(bootloaderVersion, boardID, flashSize); }
......
...@@ -125,6 +125,9 @@ public: ...@@ -125,6 +125,9 @@ public:
/// set into the link when it is added to LinkManager /// set into the link when it is added to LinkManager
uint8_t getMavlinkChannel(void) const { Q_ASSERT(_mavlinkChannelSet); return _mavlinkChannel; } 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 // 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. // connect/disconnect on link directly. All connect/disconnect calls should be made through LinkManager.
bool connect(void); bool connect(void);
......
...@@ -34,18 +34,13 @@ This file is part of the QGROUNDCONTROL project ...@@ -34,18 +34,13 @@ This file is part of the QGROUNDCONTROL project
#include <QDebug> #include <QDebug>
#ifndef __ios__ #ifndef __ios__
#ifdef __android__ #include "QGCSerialPortInfo.h"
#include "qserialportinfo.h"
#else
#include <QSerialPortInfo>
#endif
#endif #endif
#include "LinkManager.h" #include "LinkManager.h"
#include "MainWindow.h" #include "MainWindow.h"
#include "QGCMessageBox.h" #include "QGCMessageBox.h"
#include "QGCApplication.h" #include "QGCApplication.h"
#include "SerialPortIds.h"
#include "QGCApplication.h" #include "QGCApplication.h"
QGC_LOGGING_CATEGORY(LinkManagerLog, "LinkManagerLog") QGC_LOGGING_CATEGORY(LinkManagerLog, "LinkManagerLog")
...@@ -489,9 +484,9 @@ void LinkManager::_updateConfigurationList(void) ...@@ -489,9 +484,9 @@ void LinkManager::_updateConfigurationList(void)
} }
bool saveList = false; bool saveList = false;
QStringList currentPorts; QStringList currentPorts;
QList<QSerialPortInfo> portList = QSerialPortInfo::availablePorts(); QList<QGCSerialPortInfo> portList = QGCSerialPortInfo::availablePorts();
// Iterate Comm Ports // Iterate Comm Ports
foreach (QSerialPortInfo portInfo, portList) { foreach (QGCSerialPortInfo portInfo, portList) {
#if 0 #if 0
// Too noisy for most logging, so turn on as needed // Too noisy for most logging, so turn on as needed
qCDebug(LinkManagerLog) << "-----------------------------------------------------"; qCDebug(LinkManagerLog) << "-----------------------------------------------------";
...@@ -504,8 +499,15 @@ void LinkManager::_updateConfigurationList(void) ...@@ -504,8 +499,15 @@ void LinkManager::_updateConfigurationList(void)
#endif #endif
// Save port name // Save port name
currentPorts << portInfo.systemLocation(); 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()); SerialConfiguration* pSerial = _findSerialConfiguration(portInfo.systemLocation());
if (pSerial) { if (pSerial) {
//-- If this port is configured make sure it has the preferred flag set //-- If this port is configured make sure it has the preferred flag set
...@@ -514,45 +516,34 @@ void LinkManager::_updateConfigurationList(void) ...@@ -514,45 +516,34 @@ void LinkManager::_updateConfigurationList(void)
saveList = true; saveList = true;
} }
} else { } else {
// Lets create a new Serial configuration automatically switch (boardType) {
if (portInfo.description() == "AeroCore") { 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())); 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())); pSerial = new SerialConfiguration(QString("PX4Flow on %1").arg(portInfo.portName().trimmed()));
} else if (portInfo.description().contains("PX4")) { break;
pSerial = new SerialConfiguration(QString("Pixhawk on %1").arg(portInfo.portName().trimmed())); case QGCSerialPortInfo::BoardType3drRadio:
} else { pSerial = new SerialConfiguration(QString("3DR Radio on %1").arg(portInfo.portName().trimmed()));
continue; default:
} qWarning() << "Internal error";
pSerial->setDynamic(true); break;
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;
} }
} else {
// Lets create a new Serial configuration automatically (an assumption at best) pSerial->setBaud(boardType == QGCSerialPortInfo::BoardType3drRadio ? 57600 : 115200);
pSerial = new SerialConfiguration(QString("3DR Radio on %1").arg(portInfo.portName().trimmed()));
pSerial->setDynamic(true); pSerial->setDynamic(true);
pSerial->setPreferred(true); pSerial->setPreferred(true);
pSerial->setBaud(57600);
pSerial->setPortName(portInfo.systemLocation()); pSerial->setPortName(portInfo.systemLocation());
addLinkConfiguration(pSerial); addLinkConfiguration(pSerial);
saveList = true; saveList = true;
} }
} }
} }
// Now we go through the current configuration list and make sure any dynamic config has gone away // Now we go through the current configuration list and make sure any dynamic config has gone away
QList<LinkConfiguration*> _confToDelete; QList<LinkConfiguration*> _confToDelete;
foreach (LinkConfiguration* pLink, _linkConfigurations) { foreach (LinkConfiguration* pLink, _linkConfigurations) {
......
...@@ -200,14 +200,16 @@ void MAVLinkProtocol::_linkStatusChanged(LinkInterface* link, bool connected) ...@@ -200,14 +200,16 @@ void MAVLinkProtocol::_linkStatusChanged(LinkInterface* link, bool connected)
// Use the same shared pointer as LinkManager // Use the same shared pointer as LinkManager
_connectedLinks.append(_linkMgr->sharedPointerForLink(link)); _connectedLinks.append(_linkMgr->sharedPointerForLink(link));
// Send command to start MAVLink if (link->requiresUSBMavlinkStart()) {
// XXX hacky but safe // Send command to start MAVLink
// Start NSH // XXX hacky but safe
const char init[] = {0x0d, 0x0d, 0x0d, 0x0d}; // Start NSH
link->writeBytes(init, sizeof(init)); const char init[] = {0x0d, 0x0d, 0x0d, 0x0d};
const char* cmd = "sh /etc/init.d/rc.usb\n"; link->writeBytes(init, sizeof(init));
link->writeBytes(cmd, strlen(cmd)); const char* cmd = "sh /etc/init.d/rc.usb\n";
link->writeBytes(init, 4); link->writeBytes(cmd, strlen(cmd));
link->writeBytes(init, 4);
}
} else { } else {
bool found = false; bool found = false;
for (int i=0; i<_connectedLinks.count(); i++) { for (int i=0; i<_connectedLinks.count(); i++) {
......
...@@ -83,7 +83,7 @@ MockLink::MockLink(MockConfiguration* config) ...@@ -83,7 +83,7 @@ MockLink::MockLink(MockConfiguration* config)
, _vehicleSystemId(128) // FIXME: Pull from eventual parameter manager , _vehicleSystemId(128) // FIXME: Pull from eventual parameter manager
, _vehicleComponentId(200) // FIXME: magic number? , _vehicleComponentId(200) // FIXME: magic number?
, _inNSH(false) , _inNSH(false)
, _mavlinkStarted(false) , _mavlinkStarted(true)
, _mavBaseMode(MAV_MODE_FLAG_MANUAL_INPUT_ENABLED | MAV_MODE_FLAG_CUSTOM_MODE_ENABLED) , _mavBaseMode(MAV_MODE_FLAG_MANUAL_INPUT_ENABLED | MAV_MODE_FLAG_CUSTOM_MODE_ENABLED)
, _mavState(MAV_STATE_STANDBY) , _mavState(MAV_STATE_STANDBY)
, _firmwareType(MAV_AUTOPILOT_PX4) , _firmwareType(MAV_AUTOPILOT_PX4)
...@@ -336,10 +336,13 @@ void MockLink::_handleIncomingNSHBytes(const char* bytes, int cBytes) ...@@ -336,10 +336,13 @@ void MockLink::_handleIncomingNSHBytes(const char* bytes, int cBytes)
if (cBytes > 0) { if (cBytes > 0) {
qDebug() << "NSH:" << (const char*)bytes; 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) { if (strncmp(bytes, "sh /etc/init.d/rc.usb\n", cBytes) == 0) {
// This is the mavlink start command // This is the mavlink start command
_mavlinkStarted = true; _mavlinkStarted = true;
} }
#endif
} }
} }
......
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
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 <http://www.gnu.org/licenses/>.
======================================================================*/
#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> QGCSerialPortInfo::availablePorts(void)
{
QList<QGCSerialPortInfo> 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");
}
...@@ -21,13 +21,35 @@ ...@@ -21,13 +21,35 @@
======================================================================*/ ======================================================================*/
#ifndef SerialPortIds_H #ifndef QGCSerialPortInfo_H
#define SerialPortIds_H #define QGCSerialPortInfo_H
// SerialPortInfo Vendor and Product Ids for known boards #ifdef __android__
class SerialPortIds { #include "qserialportinfo.h"
#else
#include <QSerialPortInfo>
#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: 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 px4VendorId = 9900; ///< Vendor ID for Pixhawk board (V2 and V1) and PX4 Flow
static const int pixhawkFMUV2ProductId = 17; ///< Product ID for Pixhawk V2 board static const int pixhawkFMUV2ProductId = 17; ///< Product ID for Pixhawk V2 board
...@@ -40,6 +62,21 @@ public: ...@@ -40,6 +62,21 @@ public:
static const int threeDRRadioVendorId = 1027; ///< Vendor ID for 3DR Radio static const int threeDRRadioVendorId = 1027; ///< Vendor ID for 3DR Radio
static const int threeDRRadioProductId = 24597; ///< Product 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<QGCSerialPortInfo> 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 #endif
...@@ -15,10 +15,8 @@ ...@@ -15,10 +15,8 @@
#ifdef __android__ #ifdef __android__
#include "qserialport.h" #include "qserialport.h"
#include "qserialportinfo.h"
#else #else
#include <QSerialPort> #include <QSerialPort>
#include <QSerialPortInfo>
#endif #endif
#include "SerialLink.h" #include "SerialLink.h"
...@@ -26,6 +24,7 @@ ...@@ -26,6 +24,7 @@
#include "MG.h" #include "MG.h"
#include "QGCLoggingCategory.h" #include "QGCLoggingCategory.h"
#include "QGCApplication.h" #include "QGCApplication.h"
#include "QGCSerialPortInfo.h"
QGC_LOGGING_CATEGORY(SerialLinkLog, "SerialLinkLog") QGC_LOGGING_CATEGORY(SerialLinkLog, "SerialLinkLog")
...@@ -380,6 +379,15 @@ LinkConfiguration* SerialLink::getLinkConfiguration() ...@@ -380,6 +379,15 @@ LinkConfiguration* SerialLink::getLinkConfiguration()
return _config; return _config;
} }
bool SerialLink::requiresUSBMavlinkStart(void) const
{
if (_port) {
return QGCSerialPortInfo(*_port).boardTypePixhawk();
} else {
return false;
}
}
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
//-- SerialConfiguration //-- SerialConfiguration
......
...@@ -119,7 +119,8 @@ public: ...@@ -119,7 +119,8 @@ public:
void requestReset(); void requestReset();
bool isConnected() const; bool isConnected() const;
qint64 getConnectionSpeed() const; qint64 getConnectionSpeed() const;
bool requiresUSBMavlinkStart(void) const;
// These are left unimplemented in order to cause linker errors which indicate incorrect usage of // 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. // connect/disconnect on link directly. All connect/disconnect calls should be made through LinkManager.
bool connect(void); bool connect(void);
......
...@@ -33,13 +33,13 @@ This file is part of the QGROUNDCONTROL project ...@@ -33,13 +33,13 @@ This file is part of the QGROUNDCONTROL project
#include <QSslSocket> #include <QSslSocket>
#include <QProcessEnvironment> #include <QProcessEnvironment>
#ifndef __mobile__
#include <QSerialPortInfo>
#endif
#include "QGCApplication.h" #include "QGCApplication.h"
#include "MainWindow.h" #include "MainWindow.h"
#ifndef __mobile__
#include "QGCSerialPortInfo.h"
#endif
#ifdef QT_DEBUG #ifdef QT_DEBUG
#ifndef __mobile__ #ifndef __mobile__
#include "UnitTest.h" #include "UnitTest.h"
...@@ -58,7 +58,7 @@ This file is part of the QGROUNDCONTROL project ...@@ -58,7 +58,7 @@ This file is part of the QGROUNDCONTROL project
#endif #endif
#ifndef __mobile__ #ifndef __mobile__
Q_DECLARE_METATYPE(QSerialPortInfo) Q_DECLARE_METATYPE(QGCSerialPortInfo)
#endif #endif
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
...@@ -138,7 +138,7 @@ int main(int argc, char *argv[]) ...@@ -138,7 +138,7 @@ int main(int argc, char *argv[])
#endif #endif
qRegisterMetaType<QAbstractSocket::SocketError>(); qRegisterMetaType<QAbstractSocket::SocketError>();
#ifndef __mobile__ #ifndef __mobile__
qRegisterMetaType<QSerialPortInfo>(); qRegisterMetaType<QGCSerialPortInfo>();
#endif #endif
// We statically link our own QtLocation plugin // We statically link our own QtLocation plugin
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment