1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-12-02 10:24:11 +01:00

OP-306 More updates to plugins to properly destroy the Widgets when the gadgets are removed.

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@2644 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
edouard 2011-01-31 21:50:11 +00:00 committed by edouard
parent 6ef4dec59f
commit 0a87ed23c7
7 changed files with 752 additions and 741 deletions

View File

@ -38,6 +38,7 @@ DialGadget::DialGadget(QString classId, DialGadgetWidget *widget, QWidget *paren
DialGadget::~DialGadget() DialGadget::~DialGadget()
{ {
delete m_widget;
} }
/* /*

View File

@ -37,6 +37,7 @@ LineardialGadget::LineardialGadget(QString classId, LineardialGadgetWidget *widg
LineardialGadget::~LineardialGadget() LineardialGadget::~LineardialGadget()
{ {
delete m_widget;
} }
/* /*

View File

@ -1,56 +1,57 @@
/** /**
****************************************************************************** ******************************************************************************
* *
* @file pfdgadget.cpp * @file pfdgadget.cpp
* @author Edouard Lafargue Copyright (C) 2010. * @author Edouard Lafargue Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins * @addtogroup GCSPlugins GCS Plugins
* @{ * @{
* @addtogroup OPMapPlugin Primary Flight Display Plugin * @addtogroup OPMapPlugin Primary Flight Display Plugin
* @{ * @{
* @brief The Primary Flight Display Gadget * @brief The Primary Flight Display Gadget
*****************************************************************************/ *****************************************************************************/
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but * This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details. * for more details.
* *
* You should have received a copy of the GNU General Public License along * You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include "pfdgadget.h" #include "pfdgadget.h"
#include "pfdgadgetwidget.h" #include "pfdgadgetwidget.h"
#include "pfdgadgetconfiguration.h" #include "pfdgadgetconfiguration.h"
PFDGadget::PFDGadget(QString classId, PFDGadgetWidget *widget, QWidget *parent) : PFDGadget::PFDGadget(QString classId, PFDGadgetWidget *widget, QWidget *parent) :
IUAVGadget(classId, parent), IUAVGadget(classId, parent),
m_widget(widget) m_widget(widget)
{ {
} }
PFDGadget::~PFDGadget() PFDGadget::~PFDGadget()
{ {
} delete m_widget;
}
/*
This is called when a configuration is loaded, and updates the plugin's settings. /*
Careful: the plugin is already drawn before the loadConfiguration method is called the This is called when a configuration is loaded, and updates the plugin's settings.
first time, so you have to be careful not to assume all the plugin values are initialized Careful: the plugin is already drawn before the loadConfiguration method is called the
the first time you use them first time, so you have to be careful not to assume all the plugin values are initialized
*/ the first time you use them
void PFDGadget::loadConfiguration(IUAVGadgetConfiguration* config) */
{ void PFDGadget::loadConfiguration(IUAVGadgetConfiguration* config)
PFDGadgetConfiguration *m = qobject_cast<PFDGadgetConfiguration*>(config); {
m_widget->setHqFonts(m->getHqFonts()); PFDGadgetConfiguration *m = qobject_cast<PFDGadgetConfiguration*>(config);
m_widget->setDialFile(m->dialFile()); m_widget->setHqFonts(m->getHqFonts());
m_widget->enableOpenGL(m->useOpenGL()); m_widget->setDialFile(m->dialFile());
m_widget->enableSmoothUpdates(m->getBeSmooth()); m_widget->enableOpenGL(m->useOpenGL());
m_widget->connectNeedles(); m_widget->enableSmoothUpdates(m->getBeSmooth());
} m_widget->connectNeedles();
}

View File

@ -1,52 +1,53 @@
/** /**
****************************************************************************** ******************************************************************************
* *
* @file systemhealthgadget.cpp * @file systemhealthgadget.cpp
* @author Edouard Lafargue Copyright (C) 2010. * @author Edouard Lafargue Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins * @addtogroup GCSPlugins GCS Plugins
* @{ * @{
* @addtogroup SystemHealthPlugin System Health Plugin * @addtogroup SystemHealthPlugin System Health Plugin
* @{ * @{
* @brief The System Health gadget plugin * @brief The System Health gadget plugin
*****************************************************************************/ *****************************************************************************/
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but * This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details. * for more details.
* *
* You should have received a copy of the GNU General Public License along * You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include "systemhealthgadget.h" #include "systemhealthgadget.h"
#include "systemhealthgadgetwidget.h" #include "systemhealthgadgetwidget.h"
#include "systemhealthgadgetconfiguration.h" #include "systemhealthgadgetconfiguration.h"
SystemHealthGadget::SystemHealthGadget(QString classId, SystemHealthGadgetWidget *widget, QWidget *parent) : SystemHealthGadget::SystemHealthGadget(QString classId, SystemHealthGadgetWidget *widget, QWidget *parent) :
IUAVGadget(classId, parent), IUAVGadget(classId, parent),
m_widget(widget) m_widget(widget)
{ {
} }
SystemHealthGadget::~SystemHealthGadget() SystemHealthGadget::~SystemHealthGadget()
{ {
} delete m_widget;
}
/*
This is called when a configuration is loaded, and updates the plugin's settings. /*
Careful: the plugin is already drawn before the loadConfiguration method is called the This is called when a configuration is loaded, and updates the plugin's settings.
first time, so you have to be careful not to assume all the plugin values are initialized Careful: the plugin is already drawn before the loadConfiguration method is called the
the first time you use them first time, so you have to be careful not to assume all the plugin values are initialized
*/ the first time you use them
void SystemHealthGadget::loadConfiguration(IUAVGadgetConfiguration* config) */
{ void SystemHealthGadget::loadConfiguration(IUAVGadgetConfiguration* config)
SystemHealthGadgetConfiguration *m = qobject_cast<SystemHealthGadgetConfiguration*>(config); {
m_widget->setSystemFile(m->getSystemFile()); // Triggers widget repaint SystemHealthGadgetConfiguration *m = qobject_cast<SystemHealthGadgetConfiguration*>(config);
} m_widget->setSystemFile(m->getSystemFile()); // Triggers widget repaint
}

View File

@ -1,49 +1,49 @@
/** /**
****************************************************************************** ******************************************************************************
* *
* @file uavobjectbrowser.cpp * @file uavobjectbrowser.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins * @addtogroup GCSPlugins GCS Plugins
* @{ * @{
* @addtogroup UAVObjectBrowserPlugin UAVObject Browser Plugin * @addtogroup UAVObjectBrowserPlugin UAVObject Browser Plugin
* @{ * @{
* @brief The UAVObject Browser gadget plugin * @brief The UAVObject Browser gadget plugin
*****************************************************************************/ *****************************************************************************/
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but * This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details. * for more details.
* *
* You should have received a copy of the GNU General Public License along * You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include "uavobjectbrowser.h" #include "uavobjectbrowser.h"
#include "uavobjectbrowserwidget.h" #include "uavobjectbrowserwidget.h"
#include "uavobjectbrowserconfiguration.h" #include "uavobjectbrowserconfiguration.h"
UAVObjectBrowser::UAVObjectBrowser(QString classId, UAVObjectBrowserWidget *widget, QWidget *parent) : UAVObjectBrowser::UAVObjectBrowser(QString classId, UAVObjectBrowserWidget *widget, QWidget *parent) :
IUAVGadget(classId, parent), IUAVGadget(classId, parent),
m_widget(widget) m_widget(widget)
{ {
} }
UAVObjectBrowser::~UAVObjectBrowser() UAVObjectBrowser::~UAVObjectBrowser()
{ {
delete m_widget;
} }
void UAVObjectBrowser::loadConfiguration(IUAVGadgetConfiguration* config) void UAVObjectBrowser::loadConfiguration(IUAVGadgetConfiguration* config)
{ {
UAVObjectBrowserConfiguration *m = qobject_cast<UAVObjectBrowserConfiguration*>(config); UAVObjectBrowserConfiguration *m = qobject_cast<UAVObjectBrowserConfiguration*>(config);
m_widget->setRecentlyUpdatedColor(m->recentlyUpdatedColor()); m_widget->setRecentlyUpdatedColor(m->recentlyUpdatedColor());
m_widget->setManuallyChangedColor(m->manuallyChangedColor()); m_widget->setManuallyChangedColor(m->manuallyChangedColor());
m_widget->setRecentlyUpdatedTimeout(m->recentlyUpdatedTimeout()); m_widget->setRecentlyUpdatedTimeout(m->recentlyUpdatedTimeout());
} }

View File

@ -1,51 +1,51 @@
/** /**
****************************************************************************** ******************************************************************************
* *
* @file uploadergadget.cpp * @file uploadergadget.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins * @addtogroup GCSPlugins GCS Plugins
* @{ * @{
* @addtogroup YModemUploader YModem Serial Uploader Plugin * @addtogroup YModemUploader YModem Serial Uploader Plugin
* @{ * @{
* @brief The YModem protocol serial uploader plugin * @brief The YModem protocol serial uploader plugin
*****************************************************************************/ *****************************************************************************/
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but * This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details. * for more details.
* *
* You should have received a copy of the GNU General Public License along * You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include "uploadergadget.h" #include "uploadergadget.h"
#include "uploadergadgetwidget.h" #include "uploadergadgetwidget.h"
#include "uploadergadgetconfiguration.h" #include "uploadergadgetconfiguration.h"
UploaderGadget::UploaderGadget(QString classId, UploaderGadgetWidget *widget, QWidget *parent) : UploaderGadget::UploaderGadget(QString classId, UploaderGadgetWidget *widget, QWidget *parent) :
IUAVGadget(classId, parent), IUAVGadget(classId, parent),
m_widget(widget) m_widget(widget)
{ {
} }
UploaderGadget::~UploaderGadget() UploaderGadget::~UploaderGadget()
{ {
delete m_widget;
} }
/** /**
* Loads a configuration. * Loads a configuration.
* *
*/ */
void UploaderGadget::loadConfiguration(IUAVGadgetConfiguration* config) void UploaderGadget::loadConfiguration(IUAVGadgetConfiguration* config)
{ {
Q_UNUSED(config); Q_UNUSED(config);
/* UploaderGadgetConfiguration *m = qobject_cast< UploaderGadgetConfiguration*>(config); /* UploaderGadgetConfiguration *m = qobject_cast< UploaderGadgetConfiguration*>(config);
*/ */
} }

View File

@ -1,533 +1,540 @@
/** /**
****************************************************************************** ******************************************************************************
* *
* @file uploadergadgetwidget.cpp * @file uploadergadgetwidget.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins * @addtogroup GCSPlugins GCS Plugins
* @{ * @{
* @addtogroup YModemUploader YModem Serial Uploader Plugin * @addtogroup YModemUploader YModem Serial Uploader Plugin
* @{ * @{
* @brief The YModem protocol serial uploader plugin * @brief The YModem protocol serial uploader plugin
*****************************************************************************/ *****************************************************************************/
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but * This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details. * for more details.
* *
* You should have received a copy of the GNU General Public License along * You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include "uploadergadgetwidget.h" #include "uploadergadgetwidget.h"
#define DFU_DEBUG true #define DFU_DEBUG true
UploaderGadgetWidget::UploaderGadgetWidget(QWidget *parent) : QWidget(parent) UploaderGadgetWidget::UploaderGadgetWidget(QWidget *parent) : QWidget(parent)
{ {
m_config = new Ui_UploaderWidget(); m_config = new Ui_UploaderWidget();
m_config->setupUi(this); m_config->setupUi(this);
currentStep = IAP_STATE_READY; currentStep = IAP_STATE_READY;
rescueStep = RESCUE_STEP0; rescueStep = RESCUE_STEP0;
resetOnly=false; resetOnly=false;
dfu = NULL; dfu = NULL;
// Listen to autopilot connection events // Listen to autopilot connection events
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
TelemetryManager* telMngr = pm->getObject<TelemetryManager>(); TelemetryManager* telMngr = pm->getObject<TelemetryManager>();
connect(telMngr, SIGNAL(connected()), this, SLOT(onAutopilotConnect())); connect(telMngr, SIGNAL(connected()), this, SLOT(onAutopilotConnect()));
connect(telMngr, SIGNAL(disconnected()), this, SLOT(onAutopilotDisconnect())); connect(telMngr, SIGNAL(disconnected()), this, SLOT(onAutopilotDisconnect()));
// Note: remove listening to the connection manager, it overlaps with // Note: remove listening to the connection manager, it overlaps with
// listening to the telemetry manager, we should only listen to one, not both. // listening to the telemetry manager, we should only listen to one, not both.
// Also listen to disconnect actions from the user: // Also listen to disconnect actions from the user:
// Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager(); // Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
// connect(cm, SIGNAL(deviceDisconnected()), this, SLOT(onAutopilotDisconnect())); // connect(cm, SIGNAL(deviceDisconnected()), this, SLOT(onAutopilotDisconnect()));
connect(m_config->haltButton, SIGNAL(clicked()), this, SLOT(goToBootloader())); connect(m_config->haltButton, SIGNAL(clicked()), this, SLOT(goToBootloader()));
connect(m_config->resetButton, SIGNAL(clicked()), this, SLOT(systemReset())); connect(m_config->resetButton, SIGNAL(clicked()), this, SLOT(systemReset()));
connect(m_config->bootButton, SIGNAL(clicked()), this, SLOT(systemBoot())); connect(m_config->bootButton, SIGNAL(clicked()), this, SLOT(systemBoot()));
connect(m_config->rescueButton, SIGNAL(clicked()), this, SLOT(systemRescue())); connect(m_config->rescueButton, SIGNAL(clicked()), this, SLOT(systemRescue()));
getSerialPorts(); getSerialPorts();
QIcon rbi; QIcon rbi;
rbi.addFile(QString(":uploader/images/view-refresh.svg")); rbi.addFile(QString(":uploader/images/view-refresh.svg"));
m_config->refreshPorts->setIcon(rbi); m_config->refreshPorts->setIcon(rbi);
connect(m_config->refreshPorts, SIGNAL(clicked()), this, SLOT(getSerialPorts())); connect(m_config->refreshPorts, SIGNAL(clicked()), this, SLOT(getSerialPorts()));
} }
bool sortPorts(const QextPortInfo &s1,const QextPortInfo &s2) bool sortPorts(const QextPortInfo &s1,const QextPortInfo &s2)
{ {
return s1.portName<s2.portName; return s1.portName<s2.portName;
} }
/** /**
Gets the list of serial ports Gets the list of serial ports
*/ */
void UploaderGadgetWidget::getSerialPorts() void UploaderGadgetWidget::getSerialPorts()
{ {
QStringList list; QStringList list;
// Populate the telemetry combo box: // Populate the telemetry combo box:
m_config->telemetryLink->clear(); m_config->telemetryLink->clear();
list.append(QString("USB")); list.append(QString("USB"));
QList<QextPortInfo> ports = QextSerialEnumerator::getPorts(); QList<QextPortInfo> ports = QextSerialEnumerator::getPorts();
//sort the list by port number (nice idea from PT_Dreamer :)) //sort the list by port number (nice idea from PT_Dreamer :))
qSort(ports.begin(), ports.end(),sortPorts); qSort(ports.begin(), ports.end(),sortPorts);
foreach( QextPortInfo port, ports ) { foreach( QextPortInfo port, ports ) {
list.append(port.friendName); list.append(port.friendName);
} }
m_config->telemetryLink->addItems(list); m_config->telemetryLink->addItems(list);
} }
QString UploaderGadgetWidget::getPortDevice(const QString &friendName) QString UploaderGadgetWidget::getPortDevice(const QString &friendName)
{ {
QList<QextPortInfo> ports = QextSerialEnumerator::getPorts(); QList<QextPortInfo> ports = QextSerialEnumerator::getPorts();
foreach( QextPortInfo port, ports ) { foreach( QextPortInfo port, ports ) {
if(port.friendName == friendName) if(port.friendName == friendName)
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
return port.portName; return port.portName;
#else #else
return port.physName; return port.physName;
#endif #endif
} }
return ""; return "";
} }
/** /**
Enables widget buttons if autopilot connected Enables widget buttons if autopilot connected
*/ */
void UploaderGadgetWidget::onAutopilotConnect(){ void UploaderGadgetWidget::onAutopilotConnect(){
m_config->haltButton->setEnabled(true); m_config->haltButton->setEnabled(true);
m_config->resetButton->setEnabled(true); m_config->resetButton->setEnabled(true);
m_config->bootButton->setEnabled(false); m_config->bootButton->setEnabled(false);
m_config->rescueButton->setEnabled(false); m_config->rescueButton->setEnabled(false);
m_config->telemetryLink->setEnabled(false); m_config->telemetryLink->setEnabled(false);
} }
/** /**
Enables widget buttons if autopilot connected Enables widget buttons if autopilot connected
*/ */
void UploaderGadgetWidget::onAutopilotDisconnect(){ void UploaderGadgetWidget::onAutopilotDisconnect(){
m_config->haltButton->setEnabled(false); m_config->haltButton->setEnabled(false);
m_config->resetButton->setEnabled(false); m_config->resetButton->setEnabled(false);
m_config->bootButton->setEnabled(true); m_config->bootButton->setEnabled(true);
if (currentStep == IAP_STATE_BOOTLOADER) { if (currentStep == IAP_STATE_BOOTLOADER) {
m_config->rescueButton->setEnabled(false); m_config->rescueButton->setEnabled(false);
m_config->telemetryLink->setEnabled(false); m_config->telemetryLink->setEnabled(false);
} else { } else {
m_config->rescueButton->setEnabled(true); m_config->rescueButton->setEnabled(true);
m_config->telemetryLink->setEnabled(true); m_config->telemetryLink->setEnabled(true);
} }
} }
/** /**
Tell the mainboard to go to bootloader: Tell the mainboard to go to bootloader:
- Send the relevant IAP commands - Send the relevant IAP commands
- setup callback for MoBo acknowledge - setup callback for MoBo acknowledge
*/ */
void UploaderGadgetWidget::goToBootloader(UAVObject* callerObj, bool success) void UploaderGadgetWidget::goToBootloader(UAVObject* callerObj, bool success)
{ {
Q_UNUSED(callerObj); Q_UNUSED(callerObj);
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>(); UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
UAVObject *fwIAP = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("FirmwareIAPObj"))); UAVObject *fwIAP = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("FirmwareIAPObj")));
switch (currentStep) { switch (currentStep) {
case IAP_STATE_READY: case IAP_STATE_READY:
getSerialPorts(); // Useful in case a new serial port appeared since the initial list, getSerialPorts(); // Useful in case a new serial port appeared since the initial list,
// otherwise we won't find it when we stop the board. // otherwise we won't find it when we stop the board.
// The board is running, send the 1st IAP Reset order: // The board is running, send the 1st IAP Reset order:
fwIAP->getField("Command")->setValue("1122"); fwIAP->getField("Command")->setValue("1122");
connect(fwIAP,SIGNAL(transactionCompleted(UAVObject*,bool)),this,SLOT(goToBootloader(UAVObject*, bool))); connect(fwIAP,SIGNAL(transactionCompleted(UAVObject*,bool)),this,SLOT(goToBootloader(UAVObject*, bool)));
currentStep = IAP_STATE_STEP_1; currentStep = IAP_STATE_STEP_1;
clearLog(); clearLog();
log(QString("IAP Step 1")); log(QString("IAP Step 1"));
fwIAP->updated(); fwIAP->updated();
break; break;
case IAP_STATE_STEP_1: case IAP_STATE_STEP_1:
if (!success) { if (!success) {
log(QString("Oops, failure step 1")); log(QString("Oops, failure step 1"));
log("Reset did NOT happen"); log("Reset did NOT happen");
currentStep = IAP_STATE_READY; currentStep = IAP_STATE_READY;
disconnect(fwIAP, SIGNAL(transactionCompleted(UAVObject*,bool)),this,SLOT(goToBootloader(UAVObject*, bool))); disconnect(fwIAP, SIGNAL(transactionCompleted(UAVObject*,bool)),this,SLOT(goToBootloader(UAVObject*, bool)));
break; break;
} }
delay::msleep(600); delay::msleep(600);
fwIAP->getField("Command")->setValue("2233"); fwIAP->getField("Command")->setValue("2233");
currentStep = IAP_STATE_STEP_2; currentStep = IAP_STATE_STEP_2;
log(QString("IAP Step 2")); log(QString("IAP Step 2"));
fwIAP->updated(); fwIAP->updated();
break; break;
case IAP_STATE_STEP_2: case IAP_STATE_STEP_2:
if (!success) { if (!success) {
log(QString("Oops, failure step 2")); log(QString("Oops, failure step 2"));
log("Reset did NOT happen"); log("Reset did NOT happen");
currentStep = IAP_STATE_READY; currentStep = IAP_STATE_READY;
disconnect(fwIAP, SIGNAL(transactionCompleted(UAVObject*,bool)),this,SLOT(goToBootloader(UAVObject*, bool))); disconnect(fwIAP, SIGNAL(transactionCompleted(UAVObject*,bool)),this,SLOT(goToBootloader(UAVObject*, bool)));
break; break;
} }
delay::msleep(600); delay::msleep(600);
fwIAP->getField("Command")->setValue("3344"); fwIAP->getField("Command")->setValue("3344");
currentStep = IAP_STEP_RESET; currentStep = IAP_STEP_RESET;
log(QString("IAP Step 3")); log(QString("IAP Step 3"));
fwIAP->updated(); fwIAP->updated();
break; break;
case IAP_STEP_RESET: case IAP_STEP_RESET:
{ {
currentStep = IAP_STATE_READY; currentStep = IAP_STATE_READY;
if (!success) { if (!success) {
log("Oops, failure step 3"); log("Oops, failure step 3");
log("Reset did NOT happen"); log("Reset did NOT happen");
disconnect(fwIAP, SIGNAL(transactionCompleted(UAVObject*,bool)),this,SLOT(goToBootloader(UAVObject*, bool))); disconnect(fwIAP, SIGNAL(transactionCompleted(UAVObject*,bool)),this,SLOT(goToBootloader(UAVObject*, bool)));
break; break;
} }
// The board is now reset: we have to disconnect telemetry // The board is now reset: we have to disconnect telemetry
Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager(); Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
QString dli = cm->getCurrentDevice().devName; QString dli = cm->getCurrentDevice().devName;
QString dlj = cm->getCurrentDevice().displayedName; QString dlj = cm->getCurrentDevice().displayedName;
cm->disconnectDevice(); cm->disconnectDevice();
// Tell connections to stop their polling threads: otherwise it will mess up DFU // Tell connections to stop their polling threads: otherwise it will mess up DFU
cm->suspendPolling(); cm->suspendPolling();
log("Board Halt"); log("Board Halt");
m_config->boardStatus->setText("Bootloader"); m_config->boardStatus->setText("Bootloader");
if (dlj.startsWith("USB")) if (dlj.startsWith("USB"))
m_config->telemetryLink->setCurrentIndex(m_config->telemetryLink->findText("USB")); m_config->telemetryLink->setCurrentIndex(m_config->telemetryLink->findText("USB"));
else else
m_config->telemetryLink->setCurrentIndex(m_config->telemetryLink->findText(dli)); m_config->telemetryLink->setCurrentIndex(m_config->telemetryLink->findText(dli));
disconnect(fwIAP, SIGNAL(transactionCompleted(UAVObject*,bool)),this,SLOT(goToBootloader(UAVObject*, bool))); disconnect(fwIAP, SIGNAL(transactionCompleted(UAVObject*,bool)),this,SLOT(goToBootloader(UAVObject*, bool)));
currentStep = IAP_STATE_BOOTLOADER; currentStep = IAP_STATE_BOOTLOADER;
// Tell the mainboard to get into bootloader state: // Tell the mainboard to get into bootloader state:
log("Detecting devices, please wait 5 seconds..."); log("Detecting devices, please wait 5 seconds...");
this->repaint(); this->repaint();
delay::msleep(5100); // Required to let the board(s) settle delay::msleep(5100); // Required to let the board(s) settle
if (!dfu) { if (!dfu) {
if (dlj.startsWith("USB")) if (dlj.startsWith("USB"))
dfu = new DFUObject(DFU_DEBUG, false, QString()); dfu = new DFUObject(DFU_DEBUG, false, QString());
else else
dfu = new DFUObject(DFU_DEBUG,true, getPortDevice(dli)); dfu = new DFUObject(DFU_DEBUG,true, getPortDevice(dli));
} }
if (!dfu->ready()) if (!dfu->ready())
{ {
log("Could not enter DFU mode."); log("Could not enter DFU mode.");
delete dfu; delete dfu;
dfu = NULL; dfu = NULL;
cm->resumePolling(); cm->resumePolling();
return; return;
} }
dfu->AbortOperation(); dfu->AbortOperation();
if(!dfu->enterDFU(0)) if(!dfu->enterDFU(0))
{ {
log("Could not enter DFU mode."); log("Could not enter DFU mode.");
delete dfu; delete dfu;
dfu = NULL; dfu = NULL;
cm->resumePolling(); cm->resumePolling();
return; return;
} }
//dfu.StatusRequest(); //dfu.StatusRequest();
dfu->findDevices(); dfu->findDevices();
log(QString("Found ") + QString::number(dfu->numberOfDevices) + QString(" device(s).")); log(QString("Found ") + QString::number(dfu->numberOfDevices) + QString(" device(s)."));
if (dfu->numberOfDevices < 0 || dfu->numberOfDevices > 3) { if (dfu->numberOfDevices < 0 || dfu->numberOfDevices > 3) {
log("Inconsistent number of devices! Aborting"); log("Inconsistent number of devices! Aborting");
delete dfu; delete dfu;
dfu = NULL; dfu = NULL;
cm->resumePolling(); cm->resumePolling();
return; return;
} }
// Delete all previous tabs: // Delete all previous tabs:
while (m_config->systemElements->count()) { while (m_config->systemElements->count()) {
QWidget *qw = m_config->systemElements->widget(0); QWidget *qw = m_config->systemElements->widget(0);
m_config->systemElements->removeTab(0); m_config->systemElements->removeTab(0);
delete qw; delete qw;
} }
for(int i=0;i<dfu->numberOfDevices;i++) { for(int i=0;i<dfu->numberOfDevices;i++) {
deviceWidget* dw = new deviceWidget(this); deviceWidget* dw = new deviceWidget(this);
dw->setDeviceID(i); dw->setDeviceID(i);
dw->setDfu(dfu); dw->setDfu(dfu);
dw->populate(); dw->populate();
m_config->systemElements->addTab(dw, QString("Device") + QString::number(i)); m_config->systemElements->addTab(dw, QString("Device") + QString::number(i));
} }
/* /*
m_config->haltButton->setEnabled(false); m_config->haltButton->setEnabled(false);
m_config->resetButton->setEnabled(false); m_config->resetButton->setEnabled(false);
m_config->bootButton->setEnabled(true); m_config->bootButton->setEnabled(true);
m_config->telemetryLink->setEnabled(false); m_config->telemetryLink->setEnabled(false);
m_config->rescueButton->setEnabled(false); m_config->rescueButton->setEnabled(false);
*/ */
if (resetOnly) { if (resetOnly) {
resetOnly=false; resetOnly=false;
delay::msleep(3500); delay::msleep(3500);
systemBoot(); systemBoot();
break; break;
} }
} }
break; break;
case IAP_STATE_BOOTLOADER: case IAP_STATE_BOOTLOADER:
// We should never end up here anyway. // We should never end up here anyway.
break; break;
} }
} }
/** /**
Tell the mainboard to reset: Tell the mainboard to reset:
- Send the relevant IAP commands - Send the relevant IAP commands
- setup callback for MoBo acknowledge - setup callback for MoBo acknowledge
*/ */
void UploaderGadgetWidget::systemReset() void UploaderGadgetWidget::systemReset()
{ {
resetOnly = true; resetOnly = true;
if (dfu) { if (dfu) {
delete dfu; delete dfu;
dfu = NULL; dfu = NULL;
} }
m_config->textBrowser->clear(); m_config->textBrowser->clear();
log("Board Reset initiated."); log("Board Reset initiated.");
goToBootloader(); goToBootloader();
} }
/** /**
Tells the system to boot (from Bootloader state) Tells the system to boot (from Bootloader state)
*/ */
void UploaderGadgetWidget::systemBoot() void UploaderGadgetWidget::systemBoot()
{ {
clearLog(); clearLog();
m_config->bootButton->setEnabled(false); m_config->bootButton->setEnabled(false);
// Suspend telemety & polling in case it is not done yet // Suspend telemety & polling in case it is not done yet
Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager(); Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
cm->disconnectDevice(); cm->disconnectDevice();
cm->suspendPolling(); cm->suspendPolling();
QString devName = m_config->telemetryLink->currentText(); QString devName = m_config->telemetryLink->currentText();
log("Attempting to boot the system through " + devName + "."); log("Attempting to boot the system through " + devName + ".");
repaint(); repaint();
if (!dfu) { if (!dfu) {
if (devName == "USB") if (devName == "USB")
dfu = new DFUObject(DFU_DEBUG, false, QString()); dfu = new DFUObject(DFU_DEBUG, false, QString());
else else
dfu = new DFUObject(DFU_DEBUG,true,getPortDevice(devName)); dfu = new DFUObject(DFU_DEBUG,true,getPortDevice(devName));
} }
dfu->AbortOperation(); dfu->AbortOperation();
if(!dfu->enterDFU(0)) if(!dfu->enterDFU(0))
{ {
log("Could not enter DFU mode."); log("Could not enter DFU mode.");
delete dfu; delete dfu;
dfu = NULL; dfu = NULL;
m_config->bootButton->setEnabled(true); m_config->bootButton->setEnabled(true);
return; return;
} }
log("Booting system..."); log("Booting system...");
dfu->JumpToApp(); dfu->JumpToApp();
// Restart the polling thread // Restart the polling thread
cm->resumePolling(); cm->resumePolling();
m_config->bootButton->setEnabled(true); m_config->bootButton->setEnabled(true);
m_config->rescueButton->setEnabled(true); m_config->rescueButton->setEnabled(true);
m_config->telemetryLink->setEnabled(true); m_config->telemetryLink->setEnabled(true);
m_config->boardStatus->setText("Running"); m_config->boardStatus->setText("Running");
if (currentStep == IAP_STATE_BOOTLOADER ) { if (currentStep == IAP_STATE_BOOTLOADER ) {
// Freeze the tabs, they are not useful anymore and their buttons // Freeze the tabs, they are not useful anymore and their buttons
// will cause segfaults or weird stuff if we use them. // will cause segfaults or weird stuff if we use them.
for (int i=0; i< m_config->systemElements->count(); i++) { for (int i=0; i< m_config->systemElements->count(); i++) {
deviceWidget *qw = (deviceWidget*)m_config->systemElements->widget(i); deviceWidget *qw = (deviceWidget*)m_config->systemElements->widget(i);
qw->freeze(); qw->freeze();
} }
} }
currentStep = IAP_STATE_READY; currentStep = IAP_STATE_READY;
log("You can now reconnect telemetry..."); log("You can now reconnect telemetry...");
delete dfu; // Frees up the USB/Serial port too delete dfu; // Frees up the USB/Serial port too
dfu = NULL; dfu = NULL;
} }
/** /**
Attempt a guided procedure to put both boards in BL mode when Attempt a guided procedure to put both boards in BL mode when
the system is not bootable the system is not bootable
*/ */
void UploaderGadgetWidget::systemRescue() void UploaderGadgetWidget::systemRescue()
{ {
Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager(); Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
switch (rescueStep) { switch (rescueStep) {
case RESCUE_STEP0: { case RESCUE_STEP0: {
cm->disconnectDevice(); cm->disconnectDevice();
// stop the polling thread: otherwise it will mess up DFU // stop the polling thread: otherwise it will mess up DFU
cm->suspendPolling(); cm->suspendPolling();
// Delete all previous tabs: // Delete all previous tabs:
while (m_config->systemElements->count()) { while (m_config->systemElements->count()) {
QWidget *qw = m_config->systemElements->widget(0); QWidget *qw = m_config->systemElements->widget(0);
m_config->systemElements->removeTab(0); m_config->systemElements->removeTab(0);
delete qw; delete qw;
} }
// Existing DFU objects will have a handle over USB and will // Existing DFU objects will have a handle over USB and will
// disturb everything for the rescue process: // disturb everything for the rescue process:
if (dfu) { if (dfu) {
delete dfu; delete dfu;
dfu = NULL; dfu = NULL;
} }
// Now we're good to go: // Now we're good to go:
clearLog(); clearLog();
log("**********************************************************"); log("**********************************************************");
log("** Follow those instructions to attempt a system rescue **"); log("** Follow those instructions to attempt a system rescue **");
log("**********************************************************"); log("**********************************************************");
log("You will be prompted to first connect USB, then system power"); log("You will be prompted to first connect USB, then system power");
log ("Connect USB in 2 seconds..."); log ("Connect USB in 2 seconds...");
rescueStep = RESCUE_STEP1; rescueStep = RESCUE_STEP1;
QTimer::singleShot(1000, this, SLOT(systemRescue())); QTimer::singleShot(1000, this, SLOT(systemRescue()));
} }
break; break;
case RESCUE_STEP1: case RESCUE_STEP1:
rescueStep = RESCUE_STEP2; rescueStep = RESCUE_STEP2;
log (" ...1..."); log (" ...1...");
QTimer::singleShot(1000, this, SLOT(systemRescue())); QTimer::singleShot(1000, this, SLOT(systemRescue()));
break; break;
case RESCUE_STEP2: case RESCUE_STEP2:
rescueStep = RESCUE_STEP3; rescueStep = RESCUE_STEP3;
log(" ...Now!"); log(" ...Now!");
QTimer::singleShot(1000, this, SLOT(systemRescue())); QTimer::singleShot(1000, this, SLOT(systemRescue()));
break; break;
case RESCUE_STEP3: case RESCUE_STEP3:
log("... Detecting First Board..."); log("... Detecting First Board...");
repaint(); repaint();
dfu = new DFUObject(DFU_DEBUG, false, QString()); dfu = new DFUObject(DFU_DEBUG, false, QString());
dfu->AbortOperation(); dfu->AbortOperation();
if(!dfu->enterDFU(0)) if(!dfu->enterDFU(0))
{ {
rescueStep = RESCUE_STEP0; rescueStep = RESCUE_STEP0;
log("Could not enter DFU mode."); log("Could not enter DFU mode.");
delete dfu; delete dfu;
dfu = NULL; dfu = NULL;
cm->resumePolling(); cm->resumePolling();
return; return;
} }
if(!dfu->findDevices() || (dfu->numberOfDevices != 1)) if(!dfu->findDevices() || (dfu->numberOfDevices != 1))
{ {
rescueStep = RESCUE_STEP0; rescueStep = RESCUE_STEP0;
log("Could not detect a board, aborting!"); log("Could not detect a board, aborting!");
delete dfu; delete dfu;
dfu = NULL; dfu = NULL;
cm->resumePolling(); cm->resumePolling();
return; return;
} }
rescueStep = RESCUE_POWER1; rescueStep = RESCUE_POWER1;
log("Connect Power in 2 second..."); log("Connect Power in 2 second...");
QTimer::singleShot(1000, this, SLOT(systemRescue())); QTimer::singleShot(1000, this, SLOT(systemRescue()));
break; break;
case RESCUE_POWER1: case RESCUE_POWER1:
rescueStep = RESCUE_POWER2; rescueStep = RESCUE_POWER2;
log(" ...1..."); log(" ...1...");
QTimer::singleShot(1000, this, SLOT(systemRescue())); QTimer::singleShot(1000, this, SLOT(systemRescue()));
break; break;
case RESCUE_POWER2: case RESCUE_POWER2:
log("... NOW!\n***\nWaiting..."); log("... NOW!\n***\nWaiting...");
rescueStep = RESCUE_DETECT; rescueStep = RESCUE_DETECT;
QTimer::singleShot(5000, this, SLOT(systemRescue())); QTimer::singleShot(5000, this, SLOT(systemRescue()));
break; break;
case RESCUE_DETECT: case RESCUE_DETECT:
rescueStep = RESCUE_STEP0; rescueStep = RESCUE_STEP0;
log("Detecting second board..."); log("Detecting second board...");
repaint(); repaint();
if(!dfu->findDevices()) if(!dfu->findDevices())
{ {
log("Could not detect any board, aborting!"); log("Could not detect any board, aborting!");
delete dfu; delete dfu;
dfu = NULL; dfu = NULL;
cm->resumePolling(); cm->resumePolling();
return; return;
} }
log(QString("Found ") + QString::number(dfu->numberOfDevices) + QString(" device(s).")); log(QString("Found ") + QString::number(dfu->numberOfDevices) + QString(" device(s)."));
if (dfu->numberOfDevices > 5) { if (dfu->numberOfDevices > 5) {
log("Inconsistent number of devices, aborting!"); log("Inconsistent number of devices, aborting!");
delete dfu; delete dfu;
dfu = NULL; dfu = NULL;
cm->resumePolling(); cm->resumePolling();
return; return;
} }
for(int i=0;i<dfu->numberOfDevices;i++) { for(int i=0;i<dfu->numberOfDevices;i++) {
deviceWidget* dw = new deviceWidget(this); deviceWidget* dw = new deviceWidget(this);
dw->setDeviceID(i); dw->setDeviceID(i);
dw->setDfu(dfu); dw->setDfu(dfu);
dw->populate(); dw->populate();
m_config->systemElements->addTab(dw, QString("Device") + QString::number(i)); m_config->systemElements->addTab(dw, QString("Device") + QString::number(i));
} }
m_config->haltButton->setEnabled(false); m_config->haltButton->setEnabled(false);
m_config->resetButton->setEnabled(false); m_config->resetButton->setEnabled(false);
//m_config->bootButton->setEnabled(true); //m_config->bootButton->setEnabled(true);
m_config->rescueButton->setEnabled(false); m_config->rescueButton->setEnabled(false);
currentStep = IAP_STATE_BOOTLOADER; // So that we can boot from the GUI afterwards. currentStep = IAP_STATE_BOOTLOADER; // So that we can boot from the GUI afterwards.
} }
} }
/** /**
Update log entry Update log entry
*/ */
void UploaderGadgetWidget::log(QString str) void UploaderGadgetWidget::log(QString str)
{ {
m_config->textBrowser->append(str); m_config->textBrowser->append(str);
m_config->textBrowser->repaint(); m_config->textBrowser->repaint();
} }
void UploaderGadgetWidget::clearLog() void UploaderGadgetWidget::clearLog()
{ {
m_config->textBrowser->clear(); m_config->textBrowser->clear();
} }
UploaderGadgetWidget::~UploaderGadgetWidget() /**
{ * Remove all the device widgets...
*/
} UploaderGadgetWidget::~UploaderGadgetWidget()
{
while (m_config->systemElements->count()) {
/** QWidget *qw = m_config->systemElements->widget(0);
Shows a message box with an error string. m_config->systemElements->removeTab(0);
delete qw;
@param errorString The error string to display. }
}
@param errorNumber Not used
*/ /**
void UploaderGadgetWidget::error(QString errorString, int errorNumber) Shows a message box with an error string.
{
Q_UNUSED(errorNumber); @param errorString The error string to display.
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Critical); @param errorNumber Not used
msgBox.setText(errorString);
msgBox.exec(); */
m_config->boardStatus->setText(errorString); void UploaderGadgetWidget::error(QString errorString, int errorNumber)
} {
/** Q_UNUSED(errorNumber);
Shows a message box with an information string. QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Critical);
@param infoString The information string to display. msgBox.setText(errorString);
msgBox.exec();
@param infoNumber Not used m_config->boardStatus->setText(errorString);
}
*/ /**
void UploaderGadgetWidget::info(QString infoString, int infoNumber) Shows a message box with an information string.
{
Q_UNUSED(infoNumber); @param infoString The information string to display.
m_config->boardStatus->setText(infoString);
} @param infoNumber Not used
*/
void UploaderGadgetWidget::info(QString infoString, int infoNumber)
{
Q_UNUSED(infoNumber);
m_config->boardStatus->setText(infoString);
}