diff --git a/ground/src/plugins/coreplugin/connectionmanager.cpp b/ground/src/plugins/coreplugin/connectionmanager.cpp index 00ecd5fe1..7332e6d64 100644 --- a/ground/src/plugins/coreplugin/connectionmanager.cpp +++ b/ground/src/plugins/coreplugin/connectionmanager.cpp @@ -247,6 +247,45 @@ void ConnectionManager::unregisterAll(IConnection *connection) } } +/** +* Tells every connection plugin to stop polling for devices if they +* are doing that. +*/ +void ConnectionManager::suspendPolling() +{ + QList connections; + connections.clear(); + + for(QLinkedList::iterator iter = m_devList.begin(); + iter != m_devList.end(); iter++ ){ + if (!connections.contains(iter->connection)) + connections.append(iter->connection); + } + foreach (IConnection* cnx, connections) { + cnx->suspendPolling(); + } +} + +/** +* Tells every connection plugin to resume polling for devices if they +* are doing that. +*/ +void ConnectionManager::resumePolling() +{ + QList connections; + connections.clear(); + + for(QLinkedList::iterator iter = m_devList.begin(); + iter != m_devList.end(); iter++ ){ + if (!connections.contains(iter->connection)) + connections.append(iter->connection); + } + foreach (IConnection* cnx, connections) { + cnx->resumePolling(); + } +} + + /** * Register a device from a specific connection plugin */ @@ -267,6 +306,7 @@ void ConnectionManager::registerDevice(IConnection *conn, const QString &devN, c */ void ConnectionManager::devChanged(IConnection *connection) { + //clear device list combobox m_availableDevList->clear(); diff --git a/ground/src/plugins/coreplugin/connectionmanager.h b/ground/src/plugins/coreplugin/connectionmanager.h index 8b2af5515..29d5e390d 100644 --- a/ground/src/plugins/coreplugin/connectionmanager.h +++ b/ground/src/plugins/coreplugin/connectionmanager.h @@ -71,6 +71,8 @@ public: QIODevice *getCurrentConnection(); // NOTE: this is never implemented ?? devListItem getCurrentDevice() { return m_connectionDevice;} bool disconnectDevice(); + void suspendPolling(); + void resumePolling(); protected: void unregisterAll(IConnection *connection); diff --git a/ground/src/plugins/coreplugin/iconnection.h b/ground/src/plugins/coreplugin/iconnection.h index cb14422b0..c5dd787c4 100644 --- a/ground/src/plugins/coreplugin/iconnection.h +++ b/ground/src/plugins/coreplugin/iconnection.h @@ -70,6 +70,13 @@ public: */ virtual QString shortName() {return connectionName();} + /** + * Manage whether the plugin is allowed to poll for devices + * or not + */ + virtual void suspendPolling() {}; + virtual void resumePolling() {}; + signals: /** * Available devices list has changed, signal it to connection manager (and whoever wants to know) diff --git a/ground/src/plugins/rawhid/rawhidplugin.cpp b/ground/src/plugins/rawhid/rawhidplugin.cpp index 3b65ac5d3..6b40b8ee0 100644 --- a/ground/src/plugins/rawhid/rawhidplugin.cpp +++ b/ground/src/plugins/rawhid/rawhidplugin.cpp @@ -67,7 +67,7 @@ void RawHIDEnumerationThread::run() } } - msleep(500); //update available devices twice per second (doesn't need more) + msleep(1000); //update available devices every second (doesn't need more) } } @@ -90,7 +90,8 @@ RawHIDConnection::~RawHIDConnection() void RawHIDConnection::onEnumerationChanged() { - emit availableDevChanged(this); + if (enablePolling) + emit availableDevChanged(this); } QStringList RawHIDConnection::availableDevices() @@ -156,19 +157,17 @@ QString RawHIDConnection::shortName() /** Tells the Raw HID plugin to stop polling for USB devices */ -bool RawHIDConnection::suspendPolling() +void RawHIDConnection::suspendPolling() { enablePolling = false; - return true; } /** Tells the Raw HID plugin to resume polling for USB devices */ -bool RawHIDConnection::resumePolling() +void RawHIDConnection::resumePolling() { enablePolling = true; - return true; } diff --git a/ground/src/plugins/rawhid/rawhidplugin.h b/ground/src/plugins/rawhid/rawhidplugin.h index 328c96624..d1097cc28 100644 --- a/ground/src/plugins/rawhid/rawhidplugin.h +++ b/ground/src/plugins/rawhid/rawhidplugin.h @@ -83,8 +83,8 @@ public: virtual QString connectionName(); virtual QString shortName(); - bool suspendPolling(); - bool resumePolling(); + virtual void suspendPolling(); + virtual void resumePolling(); bool deviceOpened() {return m_deviceOpened;} diff --git a/ground/src/plugins/serialconnection/serialplugin.cpp b/ground/src/plugins/serialconnection/serialplugin.cpp index 33cfd3ea5..34da7de4a 100644 --- a/ground/src/plugins/serialconnection/serialplugin.cpp +++ b/ground/src/plugins/serialconnection/serialplugin.cpp @@ -73,7 +73,7 @@ void SerialEnumerationThread::run() SerialConnection::SerialConnection() - : m_enumerateThread(this) + : enablePolling(true), m_enumerateThread(this) { serialHandle = NULL; @@ -102,8 +102,10 @@ SerialConnection::~SerialConnection() void SerialConnection::onEnumerationChanged() { - emit availableDevChanged(this); + if (enablePolling) + emit availableDevChanged(this); } + bool sortPorts(const QextPortInfo &s1,const QextPortInfo &s2) { return s1.portName ports = QextSerialEnumerator::getPorts(); - //sort the list by port number (nice idea from PT_Dreamer :)) - qSort(ports.begin(), ports.end(),sortPorts); - foreach( QextPortInfo port, ports ) { - list.append(port.friendName); + if (enablePolling) { + QList ports = QextSerialEnumerator::getPorts(); + + //sort the list by port number (nice idea from PT_Dreamer :)) + qSort(ports.begin(), ports.end(),sortPorts); + foreach( QextPortInfo port, ports ) { + list.append(port.friendName); + } } return list; @@ -175,6 +180,22 @@ QString SerialConnection::shortName() return QString("Serial"); } +/** + Tells the Serial plugin to stop polling for serial devices + */ +void SerialConnection::suspendPolling() +{ + enablePolling = false; +} + +/** + Tells the Serial plugin to resume polling for serial devices + */ +void SerialConnection::resumePolling() +{ + enablePolling = true; +} + SerialPlugin::SerialPlugin() { diff --git a/ground/src/plugins/serialconnection/serialplugin.h b/ground/src/plugins/serialconnection/serialplugin.h index 812f6b8e2..115a3fdda 100644 --- a/ground/src/plugins/serialconnection/serialplugin.h +++ b/ground/src/plugins/serialconnection/serialplugin.h @@ -81,11 +81,16 @@ public: virtual QString connectionName(); virtual QString shortName(); + virtual void suspendPolling(); + virtual void resumePolling(); + bool deviceOpened() {return m_deviceOpened;} private: QextSerialPort* serialHandle; + bool enablePolling; + protected slots: void onEnumerationChanged(); diff --git a/ground/src/plugins/uavtalk/telemetrymanager.cpp b/ground/src/plugins/uavtalk/telemetrymanager.cpp index 4dae6d6bf..2d2c8bfd2 100644 --- a/ground/src/plugins/uavtalk/telemetrymanager.cpp +++ b/ground/src/plugins/uavtalk/telemetrymanager.cpp @@ -72,6 +72,7 @@ void TelemetryManager::onStop() delete telemetryMon; delete telemetry; delete utalk; + onDisconnect(); } void TelemetryManager::onConnect() diff --git a/ground/src/plugins/uavtalk/telemetrymonitor.cpp b/ground/src/plugins/uavtalk/telemetrymonitor.cpp index 91733389d..9bfed2109 100644 --- a/ground/src/plugins/uavtalk/telemetrymonitor.cpp +++ b/ground/src/plugins/uavtalk/telemetrymonitor.cpp @@ -54,6 +54,14 @@ TelemetryMonitor::TelemetryMonitor(UAVObjectManager* objMngr, Telemetry* tel) statsTimer->start(STATS_CONNECT_PERIOD_MS); } +TelemetryMonitor::~TelemetryMonitor() { + // Before saying goodbye, set the GCS connection status to disconnected too: + GCSTelemetryStats::DataFields gcsStats = gcsStatsObj->getData(); + gcsStats.Status = GCSTelemetryStats::STATUS_DISCONNECTED; + // Set data + gcsStatsObj->setData(gcsStats); +} + /** * Initiate object retrieval, initialize queue with objects to be retrieved. */ diff --git a/ground/src/plugins/uavtalk/telemetrymonitor.h b/ground/src/plugins/uavtalk/telemetrymonitor.h index ddef7200b..322b0a1fc 100644 --- a/ground/src/plugins/uavtalk/telemetrymonitor.h +++ b/ground/src/plugins/uavtalk/telemetrymonitor.h @@ -46,6 +46,7 @@ class TelemetryMonitor : public QObject public: TelemetryMonitor(UAVObjectManager* objMngr, Telemetry* tel); + ~TelemetryMonitor(); signals: void connected(); diff --git a/ground/src/plugins/uploader/SSP/port.cpp b/ground/src/plugins/uploader/SSP/port.cpp index 6ca8895b2..27efad616 100644 --- a/ground/src/plugins/uploader/SSP/port.cpp +++ b/ground/src/plugins/uploader/SSP/port.cpp @@ -25,7 +25,7 @@ int16_t port::pfSerialRead(void) { char c[1]; - if(sport->bytesAvailable()) + if( sport->bytesAvailable() ) { sport->read(c,1); } diff --git a/ground/src/plugins/uploader/SSP/qsspt.cpp b/ground/src/plugins/uploader/SSP/qsspt.cpp index 0d1df867d..9b89b599c 100644 --- a/ground/src/plugins/uploader/SSP/qsspt.cpp +++ b/ground/src/plugins/uploader/SSP/qsspt.cpp @@ -32,7 +32,7 @@ bool qsspt::sendData(uint8_t * buf,uint16_t size) msize=size; sendbufmutex.unlock(); msendwait.lock(); - sendwait.wait(&msendwait,100000); + sendwait.wait(&msendwait,10000); msendwait.unlock(); return true; } diff --git a/ground/src/plugins/uploader/uploadergadgetwidget.cpp b/ground/src/plugins/uploader/uploadergadgetwidget.cpp index 56b7205f9..ddc673157 100755 --- a/ground/src/plugins/uploader/uploadergadgetwidget.cpp +++ b/ground/src/plugins/uploader/uploadergadgetwidget.cpp @@ -127,8 +127,13 @@ void UploaderGadgetWidget::onAutopilotDisconnect(){ m_config->haltButton->setEnabled(false); m_config->resetButton->setEnabled(false); m_config->bootButton->setEnabled(true); - m_config->rescueButton->setEnabled(true); - m_config->telemetryLink->setEnabled(true); + if (currentStep == IAP_STATE_BOOTLOADER) { + m_config->rescueButton->setEnabled(false); + m_config->telemetryLink->setEnabled(false); + } else { + m_config->rescueButton->setEnabled(true); + m_config->telemetryLink->setEnabled(true); + } } @@ -147,6 +152,8 @@ void UploaderGadgetWidget::goToBootloader(UAVObject* callerObj, bool success) switch (currentStep) { case IAP_STATE_READY: + getSerialPorts(); // Useful in case a new serial port appeared since the initial list, + // otherwise we won't find it when we stop the board. // The board is running, send the 1st IAP Reset order: fwIAP->getField("Command")->setValue("1122"); connect(fwIAP,SIGNAL(transactionCompleted(UAVObject*,bool)),this,SLOT(goToBootloader(UAVObject*, bool))); @@ -192,17 +199,14 @@ void UploaderGadgetWidget::goToBootloader(UAVObject* callerObj, bool success) disconnect(fwIAP, SIGNAL(transactionCompleted(UAVObject*,bool)),this,SLOT(goToBootloader(UAVObject*, bool))); break; } - // stop the polling thread: otherwise it will mess up DFU - // Do it now, because otherwise it will send bad stuff to - // the board before we have time to stop it. - RawHIDConnection *cnx = pm->getObject(); - cnx->suspendPolling(); // The board is now reset: we have to disconnect telemetry Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager(); QString dli = cm->getCurrentDevice().devName; QString dlj = cm->getCurrentDevice().displayedName; cm->disconnectDevice(); + // Tell connections to stop their polling threads: otherwise it will mess up DFU + cm->suspendPolling(); log("Board Halt"); m_config->boardStatus->setText("Bootloader"); if (dlj.startsWith("USB")) @@ -229,7 +233,7 @@ void UploaderGadgetWidget::goToBootloader(UAVObject* callerObj, bool success) log("Could not enter DFU mode."); delete dfu; dfu = NULL; - cnx->resumePolling(); + cm->resumePolling(); return; } dfu->AbortOperation(); @@ -238,7 +242,7 @@ void UploaderGadgetWidget::goToBootloader(UAVObject* callerObj, bool success) log("Could not enter DFU mode."); delete dfu; dfu = NULL; - cnx->resumePolling(); + cm->resumePolling(); return; } //dfu.StatusRequest(); @@ -248,7 +252,7 @@ void UploaderGadgetWidget::goToBootloader(UAVObject* callerObj, bool success) log("Inconsistent number of devices! Aborting"); delete dfu; dfu = NULL; - cnx->resumePolling(); + cm->resumePolling(); return; } // Delete all previous tabs: @@ -264,11 +268,13 @@ void UploaderGadgetWidget::goToBootloader(UAVObject* callerObj, bool success) dw->populate(); m_config->systemElements->addTab(dw, QString("Device") + QString::number(i)); } + /* m_config->haltButton->setEnabled(false); m_config->resetButton->setEnabled(false); m_config->bootButton->setEnabled(true); m_config->telemetryLink->setEnabled(false); m_config->rescueButton->setEnabled(false); + */ if (resetOnly) { resetOnly=false; delay::msleep(3500); @@ -307,16 +313,18 @@ void UploaderGadgetWidget::systemReset() */ void UploaderGadgetWidget::systemBoot() { + clearLog(); + m_config->bootButton->setEnabled(false); if (currentStep != IAP_STATE_BOOTLOADER) { - this->repaint(); - // Stop the polling thread just in case (really necessary) - ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); - RawHIDConnection *cnx = pm->getObject(); - cnx->suspendPolling(); + // The board is now reset: we have to disconnect telemetry + Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager(); + cm->suspendPolling(); } QString devName = m_config->telemetryLink->currentText(); + log("Attempting to boot the system through " + devName + "."); + repaint(); if (!dfu) { if (devName == "USB") @@ -330,17 +338,16 @@ void UploaderGadgetWidget::systemBoot() log("Could not enter DFU mode."); delete dfu; dfu = NULL; + m_config->bootButton->setEnabled(true); return; } log("Booting system..."); dfu->JumpToApp(); // Restart the polling thread - ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); - RawHIDConnection *cnx = pm->getObject(); - cnx->resumePolling(); - // m_config->bootButton->setEnabled(false); - //m_config->haltButton->setEnabled(true); - //m_config->resetButton->setEnabled(true); + // The board is now reset: we have to disconnect telemetry + Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager(); + cm->resumePolling(); + m_config->bootButton->setEnabled(true); m_config->rescueButton->setEnabled(true); m_config->telemetryLink->setEnabled(true); m_config->boardStatus->setText("Running"); @@ -364,14 +371,12 @@ void UploaderGadgetWidget::systemBoot() */ void UploaderGadgetWidget::systemRescue() { - ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); - RawHIDConnection *cnx = pm->getObject(); + Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager(); switch (rescueStep) { case RESCUE_STEP0: { - Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager(); cm->disconnectDevice(); // stop the polling thread: otherwise it will mess up DFU - cnx->suspendPolling(); + cm->suspendPolling(); // Delete all previous tabs: while (m_config->systemElements->count()) { QWidget *qw = m_config->systemElements->widget(0); @@ -414,7 +419,9 @@ void UploaderGadgetWidget::systemRescue() { rescueStep = RESCUE_STEP0; log("Could not enter DFU mode."); - cnx->resumePolling(); + delete dfu; + dfu = NULL; + cm->resumePolling(); return; } if(!dfu->findDevices() || (dfu->numberOfDevices != 1)) @@ -423,7 +430,7 @@ void UploaderGadgetWidget::systemRescue() log("Could not detect mainboard."); delete dfu; dfu = NULL; - cnx->resumePolling(); + cm->resumePolling(); return; } rescueStep = RESCUE_POWER1; @@ -449,7 +456,7 @@ void UploaderGadgetWidget::systemRescue() log("Could not detect devices."); delete dfu; dfu = NULL; - cnx->resumePolling(); + cm->resumePolling(); return; } log(QString("Found ") + QString::number(dfu->numberOfDevices) + QString(" device(s).")); @@ -457,7 +464,7 @@ void UploaderGadgetWidget::systemRescue() log("Inconsistent number of devices, aborting!"); delete dfu; dfu = NULL; - cnx->resumePolling(); + cm->resumePolling(); return; } for(int i=0;inumberOfDevices;i++) {