1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-15 12:25:12 +03:00

Refactoring

This commit is contained in:
bsongis 2014-12-16 20:37:30 +01:00
parent 62b64862d8
commit 38a639cef6
102 changed files with 3055 additions and 2978 deletions

View file

@ -144,21 +144,29 @@ add_library(common ${common_SRCS})
set(companion_SRCS set(companion_SRCS
hexinterface.cpp hexinterface.cpp
flashinterface.cpp firmwareinterface.cpp
converteeprom.cpp
# xmlinterface.cpp # xmlinterface.cpp
# ${PROJECT_BINARY_DIR}/radio.cxx # ${PROJECT_BINARY_DIR}/radio.cxx
helpers.cpp helpers.cpp
helpers_html.cpp
mdichild.cpp mdichild.cpp
modelslist.cpp modelslist.cpp
mountlist.cpp mountlist.cpp
avroutputdialog.cpp
apppreferencesdialog.cpp apppreferencesdialog.cpp
fwpreferencesdialog.cpp fwpreferencesdialog.cpp
burnconfigdialog.cpp burnconfigdialog.cpp
comparedialog.cpp comparedialog.cpp
contributorsdialog.cpp contributorsdialog.cpp
customizesplashdialog.cpp customizesplashdialog.cpp
burndialog.cpp radiointerface.cpp
progresswidget.cpp
progressdialog.cpp
process_copy.cpp
process_flash.cpp
process_sync.cpp
flashfirmwaredialog.cpp
flasheepromdialog.cpp
printdialog.cpp printdialog.cpp
fusesdialog.cpp fusesdialog.cpp
logsdialog.cpp logsdialog.cpp
@ -173,7 +181,6 @@ set(companion_SRCS
) )
set(companion_MOC_HDRS set(companion_MOC_HDRS
avroutputdialog.h
apppreferencesdialog.h apppreferencesdialog.h
fwpreferencesdialog.h fwpreferencesdialog.h
burnconfigdialog.h burnconfigdialog.h
@ -185,7 +192,13 @@ set(companion_MOC_HDRS
customizesplashdialog.h customizesplashdialog.h
splashlibrary.h splashlibrary.h
splashlabel.h splashlabel.h
burndialog.h progresswidget.h
progressdialog.h
process_copy.h
process_flash.h
process_sync.h
flashfirmwaredialog.h
flasheepromdialog.h
downloaddialog.h downloaddialog.h
modelslist.h modelslist.h
mdichild.h mdichild.h
@ -198,7 +211,6 @@ set(companion_MOC_HDRS
set(companion_UIS set(companion_UIS
mdichild.ui mdichild.ui
avroutputdialog.ui
comparedialog.ui comparedialog.ui
fusesdialog.ui fusesdialog.ui
logsdialog.ui logsdialog.ui
@ -210,7 +222,10 @@ set(companion_UIS
contributorsdialog.ui contributorsdialog.ui
customizesplashdialog.ui customizesplashdialog.ui
splashlibrary.ui splashlibrary.ui
burndialog.ui progresswidget.ui
progressdialog.ui
flashfirmwaredialog.ui
flasheepromdialog.ui
radionotfound.ui radionotfound.ui
) )

View file

@ -498,8 +498,6 @@ QString AppData::libDir() { return _libDir; }
QString AppData::snapshotDir() { return _snapshotDir; } QString AppData::snapshotDir() { return _snapshotDir; }
QString AppData::updatesDir() { return _updatesDir; } QString AppData::updatesDir() { return _updatesDir; }
bool AppData::enableBackup() { return _enableBackup; }
bool AppData::backupOnFlash() { return _backupOnFlash; }
bool AppData::jsSupport() { return _jsSupport; } bool AppData::jsSupport() { return _jsSupport; }
bool AppData::maximized() { return _maximized; } bool AppData::maximized() { return _maximized; }
bool AppData::showSplash() { return _showSplash; } bool AppData::showSplash() { return _showSplash; }
@ -548,8 +546,6 @@ void AppData::libDir (const QString x) { store(x, _libDir,
void AppData::snapshotDir (const QString x) { store(x, _snapshotDir, "snapshotpath" );} void AppData::snapshotDir (const QString x) { store(x, _snapshotDir, "snapshotpath" );}
void AppData::updatesDir (const QString x) { store(x, _updatesDir, "lastUpdatesDir" );} void AppData::updatesDir (const QString x) { store(x, _updatesDir, "lastUpdatesDir" );}
void AppData::enableBackup (const bool x) { store(x, _enableBackup, "backupEnable" );}
void AppData::backupOnFlash (const bool x) { store(x, _backupOnFlash, "backupOnFlash" );}
void AppData::maximized (const bool x) { store(x, _maximized, "maximized" );} void AppData::maximized (const bool x) { store(x, _maximized, "maximized" );}
void AppData::jsSupport (const bool x) { store(x, _jsSupport, "js_support" );} void AppData::jsSupport (const bool x) { store(x, _jsSupport, "js_support" );}
void AppData::showSplash (const bool x) { store(x, _showSplash, "show_splash" );} void AppData::showSplash (const bool x) { store(x, _showSplash, "show_splash" );}
@ -674,6 +670,7 @@ AppData::AppData()
getset( _snapshotDir, "snapshotpath" ,"" ); getset( _snapshotDir, "snapshotpath" ,"" );
getset( _updatesDir, "lastUpdatesDir" ,"" ); getset( _updatesDir, "lastUpdatesDir" ,"" );
getset( _outputDisplayDetails, "outputDisplayDetails" ,false );
getset( _enableBackup, "backupEnable" ,false ); getset( _enableBackup, "backupEnable" ,false );
getset( _backupOnFlash, "backupOnFlash" ,true ); getset( _backupOnFlash, "backupOnFlash" ,true );
getset( _jsSupport, "js_support" ,false ); getset( _jsSupport, "js_support" ,false );

View file

@ -188,8 +188,19 @@ class Profile: protected CompStoreObj
void flush(); void flush();
}; };
#define BOOL_PROPERTY(name, dflt) \
public: \
inline bool name() { return _ ## name; } \
void name(const bool val) { store(val, _ ## name, # name); } \
private: \
bool _ ## name;
class AppData: protected CompStoreObj class AppData: protected CompStoreObj
{ {
BOOL_PROPERTY(enableBackup, false)
BOOL_PROPERTY(outputDisplayDetails, false)
BOOL_PROPERTY(backupOnFlash, true)
// All the global variables // All the global variables
public: public:
Profile profile[MAX_PROFILES]; Profile profile[MAX_PROFILES];
@ -224,8 +235,6 @@ class AppData: protected CompStoreObj
QString _snapshotDir; QString _snapshotDir;
QString _updatesDir; QString _updatesDir;
bool _enableBackup;
bool _backupOnFlash;
bool _maximized; bool _maximized;
bool _jsSupport; bool _jsSupport;
bool _showSplash; bool _showSplash;
@ -276,8 +285,6 @@ class AppData: protected CompStoreObj
QString snapshotDir(); QString snapshotDir();
QString updatesDir(); QString updatesDir();
bool enableBackup();
bool backupOnFlash();
bool jsSupport(); bool jsSupport();
bool maximized(); bool maximized();
bool showSplash(); bool showSplash();
@ -327,8 +334,6 @@ class AppData: protected CompStoreObj
void snapshotDir (const QString); void snapshotDir (const QString);
void updatesDir (const QString); void updatesDir (const QString);
void enableBackup (const bool);
void backupOnFlash (const bool);
void maximized (const bool); void maximized (const bool);
void jsSupport (const bool); void jsSupport (const bool);
void showSplash (const bool); void showSplash (const bool);

View file

@ -3,7 +3,7 @@
#include "mainwindow.h" #include "mainwindow.h"
#include "appdata.h" #include "appdata.h"
#include "helpers.h" #include "helpers.h"
#include "flashinterface.h" #include "firmwareinterface.h"
#ifdef JOYSTICKS #ifdef JOYSTICKS
#include "joystick.h" #include "joystick.h"
#include "joystickdialog.h" #include "joystickdialog.h"
@ -182,9 +182,9 @@ void AppPreferencesDialog::initSettings()
} }
ui->lblGeneralSettings->setText(hwSettings); ui->lblGeneralSettings->setText(hwSettings);
FirmwareInterface * current_firmware = GetCurrentFirmware(); Firmware * current_firmware = GetCurrentFirmware();
foreach(FirmwareInterface * firmware, firmwares) { foreach(Firmware * firmware, firmwares) {
ui->downloadVerCB->addItem(firmware->getName(), firmware->getId()); ui->downloadVerCB->addItem(firmware->getName(), firmware->getId());
if (current_firmware->getFirmwareBase() == firmware) { if (current_firmware->getFirmwareBase() == firmware) {
ui->downloadVerCB->setCurrentIndex(ui->downloadVerCB->count() - 1); ui->downloadVerCB->setCurrentIndex(ui->downloadVerCB->count() - 1);
@ -347,7 +347,7 @@ void AppPreferencesDialog::baseFirmwareChanged()
{ {
QVariant selected_firmware = ui->downloadVerCB->itemData(ui->downloadVerCB->currentIndex()); QVariant selected_firmware = ui->downloadVerCB->itemData(ui->downloadVerCB->currentIndex());
foreach(FirmwareInterface * firmware, firmwares) { foreach(Firmware * firmware, firmwares) {
if (firmware->getId() == selected_firmware) { if (firmware->getId() == selected_firmware) {
populateFirmwareOptions(firmware); populateFirmwareOptions(firmware);
break; break;
@ -355,11 +355,11 @@ void AppPreferencesDialog::baseFirmwareChanged()
} }
} }
FirmwareInterface * AppPreferencesDialog::getFirmwareVariant() Firmware * AppPreferencesDialog::getFirmwareVariant()
{ {
QVariant selected_firmware = ui->downloadVerCB->itemData(ui->downloadVerCB->currentIndex()); QVariant selected_firmware = ui->downloadVerCB->itemData(ui->downloadVerCB->currentIndex());
foreach(FirmwareInterface * firmware, firmwares) { foreach(Firmware * firmware, firmwares) {
QString id = firmware->getId(); QString id = firmware->getId();
if (id == selected_firmware) { if (id == selected_firmware) {
foreach(QCheckBox *cb, optionsCheckBoxes) { foreach(QCheckBox *cb, optionsCheckBoxes) {
@ -390,7 +390,7 @@ void AppPreferencesDialog::firmwareOptionChanged(bool state)
if (cb == voice) { if (cb == voice) {
showVoice(voice->isChecked()); showVoice(voice->isChecked());
} }
FirmwareInterface * firmware=NULL; Firmware * firmware=NULL;
if (cb && state) { if (cb && state) {
QVariant selected_firmware = ui->downloadVerCB->itemData(ui->downloadVerCB->currentIndex()); QVariant selected_firmware = ui->downloadVerCB->itemData(ui->downloadVerCB->currentIndex());
foreach(firmware, firmwares) { foreach(firmware, firmwares) {
@ -416,9 +416,9 @@ void AppPreferencesDialog::firmwareOptionChanged(bool state)
} }
} }
void AppPreferencesDialog::populateFirmwareOptions(const FirmwareInterface * firmware) void AppPreferencesDialog::populateFirmwareOptions(const Firmware * firmware)
{ {
const FirmwareInterface * parent = firmware->getFirmwareBase(); const Firmware * parent = firmware->getFirmwareBase();
updateLock = true; updateLock = true;

View file

@ -27,8 +27,8 @@ class AppPreferencesDialog : public QDialog
void showVoice(); void showVoice();
void hideVoice(); void hideVoice();
void populateLocale(); void populateLocale();
void populateFirmwareOptions(const FirmwareInterface *); void populateFirmwareOptions(const Firmware *);
FirmwareInterface * getFirmwareVariant(); Firmware * getFirmwareVariant();
QCheckBox * voice; QCheckBox * voice;
Ui::AppPreferencesDialog *ui; Ui::AppPreferencesDialog *ui;

View file

@ -1,504 +0,0 @@
#include "avroutputdialog.h"
#include "ui_avroutputdialog.h"
#include <QtGui>
#include "eeprominterface.h"
#include "flashinterface.h"
#if defined WIN32 || !defined __GNUC__
#include <Windows.h>
#include <WinBase.h>
#include <tlhelp32.h>
#define sleep(x) Sleep(x*1000)
#else
#include <unistd.h>
#include "mountlist.h"
#endif
avrOutputDialog::avrOutputDialog(QWidget *parent, QString prog, QStringList arg, QString wTitle, int closeBehaviour, bool displayDetails) :
QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
ui(new Ui::avrOutputDialog),
kill_timer(NULL),
hasErrors(false)
{
ui->setupUi(this);
#ifdef __APPLE__
QFont newFont("Courier", 13);
ui->plainTextEdit->setFont(newFont);
ui->plainTextEdit->setAttribute(Qt::WA_MacNormalSize);
#endif
#if defined WIN32 || !defined __GNUC__
QFont newFont("Courier", 9);
ui->plainTextEdit->setFont(newFont);
#endif
cmdLine = prog;
closeOpt = closeBehaviour;
if (cmdLine.isEmpty()) {
if (arg.count()<2) {
closeOpt = AVR_DIALOG_FORCE_CLOSE;
QTimer::singleShot(0, this, SLOT(forceClose()));
}
else {
sourceFile=arg.at(0);
destFile=arg.at(1);
if (!displayDetails) {
ui->plainTextEdit->hide();
QTimer::singleShot(0, this, SLOT(shrink()));
} else {
ui->checkBox->setChecked(true);
}
ui->progressBar->setMaximum(127);
QTimer::singleShot(500, this, SLOT(doCopy()));
}
}
else {
if (wTitle.isEmpty())
setWindowTitle(getProgrammer() + " " + tr("result"));
else
setWindowTitle(getProgrammer() + " - " + wTitle);
QFile exec;
winTitle=wTitle;
if (!(exec.exists(prog))) {
QMessageBox::critical(this, "Companion", getProgrammer() + " " + tr("executable not found"));
closeOpt = AVR_DIALOG_FORCE_CLOSE;
QTimer::singleShot(0, this, SLOT(forceClose()));
}
else {
foreach(QString str, arg) cmdLine.append(" " + str);
lfuse = 0;
hfuse = 0;
efuse = 0;
phase=0;
currLine.clear();
if (!displayDetails) {
ui->plainTextEdit->hide();
QTimer::singleShot(0, this, SLOT(shrink()));
}
else {
ui->checkBox->setChecked(true);
}
process = new QProcess(this);
connect(process,SIGNAL(readyReadStandardError()), this, SLOT(doAddTextStdErr()));
connect(process,SIGNAL(started()),this,SLOT(doProcessStarted()));
connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(doAddTextStdOut()));
connect(process,SIGNAL(finished(int)),this,SLOT(doFinished(int)));
#if !__GNUC__
kill_timer = new QTimer(this);
connect(kill_timer, SIGNAL(timeout()), this, SLOT(killTimerElapsed()));
kill_timer->start(2000);
#endif
process->start(prog,arg);
}
}
}
# if !__GNUC__
BOOL KillProcessByName(char *szProcessToKill){
HANDLE hProcessSnap;
HANDLE hProcess;
PROCESSENTRY32 pe32;
DWORD dwPriorityClass;
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); // Takes a snapshot of all the processes
if(hProcessSnap == INVALID_HANDLE_VALUE){
return( FALSE );
}
pe32.dwSize = sizeof(PROCESSENTRY32);
if(!Process32First(hProcessSnap, &pe32)){
CloseHandle(hProcessSnap);
return( FALSE );
}
do{
if(!strcmp(pe32.szExeFile,szProcessToKill)){ // checks if process at current position has the name of to be killed app
hProcess = OpenProcess(PROCESS_TERMINATE,0, pe32.th32ProcessID); // gets handle to process
TerminateProcess(hProcess,0); // Terminate process by handle
CloseHandle(hProcess); // close the handle
}
}while(Process32Next(hProcessSnap,&pe32)); // gets next member of snapshot
CloseHandle(hProcessSnap); // closes the snapshot handle
return( TRUE );
}
#endif
void avrOutputDialog::doCopy()
{
char buf[BLKSIZE];
QFile source(sourceFile);
int blocks = (source.size() + BLKSIZE - 1) / BLKSIZE;
ui->progressBar->setMaximum(blocks-1);
if (source.open(QIODevice::ReadOnly)) {
QFile dest(destFile);
if (dest.open(QIODevice::WriteOnly)) {
addText(tr("Writing file: "));
for (int i=0; i<blocks; i++) {
int read = source.read(buf, BLKSIZE);
if (dest.write(buf, read) == read) {
dest.flush();
ui->progressBar->setValue(i);
if ((i%2) != 0)
addText("#");
}
else {
QMessageBox::warning(this, tr("Error"), tr("Write error"));
break;
}
}
dest.close();
}
else {
QMessageBox::warning(this, tr("Error"),tr("Cannot write destination") + ": " + dest.fileName() + ", " + tr("reason") + ": " + dest.errorString());
}
}
else {
QMessageBox::warning(this, tr("Error"),tr("Cannot open source file") + ": " + source.fileName() + ", " + tr("reason") + ": " + source.errorString());
}
source.close();
doFinished(0);
}
void avrOutputDialog::killTimerElapsed()
{
delete kill_timer;
kill_timer = NULL;
# if !__GNUC__
KillProcessByName("tasklist.exe");
#endif
}
avrOutputDialog::~avrOutputDialog()
{
delete ui;
delete kill_timer;
}
void avrOutputDialog::runAgain(QString prog, QStringList arg, int closeBehaviour)
{
cmdLine = prog;
foreach(QString str, arg) cmdLine.append(" " + str);
closeOpt = closeBehaviour;
currLine.clear();
process->start(prog,arg);
}
void avrOutputDialog::waitForFinish()
{
process->waitForFinished();
}
void avrOutputDialog::addText(const QString &text)
{
QTextCursor cursor(ui->plainTextEdit->textCursor());
// is the scrollbar at the end?
bool atEnd = (ui->plainTextEdit->verticalScrollBar()->value() == ui->plainTextEdit->verticalScrollBar()->maximum());
cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor, 1);
cursor.insertText(text);
if (atEnd) {
ui->plainTextEdit->verticalScrollBar()->triggerAction(QAbstractSlider::SliderToMaximum);
}
}
void avrOutputDialog::doAddTextStdOut()
{
QByteArray data = process->readAllStandardOutput();
QString text = QString(data);
QString temp;
int nlPos, pos, size;
addText(text);
currStdLine.append(text);
if (currStdLine.contains("size = ")) {
pos = currStdLine.lastIndexOf("size = ");
temp = currStdLine.mid(pos+7);
pos = temp.lastIndexOf("\n");
size = temp.left(pos).toInt();
ui->progressBar->setMaximum(size/2048);
}
if (currStdLine.contains("\n")) {
nlPos = currStdLine.lastIndexOf("\n");
currStdLine = currStdLine.mid(nlPos+1);
}
if (!currStdLine.isEmpty()) {
if (currStdLine.at(0) == QChar('.')) {
pos = currStdLine.lastIndexOf(".");
ui->progressBar->setValue(pos);
}
else if (currStdLine.startsWith("Starting upload: [")) {
pos = (currStdLine.lastIndexOf("#")-19)/(MAX_FSIZE/204800.0);
ui->progressBar->setValue(pos);
}
}
if (text.contains("Complete ")) {
#if !__GNUC__
delete kill_timer;
kill_timer = NULL;
#endif
int start = text.indexOf("Complete ");
int end = text.indexOf("%");
if (start > 0) {
start += 9;
int value = text.mid(start, end-start).toInt();
ui->progressBar->setValue(value);
}
}
if (text.contains(":010000")) {
//contains fuse info
QStringList stl = text.split(":01000000");
foreach (QString t, stl) {
bool ok = false;
if (!lfuse) lfuse = t.left(2).toInt(&ok,16);
if (!hfuse && !ok) hfuse = t.left(2).toInt(&ok,16);
if (!efuse && !ok) efuse = t.left(2).toInt(&ok,16);
}
}
if (text.contains("-E-")) {
hasErrors = true;
}
}
QString avrOutputDialog::getProgrammer()
{
EEPROMInterface *eepromInterface = GetEepromInterface();
if (IS_TARANIS(eepromInterface->getBoard())) {
return "DFU Util";
}
else if IS_SKY9X(eepromInterface->getBoard()) {
return "SAM-BA";
}
else {
return "AVRDUDE";
}
}
void avrOutputDialog::errorWizard()
{
QString output=ui->plainTextEdit->toPlainText();
if (output.contains("avrdude: Expected signature for")) { // wrong signature
int pos=output.indexOf("avrdude: Device signature = ");
bool fwexist=false;
QString DeviceStr="Unknown";
QString FwStr="";
if (pos>0) {
QString DeviceId=output.mid(pos+28,8);
if (DeviceId=="0x1e9602") {
DeviceStr="Atmega 64";
FwStr="\n"+tr("ie: OpenTX for 9X board or OpenTX for 9XR board");
fwexist=true;
}
else if (DeviceId=="0x1e9702") {
DeviceStr="Atmega 128";
FwStr="\n"+tr("ie: OpenTX for M128 / 9X board or OpenTX for 9XR board with M128 chip");
fwexist=true;
}
else if (DeviceId=="0x1e9703") {
DeviceStr="Atmega 1280";
}
else if (DeviceId=="0x1e9704") {
DeviceStr="Atmega 1281";
}
else if (DeviceId=="0x1e9801") {
DeviceStr="Atmega 2560";
FwStr="\n"+tr("ie: OpenTX for Gruvin9X board");
fwexist=true;
}
else if (DeviceId=="0x1e9802") {
DeviceStr="Atmega 2561";
}
}
if (fwexist==false) {
QMessageBox::warning(this, "Companion - Tip of the day", tr("Your radio uses a %1 CPU!!!\n\nPlease check advanced burn options to set the correct cpu type.").arg(DeviceStr));
}
else {
FirmwareInterface *firmware = GetCurrentFirmware();
QMessageBox::warning(this, "Companion - Tip of the day", tr("Your radio uses a %1 CPU!!!\n\nPlease select an appropriate firmware type to program it.").arg(DeviceStr)+FwStr+tr("\nYou are currently using:\n %1").arg(firmware->getName()));
}
}
}
void avrOutputDialog::doAddTextStdErr()
{
int nlPos;
int pbvalue;
QString avrphase;
QByteArray data = process->readAllStandardError();
QString text = QString(data);
currLine.append(text);
if (currLine.contains("#")) {
avrphase = currLine.left(1).toLower();
if (avrphase=="w") {
ui->progressBar->setStyleSheet("QProgressBar {text-align: center;} QProgressBar::chunk { background-color: #ff0000; text-align:center;}:");
phase=1;
if(winTitle.isEmpty())
setWindowTitle(getProgrammer() + " - " + tr("Writing"));
else
setWindowTitle(getProgrammer() + " - " + winTitle + " - " + tr("Writing"));
pbvalue=currLine.count("#")*2;
ui->progressBar->setValue(pbvalue);
}
else if (avrphase=="r") {
if (phase==0) {
ui->progressBar->setStyleSheet("QProgressBar {text-align: center;} QProgressBar::chunk { background-color: #00ff00; text-align:center;}:");
if(winTitle.isEmpty())
setWindowTitle(getProgrammer() + " - " + tr("Reading"));
else
setWindowTitle(getProgrammer() + " - " + winTitle + " - " + tr("Reading"));
}
else {
ui->progressBar->setStyleSheet("QProgressBar {text-align: center;} QProgressBar::chunk { background-color: #0000ff; text-align:center;}:");
phase=2;
if(winTitle.isEmpty())
setWindowTitle(getProgrammer() + " - " + tr("Verifying"));
else
setWindowTitle(getProgrammer() + " - " + winTitle + " - " + tr("Verifying"));
}
pbvalue=currLine.count("#")*2;
ui->progressBar->setValue(pbvalue);
}
}
if (currLine.contains("\n")) {
nlPos = currLine.lastIndexOf("\n");
currLine = currLine.mid(nlPos+1);
}
if (text.contains("-E-") && !text.contains("-E- No receive file name")) {
hasErrors = true;
}
addText(text);
}
#define HLINE_SEPARATOR "================================================================================="
void avrOutputDialog::doFinished(int code=0)
{
addText("\n" HLINE_SEPARATOR);
if (code==1 && getProgrammer()=="SAM-BA")
code=0;
if (code) {
ui->checkBox->setChecked(true);
addText("\n" + getProgrammer() + " " + tr("done - exit code %1").arg(code));
}
else if (hasErrors) {
ui->checkBox->setChecked(true);
addText("\n" + getProgrammer() + " " + tr("done with errors"));
}
else if (!cmdLine.isEmpty()) {
addText("\n" + getProgrammer() + " " + tr("done - SUCCESSFUL"));
}
else {
addText(tr("done - SUCCESSFUL"));
}
addText("\n" HLINE_SEPARATOR "\n");
if(lfuse || hfuse || efuse) {
addReadFuses();
}
switch(closeOpt)
{
case AVR_DIALOG_CLOSE_IF_SUCCESSFUL:
if (!hasErrors && !code) accept();
if (code) {
errorWizard();
}
break;
case AVR_DIALOG_FORCE_CLOSE:
if (hasErrors || code)
reject();
else
accept();
break;
case AVR_DIALOG_SHOW_DONE:
if (hasErrors || code) {
if (!cmdLine.isEmpty()) {
if (getProgrammer()!="AVRDUDE") {
QMessageBox::critical(this, "Companion", getProgrammer() + " " + tr("did not finish correctly"));
}
else {
int res = QMessageBox::question(this, "Companion",getProgrammer() + " " + tr("did not finish correctly!\nDo you want some help ?"),QMessageBox::Yes | QMessageBox::No);
if (res != QMessageBox::No) {
errorWizard();
}
}
}
else {
QMessageBox::critical(this, "Companion", tr("Copy did not finish correctly"));
}
// reject();
}
else {
if (!cmdLine.isEmpty()) {
ui->progressBar->setValue(ui->progressBar->maximum());
QMessageBox::information(this, "Companion", getProgrammer() + " " + tr("finished correctly"));
accept();
}
else {
QMessageBox::information(this, "Companion", tr("Copy finished correctly"));
accept();
}
}
break;
default: //AVR_DIALOG_KEEP_OPEN
break;
}
}
void avrOutputDialog::doProcessStarted()
{
addText(HLINE_SEPARATOR "\n");
addText(tr("Started") + " " + getProgrammer() + "\n");
addText(cmdLine);
addText("\n" HLINE_SEPARATOR "\n");
}
void avrOutputDialog::addReadFuses()
{
addText(HLINE_SEPARATOR "\n");
addText(tr("FUSES: Low=%1 High=%2 Ext=%3").arg(lfuse,2,16,QChar('0')).arg(hfuse,2,16,QChar('0')).arg(efuse,2,16,QChar('0')));
addText("\n" HLINE_SEPARATOR "\n");
}
void avrOutputDialog::on_checkBox_toggled(bool checked)
{
if (checked) {
ui->plainTextEdit->show();
}
else {
ui->plainTextEdit->hide();
QTimer::singleShot(0, this, SLOT(shrink()));
}
}
void avrOutputDialog::shrink()
{
resize(0,0);
}
void avrOutputDialog::forceClose()
{
accept();
}

View file

@ -1,65 +0,0 @@
#ifndef AVROUTPUTDIALOG_H
#define AVROUTPUTDIALOG_H
#include <QDialog>
#include <QtGui>
#define AVR_DIALOG_CLOSE_IF_SUCCESSFUL 0x00
#define AVR_DIALOG_KEEP_OPEN 0x01
#define AVR_DIALOG_FORCE_CLOSE 0x02
#define AVR_DIALOG_SHOW_DONE 0x04
#define READBUF 65536
#define BLKSIZE 512
namespace Ui {
class avrOutputDialog;
}
class avrOutputDialog : public QDialog
{
Q_OBJECT
public:
explicit avrOutputDialog(QWidget *parent, QString prog, QStringList arg, QString wTitle, int closeBehaviour=AVR_DIALOG_CLOSE_IF_SUCCESSFUL, bool displayDetails=false);
~avrOutputDialog();
void addText(const QString &text);
void runAgain(QString prog, QStringList arg, int closeBehaviour=AVR_DIALOG_CLOSE_IF_SUCCESSFUL);
void waitForFinish();
void addReadFuses();
protected slots:
void doAddTextStdOut();
void doAddTextStdErr();
void doProcessStarted();
void doCopy();
void doFinished(int code);
void on_checkBox_toggled(bool checked);
void shrink();
void forceClose();
void killTimerElapsed();
void errorWizard();
private:
QString getProgrammer();
Ui::avrOutputDialog *ui;
QProcess *process;
QTimer *kill_timer;
QString cmdLine;
int closeOpt;
quint8 lfuse;
quint8 hfuse;
quint8 efuse;
QString currLine;
QString currStdLine;
int phase;
QString winTitle;
bool hasErrors;
QString sourceFile;
QString destFile;
};
#endif // AVROUTPUTDIALOG_H

View file

@ -1,10 +1,10 @@
#include "burnconfigdialog.h" #include "burnconfigdialog.h"
#include "ui_burnconfigdialog.h" #include "ui_burnconfigdialog.h"
#include "avroutputdialog.h"
#include "eeprominterface.h" #include "eeprominterface.h"
#include "helpers.h" #include "helpers.h"
#include "appdata.h" #include "appdata.h"
#include <QtGui> #include "progressdialog.h"
#include "process_flash.h"
#if !defined WIN32 && defined __GNUC__ #if !defined WIN32 && defined __GNUC__
#include <unistd.h> #include <unistd.h>
@ -123,7 +123,7 @@ void burnConfigDialog::getSettings()
sambaPort = g.sambaPort(); sambaPort = g.sambaPort();
ui->avrdude_location->setText(getAVRDUDE()); ui->avrdude_location->setText(getAVRDUDE());
ui->avrArgs->setText(getAVRArgs().join(" ")); ui->avrArgs->setText(avrArgs.join(" "));
ui->samba_location->setText(getSAMBA()); ui->samba_location->setText(getSAMBA());
ui->samba_port->setText(getSambaPort()); ui->samba_port->setText(getSambaPort());
@ -285,118 +285,25 @@ void burnConfigDialog::on_dfuArgs_editingFinished()
dfuArgs = ui->dfuArgs->text().split(" ", QString::SkipEmptyParts); dfuArgs = ui->dfuArgs->text().split(" ", QString::SkipEmptyParts);
} }
void burnConfigDialog::listProgrammers() void burnConfigDialog::listAvrdudeProgrammers()
{ {
QStringList arguments; ProgressDialog progressDialog(this, tr("List available programmers"), CompanionIcon("list.png"), true);
arguments << "-c?"; FlashProcess flashProcess(ui->avrdude_location->text(), QStringList() << "-c?", progressDialog.progress());
avrOutputDialog *ad = new avrOutputDialog(this, ui->avrdude_location->text(), arguments, "List available programmers", AVR_DIALOG_KEEP_OPEN, TRUE); flashProcess.run();
ad->setWindowIcon(CompanionIcon("list.png"));
ad->show();
delete ad;
} }
// TODO choose better name when no merge in progress....
void burnConfigDialog::on_pushButton_3_clicked() void burnConfigDialog::on_pushButton_3_clicked()
{ {
listProgrammers(); listAvrdudeProgrammers();
} }
// TODO choose better name when no merge in progress....
void burnConfigDialog::on_pushButton_4_clicked() void burnConfigDialog::on_pushButton_4_clicked()
{ {
QStringList arguments; ProgressDialog progressDialog(this, tr("Avrdude help"), CompanionIcon("configure.png"), true);
arguments << "-?"; FlashProcess flashProcess(ui->avrdude_location->text(), QStringList() << "-?", progressDialog.progress());
flashProcess.run();
avrOutputDialog *ad = new avrOutputDialog(this, ui->avrdude_location->text(), arguments, "Show help", AVR_DIALOG_KEEP_OPEN,TRUE);
ad->setWindowIcon(CompanionIcon("configure.png"));
ad->show();
delete ad;
}
void burnConfigDialog::readFuses()
{
QStringList args = avrArgs;
if(!avrPort.isEmpty()) args << "-P" << avrPort;
QStringList str;
str << "-U" << "lfuse:r:-:i" << "-U" << "hfuse:r:-:i" << "-U" << "efuse:r:-:i";
QStringList arguments;
arguments << "-c" << avrProgrammer << "-p" << avrMCU << args << str;
avrOutputDialog *ad = new avrOutputDialog(this, avrLoc, arguments, "Read Fuses",AVR_DIALOG_KEEP_OPEN,TRUE);
ad->setWindowIcon(CompanionIcon("fuses.png"));
ad->show();
delete ad;
}
void burnConfigDialog::restFuses(bool eeProtect)
{
//fuses
//avrdude -c usbasp -p m64 -U lfuse:w:<0x0E>:m
//avrdude -c usbasp -p m64 -U hfuse:w:<0x89>:m 0x81 for eeprom protection
//avrdude -c usbasp -p m64 -U efuse:w:<0xFF>:m
QMessageBox::StandardButton ret = QMessageBox::No;
ret = QMessageBox::warning(this, tr("Companion"),
tr("<b><u>WARNING!</u></b><br>This will reset the fuses of %1 to the factory settings.<br>Writing fuses can mess up your radio.<br>Do this only if you are sure they are wrong!<br>Are you sure you want to continue?").arg(avrMCU),
QMessageBox::Yes | QMessageBox::No);
if (ret == QMessageBox::Yes)
{
QStringList args = avrArgs;
if(!avrPort.isEmpty()) args << "-P" << avrPort;
QStringList str;
if (avrMCU=="m2560") {
args << "-B8";
QString erStr = eeProtect ? "hfuse:w:0x11:m" : "hfuse:w:0x19:m";
str << "-U" << "lfuse:w:0xD7:m" << "-U" << erStr << "-U" << "efuse:w:0xFC:m";
//use hfuse = 0x81 to prevent eeprom being erased with every flashing
}
else {
QString lfuses;
QString tempFile = generateProcessUniqueTempFileName("ftemp.bin");
QStringList argread;
argread << "-c" << avrProgrammer << "-p" << avrMCU << args <<"-U" << "lfuse:r:"+tempFile+":r" ;
avrOutputDialog *ad = new avrOutputDialog(this, avrLoc, argread, "Reset Fuses",AVR_DIALOG_CLOSE_IF_SUCCESSFUL,FALSE);
ad->setWindowIcon(CompanionIcon("fuses.png"));
ad->exec();
delete ad;
QFile file(tempFile);
if (file.exists() && file.size()==1) {
file.open(QIODevice::ReadOnly);
char bin_flash[1];
file.read(bin_flash, 1);
if (bin_flash[0]==0x0E) {
lfuses="lfuse:w:0x0E:m";
}
else {
lfuses="lfuse:w:0x3F:m";
}
file.close();
qunlink(tempFile);
}
else {
lfuses="lfuse:w:0x3F:m";
}
QString erStr = eeProtect ? "hfuse:w:0x81:m" : "hfuse:w:0x89:m";
str << "-U" << lfuses << "-U" << erStr << "-U" << "efuse:w:0xFF:m";
//use hfuse = 0x81 to prevent eeprom being erased with every flashing
}
QStringList arguments;
if (avrMCU=="m2560") {
arguments << "-c" << avrProgrammer << "-p" << avrMCU << args << "-u" << str;
}
else {
arguments << "-c" << avrProgrammer << "-p" << avrMCU << args << "-B" << "100" << "-u" << str;
}
avrOutputDialog *ad = new avrOutputDialog(this, avrLoc, arguments, "Reset Fuses",AVR_DIALOG_KEEP_OPEN,TRUE);
ad->setWindowIcon(CompanionIcon("fuses.png"));
ad->show();
delete ad;
}
} }
void burnConfigDialog::on_advCtrChkB_toggled(bool checked) void burnConfigDialog::on_advCtrChkB_toggled(bool checked)

View file

@ -1,5 +1,5 @@
#ifndef BURNCONFIGDIALOG_H #ifndef BURNCONFIGDIALOG_H_
#define BURNCONFIGDIALOG_H #define BURNCONFIGDIALOG_H_
#include <QDialog> #include <QDialog>
#include <QtGui> #include <QtGui>
@ -23,7 +23,7 @@ public:
QString getAVRDUDE() {return avrLoc;} QString getAVRDUDE() {return avrLoc;}
QString getSAMBA() {return sambaLoc;} QString getSAMBA() {return sambaLoc;}
QString getDFU() {return dfuLoc;} QString getDFU() {return dfuLoc;}
QStringList getAVRArgs() {return avrArgs;} QStringList getAvrdudeArgs() { QStringList args = avrArgs; if (!avrPort.isEmpty()) args << "-P" << avrPort; return args; }
QStringList getDFUArgs() {return dfuArgs;} QStringList getDFUArgs() {return dfuArgs;}
QString getProgrammer() {return avrProgrammer;} QString getProgrammer() {return avrProgrammer;}
QString getMCU() {return avrMCU;} QString getMCU() {return avrMCU;}
@ -31,9 +31,7 @@ public:
QString getPort() {return avrPort;} QString getPort() {return avrPort;}
QString getSambaPort() {return sambaPort;} QString getSambaPort() {return sambaPort;}
void listProgrammers(); void listAvrdudeProgrammers();
void restFuses(bool eeProtect);
void readFuses();
private: private:
Ui::burnConfigDialog *ui; Ui::burnConfigDialog *ui;
@ -73,4 +71,4 @@ private slots:
void putSettings(); void putSettings();
}; };
#endif // BURNCONFIGDIALOG_H #endif // BURNCONFIGDIALOG_H_

View file

@ -1,615 +0,0 @@
#include "burndialog.h"
#include "ui_burndialog.h"
#include <QtGui>
#include "eeprominterface.h"
#include "helpers.h"
#include "splashlibrary.h"
#include "flashinterface.h"
#include "hexinterface.h"
#include "appdata.h"
// Type 1 = Burn EEPROM, Type 2= Burn Flash
burnDialog::burnDialog(QWidget *parent, int Type, QString * fileName, bool * backupEE, QString DocName):
QDialog(parent),
ui(new Ui::burnDialog),
hexfileName(fileName),
backup(backupEE),
hexType(Type)
{
ui->setupUi(this);
setWindowIcon(CompanionIcon("write_flash.png"));
if (!g.profile[g.id()].splashFile().isEmpty()){
imageSource=PROFILE;
imageFile=g.profile[g.id()].splashFile();
}
else {
ui->useProfileImageCB->setDisabled(true);
imageSource=FIRMWARE;
imageFile="";
}
ui->SplashFrame->hide();
ui->FramFWInfo->hide();
ui->EEbackupCB->hide();
ui->EEbackupCB->setCheckState(*backup ? Qt::Checked : Qt::Unchecked);
if (Type == FLASH_FILE_TYPE ) {
ui->EEpromCB->hide();
ui->profile_label->hide();
ui->patchcalib_CB->hide();
ui->patchhw_CB->hide();
setWindowTitle(tr("Write firmware to Radio"));
if (IS_TARANIS(GetEepromInterface()->getBoard())) {
ui->EEbackupCB->hide();
}
}
else {
ui->FlashLoadButton->setText(tr("Browse for file"));
ui->profile_label->hide();
ui->patchcalib_CB->hide();
ui->patchhw_CB->hide();
ui->EEpromCB->hide();
ui->BurnFlashButton->setDisabled(true);
ui->FWFileName->clear();
ui->DateField->clear();
ui->versionField->clear();
ui->ModField->clear();
ui->FramFWInfo->hide();
ui->SplashFrame->hide();
ui->BurnFlashButton->setDisabled(true);
ui->EEbackupCB->hide();
if (DocName.isEmpty()) {
setWindowTitle(tr("Write Backup to Radio"));
}
else {
setWindowTitle(tr("Write Backup from %1 to Radio").arg(DocName));
}
ui->profile_label->setText(tr("Current profile")+QString(": ")+g.profile[g.id()].name());
}
if (!hexfileName->isEmpty()) {
ui->FWFileName->setText(*hexfileName);
if (Type==FLASH_FILE_TYPE) {
checkFw(*hexfileName);
}
else {
burnraw=false;
if (checkeEprom(*hexfileName)) {
QString Name = g.profile[g.id()].name();
QString calib = g.profile[g.id()].stickPotCalib();
QString trainercalib = g.profile[g.id()].trainerCalib();
QString DisplaySet = g.profile[g.id()].display();
QString BeeperSet = g.profile[g.id()].beeper();
QString HapticSet = g.profile[g.id()].haptic();
QString SpeakerSet = g.profile[g.id()].speaker();
if (!Name.isEmpty()) {
ui->profile_label->show();
ui->patchcalib_CB->show();
ui->patchhw_CB->show();
// TODO I hardcode the number of pots here, should be dependant on the board?
if (!((calib.length()==(NUM_STICKS+3)*12) && (trainercalib.length()==16))) {
ui->patchcalib_CB->setDisabled(true);
}
if (!((DisplaySet.length()==6) && (BeeperSet.length()==4) && (HapticSet.length()==6) && (SpeakerSet.length()==6))) {
ui->patchhw_CB->setDisabled(true);
}
}
else {
ui->profile_label->hide();
}
if (!IS_TARANIS(GetEepromInterface()->getBoard())) {
ui->EEpromCB->show();
}
else {
ui->EEpromCB->setChecked(false);
}
ui->BurnFlashButton->setEnabled(true);
}
}
ui->FWFileName->hide();
ui->FlashLoadButton->hide();
hexfileName->clear();
}
else if (Type==FLASH_FILE_TYPE) {
QString FileName = g.profile[g.id()].fwName();
QFile file(FileName);
if (file.exists()) {
checkFw(FileName);
}
}
updateUI();
resize(0, 0);
}
burnDialog::~burnDialog()
{
delete ui;
}
void burnDialog::on_FlashLoadButton_clicked()
{
QString fileName;
ui->BurnFlashButton->setDisabled(true);
ui->FWFileName->clear();
ui->DateField->clear();
ui->versionField->clear();
ui->ModField->clear();
ui->FramFWInfo->hide();
ui->SplashFrame->hide();
ui->BurnFlashButton->setDisabled(true);
ui->EEbackupCB->hide();
QTimer::singleShot(0, this, SLOT(shrink()));
if (hexType==FLASH_FILE_TYPE) {
fileName = QFileDialog::getOpenFileName(this, tr("Open Firmware File"), g.flashDir(), FLASH_FILES_FILTER);
if(fileName.isEmpty())
return;
checkFw(fileName);
}
else {
QString fileName = QFileDialog::getOpenFileName(this,tr("Choose Radio Backup file"), g.eepromDir(), tr(EXTERNAL_EEPROM_FILES_FILTER));
if (checkeEprom(fileName)) {
if (burnraw==false) {
ui->BurnFlashButton->setEnabled(true);
ui->profile_label->show();
ui->patchcalib_CB->show();
ui->patchhw_CB->show();
if (!IS_TARANIS(GetEepromInterface()->getBoard())) {
ui->EEpromCB->show();
}
else {
ui->EEpromCB->setChecked(false);
}
}
else {
ui->BurnFlashButton->setEnabled(true);
ui->profile_label->hide();
ui->patchcalib_CB->setChecked(false);
ui->patchhw_CB->setChecked(false);
ui->patchhw_CB->hide();
ui->patchcalib_CB->hide();
}
QTimer::singleShot(0, this, SLOT(shrink()));
}
}
updateUI();
}
void burnDialog::checkFw(QString fileName)
{
if (fileName.isEmpty()) {
return;
}
if (!IS_TARANIS(GetEepromInterface()->getBoard())) {
ui->EEbackupCB->show();
}
else {
ui->EEbackupCB->setChecked(false);
*backup=false;
}
ui->FWFileName->setText(fileName);
FlashInterface flash(fileName);
if (flash.isValid()) {
ui->FramFWInfo->show();
ui->DateField->setText(flash.getDate() + " " + flash.getTime());
ui->versionField->setText(flash.getVersion());
ui->ModField->setText(flash.getEEpromId());
ui->SplashFrame->hide();
if (flash.hasSplash()) {
ui->SplashFrame->show();
ui->imageLabel->setFixedSize(flash.getSplashWidth(), flash.getSplashHeight());
}
}
else {
QMessageBox::warning(this, tr("Warning"), tr("%1 may not be a valid firmware file").arg(fileName));
}
ui->BurnFlashButton->setEnabled(true);
QTimer::singleShot(0, this, SLOT(shrink()));
g.flashDir( QFileInfo(fileName).dir().absolutePath() );
}
bool burnDialog::checkeEprom(QString fileName)
{
if (fileName.isEmpty()) {
return false;
}
QFile file(fileName);
if (!file.exists()) {
QMessageBox::critical(this, tr("Error"), tr("Unable to find file %1!").arg(fileName));
return false;
}
burnraw=false;
int fileType = getFileType(fileName);
#if 0
if (fileType==FILE_TYPE_XML) {
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { //reading HEX TEXT file
QMessageBox::critical(this, tr("Error"),tr("Error opening file %1:\n%2.").arg(fileName).arg(file.errorString()));
return false;
}
QTextStream inputStream(&file);
XmlInterface(inputStream).load(radioData);
}
else
#endif
if (fileType==FILE_TYPE_HEX || fileType==FILE_TYPE_EEPE) { //read HEX file
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { //reading HEX TEXT file
QMessageBox::critical(this, tr("Error"),tr("Error opening file %1:\n%2.").arg(fileName).arg(file.errorString()));
return false;
}
QDomDocument doc(ER9X_EEPROM_FILE_TYPE);
bool xmlOK = doc.setContent(&file);
if(xmlOK) {
if (!LoadEepromXml(radioData, doc)){
return false;
}
}
file.reset();
QTextStream inputStream(&file);
if (fileType==FILE_TYPE_EEPE) { // read EEPE file header
QString hline = inputStream.readLine();
if (hline!=EEPE_EEPROM_FILE_HEADER) {
file.close();
return false;
}
}
uint8_t eeprom[EESIZE_RLC_MAX];
int eeprom_size = HexInterface(inputStream).load(eeprom, EESIZE_RLC_MAX);
if (!eeprom_size) {
int res = QMessageBox::question(this, "Companion",tr("Invalid binary Models and Settings File %1, Proceed anyway ?").arg(fileName),QMessageBox::Yes | QMessageBox::No);
if (res == QMessageBox::No) {
return false;
}
burnraw=true;
ui->FWFileName->setText(fileName);
return true;
}
file.close();
if (!LoadEeprom(radioData, eeprom, eeprom_size)) {
int res = QMessageBox::question(this, "Companion",tr("Invalid binary Models and Settings File %1, Proceed anyway ?").arg(fileName),QMessageBox::Yes | QMessageBox::No);
if (res == QMessageBox::No) {
return false;
}
burnraw=true;
ui->FWFileName->setText(fileName);
return true;
}
}
else if (fileType==FILE_TYPE_BIN) { //read binary
int eeprom_size = file.size();
if (!file.open(QFile::ReadOnly)) { //reading binary file - TODO HEX support
QMessageBox::critical(this, tr("Error"),tr("Error opening file %1:\n%2.").arg(fileName).arg(file.errorString()));
return false;
}
uint8_t *eeprom = (uint8_t *)malloc(eeprom_size);
memset(eeprom, 0, eeprom_size);
long result = file.read((char*)eeprom, eeprom_size);
file.close();
if (result != eeprom_size) {
QMessageBox::critical(this, tr("Error"),tr("Error reading file %1:\n%2.").arg(fileName).arg(file.errorString()));
return false;
}
if (!LoadEeprom(radioData, eeprom, eeprom_size)) {
int res = QMessageBox::question(this, "Companion",tr("Invalid binary Models and Settings File %1, Proceed anyway ?").arg(fileName),QMessageBox::Yes | QMessageBox::No);
if (res == QMessageBox::No) {
return false;
}
burnraw=true;
}
}
ui->FWFileName->setText(fileName);
return true;
}
void burnDialog::displaySplash()
{
QImage image;
if (imageSource == FIRMWARE){
FlashInterface flash(ui->FWFileName->text());
image = flash.getSplash();
}
else {
image.load(imageFile);
}
if (image.isNull()) {
return;
}
ui->imageLabel->setPixmap( makePixMap( image, g.profile[g.id()].fwType()));
}
void burnDialog::updateUI()
{
if (hexType==EEPROM_FILE_TYPE)
return;
ui->useProfileImageCB->setChecked( imageSource == PROFILE );
ui->useFwImageCB->setChecked( imageSource == FIRMWARE );
ui->useLibraryImageCB->setChecked( imageSource == LIBRARY );
ui->useAnotherImageCB->setChecked( imageSource == ANOTHER );
displaySplash();
}
void burnDialog::on_useFwImageCB_clicked()
{
QString fileName = ui->FWFileName->text();
FlashInterface flash(fileName);
if (!flash.isValid()) {
QMessageBox::critical(this, tr("Error"), tr( "The firmware file is not valid." ));
}
else {
if (!flash.hasSplash()) {
QMessageBox::critical(this, tr("Error"), tr( "There is no start screen image in the firmware file." ));
}
else{
imageSource = FIRMWARE;
imageFile = fileName;
}
}
updateUI();
}
void burnDialog::on_useProfileImageCB_clicked()
{
QString fileName = g.profile[g.id()].splashFile();
if (!fileName.isEmpty()){
QImage image(fileName);
if (image.isNull()) {
QMessageBox::critical(this, tr("Error"), tr("Profile image %1 is invalid.").arg(fileName));
}
else {
imageSource = PROFILE;
imageFile = fileName;
}
}
updateUI();
}
void burnDialog::on_useAnotherImageCB_clicked()
{
QString supportedImageFormats;
for (int formatIndex = 0; formatIndex < QImageReader::supportedImageFormats().count(); formatIndex++) {
supportedImageFormats += QLatin1String(" *.") + QImageReader::supportedImageFormats()[formatIndex];
}
QString fileName = QFileDialog::getOpenFileName(this, tr("Open image file to use as radio start screen"), g.imagesDir(), tr("Images (%1)").arg(supportedImageFormats));
if (!fileName.isEmpty()){
g.imagesDir( QFileInfo(fileName).dir().absolutePath() );
QImage image(fileName);
if (image.isNull()) {
QMessageBox::critical(this, tr("Error"), tr("Image could not be loaded from %1").arg(fileName));
}
else{
imageSource = ANOTHER;
imageFile = fileName;
}
}
updateUI();
}
void burnDialog::on_useLibraryImageCB_clicked()
{
QString fileName;
splashLibrary *ld = new splashLibrary(this,&fileName);
ld->exec();
if (!fileName.isEmpty()) {
QImage image(fileName);
if (image.isNull()) {
QMessageBox::critical(this, tr("Error"), tr("The library image could not be loaded"));
}
else{
imageSource = LIBRARY;
imageFile = fileName;
}
}
updateUI();
}
void burnDialog::on_BurnFlashButton_clicked()
{
if (hexType==FLASH_FILE_TYPE) {
QString fileName=ui->FWFileName->text();
if (!fileName.isEmpty()) {
g.flashDir( QFileInfo(fileName).dir().absolutePath() );
if (!ui->useFwImageCB->isChecked()) {
const QPixmap * pixmap = ui->imageLabel->pixmap();
QImage image;
if (pixmap) {
image = pixmap->toImage().scaled(ui->imageLabel->width(), ui->imageLabel->height());
}
if (!image.isNull()) {
QString tempFile;
if (getFileType(fileName) == FILE_TYPE_HEX)
tempFile = generateProcessUniqueTempFileName("flash.hex");
else
tempFile = generateProcessUniqueTempFileName("flash.bin");
FlashInterface flash(fileName);
flash.setSplash(image);
if (flash.saveFlash(tempFile) > 0) {
hexfileName->clear();
hexfileName->append(tempFile);
}
else {
hexfileName->clear();
QMessageBox::critical(this, tr("Warning"), tr("Cannot save customized firmware"));
}
}
else {
hexfileName->clear();
QMessageBox::critical(this, tr("Warning"), tr("Custom image not found"));
}
}
else {
hexfileName->clear();
hexfileName->append(fileName);
}
}
else {
QMessageBox::critical(this, tr("Warning"), tr("No firmware selected"));
hexfileName->clear();
}
}
if (hexType==EEPROM_FILE_TYPE) {
QString calib = g.profile[g.id()].stickPotCalib();
QString trainercalib = g.profile[g.id()].trainerCalib();
int potsnum=GetCurrentFirmware()->getCapability(Pots);
int8_t vBatCalib=(int8_t) g.profile[g.id()].vBatCalib();
int8_t currentCalib=(int8_t) g.profile[g.id()].currentCalib();
int8_t PPM_Multiplier=(int8_t) g.profile[g.id()].ppmMultiplier();
uint8_t GSStickMode=(uint8_t) g.profile[g.id()].gsStickMode();
uint8_t vBatWarn=(uint8_t) g.profile[g.id()].vBatWarn();
QString DisplaySet= g.profile[g.id()].display();
QString BeeperSet= g.profile[g.id()].beeper();
QString HapticSet= g.profile[g.id()].haptic();
QString SpeakerSet= g.profile[g.id()].speaker();
bool patch=false;
if (ui->patchcalib_CB->isChecked()) {
if ((calib.length()==(NUM_STICKS+potsnum)*12) && (trainercalib.length()==16)) {
QString Byte;
int16_t byte16;
bool ok;
for (int i=0; i<(NUM_STICKS+potsnum); i++) {
Byte=calib.mid(i*12,4);
byte16=(int16_t)Byte.toInt(&ok,16);
if (ok)
radioData.generalSettings.calibMid[i]=byte16;
Byte=calib.mid(4+i*12,4);
byte16=(int16_t)Byte.toInt(&ok,16);
if (ok)
radioData.generalSettings.calibSpanNeg[i]=byte16;
Byte=calib.mid(8+i*12,4);
byte16=(int16_t)Byte.toInt(&ok,16);
if (ok)
radioData.generalSettings.calibSpanPos[i]=byte16;
}
for (int i=0; i<4; i++) {
Byte=trainercalib.mid(i*4,4);
byte16=(int16_t)Byte.toInt(&ok,16);
if (ok)
radioData.generalSettings.trainer.calib[i]=byte16;
}
radioData.generalSettings.currentCalib=currentCalib;
radioData.generalSettings.vBatCalib=vBatCalib;
radioData.generalSettings.PPM_Multiplier=PPM_Multiplier;
patch=true;
}
else {
QMessageBox::critical(this, tr("Warning"), tr("Wrong radio calibration data in profile, Settings not patched"));
}
}
if (ui->patchhw_CB->isChecked()) {
if ((DisplaySet.length()==6) && (BeeperSet.length()==4) && (HapticSet.length()==6) && (SpeakerSet.length()==6)) {
radioData.generalSettings.vBatWarn=vBatWarn;
radioData.generalSettings.stickMode=GSStickMode;
uint8_t byte8u;
int8_t byte8;
bool ok;
byte8=(int8_t)DisplaySet.mid(0,2).toInt(&ok,16);
if (ok)
radioData.generalSettings.optrexDisplay=(byte8==1 ? true : false);
byte8u=(uint8_t)DisplaySet.mid(2,2).toUInt(&ok,16);
if (ok)
radioData.generalSettings.contrast=byte8u;
byte8u=(uint8_t)DisplaySet.mid(4,2).toUInt(&ok,16);
if (ok)
radioData.generalSettings.backlightBright=byte8u;
byte8u=(uint8_t)BeeperSet.mid(0,2).toUInt(&ok,16);
if (ok)
radioData.generalSettings.beeperMode=(GeneralSettings::BeeperMode)byte8u;
byte8=(int8_t)BeeperSet.mid(2,2).toInt(&ok,16);
if (ok)
radioData.generalSettings.beeperLength=byte8;
byte8u=(uint8_t)HapticSet.mid(0,2).toUInt(&ok,16);
if (ok)
radioData.generalSettings.hapticMode=(GeneralSettings::BeeperMode)byte8u;
byte8u=(uint8_t)HapticSet.mid(2,2).toUInt(&ok,16);
if (ok)
radioData.generalSettings.hapticStrength=byte8u;
byte8=(int8_t)HapticSet.mid(4,2).toInt(&ok,16);
if (ok)
radioData.generalSettings.hapticLength=byte8;
byte8u=(uint8_t)SpeakerSet.mid(0,2).toUInt(&ok,16);
if (ok)
radioData.generalSettings.speakerMode=byte8u;
byte8u=(uint8_t)SpeakerSet.mid(2,2).toUInt(&ok,16);
if (ok)
radioData.generalSettings.speakerPitch=byte8u;
byte8u=(uint8_t)SpeakerSet.mid(4,2).toUInt(&ok,16);
if (ok)
radioData.generalSettings.speakerVolume=byte8u;
patch=true;
}
else {
QMessageBox::critical(this, tr("Warning"), tr("Wrong radio setting data in profile, Settings not patched"));
}
if (patch) {
QString fileName = generateProcessUniqueTempFileName("temp.bin");
QFile file(fileName);
uint8_t *eeprom = (uint8_t*)malloc(GetEepromInterface()->getEEpromSize());
int eeprom_size = GetEepromInterface()->save(eeprom, radioData, GetCurrentFirmware()->getVariantNumber());
if (!eeprom_size) {
QMessageBox::warning(this, tr("Error"),tr("Cannot write file %1:\n%2.").arg(fileName).arg(file.errorString()));
hexfileName->clear();
}
if (!file.open(QIODevice::WriteOnly)) {
QMessageBox::warning(this, tr("Error"),tr("Cannot write file %1:\n%2.").arg(fileName).arg(file.errorString()));
hexfileName->clear();
}
QTextStream outputStream(&file);
long result = file.write((char*)eeprom, eeprom_size);
if (result != eeprom_size) {
QMessageBox::warning(this, tr("Error"),tr("Error writing file %1:\n%2.").arg(fileName).arg(file.errorString()));
}
hexfileName->clear();
hexfileName->append(fileName);
}
else {
hexfileName->clear();
hexfileName->append(ui->FWFileName->text());
}
}
else {
hexfileName->clear();
hexfileName->append(ui->FWFileName->text());
}
}
this->close();
}
void burnDialog::on_cancelButton_clicked()
{
hexfileName->clear();
this->close();
}
void burnDialog::on_EEpromCB_toggled(bool checked)
{
*backup = ui->EEpromCB->isChecked();
}
void burnDialog::shrink()
{
resize(0,0);
}
void burnDialog::on_EEbackupCB_clicked()
{
*backup = ui->EEbackupCB->isChecked();
}

View file

@ -1,66 +0,0 @@
#ifndef BURNDIALOG_H
#define BURNDIALOG_H
#include <QtGui>
#include <QDialog>
#include "eeprominterface.h"
#include "flashinterface.h"
#include "xmlinterface.h"
#define HEX_FILES_FILTER "HEX files (*.hex);;"
#define BIN_FILES_FILTER "BIN files (*.bin);;"
#define EEPE_FILES_FILTER "EEPE EEPROM files (*.eepe);;"
#define EEPROM_FILES_FILTER "EEPE files (*.eepe *.bin *.hex);;" EEPE_FILES_FILTER BIN_FILES_FILTER HEX_FILES_FILTER
#define FLASH_FILES_FILTER "FLASH files (*.bin *.hex);;" BIN_FILES_FILTER HEX_FILES_FILTER
#define EXTERNAL_EEPROM_FILES_FILTER "EEPROM files (*.bin *.hex);;" BIN_FILES_FILTER HEX_FILES_FILTER
#define ER9X_EEPROM_FILE_TYPE "ER9X_EEPROM_FILE"
#define EEPE_EEPROM_FILE_HEADER "EEPE EEPROM FILE"
#define EEPE_MODEL_FILE_HEADER "EEPE MODEL FILE"
#define EEPROM_FILE_TYPE 1
#define FLASH_FILE_TYPE 2
namespace Ui
{
class burnDialog;
}
class burnDialog : public QDialog
{
Q_OBJECT
public:
explicit burnDialog(QWidget *parent = 0, int Type = 2, QString * fileName = NULL, bool * backupEE=NULL, QString docname="");
~burnDialog();
private slots:
void on_FlashLoadButton_clicked();
void on_BurnFlashButton_clicked();
void on_cancelButton_clicked();
void on_EEbackupCB_clicked();
void on_EEpromCB_toggled(bool checked);
bool checkeEprom(QString fileName);
void on_useProfileImageCB_clicked();
void on_useFwImageCB_clicked();
void on_useLibraryImageCB_clicked();
void on_useAnotherImageCB_clicked();
void checkFw(QString fileName);
void displaySplash();
void updateUI();
void shrink();
private:
Ui::burnDialog *ui;
QString * hexfileName;
bool * backup;
int hexType;
RadioData radioData;
bool burnraw;
enum ImageSource {FIRMWARE, PROFILE, LIBRARY, ANOTHER};
ImageSource imageSource;
QString imageFile;
};
#endif // BURNDIALOG_H

View file

@ -1,379 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>burnDialog</class>
<widget class="QDialog" name="burnDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>399</width>
<height>564</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="windowTitle">
<string>Customize Splash</string>
</property>
<property name="windowIcon">
<iconset resource="companion.qrc">
<normaloff>:/icon.png</normaloff>:/icon.png</iconset>
</property>
<layout class="QGridLayout" name="gridLayout_7">
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<spacer name="hs2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="cancelButton">
<property name="minimumSize">
<size>
<width>90</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="BurnFlashButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>90</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Write to TX</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout_4">
<item row="5" column="0">
<widget class="QCheckBox" name="patchcalib_CB">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Modify calibration parameters using settings from current profile&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Patch calibration setting from profile</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QCheckBox" name="patchhw_CB">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Modify HW parameters using settings from current profile&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Patch HW setting from profile</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QFrame" name="FramFWInfo">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<item row="3" column="0">
<widget class="QLabel" name="dateLabel">
<property name="text">
<string>Date &amp; Time</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="versionField">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="buildLabel">
<property name="text">
<string>Variant</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="ModField">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="versionLabel">
<property name="text">
<string>Version</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="DateField">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLineEdit" name="FWFileName">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>250</width>
<height>0</height>
</size>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="FlashLoadButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Browse for file</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="7" column="0">
<widget class="QCheckBox" name="EEpromCB">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Allows Companion to write to older version of the firmware</string>
</property>
<property name="text">
<string>Check Firmware compatibility</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="EEbackupCB">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Backup and restore Models and Settings</string>
</property>
<property name="tristate">
<bool>false</bool>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="profile_label">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Current Profile</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QFrame" name="SplashFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QGridLayout" name="SplashLayout" rowstretch="0,0,0,0,0,0,0">
<item row="0" column="1" rowspan="7">
<layout class="QGridLayout" name="gridLayout_2" rowstretch="0">
<item row="0" column="0">
<widget class="QLabel" name="imageLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>128</width>
<height>64</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>214</width>
<height>66</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::Panel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
<property name="text">
<string/>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="useFwImageCB">
<property name="text">
<string>Use firmware start screen</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="useAnotherImageCB">
<property name="text">
<string>Use another start screen</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="useProfileImageCB">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Use profile start screen</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="useLibraryImageCB">
<property name="text">
<string>Use library start screen</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<tabstops>
<tabstop>BurnFlashButton</tabstop>
<tabstop>FWFileName</tabstop>
<tabstop>FlashLoadButton</tabstop>
<tabstop>versionField</tabstop>
<tabstop>ModField</tabstop>
<tabstop>useProfileImageCB</tabstop>
<tabstop>useFwImageCB</tabstop>
<tabstop>useLibraryImageCB</tabstop>
<tabstop>useAnotherImageCB</tabstop>
<tabstop>EEbackupCB</tabstop>
<tabstop>patchcalib_CB</tabstop>
<tabstop>patchhw_CB</tabstop>
<tabstop>EEpromCB</tabstop>
<tabstop>cancelButton</tabstop>
</tabstops>
<resources>
<include location="companion.qrc"/>
</resources>
<connections/>
</ui>

View file

@ -96,7 +96,7 @@ int main(int argc, char *argv[])
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
RegisterEepromInterfaces(); registerEEpromInterfaces();
registerOpenTxFirmwares(); registerOpenTxFirmwares();
if (g.profile[g.id()].fwType().isEmpty()){ if (g.profile[g.id()].fwType().isEmpty()){
@ -130,8 +130,8 @@ int main(int argc, char *argv[])
delete splash; delete splash;
delete mainWin; delete mainWin;
UnregisterFirmwares(); unregisterFirmwares();
UnregisterEepromInterfaces(); unregisterEEpromInterfaces();
return result; return result;
} }

View file

@ -1,6 +1,7 @@
#include "comparedialog.h" #include "comparedialog.h"
#include "ui_comparedialog.h" #include "ui_comparedialog.h"
#include "helpers.h" #include "helpers.h"
#include "helpers_html.h"
#include "eeprominterface.h" #include "eeprominterface.h"
#include <QtGui> #include <QtGui>
#include <QImage> #include <QImage>
@ -165,37 +166,6 @@ CompareDialog::~CompareDialog()
delete ui; delete ui;
} }
QString CompareDialog::doTC(const QString s, const QString color="", bool bold=false)
{
QString str = s;
if(bold) str = "<b>" + str + "</b>";
if(!color.isEmpty()) str = "<font color=" + color + ">" + str + "</font>";
return "<td align=center>" + str + "</td>";
}
QString CompareDialog::doTR(const QString s, const QString color="", bool bold=false)
{
QString str = s;
if(bold) str = "<b>" + str + "</b>";
if(!color.isEmpty()) str = "<font color=" + color + ">" + str + "</font>";
return "<td align=right>" + str + "</td>";
}
QString CompareDialog::doTL(const QString s, const QString color="", bool bold=false)
{
QString str = s;
if(bold) str = "<b>" + str + "</b>";
if(!color.isEmpty()) str = "<font color=" + color + ">" + str + "</font>";
return "<td align=left>" + str + "</td>";
}
QString CompareDialog::fv(const QString name, const QString value, const QString color="green")
{
return "<b>" + name + ": </b><font color=" +color + ">" + value + "</font><br>";
}
int CompareDialog::ModelHasExpo(ExpoData * ExpoArray, ExpoData expo, bool * expoused) int CompareDialog::ModelHasExpo(ExpoData * ExpoArray, ExpoData expo, bool * expoused)
{ {
for (int i=0; i< C9X_MAX_EXPOS; i++) { for (int i=0; i< C9X_MAX_EXPOS; i++) {

View file

@ -29,10 +29,6 @@ class CompareDialog : public QDialog
private: private:
void closeEvent(QCloseEvent *event); void closeEvent(QCloseEvent *event);
Ui::CompareDialog *ui; Ui::CompareDialog *ui;
QString doTC(const QString s, const QString color, bool bold);
QString doTR(const QString s, const QString color, bool bold);
QString doTL(const QString s, const QString color, bool bold);
QString fv(const QString name, const QString value,const QString color);
template<class T> QString getColor1(T val1, T val2) { template<class T> QString getColor1(T val1, T val2) {
if (val1!=val2) if (val1!=val2)
return "green"; return "green";

42
companion/src/converteeprom.cpp Executable file
View file

@ -0,0 +1,42 @@
#include "converteeprom.h"
#include "eeprominterface.h"
#include "firmwareinterface.h"
#include <QFile>
bool convertEEprom(const QString &sourceEEprom, const QString &destinationEEprom, const QString &firmwareFilename)
{
Firmware *currentFirmware = GetCurrentFirmware();
FirmwareInterface firmware(firmwareFilename);
if (!firmware.isValid())
return false;
unsigned int version = firmware.getEEpromVersion();
unsigned int variant = firmware.getEEpromVariant();
QFile sourceFile(sourceEEprom);
int eeprom_size = sourceFile.size();
if (!eeprom_size)
return false;
if (!sourceFile.open(QIODevice::ReadOnly))
return false;
QByteArray eeprom(eeprom_size, 0);
long result = sourceFile.read(eeprom.data(), eeprom_size);
sourceFile.close();
QSharedPointer<RadioData> radioData = QSharedPointer<RadioData>(new RadioData());
if (!loadEEprom(*radioData, (uint8_t *)eeprom.data(), eeprom_size) || !currentFirmware->saveEEPROM((uint8_t *)eeprom.data(), *radioData, variant, version))
return false;
QFile destinationFile(destinationEEprom);
if (!destinationFile.open(QIODevice::WriteOnly))
return false;
result = destinationFile.write(eeprom.constData(), eeprom_size);
destinationFile.close();
if (result != eeprom_size)
return false;
return true;
}

8
companion/src/converteeprom.h Executable file
View file

@ -0,0 +1,8 @@
#ifndef CONVERTHEADER_H_
#define CONVERTHEADER_H_
#include <QString>
bool convertEEprom(const QString &sourceEEprom, const QString &destinationEEprom, const QString &firmware);
#endif /* CONVERTHEADER_H_ */

View file

@ -1,12 +1,10 @@
#include "customizesplashdialog.h" #include "customizesplashdialog.h"
#include "ui_customizesplashdialog.h" #include "ui_customizesplashdialog.h"
#include "flashfirmwaredialog.h"
#include <QtGui>
#include "appdata.h" #include "appdata.h"
#include "helpers.h" #include "helpers.h"
#include "burndialog.h"
#include "splashlibrary.h" #include "splashlibrary.h"
#include "flashinterface.h" #include "firmwareinterface.h"
//*** Side Class *** //*** Side Class ***
@ -44,12 +42,12 @@ bool Side::displayImage( QString fileName, Source pictSource )
// Determine which picture format to use // Determine which picture format to use
if (pictSource == FW ){ if (pictSource == FW ){
FlashInterface flash(fileName); FirmwareInterface firmware(fileName);
if (!flash.hasSplash()) if (!firmware.hasSplash())
return false; return false;
else else
image = flash.getSplash(); image = firmware.getSplash();
*format = (flash.getSplashWidth()==WIDTH_TARANIS ? LCDTARANIS : LCD9X); *format = (firmware.getSplashWidth()==WIDTH_TARANIS ? LCDTARANIS : LCD9X);
} }
else { else {
image.load(fileName); image.load(fileName);
@ -105,12 +103,12 @@ bool Side::saveImage()
{ {
if (*source == FW ) if (*source == FW )
{ {
FlashInterface flash(*saveToFileName); FirmwareInterface firmware(*saveToFileName);
if (!flash.hasSplash()) { if (!firmware.hasSplash()) {
return false; return false;
} }
QImage image = imageLabel->pixmap()->toImage().scaled(flash.getSplashWidth(), flash.getSplashHeight()); QImage image = imageLabel->pixmap()->toImage().scaled(firmware.getSplashWidth(), firmware.getSplashHeight());
if (flash.setSplash(image) && (flash.saveFlash(*saveToFileName) > 0)) { if (firmware.setSplash(image) && (firmware.save(*saveToFileName) > 0)) {
g.flashDir( QFileInfo(*saveToFileName).dir().absolutePath() ); g.flashDir( QFileInfo(*saveToFileName).dir().absolutePath() );
} }
else { else {

View file

@ -3,7 +3,7 @@
#include <QtGui> #include <QtGui>
#include <QDialog> #include <QDialog>
#include "flashinterface.h" #include "firmwareinterface.h"
namespace Ui namespace Ui
{ {

View file

@ -11,6 +11,7 @@
#include "appdata.h" #include "appdata.h"
#include "helpers.h" #include "helpers.h"
#include "wizarddata.h" #include "wizarddata.h"
#include "firmwareinterface.h"
std::list<QString> EEPROMWarnings; std::list<QString> EEPROMWarnings;
@ -164,7 +165,7 @@ RawSourceRange RawSource::getRange(const ModelData * model, const GeneralSetting
{ {
RawSourceRange result; RawSourceRange result;
FirmwareInterface * firmware = GetCurrentFirmware(); Firmware * firmware = GetCurrentFirmware();
int board = firmware->getBoard(); int board = firmware->getBoard();
bool singleprec = (flags & RANGE_SINGLE_PRECISION); bool singleprec = (flags & RANGE_SINGLE_PRECISION);
@ -863,7 +864,7 @@ QString CustomFunctionData::funcToString()
else if (func == FuncPlayScript) else if (func == FuncPlayScript)
return QObject::tr("Play Script"); return QObject::tr("Play Script");
else if (func == FuncLogs) else if (func == FuncLogs)
return QObject::tr("SD Logs"); return QObject::tr("Start Logs");
else if (func == FuncVolume) else if (func == FuncVolume)
return QObject::tr("Volume"); return QObject::tr("Volume");
else if (func == FuncBacklight) else if (func == FuncBacklight)
@ -1456,7 +1457,7 @@ int ModelData::getChannelsMax(bool forceExtendedLimits) const
} }
QList<EEPROMInterface *> eepromInterfaces; QList<EEPROMInterface *> eepromInterfaces;
void RegisterEepromInterfaces() void registerEEpromInterfaces()
{ {
eepromInterfaces.push_back(new OpenTxEepromInterface(BOARD_STOCK)); eepromInterfaces.push_back(new OpenTxEepromInterface(BOARD_STOCK));
eepromInterfaces.push_back(new OpenTxEepromInterface(BOARD_M128)); eepromInterfaces.push_back(new OpenTxEepromInterface(BOARD_M128));
@ -1472,7 +1473,7 @@ void RegisterEepromInterfaces()
eepromInterfaces.push_back(new Er9xInterface()); eepromInterfaces.push_back(new Er9xInterface());
} }
void UnregisterEepromInterfaces() void unregisterEEpromInterfaces()
{ {
foreach(EEPROMInterface * intf, eepromInterfaces) { foreach(EEPROMInterface * intf, eepromInterfaces) {
// qDebug() << "UnregisterEepromInterfaces(): deleting " << QString::number( reinterpret_cast<uint64_t>(intf), 16 ); // qDebug() << "UnregisterEepromInterfaces(): deleting " << QString::number( reinterpret_cast<uint64_t>(intf), 16 );
@ -1481,18 +1482,18 @@ void UnregisterEepromInterfaces()
OpenTxEepromCleanup(); OpenTxEepromCleanup();
} }
QList<FirmwareInterface *> firmwares; QList<Firmware *> firmwares;
FirmwareInterface * default_firmware_variant; Firmware * default_firmware_variant;
FirmwareInterface * current_firmware_variant; Firmware * current_firmware_variant;
void UnregisterFirmwares() void unregisterFirmwares()
{ {
foreach (FirmwareInterface * f, firmwares) { foreach (Firmware * f, firmwares) {
delete f; delete f;
} }
} }
bool LoadEeprom(RadioData &radioData, const uint8_t *eeprom, const int size) bool loadEEprom(RadioData &radioData, const uint8_t *eeprom, const int size)
{ {
foreach(EEPROMInterface *eepromInterface, eepromInterfaces) { foreach(EEPROMInterface *eepromInterface, eepromInterfaces) {
if (eepromInterface->load(radioData, eeprom, size)) if (eepromInterface->load(radioData, eeprom, size))
@ -1502,7 +1503,7 @@ bool LoadEeprom(RadioData &radioData, const uint8_t *eeprom, const int size)
return false; return false;
} }
bool LoadBackup(RadioData &radioData, uint8_t *eeprom, int size, int index) bool loadBackup(RadioData &radioData, uint8_t *eeprom, int size, int index)
{ {
foreach(EEPROMInterface *eepromInterface, eepromInterfaces) { foreach(EEPROMInterface *eepromInterface, eepromInterfaces) {
if (eepromInterface->loadBackup(radioData, eeprom, size, index)) if (eepromInterface->loadBackup(radioData, eeprom, size, index))
@ -1513,7 +1514,7 @@ bool LoadBackup(RadioData &radioData, uint8_t *eeprom, int size, int index)
} }
bool LoadEepromXml(RadioData &radioData, QDomDocument &doc) bool loadEEpromXml(RadioData &radioData, QDomDocument &doc)
{ {
foreach(EEPROMInterface *eepromInterface, eepromInterfaces) { foreach(EEPROMInterface *eepromInterface, eepromInterfaces) {
if (eepromInterface->loadxml(radioData, doc)) if (eepromInterface->loadxml(radioData, doc))
@ -1547,10 +1548,10 @@ QString getBoardName(BoardEnum board)
} }
} }
FirmwareInterface * GetFirmware(QString id) Firmware * GetFirmware(QString id)
{ {
foreach(FirmwareInterface * firmware, firmwares) { foreach(Firmware * firmware, firmwares) {
FirmwareInterface * result = firmware->getFirmwareVariant(id); Firmware * result = firmware->getFirmwareVariant(id);
if (result) { if (result) {
return result; return result;
} }
@ -1559,16 +1560,16 @@ FirmwareInterface * GetFirmware(QString id)
return default_firmware_variant; return default_firmware_variant;
} }
void FirmwareInterface::addOption(const char *option, QString tooltip, uint32_t variant) void Firmware::addOption(const char *option, QString tooltip, uint32_t variant)
{ {
Option options[] = { { option, tooltip, variant }, { NULL } }; Option options[] = { { option, tooltip, variant }, { NULL } };
addOptions(options); addOptions(options);
} }
unsigned int FirmwareInterface::getVariantNumber() unsigned int Firmware::getVariantNumber()
{ {
unsigned int result = 0; unsigned int result = 0;
const FirmwareInterface * base = getFirmwareBase(); const Firmware * base = getFirmwareBase();
QStringList options = id.mid(base->getId().length()+1).split("-", QString::SkipEmptyParts); QStringList options = id.mid(base->getId().length()+1).split("-", QString::SkipEmptyParts);
foreach(QString option, options) { foreach(QString option, options) {
foreach(QList<Option> group, base->opts) { foreach(QList<Option> group, base->opts) {
@ -1582,17 +1583,17 @@ unsigned int FirmwareInterface::getVariantNumber()
return result; return result;
} }
void FirmwareInterface::addLanguage(const char *lang) void Firmware::addLanguage(const char *lang)
{ {
languages.push_back(lang); languages.push_back(lang);
} }
void FirmwareInterface::addTTSLanguage(const char *lang) void Firmware::addTTSLanguage(const char *lang)
{ {
ttslanguages.push_back(lang); ttslanguages.push_back(lang);
} }
void FirmwareInterface::addOptions(Option options[]) void Firmware::addOptions(Option options[])
{ {
QList<Option> opts; QList<Option> opts;
for (int i=0; options[i].name; i++) { for (int i=0; options[i].name; i++) {

View file

@ -1475,13 +1475,14 @@ inline void applyStickModeToModel(ModelData &model, unsigned int mode)
model.swashRingData.collectiveSource.index = applyStickMode(model.swashRingData.collectiveSource.index + 1, mode) - 1; model.swashRingData.collectiveSource.index = applyStickMode(model.swashRingData.collectiveSource.index + 1, mode) - 1;
} }
void RegisterEepromInterfaces(); void registerEEpromInterfaces();
void UnregisterFirmwares(); void unregisterEEpromInterfaces();
void registerOpenTxFirmwares(); void registerOpenTxFirmwares();
void unregisterFirmwares();
bool LoadBackup(RadioData &radioData, uint8_t *eeprom, int esize, int index); bool loadBackup(RadioData &radioData, uint8_t *eeprom, int esize, int index);
bool LoadEeprom(RadioData &radioData, const uint8_t *eeprom, int size); bool loadEEprom(RadioData &radioData, const uint8_t *eeprom, int size);
bool LoadEepromXml(RadioData &radioData, QDomDocument &doc); bool loadEEpromXml(RadioData &radioData, QDomDocument &doc);
struct Option { struct Option {
const char * name; const char * name;
@ -1489,10 +1490,10 @@ struct Option {
uint32_t variant; uint32_t variant;
}; };
class FirmwareInterface { class Firmware {
public: public:
FirmwareInterface(const QString & id, const QString & name, const BoardEnum board, EEPROMInterface * eepromInterface): Firmware(const QString & id, const QString & name, const BoardEnum board, EEPROMInterface * eepromInterface):
id(id), id(id),
name(name), name(name),
board(board), board(board),
@ -1502,7 +1503,7 @@ class FirmwareInterface {
{ {
} }
FirmwareInterface(FirmwareInterface * base, const QString & id, const QString & name, const BoardEnum board, EEPROMInterface * eepromInterface): Firmware(Firmware * base, const QString & id, const QString & name, const BoardEnum board, EEPROMInterface * eepromInterface):
id(id), id(id),
name(name), name(name),
board(board), board(board),
@ -1512,12 +1513,12 @@ class FirmwareInterface {
{ {
} }
virtual ~FirmwareInterface() virtual ~Firmware()
{ {
delete eepromInterface; delete eepromInterface;
} }
inline const FirmwareInterface * getFirmwareBase() const inline const Firmware * getFirmwareBase() const
{ {
return base ? base : this; return base ? base : this;
} }
@ -1528,7 +1529,7 @@ class FirmwareInterface {
variantBase = variant; variantBase = variant;
} }
virtual FirmwareInterface * getFirmwareVariant(const QString & id) { return NULL; } virtual Firmware * getFirmwareVariant(const QString & id) { return NULL; }
unsigned int getVariantNumber(); unsigned int getVariantNumber();
@ -1591,20 +1592,20 @@ class FirmwareInterface {
BoardEnum board; BoardEnum board;
EEPROMInterface * eepromInterface; EEPROMInterface * eepromInterface;
unsigned int variantBase; unsigned int variantBase;
FirmwareInterface * base; Firmware * base;
private: private:
FirmwareInterface(); Firmware();
}; };
extern QList<FirmwareInterface *> firmwares; extern QList<Firmware *> firmwares;
extern FirmwareInterface * default_firmware_variant; extern Firmware * default_firmware_variant;
extern FirmwareInterface * current_firmware_variant; extern Firmware * current_firmware_variant;
FirmwareInterface * GetFirmware(QString id); Firmware * GetFirmware(QString id);
inline FirmwareInterface * GetCurrentFirmware() inline Firmware * GetCurrentFirmware()
{ {
return current_firmware_variant; return current_firmware_variant;
} }
@ -1614,8 +1615,6 @@ inline EEPROMInterface * GetEepromInterface()
return GetCurrentFirmware()->getEepromInterface(); return GetCurrentFirmware()->getEepromInterface();
} }
void UnregisterEepromInterfaces();
inline int divRoundClosest(const int n, const int d) inline int divRoundClosest(const int n, const int d)
{ {
return ((n < 0) ^ (d < 0)) ? ((n - d/2)/d) : ((n + d/2)/d); return ((n < 0) ^ (d < 0)) ? ((n - d/2)/d) : ((n + d/2)/d);

View file

@ -17,7 +17,7 @@
#include <QtGui> #include <QtGui>
#include "hexinterface.h" #include "hexinterface.h"
#include "splash.h" #include "splash.h"
#include "flashinterface.h" #include "firmwareinterface.h"
#include "helpers.h" #include "helpers.h"
#define VERS_MARK "VERS" #define VERS_MARK "VERS"
@ -42,7 +42,7 @@ int getFileType(const QString &fullFileName)
return 0; return 0;
} }
FlashInterface::FlashInterface(QString fileName): FirmwareInterface::FirmwareInterface(const QString &filename):
flash(MAX_FSIZE, 0), flash(MAX_FSIZE, 0),
flash_size(0), flash_size(0),
versionId(0), versionId(0),
@ -52,8 +52,8 @@ FlashInterface::FlashInterface(QString fileName):
splash_height(0), splash_height(0),
isValidFlag(false) isValidFlag(false)
{ {
if (!fileName.isEmpty()) { if (!filename.isEmpty()) {
QFile file(fileName); QFile file(filename);
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { // reading HEX TEXT file if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { // reading HEX TEXT file
QTextStream inputStream(&file); QTextStream inputStream(&file);
flash_size = HexInterface(inputStream).load((uint8_t *)flash.data(), MAX_FSIZE); flash_size = HexInterface(inputStream).load((uint8_t *)flash.data(), MAX_FSIZE);
@ -82,11 +82,11 @@ FlashInterface::FlashInterface(QString fileName):
versionId = version2index(version); versionId = version2index(version);
SeekSplash(); SeekSplash();
isValidFlag = true; isValidFlag = !version.isEmpty();
} }
} }
QString FlashInterface::seekString(const QString & string) QString FirmwareInterface::seekString(const QString & string)
{ {
QString result = ""; QString result = "";
@ -109,7 +109,7 @@ QString FlashInterface::seekString(const QString & string)
return result; return result;
} }
QString FlashInterface::seekLabel(const QString & label) QString FirmwareInterface::seekLabel(const QString & label)
{ {
QString result = seekString(label + "\037\033:"); QString result = seekString(label + "\037\033:");
if (!result.isEmpty()) if (!result.isEmpty())
@ -118,7 +118,7 @@ QString FlashInterface::seekLabel(const QString & label)
return seekString(label + ":"); return seekString(label + ":");
} }
bool FlashInterface::SeekSplash(QByteArray splash) bool FirmwareInterface::SeekSplash(QByteArray splash)
{ {
int start = flash.indexOf(splash); int start = flash.indexOf(splash);
if (start>0) { if (start>0) {
@ -131,7 +131,7 @@ bool FlashInterface::SeekSplash(QByteArray splash)
} }
} }
bool FlashInterface::SeekSplash(QByteArray sps, QByteArray spe, int size) bool FirmwareInterface::SeekSplash(QByteArray sps, QByteArray spe, int size)
{ {
int start = 0; int start = 0;
while (start>=0) { while (start>=0) {
@ -157,7 +157,7 @@ bool FlashInterface::SeekSplash(QByteArray sps, QByteArray spe, int size)
#define OTX_SPE "SPE" #define OTX_SPE "SPE"
#define OTX_SPE_SIZE 4 #define OTX_SPE_SIZE 4
void FlashInterface::SeekSplash(void) void FirmwareInterface::SeekSplash(void)
{ {
splash_size = 0; splash_size = 0;
splash_offset = 0; splash_offset = 0;
@ -209,7 +209,7 @@ void FlashInterface::SeekSplash(void)
} }
} }
bool FlashInterface::setSplash(const QImage & newsplash) bool FirmwareInterface::setSplash(const QImage & newsplash)
{ {
if (splash_offset == 0 || splash_size == 0) { if (splash_offset == 0 || splash_size == 0) {
return false; return false;
@ -245,22 +245,22 @@ bool FlashInterface::setSplash(const QImage & newsplash)
return true; return true;
} }
int FlashInterface::getSplashWidth() int FirmwareInterface::getSplashWidth()
{ {
return splash_width; return splash_width;
} }
uint FlashInterface::getSplashHeight() uint FirmwareInterface::getSplashHeight()
{ {
return splash_height; return splash_height;
} }
QImage::Format FlashInterface::getSplashFormat() QImage::Format FirmwareInterface::getSplashFormat()
{ {
return splash_format; return splash_format;
} }
QImage FlashInterface::getSplash() QImage FirmwareInterface::getSplash()
{ {
if (splash_offset == 0 || splash_size == 0) { if (splash_offset == 0 || splash_size == 0) {
return QImage(); // empty image return QImage(); // empty image
@ -295,17 +295,17 @@ QImage FlashInterface::getSplash()
} }
} }
bool FlashInterface::hasSplash() bool FirmwareInterface::hasSplash()
{ {
return (splash_offset > 0 ? true : false); return (splash_offset > 0 ? true : false);
} }
bool FlashInterface::isValid() bool FirmwareInterface::isValid()
{ {
return isValidFlag; return isValidFlag;
} }
uint FlashInterface::saveFlash(QString fileName) unsigned int FirmwareInterface::save(QString fileName)
{ {
uint8_t binflash[MAX_FSIZE]; uint8_t binflash[MAX_FSIZE];
memcpy(&binflash, flash.constData(), flash_size); memcpy(&binflash, flash.constData(), flash_size);

View file

@ -12,13 +12,12 @@
* *
*/ */
#ifndef FLASHINTERFACE_H #ifndef FIRMWAREINTERFACE_H_
#define FLASHINTERFACE_H #define FIRMWAREINTERFACE_H_
#include <QDialog> #include <QString>
#include <QtGui> #include <QImage>
#include <inttypes.h> #include <QByteArray>
#include "file.h"
#define MAX_FSIZE (512*1024) #define MAX_FSIZE (512*1024)
#define SPLASH_WIDTH (128) #define SPLASH_WIDTH (128)
@ -40,10 +39,10 @@
int getFileType(const QString &fullFileName); int getFileType(const QString &fullFileName);
class FlashInterface class FirmwareInterface
{ {
public: public:
FlashInterface(QString filename); FirmwareInterface(const QString &filename);
inline QString getDate() { return date; } inline QString getDate() { return date; }
inline QString getTime() { return time; } inline QString getTime() { return time; }
int getSize() { return flash_size; } int getSize() { return flash_size; }
@ -58,7 +57,7 @@ class FlashInterface
int getSplashWidth(); int getSplashWidth();
uint getSplashHeight(); uint getSplashHeight();
QImage::Format getSplashFormat(); QImage::Format getSplashFormat();
uint saveFlash(QString fileName); unsigned int save(QString fileName);
bool isValid(); bool isValid();
private: private:
@ -86,5 +85,4 @@ class FlashInterface
bool isValidFlag; bool isValidFlag;
}; };
#endif /* FLASHINTERFACE_H */ #endif /* FIRMWAREINTERFACE_H_ */

View file

@ -53,8 +53,7 @@ const int Gruvin9xInterface::getEEpromSize()
return EESIZE_STOCK*2; return EESIZE_STOCK*2;
} }
return EESIZE_STOCK; return EESIZE_STOCK;
} } else {
else {
return EESIZE_GRUVIN9X; return EESIZE_GRUVIN9X;
} }
} }

View file

@ -484,10 +484,10 @@ int OpenTxEepromInterface::getSize(GeneralSettings &settings)
return efile->size(0); return efile->size(0);
} }
FirmwareInterface * OpenTxFirmware::getFirmwareVariant(const QString & id) Firmware * OpenTxFirmware::getFirmwareVariant(const QString & id)
{ {
if (id.contains(getId()+"-") || (!id.contains("-") && id.contains(getId()))) { if (id.contains(getId()+"-") || (!id.contains("-") && id.contains(getId()))) {
FirmwareInterface * result = new OpenTxFirmware(id, this); Firmware * result = new OpenTxFirmware(id, this);
// TODO result.variant = firmware->getVariant(id); // TODO result.variant = firmware->getVariant(id);
return result; return result;
} }

View file

@ -77,15 +77,15 @@ class OpenTxEepromInterface : public EEPROMInterface
}; };
class OpenTxFirmware: public FirmwareInterface { class OpenTxFirmware: public Firmware {
public: public:
OpenTxFirmware(const QString & id, OpenTxFirmware * parent): OpenTxFirmware(const QString & id, OpenTxFirmware * parent):
FirmwareInterface(parent, id, parent->getName(), parent->getBoard(), parent->eepromInterface) Firmware(parent, id, parent->getName(), parent->getBoard(), parent->eepromInterface)
{ {
} }
OpenTxFirmware(const QString & id, const QString & name, const BoardEnum board): OpenTxFirmware(const QString & id, const QString & name, const BoardEnum board):
FirmwareInterface(id, name, board, new OpenTxEepromInterface(board)) Firmware(id, name, board, new OpenTxEepromInterface(board))
{ {
addLanguage("en"); addLanguage("en");
addLanguage("fr"); addLanguage("fr");
@ -110,7 +110,7 @@ class OpenTxFirmware: public FirmwareInterface {
addTTSLanguage("hu"); addTTSLanguage("hu");
} }
virtual FirmwareInterface * getFirmwareVariant(const QString & id); virtual Firmware * getFirmwareVariant(const QString & id);
virtual QString getStampUrl(); virtual QString getStampUrl();

View file

@ -0,0 +1,347 @@
#include "flasheepromdialog.h"
#include "ui_flasheepromdialog.h"
#include "eeprominterface.h"
#include "helpers.h"
#include "splashlibrary.h"
#include "firmwareinterface.h"
#include "hexinterface.h"
#include "appdata.h"
#include "progressdialog.h"
#include "radiointerface.h"
#include "converteeprom.h"
FlashEEpromDialog::FlashEEpromDialog(QWidget *parent, const QString &filename):
QDialog(parent),
ui(new Ui::FlashEEpromDialog),
eepromFilename(filename),
radioData(new RadioData())
{
ui->setupUi(this);
ui->profileLabel->setText(tr("Current profile: %1").arg(g.profile[g.id()].name()));
if (!filename.isEmpty()) {
ui->eepromFilename->hide();
ui->eepromLoad->hide();
}
QString backupPath = g.backupDir();
if (backupPath.isEmpty() || !QDir(backupPath).exists()) {
ui->backupBeforeWrite->setEnabled(false);
}
updateUI();
}
FlashEEpromDialog::~FlashEEpromDialog()
{
delete ui;
}
void FlashEEpromDialog::updateUI()
{
// ui->burnButton->setEnabled(true);
ui->eepromFilename->setText(eepromFilename);
if (getEEpromVersion(eepromFilename) >= 0) {
ui->profileLabel->show();
ui->patchCalibration->show();
ui->patchHardwareSettings->show();
QString name = g.profile[g.id()].name();
QString calib = g.profile[g.id()].stickPotCalib();
QString trainercalib = g.profile[g.id()].trainerCalib();
QString DisplaySet = g.profile[g.id()].display();
QString BeeperSet = g.profile[g.id()].beeper();
QString HapticSet = g.profile[g.id()].haptic();
QString SpeakerSet = g.profile[g.id()].speaker();
if (!name.isEmpty()) {
ui->profileLabel->show();
ui->patchCalibration->show();
ui->patchHardwareSettings->show();
// TODO I hardcode the number of pots here, should be dependant on the board?
if (!((calib.length()==(NUM_STICKS+3)*12) && (trainercalib.length()==16))) {
ui->patchCalibration->setDisabled(true);
}
if (!((DisplaySet.length()==6) && (BeeperSet.length()==4) && (HapticSet.length()==6) && (SpeakerSet.length()==6))) {
ui->patchHardwareSettings->setDisabled(true);
}
}
else {
ui->profileLabel->hide();
}
ui->burnButton->setEnabled(true);
}
else {
ui->profileLabel->hide();
ui->patchCalibration->hide();
ui->patchHardwareSettings->hide();
}
QTimer::singleShot(0, this, SLOT(shrink()));
}
void FlashEEpromDialog::on_eepromLoad_clicked()
{
QString filename = QFileDialog::getOpenFileName(this, tr("Choose Radio Backup file"), g.eepromDir(), tr(EXTERNAL_EEPROM_FILES_FILTER));
if (!filename.isEmpty()) {
eepromFilename = filename;
updateUI();
}
}
int FlashEEpromDialog::getEEpromVersion(const QString &filename)
{
RadioData testData;
if (filename.isEmpty()) {
return -1;
}
QFile file(filename);
if (!file.exists()) {
QMessageBox::warning(this, tr("Error"), tr("Unable to find file %1!").arg(filename));
return -1;
}
int fileType = getFileType(filename);
#if 0
if (fileType==FILE_TYPE_XML) {
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { //reading HEX TEXT file
QMessageBox::critical(this, tr("Error"),tr("Error opening file %1:\n%2.").arg(filename).arg(file.errorString()));
return -1;
}
QTextStream inputStream(&file);
XmlInterface(inputStream).load(testData);
}
else
#endif
if (fileType==FILE_TYPE_HEX || fileType==FILE_TYPE_EEPE) { //read HEX file
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { //reading HEX TEXT file
QMessageBox::warning(this, tr("Error"),tr("Error opening file %1:\n%2.").arg(filename).arg(file.errorString()));
return -1;
}
QDomDocument doc(ER9X_EEPROM_FILE_TYPE);
bool xmlOK = doc.setContent(&file);
if(xmlOK) {
if (!loadEEpromXml(testData, doc)) {
QMessageBox::warning(this, tr("Error"), tr("Invalid Models and Settings File %1").arg(filename));
return -1;
}
}
file.reset();
QTextStream inputStream(&file);
if (fileType==FILE_TYPE_EEPE) { // read EEPE file header
QString hline = inputStream.readLine();
if (hline!=EEPE_EEPROM_FILE_HEADER) {
QMessageBox::warning(this, tr("Error"), tr("Invalid Models and Settings File %1").arg(filename));
return -1;
}
}
QByteArray eeprom(EESIZE_RLC_MAX, 0);
int eeprom_size = HexInterface(inputStream).load((uint8_t *)eeprom.data(), EESIZE_RLC_MAX);
if (!eeprom_size) {
QMessageBox::warning(this, tr("Error"), tr("Invalid Models and Settings File %1").arg(filename));
return -1;
}
if (!loadEEprom(testData, (const uint8_t *)eeprom.data(), eeprom_size)) {
QMessageBox::warning(this, tr("Error"), tr("Invalid Models and Settings File %1").arg(filename));
return -1;
}
}
else if (fileType==FILE_TYPE_BIN) { //read binary
int eeprom_size = file.size();
if (!file.open(QFile::ReadOnly)) { //reading binary file - TODO HEX support
QMessageBox::warning(this, tr("Error"), tr("Error opening file %1:\n%2.").arg(filename).arg(file.errorString()));
return -1;
}
QByteArray eeprom(eeprom_size, 0);
long result = file.read(eeprom.data(), eeprom_size);
if (result != eeprom_size) {
QMessageBox::warning(this, tr("Error"), tr("Error reading file %1:\n%2.").arg(filename).arg(file.errorString()));
return -1;
}
if (!loadEEprom(testData, (uint8_t *)eeprom.data(), eeprom_size)) {
QMessageBox::warning(this, tr("Error"), tr("Invalid binary Models and Settings File %1").arg(filename));
return -1;
}
}
return testData.generalSettings.version;
}
bool FlashEEpromDialog::patchCalibration()
{
QString calib = g.profile[g.id()].stickPotCalib();
QString trainercalib = g.profile[g.id()].trainerCalib();
int potsnum=GetCurrentFirmware()->getCapability(Pots);
int8_t vBatCalib=(int8_t) g.profile[g.id()].vBatCalib();
int8_t currentCalib=(int8_t) g.profile[g.id()].currentCalib();
int8_t PPM_Multiplier=(int8_t) g.profile[g.id()].ppmMultiplier();
if ((calib.length()==(NUM_STICKS+potsnum)*12) && (trainercalib.length()==16)) {
QString Byte;
int16_t byte16;
bool ok;
for (int i=0; i<(NUM_STICKS+potsnum); i++) {
Byte=calib.mid(i*12,4);
byte16=(int16_t)Byte.toInt(&ok,16);
if (ok)
radioData->generalSettings.calibMid[i]=byte16;
Byte=calib.mid(4+i*12,4);
byte16=(int16_t)Byte.toInt(&ok,16);
if (ok)
radioData->generalSettings.calibSpanNeg[i]=byte16;
Byte=calib.mid(8+i*12,4);
byte16=(int16_t)Byte.toInt(&ok,16);
if (ok)
radioData->generalSettings.calibSpanPos[i]=byte16;
}
for (int i=0; i<4; i++) {
Byte = trainercalib.mid(i*4,4);
byte16 = (int16_t)Byte.toInt(&ok,16);
if (ok) {
radioData->generalSettings.trainer.calib[i] = byte16;
}
}
radioData->generalSettings.currentCalib = currentCalib;
radioData->generalSettings.vBatCalib = vBatCalib;
radioData->generalSettings.PPM_Multiplier = PPM_Multiplier;
return true;
}
else {
QMessageBox::critical(this, tr("Warning"), tr("Wrong radio calibration data in profile, Settings not patched"));
return false;
}
}
bool FlashEEpromDialog::patchHardwareSettings()
{
QString DisplaySet = g.profile[g.id()].display();
QString BeeperSet = g.profile[g.id()].beeper();
QString HapticSet = g.profile[g.id()].haptic();
QString SpeakerSet = g.profile[g.id()].speaker();
uint8_t GSStickMode=(uint8_t) g.profile[g.id()].gsStickMode();
uint8_t vBatWarn=(uint8_t) g.profile[g.id()].vBatWarn();
if ((DisplaySet.length()==6) && (BeeperSet.length()==4) && (HapticSet.length()==6) && (SpeakerSet.length()==6)) {
radioData->generalSettings.vBatWarn = vBatWarn;
radioData->generalSettings.stickMode = GSStickMode;
uint8_t byte8u;
int8_t byte8;
bool ok;
byte8=(int8_t)DisplaySet.mid(0,2).toInt(&ok,16);
if (ok) radioData->generalSettings.optrexDisplay=(byte8==1 ? true : false);
byte8u=(uint8_t)DisplaySet.mid(2,2).toUInt(&ok,16);
if (ok) radioData->generalSettings.contrast=byte8u;
byte8u=(uint8_t)DisplaySet.mid(4,2).toUInt(&ok,16);
if (ok) radioData->generalSettings.backlightBright=byte8u;
byte8u=(uint8_t)BeeperSet.mid(0,2).toUInt(&ok,16);
if (ok) radioData->generalSettings.beeperMode=(GeneralSettings::BeeperMode)byte8u;
byte8=(int8_t)BeeperSet.mid(2,2).toInt(&ok,16);
if (ok) radioData->generalSettings.beeperLength=byte8;
byte8u=(uint8_t)HapticSet.mid(0,2).toUInt(&ok,16);
if (ok) radioData->generalSettings.hapticMode=(GeneralSettings::BeeperMode)byte8u;
byte8u=(uint8_t)HapticSet.mid(2,2).toUInt(&ok,16);
if (ok) radioData->generalSettings.hapticStrength=byte8u;
byte8=(int8_t)HapticSet.mid(4,2).toInt(&ok,16);
if (ok) radioData->generalSettings.hapticLength=byte8;
byte8u=(uint8_t)SpeakerSet.mid(0,2).toUInt(&ok,16);
if (ok) radioData->generalSettings.speakerMode=byte8u;
byte8u=(uint8_t)SpeakerSet.mid(2,2).toUInt(&ok,16);
if (ok) radioData->generalSettings.speakerPitch=byte8u;
byte8u=(uint8_t)SpeakerSet.mid(4,2).toUInt(&ok,16);
if (ok) radioData->generalSettings.speakerVolume=byte8u;
return true;
}
else {
QMessageBox::critical(this, tr("Warning"), tr("Wrong radio setting data in profile, Settings not patched"));
return false;
}
}
void FlashEEpromDialog::on_burnButton_clicked()
{
// patch the eeprom if needed
bool patch = false;
if (ui->patchCalibration->isChecked()) {
patch |= patchCalibration();
}
if (ui->patchHardwareSettings->isChecked()) {
patch |= patchHardwareSettings();
}
QString filename = eepromFilename;
if (patch) {
QString filename = generateProcessUniqueTempFileName("temp.bin");
QFile file(filename);
uint8_t *eeprom = (uint8_t*)malloc(GetEepromInterface()->getEEpromSize());
int eeprom_size = GetEepromInterface()->save(eeprom, *radioData, GetCurrentFirmware()->getVariantNumber());
if (!eeprom_size) {
QMessageBox::warning(this, tr("Error"), tr("Cannot write file %1:\n%2.").arg(filename).arg(file.errorString()));
return;
}
if (!file.open(QIODevice::WriteOnly)) {
QMessageBox::warning(this, tr("Error"), tr("Cannot write file %1:\n%2.").arg(filename).arg(file.errorString()));
return;
}
QTextStream outputStream(&file);
long result = file.write((char*)eeprom, eeprom_size);
if (result != eeprom_size) {
QMessageBox::warning(this, tr("Error"), tr("Error writing file %1:\n%2.").arg(filename).arg(file.errorString()));
return;
}
}
close();
ProgressDialog progressDialog(this, tr("Write Models and Settings to Radio"), CompanionIcon("write_eeprom.png"));
// backup previous EEPROM if requested
QString backupFilename;
if (ui->backupBeforeWrite->isChecked()) {
backupFilename = g.backupDir() + "/backup-" + QDateTime().currentDateTime().toString("yyyy-MM-dd-HHmmss") + ".bin";
}
else if (ui->checkFirmwareCompatibility->isChecked()) {
backupFilename = generateProcessUniqueTempFileName("eeprom.bin");
}
if (!backupFilename.isEmpty()) {
if (!readEeprom(backupFilename, progressDialog.progress())) {
return;
}
}
// check EEPROM compatibility if requested
if (ui->checkFirmwareCompatibility->isChecked()) {
int eepromVersion = getEEpromVersion(filename);
QString firmwareFilename = generateProcessUniqueTempFileName("flash.bin");
if (!readFirmware(firmwareFilename, progressDialog.progress()))
return;
QString compatEEprom = generateProcessUniqueTempFileName("compat.bin");
if (convertEEprom(filename, compatEEprom, firmwareFilename)) {
int compatVersion = getEEpromVersion(compatEEprom);
if ((compatVersion / 100) != (eepromVersion / 100)) {
QMessageBox::warning(this, tr("Warning"), tr("The radio firmware belongs to another product family, check file and preferences!"));
return;
}
else if (compatVersion < eepromVersion) {
QMessageBox::warning(this, tr("Warning"), tr("The radio firmware is outdated, please upgrade!"));
return;
}
filename = compatEEprom;
}
else if (QMessageBox::question(this, "Error", tr("Cannot check Models and Settings compatibility! Continue anyway?"), QMessageBox::Yes|QMessageBox::No) == QMessageBox::No) {
return;
}
qunlink(firmwareFilename);
}
// and write...
writeEeprom(filename, progressDialog.progress());
progressDialog.exec();
}
void FlashEEpromDialog::on_cancelButton_clicked()
{
close();
}
void FlashEEpromDialog::shrink()
{
resize(0, 0);
}

View file

@ -0,0 +1,46 @@
#ifndef FLASHEEPROMDIALOG_H_
#define FLASHEEPROMDIALOG_H_
#include <QDialog>
#define ER9X_EEPROM_FILE_TYPE "ER9X_EEPROM_FILE"
#define EEPE_EEPROM_FILE_HEADER "EEPE EEPROM FILE"
#define HEX_FILES_FILTER "HEX files (*.hex);;"
#define BIN_FILES_FILTER "BIN files (*.bin);;"
#define EXTERNAL_EEPROM_FILES_FILTER "EEPROM files (*.bin *.hex);;" BIN_FILES_FILTER HEX_FILES_FILTER
namespace Ui
{
class FlashEEpromDialog;
}
class RadioData;
class FlashEEpromDialog : public QDialog
{
Q_OBJECT
public:
explicit FlashEEpromDialog(QWidget *parent, const QString &fileName="");
~FlashEEpromDialog();
private slots:
void on_eepromLoad_clicked();
void on_burnButton_clicked();
void on_cancelButton_clicked();
void shrink();
protected:
void updateUI();
bool isValidEEprom(const QString &filename);
int getEEpromVersion(const QString &filename);
bool patchCalibration();
bool patchHardwareSettings();
private:
Ui::FlashEEpromDialog *ui;
QString eepromFilename;
RadioData *radioData;
};
#endif // FLASHEEPROMDIALOG_H_

View file

@ -0,0 +1,198 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FlashEEpromDialog</class>
<widget class="QDialog" name="FlashEEpromDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>399</width>
<height>201</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="windowTitle">
<string>Write Models and Settings to Radio</string>
</property>
<property name="windowIcon">
<iconset resource="companion.qrc">
<normaloff>:/themes/classic/16/write_eeprom.png</normaloff>:/themes/classic/16/write_eeprom.png</iconset>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="filanameLayout">
<item>
<widget class="QLineEdit" name="eepromFilename">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>250</width>
<height>0</height>
</size>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="eepromLoad">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Load...</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="profileLabel">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Current Profile</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkFirmwareCompatibility">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Allows Companion to write to older version of the firmware</string>
</property>
<property name="text">
<string>Check Firmware compatibility</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="backupBeforeWrite">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Allows Companion to write to older version of the firmware</string>
</property>
<property name="text">
<string>Backup before Write</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="patchCalibration">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Modify calibration parameters using settings from current profile&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Patch calibration setting from profile</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="patchHardwareSettings">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Modify HW parameters using settings from current profile&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Patch HW settings from profile</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="buttonsLayout">
<item>
<spacer name="spacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="cancelButton">
<property name="minimumSize">
<size>
<width>90</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="burnButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>90</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Write to TX</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<tabstops>
<tabstop>burnButton</tabstop>
<tabstop>eepromFilename</tabstop>
<tabstop>eepromLoad</tabstop>
<tabstop>cancelButton</tabstop>
</tabstops>
<resources>
<include location="companion.qrc"/>
</resources>
<connections/>
</ui>

View file

@ -0,0 +1,276 @@
#include "flashfirmwaredialog.h"
#include "ui_flashfirmwaredialog.h"
#include "appdata.h"
#include "converteeprom.h"
#include "eeprominterface.h"
#include "firmwareinterface.h"
#include "process_flash.h"
#include "helpers.h"
#include "hexinterface.h"
#include "progressdialog.h"
#include "radiointerface.h"
#include "splashlibrary.h"
#if defined WIN32 || !defined __GNUC__
#include <windows.h>
#define sleep(x) Sleep(x*1000)
#else
#include <unistd.h>
#endif
FlashFirmwareDialog::FlashFirmwareDialog(QWidget *parent):
QDialog(parent),
ui(new Ui::FlashFirmwareDialog),
fwName(g.profile[g.id()].fwName())
{
ui->setupUi(this);
if (!g.profile[g.id()].splashFile().isEmpty()){
imageSource = PROFILE;
imageFile = g.profile[g.id()].splashFile();
ui->useProfileSplash->setChecked(true);
}
else {
imageSource = FIRMWARE;
imageFile = "";
ui->useProfileSplash->setDisabled(true);
}
if (IS_TARANIS(GetEepromInterface()->getBoard())) {
// No backup on Taranis ... could be done if in massstorage
ui->backupEEprom->hide();
ui->backupEEprom->setCheckState(Qt::Unchecked);
}
else {
ui->backupEEprom->setCheckState(g.backupOnFlash() ? Qt::Checked : Qt::Unchecked);
}
QString backupPath = g.backupDir();
if (backupPath.isEmpty() || !QDir(backupPath).exists()) {
ui->backupEEprom->setEnabled(false);
}
updateUI();
resize(0, 0); // TODO needed?
}
FlashFirmwareDialog::~FlashFirmwareDialog()
{
delete ui;
}
void FlashFirmwareDialog::updateUI()
{
ui->firmwareFilename->setText(fwName);
ui->burnButton->setEnabled(QFile(fwName).exists());
FirmwareInterface firmware(fwName);
if (firmware.isValid()) {
ui->firmwareInfoFrame->show();
ui->date->setText(firmware.getDate() + " " + firmware.getTime());
ui->version->setText(firmware.getVersion());
ui->variant->setText(firmware.getEEpromId());
ui->date->setEnabled(true);
ui->version->setEnabled(true);
ui->variant->setEnabled(true);
if (firmware.hasSplash()) {
ui->splashFrame->show();
ui->splash->setFixedSize(firmware.getSplashWidth(), firmware.getSplashHeight());
}
else {
ui->splashFrame->hide();
}
}
else {
imageSource = FIRMWARE;
ui->firmwareInfoFrame->hide();
ui->splashFrame->hide();
}
QImage image;
switch(imageSource) {
case FIRMWARE:
ui->useFirmwareSplash->setChecked(true);
image = firmware.getSplash();
break;
case PROFILE:
ui->useProfileSplash->setChecked(true);
image.load(g.profile[g.id()].splashFile());
break;
case LIBRARY:
ui->useLibrarySplash->setChecked(true);
image.load(imageFile);
break;
case EXTERNAL:
ui->useExternalSplash->setChecked(true);
image.load(imageFile);
break;
}
if (!image.isNull()) {
ui->splash->setPixmap(makePixMap(image, g.profile[g.id()].fwType()));
}
}
void FlashFirmwareDialog::on_firmwareLoad_clicked()
{
QString fileName = QFileDialog::getOpenFileName(this, tr("Open Firmware File"), g.flashDir(), FLASH_FILES_FILTER);
if (!fileName.isEmpty()) {
fwName = fileName;
if (!fwName.isEmpty() && !FirmwareInterface(fwName).isValid()) {
QMessageBox::warning(this, tr("Warning"), tr("%1 may not be a valid firmware file").arg(fwName));
}
updateUI();
}
}
void FlashFirmwareDialog::on_useFirmwareSplash_clicked()
{
FirmwareInterface firmware(fwName);
if (!firmware.isValid()) {
QMessageBox::warning(this, tr("Error"), tr( "The firmware file is not valid." ));
}
else if (!firmware.hasSplash()) {
QMessageBox::warning(this, tr("Error"), tr( "There is no start screen image in the firmware file." ));
}
else {
imageSource = FIRMWARE;
}
updateUI();
}
void FlashFirmwareDialog::on_useProfileSplash_clicked()
{
QString fileName = g.profile[g.id()].splashFile();
if (!fileName.isEmpty()) {
QImage image(fileName);
if (image.isNull()) {
QMessageBox::critical(this, tr("Error"), tr("Profile image %1 is invalid.").arg(fileName));
}
else {
imageSource = PROFILE;
}
}
updateUI();
}
void FlashFirmwareDialog::on_useExternalSplash_clicked()
{
QString supportedImageFormats;
for (int formatIndex = 0; formatIndex < QImageReader::supportedImageFormats().count(); formatIndex++) {
supportedImageFormats += QLatin1String(" *.") + QImageReader::supportedImageFormats()[formatIndex];
}
QString fileName = QFileDialog::getOpenFileName(this, tr("Open image file to use as radio start screen"), g.imagesDir(), tr("Images (%1)").arg(supportedImageFormats));
if (!fileName.isEmpty()){
g.imagesDir( QFileInfo(fileName).dir().absolutePath() );
QImage image(fileName);
if (image.isNull()) {
QMessageBox::critical(this, tr("Error"), tr("Image could not be loaded from %1").arg(fileName));
}
else{
imageSource = EXTERNAL;
imageFile = fileName;
}
}
updateUI();
}
void FlashFirmwareDialog::on_useLibrarySplash_clicked()
{
QString fileName;
splashLibrary *ld = new splashLibrary(this, &fileName);
ld->exec();
if (!fileName.isEmpty()) {
QImage image(fileName);
if (image.isNull()) {
QMessageBox::critical(this, tr("Error"), tr("The library image could not be loaded"));
}
else {
imageSource = LIBRARY;
imageFile = fileName;
}
}
updateUI();
}
void FlashFirmwareDialog::on_burnButton_clicked()
{
g.flashDir(QFileInfo(fwName).dir().absolutePath());
if (imageSource != FIRMWARE) {
// load the splash image
const QPixmap * pixmap = ui->splash->pixmap();
QImage image;
if (pixmap) {
image = pixmap->toImage().scaled(ui->splash->width(), ui->splash->height());
}
if (image.isNull()) {
QMessageBox::critical(this, tr("Warning"), tr("Splash image not found"));
return;
}
// write the customized firmware
QString tempFile;
if (getFileType(fwName) == FILE_TYPE_HEX)
tempFile = generateProcessUniqueTempFileName("flash.hex");
else
tempFile = generateProcessUniqueTempFileName("flash.bin");
FirmwareInterface firmware(fwName);
firmware.setSplash(image);
if (firmware.save(tempFile) <= 0) {
QMessageBox::critical(this, tr("Warning"), tr("Cannot save customized firmware"));
return;
}
startFlash(tempFile);
}
else {
startFlash(fwName);
}
}
void FlashFirmwareDialog::on_cancelButton_clicked()
{
close();
}
void FlashFirmwareDialog::shrink()
{
resize(0, 0);
}
void FlashFirmwareDialog::startFlash(const QString &filename)
{
bool backup = ui->backupEEprom->checkState() == Qt::Checked;
g.backupOnFlash(backup);
close();
ProgressDialog progressDialog(this, tr("Write Models and Settings to Radio"), CompanionIcon("write_eeprom.png"));
// backup if requested
bool result = true;
QString backupFilename;
if (backup) {
backupFilename = g.backupDir() + "/backup-" + QDateTime().currentDateTime().toString("yyyy-MM-dd-HHmmss") + ".bin";
result = readEeprom(backupFilename, progressDialog.progress());
sleep(2);
}
// flash
result = (result && writeFirmware(filename, progressDialog.progress()));
// restore if backup requested
if (backup && result) {
sleep(2);
QString restoreFilename = generateProcessUniqueTempFileName("restore.bin");
if (!convertEEprom(backupFilename, restoreFilename, filename)) {
QMessageBox::warning(this, tr("Conversion failed"), tr("Cannot convert Models and Settings for use with this firmware, original data will be used"));
restoreFilename = backupFilename;
}
if (!writeEeprom(restoreFilename, progressDialog.progress())) {
QMessageBox::warning(this, tr("Restore failed"), tr("Could not restore Models and Settings to Radio. The models and settings data file can be found at: %1").arg(backupFilename));
}
}
progressDialog.exec();
}

View file

@ -0,0 +1,56 @@
#ifndef FLASH_FIRMWARE_DIALOG_H
#define FLASH_FIRMWARE_DIALOG_H
#include <QtGui>
#include <QDialog>
#include "eeprominterface.h"
#include "firmwareinterface.h"
#include "xmlinterface.h"
#define HEX_FILES_FILTER "HEX files (*.hex);;"
#define BIN_FILES_FILTER "BIN files (*.bin);;"
#define EEPE_FILES_FILTER "EEPE EEPROM files (*.eepe);;"
#define EEPROM_FILES_FILTER "EEPE files (*.eepe *.bin *.hex);;" EEPE_FILES_FILTER BIN_FILES_FILTER HEX_FILES_FILTER
#define FLASH_FILES_FILTER "FLASH files (*.bin *.hex);;" BIN_FILES_FILTER HEX_FILES_FILTER
#define EXTERNAL_EEPROM_FILES_FILTER "EEPROM files (*.bin *.hex);;" BIN_FILES_FILTER HEX_FILES_FILTER
#define ER9X_EEPROM_FILE_TYPE "ER9X_EEPROM_FILE"
#define EEPE_EEPROM_FILE_HEADER "EEPE EEPROM FILE"
#define EEPE_MODEL_FILE_HEADER "EEPE MODEL FILE"
namespace Ui
{
class FlashFirmwareDialog;
}
class FlashFirmwareDialog : public QDialog
{
Q_OBJECT
public:
FlashFirmwareDialog(QWidget *parent = 0);
~FlashFirmwareDialog();
private slots:
void on_firmwareLoad_clicked();
void on_burnButton_clicked();
void on_cancelButton_clicked();
void on_useProfileSplash_clicked();
void on_useFirmwareSplash_clicked();
void on_useLibrarySplash_clicked();
void on_useExternalSplash_clicked();
void shrink();
protected:
void updateUI();
void startFlash(const QString &filename);
private:
Ui::FlashFirmwareDialog *ui;
QString fwName;
RadioData radioData;
enum ImageSource {FIRMWARE, PROFILE, LIBRARY, EXTERNAL};
ImageSource imageSource;
QString imageFile;
};
#endif // FLASH_FIRMWARE_DIALOG_H

View file

@ -0,0 +1,305 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FlashFirmwareDialog</class>
<widget class="QDialog" name="FlashFirmwareDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>421</width>
<height>375</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="windowTitle">
<string>Flash Firmware</string>
</property>
<property name="windowIcon">
<iconset resource="companion.qrc">
<normaloff>:/icon.png</normaloff>:/icon.png</iconset>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout2">
<item>
<widget class="QLineEdit" name="firmwareFilename">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>250</width>
<height>0</height>
</size>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="firmwareLoad">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Load...</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QFrame" name="firmwareInfoFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<item row="3" column="0">
<widget class="QLabel" name="dateLabel">
<property name="text">
<string>Date &amp; Time</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="version">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="buildLabel">
<property name="text">
<string>Variant</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="variant">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="versionLabel">
<property name="text">
<string>Version</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="date">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="splashFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QRadioButton" name="useProfileSplash">
<property name="text">
<string>Use profile start screen</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="useFirmwareSplash">
<property name="text">
<string>Use firmware start screen</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="useLibrarySplash">
<property name="text">
<string>Use library start screen</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="useExternalSplash">
<property name="text">
<string>Use another start screen</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="splash">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>128</width>
<height>64</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>214</width>
<height>66</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::Panel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
<property name="text">
<string/>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QCheckBox" name="backupEEprom">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Backup and restore Models and Settings</string>
</property>
<property name="tristate">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<spacer name="spacer2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout1">
<item>
<spacer name="spacer1">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="cancelButton">
<property name="minimumSize">
<size>
<width>90</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="burnButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>90</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Write to TX</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<tabstops>
<tabstop>burnButton</tabstop>
<tabstop>firmwareFilename</tabstop>
<tabstop>firmwareLoad</tabstop>
<tabstop>version</tabstop>
<tabstop>variant</tabstop>
<tabstop>cancelButton</tabstop>
</tabstops>
<resources>
<include location="companion.qrc"/>
</resources>
<connections/>
</ui>

View file

@ -1,35 +1,36 @@
#include "fusesdialog.h" #include "fusesdialog.h"
#include "ui_fusesdialog.h" #include "ui_fusesdialog.h"
#include "burnconfigdialog.h"
#include "helpers.h" #include "helpers.h"
#include "progressdialog.h"
#include "radiointerface.h"
fusesDialog::fusesDialog(QWidget *parent) : FusesDialog::FusesDialog(QWidget *parent) :
QDialog(parent), QDialog(parent),
ui(new Ui::fusesDialog) ui(new Ui::FusesDialog)
{ {
ui->setupUi(this); ui->setupUi(this);
this->setWindowIcon(CompanionIcon("fuses.png")); setWindowIcon(CompanionIcon("fuses.png"));
} }
fusesDialog::~fusesDialog() FusesDialog::~FusesDialog()
{ {
delete ui; delete ui;
} }
void fusesDialog::on_resetFuses_EEprotect_clicked() void FusesDialog::on_resetFuses_EEprotect_clicked()
{ {
burnConfigDialog *bcd = new burnConfigDialog(this); ProgressDialog progressDialog(this, tr("Reset Radio Fuses"), CompanionIcon("fuses.png"), true);
bcd->restFuses(true); return resetAvrdudeFuses(true, progressDialog.progress());
} }
void fusesDialog::on_resetFuses_EEdelete_clicked() void FusesDialog::on_resetFuses_EEdelete_clicked()
{ {
burnConfigDialog *bcd = new burnConfigDialog(this); ProgressDialog progressDialog(this, tr("Reset Radio Fuses"), CompanionIcon("fuses.png"), true);
bcd->restFuses(false); return resetAvrdudeFuses(false, progressDialog.progress());
} }
void fusesDialog::on_readFuses_clicked() void FusesDialog::on_readFuses_clicked()
{ {
burnConfigDialog *bcd = new burnConfigDialog(this); ProgressDialog progressDialog(this, tr("Read Fuses from Radio"), CompanionIcon("fuses.png"), true);
bcd->readFuses(); return readAvrdudeFuses(progressDialog.progress());
} }

View file

@ -1,27 +1,28 @@
#ifndef FUSESDIALOG_H #ifndef FUSESDIALOG_H_
#define FUSESDIALOG_H #define FUSESDIALOG_H_
#include <QDialog> #include <QDialog>
namespace Ui { namespace Ui {
class fusesDialog; class FusesDialog;
} }
class fusesDialog : public QDialog class FusesDialog : public QDialog
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit fusesDialog(QWidget *parent = 0); explicit FusesDialog(QWidget *parent = 0);
~fusesDialog(); ~FusesDialog();
private:
Ui::fusesDialog *ui;
private slots: private slots:
void on_readFuses_clicked(); void on_readFuses_clicked();
void on_resetFuses_EEdelete_clicked(); void on_resetFuses_EEdelete_clicked();
void on_resetFuses_EEprotect_clicked(); void on_resetFuses_EEprotect_clicked();
private:
Ui::FusesDialog *ui;
}; };
#endif // FUSESDIALOG_H #endif // FUSESDIALOG_H_

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"> <ui version="4.0">
<class>fusesDialog</class> <class>FusesDialog</class>
<widget class="QDialog" name="fusesDialog"> <widget class="QDialog" name="FusesDialog">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>

View file

@ -1,7 +1,7 @@
#include "calibration.h" #include "calibration.h"
#include "ui_calibration.h" #include "ui_calibration.h"
CalibrationPanel::CalibrationPanel(QWidget * parent, GeneralSettings & generalSettings, FirmwareInterface * firmware): CalibrationPanel::CalibrationPanel(QWidget * parent, GeneralSettings & generalSettings, Firmware * firmware):
GeneralPanel(parent, generalSettings, firmware), GeneralPanel(parent, generalSettings, firmware),
ui(new Ui::Calibration) ui(new Ui::Calibration)
{ {

View file

@ -12,7 +12,7 @@ class CalibrationPanel : public GeneralPanel
Q_OBJECT Q_OBJECT
public: public:
CalibrationPanel(QWidget *parent, GeneralSettings & generalSettings, FirmwareInterface * firmware); CalibrationPanel(QWidget *parent, GeneralSettings & generalSettings, Firmware * firmware);
virtual ~CalibrationPanel(); virtual ~CalibrationPanel();
virtual void update(); virtual void update();

View file

@ -11,7 +11,7 @@
#include "../modeledit/customfunctions.h" #include "../modeledit/customfunctions.h"
#include "verticalscrollarea.h" #include "verticalscrollarea.h"
GeneralEdit::GeneralEdit(QWidget * parent, RadioData & radioData, FirmwareInterface * firmware) : GeneralEdit::GeneralEdit(QWidget * parent, RadioData & radioData, Firmware * firmware) :
QDialog(parent), QDialog(parent),
ui(new Ui::GeneralEdit), ui(new Ui::GeneralEdit),
generalSettings(radioData.generalSettings), generalSettings(radioData.generalSettings),

View file

@ -12,7 +12,7 @@ namespace Ui {
class GeneralPanel : public GenericPanel class GeneralPanel : public GenericPanel
{ {
public: public:
GeneralPanel(QWidget *parent, GeneralSettings & generalSettings, FirmwareInterface * firmware): GeneralPanel(QWidget *parent, GeneralSettings & generalSettings, Firmware * firmware):
GenericPanel(parent, NULL, generalSettings, firmware) GenericPanel(parent, NULL, generalSettings, firmware)
{ {
} }
@ -23,7 +23,7 @@ class GeneralEdit : public QDialog
Q_OBJECT Q_OBJECT
public: public:
GeneralEdit(QWidget * parent, RadioData & radioData, FirmwareInterface * firmware); GeneralEdit(QWidget * parent, RadioData & radioData, Firmware * firmware);
~GeneralEdit(); ~GeneralEdit();
private: private:
@ -47,7 +47,7 @@ class GeneralEdit : public QDialog
void on_calstore_PB_clicked(); void on_calstore_PB_clicked();
private: private:
FirmwareInterface * firmware; Firmware * firmware;
QVector<GenericPanel *> panels; QVector<GenericPanel *> panels;
void addTab(GenericPanel *panel, QString text); void addTab(GenericPanel *panel, QString text);

View file

@ -2,7 +2,7 @@
#include "ui_generalsetup.h" #include "ui_generalsetup.h"
#include <QMessageBox> #include <QMessageBox>
GeneralSetupPanel::GeneralSetupPanel(QWidget * parent, GeneralSettings & generalSettings, FirmwareInterface * firmware): GeneralSetupPanel::GeneralSetupPanel(QWidget * parent, GeneralSettings & generalSettings, Firmware * firmware):
GeneralPanel(parent, generalSettings, firmware), GeneralPanel(parent, generalSettings, firmware),
ui(new Ui::GeneralSetup) ui(new Ui::GeneralSetup)
{ {

View file

@ -13,7 +13,7 @@ class GeneralSetupPanel : public GeneralPanel
Q_OBJECT Q_OBJECT
public: public:
GeneralSetupPanel(QWidget *parent, GeneralSettings & generalSettings, FirmwareInterface * firmware); GeneralSetupPanel(QWidget *parent, GeneralSettings & generalSettings, Firmware * firmware);
virtual ~GeneralSetupPanel(); virtual ~GeneralSetupPanel();
private slots: private slots:

View file

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>758</width> <width>689</width>
<height>635</height> <height>606</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -1897,9 +1897,9 @@ Mode 4:
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt; <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt; &lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; } p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt; &lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:8pt;&quot;&gt;Play Delay&lt;/span&gt;&lt;/p&gt; &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:8pt;&quot;&gt;LCD Screen Contrast&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:8pt;&quot;&gt;Values can be 0ms-300ms&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:8pt;&quot;&gt;Values can be 20-45&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="suffix"> <property name="suffix">
<string> ms</string> <string> ms</string>

View file

@ -1,7 +1,7 @@
#include "trainer.h" #include "trainer.h"
#include "ui_trainer.h" #include "ui_trainer.h"
TrainerPanel::TrainerPanel(QWidget * parent, GeneralSettings & generalSettings, FirmwareInterface * firmware): TrainerPanel::TrainerPanel(QWidget * parent, GeneralSettings & generalSettings, Firmware * firmware):
GeneralPanel(parent, generalSettings, firmware), GeneralPanel(parent, generalSettings, firmware),
ui(new Ui::Trainer) ui(new Ui::Trainer)
{ {

View file

@ -13,7 +13,7 @@ class TrainerPanel : public GeneralPanel
Q_OBJECT Q_OBJECT
public: public:
TrainerPanel(QWidget *parent, GeneralSettings & generalSettings, FirmwareInterface * firmware); TrainerPanel(QWidget *parent, GeneralSettings & generalSettings, Firmware * firmware);
virtual ~TrainerPanel(); virtual ~TrainerPanel();
private slots: private slots:

View file

@ -10,7 +10,7 @@
#include "helpers.h" #include "helpers.h"
#include "simulatordialog.h" #include "simulatordialog.h"
#include "simulatorinterface.h" #include "simulatorinterface.h"
#include "flashinterface.h" #include "firmwareinterface.h"
const QColor colors[C9X_MAX_CURVES] = { const QColor colors[C9X_MAX_CURVES] = {
QColor(0,0,127), QColor(0,0,127),
@ -686,40 +686,6 @@ QString image2qstring(QImage image)
return ImageStr; return ImageStr;
} }
// TODO KKERNEN 20140222
// I am sure that this code has had some kind of function, but now it only seems to cause
// problems. I think it is an attempt to open an image file from a double byte string which
// is first converted to a single byte string. Only used in burndialog.cpp
// It doesn't work for me in 2.0. I do not know why. I doubt it has ever worked for files or
// file paths containing non-english characters.
// Code can be removed ,when 2.0 is tested.
QImage qstring2image(QString imagestr)
{
bool ok;
bool failed=false;
QImage Image;
int len = imagestr.length();
char b=0;
QBuffer buffer;
buffer.open(QIODevice::ReadWrite);
buffer.seek(0);
for (int i = 0; i < len/2; i++) {
QString Byte;
Byte = imagestr.mid((i * 2), 2);
b = Byte.toUInt(&ok, 16);
if (!ok) {
failed = true;
}
buffer.putChar(b);
}
buffer.seek(0);
if (!failed) {
Image.load(&buffer,"PNG");
}
return Image;
}
int findmult(float value, float base) int findmult(float value, float base)
{ {
int vvalue = value*10; int vvalue = value*10;
@ -920,7 +886,7 @@ QString getTheme()
return Theme; return Theme;
} }
CompanionIcon::CompanionIcon(QString baseimage) CompanionIcon::CompanionIcon(const QString &baseimage)
{ {
static QString theme = getTheme(); static QString theme = getTheme();
addFile(":/themes/"+theme+"/16/"+baseimage, QSize(16,16)); addFile(":/themes/"+theme+"/16/"+baseimage, QSize(16,16));

View file

@ -32,7 +32,7 @@ QString getTheme();
class CompanionIcon: public QIcon { class CompanionIcon: public QIcon {
public: public:
CompanionIcon(QString baseimage); CompanionIcon(const QString &baseimage);
}; };
class GVarGroup: public QObject { class GVarGroup: public QObject {
@ -119,7 +119,6 @@ void populateSourceCB(QComboBox *b, const RawSource &source, const ModelData * m
QString getPhaseName(int val, const char * phasename=NULL); QString getPhaseName(int val, const char * phasename=NULL);
QString getInputStr(ModelData * model, int index); QString getInputStr(ModelData * model, int index);
QString image2qstring(QImage image); QString image2qstring(QImage image);
QImage qstring2image(QString imagestr);
int findmult(float value, float base); int findmult(float value, float base);
QString getTrimInc(ModelData * g_model); QString getTrimInc(ModelData * g_model);

31
companion/src/helpers_html.cpp Executable file
View file

@ -0,0 +1,31 @@
#include "helpers_html.h"
QString tdAlign(const QString &s, const QString &align, const QString &color, bool bold)
{
QString str = s;
if (bold) str = "<b>" + str + "</b>";
if (!color.isEmpty()) str = "<font color=" + color + ">" + str + "</font>";
return "<td align=" + align + ">" + str + "</td>";
}
QString doTC(const QString &s, const QString &color, bool bold)
{
return tdAlign(s, "center", color, bold);
}
QString doTR(const QString &s, const QString &color, bool bold)
{
return tdAlign(s, "right", color, bold);
}
QString doTL(const QString &s, const QString &color, bool bold)
{
return tdAlign(s, "left", color, bold);
}
QString fv(const QString &name, const QString &value, const QString &color)
{
return "<b>" + name + ": </b><font color=" +color + ">" + value + "</font><br>";
}

11
companion/src/helpers_html.h Executable file
View file

@ -0,0 +1,11 @@
#ifndef HELPERS_HTML_H_
#define HELPERS_HTML_H_
#include <QString>
QString doTC(const QString &s, const QString &color="", bool bold=false);
QString doTR(const QString &s, const QString &color="", bool bold=false);
QString doTL(const QString &s, const QString &color="", bool bold=false);
QString fv(const QString &name, const QString &value, const QString &color="green");
#endif /* HELPERS_HTML_H_ */

View file

@ -46,25 +46,27 @@
#include "mainwindow.h" #include "mainwindow.h"
#include "mdichild.h" #include "mdichild.h"
#include "burnconfigdialog.h" #include "burnconfigdialog.h"
#include "avroutputdialog.h"
#include "comparedialog.h" #include "comparedialog.h"
#include "logsdialog.h" #include "logsdialog.h"
#include "apppreferencesdialog.h" #include "apppreferencesdialog.h"
#include "fwpreferencesdialog.h" #include "fwpreferencesdialog.h"
#include "flashinterface.h" #include "firmwareinterface.h"
#include "fusesdialog.h" #include "fusesdialog.h"
#include "downloaddialog.h" #include "downloaddialog.h"
#include "printdialog.h" #include "printdialog.h"
#include "version.h" #include "version.h"
#include "contributorsdialog.h" #include "contributorsdialog.h"
#include "customizesplashdialog.h" #include "customizesplashdialog.h"
#include "burndialog.h" #include "flasheepromdialog.h"
#include "flashfirmwaredialog.h"
#include "hexinterface.h" #include "hexinterface.h"
#include "warnings.h" #include "warnings.h"
#include "helpers.h" #include "helpers.h"
#include "appdata.h" #include "appdata.h"
#include "radionotfound.h" #include "radionotfound.h"
#include "foldersync.h" #include "process_sync.h"
#include "radiointerface.h"
#include "progressdialog.h"
#define OPENTX_COMPANION_DOWNLOADS "http://downloads-20.open-tx.org/companion" #define OPENTX_COMPANION_DOWNLOADS "http://downloads-20.open-tx.org/companion"
#define DONATE_STR "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=QUZ48K4SEXDP2" #define DONATE_STR "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=QUZ48K4SEXDP2"
@ -82,7 +84,6 @@
#define sleep(x) Sleep(x*1000) #define sleep(x) Sleep(x*1000)
#else #else
#include <unistd.h> #include <unistd.h>
#include "mountlist.h"
#endif #endif
MainWindow::MainWindow(): MainWindow::MainWindow():
@ -670,11 +671,16 @@ void MainWindow::contributors()
void MainWindow::sdsync() void MainWindow::sdsync()
{ {
QString massstoragePath = FindMassstoragePath("SOUNDS"); QString massstoragePath = findMassstoragePath("SOUNDS");
if (!massstoragePath.isEmpty()) if (massstoragePath.isEmpty()) {
QMessageBox::warning(this, QObject::tr("Synchronization error"), QObject::tr("No Radio connected!"));
return;
}
massstoragePath += "/.."; massstoragePath += "/..";
FoldersSyncTask syncTask(massstoragePath, g.profile[g.id()].sdPath()); ProgressDialog progressDialog(this, tr("Synchronize SD"), CompanionIcon("sdsync.png"));
syncTask.run(); SyncProcess syncProcess(massstoragePath, g.profile[g.id()].sdPath(), progressDialog.progress());
syncProcess.run();
progressDialog.exec();
} }
void MainWindow::changelog() void MainWindow::changelog()
@ -685,7 +691,7 @@ void MainWindow::changelog()
void MainWindow::fwchangelog() void MainWindow::fwchangelog()
{ {
FirmwareInterface *currfirm = GetCurrentFirmware(); Firmware *currfirm = GetCurrentFirmware();
QString rn=currfirm->getReleaseNotesUrl(); QString rn=currfirm->getReleaseNotesUrl();
if (rn.isEmpty()) { if (rn.isEmpty()) {
QMessageBox::information(this, tr("Firmware updates"), tr("Current firmware does not provide release notes informations.")); QMessageBox::information(this, tr("Firmware updates"), tr("Current firmware does not provide release notes informations."));
@ -749,211 +755,6 @@ void MainWindow::loadBackup()
activeMdiChild()->loadBackup(); activeMdiChild()->loadBackup();
} }
QString MainWindow::GetAvrdudeLocation()
{
burnConfigDialog bcd;
EEPROMInterface *eepromInterface = GetEepromInterface();
if (IS_TARANIS(eepromInterface->getBoard())) {
return bcd.getDFU();
} else if (IS_SKY9X(GetEepromInterface()->getBoard())) {
return bcd.getSAMBA();
} else {
return bcd.getAVRDUDE();
}
}
QStringList MainWindow::GetAvrdudeArguments(const QString &cmd, const QString &filename)
{
QStringList arguments;
burnConfigDialog bcd;
QString programmer = bcd.getProgrammer();
QStringList args = bcd.getAVRArgs();
QString mcu = bcd.getMCU();
if(!bcd.getPort().isEmpty()) args << "-P" << bcd.getPort();
arguments << "-c" << programmer << "-p";
if (GetEepromInterface()->getBoard() == BOARD_GRUVIN9X)
arguments << "m2560";
else if (GetEepromInterface()->getBoard() == BOARD_M128)
arguments << "m128";
else
arguments << mcu;
arguments << args;
QString fullcmd = cmd + filename;
if(QFileInfo(filename).suffix().toUpper()=="HEX") fullcmd += ":i";
else if(QFileInfo(filename).suffix().toUpper()=="BIN") fullcmd += ":r";
else fullcmd += ":a";
arguments << "-U" << fullcmd;
return arguments;
}
QStringList MainWindow::GetDFUUtilArguments(const QString &cmd, const QString &filename)
{
QStringList arguments;
burnConfigDialog bcd;
QStringList args = bcd.getDFUArgs();
QString memory="0x08000000";
if (cmd=="-U") {
memory.append(QString(":%1").arg(MAX_FSIZE));
}
arguments << args << "--dfuse-address" << memory << "-d" << "0483:df11";
QString fullcmd = cmd + filename;
arguments << "" << fullcmd;
return arguments;
}
QStringList MainWindow::GetSambaArguments(const QString &tcl)
{
QStringList result;
QString tclFilename = generateProcessUniqueTempFileName("temp.tcl");
if (QFile::exists(tclFilename)) {
qunlink(tclFilename);
}
QFile tclFile(tclFilename);
if (!tclFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
QMessageBox::warning(this, tr("Error"),
tr("Cannot write file %1:\n%2.")
.arg(tclFilename)
.arg(tclFile.errorString()));
return result;
}
QTextStream outputStream(&tclFile);
outputStream << tcl;
burnConfigDialog bcd;
result << bcd.getSambaPort() << bcd.getArmMCU() << tclFilename ;
return result;
}
QStringList MainWindow::GetReceiveEEpromCommand(const QString &filename)
{
QStringList ret;
EEPROMInterface *eepromInterface = GetEepromInterface();
if (IS_TARANIS(eepromInterface->getBoard())) {
// impossible
}
else if (IS_SKY9X(eepromInterface->getBoard())) {
ret=GetSambaArguments(QString("SERIALFLASH::Init 0\n") + "receive_file {SerialFlash AT25} \"" + filename + "\" 0x0 0x80000 0\n");
}
else {
ret=GetAvrdudeArguments("eeprom:r:", filename);
}
return ret;
}
QStringList MainWindow::GetSendEEpromCommand(const QString &filename)
{
QStringList ret;
EEPROMInterface *eepromInterface = GetEepromInterface();
if (IS_TARANIS(eepromInterface->getBoard())) {
// impossible
}
else if (IS_SKY9X(eepromInterface->getBoard())) {
ret=GetSambaArguments(QString("SERIALFLASH::Init 0\n") + "send_file {SerialFlash AT25} \"" + filename + "\" 0x0 0\n");
}
else {
ret=GetAvrdudeArguments("eeprom:w:", filename);
}
return ret;
}
QStringList MainWindow::GetSendFlashCommand(const QString &filename)
{
QStringList ret;
EEPROMInterface *eepromInterface = GetEepromInterface();
if (IS_TARANIS(eepromInterface->getBoard())) {
ret=GetDFUUtilArguments("-D", filename);
}
else if (eepromInterface->getBoard() == BOARD_SKY9X) {
ret=GetSambaArguments(QString("send_file {Flash} \"") + filename + "\" 0x400000 0\n" + "FLASH::ScriptGPNMV 2\n");
}
else if (eepromInterface->getBoard() == BOARD_9XRPRO) {
ret=GetSambaArguments(QString("send_file {Flash} \"") + filename + "\" 0x400000 0\n" + "FLASH::ScriptGPNMV 2\n");
}
else {
ret=GetAvrdudeArguments("flash:w:", filename);
}
return ret;
}
QStringList MainWindow::GetReceiveFlashCommand(const QString &filename)
{
EEPROMInterface *eepromInterface = GetEepromInterface();
if (IS_TARANIS(eepromInterface->getBoard())) {
return GetDFUUtilArguments("-U", filename);
}
else if (eepromInterface->getBoard() == BOARD_SKY9X) {
return GetSambaArguments(QString("receive_file {Flash} \"") + filename + "\" 0x400000 0x40000 0\n");
}
else if (eepromInterface->getBoard() == BOARD_9XRPRO) {
return GetSambaArguments(QString("receive_file {Flash} \"") + filename + "\" 0x400000 0x80000 0\n");
}
else {
return GetAvrdudeArguments("flash:r:", filename);
}
}
QString MainWindow::FindMassstoragePath(QString filename)
{
QString temppath;
QStringList drives;
QString eepromfile;
QString fsname;
#if defined WIN32 || !defined __GNUC__
foreach( QFileInfo drive, QDir::drives() ) {
WCHAR szVolumeName[256] ;
WCHAR szFileSystemName[256];
DWORD dwSerialNumber = 0;
DWORD dwMaxFileNameLength=256;
DWORD dwFileSystemFlags=0;
bool ret = GetVolumeInformationW( (WCHAR *) drive.absolutePath().utf16(),szVolumeName,256,&dwSerialNumber,&dwMaxFileNameLength,&dwFileSystemFlags,szFileSystemName,256);
if (ret) {
QString vName = QString::fromUtf16 ( (const ushort *) szVolumeName) ;
temppath = drive.absolutePath();
eepromfile = temppath;
eepromfile.append("/" + filename);
if (QFile::exists(eepromfile)) {
return eepromfile;
}
}
}
#else
struct mount_entry *entry;
entry = read_file_system_list(true);
while (entry != NULL) {
if (!drives.contains(entry->me_devname)) {
drives.append(entry->me_devname);
temppath = entry->me_mountdir;
eepromfile = temppath;
eepromfile.append("/" + filename);
#if !defined __APPLE__
QString fstype = entry->me_type;
if (QFile::exists(eepromfile) && fstype.contains("fat") ) {
#else
if (QFile::exists(eepromfile)) {
#endif
return eepromfile;
}
}
entry = entry->me_next;
}
#endif
return QString();
}
void MainWindow::readEeprom() void MainWindow::readEeprom()
{ {
QString tempFile; QString tempFile;
@ -967,7 +768,7 @@ void MainWindow::readEeprom()
qDebug() << "MainWindow::readEeprom(): using temp file: " << tempFile; qDebug() << "MainWindow::readEeprom(): using temp file: " << tempFile;
if (readEepromFromRadio(tempFile, tr("Read Models and Settings From Radio"))) { if (readEepromFromRadio(tempFile)) {
MdiChild *child = createMdiChild(); MdiChild *child = createMdiChild();
child->newFile(); child->newFile();
child->loadFile(tempFile, false); child->loadFile(tempFile, false);
@ -976,244 +777,34 @@ void MainWindow::readEeprom()
} }
} }
bool MainWindow::readFirmwareFromRadio(const QString filename) bool MainWindow::readFirmwareFromRadio(const QString &filename)
{ {
bool result = false; ProgressDialog progressDialog(this, tr("Read Firmware from Radio"), CompanionIcon("read_flash.png"));
return readFirmware(filename, progressDialog.progress());
QString message = tr("Read Firmware From Radio");
QFile file(filename);
if (file.exists()) {
file.remove();
} }
g.flashDir(QFileInfo(filename).dir().absolutePath()); bool MainWindow::writeFirmwareToRadio(const QString &filename)
if (IS_ARM(GetCurrentFirmware()->getBoard())) {
QString path = FindMassstoragePath("FIRMWARE.BIN");
if (!path.isEmpty()) {
QStringList str;
str << path << filename;
avrOutputDialog *ad = new avrOutputDialog(this, "", str, message);
ad->setWindowIcon(CompanionIcon("read_flash.png"));
ad->exec();
delete ad;
result = true;
}
}
if (result == false) {
QStringList str = GetReceiveFlashCommand(filename);
avrOutputDialog *ad = new avrOutputDialog(this, GetAvrdudeLocation(), str, message);
ad->setWindowIcon(CompanionIcon("read_flash.png"));
ad->exec();
delete ad;
result = true;
}
if (!QFileInfo(filename).exists())
result = false;
return result;
}
bool MainWindow::writeFirmwareToRadio(const QString filename)
{ {
bool result = false; ProgressDialog progressDialog(this, tr("Write Firmware to Radio"), CompanionIcon("write_flash.png"));
return writeFirmware(filename, progressDialog.progress());
QString message = tr("Write Firmware To Radio");
if (IS_ARM(GetCurrentFirmware()->getBoard())) {
QString path = FindMassstoragePath("FIRMWARE.BIN");
if (!path.isEmpty()) {
QStringList str;
str << filename << path;
avrOutputDialog *ad = new avrOutputDialog(this, "", str, message);
ad->setWindowIcon(CompanionIcon("write_flash.png"));
ad->exec();
delete ad;
result = true;
}
} }
if (result == false) { bool MainWindow::readEepromFromRadio(const QString &filename)
QStringList str = GetSendFlashCommand(filename);
avrOutputDialog *ad = new avrOutputDialog(this, GetAvrdudeLocation(), str, message, AVR_DIALOG_CLOSE_IF_SUCCESSFUL);
CompanionIcon iconw("write_flash.png");
ad->setWindowIcon(iconw);
result = ad->exec();
delete ad;
}
return result;
}
bool MainWindow::readEepromFromRadio(const QString filename, const QString message)
{ {
bool result = false; ProgressDialog progressDialog(this, tr("Read Models and Settings from Radio"), CompanionIcon("read_eeprom.png"));
return ::readEeprom(filename, progressDialog.progress());
QFile file(filename);
if (file.exists()) {
if (!file.remove()) {
QMessageBox::warning(this, tr("Error"), tr("Could not delete temporary file: %1").arg(filename));
return false;
}
} }
if (IS_ARM(GetCurrentFirmware()->getBoard())) { bool MainWindow::writeEepromToRadio(const QString &filename)
QString path = FindMassstoragePath("EEPROM.BIN");
if (path.isEmpty()) {
// On previous OpenTX we called the EEPROM file "TARANIS.BIN" :(
path = FindMassstoragePath("TARANIS.BIN");
}
if (path.isEmpty()) {
// Mike's bootloader calls the EEPROM file "ERSKY9X.BIN" :(
path = FindMassstoragePath("ERSKY9X.BIN");
}
if (!path.isEmpty()) {
QStringList str;
str << path << filename;
avrOutputDialog *ad = new avrOutputDialog(this, "", str, message);
ad->setWindowIcon(CompanionIcon("read_eeprom.png"));
ad->exec();
delete ad;
result = true;
}
}
if (result == false && !IS_TARANIS(GetCurrentFirmware()->getBoard())) {
QStringList str = GetReceiveEEpromCommand(filename);
avrOutputDialog *ad = new avrOutputDialog(this, GetAvrdudeLocation(), str, message);
ad->setWindowIcon(CompanionIcon("read_eeprom.png"));
ad->exec();
delete ad;
result = true;
}
if (result == false && IS_ARM(GetCurrentFirmware()->getBoard())) {
RadioNotFoundDialog *dialog = new RadioNotFoundDialog(this);
dialog->exec();
delete dialog;
}
if (!QFileInfo(filename).exists()) {
result = false;
}
return result;
}
bool MainWindow::writeEepromToRadio(const QString filename, const QString message)
{ {
bool result = false; ProgressDialog progressDialog(this, tr("Write Models and Settings to Radio"), CompanionIcon("write_eeprom.png"));
return ::writeEeprom(filename, progressDialog.progress());
if (IS_ARM(GetCurrentFirmware()->getBoard())) {
QString path = FindMassstoragePath("EEPROM.BIN");
if (path.isEmpty()) {
// On previous OpenTX we called the EEPROM file "TARANIS.BIN" :(
path = FindMassstoragePath("TARANIS.BIN");
}
if (path.isEmpty()) {
// Mike's bootloader calls the EEPROM file "ERSKY9X.BIN" :(
path = FindMassstoragePath("ERSKY9X.BIN");
}
if (!path.isEmpty()) {
QStringList str;
str << filename << path;
avrOutputDialog *ad = new avrOutputDialog(this, "", str, message, AVR_DIALOG_SHOW_DONE);
ad->setWindowIcon(CompanionIcon("write_eeprom.png"));
ad->exec();
delete ad;
result = true;
}
}
if (result == false && !IS_TARANIS(GetCurrentFirmware()->getBoard())) {
QStringList str = GetSendEEpromCommand(filename);
avrOutputDialog *ad = new avrOutputDialog(this, GetAvrdudeLocation(), str, "Write EEPROM To Radio", AVR_DIALOG_SHOW_DONE);
ad->setWindowIcon(CompanionIcon("write_eeprom.png"));
ad->exec();
delete ad;
result = true;
}
if (result == false && IS_ARM(GetCurrentFirmware()->getBoard())) {
RadioNotFoundDialog *dialog = new RadioNotFoundDialog(this);
dialog->exec();
delete dialog;
}
return result;
} }
void MainWindow::writeBackup() void MainWindow::writeBackup()
{ {
QString fileName; FlashEEpromDialog *cd = new FlashEEpromDialog(this);
bool backup = false;
burnDialog *cd = new burnDialog(this, 1, &fileName, &backup);
cd->exec(); cd->exec();
if (!fileName.isEmpty()) {
g.eepromDir(QFileInfo(fileName).dir().absolutePath());
int ret = QMessageBox::question(this, "Companion", tr("Write Radio Backup from %1 to the radio?").arg(QFileInfo(fileName).fileName()), QMessageBox::Yes | QMessageBox::No);
if (ret != QMessageBox::Yes) return;
if (!isValidEEPROM(fileName))
ret = QMessageBox::question(this, "Companion", tr("The file %1\nhas not been recognized as a valid Models and Settings file\nWrite anyway ?").arg(QFileInfo(fileName).fileName()), QMessageBox::Yes | QMessageBox::No);
if (ret != QMessageBox::Yes) return;
bool backupEnable = g.enableBackup();
QString backupPath = g.backupDir();
if (!backupPath.isEmpty()) {
if (!QDir(backupPath).exists()) {
if (backupEnable) {
QMessageBox::warning(this, tr("Backup is impossible"), tr("The backup dir set in preferences does not exist"));
}
backupEnable = false;
}
}
else {
backupEnable = false;
}
if (backup) {
if (backupEnable) {
QString backupFile = backupPath + "/backup-" + QDateTime().currentDateTime().toString("yyyy-MM-dd-HHmmss") + ".bin";
if (!readEepromFromRadio(backupFile, tr("Backup Models and Settings From Radio")))
return;
}
int oldrev = getEpromVersion(fileName);
QString tempFlash = generateProcessUniqueTempFileName("flash.bin");
if (!readFirmwareFromRadio(tempFlash))
return;
QString restoreFile = generateProcessUniqueTempFileName("compat.bin");
if (!convertEEPROM(fileName, restoreFile, tempFlash)) {
int ret = QMessageBox::question(this, "Error", tr("Cannot check Models and Settings compatibility! Continue anyway?") ,
QMessageBox::Yes | QMessageBox::No);
if (ret==QMessageBox::No)
return;
}
else {
int rev = getEpromVersion(restoreFile);
if ((rev / 100) != (oldrev / 100)) {
QMessageBox::warning(this, tr("Warning"), tr("The radio firmware belongs to another product family, check file and preferences!"));
}
else if (rev < oldrev) {
QMessageBox::warning(this, tr("Warning"), tr("The radio firmware is outdated, please upgrade!"));
}
fileName = restoreFile;
}
qunlink(tempFlash);
}
else {
if (backupEnable) {
QString backupFile = backupPath + "/backup-" + QDateTime().currentDateTime().toString("yyyy-MM-dd-hhmmss") + ".bin";
if (!readEepromFromRadio(backupFile, tr("Backup Models and Settings From Radio")))
return;
}
}
if (!writeEepromToRadio(fileName, tr("Write Backup To Radio")))
return;
}
} }
int MainWindow::getFileType(const QString &fullFileName) int MainWindow::getFileType(const QString &fullFileName)
@ -1226,165 +817,17 @@ int MainWindow::getFileType(const QString &fullFileName)
return 0; return 0;
} }
bool MainWindow::isValidEEPROM(QString eepromfile)
{
int eeprom_size;
QFile file(eepromfile);
int fileType = getFileType(eepromfile);
if (fileType==FILE_TYPE_HEX || fileType==FILE_TYPE_EEPE) {
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return false;
eeprom_size = file.size();
QByteArray eeprom(eeprom_size, 0);
QTextStream inputStream(&file);
eeprom_size = HexInterface(inputStream).load((uint8_t *)eeprom.data(), eeprom_size);
if (!eeprom_size) {
return false;
}
file.close();
RadioData * radioData = new RadioData();
bool result = LoadEeprom(*radioData, (uint8_t *)eeprom.data(), eeprom_size);
delete radioData;
return result;
}
else if (fileType==FILE_TYPE_BIN) { //read binary
if (!file.open(QFile::ReadOnly))
return false;
eeprom_size = file.size();
QByteArray eeprom(eeprom_size, 0);
long read = file.read(eeprom.data(), eeprom_size);
file.close();
if (read != eeprom_size) {
return false;
}
RadioData * radioData = new RadioData();
bool result = LoadEeprom(*radioData, (uint8_t *)eeprom.data(), eeprom_size);
delete radioData;
return result;
}
return false;
}
bool MainWindow::convertEEPROM(QString backupFile, QString restoreFile, QString flashFile)
{
FirmwareInterface *firmware = GetCurrentFirmware();
FlashInterface flash(flashFile);
if (!flash.isValid())
return false;
unsigned int version = flash.getEEpromVersion();
unsigned int variant = flash.getEEpromVariant();
QFile file(backupFile);
int eeprom_size = file.size();
if (!eeprom_size)
return false;
if (!file.open(QIODevice::ReadOnly))
return false;
QByteArray eeprom(eeprom_size, 0);
long result = file.read(eeprom.data(), eeprom_size);
file.close();
QSharedPointer<RadioData> radioData = QSharedPointer<RadioData>(new RadioData());
if (!LoadEeprom(*radioData, (uint8_t *)eeprom.data(), eeprom_size) || !firmware->saveEEPROM((uint8_t *)eeprom.data(), *radioData, variant, version))
return false;
QFile file2(restoreFile);
if (!file2.open(QIODevice::WriteOnly))
return false;
result = file2.write(eeprom.constData(), eeprom_size);
file2.close();
if (result != eeprom_size)
return false;
return true;
}
void MainWindow::writeFlash(QString fileToFlash) void MainWindow::writeFlash(QString fileToFlash)
{ {
QString fileName; FlashFirmwareDialog *cd = new FlashFirmwareDialog(this);
bool backup = g.backupOnFlash();
if(!fileToFlash.isEmpty())
fileName = fileToFlash;
burnDialog *cd = new burnDialog(this, 2, &fileName, &backup);
cd->exec(); cd->exec();
if (IS_TARANIS(GetEepromInterface()->getBoard()))
backup=false;
if (!fileName.isEmpty()) {
g.backupOnFlash(backup);
if (backup) {
QString backupFile = generateProcessUniqueTempFileName("backup.bin");
bool backupEnable=g.enableBackup();
QString backupPath=g.backupDir();
if (!backupPath.isEmpty() && !IS_TARANIS(GetEepromInterface()->getBoard())) {
if (!QDir(backupPath).exists()) {
if (backupEnable) {
QMessageBox::warning(this, tr("Backup is impossible"), tr("The backup dir set in preferences does not exist"));
}
backupEnable=false;
}
}
else {
backupEnable=false;
}
if (backupEnable) {
QDateTime datetime;
backupFile.clear();
backupFile = backupPath+"/backup-"+QDateTime().currentDateTime().toString("yyyy-MM-dd-hhmmss")+".bin";
}
if (readEepromFromRadio(backupFile, tr("Backup Models and Settings From Radio"))) {
sleep(2);
int res = writeFirmwareToRadio(fileName);
if (res) {
QString restoreFile = generateProcessUniqueTempFileName("restore.bin");
if (!convertEEPROM(backupFile, restoreFile, fileName)) {
QMessageBox::warning(this, tr("Conversion failed"), tr("Cannot convert Models and Settings for use with this firmware, original data will be used"));
restoreFile = backupFile;
}
sleep(2);
if (!writeEepromToRadio(restoreFile, tr("Restore Models and Settings To Radio"))) {
QMessageBox::warning(this, tr("Restore failed"), tr("Could not restore Models and Settings to Radio. The models and settings data file can be found at: %1").arg(backupFile));
}
}
else {
QMessageBox::warning(this, tr("Firmware write failed"), tr("Could not write firmware to radio. The models and settings data file can be found at: %1").arg(backupFile));
}
}
else {
QMessageBox::warning(this, tr("Backup failed"), tr("Cannot backup existing Models and Settings from Radio. Firmware write process aborted"));
}
}
else {
bool backupEnable=g.enableBackup();
QString backupPath=g.backupDir();
if (!QDir(backupPath).exists()) {
if (backupEnable) {
QMessageBox::warning(this, tr("Backup is impossible"), tr("The backup dir set in preferences does not exist"));
}
backupEnable=false;
}
if (backupEnable && !IS_TARANIS(GetEepromInterface()->getBoard())) {
QDateTime datetime;
QString backupFile = backupPath+"/backup-"+QDateTime().currentDateTime().toString("yyyy-MM-dd-hhmmss")+".bin";
readEepromFromRadio(backupFile, tr("Backup Models and Settings From Radio"));
sleep(2);
}
writeFirmwareToRadio(fileName);
}
}
} }
void MainWindow::readBackup() void MainWindow::readBackup()
{ {
QString fileName = QFileDialog::getSaveFileName(this, tr("Save Radio Backup to File"), g.eepromDir(), tr(EXTERNAL_EEPROM_FILES_FILTER)); QString fileName = QFileDialog::getSaveFileName(this, tr("Save Radio Backup to File"), g.eepromDir(), tr(EXTERNAL_EEPROM_FILES_FILTER));
if (!fileName.isEmpty()) { if (!fileName.isEmpty()) {
if (!readEepromFromRadio(fileName, tr("Read Radio Backup"))) if (!readEepromFromRadio(fileName))
return; return;
} }
} }
@ -1406,13 +849,13 @@ void MainWindow::burnConfig()
void MainWindow::burnList() void MainWindow::burnList()
{ {
burnConfigDialog *bcd = new burnConfigDialog(this); burnConfigDialog bcd(this);
bcd->listProgrammers(); bcd.listAvrdudeProgrammers();
} }
void MainWindow::burnFuses() void MainWindow::burnFuses()
{ {
fusesDialog *fd = new fusesDialog(this); FusesDialog *fd = new FusesDialog(this);
fd->exec(); fd->exec();
delete fd; delete fd;
} }
@ -1451,6 +894,12 @@ void MainWindow::about()
msgBox.exec(); msgBox.exec();
} }
void MainWindow::updateSdsyncAction()
{
QTimer::singleShot(1000, this, SLOT(updateSdsyncAction()));
sdsyncAct->setEnabled(!findMassstoragePath("SOUNDS").isEmpty());
}
void MainWindow::updateMenus() void MainWindow::updateMenus()
{ {
bool hasMdiChild = (activeMdiChild() != 0); bool hasMdiChild = (activeMdiChild() != 0);
@ -1467,13 +916,12 @@ void MainWindow::updateMenus()
printAct->setEnabled(hasSelection); printAct->setEnabled(hasSelection);
loadbackupAct->setEnabled(hasMdiChild); loadbackupAct->setEnabled(hasMdiChild);
compareAct->setEnabled(activeMdiChild()); compareAct->setEnabled(activeMdiChild());
updateSdsyncAction();
updateRecentFileActions(); updateRecentFileActions();
updateProfilesActions(); updateProfilesActions();
updateLanguageActions(); updateLanguageActions();
updateIconSizeActions(); updateIconSizeActions();
updateIconThemeActions(); updateIconThemeActions();
sdsyncAct->setEnabled(!FindMassstoragePath("SOUNDS").isEmpty());
setWindowTitle(tr("OpenTX Companion - FW: %1 - Profile: %2").arg(GetCurrentFirmware()->getName()).arg( g.profile[g.id()].name() )); setWindowTitle(tr("OpenTX Companion - FW: %1 - Profile: %2").arg(GetCurrentFirmware()->getName()).arg( g.profile[g.id()].name() ));
} }
@ -1611,7 +1059,7 @@ void MainWindow::createActions()
writeBackupToRadioAct = addAct("write_eeprom_file.png", tr("Write Backup to Radio"), tr("Write Backup from file to Radio"), SLOT(writeBackup())); writeBackupToRadioAct = addAct("write_eeprom_file.png", tr("Write Backup to Radio"), tr("Write Backup from file to Radio"), SLOT(writeBackup()));
readBackupToFileAct = addAct("read_eeprom_file.png", tr("Backup Radio to File"), tr("Save a complete backup file of all settings and model data in the Radio"), SLOT(readBackup())); readBackupToFileAct = addAct("read_eeprom_file.png", tr("Backup Radio to File"), tr("Save a complete backup file of all settings and model data in the Radio"), SLOT(readBackup()));
contributorsAct = addAct("contributors.png", tr("Contributors..."), tr("A tribute to those who have contributed to OpenTX and Companion"), SLOT(contributors())); contributorsAct = addAct("contributors.png", tr("Contributors..."), tr("A tribute to those who have contributed to OpenTX and Companion"), SLOT(contributors()));
sdsyncAct = addAct("sdsync.png", tr("SD Synchro"), tr("SD card synchronization"), SLOT(sdsync())); sdsyncAct = addAct("sdsync.png", tr("Synchronize SD"), tr("SD card synchronization"), SLOT(sdsync()));
compareAct->setEnabled(false); compareAct->setEnabled(false);
simulateAct->setEnabled(false); simulateAct->setEnabled(false);
@ -1972,85 +1420,6 @@ QString MainWindow::strippedName(const QString &fullFileName)
return QFileInfo(fullFileName).fileName(); return QFileInfo(fullFileName).fileName();
} }
int MainWindow::getEpromVersion(QString fileName)
{
RadioData testData;
if (fileName.isEmpty()) {
return -1;
}
QFile file(fileName);
if (!file.exists()) {
QMessageBox::critical(this, tr("Error"), tr("Unable to find file %1!").arg(fileName));
return -1;
}
int fileType = getFileType(fileName);
#if 0
if (fileType==FILE_TYPE_XML) {
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { //reading HEX TEXT file
QMessageBox::critical(this, tr("Error"),tr("Error opening file %1:\n%2.").arg(fileName).arg(file.errorString()));
return -1;
}
QTextStream inputStream(&file);
XmlInterface(inputStream).load(testData);
}
else
#endif
if (fileType==FILE_TYPE_HEX || fileType==FILE_TYPE_EEPE) { //read HEX file
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { //reading HEX TEXT file
QMessageBox::critical(this, tr("Error"),tr("Error opening file %1:\n%2.").arg(fileName).arg(file.errorString()));
return -1;
}
QDomDocument doc(ER9X_EEPROM_FILE_TYPE);
bool xmlOK = doc.setContent(&file);
if(xmlOK) {
if (!LoadEepromXml(testData, doc)){
return -1;
}
}
file.reset();
QTextStream inputStream(&file);
if (fileType==FILE_TYPE_EEPE) { // read EEPE file header
QString hline = inputStream.readLine();
if (hline!=EEPE_EEPROM_FILE_HEADER) {
file.close();
return -1;
}
}
uint8_t eeprom[EESIZE_RLC_MAX];
int eeprom_size = HexInterface(inputStream).load(eeprom, EESIZE_RLC_MAX);
if (!eeprom_size) {
QMessageBox::critical(this, tr("Error"), tr("Invalid Models and Settings File %1").arg(fileName));
file.close();
return -1;
}
file.close();
if (!LoadEeprom(testData, eeprom, eeprom_size)) {
QMessageBox::critical(this, tr("Error"),tr("Invalid Models and Settings File %1").arg(fileName));
return -1;
}
}
else if (fileType==FILE_TYPE_BIN) { //read binary
int eeprom_size = file.size();
if (!file.open(QFile::ReadOnly)) { //reading binary file - TODO HEX support
QMessageBox::critical(this, tr("Error"),tr("Error opening file %1:\n%2.").arg(fileName).arg(file.errorString()));
return -1;
}
QByteArray eeprom(eeprom_size, 0);
long result = file.read(eeprom.data(), eeprom_size);
file.close();
if (result != eeprom_size) {
QMessageBox::critical(this, tr("Error"),tr("Error reading file %1:\n%2.").arg(fileName).arg(file.errorString()));
return -1;
}
if (!LoadEeprom(testData, (uint8_t *)eeprom.data(), eeprom_size)) {
QMessageBox::critical(this, tr("Error"),tr("Invalid binary Models and Settings File %1").arg(fileName));
return -1;
}
}
return testData.generalSettings.version;
}
void MainWindow::dragEnterEvent(QDragEnterEvent *event) void MainWindow::dragEnterEvent(QDragEnterEvent *event)
{ {
if (event->mimeData()->hasFormat("text/uri-list")) if (event->mimeData()->hasFormat("text/uri-list"))
@ -2085,5 +1454,3 @@ void MainWindow::autoClose()
{ {
this->close(); this->close();
} }

View file

@ -69,7 +69,6 @@ QT_END_NAMESPACE
class MainWindow : public QMainWindow class MainWindow : public QMainWindow
{ {
friend class FirmwarePreferencesDialog; friend class FirmwarePreferencesDialog;
friend class MdiChild; // TODO GetAvrdudeArgs could be external to this class
Q_OBJECT Q_OBJECT
@ -156,6 +155,7 @@ class MainWindow : public QMainWindow
void loadBackup(); void loadBackup();
void appPrefs(); void appPrefs();
void fwPrefs(); void fwPrefs();
void updateSdsyncAction();
void updateMenus(); void updateMenus();
void createProfile(); void createProfile();
MdiChild *createMdiChild(); MdiChild *createMdiChild();
@ -184,30 +184,18 @@ class MainWindow : public QMainWindow
void updateIconThemeActions(); void updateIconThemeActions();
int getFileType(const QString &fullFileName); int getFileType(const QString &fullFileName);
QString FindMassstoragePath(QString filename);
QString Theme; QString Theme;
QString ISize; QString ISize;
QString strippedName(const QString &fullFileName); QString strippedName(const QString &fullFileName);
MdiChild *activeMdiChild(); MdiChild *activeMdiChild();
QMdiSubWindow *findMdiChild(const QString &fileName); QMdiSubWindow *findMdiChild(const QString &fileName);
QString GetAvrdudeLocation();
QStringList GetAvrdudeArguments(const QString &cmd, const QString &filename);
QStringList GetSambaArguments(const QString &tcl);
QStringList GetDFUUtilArguments(const QString &cmd, const QString &filename);
QStringList GetReceiveEEpromCommand(const QString &filename);
QStringList GetSendEEpromCommand(const QString &filename);
QStringList GetReceiveFlashCommand(const QString &filename);
QStringList GetSendFlashCommand(const QString &filename);
int getEpromVersion(QString fileName); int getEpromVersion(QString fileName);
bool convertEEPROM(QString backupFile, QString restoreFile, QString flashFile); bool readEepromFromRadio(const QString &filename);
bool isValidEEPROM(QString eepromfile); bool writeEepromToRadio(const QString &filename);
bool readFirmwareFromRadio(const QString &filename);
bool readEepromFromRadio(const QString filename, const QString message); bool writeFirmwareToRadio(const QString &filename);
bool writeEepromToRadio(const QString filename, const QString message);
bool readFirmwareFromRadio(const QString filename);
bool writeFirmwareToRadio(const QString filename);
QMdiArea *mdiArea; QMdiArea *mdiArea;
QSignalMapper *windowMapper; QSignalMapper *windowMapper;

View file

@ -46,13 +46,13 @@
#include "mainwindow.h" #include "mainwindow.h"
#include "modeledit/modeledit.h" #include "modeledit/modeledit.h"
#include "generaledit/generaledit.h" #include "generaledit/generaledit.h"
#include "avroutputdialog.h"
#include "burnconfigdialog.h" #include "burnconfigdialog.h"
#include "printdialog.h" #include "printdialog.h"
#include "burndialog.h" #include "flasheepromdialog.h"
#include "helpers.h" #include "helpers.h"
#include "appdata.h" #include "appdata.h"
#include "wizarddialog.h" #include "wizarddialog.h"
#include "flashfirmwaredialog.h"
#include <QFileInfo> #include <QFileInfo>
#if defined WIN32 || !defined __GNUC__ #if defined WIN32 || !defined __GNUC__
@ -264,7 +264,7 @@ bool MdiChild::loadFile(const QString &fileName, bool resetCurrentFile)
QDomDocument doc(ER9X_EEPROM_FILE_TYPE); QDomDocument doc(ER9X_EEPROM_FILE_TYPE);
bool xmlOK = doc.setContent(&file); bool xmlOK = doc.setContent(&file);
if(xmlOK) { if(xmlOK) {
if (LoadEepromXml(radioData, doc)){ if (loadEEpromXml(radioData, doc)){
ui->modelsList->refreshList(); ui->modelsList->refreshList();
if(resetCurrentFile) setCurrentFile(fileName); if(resetCurrentFile) setCurrentFile(fileName);
return true; return true;
@ -294,7 +294,7 @@ bool MdiChild::loadFile(const QString &fileName, bool resetCurrentFile)
file.close(); file.close();
if (!LoadEeprom(radioData, eeprom, eeprom_size)) { if (!loadEEprom(radioData, eeprom, eeprom_size)) {
QMessageBox::critical(this, tr("Error"), QMessageBox::critical(this, tr("Error"),
tr("Invalid EEPROM File %1") tr("Invalid EEPROM File %1")
.arg(fileName)); .arg(fileName));
@ -330,7 +330,7 @@ bool MdiChild::loadFile(const QString &fileName, bool resetCurrentFile)
return false; return false;
} }
if (!LoadEeprom(radioData, eeprom, eeprom_size) && !LoadBackup(radioData, eeprom, eeprom_size, 0)) { if (!loadEEprom(radioData, eeprom, eeprom_size) && !::loadBackup(radioData, eeprom, eeprom_size, 0)) {
QMessageBox::critical(this, tr("Error"), QMessageBox::critical(this, tr("Error"),
tr("Invalid binary EEPROM File %1") tr("Invalid binary EEPROM File %1")
.arg(fileName)); .arg(fileName));
@ -516,21 +516,6 @@ QString MdiChild::strippedName(const QString &fullFileName)
void MdiChild::writeEeprom() // write to Tx void MdiChild::writeEeprom() // write to Tx
{ {
bool backupEnable=g.enableBackup();
QString backupPath=g.backupDir();
if (!backupPath.isEmpty()) {
if (!QDir(backupPath).exists()) {
if (backupEnable) {
QMessageBox::warning(this, tr("Backup is impossible"), tr("The backup dir set in preferences does not exist"));
}
backupEnable=false;
}
}
else {
backupEnable=false;
}
QString stickCal=g.profile[g.id()].stickPotCalib();
burnConfigDialog bcd;
QString tempFile = generateProcessUniqueTempFileName("temp.bin"); QString tempFile = generateProcessUniqueTempFileName("temp.bin");
saveFile(tempFile, false); saveFile(tempFile, false);
if(!QFileInfo(tempFile).exists()) { if(!QFileInfo(tempFile).exists()) {
@ -538,51 +523,8 @@ void MdiChild::writeEeprom() // write to Tx
return; return;
} }
bool backup=false; FlashEEpromDialog *cd = new FlashEEpromDialog(this, tempFile);
burnDialog *cd = new burnDialog(this, 1, &tempFile, &backup,strippedName(curFile));
cd->exec(); cd->exec();
if (!tempFile.isEmpty()) {
if (backup) {
if (backupEnable) {
QString backupFile=backupPath+"/backup-"+QDateTime().currentDateTime().toString("yyyy-MM-dd-HHmmss")+".bin";
if (!((MainWindow *)this->parent())->readEepromFromRadio(backupFile, tr("Backup EEPROM From Radio")))
return;
}
int oldrev=((MainWindow *)this->parent())->getEpromVersion(tempFile);
QString tempFlash = generateProcessUniqueTempFileName("flash.bin");
if (!((MainWindow *)this->parent())->readFirmwareFromRadio(tempFlash))
return;
QString restoreFile = generateProcessUniqueTempFileName("compat.bin");
if (!((MainWindow *)this->parent())->convertEEPROM(tempFile, restoreFile, tempFlash)) {
int ret = QMessageBox::question(this, tr("Error"), tr("Cannot check eeprom compatibility! Continue anyway?"), QMessageBox::Yes | QMessageBox::No);
if (ret == QMessageBox::No)
return;
}
else {
int rev=((MainWindow *)this->parent())->getEpromVersion(restoreFile);
if ((rev/100)!=(oldrev/100)) {
QMessageBox::warning(this,tr("Warning"), tr("Firmware in radio is of a different family of eeprom written, check file and preferences!"));
}
if (rev<oldrev) {
QMessageBox::warning(this,tr("Warning"), tr("Firmware in flash is outdated, please upgrade!"));
}
tempFile=restoreFile;
}
qunlink(tempFlash);
}
else {
if (backupEnable) {
QString backupFile=backupPath+"/backup-"+QDateTime().currentDateTime().toString("yyyy-MM-dd-hhmmss")+".bin";
if (!((MainWindow *)this->parent())->readEepromFromRadio(backupFile, tr("Backup EEPROM From Radio")))
return;
}
}
if (!((MainWindow *)this->parent())->writeEepromToRadio(tempFile, tr("Write EEPROM To Radio")))
return;
}
} }
void MdiChild::simulate() void MdiChild::simulate()
@ -654,7 +596,7 @@ bool MdiChild::loadBackup()
return false; return false;
} }
if (!LoadBackup(radioData, (uint8_t *)eeprom.data(), eeprom_size, index)) { if (!::loadBackup(radioData, (uint8_t *)eeprom.data(), eeprom_size, index)) {
QMessageBox::critical(this, tr("Error"), QMessageBox::critical(this, tr("Error"),
tr("Invalid binary backup File %1") tr("Invalid binary backup File %1")
.arg(fileName)); .arg(fileName));

View file

@ -116,7 +116,7 @@ class MdiChild : public QWidget
QString curFile; QString curFile;
FirmwareInterface * firmware; Firmware * firmware;
RadioData radioData; RadioData radioData;
bool isUntitled; bool isUntitled;

View file

@ -7,7 +7,7 @@
#include <QCheckBox> #include <QCheckBox>
#include <QDoubleSpinBox> #include <QDoubleSpinBox>
LimitsGroup::LimitsGroup(FirmwareInterface * firmware, QGridLayout *gridLayout, int row, int col, int & value, int min, int max, int deflt): LimitsGroup::LimitsGroup(Firmware * firmware, QGridLayout *gridLayout, int row, int col, int & value, int min, int max, int deflt):
firmware(firmware), firmware(firmware),
spinbox(new QDoubleSpinBox()), spinbox(new QDoubleSpinBox()),
value(value), value(value),
@ -71,7 +71,7 @@ void LimitsGroup::updateMinMax(int max)
} }
} }
Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, FirmwareInterface * firmware): Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware):
ModelPanel(parent, model, generalSettings, firmware) ModelPanel(parent, model, generalSettings, firmware)
{ {
QGridLayout * gridLayout = new QGridLayout(this); QGridLayout * gridLayout = new QGridLayout(this);

View file

@ -9,13 +9,13 @@ class GVarGroup;
class LimitsGroup class LimitsGroup
{ {
public: public:
LimitsGroup(FirmwareInterface * firmware, QGridLayout *gridLayout, int row, int col, int & value, int min, int max, int deflt); LimitsGroup(Firmware * firmware, QGridLayout *gridLayout, int row, int col, int & value, int min, int max, int deflt);
~LimitsGroup(); ~LimitsGroup();
void updateMinMax(int max); void updateMinMax(int max);
protected: protected:
FirmwareInterface * firmware; Firmware * firmware;
QDoubleSpinBox * spinbox; QDoubleSpinBox * spinbox;
GVarGroup * gvarGroup; GVarGroup * gvarGroup;
int & value; int & value;
@ -27,7 +27,7 @@ class Channels : public ModelPanel
Q_OBJECT Q_OBJECT
public: public:
Channels(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, FirmwareInterface * firmware); Channels(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware);
~Channels(); ~Channels();
private: private:

View file

@ -92,7 +92,7 @@ float curveSymmetricalX(float x, float coeff, float yMin, float yMid, float yMax
return y; return y;
} }
Curves::Curves(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, FirmwareInterface * firmware): Curves::Curves(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware):
ModelPanel(parent, model, generalSettings, firmware), ModelPanel(parent, model, generalSettings, firmware),
ui(new Ui::Curves), ui(new Ui::Curves),
currentCurve(0) currentCurve(0)

View file

@ -22,7 +22,7 @@ class Curves : public ModelPanel
Q_OBJECT Q_OBJECT
public: public:
Curves(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, FirmwareInterface * firmware); Curves(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware);
virtual ~Curves(); virtual ~Curves();
virtual void update(); virtual void update();

View file

@ -47,7 +47,7 @@ void RepeatComboBox::update()
setCurrentIndex(value); setCurrentIndex(value);
} }
CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, GeneralSettings & generalSettings, FirmwareInterface * firmware): CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, GeneralSettings & generalSettings, Firmware * firmware):
GenericPanel(parent, model, generalSettings, firmware), GenericPanel(parent, model, generalSettings, firmware),
functions(model ? model->customFn : generalSettings.customFn), functions(model ? model->customFn : generalSettings.customFn),
initialized(false) initialized(false)

View file

@ -37,7 +37,7 @@ class CustomFunctionsPanel : public GenericPanel
Q_OBJECT Q_OBJECT
public: public:
CustomFunctionsPanel(QWidget *parent, ModelData * mode, GeneralSettings & generalSettings, FirmwareInterface * firmware); CustomFunctionsPanel(QWidget *parent, ModelData * mode, GeneralSettings & generalSettings, Firmware * firmware);
~CustomFunctionsPanel(); ~CustomFunctionsPanel();
virtual void update(); virtual void update();

View file

@ -2,7 +2,7 @@
#include "ui_expodialog.h" #include "ui_expodialog.h"
#include "helpers.h" #include "helpers.h"
ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, GeneralSettings & generalSettings, FirmwareInterface * firmware, char * inputName) : ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, GeneralSettings & generalSettings, Firmware * firmware, char * inputName) :
QDialog(parent), QDialog(parent),
ui(new Ui::ExpoDialog), ui(new Ui::ExpoDialog),
model(model), model(model),

View file

@ -14,7 +14,7 @@ namespace Ui {
class ExpoDialog : public QDialog { class ExpoDialog : public QDialog {
Q_OBJECT Q_OBJECT
public: public:
ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expodata, GeneralSettings & generalSettings, FirmwareInterface * firmware, char * inputName); ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expodata, GeneralSettings & generalSettings, Firmware * firmware, char * inputName);
~ExpoDialog(); ~ExpoDialog();
protected: protected:
@ -28,7 +28,7 @@ class ExpoDialog : public QDialog {
Ui::ExpoDialog * ui; Ui::ExpoDialog * ui;
ModelData & model; ModelData & model;
GeneralSettings & generalSettings; GeneralSettings & generalSettings;
FirmwareInterface * firmware; Firmware * firmware;
ExpoData * ed; ExpoData * ed;
char * inputName; char * inputName;
GVarGroup * gvWeightGroup; GVarGroup * gvWeightGroup;

View file

@ -5,7 +5,7 @@
#include <QComboBox> #include <QComboBox>
#include <QGridLayout> #include <QGridLayout>
FlightModePanel::FlightModePanel(QWidget * parent, ModelData & model, int phaseIdx, GeneralSettings & generalSettings, FirmwareInterface * firmware): FlightModePanel::FlightModePanel(QWidget * parent, ModelData & model, int phaseIdx, GeneralSettings & generalSettings, Firmware * firmware):
ModelPanel(parent, model, generalSettings, firmware), ModelPanel(parent, model, generalSettings, firmware),
ui(new Ui::FlightMode), ui(new Ui::FlightMode),
phaseIdx(phaseIdx), phaseIdx(phaseIdx),
@ -422,7 +422,7 @@ void FlightModePanel::phaseTrimSlider_valueChanged()
/**********************************************************/ /**********************************************************/
FlightModesPanel::FlightModesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, FirmwareInterface * firmware): FlightModesPanel::FlightModesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware):
ModelPanel(parent, model, generalSettings, firmware), ModelPanel(parent, model, generalSettings, firmware),
modesCount(firmware->getCapability(FlightModes)) modesCount(firmware->getCapability(FlightModes))
{ {

View file

@ -19,7 +19,7 @@ class FlightModePanel : public ModelPanel
Q_OBJECT Q_OBJECT
public: public:
FlightModePanel(QWidget *parent, ModelData &model, int modeIdx, GeneralSettings & generalSettings, FirmwareInterface * firmware); FlightModePanel(QWidget *parent, ModelData &model, int modeIdx, GeneralSettings & generalSettings, Firmware * firmware);
virtual ~FlightModePanel(); virtual ~FlightModePanel();
virtual void update(); virtual void update();
@ -66,7 +66,7 @@ class FlightModesPanel : public ModelPanel
Q_OBJECT Q_OBJECT
public: public:
FlightModesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, FirmwareInterface * firmware); FlightModesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware);
virtual ~FlightModesPanel(); virtual ~FlightModesPanel();
virtual void update(); virtual void update();

View file

@ -2,7 +2,7 @@
#include "ui_heli.h" #include "ui_heli.h"
#include "helpers.h" #include "helpers.h"
HeliPanel::HeliPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, FirmwareInterface * firmware): HeliPanel::HeliPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware):
ModelPanel(parent, model, generalSettings, firmware), ModelPanel(parent, model, generalSettings, firmware),
ui(new Ui::Heli) ui(new Ui::Heli)
{ {

View file

@ -12,7 +12,7 @@ class HeliPanel : public ModelPanel
Q_OBJECT Q_OBJECT
public: public:
HeliPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, FirmwareInterface * firmware); HeliPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware);
~HeliPanel(); ~HeliPanel();
void update(); void update();

View file

@ -3,7 +3,7 @@
#include "expodialog.h" #include "expodialog.h"
#include "helpers.h" #include "helpers.h"
InputsPanel::InputsPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, FirmwareInterface * firmware): InputsPanel::InputsPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware):
ModelPanel(parent, model, generalSettings, firmware), ModelPanel(parent, model, generalSettings, firmware),
expoInserted(false) expoInserted(false)
{ {

View file

@ -9,7 +9,7 @@ class InputsPanel : public ModelPanel
Q_OBJECT Q_OBJECT
public: public:
InputsPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, FirmwareInterface * firmware); InputsPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware);
virtual ~InputsPanel(); virtual ~InputsPanel();
virtual void update(); virtual void update();

View file

@ -7,7 +7,7 @@
#include <QDoubleSpinBox> #include <QDoubleSpinBox>
#include "helpers.h" #include "helpers.h"
LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, FirmwareInterface * firmware): LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware):
ModelPanel(parent, model, generalSettings, firmware), ModelPanel(parent, model, generalSettings, firmware),
selectedSwitch(0) selectedSwitch(0)
{ {

View file

@ -12,7 +12,7 @@ class LogicalSwitchesPanel : public ModelPanel
Q_OBJECT Q_OBJECT
public: public:
LogicalSwitchesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, FirmwareInterface * firmware); LogicalSwitchesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware);
virtual ~LogicalSwitchesPanel(); virtual ~LogicalSwitchesPanel();
virtual void update(); virtual void update();

View file

@ -3,7 +3,7 @@
#include "eeprominterface.h" #include "eeprominterface.h"
#include "helpers.h" #include "helpers.h"
MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData *mixdata, GeneralSettings & generalSettings, FirmwareInterface * firmware) : MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData *mixdata, GeneralSettings & generalSettings, Firmware * firmware) :
QDialog(parent), QDialog(parent),
ui(new Ui::MixerDialog), ui(new Ui::MixerDialog),
model(model), model(model),

View file

@ -14,7 +14,7 @@ namespace Ui {
class MixerDialog : public QDialog { class MixerDialog : public QDialog {
Q_OBJECT Q_OBJECT
public: public:
MixerDialog(QWidget *parent, ModelData & model, MixData *mixdata, GeneralSettings & generalSettings, FirmwareInterface * firmware); MixerDialog(QWidget *parent, ModelData & model, MixData *mixdata, GeneralSettings & generalSettings, Firmware * firmware);
~MixerDialog(); ~MixerDialog();
protected: protected:
@ -28,7 +28,7 @@ class MixerDialog : public QDialog {
Ui::MixerDialog *ui; Ui::MixerDialog *ui;
ModelData & model; ModelData & model;
GeneralSettings & generalSettings; GeneralSettings & generalSettings;
FirmwareInterface * firmware; Firmware * firmware;
MixData *md; MixData *md;
bool lock; bool lock;
GVarGroup * gvWeightGroup; GVarGroup * gvWeightGroup;

View file

@ -67,7 +67,7 @@
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt; &lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; } p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt; &lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Delay and Slow&lt;/span&gt;&lt;/p&gt; &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Delay ans Slow&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-weight:600; text-decoration: underline;&quot;&gt;&lt;/p&gt; &lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-weight:600; text-decoration: underline;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;These values control the speed and delay of the output of the mix. &lt;/p&gt; &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;These values control the speed and delay of the output of the mix. &lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt; &lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
@ -96,7 +96,7 @@ p, li { white-space: pre-wrap; }
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt; &lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; } p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt; &lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Delay and Slow&lt;/span&gt;&lt;/p&gt; &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Delay ans Slow&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-weight:600; text-decoration: underline;&quot;&gt;&lt;/p&gt; &lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-weight:600; text-decoration: underline;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;These values control the speed and delay of the output of the mix. &lt;/p&gt; &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;These values control the speed and delay of the output of the mix. &lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt; &lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
@ -125,7 +125,7 @@ p, li { white-space: pre-wrap; }
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt; &lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; } p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt; &lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Delay and Slow&lt;/span&gt;&lt;/p&gt; &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Delay ans Slow&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-weight:600; text-decoration: underline;&quot;&gt;&lt;/p&gt; &lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-weight:600; text-decoration: underline;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;These values control the speed and delay of the output of the mix. &lt;/p&gt; &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;These values control the speed and delay of the output of the mix. &lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt; &lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
@ -148,7 +148,7 @@ p, li { white-space: pre-wrap; }
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt; &lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; } p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt; &lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Delay and Slow&lt;/span&gt;&lt;/p&gt; &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Delay ans Slow&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-weight:600; text-decoration: underline;&quot;&gt;&lt;/p&gt; &lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-weight:600; text-decoration: underline;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;These values control the speed and delay of the output of the mix. &lt;/p&gt; &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;These values control the speed and delay of the output of the mix. &lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt; &lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;

View file

@ -3,7 +3,7 @@
// #include <QMessageBox> // #include <QMessageBox>
// #include "expodialog.h" // #include "expodialog.h"
MixesPanel::MixesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, FirmwareInterface * firmware): MixesPanel::MixesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware):
ModelPanel(parent, model, generalSettings, firmware), ModelPanel(parent, model, generalSettings, firmware),
mixInserted(false), mixInserted(false),
highlightedSource(0) highlightedSource(0)

View file

@ -10,7 +10,7 @@ class MixesPanel : public ModelPanel
Q_OBJECT Q_OBJECT
public: public:
MixesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, FirmwareInterface * firmware); MixesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware);
virtual ~MixesPanel(); virtual ~MixesPanel();
virtual void update(); virtual void update();

View file

@ -15,7 +15,7 @@
#include "appdata.h" #include "appdata.h"
#include <QScrollArea> #include <QScrollArea>
ModelEdit::ModelEdit(QWidget * parent, RadioData & radioData, int modelId, FirmwareInterface * firmware) : ModelEdit::ModelEdit(QWidget * parent, RadioData & radioData, int modelId, Firmware * firmware) :
QDialog(parent), QDialog(parent),
ui(new Ui::ModelEdit), ui(new Ui::ModelEdit),
modelId(modelId), modelId(modelId),

View file

@ -13,7 +13,7 @@ namespace Ui {
class ModelPanel : public GenericPanel class ModelPanel : public GenericPanel
{ {
public: public:
ModelPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, FirmwareInterface * firmware): ModelPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware):
GenericPanel(parent, &model, generalSettings, firmware) GenericPanel(parent, &model, generalSettings, firmware)
{ {
} }
@ -24,7 +24,7 @@ class ModelEdit : public QDialog
Q_OBJECT Q_OBJECT
public: public:
ModelEdit(QWidget * parent, RadioData & radioData, int modelId, FirmwareInterface * firmware); ModelEdit(QWidget * parent, RadioData & radioData, int modelId, Firmware * firmware);
~ModelEdit(); ~ModelEdit();
protected: protected:
@ -43,7 +43,7 @@ class ModelEdit : public QDialog
int modelId; int modelId;
ModelData & model; ModelData & model;
GeneralSettings & generalSettings; GeneralSettings & generalSettings;
FirmwareInterface * firmware; Firmware * firmware;
QVector<GenericPanel *> panels; QVector<GenericPanel *> panels;
void addTab(GenericPanel *panel, QString text); void addTab(GenericPanel *panel, QString text);

View file

@ -5,7 +5,7 @@
#include "helpers.h" #include "helpers.h"
#include "appdata.h" #include "appdata.h"
TimerPanel::TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, FirmwareInterface * firmware, QWidget *prevFocus): TimerPanel::TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware, QWidget *prevFocus):
ModelPanel(parent, model, generalSettings, firmware), ModelPanel(parent, model, generalSettings, firmware),
timer(timer), timer(timer),
ui(new Ui::Timer) ui(new Ui::Timer)
@ -119,7 +119,7 @@ void TimerPanel::on_name_editingFinished()
/******************************************************************************/ /******************************************************************************/
ModulePanel::ModulePanel(QWidget *parent, ModelData & model, ModuleData & module, GeneralSettings & generalSettings, FirmwareInterface * firmware, int moduleIdx): ModulePanel::ModulePanel(QWidget *parent, ModelData & model, ModuleData & module, GeneralSettings & generalSettings, Firmware * firmware, int moduleIdx):
ModelPanel(parent, model, generalSettings, firmware), ModelPanel(parent, model, generalSettings, firmware),
module(module), module(module),
moduleIdx(moduleIdx), moduleIdx(moduleIdx),
@ -365,7 +365,7 @@ void ModulePanel::onFailsafeSpinChanged(double value)
/******************************************************************************/ /******************************************************************************/
SetupPanel::SetupPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, FirmwareInterface * firmware): SetupPanel::SetupPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware):
ModelPanel(parent, model, generalSettings, firmware), ModelPanel(parent, model, generalSettings, firmware),
ui(new Ui::Setup) ui(new Ui::Setup)
{ {
@ -715,8 +715,6 @@ void SetupPanel::updateStartupSwitches()
unsigned int switchStates = model->switchWarningStates; unsigned int switchStates = model->switchWarningStates;
for (int i=0; i<firmware->getCapability(Switches); i++) { for (int i=0; i<firmware->getCapability(Switches); i++) {
if (!IS_TARANIS(firmware->getBoard()) && i==firmware->getCapability(Switches)-1)
continue;
QSlider * slider = startupSwitchesSliders[i]; QSlider * slider = startupSwitchesSliders[i];
QCheckBox * cb = startupSwitchesCheckboxes[i]; QCheckBox * cb = startupSwitchesCheckboxes[i];
bool enabled = !(model->switchWarningEnable & (1 << i)); bool enabled = !(model->switchWarningEnable & (1 << i));
@ -727,6 +725,10 @@ void SetupPanel::updateStartupSwitches()
switchStates >>= 2; switchStates >>= 2;
} }
else { else {
if (i == firmware->getCapability(Switches)-1) {
// Trainer switch, no switch warning
continue;
}
slider->setValue(i==0 ? switchStates & 0x3 : switchStates & 0x1); slider->setValue(i==0 ? switchStates & 0x3 : switchStates & 0x1);
switchStates >>= (i==0 ? 2 : 1); switchStates >>= (i==0 ? 2 : 1);
} }

View file

@ -21,7 +21,7 @@ class TimerPanel : public ModelPanel
Q_OBJECT Q_OBJECT
public: public:
TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, FirmwareInterface * firmware, QWidget *prevFocus); TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware, QWidget *prevFocus);
virtual ~TimerPanel(); virtual ~TimerPanel();
virtual void update(); virtual void update();
@ -43,7 +43,7 @@ class ModulePanel : public ModelPanel
Q_OBJECT Q_OBJECT
public: public:
ModulePanel(QWidget *parent, ModelData & model, ModuleData & module, GeneralSettings & generalSettings, FirmwareInterface * firmware, int moduleIdx); ModulePanel(QWidget *parent, ModelData & model, ModuleData & module, GeneralSettings & generalSettings, Firmware * firmware, int moduleIdx);
virtual ~ModulePanel(); virtual ~ModulePanel();
virtual void update(); virtual void update();
@ -72,7 +72,7 @@ class SetupPanel : public ModelPanel
Q_OBJECT Q_OBJECT
public: public:
SetupPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, FirmwareInterface * firmware); SetupPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware);
virtual ~SetupPanel(); virtual ~SetupPanel();
virtual void update(); virtual void update();

View file

@ -6,7 +6,7 @@
#include "helpers.h" #include "helpers.h"
#include "appdata.h" #include "appdata.h"
TelemetryAnalog::TelemetryAnalog(QWidget *parent, FrSkyChannelData & analog, ModelData & model, GeneralSettings & generalSettings, FirmwareInterface * firmware): TelemetryAnalog::TelemetryAnalog(QWidget *parent, FrSkyChannelData & analog, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware):
ModelPanel(parent, model, generalSettings, firmware), ModelPanel(parent, model, generalSettings, firmware),
ui(new Ui::TelemetryAnalog), ui(new Ui::TelemetryAnalog),
analog(analog), analog(analog),
@ -287,7 +287,7 @@ TelemetryAnalog::~TelemetryAnalog()
/******************************************************/ /******************************************************/
TelemetryCustomScreen::TelemetryCustomScreen(QWidget *parent, ModelData & model, FrSkyScreenData & screen, GeneralSettings & generalSettings, FirmwareInterface * firmware): TelemetryCustomScreen::TelemetryCustomScreen(QWidget *parent, ModelData & model, FrSkyScreenData & screen, GeneralSettings & generalSettings, Firmware * firmware):
ModelPanel(parent, model, generalSettings, firmware), ModelPanel(parent, model, generalSettings, firmware),
ui(new Ui::TelemetryCustomScreen), ui(new Ui::TelemetryCustomScreen),
screen(screen) screen(screen)
@ -475,7 +475,7 @@ void TelemetryCustomScreen::barMaxChanged(double value)
} }
} }
TelemetrySensorPanel::TelemetrySensorPanel(QWidget *parent, SensorData & sensor, ModelData & model, GeneralSettings & generalSettings, FirmwareInterface * firmware): TelemetrySensorPanel::TelemetrySensorPanel(QWidget *parent, SensorData & sensor, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware):
ModelPanel(parent, model, generalSettings, firmware), ModelPanel(parent, model, generalSettings, firmware),
ui(new Ui::TelemetrySensor), ui(new Ui::TelemetrySensor),
sensor(sensor), sensor(sensor),
@ -653,7 +653,7 @@ void TelemetrySensorPanel::on_prec_editingFinished()
/******************************************************/ /******************************************************/
TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, FirmwareInterface * firmware): TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware):
ModelPanel(parent, model, generalSettings, firmware), ModelPanel(parent, model, generalSettings, firmware),
ui(new Ui::Telemetry) ui(new Ui::Telemetry)
{ {

View file

@ -23,7 +23,7 @@ class TelemetryAnalog: public ModelPanel
friend class TelemetryPanel; friend class TelemetryPanel;
public: public:
TelemetryAnalog(QWidget *parent, FrSkyChannelData & analog, ModelData & model, GeneralSettings & generalSettings, FirmwareInterface * firmware); TelemetryAnalog(QWidget *parent, FrSkyChannelData & analog, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware);
virtual ~TelemetryAnalog(); virtual ~TelemetryAnalog();
signals: signals:
@ -54,7 +54,7 @@ class TelemetryCustomScreen: public ModelPanel
Q_OBJECT Q_OBJECT
public: public:
TelemetryCustomScreen(QWidget *parent, ModelData & model, FrSkyScreenData & screen, GeneralSettings & generalSettings, FirmwareInterface * firmware); TelemetryCustomScreen(QWidget *parent, ModelData & model, FrSkyScreenData & screen, GeneralSettings & generalSettings, Firmware * firmware);
~TelemetryCustomScreen(); ~TelemetryCustomScreen();
void update(); void update();
@ -83,7 +83,7 @@ class TelemetrySensorPanel: public ModelPanel
Q_OBJECT Q_OBJECT
public: public:
TelemetrySensorPanel(QWidget *parent, SensorData & sensor, ModelData & model, GeneralSettings & generalSettings, FirmwareInterface * firmware); TelemetrySensorPanel(QWidget *parent, SensorData & sensor, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware);
~TelemetrySensorPanel(); ~TelemetrySensorPanel();
void update(); void update();
@ -111,7 +111,7 @@ class TelemetryPanel : public ModelPanel
Q_OBJECT Q_OBJECT
public: public:
TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, FirmwareInterface * firmware); TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware);
virtual ~TelemetryPanel(); virtual ~TelemetryPanel();
virtual void update(); virtual void update();

View file

@ -1,6 +1,7 @@
#include "printdialog.h" #include "printdialog.h"
#include "ui_printdialog.h" #include "ui_printdialog.h"
#include "helpers.h" #include "helpers.h"
#include "helpers_html.h"
#include "eeprominterface.h" #include "eeprominterface.h"
#include <QtGui> #include <QtGui>
#include <QImage> #include <QImage>
@ -14,7 +15,7 @@
#define ISIZE 200 // curve image size #define ISIZE 200 // curve image size
#define ISIZEW 400 // curve image size #define ISIZEW 400 // curve image size
PrintDialog::PrintDialog(QWidget *parent, FirmwareInterface * firmware, GeneralSettings *gg, ModelData *gm, QString filename) : PrintDialog::PrintDialog(QWidget *parent, Firmware * firmware, GeneralSettings *gg, ModelData *gm, QString filename) :
QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint), QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
firmware(firmware), firmware(firmware),
g_eeGeneral(gg), g_eeGeneral(gg),
@ -24,7 +25,7 @@ PrintDialog::PrintDialog(QWidget *parent, FirmwareInterface * firmware, GeneralS
gvars(firmware->getCapability(Gvars)) gvars(firmware->getCapability(Gvars))
{ {
ui->setupUi(this); ui->setupUi(this);
this->setWindowIcon(CompanionIcon("print.png")); setWindowIcon(CompanionIcon("print.png"));
te = ui->textEdit; te = ui->textEdit;
setWindowTitle(tr("Setup for: ") + g_model->name); setWindowTitle(tr("Setup for: ") + g_model->name);
@ -70,35 +71,6 @@ PrintDialog::~PrintDialog()
delete ui; delete ui;
} }
QString doTC(const QString s, const QString color="", bool bold=false)
{
QString str = s;
if(bold) str = "<b>" + str + "</b>";
if(!color.isEmpty()) str = "<font color=" + color + ">" + str + "</font>";
return "<td align=center>" + str + "</td>";
}
QString doTR(const QString s, const QString color="", bool bold=false)
{
QString str = s;
if(bold) str = "<b>" + str + "</b>";
if(!color.isEmpty()) str = "<font color=" + color + ">" + str + "</font>";
return "<td align=right>" + str + "</td>";
}
QString doTL(const QString s, const QString color="", bool bold=false)
{
QString str = s;
if(bold) str = "<b>" + str + "</b>";
if(!color.isEmpty()) str = "<font color=" + color + ">" + str + "</font>";
return "<td align=left>" + str + "</td>";
}
QString PrintDialog::fv(const QString name, const QString value)
{
return "<b>" + name + ": </b><font color=green>" + value + "</font><br>";
}
void PrintDialog::printSetup() void PrintDialog::printSetup()
{ {
QString str = "<a name=1></a><table border=1 cellspacing=0 cellpadding=3 width=\"100%\">"; QString str = "<a name=1></a><table border=1 cellspacing=0 cellpadding=3 width=\"100%\">";

View file

@ -15,12 +15,12 @@ class PrintDialog : public QDialog
Q_OBJECT Q_OBJECT
public: public:
explicit PrintDialog(QWidget *parent, FirmwareInterface * firmware, GeneralSettings *gg, ModelData *gm, QString filename=""); explicit PrintDialog(QWidget *parent, Firmware * firmware, GeneralSettings *gg, ModelData *gm, QString filename="");
~PrintDialog(); ~PrintDialog();
void closeEvent(QCloseEvent *event); void closeEvent(QCloseEvent *event);
FirmwareInterface * firmware; Firmware * firmware;
GeneralSettings * g_eeGeneral; GeneralSettings * g_eeGeneral;
ModelData * g_model; ModelData * g_model;
@ -43,8 +43,6 @@ private:
void printFrSky(); void printFrSky();
void printToFile(); void printToFile();
QString fv(const QString name, const QString value);
QTextEdit * te; QTextEdit * te;
QString curvefile5; QString curvefile5;
QString curvefile9; QString curvefile9;

71
companion/src/process_copy.cpp Executable file
View file

@ -0,0 +1,71 @@
#include "process_copy.h"
#include "progresswidget.h"
#include <QEventLoop>
#include <QFile>
#include <QMessageBox>
#include <QTimer>
#define BLKSIZE 512
CopyProcess::CopyProcess(const QString &source, const QString &destination, ProgressWidget *progress):
progress(progress),
source(source),
destination(destination),
result(true)
{
}
bool CopyProcess::run()
{
progress->lock(true);
progress->setInfo(tr("Copying file..."));
QEventLoop loop;
connect(this, SIGNAL(finished()), &loop, SLOT(quit()));
QTimer::singleShot(500, this, SLOT(onTimer()));
loop.exec();
return result;
}
void CopyProcess::onTimer()
{
char buf[BLKSIZE];
QFile sourceFile(source);
int blocks = (sourceFile.size() + BLKSIZE - 1) / BLKSIZE;
progress->setMaximum(blocks-1);
if (sourceFile.open(QIODevice::ReadOnly)) {
QFile destinationFile(destination);
if (destinationFile.open(QIODevice::WriteOnly)) {
progress->addText(tr("Writing file: "));
for (int i=0; i<blocks; i++) {
int read = sourceFile.read(buf, BLKSIZE);
if (destinationFile.write(buf, read) == read) {
destinationFile.flush();
progress->setValue(i);
}
else {
QMessageBox::warning(NULL, tr("Error"), tr("Write error"));
result = false;
break;
}
}
destinationFile.close();
}
else {
QMessageBox::warning(NULL, tr("Error"),tr("Cannot write %1 (reason: %2)").arg(destinationFile.fileName()).arg(sourceFile.errorString()));
result = false;
}
}
else {
QMessageBox::warning(NULL, tr("Error"),tr("Cannot open %1 (reason: %2)").arg(sourceFile.fileName()).arg(sourceFile.errorString()));
result = false;
}
sourceFile.close();
progress->lock(false);
emit finished();
}

31
companion/src/process_copy.h Executable file
View file

@ -0,0 +1,31 @@
#ifndef COPYPROCESS_H_
#define COPYPROCESS_H_
#include <QObject>
#include <QString>
#include <QStringList>
class ProgressWidget;
class CopyProcess : public QObject
{
Q_OBJECT
public:
CopyProcess(const QString &source, const QString &destination, ProgressWidget *progress);
bool run();
signals:
void finished();
protected slots:
void onTimer();
protected:
ProgressWidget *progress;
const QString source;
const QString destination;
bool result;
};
#endif // COPYPROCESS_H_

295
companion/src/process_flash.cpp Executable file
View file

@ -0,0 +1,295 @@
#include "process_flash.h"
#include "progresswidget.h"
#include <QFile>
#include <QMessageBox>
#include <QProcess>
#include "eeprominterface.h"
//#include "firmwareinterface.h"
#if defined WIN32 || !defined __GNUC__
#include <Windows.h>
#include <WinBase.h>
#include <tlhelp32.h>
#define sleep(x) Sleep(x*1000)
#else
#include <unistd.h>
#include "mountlist.h"
#endif
FlashProcess::FlashProcess(const QString &cmd, const QStringList &args, ProgressWidget *progress):
progress(progress),
cmd(cmd),
args(args),
process(new QProcess(this)),
hasErrors(false),
lfuse(0),
hfuse(0),
efuse(0),
flashPhase(READING)
#if !__GNUC__
, killTimer(NULL)
#endif
{
connect(process, SIGNAL(started()),this, SLOT(onStarted()));
connect(process, SIGNAL(readyReadStandardOutput()), this, SLOT(onReadyReadStandardOutput()));
connect(process, SIGNAL(readyReadStandardError()), this, SLOT(onReadyReadStandardError()));
connect(process, SIGNAL(finished(int)), this, SLOT(onFinished(int)));
}
FlashProcess::~FlashProcess()
{
#if !__GNUC__
delete killTimer;
#endif
}
bool FlashProcess::run()
{
if (!QFile::exists(cmd)) {
QMessageBox::critical(NULL, "Companion", tr("Executable %1 not found").arg(cmd));
return false;
}
#if !__GNUC__
if (cmd.toLower().contains("sam-ba")) {
killTimer = new QTimer(this);
connect(killTimer, SIGNAL(timeout()), this, SLOT(onKillTimerElapsed()));
killTimer->start(2000);
}
#endif
QEventLoop loop;
connect(this, SIGNAL(finished()), &loop, SLOT(quit()));
process->start(cmd, args);
loop.exec();
return true;
}
void FlashProcess::onStarted()
{
progress->lock(true);
progress->addText(cmd + " " + args.join(" "));
progress->addSeparator();
}
# if !__GNUC__
bool KillProcessByName(const char *szProcessToKill)
{
HANDLE hProcessSnap;
HANDLE hProcess;
PROCESSENTRY32 pe32;
DWORD dwPriorityClass;
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); // Takes a snapshot of all the processes
if (hProcessSnap == INVALID_HANDLE_VALUE) {
return false;
}
pe32.dwSize = sizeof(PROCESSENTRY32);
if (!Process32First(hProcessSnap, &pe32)) {
CloseHandle(hProcessSnap);
return false;
}
do {
if (!strcmp(pe32.szExeFile,szProcessToKill)) { // checks if process at current position has the name of to be killed app
hProcess = OpenProcess(PROCESS_TERMINATE,0, pe32.th32ProcessID); // gets handle to process
TerminateProcess(hProcess, 0); // Terminate process by handle
CloseHandle(hProcess); // close the handle
}
} while (Process32Next(hProcessSnap, &pe32)); // gets next member of snapshot
CloseHandle(hProcessSnap); // closes the snapshot handle
return true;
}
#endif
# if !__GNUC__
void FlashProcess::onKillTimerElapsed()
{
// trick to accelerate SAM-BA startup
KillProcessByName("tasklist.exe");
}
#endif
void FlashProcess::analyseStandardOutput(const QString &text)
{
currStdoutLine.append(text);
if (currStdoutLine.contains("size = ")) {
int pos = currStdoutLine.lastIndexOf("size = ");
QString temp = currStdoutLine.mid(pos+7);
pos = temp.lastIndexOf("\n");
int size = temp.left(pos).toInt();
progress->setMaximum(size/2048);
}
if (currStdoutLine.contains("\n")) {
int nlPos = currStdoutLine.lastIndexOf("\n");
currStdoutLine = currStdoutLine.mid(nlPos+1);
}
if (!currStdoutLine.isEmpty()) {
if (currStdoutLine.at(0) == QChar('.')) {
int pos = currStdoutLine.lastIndexOf(".");
progress->setValue(pos);
}
else if (currStdoutLine.startsWith("Starting upload: [")) {
int pos = (currStdoutLine.lastIndexOf("#")-19)*100/256;
progress->setValue(pos);
}
}
if (text.contains("Complete ")) {
#if !__GNUC__
delete killTimer;
killTimer = NULL;
#endif
int start = text.indexOf("Complete ");
int end = text.indexOf("%");
if (start > 0) {
start += 9;
int value = text.mid(start, end-start).toInt();
progress->setValue(value);
}
}
if (text.contains(":010000")) {
// contains fuse info
QStringList stl = text.split(":01000000");
foreach (QString t, stl) {
bool ok = false;
if (!lfuse) lfuse = t.left(2).toInt(&ok, 16);
if (!hfuse && !ok) hfuse = t.left(2).toInt(&ok, 16);
if (!efuse && !ok) efuse = t.left(2).toInt(&ok, 16);
}
}
if (text.contains("-E-")) {
hasErrors = true;
}
}
void FlashProcess::analyseStandardError(const QString &text)
{
currStderrLine.append(text);
if (currStderrLine.contains("#")) {
QString avrflashPhase = currStderrLine.left(1).toLower();
if (avrflashPhase == "w") {
flashPhase = WRITING;
progress->setInfo(tr("Writing..."));
progress->setValue(2 * currStderrLine.count("#"));
}
else if (avrflashPhase == "r") {
if (flashPhase == READING) {
progress->setInfo(tr("Reading..."));
}
else {
flashPhase = VERIFYING;
progress->setInfo(tr("Verifying..."));
}
progress->setValue(2 * currStderrLine.count("#"));
}
}
if (currStderrLine.contains("\n")) {
int nlPos = currStderrLine.lastIndexOf("\n");
currStderrLine = currStderrLine.mid(nlPos+1);
}
if (text.contains("-E-") && !text.contains("-E- No receive file name")) {
hasErrors = true;
}
}
void FlashProcess::onReadyReadStandardOutput()
{
QString text = QString(process->readAllStandardOutput());
progress->addText(text);
analyseStandardOutput(text);
}
void FlashProcess::onReadyReadStandardError()
{
QString text = QString(process->readAllStandardError());
progress->addText(text);
analyseStandardError(text);
}
void FlashProcess::errorWizard()
{
QString output; // TODO = ui->plainTextEdit->toPlainText();
if (output.contains("avrdude: Expected signature for")) { // wrong signature
int pos=output.indexOf("avrdude: Device signature = ");
bool fwexist=false;
QString DeviceStr="Unknown";
QString FwStr="";
if (pos>0) {
QString DeviceId=output.mid(pos+28,8);
if (DeviceId=="0x1e9602") {
DeviceStr="Atmega 64";
FwStr="\n"+tr("ie: OpenTX for 9X board or OpenTX for 9XR board");
fwexist=true;
}
else if (DeviceId=="0x1e9702") {
DeviceStr="Atmega 128";
FwStr="\n"+tr("ie: OpenTX for M128 / 9X board or OpenTX for 9XR board with M128 chip");
fwexist=true;
}
else if (DeviceId=="0x1e9703") {
DeviceStr="Atmega 1280";
}
else if (DeviceId=="0x1e9704") {
DeviceStr="Atmega 1281";
}
else if (DeviceId=="0x1e9801") {
DeviceStr="Atmega 2560";
FwStr="\n"+tr("ie: OpenTX for Gruvin9X board");
fwexist = true;
}
else if (DeviceId=="0x1e9802") {
DeviceStr="Atmega 2561";
}
}
if (fwexist==false) {
QMessageBox::warning(NULL, "Companion - Tip of the day", tr("Your radio uses a %1 CPU!!!\n\nPlease check advanced burn options to set the correct cpu type.").arg(DeviceStr));
}
else {
Firmware *firmware = GetCurrentFirmware();
QMessageBox::warning(NULL, "Companion - Tip of the day", tr("Your radio uses a %1 CPU!!!\n\nPlease select an appropriate firmware type to program it.").arg(DeviceStr)+FwStr+tr("\nYou are currently using:\n %1").arg(firmware->getName()));
}
}
}
void FlashProcess::onFinished(int code=0)
{
progress->addSeparator();
if (code==1 && cmd.toLower().contains("sam-ba")) {
code = 0;
}
if (code) {
progress->setInfo(tr("Flashing done (exit code = %1)").arg(code));
if (cmd.toLower().contains("avrdude")) {
errorWizard();
}
}
else if (hasErrors)
progress->setInfo(tr("Flashing done with errors"));
else
progress->setInfo(tr("Flashing done"));
progress->addSeparator();
if(lfuse || hfuse || efuse) {
addReadFuses();
}
progress->lock(false);
emit finished();
}
void FlashProcess::addReadFuses()
{
progress->addSeparator();
progress->addText(tr("FUSES: Low=%1 High=%2 Ext=%3").arg(lfuse,2,16,QChar('0')).arg(hfuse,2,16,QChar('0')).arg(efuse,2,16,QChar('0')));
progress->addSeparator();
}

48
companion/src/process_flash.h Executable file
View file

@ -0,0 +1,48 @@
#ifndef FLASHPROCESS_H_
#define FLASHPROCESS_H_
#include <QObject>
#include <QString>
#include <QStringList>
class ProgressWidget;
class QProcess;
class FlashProcess : public QObject
{
Q_OBJECT
public:
FlashProcess(const QString &cmd, const QStringList &args, ProgressWidget *progress);
~FlashProcess();
bool run();
signals:
void finished();
protected slots:
void onStarted();
void onReadyReadStandardOutput();
void onReadyReadStandardError();
void onFinished(int);
protected:
void analyseStandardOutput(const QString &text);
void analyseStandardError(const QString &text);
void errorWizard();
void addReadFuses();
ProgressWidget *progress;
const QString cmd;
const QStringList args;
QProcess *process;
bool hasErrors;
QString currStdoutLine;
QString currStderrLine;
unsigned int lfuse;
unsigned int hfuse;
unsigned int efuse;
enum FlashPhase { READING, WRITING, VERIFYING };
FlashPhase flashPhase;
};
#endif // FLASHPROCESS_H_

123
companion/src/process_sync.cpp Executable file
View file

@ -0,0 +1,123 @@
#include "process_sync.h"
#include "progresswidget.h"
#include <QDirIterator>
#include <QDateTime>
#include <QMessageBox>
#include <QTextStream>
#include <QDebug>
SyncProcess::SyncProcess(const QString &folder1, const QString &folder2, ProgressWidget *progress):
folder1(folder1),
folder2(folder2),
progress(progress),
simulation(false),
index(0)
{
}
void SyncProcess::run()
{
simulation = true;
index = 0;
if (synchronize()) {
int count = index;
progress->setMaximum(count);
simulation = false;
index = 0;
synchronize();
progress->setValue(count);
}
}
bool SyncProcess::synchronize()
{
if (!QFile::exists(folder1)) {
QMessageBox::warning(NULL, QObject::tr("Synchronization error"), QObject::tr("The directory '%1' doesn't exist!").arg(folder1));
return false;
}
if (!QFile::exists(folder2)) {
QMessageBox::warning(NULL, QObject::tr("Synchronization error"), QObject::tr("The directory '%1' doesn't exist!").arg(folder2));
return false;
}
QStringList errors = updateDir(folder1, folder2) + updateDir(folder2, folder1);
if (errors.count() > 0) {
QMessageBox::warning(NULL, QObject::tr("Synchronization error"), errors.join("\n"));
return false;
}
return true;
}
QStringList SyncProcess::updateDir(const QDir &source, const QDir &destination)
{
QDirIterator it(source, QDirIterator::Subdirectories);
while (it.hasNext()) {
if (!simulation) {
progress->setValue(index);
}
QString path = it.next();
// qDebug() << path;
QFileInfo sourceInfo(path);
QString relativePath = source.relativeFilePath(path);
QString destinationPath = destination.absoluteFilePath(relativePath);
QFileInfo destinationInfo(destinationPath);
if (sourceInfo.isDir()) {
if (!destinationInfo.exists()) {
++index;
if (!simulation) {
progress->addText(tr("Create directory %1\n").arg(destinationPath));
if (!destination.mkdir(relativePath)) {
errors << QObject::tr("Create '%1' failed").arg(destinationPath);
continue;
}
}
}
}
else {
if (!destinationInfo.exists()) {
// qDebug() << "Copy" << path << "to" << destinationPath;
++index;
if (!simulation) {
progress->addText(tr("Copy %1 to %2\n").arg(path).arg(destinationPath));
if (!QFile::copy(path, destinationPath)) {
errors << QObject::tr("Copy '%1' to '%2' failed").arg(path).arg(destinationPath);
continue;
}
}
}
else if (sourceInfo.lastModified() > destinationInfo.lastModified()) {
++index;
if (!simulation) {
progress->addText(tr("Read %1\n").arg(path));
// retrieve source contents
QFile sourceFile(path);
if (!sourceFile.open(QFile::ReadOnly)) {
errors << QObject::tr("Open '%1' failed").arg(path);
continue;
}
QString sourceContents = sourceFile.readAll();
sourceFile.close();
// try to retrieve destination contents
QFile destinationFile(path);
if (destinationFile.open(QFile::ReadOnly)) {
QString destinationContents = destinationFile.readAll();
destinationFile.close();
if (sourceContents == destinationContents) {
// qDebug() << "Skip" << path;
continue;
}
}
if (!destinationFile.open(QFile::WriteOnly)) {
errors << QObject::tr("Write '%1' failed").arg(destinationPath);
continue;
}
progress->addText(tr("Write %1\n").arg(destinationPath));
// qDebug() << "Write" << destinationPath;
QTextStream destinationStream(&destinationFile);
destinationStream << sourceContents;
destinationFile.close();
}
}
}
}
return errors;
}

30
companion/src/process_sync.h Executable file
View file

@ -0,0 +1,30 @@
#ifndef SYNCPROCESS_H_
#define SYNCPROCESS_H_
#include <QObject>
#include <QString>
#include <QStringList>
class QDir;
class ProgressWidget;
class SyncProcess : public QObject
{
Q_OBJECT
public:
SyncProcess(const QString &folder1, const QString &folder2, ProgressWidget *progress);
void run();
protected:
bool synchronize();
QStringList updateDir(const QDir &source, const QDir &destination);
QString folder1;
QString folder2;
ProgressWidget *progress;
QStringList errors;
bool simulation;
int index;
};
#endif /* SYNCPROCESS_H_ */

View file

@ -0,0 +1,52 @@
#include "progressdialog.h"
#include "ui_progressdialog.h"
#include "appdata.h"
#include <QTimer>
ProgressDialog::ProgressDialog(QWidget *parent, const QString &title, const QIcon &icon, bool forceOpen):
QDialog(parent),
ui(new Ui::ProgressDialog),
locked(false)
{
ui->setupUi(this);
setWindowTitle(title);
setWindowIcon(icon);
if (forceOpen) {
ui->outputProgress->forceOpen();
}
resize(0, 0);
show();
}
ProgressDialog::~ProgressDialog()
{
delete ui;
}
ProgressWidget *ProgressDialog::progress()
{
return ui->outputProgress;
}
void ProgressDialog::on_closeButton_clicked()
{
if (!locked) {
close();
}
}
void ProgressDialog::on_outputProgress_detailsToggled()
{
QTimer::singleShot(0, this, SLOT(shrink()));
}
void ProgressDialog::on_outputProgress_locked(bool lock)
{
ui->closeButton->setEnabled(!lock);
locked = lock;
}
void ProgressDialog::shrink()
{
resize(0, 0);
}

34
companion/src/progressdialog.h Executable file
View file

@ -0,0 +1,34 @@
#ifndef PROGRESS_DIALOG_H_
#define PROGRESS_DIALOG_H_
#include <QDialog>
namespace Ui
{
class ProgressDialog;
}
class ProgressWidget;
class ProgressDialog : public QDialog
{
Q_OBJECT
public:
ProgressDialog(QWidget *parent, const QString &label, const QIcon &icon, bool forceOpen=false);
~ProgressDialog();
ProgressWidget *progress();
private slots:
void on_closeButton_clicked();
void on_outputProgress_detailsToggled();
void on_outputProgress_locked(bool);
void shrink();
private:
Ui::ProgressDialog *ui;
bool locked;
};
#endif // PROGRESS_DIALOG_H_

99
companion/src/progressdialog.ui Executable file
View file

@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ProgressDialog</class>
<widget class="QDialog" name="ProgressDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>431</width>
<height>115</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="windowTitle">
<string>Flash Firmware</string>
</property>
<property name="windowIcon">
<iconset resource="companion.qrc">
<normaloff>:/icon.png</normaloff>:/icon.png</iconset>
</property>
<property name="modal">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="ProgressWidget" name="outputProgress" native="true"/>
</item>
<item>
<spacer name="spacer2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="spacer1">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="closeButton">
<property name="minimumSize">
<size>
<width>90</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Close</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>ProgressWidget</class>
<extends>QWidget</extends>
<header>progresswidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>closeButton</tabstop>
</tabstops>
<resources>
<include location="companion.qrc"/>
</resources>
<connections/>
</ui>

101
companion/src/progresswidget.cpp Executable file
View file

@ -0,0 +1,101 @@
#include "progresswidget.h"
#include "ui_progresswidget.h"
#include "appdata.h"
#include <QDebug>
#include <QTimer>
#include <QScrollBar>
ProgressWidget::ProgressWidget(QWidget *parent):
QWidget(parent),
ui(new Ui::ProgressWidget)
{
ui->setupUi(this);
ui->info->hide();
#ifdef __APPLE__
QFont newFont("Courier", 13);
ui->textEdit->setFont(newFont);
ui->textEdit->setAttribute(Qt::WA_MacNormalSize);
#elif defined WIN32 || !defined __GNUC__
QFont newFont("Courier", 9);
ui->textEdit->setFont(newFont);
#endif
if (g.outputDisplayDetails())
ui->checkBox->setChecked(true);
else
ui->textEdit->setVisible(false);
}
ProgressWidget::~ProgressWidget()
{
delete ui;
}
void ProgressWidget::forceOpen()
{
ui->checkBox->hide();
ui->textEdit->show();
}
void ProgressWidget::setInfo(const QString &text)
{
ui->info->show();
ui->info->setText(text);
}
void ProgressWidget::setMaximum(int value)
{
ui->progressBar->setMaximum(value);
}
void ProgressWidget::setValue(int value)
{
ui->progressBar->setValue(value);
}
void ProgressWidget::addText(const QString &text)
{
QTextCursor cursor(ui->textEdit->textCursor());
// is the scrollbar at the end?
bool atEnd = (ui->textEdit->verticalScrollBar()->value() == ui->textEdit->verticalScrollBar()->maximum());
cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor, 1);
cursor.insertText(text);
if (atEnd) {
ui->textEdit->verticalScrollBar()->triggerAction(QAbstractSlider::SliderToMaximum);
}
}
void ProgressWidget::setProgressColor(const QColor &color)
{
ui->progressBar->setStyleSheet(QString("QProgressBar {text-align: center;} QProgressBar::chunk { background-color: %1; text-align:center;}:").arg(color.name()));
}
#define HLINE_SEPARATOR "================================================================================="
void ProgressWidget::addSeparator()
{
addText("\n" HLINE_SEPARATOR "\n");
}
void ProgressWidget::on_checkBox_toggled(bool checked)
{
g.outputDisplayDetails(checked);
ui->textEdit->setVisible(checked);
QTimer::singleShot(0, this, SLOT(shrink()));
}
void ProgressWidget::lock(bool lock)
{
emit locked(lock);
}
void ProgressWidget::shrink()
{
emit detailsToggled();
}

38
companion/src/progresswidget.h Executable file
View file

@ -0,0 +1,38 @@
#ifndef PROGRESS_WIDGET_H_
#define PROGRESS_WIDGET_H_
#include <QWidget>
namespace Ui {
class ProgressWidget;
}
class ProgressWidget : public QWidget
{
Q_OBJECT
public:
explicit ProgressWidget(QWidget *parent);
~ProgressWidget();
void lock(bool lock);
void addText(const QString &text);
void setInfo(const QString &text);
void setMaximum(int value);
void setValue(int value);
void setProgressColor(const QColor &color);
void addSeparator();
void forceOpen();
signals:
void detailsToggled();
void locked(bool);
protected slots:
void on_checkBox_toggled(bool checked);
void shrink();
private:
Ui::ProgressWidget *ui;
};
#endif // PROGRESS_WIDGET_H_

View file

@ -1,13 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"> <ui version="4.0">
<class>avrOutputDialog</class> <class>ProgressWidget</class>
<widget class="QDialog" name="avrOutputDialog"> <widget class="QWidget" name="ProgressWidget">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>700</width> <width>700</width>
<height>348</height> <height>244</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
@ -22,33 +25,42 @@
<height>0</height> <height>0</height>
</size> </size>
</property> </property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="windowTitle"> <property name="windowTitle">
<string>Dialog</string> <string>Form</string>
</property> </property>
<property name="windowIcon"> <layout class="QVBoxLayout" name="verticalLayout">
<iconset resource="companion.qrc"> <property name="leftMargin">
<normaloff>:/icon.png</normaloff>:/icon.png</iconset> <number>0</number>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <property name="topMargin">
<item row="0" column="0"> <number>5</number>
<layout class="QHBoxLayout" name="horizontalLayout"> </property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="info">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,0">
<item> <item>
<widget class="QProgressBar" name="progressBar"> <widget class="QProgressBar" name="progressBar">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>480</width> <width>0</width>
<height>0</height> <height>0</height>
</size> </size>
</property> </property>
@ -66,21 +78,21 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="1" column="0"> <item>
<widget class="QPlainTextEdit" name="plainTextEdit"> <widget class="QPlainTextEdit" name="textEdit">
<property name="enabled"> <property name="enabled">
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>0</width> <width>600</width>
<height>312</height> <height>100</height>
</size> </size>
</property> </property>
<property name="font"> <property name="font">
@ -89,11 +101,20 @@
<pointsize>10</pointsize> <pointsize>10</pointsize>
</font> </font>
</property> </property>
<property name="lineWidth">
<number>80</number>
</property>
<property name="midLineWidth">
<number>80</number>
</property>
<property name="verticalScrollBarPolicy"> <property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOn</enum> <enum>Qt::ScrollBarAlwaysOn</enum>
</property> </property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="lineWrapMode"> <property name="lineWrapMode">
<enum>QPlainTextEdit::WidgetWidth</enum> <enum>QPlainTextEdit::NoWrap</enum>
</property> </property>
<property name="readOnly"> <property name="readOnly">
<bool>true</bool> <bool>true</bool>
@ -108,8 +129,6 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<resources> <resources/>
<include location="companion.qrc"/>
</resources>
<connections/> <connections/>
</ui> </ui>

405
companion/src/radiointerface.cpp Executable file
View file

@ -0,0 +1,405 @@
#include "radiointerface.h"
#include "appdata.h"
#include "eeprominterface.h"
#include "process_flash.h"
#include "radionotfound.h"
#include "burnconfigdialog.h"
#include "firmwareinterface.h"
#include "helpers.h"
#include "mountlist.h"
#include "process_copy.h"
#include <QFile>
#include <QMessageBox>
QString getRadioInterfaceCmd()
{
burnConfigDialog bcd;
EEPROMInterface *eepromInterface = GetEepromInterface();
if (IS_TARANIS(eepromInterface->getBoard())) {
return bcd.getDFU();
}
else if (IS_SKY9X(GetEepromInterface()->getBoard())) {
return bcd.getSAMBA();
}
else {
return bcd.getAVRDUDE();
}
}
QString findMassstoragePath(const QString &filename)
{
QString temppath;
QStringList drives;
QString eepromfile;
QString fsname;
#if defined WIN32 || !defined __GNUC__
foreach( QFileInfo drive, QDir::drives() ) {
WCHAR szVolumeName[256] ;
WCHAR szFileSystemName[256];
DWORD dwSerialNumber = 0;
DWORD dwMaxFileNameLength=256;
DWORD dwFileSystemFlags=0;
bool ret = GetVolumeInformationW( (WCHAR *) drive.absolutePath().utf16(),szVolumeName,256,&dwSerialNumber,&dwMaxFileNameLength,&dwFileSystemFlags,szFileSystemName,256);
if (ret) {
QString vName = QString::fromUtf16 ( (const ushort *) szVolumeName) ;
temppath = drive.absolutePath();
eepromfile = temppath;
eepromfile.append("/" + filename);
if (QFile::exists(eepromfile)) {
return eepromfile;
}
}
}
#else
struct mount_entry *entry;
entry = read_file_system_list(true);
while (entry != NULL) {
if (!drives.contains(entry->me_devname)) {
drives.append(entry->me_devname);
temppath = entry->me_mountdir;
eepromfile = temppath;
eepromfile.append("/" + filename);
#if !defined __APPLE__
QString fstype = entry->me_type;
if (QFile::exists(eepromfile) && fstype.contains("fat") ) {
#else
if (QFile::exists(eepromfile)) {
#endif
return eepromfile;
}
}
entry = entry->me_next;
}
#endif
return QString();
}
QStringList getAvrdudeArgs(const QString &cmd, const QString &filename)
{
QStringList args;
burnConfigDialog bcd;
QString programmer = bcd.getProgrammer();
QString mcu = bcd.getMCU();
args << "-c" << programmer << "-p";
if (GetEepromInterface()->getBoard() == BOARD_GRUVIN9X)
args << "m2560";
else if (GetEepromInterface()->getBoard() == BOARD_M128)
args << "m128";
else
args << mcu;
args << bcd.getAvrdudeArgs();
QString fullcmd = cmd + filename;
if (QFileInfo(filename).suffix().toUpper() == "HEX")
fullcmd += ":i";
else if (QFileInfo(filename).suffix().toUpper()=="BIN")
fullcmd += ":r";
else
fullcmd += ":a";
args << "-U" << fullcmd;
return args;
}
QStringList getDfuArgs(const QString &cmd, const QString &filename)
{
QStringList arguments;
burnConfigDialog bcd;
QString memory="0x08000000";
if (cmd=="-U") {
memory.append(QString(":%1").arg(MAX_FSIZE));
}
arguments << bcd.getDFUArgs() << "--dfuse-address" << memory << "-d" << "0483:df11";
QString fullcmd = cmd + filename;
arguments << "" << fullcmd;
return arguments;
}
QStringList getSambaArgs(const QString &tcl)
{
QStringList result;
QString tclFilename = generateProcessUniqueTempFileName("temp.tcl");
if (QFile::exists(tclFilename)) {
qunlink(tclFilename);
}
QFile tclFile(tclFilename);
if (!tclFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
QMessageBox::warning(NULL, QObject::tr("Error"), QObject::tr("Cannot write file %1:\n%2.").arg(tclFilename).arg(tclFile.errorString()));
return result;
}
QTextStream outputStream(&tclFile);
outputStream << tcl;
burnConfigDialog bcd;
result << bcd.getSambaPort() << bcd.getArmMCU() << tclFilename ;
return result;
}
QStringList getReadEEpromCmd(const QString &filename)
{
QStringList result;
EEPROMInterface *eepromInterface = GetEepromInterface();
if (IS_TARANIS(eepromInterface->getBoard())) {
// impossible
}
else if (IS_SKY9X(eepromInterface->getBoard())) {
result = getSambaArgs(QString("SERIALFLASH::Init 0\n") + "receive_file {SerialFlash AT25} \"" + filename + "\" 0x0 0x80000 0\n");
}
else {
result = getAvrdudeArgs("eeprom:r:", filename);
}
return result;
}
QStringList getWriteEEpromCmd(const QString &filename)
{
EEPROMInterface *eepromInterface = GetEepromInterface();
if (IS_TARANIS(eepromInterface->getBoard())) {
// impossible
return QStringList();
}
else if (IS_SKY9X(eepromInterface->getBoard())) {
return getSambaArgs(QString("SERIALFLASH::Init 0\n") + "send_file {SerialFlash AT25} \"" + filename + "\" 0x0 0\n");
}
else {
return getAvrdudeArgs("eeprom:w:", filename);
}
}
QStringList getWriteFirmwareArgs(const QString &filename)
{
EEPROMInterface *eepromInterface = GetEepromInterface();
if (IS_TARANIS(eepromInterface->getBoard())) {
return getDfuArgs("-D", filename);
}
else if (eepromInterface->getBoard() == BOARD_SKY9X) {
return getSambaArgs(QString("send_file {Flash} \"") + filename + "\" 0x400000 0\n" + "FLASH::ScriptGPNMV 2\n");
}
else if (eepromInterface->getBoard() == BOARD_9XRPRO) {
return getSambaArgs(QString("send_file {Flash} \"") + filename + "\" 0x400000 0\n" + "FLASH::ScriptGPNMV 2\n");
}
else {
return getAvrdudeArgs("flash:w:", filename);
}
}
QStringList getReadFirmwareArgs(const QString &filename)
{
EEPROMInterface *eepromInterface = GetEepromInterface();
if (IS_TARANIS(eepromInterface->getBoard())) {
return getDfuArgs("-U", filename);
}
else if (eepromInterface->getBoard() == BOARD_SKY9X) {
return getSambaArgs(QString("receive_file {Flash} \"") + filename + "\" 0x400000 0x40000 0\n");
}
else if (eepromInterface->getBoard() == BOARD_9XRPRO) {
return getSambaArgs(QString("receive_file {Flash} \"") + filename + "\" 0x400000 0x80000 0\n");
}
else {
return getAvrdudeArgs("flash:r:", filename);
}
}
void readAvrdudeFuses(ProgressWidget *progress)
{
burnConfigDialog bcd;
QStringList args;
args << "-c" << bcd.getProgrammer() << "-p" << bcd.getMCU() << bcd.getAvrdudeArgs() << "-U" << "lfuse:r:-:i" << "-U" << "hfuse:r:-:i" << "-U" << "efuse:r:-:i";
FlashProcess flashProcess(bcd.getAVRDUDE(), args, progress);
flashProcess.run();
}
void resetAvrdudeFuses(bool eepromProtect, ProgressWidget *progress)
{
//fuses
//avrdude -c usbasp -p m64 -U lfuse:w:<0x0E>:m
//avrdude -c usbasp -p m64 -U hfuse:w:<0x89>:m 0x81 for eeprom protection
//avrdude -c usbasp -p m64 -U efuse:w:<0xFF>:m
burnConfigDialog bcd;
QMessageBox::StandardButton ret = QMessageBox::No;
ret = QMessageBox::warning(NULL, QObject::tr("Companion"),
QObject::tr("<b><u>WARNING!</u></b><br>This will reset the fuses of %1 to the factory settings.<br>"
"Writing fuses can mess up your radio.<br>Do this only if you are sure they are wrong!<br>"
"Are you sure you want to continue?").arg(bcd.getMCU()),
QMessageBox::Yes | QMessageBox::No);
if (ret == QMessageBox::Yes) {
QStringList args = bcd.getAvrdudeArgs();
QStringList str;
if (bcd.getMCU() == "m2560") {
args << "-B8";
QString erStr = eepromProtect ? "hfuse:w:0x11:m" : "hfuse:w:0x19:m";
str << "-U" << "lfuse:w:0xD7:m" << "-U" << erStr << "-U" << "efuse:w:0xFC:m";
//use hfuse = 0x81 to prevent eeprom being erased with every flashing
}
else {
QString lfuses;
QString tempFile = generateProcessUniqueTempFileName("ftemp.bin");
QStringList argread;
argread << "-c" << bcd.getProgrammer() << "-p" << bcd.getMCU() << args <<"-U" << "lfuse:r:"+tempFile+":r";
FlashProcess flashProcess(bcd.getAVRDUDE(), argread, progress);
flashProcess.run();
QFile file(tempFile);
if (file.exists() && file.size()==1) {
file.open(QIODevice::ReadOnly);
char bin_flash[1];
file.read(bin_flash, 1);
if (bin_flash[0]==0x0E) {
lfuses = "lfuse:w:0x0E:m";
}
else {
lfuses = "lfuse:w:0x3F:m";
}
file.close();
qunlink(tempFile);
}
else {
lfuses = "lfuse:w:0x3F:m";
}
QString erStr = eepromProtect ? "hfuse:w:0x81:m" : "hfuse:w:0x89:m";
str << "-U" << lfuses << "-U" << erStr << "-U" << "efuse:w:0xFF:m";
//use hfuse = 0x81 to prevent eeprom being erased with every flashing
}
QStringList arguments;
if (bcd.getMCU() == "m2560") {
arguments << "-c" << bcd.getProgrammer() << "-p" << bcd.getMCU() << args << "-u" << str;
}
else {
arguments << "-c" << bcd.getProgrammer() << "-p" << bcd.getMCU() << args << "-B" << "100" << "-u" << str;
}
FlashProcess flashProcess(bcd.getAVRDUDE(), arguments, progress);
flashProcess.run();
}
}
bool readFirmware(const QString &filename, ProgressWidget *progress)
{
bool result = false;
QFile file(filename);
if (file.exists() && !file.remove()) {
QMessageBox::warning(NULL, QObject::tr("Error"), QObject::tr("Could not delete temporary file: %1").arg(filename));
return false;
}
g.flashDir(QFileInfo(filename).dir().absolutePath());
if (IS_ARM(GetCurrentFirmware()->getBoard())) {
QString path = findMassstoragePath("FIRMWARE.BIN");
if (!path.isEmpty()) {
CopyProcess copyProcess(path, filename, progress);
result = copyProcess.run();
}
}
if (result == false) {
FlashProcess flashProcess(getRadioInterfaceCmd(), getReadFirmwareArgs(filename), progress);
result = flashProcess.run();
}
if (!QFileInfo(filename).exists()) {
result = false;
}
return result;
}
bool writeFirmware(const QString &filename, ProgressWidget *progress)
{
if (IS_ARM(GetCurrentFirmware()->getBoard())) {
QString path = findMassstoragePath("FIRMWARE.BIN");
if (!path.isEmpty()) {
CopyProcess copyProcess(filename, path, progress);
return copyProcess.run();
}
}
FlashProcess flashProcess(getRadioInterfaceCmd(), getWriteFirmwareArgs(filename), progress);
return flashProcess.run();
}
bool readEeprom(const QString &filename, ProgressWidget *progress)
{
bool result = false;
QFile file(filename);
if (file.exists() && !file.remove()) {
QMessageBox::warning(NULL, QObject::tr("Error"), QObject::tr("Could not delete temporary file: %1").arg(filename));
return false;
}
if (IS_ARM(GetCurrentFirmware()->getBoard())) {
QString path = findMassstoragePath("EEPROM.BIN");
if (path.isEmpty()) {
// On previous OpenTX we called the EEPROM file "TARANIS.BIN" :(
path = findMassstoragePath("TARANIS.BIN");
}
if (path.isEmpty()) {
// Mike's bootloader calls the EEPROM file "ERSKY9X.BIN" :(
path = findMassstoragePath("ERSKY9X.BIN");
}
if (!path.isEmpty()) {
CopyProcess copyProcess(path, filename, progress);
result = copyProcess.run();
}
}
if (result == false && !IS_TARANIS(GetCurrentFirmware()->getBoard())) {
FlashProcess flashProcess(getRadioInterfaceCmd(), getReadEEpromCmd(filename), progress);
result = flashProcess.run();
}
if (result == false && IS_ARM(GetCurrentFirmware()->getBoard())) {
RadioNotFoundDialog dialog;
dialog.exec();
}
if (!QFileInfo(filename).exists()) {
result = false;
}
return result;
}
bool writeEeprom(const QString &filename, ProgressWidget *progress)
{
if (IS_ARM(GetCurrentFirmware()->getBoard())) {
QString path = findMassstoragePath("EEPROM.BIN");
if (path.isEmpty()) {
// On previous OpenTX we called the EEPROM file "TARANIS.BIN" :(
path = findMassstoragePath("TARANIS.BIN");
}
if (path.isEmpty()) {
// Mike's bootloader calls the EEPROM file "ERSKY9X.BIN" :(
path = findMassstoragePath("ERSKY9X.BIN");
}
if (!path.isEmpty()) {
CopyProcess copyProcess(filename, path, progress);
return copyProcess.run();
}
}
if (!IS_TARANIS(GetCurrentFirmware()->getBoard())) {
FlashProcess flashProcess(getRadioInterfaceCmd(), getWriteEEpromCmd(filename), progress);
return flashProcess.run();
}
if (IS_ARM(GetCurrentFirmware()->getBoard())) {
RadioNotFoundDialog dialog;
dialog.exec();
}
return false;
}

30
companion/src/radiointerface.h Executable file
View file

@ -0,0 +1,30 @@
#ifndef RADIOINTERFACE_H_
#define RADIOINTERFACE_H_
#include <QString>
#include <QStringList>
class ProgressWidget;
QString getRadioInterfaceCmd();
QString findMassstoragePath(const QString &filename);
QStringList getAvrdudeArgs(const QString &cmd, const QString &filename);
QStringList getSambaArgs(const QString &tcl);
QStringList getDfuArgs(const QString &cmd, const QString &filename);
void readAvrdudeFuses(ProgressWidget *progress);
void resetAvrdudeFuses(bool eepromProtect, ProgressWidget *progress);
QStringList getReadEEpromCmd(const QString &filename);
QStringList getWriteEEpromCmd(const QString &filename);
QStringList getReadFirmwareArgs(const QString &filename);
QStringList getWriteFirmwareArgs(const QString &filename);
bool readFirmware(const QString &filename, ProgressWidget *progress);
bool writeFirmware(const QString &filename, ProgressWidget *progress);
bool readEeprom(const QString &filename, ProgressWidget *progress);
bool writeEeprom(const QString &filename, ProgressWidget *progress);
#endif /* RADIOINTERFACE_H_ */

View file

@ -1,7 +1,6 @@
include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
set(shared_SRCS set(shared_SRCS
foldersync.cpp
genericpanel.cpp genericpanel.cpp
hexspinbox.cpp hexspinbox.cpp
verticalscrollarea.cpp verticalscrollarea.cpp

View file

@ -1,88 +0,0 @@
#include "foldersync.h"
#include <QDirIterator>
#include <QDateTime>
#include <QMessageBox>
#include <QTextStream>
#include <QDebug>
FoldersSyncTask::FoldersSyncTask(const QString &folder1, const QString &folder2)
{
folders[0] = folder1;
folders[1] = folder2;
}
void FoldersSyncTask::run()
{
if (!QFile::exists(folders[0])) {
QMessageBox::warning(NULL, QObject::tr("Synchronization error"), QObject::tr("The directory '%1' doesn't exist!").arg(folders[0]));
return;
}
if (!QFile::exists(folders[1])) {
QMessageBox::warning(NULL, QObject::tr("Synchronization error"), QObject::tr("The directory '%1' doesn't exist!").arg(folders[1]));
return;
}
QStringList errors = updateDir(folders[0], folders[1]) + updateDir(folders[1], folders[0]);
if (errors.count() > 0) {
QMessageBox::warning(NULL, QObject::tr("Synchronization error"), errors.join("\n"));
}
}
QStringList FoldersSyncTask::updateDir(const QDir &source, const QDir &destination)
{
QStringList errors;
QDirIterator it(source, QDirIterator::Subdirectories);
while (it.hasNext()) {
QString path = it.next();
// qDebug() << path;
QFileInfo sourceInfo(path);
QString relativePath = source.relativeFilePath(path);
QString destinationPath = destination.absoluteFilePath(relativePath);
QFileInfo destinationInfo(destinationPath);
if (sourceInfo.isDir()) {
if (!destinationInfo.exists()) {
if (!destination.mkdir(relativePath)) {
errors << QObject::tr("Create '%1' failed").arg(destinationPath);
continue;
}
}
}
else {
if (!destinationInfo.exists()) {
qDebug() << "Copy" << path << "to" << destinationPath;
if (!QFile::copy(path, destinationPath)) {
errors << QObject::tr("Copy '%1' to '%2' failed").arg(path).arg(destinationPath);
continue;
}
}
else if (sourceInfo.lastModified() > destinationInfo.lastModified()) {
// retrieve source contents
QFile sourceFile(path);
if (!sourceFile.open(QFile::ReadOnly)) {
errors << QObject::tr("Open '%1' failed").arg(path);
continue;
}
QString sourceContents = sourceFile.readAll();
sourceFile.close();
// try to retrieve destination contents
QFile destinationFile(path);
if (destinationFile.open(QFile::ReadOnly)) {
QString destinationContents = destinationFile.readAll();
destinationFile.close();
if (sourceContents == destinationContents) {
// qDebug() << "Skip" << path;
continue;
}
}
if (!destinationFile.open(QFile::WriteOnly)) {
errors << QObject::tr("Write '%1' failed").arg(destinationPath);
continue;
}
qDebug() << "Write" << destinationPath;
QTextStream destinationStream(&destinationFile);
destinationStream << sourceContents;
destinationFile.close();
}
}
}
return errors;
}

View file

@ -1,20 +0,0 @@
#ifndef FOLDERSYNC_H_
#define FOLDERSYNC_H_
#include <QString>
#include <QStringList>
class QDir;
class FoldersSyncTask
{
public:
FoldersSyncTask(const QString &folder1, const QString &folder2);
void run();
protected:
QStringList updateDir(const QDir &source, const QDir &destination);
QString folders[2];
};
#endif /* FOLDERSYNC_H_ */

View file

@ -5,7 +5,7 @@
#include <QGridLayout> #include <QGridLayout>
#include <QSpacerItem> #include <QSpacerItem>
GenericPanel::GenericPanel(QWidget * parent, ModelData * model, GeneralSettings & generalSettings, FirmwareInterface * firmware): GenericPanel::GenericPanel(QWidget * parent, ModelData * model, GeneralSettings & generalSettings, Firmware * firmware):
QWidget(parent), QWidget(parent),
model(model), model(model),
generalSettings(generalSettings), generalSettings(generalSettings),

View file

@ -5,7 +5,7 @@
class ModelData; class ModelData;
class GeneralSettings; class GeneralSettings;
class FirmwareInterface; class Firmware;
class QGridLayout; class QGridLayout;
class QString; class QString;
@ -20,7 +20,7 @@ class GenericPanel : public QWidget
friend class AutoLineEdit; friend class AutoLineEdit;
public: public:
GenericPanel(QWidget *parent, ModelData * model, GeneralSettings & generalSettings, FirmwareInterface * firmware); GenericPanel(QWidget *parent, ModelData * model, GeneralSettings & generalSettings, Firmware * firmware);
virtual ~GenericPanel(); virtual ~GenericPanel();
signals: signals:
@ -32,7 +32,7 @@ class GenericPanel : public QWidget
protected: protected:
ModelData * model; ModelData * model;
GeneralSettings & generalSettings; GeneralSettings & generalSettings;
FirmwareInterface * firmware; Firmware * firmware;
bool lock; bool lock;
void addLabel(QGridLayout * gridLayout, const QString &text, int col, bool mimimize=false); void addLabel(QGridLayout * gridLayout, const QString &text, int col, bool mimimize=false);
void addEmptyLabel(QGridLayout * gridLayout, int col); void addEmptyLabel(QGridLayout * gridLayout, int col);

Some files were not shown because too many files have changed in this diff Show more