Commit 77b486be authored by Lorenz Meier's avatar Lorenz Meier

Added PX4 firmware uploader skeleton, operational on all levels, needs full protocol implementation

No related merge requests found
This diff is collapsed.
#include "PX4FirmwareUpgradeWorker.h"
#include <SerialLink.h>
#include <QGC.h>
#include <QDebug>
// protocol bytes
#define INSYNC 0x12
#define EOC 0x20
// reply bytes
#define OK 0x10
#define FAILED 0x11
#define INVALID 0x13 // rev3+
// command bytes
#define NOP 0x00 // guaranteed to be discarded by the bootloader
#define GET_SYNC 0x21
#define GET_DEVICE 0x22
#define CHIP_ERASE 0x23
#define CHIP_VERIFY 0x24 // rev2 only
#define PROG_MULTI 0x27
#define READ_MULTI 0x28 // rev2 only
#define GET_CRC 0x29 // rev3+
#define REBOOT 0x30
#define INFO_BL_REV 1 // bootloader protocol revision
#define BL_REV_MIN 2 // minimum supported bootloader protocol
#define BL_REV_MAX 3 // maximum supported bootloader protocol
#define INFO_BOARD_ID 2 // board type
#define INFO_BOARD_REV 3 // board revision
#define INFO_FLASH_SIZE 4 // max firmware size in bytes
PX4FirmwareUpgradeWorker::PX4FirmwareUpgradeWorker(QObject *parent) :
QObject(parent),
link(NULL)
{
}
PX4FirmwareUpgradeWorker* PX4FirmwareUpgradeWorker::putWorkerInThread(QObject *parent)
{
PX4FirmwareUpgradeWorker *worker = new PX4FirmwareUpgradeWorker;
QThread *workerThread = new QThread(parent);
connect(workerThread, SIGNAL(started()), worker, SLOT(startContinousScan()));
connect(workerThread, SIGNAL(finished()), worker, SLOT(deleteLater()));
worker->moveToThread(workerThread);
// Starts an event loop, and emits workerThread->started()
workerThread->start();
}
bool PX4FirmwareUpgradeWorker::startContinousScan()
{
while (true) {
if (detect()) {
break;
}
}
return true;
}
bool PX4FirmwareUpgradeWorker::detect()
{
if (!link)
{
link = new SerialLink("", 921600);
connect(link, SIGNAL(bytesReceived(LinkInterface*,QByteArray)), this, SLOT(receiveBytes(LinkInterface*,QByteArray)));
}
// Get a list of ports
QVector<QString>* ports = link->getCurrentPorts();
// Scan
for (int i = 0; i < ports->size(); i++)
{
// Ignore known wrong link names
if (ports->at(i).contains("Bluetooth")) {
continue;
}
link->setPortName(ports->at(i));
// Open port and talk to it
link->connect();
char buf[2] = { GET_SYNC, EOC };
if (!link->isConnected()) {
continue;
}
// Send sync request
insync = false;
link->writeBytes(buf, 2);
// Wait for response
QGC::SLEEP::msleep(20);
if (insync)
emit validPortFound(ports->at(i));
break;
}
if (insync) {
return true;
} else {
return false;
}
//ui.portName->setCurrentIndex(ui.baudRate->findText(QString("%1").arg(this->link->getPortName())));
// Set port
// Load current link config
}
void PX4FirmwareUpgradeWorker::receiveBytes(LinkInterface* link, QByteArray b)
{
for (int position = 0; position < b.size(); position++) {
qDebug() << "BYTES";
qDebug() << std::hex << (char)(b[position]);
if (((const char)b[position]) == INSYNC)
{
qDebug() << "SYNC";
insync = true;
emit detectionStatusChanged("Found PX4 board");
}
}
printf("\n");
}
bool PX4FirmwareUpgradeWorker::upgrade(const QString &filename)
{
}
#ifndef PX4FIRMWAREUPGRADEWORKER_H
#define PX4FIRMWAREUPGRADEWORKER_H
#include <QObject>
#include <SerialLink.h>
class PX4FirmwareUpgradeWorker : public QObject
{
Q_OBJECT
public:
explicit PX4FirmwareUpgradeWorker(QObject *parent = 0);
static PX4FirmwareUpgradeWorker* putWorkerInThread(QObject *parent);
signals:
void detectionStatusChanged(const QString& status);
void upgradeStatusChanged(const QString& status);
void upgradeProgressChanged(int percent);
void validPortFound(const QString& portName);
public slots:
/**
* @brief Continously scan for bootloaders
* @return
*/
bool startContinousScan();
/**
* @brief Detect connected PX4 bootloaders
*
* If a bootloader was found, the link will be opened to this
* bootloader and ready for flashing when returning from the call.
*
* @return true if found on one link, false else
*/
bool detect();
/**
* @brief Upgrade the firmware using the currently connected link
* @param filename file name / path of the firmware file
* @return true if upgrade succeeds, false else
*/
bool upgrade(const QString &filename);
/**
* @brief Receive bytes from a link
* @param link
* @param b
*/
void receiveBytes(LinkInterface* link, QByteArray b);
private:
SerialLink *link;
bool insync;
};
#endif // PX4FIRMWAREUPGRADEWORKER_H
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2011 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/>.
======================================================================*/
/**
* @file
* @brief Implementation of main application class
*
* @author Lorenz Meier <lm@inf.ethz.ch>
*
*/
#include <QFile>
#include <QFlags>
#include <QThread>
#include <QSplashScreen>
#include <QPixmap>
#include <QDesktopWidget>
#include <QPainter>
#include <QStyleFactory>
#include <QAction>
#include <QSettings>
#include <QFontDatabase>
#include <QMainWindow>
#include "QUpgradeApp.h"
#include "QUpgradeMainWindow.h"
#include "PX4FirmwareUpgradeWorker.h"
#include "UDPLink.h"
/**
* @brief Constructor for the main application.
*
* This constructor initializes and starts the whole application. It takes standard
* command-line parameters
*
* @param argc The number of command-line parameters
* @param argv The string array of parameters
**/
QUpgradeApp::QUpgradeApp(int &argc, char* argv[]) : QApplication(argc, argv)
{
this->setApplicationName("Q PX4 Firmware Upgrade");
this->setApplicationVersion("v. 1.0.0 (Beta)");
this->setOrganizationName(QLatin1String("PX4"));
this->setOrganizationDomain("http://pixhawk.ethz.ch/px4/");
QSettings::setDefaultFormat(QSettings::IniFormat);
// Exit main application when last window is closed
connect(this, SIGNAL(lastWindowClosed()), this, SLOT(quit()));
// Create main window
QUpgradeMainWindow* window = new QUpgradeMainWindow();
// Get PX4 upgrade widget and instantiate worker thread
PX4FirmwareUpgradeWorker* worker = PX4FirmwareUpgradeWorker::putWorkerInThread(this);
connect(worker, SIGNAL(detectionStatusChanged(QString)), window->firmwareUpgrader(), SLOT(setDetectionStatusText(QString)));
connect(worker, SIGNAL(upgradeStatusChanged(QString)), window->firmwareUpgrader(), SLOT(setFlashStatusText(QString)));
connect(worker, SIGNAL(upgradeProgressChanged(int)), window->firmwareUpgrader(), SLOT(setFlashProgress(int)));
connect(worker, SIGNAL(validPortFound(QString)), window->firmwareUpgrader(), SLOT(setPortName(QString)));
window->setWindowTitle(applicationName() + " " + applicationVersion());
window->show();
}
/**
* @brief Destructor for the groundstation. It destroys all loaded instances.
*
**/
QUpgradeApp::~QUpgradeApp()
{
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2011 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/>.
======================================================================*/
/**
* @file
* @brief Definition of main application class
*
* @author Lorenz Meier <lm@inf.ethz.ch>
*
*/
#ifndef QUPGRADEAPP_H
#define QUPGRADEAPP_H
#include <QApplication>
/**
* @brief The main application and management class.
*
* This class is started by the main method and provides
* the central management unit of the groundstation application.
*
**/
class QUpgradeApp : public QApplication
{
Q_OBJECT
public:
QUpgradeApp(int &argc, char* argv[]);
~QUpgradeApp();
protected:
private:
};
#endif /* QUPGRADEAPP_H */
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2011 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/>.
======================================================================*/
/**
* @file
* @brief Implementation of main window
*
* @author Lorenz Meier
*
*/
#include "QUpgradeMainWindow.h"
#include "ui_QUpgradeMainWindow.h"
//#include "UDPLink.h"
#include <QDebug>
QUpgradeMainWindow::QUpgradeMainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::QUpgradeMainWindow)
{
ui->setupUi(this);
}
PX4FirmwareUpgrader* QUpgradeMainWindow::firmwareUpgrader() {
return ui->centralwidget;
}
QUpgradeMainWindow::~QUpgradeMainWindow()
{
delete ui;
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2011 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/>.
======================================================================*/
/**
* @file
* @brief Definition of main window
*
* @author Lorenz Meier
*
*/
#ifndef QUPGRADEMAINWINDOW_H
#define QUPGRADEMAINWINDOW_H
#include <QMainWindow>
#include "PX4FirmwareUpgrader.h"
namespace Ui {
class QUpgradeMainWindow;
}
class QUpgradeMainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit QUpgradeMainWindow(QWidget *parent = 0);
~QUpgradeMainWindow();
PX4FirmwareUpgrader* firmwareUpgrader();
public slots:
protected:
private:
Ui::QUpgradeMainWindow *ui;
};
#endif // QUPGRADEMAINWINDOW_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QUpgradeMainWindow</class>
<widget class="QMainWindow" name="QUpgradeMainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="PX4FirmwareUpgrader" name="centralwidget">
<layout class="QGridLayout" name="gridLayout" rowstretch="0"/>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<customwidgets>
<customwidget>
<class>PX4FirmwareUpgrader</class>
<extends>QWidget</extends>
<header location="global">PX4FirmwareUpgrader.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2011 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/>.
======================================================================*/
/**
* @file
* @brief Main executable
* @author Lorenz Meier <lm@inf.ethz.ch>
*
*/
#include <QtGui/QApplication>
#include "QUpgradeApp.h"
/**
* @brief Starts the application
*
* @param argc Number of commandline arguments
* @param argv Commandline arguments
* @return exit code, 0 for normal exit and !=0 for error cases
*/
int main(int argc, char *argv[])
{
QUpgradeApp app(argc, argv);
return app.exec();
}
......@@ -563,10 +563,16 @@ bool SerialLink::disconnect()
emit disconnected();
emit connected(false);
if (port) {
port->close();
}
return closed;
}
else {
// No port, so we're disconnected
// not running
if (port) {
port->close();
}
return true;
}
......
#include "PX4FirmwareUpgrader.h"
#include "ui_PX4FirmwareUpgrader.h"
#include <QGC.h>
#include <QDebug>
PX4FirmwareUpgrader::PX4FirmwareUpgrader(QWidget *parent) :
QWidget(parent),
ui(new Ui::PX4FirmwareUpgrader)
{
ui->setupUi(this);
connect(ui->selectFileButton, SIGNAL(clicked()), this, SLOT(selectFirmwareFile()));
connect(ui->flashButton, SIGNAL(clicked()), this, SIGNAL(upgrade()));
}
PX4FirmwareUpgrader::~PX4FirmwareUpgrader()
{
delete ui;
}
void PX4FirmwareUpgrader::selectFirmwareFile()
{
}
void PX4FirmwareUpgrader::setDetectionStatusText(const QString &text)
{
ui->detectionStatusLabel->setText(text);
}
void PX4FirmwareUpgrader::setFlashStatusText(const QString &text)
{
ui->flashProgressLabel->setText(text);
}
void PX4FirmwareUpgrader::setFlashProgress(int percent)
{
ui->flashProgressBar->setValue(percent);
}
void PX4FirmwareUpgrader::setPortName(const QString &portname)
{
// Prepend newly found port to the list
if (ui->serialPortComboBox->findText(portname) == -1)
{
ui->serialPortComboBox->insertItem(0, portname);
ui->serialPortComboBox->setEditText(portname);
}
}
#ifndef PX4FIRMWAREUPGRADER_H
#define PX4FIRMWAREUPGRADER_H
#include <QWidget>
#include <QTimer>
#include <SerialLink.h>
namespace Ui {
class PX4FirmwareUpgrader;
}
class PX4FirmwareUpgrader : public QWidget
{
Q_OBJECT
public:
PX4FirmwareUpgrader(QWidget *parent = 0);
~PX4FirmwareUpgrader();
public slots:
void setDetectionStatusText(const QString &text);
void setFlashStatusText(const QString &text);
void setFlashProgress(int percent);
void selectFirmwareFile();
void setPortName(const QString &portname);
signals:
void firmwareFileNameSet(const QString &fileName);
void upgrade();
private:
Ui::PX4FirmwareUpgrader *ui;
};
#endif // PX4FIRMWAREUPGRADER_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PX4FirmwareUpgrader</class>
<widget class="QWidget" name="PX4FirmwareUpgrader">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>428</width>
<height>331</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="3" column="0" colspan="3">
<widget class="QTextBrowser" name="descriptionTextBrowser"/>
</item>
<item row="4" column="0" colspan="3">
<widget class="QProgressBar" name="flashProgressBar">
<property name="value">
<number>24</number>
</property>
</widget>
</item>
<item row="5" column="0" colspan="2">
<widget class="QLabel" name="flashProgressLabel">
<property name="text">
<string>No update in progress.</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QComboBox" name="versionComboBox"/>
</item>
<item row="2" column="2">
<widget class="QPushButton" name="selectFileButton">
<property name="text">
<string>Select File..</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QPushButton" name="versionButton">
<property name="text">
<string>Check Online</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="serialPortButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Set Serial Port</string>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QPushButton" name="flashButton">
<property name="text">
<string>Flash Firmware</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="detectionStatusLabel">
<property name="text">
<string>No PX4 board detected..</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="detectionAutoCheckBox">
<property name="text">
<string>Auto Detect Port</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QComboBox" name="serialPortComboBox">
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
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