Added a firmware uploader that can be used to upload firmware to supported cortex M3 boards (gvret, gevcu, evtvbms, etc) - Not tested to properly work yet but it does operate. Use at your own risk!
This commit is contained in:
+6
-3
@@ -34,7 +34,8 @@ SOURCES += main.cpp\
|
||||
dbcsignaleditor.cpp \
|
||||
framefileio.cpp \
|
||||
filecomparatorwindow.cpp \
|
||||
mainsettingsdialog.cpp
|
||||
mainsettingsdialog.cpp \
|
||||
firmwareuploaderwindow.cpp
|
||||
|
||||
HEADERS += mainwindow.h \
|
||||
can_structs.h \
|
||||
@@ -57,7 +58,8 @@ HEADERS += mainwindow.h \
|
||||
framefileio.h \
|
||||
config.h \
|
||||
filecomparatorwindow.h \
|
||||
mainsettingsdialog.h
|
||||
mainsettingsdialog.h \
|
||||
firmwareuploaderwindow.h
|
||||
|
||||
FORMS += mainwindow.ui \
|
||||
graphingwindow.ui \
|
||||
@@ -70,7 +72,8 @@ FORMS += mainwindow.ui \
|
||||
dbcmaineditor.ui \
|
||||
dbcsignaleditor.ui \
|
||||
filecomparatorwindow.ui \
|
||||
mainsettingsdialog.ui
|
||||
mainsettingsdialog.ui \
|
||||
firmwareuploaderwindow.ui
|
||||
|
||||
DISTFILES +=
|
||||
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
#include "firmwareuploaderwindow.h"
|
||||
#include "ui_firmwareuploaderwindow.h"
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include <QFile>
|
||||
|
||||
FirmwareUploaderWindow::FirmwareUploaderWindow(const QVector<CANFrame> *frames, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::FirmwareUploaderWindow)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
transferInProgress = false;
|
||||
startedProcess = false;
|
||||
firmwareSize = 0;
|
||||
currentSendingPosition = 0;
|
||||
baseAddress = 0;
|
||||
bus = 0;
|
||||
modelFrames = frames;
|
||||
|
||||
ui->lblFilename->setText("");
|
||||
ui->spinBus->setValue(0);
|
||||
ui->spinBus->setMaximum(1);
|
||||
ui->txtBaseAddr->setText("0x100");
|
||||
updateProgress();
|
||||
|
||||
timer = new QTimer();
|
||||
timer->setInterval(100); //100ms without a reply will cause us to attempt a resend
|
||||
|
||||
connect(MainWindow::getReference(), SIGNAL(framesUpdated(int)), this, SLOT(updatedFrames(int)));
|
||||
connect(ui->btnLoadFile, SIGNAL(clicked(bool)), this, SLOT(handleLoadFile()));
|
||||
connect(ui->btnStartStop, SIGNAL(clicked(bool)), this, SLOT(handleStartStopTransfer()));
|
||||
connect(timer, SIGNAL(timeout()), this, SLOT(timerElapsed()));
|
||||
}
|
||||
|
||||
FirmwareUploaderWindow::~FirmwareUploaderWindow()
|
||||
{
|
||||
timer->stop();
|
||||
delete timer;
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void FirmwareUploaderWindow::updateProgress()
|
||||
{
|
||||
ui->lblProgress->setText(QString::number(currentSendingPosition * 4) + " of " + QString::number(firmwareSize) + " transferred");
|
||||
}
|
||||
|
||||
void FirmwareUploaderWindow::updatedFrames(int numFrames)
|
||||
{
|
||||
CANFrame thisFrame;
|
||||
if (numFrames == -1) //all frames deleted.
|
||||
{
|
||||
}
|
||||
else if (numFrames == -2) //all new set of frames.
|
||||
{
|
||||
}
|
||||
else //just got some new frames. See if they are relevant.
|
||||
{
|
||||
/*
|
||||
//run through the supposedly new frames in order
|
||||
for (int i = modelFrames->count() - numFrames; i < modelFrames->count(); i++)
|
||||
{
|
||||
thisFrame = modelFrames->at(i);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
void FirmwareUploaderWindow::gotTargettedFrame(int frameLoc)
|
||||
{
|
||||
const CANFrame &frame = modelFrames->at(frameLoc);
|
||||
if (frame.ID == (baseAddress + 0x10)) {
|
||||
qDebug() << "Start firmware reply";
|
||||
if ((frame.data[0] == 0xDE) && (frame.data[1] == 0xAF))
|
||||
{
|
||||
if ((frame.data[2] == 0xDE) && (frame.data[3] == 0xED))
|
||||
{
|
||||
if ((frame.data[4] == (token & 0xFF)) && (frame.data[5] == ((token >> 8) & 0xFF)))
|
||||
{
|
||||
if ((frame.data[6] == ((token >> 16) & 0xFF)) && (frame.data[7] == ((token >> 24) & 0xFF)))
|
||||
{
|
||||
qDebug() << "starting firmware process";
|
||||
MainWindow::getReference()->setTargettedID(baseAddress + 0x20);
|
||||
transferInProgress = true;
|
||||
sendFirmwareChunk();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (frame.ID == (baseAddress + 0x20)) {
|
||||
qDebug() << "Firmware reception success reply";
|
||||
int seq = frame.data[0] + (256 * frame.data[1]);
|
||||
if (seq == currentSendingPosition)
|
||||
{
|
||||
currentSendingPosition++;
|
||||
if (currentSendingPosition * 4 > firmwareSize || currentSendingPosition > 65535)
|
||||
{
|
||||
transferInProgress = false;
|
||||
timer->stop();
|
||||
handleStartStopTransfer();
|
||||
ui->progressBar->setValue(100);
|
||||
sendFirmwareEnding();
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->progressBar->setValue((400 * currentSendingPosition) / firmwareSize);
|
||||
updateProgress();
|
||||
sendFirmwareChunk();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FirmwareUploaderWindow::timerElapsed()
|
||||
{
|
||||
sendFirmwareChunk(); //resend
|
||||
}
|
||||
|
||||
void FirmwareUploaderWindow::sendFirmwareChunk()
|
||||
{
|
||||
CANFrame *output = new CANFrame;
|
||||
int firmwareLocation = currentSendingPosition * 4;
|
||||
int xorByte = 0;
|
||||
output->extended = false;
|
||||
output->len = 7;
|
||||
output->ID = baseAddress + 0x16;
|
||||
output->data[0] = currentSendingPosition & 0xFF;
|
||||
output->data[1] = (currentSendingPosition >> 8) & 0xFF;
|
||||
output->data[2] = firmwareData[firmwareLocation++];
|
||||
output->data[3] = firmwareData[firmwareLocation++];
|
||||
output->data[4] = firmwareData[firmwareLocation++];
|
||||
output->data[5] = firmwareData[firmwareLocation++];
|
||||
for (int i = 0; i < 6; i++) xorByte = xorByte ^ output->data[i];
|
||||
output->data[6] = xorByte;
|
||||
sendCANFrame(output, bus);
|
||||
timer->start();
|
||||
}
|
||||
|
||||
void FirmwareUploaderWindow::sendFirmwareEnding()
|
||||
{
|
||||
CANFrame *output = new CANFrame;
|
||||
output->extended = false;
|
||||
output->len = 4;
|
||||
output->ID = baseAddress + 0x30;
|
||||
output->data[0] = 0xC0;
|
||||
output->data[1] = 0xDE;
|
||||
output->data[2] = 0xFA;
|
||||
output->data[3] = 0xDE;
|
||||
sendCANFrame(output, bus);
|
||||
}
|
||||
|
||||
void FirmwareUploaderWindow::handleStartStopTransfer()
|
||||
{
|
||||
startedProcess = !startedProcess;
|
||||
|
||||
if (startedProcess) //start the process
|
||||
{
|
||||
ui->progressBar->setValue(0);
|
||||
ui->btnStartStop->setText("Stop Upload");
|
||||
token = Utility::ParseStringToNum(ui->txtToken->text());
|
||||
bus = ui->spinBus->value();
|
||||
baseAddress = Utility::ParseStringToNum(ui->txtBaseAddr->text());
|
||||
qDebug() << "Base address: " + QString::number(baseAddress);
|
||||
MainWindow::getReference()->setTargettedID(baseAddress + 0x10);
|
||||
CANFrame *output = new CANFrame;
|
||||
output->extended = false;
|
||||
output->len = 8;
|
||||
output->ID = baseAddress;
|
||||
output->data[0] = 0xDE;
|
||||
output->data[1] = 0xAD;
|
||||
output->data[2] = 0xBE;
|
||||
output->data[3] = 0xEF;
|
||||
output->data[4] = token & 0xFF;
|
||||
output->data[5] = (token >> 8) & 0xFF;
|
||||
output->data[6] = (token >> 16) & 0xFF;
|
||||
output->data[7] = (token >> 24) & 0xFF;
|
||||
sendCANFrame(output, bus);
|
||||
}
|
||||
else //stop anything in process
|
||||
{
|
||||
ui->btnStartStop->setText("Start Upload");
|
||||
MainWindow::getReference()->setTargettedID(-1);
|
||||
}
|
||||
}
|
||||
|
||||
void FirmwareUploaderWindow::handleLoadFile()
|
||||
{
|
||||
QString filename;
|
||||
QFileDialog dialog;
|
||||
bool result = false;
|
||||
|
||||
QStringList filters;
|
||||
filters.append(QString(tr("Raw firmware binary (*.bin)")));
|
||||
|
||||
dialog.setFileMode(QFileDialog::ExistingFile);
|
||||
dialog.setNameFilters(filters);
|
||||
dialog.setViewMode(QFileDialog::Detail);
|
||||
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
{
|
||||
filename = dialog.selectedFiles()[0];
|
||||
|
||||
loadBinaryFile(filename);
|
||||
}
|
||||
}
|
||||
|
||||
void FirmwareUploaderWindow::loadBinaryFile(QString filename)
|
||||
{
|
||||
|
||||
if (transferInProgress) handleStartStopTransfer();
|
||||
|
||||
QFile *inFile = new QFile(filename);
|
||||
|
||||
if (!inFile->open(QIODevice::ReadOnly))
|
||||
{
|
||||
delete inFile;
|
||||
return;
|
||||
}
|
||||
|
||||
firmwareData = inFile->readAll();
|
||||
|
||||
currentSendingPosition = 0;
|
||||
firmwareSize = firmwareData.length();
|
||||
|
||||
updateProgress();
|
||||
|
||||
inFile->close();
|
||||
delete inFile;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
#ifndef FIRMWAREUPLOADERWINDOW_H
|
||||
#define FIRMWAREUPLOADERWINDOW_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QTimer>
|
||||
#include "can_structs.h"
|
||||
#include "utility.h"
|
||||
#include "serialworker.h"
|
||||
|
||||
namespace Ui {
|
||||
class FirmwareUploaderWindow;
|
||||
}
|
||||
|
||||
class FirmwareUploaderWindow : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit FirmwareUploaderWindow(const QVector<CANFrame> *frames, QWidget *parent = 0);
|
||||
~FirmwareUploaderWindow();
|
||||
|
||||
signals:
|
||||
void sendCANFrame(const CANFrame *, int);
|
||||
|
||||
public slots:
|
||||
void gotTargettedFrame(int frameLoc);
|
||||
|
||||
private slots:
|
||||
void handleLoadFile();
|
||||
void handleStartStopTransfer();
|
||||
void updatedFrames(int);
|
||||
void timerElapsed();
|
||||
|
||||
private:
|
||||
void updateProgress();
|
||||
void loadBinaryFile(QString);
|
||||
void sendFirmwareChunk();
|
||||
void sendFirmwareEnding();
|
||||
|
||||
Ui::FirmwareUploaderWindow *ui;
|
||||
bool transferInProgress;
|
||||
bool startedProcess;
|
||||
int firmwareSize;
|
||||
int currentSendingPosition;
|
||||
int baseAddress;
|
||||
int bus;
|
||||
uint32_t token;
|
||||
QByteArray firmwareData;
|
||||
const QVector<CANFrame> *modelFrames;
|
||||
QTimer *timer;
|
||||
};
|
||||
|
||||
#endif // FIRMWAREUPLOADERWINDOW_H
|
||||
@@ -0,0 +1,106 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>FirmwareUploaderWindow</class>
|
||||
<widget class="QDialog" name="FirmwareUploaderWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>327</width>
|
||||
<height>357</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item alignment="Qt::AlignHCenter">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Loaded File:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblFilename">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnLoadFile">
|
||||
<property name="text">
|
||||
<string>Load File</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item alignment="Qt::AlignHCenter">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Device Token:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="txtToken"/>
|
||||
</item>
|
||||
<item alignment="Qt::AlignHCenter">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>CAN Bus:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="spinBus"/>
|
||||
</item>
|
||||
<item alignment="Qt::AlignHCenter">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Base Address:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="txtBaseAddr"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QProgressBar" name="progressBar">
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item alignment="Qt::AlignHCenter">
|
||||
<widget class="QLabel" name="lblProgress">
|
||||
<property name="text">
|
||||
<string>X of Y bytes</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnStartStop">
|
||||
<property name="text">
|
||||
<string>Start Upload</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -104,6 +104,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
dbcMainEditor = NULL;
|
||||
comparatorWindow = NULL;
|
||||
settingsDialog = NULL;
|
||||
firmwareUploaderWindow = NULL;
|
||||
dbcHandler = new DBCHandler;
|
||||
bDirty = false;
|
||||
inhibitFilterUpdate = false;
|
||||
@@ -143,6 +144,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
connect(ui->listFilters, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(filterListItemChanged(QListWidgetItem*)));
|
||||
connect(ui->btnFilterAll, SIGNAL(clicked(bool)), this, SLOT(filterSetAll()));
|
||||
connect(ui->btnFilterNone, SIGNAL(clicked(bool)), this, SLOT(filterClearAll()));
|
||||
connect(ui->actionFirmware_Uploader, SIGNAL(triggered(bool)), this, SLOT(showFirmwareUploaderWindow()));
|
||||
|
||||
lbStatusConnected.setText(tr("Not connected"));
|
||||
updateFileStatus();
|
||||
@@ -906,6 +908,11 @@ void MainWindow::gotDeviceInfo(int build, int swCAN)
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::setTargettedID(int id)
|
||||
{
|
||||
worker->targetFrameID(id);
|
||||
}
|
||||
|
||||
void MainWindow::showSettingsDialog()
|
||||
{
|
||||
if (!settingsDialog)
|
||||
@@ -972,6 +979,17 @@ void MainWindow::showPlaybackWindow()
|
||||
playbackWindow->show();
|
||||
}
|
||||
|
||||
void MainWindow::showFirmwareUploaderWindow()
|
||||
{
|
||||
if (!firmwareUploaderWindow)
|
||||
{
|
||||
firmwareUploaderWindow = new FirmwareUploaderWindow(model->getListReference());
|
||||
connect(firmwareUploaderWindow, SIGNAL(sendCANFrame(const CANFrame*,int)), worker, SLOT(sendFrame(const CANFrame*,int)));
|
||||
connect(worker, SIGNAL(gotTargettedFrame(int)), firmwareUploaderWindow, SLOT(gotTargettedFrame(int)));
|
||||
}
|
||||
firmwareUploaderWindow->show();
|
||||
}
|
||||
|
||||
void MainWindow::showComparisonWindow()
|
||||
{
|
||||
if (!comparatorWindow)
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "dbchandler.h"
|
||||
#include "dbcmaineditor.h"
|
||||
#include "mainsettingsdialog.h"
|
||||
#include "firmwareuploaderwindow.h"
|
||||
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
@@ -30,6 +31,7 @@ public:
|
||||
explicit MainWindow(QWidget *parent = 0);
|
||||
static QString loadedFileName;
|
||||
static MainWindow *getReference();
|
||||
void setTargettedID(int);
|
||||
~MainWindow();
|
||||
|
||||
private slots:
|
||||
@@ -52,6 +54,7 @@ private slots:
|
||||
void showFuzzyScopeWindow();
|
||||
void showComparisonWindow();
|
||||
void showSettingsDialog();
|
||||
void showFirmwareUploaderWindow();
|
||||
void exitApp();
|
||||
void handleSaveDecoded();
|
||||
void changeBaudRates();
|
||||
@@ -115,6 +118,7 @@ private:
|
||||
DBCMainEditor *dbcMainEditor;
|
||||
FileComparatorWindow *comparatorWindow;
|
||||
MainSettingsDialog *settingsDialog;
|
||||
FirmwareUploaderWindow *firmwareUploaderWindow;
|
||||
|
||||
//various private storage
|
||||
QLabel lbStatusConnected;
|
||||
|
||||
+7
-1
@@ -293,7 +293,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>26</height>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menu_RE_Tools">
|
||||
@@ -314,6 +314,7 @@
|
||||
</property>
|
||||
<addaction name="action_Playback"/>
|
||||
<addaction name="action_Custom"/>
|
||||
<addaction name="actionFirmware_Uploader"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuFile">
|
||||
<property name="title">
|
||||
@@ -440,6 +441,11 @@
|
||||
<string>Save Filter Definition</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionFirmware_Uploader">
|
||||
<property name="text">
|
||||
<string>Firmware Uploader</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources/>
|
||||
|
||||
+7
-1
@@ -19,6 +19,7 @@ SerialWorker::SerialWorker(CANFrameModel *model, QObject *parent) : QObject(pare
|
||||
capturing = true;
|
||||
gotValidated = true;
|
||||
isAutoRestart = false;
|
||||
targetID = -1;
|
||||
|
||||
readSettings();
|
||||
}
|
||||
@@ -245,7 +246,7 @@ void SerialWorker::procRXChar(unsigned char c)
|
||||
break;
|
||||
case 9:
|
||||
gotValidated = true;
|
||||
qDebug() << "Got validated";
|
||||
//qDebug() << "Got validated";
|
||||
rx_state = IDLE;
|
||||
break;
|
||||
}
|
||||
@@ -302,6 +303,7 @@ void SerialWorker::procRXChar(unsigned char c)
|
||||
{
|
||||
canModel->addFrame(*buildFrame, false);
|
||||
gotFrames++;
|
||||
if (buildFrame->ID == targetID) emit gotTargettedFrame(canModel->rowCount() - 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -477,3 +479,7 @@ void SerialWorker::startFrameCapture()
|
||||
capturing = true;
|
||||
}
|
||||
|
||||
void SerialWorker::targetFrameID(int target)
|
||||
{
|
||||
targetID = target;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ public:
|
||||
SerialWorker(CANFrameModel *model, QObject *parent = 0);
|
||||
~SerialWorker();
|
||||
void readSettings();
|
||||
void targetFrameID(int);
|
||||
|
||||
signals: //we emit signals
|
||||
void error(const QString &);
|
||||
@@ -39,6 +40,7 @@ signals: //we emit signals
|
||||
void connectionSuccess(int, int);
|
||||
void connectionFailure();
|
||||
void deviceInfo(int, int);
|
||||
void gotTargettedFrame(int);
|
||||
|
||||
private slots: //we receive things in slots
|
||||
void readSerialData();
|
||||
@@ -70,6 +72,7 @@ private:
|
||||
QTime *elapsedTime;
|
||||
int framesPerSec;
|
||||
int gotFrames;
|
||||
int targetID;
|
||||
STATE rx_state;
|
||||
int rx_step;
|
||||
CANFrame *buildFrame;
|
||||
|
||||
Reference in New Issue
Block a user