diff --git a/ground/openpilotgcs/src/plugins/uploader/uploadergadgetwidget.cpp b/ground/openpilotgcs/src/plugins/uploader/uploadergadgetwidget.cpp index 2943bcdfd..5a4b350b2 100755 --- a/ground/openpilotgcs/src/plugins/uploader/uploadergadgetwidget.cpp +++ b/ground/openpilotgcs/src/plugins/uploader/uploadergadgetwidget.cpp @@ -33,7 +33,6 @@ UploaderGadgetWidget::UploaderGadgetWidget(QWidget *parent) : QWidget(parent) m_config = new Ui_UploaderWidget(); m_config->setupUi(this); currentStep = IAP_STATE_READY; - rescueStep = RESCUE_STEP0; resetOnly=false; dfu = NULL; @@ -393,89 +392,93 @@ void UploaderGadgetWidget::systemBoot() void UploaderGadgetWidget::systemRescue() { Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager(); - switch (rescueStep) { - case RESCUE_STEP0: { - cm->disconnectDevice(); - // stop the polling thread: otherwise it will mess up DFU - cm->suspendPolling(); - // Delete all previous tabs: - while (m_config->systemElements->count()) { - QWidget *qw = m_config->systemElements->widget(0); - m_config->systemElements->removeTab(0); - delete qw; - } - // Existing DFU objects will have a handle over USB and will - // disturb everything for the rescue process: - if (dfu) { - delete dfu; - dfu = NULL; - } - // Avoid dumb users pressing Rescue twice. It can happen. - m_config->rescueButton->setEnabled(false); - - // Now we're good to go: - clearLog(); - log("**********************************************************"); - log("** Follow those instructions to attempt a system rescue **"); - log("**********************************************************"); - log("You will be prompted to first connect USB, then system power"); - log ("Connect USB in 2 seconds..."); - rescueStep = RESCUE_STEP1; - QTimer::singleShot(1000, this, SLOT(systemRescue())); + cm->disconnectDevice(); + // stop the polling thread: otherwise it will mess up DFU + cm->suspendPolling(); + // Delete all previous tabs: + while (m_config->systemElements->count()) { + QWidget *qw = m_config->systemElements->widget(0); + m_config->systemElements->removeTab(0); + delete qw; } - break; - case RESCUE_STEP1: - rescueStep = RESCUE_STEP2; - log (" ...1..."); - QTimer::singleShot(1000, this, SLOT(systemRescue())); - break; - case RESCUE_STEP2: - rescueStep = RESCUE_STEP3; - log(" ...Now!"); - QTimer::singleShot(1000, this, SLOT(systemRescue())); - break; - case RESCUE_STEP3: - log("... Detecting First Board..."); - repaint(); - dfu = new DFUObject(DFU_DEBUG, false, QString()); - dfu->AbortOperation(); - if(!dfu->enterDFU(0)) + // Existing DFU objects will have a handle over USB and will + // disturb everything for the rescue process: + if (dfu) { + delete dfu; + dfu = NULL; + } + // Avoid dumb users pressing Rescue twice. It can happen. + m_config->rescueButton->setEnabled(false); + + // Now we're good to go: + clearLog(); + log("**********************************************************"); + log("** Follow those instructions to attempt a system rescue **"); + log("**********************************************************"); + log("You will be prompted to first connect USB, then system power"); + if(USBMonitor::instance()->availableDevices(0x20a0,-1,-1,-1).length()>0) + { + if(QMessageBox::warning(this,tr("OpenPilot Uploader"),tr("Please disconnect all openpilot boards"),QMessageBox::Ok,QMessageBox::Cancel)==QMessageBox::Cancel) { - rescueStep = RESCUE_STEP0; - log("Could not enter DFU mode."); - delete dfu; - dfu = NULL; - cm->resumePolling(); m_config->rescueButton->setEnabled(true); return; } - if(!dfu->findDevices() || (dfu->numberOfDevices != 1)) - { - rescueStep = RESCUE_STEP0; - log("Could not detect a board, aborting!"); - delete dfu; - dfu = NULL; - cm->resumePolling(); - m_config->rescueButton->setEnabled(true); - return; - } - rescueStep = RESCUE_POWER1; - log("Connect Power in 2 second..."); - log("(not required on CopterControl)"); - QTimer::singleShot(1000, this, SLOT(systemRescue())); - break; - case RESCUE_POWER1: - rescueStep = RESCUE_POWER2; - log(" ...1..."); - QTimer::singleShot(1000, this, SLOT(systemRescue())); - break; - case RESCUE_POWER2: - log("... NOW!\n***\nWaiting..."); - rescueStep = RESCUE_DETECT; - QTimer::singleShot(5000, this, SLOT(systemRescue())); - break; - case RESCUE_DETECT: - rescueStep = RESCUE_STEP0; + } + // Now we're good to go: + clearLog(); + log("**********************************************************"); + log("** Follow those instructions to attempt a system rescue **"); + log("**********************************************************"); + log("You will be prompted to first connect USB, then system power"); + pd = new QProgressDialog(tr("Please connect the board (USB only!)"), tr("Cancel"), 0, 20); + QProgressBar * bar=new QProgressBar(pd); + bar->setFormat("Timeout"); + pd->setBar(bar); + pd->setMinimumDuration(0); + pd->setRange(0,20); + connect(pd, SIGNAL(canceled()), this, SLOT(cancel())); + t = new QTimer(this); + connect(t, SIGNAL(timeout()), this, SLOT(perform())); + t->start(1000); + connect(USBMonitor::instance(), SIGNAL(deviceDiscovered(USBPortInfo)),&q, SLOT(quit())); + q.exec(); + if(!t->isActive()) + { + pd->close(); + t->stop(); + QMessageBox::warning(this,tr("Openpilot Uploader"),tr("No board connection was detected!")); + m_config->rescueButton->setEnabled(true); + return; + } + pd->close(); + t->stop(); + log("... Detecting First Board..."); + repaint(); + dfu = new DFUObject(DFU_DEBUG, false, QString()); + dfu->AbortOperation(); + if(!dfu->enterDFU(0)) + { + log("Could not enter DFU mode."); + delete dfu; + dfu = NULL; + cm->resumePolling(); + m_config->rescueButton->setEnabled(true); + return; + } + if(!dfu->findDevices() || (dfu->numberOfDevices != 1)) + { + log("Could not detect a board, aborting!"); + delete dfu; + dfu = NULL; + cm->resumePolling(); + m_config->rescueButton->setEnabled(true); + return; + } + if(QMessageBox::question(this,tr("OpenPilot Uploader"),tr("If you want to search for other boards connect power now and press Yes"),QMessageBox::Yes,QMessageBox::No)==QMessageBox::Yes) + { + log("\nWaiting..."); + QTimer::singleShot(3000, &q, SLOT(quit())); + q.exec(); log("Detecting second board..."); repaint(); if(!dfu->findDevices()) @@ -489,28 +492,42 @@ void UploaderGadgetWidget::systemRescue() m_config->rescueButton->setEnabled(true); return; } - log(QString("Found ") + QString::number(dfu->numberOfDevices) + QString(" device(s).")); - if (dfu->numberOfDevices > 5) { - log("Inconsistent number of devices, aborting!"); - delete dfu; - dfu = NULL; - cm->resumePolling(); - m_config->rescueButton->setEnabled(true); - return; - } - for(int i=0;inumberOfDevices;i++) { - deviceWidget* dw = new deviceWidget(this); - dw->setDeviceID(i); - dw->setDfu(dfu); - 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->rescueButton->setEnabled(false); - currentStep = IAP_STATE_BOOTLOADER; // So that we can boot from the GUI afterwards. } + log(QString("Found ") + QString::number(dfu->numberOfDevices) + QString(" device(s).")); + if (dfu->numberOfDevices > 5) { + log("Inconsistent number of devices, aborting!"); + delete dfu; + dfu = NULL; + cm->resumePolling(); + m_config->rescueButton->setEnabled(true); + return; + } + for(int i=0;inumberOfDevices;i++) { + deviceWidget* dw = new deviceWidget(this); + dw->setDeviceID(i); + dw->setDfu(dfu); + 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->rescueButton->setEnabled(false); + currentStep = IAP_STATE_BOOTLOADER; // So that we can boot from the GUI afterwards. +} +void UploaderGadgetWidget::perform() +{ + if(pd->value()==19) + { + t->stop(); + q.exit(); + } + pd->setValue(pd->value()+1); +} +void UploaderGadgetWidget::cancel() +{ + t->stop(); + q.exit(); } /** @@ -538,6 +555,11 @@ UploaderGadgetWidget::~UploaderGadgetWidget() m_config->systemElements->removeTab(0); delete qw; } + if (pd) + delete pd; + if (t) + delete t; + } diff --git a/ground/openpilotgcs/src/plugins/uploader/uploadergadgetwidget.h b/ground/openpilotgcs/src/plugins/uploader/uploadergadgetwidget.h index 7c7bae19e..b629ad605 100755 --- a/ground/openpilotgcs/src/plugins/uploader/uploadergadgetwidget.h +++ b/ground/openpilotgcs/src/plugins/uploader/uploadergadgetwidget.h @@ -53,6 +53,7 @@ #include #include +#include using namespace OP_DFU; @@ -64,7 +65,6 @@ public: UploaderGadgetWidget(QWidget *parent = 0); ~UploaderGadgetWidget(); typedef enum { IAP_STATE_READY, IAP_STATE_STEP_1, IAP_STATE_STEP_2, IAP_STEP_RESET, IAP_STATE_BOOTLOADER} IAPStep; - typedef enum { RESCUE_STEP0, RESCUE_STEP1, RESCUE_STEP2, RESCUE_STEP3, RESCUE_POWER1, RESCUE_POWER2, RESCUE_DETECT } RescueStep; void log(QString str); public slots: @@ -75,13 +75,13 @@ private: Ui_UploaderWidget *m_config; DFUObject *dfu; IAPStep currentStep; - RescueStep rescueStep; bool resetOnly; void clearLog(); QString getPortDevice(const QString &friendName); - + QProgressDialog* pd; + QTimer* t; QLineEdit* openFileNameLE; - + QEventLoop q; private slots: void error(QString errorString,int errorNumber); void info(QString infoString,int infoNumber); @@ -90,6 +90,8 @@ private slots: void systemBoot(); void systemRescue(); void getSerialPorts(); + void perform(); + void cancel(); };