2010-04-10 02:09:53 +02:00
|
|
|
/**
|
|
|
|
******************************************************************************
|
|
|
|
*
|
2010-04-14 23:23:13 +02:00
|
|
|
* @file uploadergadgetwidget.cpp
|
2010-04-10 02:09:53 +02:00
|
|
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
2010-07-16 18:01:53 +02:00
|
|
|
* @addtogroup GCSPlugins GCS Plugins
|
2010-04-10 02:09:53 +02:00
|
|
|
* @{
|
2010-07-16 18:01:53 +02:00
|
|
|
* @addtogroup YModemUploader YModem Serial Uploader Plugin
|
|
|
|
* @{
|
|
|
|
* @brief The YModem protocol serial uploader plugin
|
2010-04-10 02:09:53 +02:00
|
|
|
*****************************************************************************/
|
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*/
|
|
|
|
#include "uploadergadgetwidget.h"
|
|
|
|
|
|
|
|
UploaderGadgetWidget::UploaderGadgetWidget(QWidget *parent) : QWidget(parent)
|
|
|
|
{
|
2010-10-31 23:56:31 +01:00
|
|
|
m_config = new Ui_UploaderWidget();
|
|
|
|
m_config->setupUi(this);
|
2010-11-01 15:06:33 +01:00
|
|
|
currentStep = IAP_STATE_READY;
|
|
|
|
resetOnly=false;
|
2010-04-10 02:09:53 +02:00
|
|
|
|
2010-11-01 19:15:48 +01:00
|
|
|
//m_config->systemElements->addTab((QWidget*)new deviceWidget(),QString("Device"));
|
|
|
|
|
2010-11-01 15:06:33 +01:00
|
|
|
connect(m_config->haltButton, SIGNAL(clicked()), this, SLOT(goToBootloader()));
|
|
|
|
connect(m_config->resetButton, SIGNAL(clicked()), this, SLOT(systemReset()));
|
2010-11-01 21:02:59 +01:00
|
|
|
connect(m_config->bootButton, SIGNAL(clicked()), this, SLOT(systemBoot()));
|
2010-11-01 15:06:33 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Tell the mainboard to go to bootloader:
|
|
|
|
- Send the relevant IAP commands
|
|
|
|
- setup callback for MoBo acknowledge
|
|
|
|
*/
|
|
|
|
void UploaderGadgetWidget::goToBootloader(UAVObject* callerObj, bool success)
|
|
|
|
{
|
|
|
|
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
|
|
|
|
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
|
|
|
|
UAVObject *fwIAP = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("FirmwareIAPObj")));
|
|
|
|
|
|
|
|
switch (currentStep) {
|
|
|
|
case IAP_STATE_READY:
|
|
|
|
// 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)));
|
|
|
|
currentStep = IAP_STATE_STEP_1;
|
|
|
|
fwIAP->updated();
|
2010-11-01 21:50:59 +01:00
|
|
|
clearLog();
|
2010-11-01 15:06:33 +01:00
|
|
|
log(QString("IAP Step 1"));
|
|
|
|
break;
|
|
|
|
case IAP_STATE_STEP_1:
|
|
|
|
if (!success) {
|
|
|
|
log(QString("Oops, failure step 1"));
|
2010-11-01 19:15:48 +01:00
|
|
|
log("Reset did NOT happen");
|
2010-11-01 15:06:33 +01:00
|
|
|
currentStep == IAP_STATE_READY;
|
2010-11-01 19:15:48 +01:00
|
|
|
disconnect(fwIAP, SIGNAL(transactionCompleted(UAVObject*,bool)),this,SLOT(goToBootloader(UAVObject*, bool)));
|
2010-11-01 15:06:33 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
delay::msleep(600);
|
|
|
|
fwIAP->getField("Command")->setValue("2233");
|
|
|
|
currentStep = IAP_STATE_STEP_2;
|
|
|
|
fwIAP->updated();
|
|
|
|
log(QString("IAP Step 2"));
|
|
|
|
break;
|
|
|
|
case IAP_STATE_STEP_2:
|
|
|
|
if (!success) {
|
|
|
|
log(QString("Oops, failure step 2"));
|
2010-11-01 19:15:48 +01:00
|
|
|
log("Reset did NOT happen");
|
2010-11-01 15:06:33 +01:00
|
|
|
currentStep == IAP_STATE_READY;
|
2010-11-01 19:15:48 +01:00
|
|
|
disconnect(fwIAP, SIGNAL(transactionCompleted(UAVObject*,bool)),this,SLOT(goToBootloader(UAVObject*, bool)));
|
2010-11-01 15:06:33 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
delay::msleep(600);
|
|
|
|
fwIAP->getField("Command")->setValue("3344");
|
|
|
|
currentStep = IAP_STEP_RESET;
|
|
|
|
fwIAP->updated();
|
|
|
|
log(QString("IAP Step 3"));
|
|
|
|
break;
|
|
|
|
case IAP_STEP_RESET: {
|
|
|
|
currentStep = IAP_STATE_READY;
|
|
|
|
if (success) {
|
|
|
|
log("Oops, unexpected success step 3");
|
|
|
|
log("Reset did NOT happen");
|
2010-11-01 19:15:48 +01:00
|
|
|
disconnect(fwIAP, SIGNAL(transactionCompleted(UAVObject*,bool)),this,SLOT(goToBootloader(UAVObject*, bool)));
|
2010-11-01 15:06:33 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
// The board is now reset: we have to disconnect telemetry
|
|
|
|
Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
|
|
|
|
cm->disconnectDevice();
|
2010-11-01 19:15:48 +01:00
|
|
|
log("Board Reset");
|
2010-11-01 15:06:33 +01:00
|
|
|
|
|
|
|
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
|
|
|
|
disconnect(fwIAP, SIGNAL(transactionCompleted(UAVObject*,bool)),this,SLOT(goToBootloader(UAVObject*, bool)));
|
|
|
|
if (resetOnly) {
|
|
|
|
resetOnly=false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// stop the polling thread: otherwise it will mess up DFU
|
|
|
|
RawHIDConnection *cnx = pm->getObject<RawHIDConnection>();
|
|
|
|
cnx->suspendPolling();
|
|
|
|
|
2010-11-01 19:15:48 +01:00
|
|
|
// Tell the mainboard to get into bootloader state:
|
|
|
|
log("Going into Bootloader mode...");
|
|
|
|
OP_DFU dfu(true);
|
|
|
|
dfu.AbortOperation();
|
|
|
|
if(!dfu.enterDFU(0))
|
|
|
|
{
|
|
|
|
log("Could not enter DFU mode.");
|
2010-11-01 21:50:59 +01:00
|
|
|
return;
|
2010-11-01 19:15:48 +01:00
|
|
|
}
|
2010-11-01 21:50:59 +01:00
|
|
|
m_config->boardStatus->setText("Bootloader");
|
2010-11-01 21:02:59 +01:00
|
|
|
currentStep = IAP_STATE_BOOTLOADER;
|
2010-11-01 19:15:48 +01:00
|
|
|
OP_DFU::Status ret=dfu.StatusRequest();
|
|
|
|
dfu.findDevices();
|
|
|
|
log(QString("Found ") + QString::number(dfu.numberOfDevices) + QString(" device(s)."));
|
|
|
|
// Delete all previous tabs:
|
|
|
|
for (int i=0; i< m_config->systemElements->count(); i++) {
|
|
|
|
QWidget *qw = m_config->systemElements->widget(i);
|
|
|
|
m_config->systemElements->removeTab(i);
|
|
|
|
delete qw;
|
|
|
|
}
|
|
|
|
for(int i=0;i<dfu.numberOfDevices;i++) {
|
2010-11-01 21:50:59 +01:00
|
|
|
deviceWidget* dw = new deviceWidget(this);
|
|
|
|
dw->setDeviceID(i);
|
|
|
|
dw->setDfu(&dfu);
|
|
|
|
dw->populate();
|
2010-11-01 19:15:48 +01:00
|
|
|
m_config->systemElements->addTab(dw, QString("Device") + QString::number(i));
|
|
|
|
}
|
2010-11-01 21:50:59 +01:00
|
|
|
m_config->haltButton->setEnabled(false);
|
|
|
|
m_config->resetButton->setEnabled(false);
|
2010-11-01 21:02:59 +01:00
|
|
|
m_config->bootButton->setEnabled(true);
|
2010-11-01 19:15:48 +01:00
|
|
|
}
|
2010-11-01 15:06:33 +01:00
|
|
|
}
|
2010-04-10 02:09:53 +02:00
|
|
|
}
|
2010-11-01 15:06:33 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
Tell the mainboard to reset:
|
|
|
|
- Send the relevant IAP commands
|
|
|
|
- setup callback for MoBo acknowledge
|
|
|
|
*/
|
|
|
|
void UploaderGadgetWidget::systemReset()
|
|
|
|
{
|
|
|
|
resetOnly = true;
|
|
|
|
m_config->textBrowser->clear();
|
|
|
|
log("Board Reset initiated.");
|
|
|
|
goToBootloader();
|
|
|
|
}
|
|
|
|
|
2010-11-01 21:02:59 +01:00
|
|
|
/**
|
|
|
|
Tells the system to boot (from Bootloader state)
|
|
|
|
*/
|
|
|
|
void UploaderGadgetWidget::systemBoot()
|
|
|
|
{
|
|
|
|
if (currentStep == IAP_STATE_BOOTLOADER) {
|
2010-11-01 21:50:59 +01:00
|
|
|
clearLog();
|
2010-11-01 21:02:59 +01:00
|
|
|
OP_DFU dfu(true);
|
|
|
|
dfu.AbortOperation();
|
|
|
|
if(!dfu.enterDFU(0))
|
|
|
|
{
|
|
|
|
log("Could not enter DFU mode.");
|
2010-11-01 21:50:59 +01:00
|
|
|
return;
|
2010-11-01 21:02:59 +01:00
|
|
|
}
|
|
|
|
log("Booting system...");
|
|
|
|
dfu.JumpToApp();
|
|
|
|
currentStep = IAP_STATE_READY;
|
|
|
|
// stop the polling thread: otherwise it will mess up DFU
|
|
|
|
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
|
|
|
|
RawHIDConnection *cnx = pm->getObject<RawHIDConnection>();
|
|
|
|
cnx->resumePolling();
|
|
|
|
m_config->bootButton->setEnabled(false);
|
2010-11-01 21:50:59 +01:00
|
|
|
m_config->haltButton->setEnabled(true);
|
|
|
|
m_config->resetButton->setEnabled(true);
|
|
|
|
m_config->boardStatus->setText("Running");
|
|
|
|
|
2010-11-01 21:02:59 +01:00
|
|
|
} else {
|
|
|
|
log("Not in bootloader mode!");
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2010-11-01 15:06:33 +01:00
|
|
|
/**
|
2010-11-01 21:50:59 +01:00
|
|
|
Update log entry
|
2010-11-01 15:06:33 +01:00
|
|
|
*/
|
|
|
|
void UploaderGadgetWidget::log(QString str)
|
|
|
|
{
|
|
|
|
m_config->textBrowser->append(str);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2010-11-01 21:50:59 +01:00
|
|
|
void UploaderGadgetWidget::clearLog()
|
|
|
|
{
|
|
|
|
m_config->textBrowser->clear();
|
|
|
|
}
|
|
|
|
|
2010-04-14 23:23:13 +02:00
|
|
|
//user pressed send, send file using a new thread with qymodem library
|
2010-04-10 02:09:53 +02:00
|
|
|
void UploaderGadgetWidget::send()
|
|
|
|
{
|
|
|
|
Ymodem->SendFileT(openFileNameLE->text());
|
|
|
|
}
|
2010-04-14 23:23:13 +02:00
|
|
|
//destructor !!?! do I need to delete something else?
|
2010-04-10 02:09:53 +02:00
|
|
|
UploaderGadgetWidget::~UploaderGadgetWidget()
|
|
|
|
{
|
|
|
|
delete Port;
|
|
|
|
delete Ymodem;
|
|
|
|
}
|
|
|
|
|
2010-04-14 23:23:13 +02:00
|
|
|
//from load configuration, creates a new qymodemsend class with the the port
|
|
|
|
/**
|
|
|
|
Cteates a new qymodemsend class.
|
|
|
|
|
|
|
|
@param port The serial port to use.
|
|
|
|
|
|
|
|
|
|
|
|
*/
|
2010-04-10 02:09:53 +02:00
|
|
|
void UploaderGadgetWidget::setPort(QextSerialPort* port)
|
|
|
|
{
|
2010-04-14 23:23:13 +02:00
|
|
|
|
2010-04-10 02:09:53 +02:00
|
|
|
Port=port;
|
|
|
|
Ymodem=new QymodemSend(*Port);
|
2010-04-14 23:23:13 +02:00
|
|
|
//only now can we connect this signals
|
|
|
|
//signals errors
|
2010-04-10 02:09:53 +02:00
|
|
|
connect(Ymodem,SIGNAL(Error(QString,int))
|
|
|
|
,this,SLOT(error(QString,int)));
|
2010-04-14 23:23:13 +02:00
|
|
|
//signals new information
|
2010-04-10 02:09:53 +02:00
|
|
|
connect(Ymodem,SIGNAL(Information(QString,int)),
|
|
|
|
this,SLOT(info(QString,int)));
|
2010-04-14 23:23:13 +02:00
|
|
|
//signals new percentage value
|
2010-04-10 22:29:34 +02:00
|
|
|
connect(Ymodem,SIGNAL(Percent(int)),
|
|
|
|
this,SLOT(updatePercSlot(int)));
|
2010-04-10 02:09:53 +02:00
|
|
|
}
|
2010-04-14 23:23:13 +02:00
|
|
|
/**
|
|
|
|
Updates progress bar value.
|
2010-04-10 02:09:53 +02:00
|
|
|
|
2010-04-14 23:23:13 +02:00
|
|
|
@param i New percentage value.
|
|
|
|
|
|
|
|
*/
|
2010-04-10 22:29:34 +02:00
|
|
|
void UploaderGadgetWidget::updatePercSlot(int i)
|
|
|
|
{
|
2010-04-11 01:01:59 +02:00
|
|
|
progressBar->setValue(i);
|
2010-04-10 22:29:34 +02:00
|
|
|
}
|
2010-04-14 23:23:13 +02:00
|
|
|
/**
|
|
|
|
|
|
|
|
Opens an open file dialog.
|
2010-04-10 02:09:53 +02:00
|
|
|
|
2010-04-14 23:23:13 +02:00
|
|
|
*/
|
2010-04-10 02:09:53 +02:00
|
|
|
void UploaderGadgetWidget::setOpenFileName()
|
|
|
|
{
|
|
|
|
QFileDialog::Options options;
|
|
|
|
QString selectedFilter;
|
|
|
|
QString fileName = QFileDialog::getOpenFileName(this,
|
|
|
|
tr("QFileDialog::getOpenFileName()"),
|
|
|
|
openFileNameLE->text(),
|
|
|
|
tr("All Files (*);;Text Files (*.bin)"),
|
|
|
|
&selectedFilter,
|
|
|
|
options);
|
|
|
|
if (!fileName.isEmpty()) openFileNameLE->setText(fileName);
|
|
|
|
|
|
|
|
}
|
2010-04-14 23:23:13 +02:00
|
|
|
/**
|
|
|
|
Shows a message box with an error string.
|
|
|
|
|
|
|
|
@param errorString The error string to display.
|
2010-04-10 02:09:53 +02:00
|
|
|
|
2010-04-14 23:23:13 +02:00
|
|
|
@param errorNumber Not used
|
|
|
|
|
|
|
|
*/
|
2010-04-10 02:09:53 +02:00
|
|
|
void UploaderGadgetWidget::error(QString errorString, int errorNumber)
|
|
|
|
{
|
|
|
|
QMessageBox msgBox;
|
|
|
|
msgBox.setIcon(QMessageBox::Critical);
|
|
|
|
msgBox.setText(errorString);
|
|
|
|
msgBox.exec();
|
|
|
|
status->setText(errorString);
|
|
|
|
}
|
2010-04-14 23:23:13 +02:00
|
|
|
/**
|
|
|
|
Shows a message box with an information string.
|
|
|
|
|
|
|
|
@param infoString The information string to display.
|
|
|
|
|
|
|
|
@param infoNumber Not used
|
|
|
|
|
|
|
|
*/
|
2010-04-10 02:09:53 +02:00
|
|
|
void UploaderGadgetWidget::info(QString infoString, int infoNumber)
|
|
|
|
{
|
|
|
|
status->setText(infoString);
|
|
|
|
}
|