Support reading and writing yaml settings from/to radio

This commit is contained in:
elecpower
2021-12-31 10:53:09 +01:00
committed by Raphael Coeffic
parent 6b8175835b
commit cade5c3529
11 changed files with 116 additions and 152 deletions
+3
View File
@@ -486,6 +486,9 @@ int Boards::getCapability(Board::Type board, Board::Capability capability)
case NumFunctionSwitches:
return IS_JUMPER_TPRO(board) ? 6 : 0;
case HasSDCard:
return IS_STM32(board);
default:
return 0;
}
+2 -1
View File
@@ -145,7 +145,8 @@ namespace Board {
NumTrimSwitches,
HasRTC,
HasColorLcd,
NumFunctionSwitches
NumFunctionSwitches,
HasSDCard
};
struct SwitchInfo
+2 -1
View File
@@ -164,7 +164,8 @@ enum Capability {
HasTelemetryBaudrate,
TopBarZones,
FunctionSwitches,
HasModelList
Has,
HasModelsList
};
class EEPROMInterface
+2 -2
View File
@@ -266,7 +266,7 @@ void FlashEEpromDialog::on_burnButton_clicked()
backupFilename = generateProcessUniqueTempFileName("eeprom.bin");
}
if (!backupFilename.isEmpty()) {
if (!readEeprom(backupFilename, progressDialog.progress())) {
if (!readSettings(backupFilename, progressDialog.progress())) {
return;
}
}
@@ -297,7 +297,7 @@ void FlashEEpromDialog::on_burnButton_clicked()
}
// and write...
bool result = writeEeprom(filename, progressDialog.progress());
bool result = writeSettings(filename, progressDialog.progress());
if (!result && !progressDialog.isEmpty()) {
progressDialog.exec();
}
+3 -3
View File
@@ -307,7 +307,7 @@ void FlashFirmwareDialog::startFlash(const QString &filename)
backupPath=g.backupDir();
}
backupFilename = backupPath + "/backup-" + QDateTime().currentDateTime().toString("yyyy-MM-dd-HHmmss") + ".bin";
result = readEeprom(backupFilename, progressDialog.progress());
result = readSettings(backupFilename, progressDialog.progress());
sleep(2);
}
@@ -322,14 +322,14 @@ void FlashFirmwareDialog::startFlash(const QString &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())) {
if (!writeSettings(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.progress()->setInfo(tr("Flashing done"));
}
progressDialog.exec();
if (isTempFileName(filename)) {
+14 -14
View File
@@ -897,13 +897,13 @@ void MainWindow::customizeSplash()
dialog->deleteLater();
}
void MainWindow::writeEeprom()
void MainWindow::writeSettings()
{
if (activeMdiChild())
activeMdiChild()->writeEeprom();
activeMdiChild()->writeSettings();
}
void MainWindow::readEeprom()
void MainWindow::readSettings()
{
Board::Type board = getCurrentBoard();
QString tempFile;
@@ -936,7 +936,7 @@ bool MainWindow::readFirmwareFromRadio(const QString & filename)
bool MainWindow::readEepromFromRadio(const QString & filename)
{
ProgressDialog progressDialog(this, tr("Read Models and Settings from Radio"), CompanionIcon("read_eeprom.png"));
bool result = ::readEeprom(filename, progressDialog.progress());
bool result = ::readSettings(filename, progressDialog.progress());
if (!result) {
if (!progressDialog.isEmpty()) {
progressDialog.exec();
@@ -1045,8 +1045,8 @@ void MainWindow::updateMenus()
saveAsAct->setEnabled(activeChild);
closeAct->setEnabled(activeChild);
compareAct->setEnabled(activeChild);
writeEepromAct->setEnabled(activeChild);
readEepromAct->setEnabled(true);
writeSettingsAct->setEnabled(activeChild);
readSettingsAct->setEnabled(true);
if (IS_FAMILY_HORUS_OR_T16(getCurrentBoard())) {
writeBUToRadioAct->setEnabled(false);
readBUToFileAct->setEnabled(false);
@@ -1199,8 +1199,8 @@ void MainWindow::retranslateUi(bool showMsg)
trAct(sdsyncAct, tr("Synchronize SD"), tr("SD card synchronization"));
trAct(openDocURLAct, tr("Manuals and other Documents"), tr("Open the EdgeTX document page in a web browser"));
trAct(writeEepromAct, tr("Write Models and Settings To Radio"), tr("Write Models and Settings to Radio"));
trAct(readEepromAct, tr("Read Models and Settings From Radio"), tr("Read Models and Settings from Radio"));
trAct(writeSettingsAct, tr("Write Models and Settings To Radio"), tr("Write Models and Settings to Radio"));
trAct(readSettingsAct, tr("Read Models and Settings From Radio"), tr("Read Models and Settings from Radio"));
trAct(burnConfigAct, tr("Configure Communications..."), tr("Configure software for communicating with the Radio"));
trAct(writeBUToRadioAct, tr("Write Backup to Radio"), tr("Write Backup from file to Radio"));
trAct(readBUToFileAct, tr("Backup Radio to File"), tr("Save a complete backup file of all settings and model data in the Radio"));
@@ -1256,8 +1256,8 @@ void MainWindow::createActions()
burnListAct = addAct("list.png", SLOT(burnList()));
readFlashAct = addAct("read_flash.png", SLOT(readFlash()));
writeFlashAct = addAct("write_flash.png", SLOT(writeFlash()));
writeEepromAct = addAct("write_eeprom.png", SLOT(writeEeprom()));
readEepromAct = addAct("read_eeprom.png", SLOT(readEeprom()));
writeSettingsAct = addAct("write_eeprom.png", SLOT(writeSettings()));
readSettingsAct = addAct("read_eeprom.png", SLOT(readSettings()));
burnConfigAct = addAct("configure.png", SLOT(burnConfig()));
writeBUToRadioAct = addAct("write_eeprom_file.png", SLOT(writeBackup()));
@@ -1347,8 +1347,8 @@ void MainWindow::createMenus()
settingsMenu->addAction(importSettingsAct);
burnMenu = menuBar()->addMenu("");
burnMenu->addAction(writeEepromAct);
burnMenu->addAction(readEepromAct);
burnMenu->addAction(writeSettingsAct);
burnMenu->addAction(readSettingsAct);
burnMenu->addSeparator();
burnMenu->addAction(writeBUToRadioAct);
burnMenu->addAction(readBUToFileAct);
@@ -1435,8 +1435,8 @@ void MainWindow::createToolBars()
burnToolBar = new QToolBar(this);
addToolBar( Qt::LeftToolBarArea, burnToolBar );
burnToolBar->setObjectName("Write");
burnToolBar->addAction(writeEepromAct);
burnToolBar->addAction(readEepromAct);
burnToolBar->addAction(writeSettingsAct);
burnToolBar->addAction(readSettingsAct);
burnToolBar->addSeparator();
burnToolBar->addAction(writeBUToRadioAct);
burnToolBar->addAction(readBUToFileAct);
+4 -4
View File
@@ -103,8 +103,8 @@ class MainWindow : public QMainWindow
bool loadProfileId(const unsigned pid);
void loadProfile();
void logFile();
void writeEeprom();
void readEeprom();
void writeSettings();
void readSettings();
void writeFlash(QString fileToFlash="");
void readFlash();
void writeBackup();
@@ -203,8 +203,8 @@ class MainWindow : public QMainWindow
QAction *changelogAct;
QAction *compareAct;
QAction *editSplashAct;
QAction *writeEepromAct;
QAction *readEepromAct;
QAction *writeSettingsAct;
QAction *readSettingsAct;
QAction *burnConfigAct;
QAction *burnListAct;
QAction *writeFlashAct;
+6 -4
View File
@@ -1528,7 +1528,7 @@ int MdiChild::askQuestion(const QString & msg, QMessageBox::StandardButtons butt
return QMessageBox::question(this, CPN_STR_APP_NAME, msg, buttons, defaultButton);
}
void MdiChild::writeEeprom() // write to Tx
void MdiChild::writeSettings() // write to Tx
{
if (g.confirmWriteModelsAndSettings()) {
QMessageBox msgbox;
@@ -1547,19 +1547,21 @@ void MdiChild::writeEeprom() // write to Tx
}
Board::Type board = getCurrentBoard();
if (IS_FAMILY_HORUS_OR_T16(board)) {
if (Boards::getCapability(board, Board::HasSDCard)) {
QString radioPath = findMassstoragePath("RADIO", true);
qDebug() << "Searching for SD card, found" << radioPath;
if (radioPath.isEmpty()) {
qDebug() << "MdiChild::writeEeprom(): Horus radio not found";
qDebug() << "Radio SD card not found";
QMessageBox::critical(this, CPN_STR_TTL_ERROR, tr("Unable to find radio SD card!"));
return;
}
if (saveFile(radioPath, false)) {
emit newStatusMessage(tr("Models and Settings written"), 2000);
QMessageBox::information(this, CPN_STR_TTL_INFO, tr("Saved models and settings to radio"));
}
else {
qDebug() << "MdiChild::writeEeprom(): saveFile error";
QMessageBox::critical(this, CPN_STR_TTL_ERROR, tr("Error saving models and settings to radio!"));
}
}
else {
+1 -1
View File
@@ -87,7 +87,7 @@ class MdiChild : public QWidget
bool saveAs(bool isNew=false);
bool saveFile(const QString & fileName, bool setCurrent=true);
void closeFile(bool force = false);
void writeEeprom();
void writeSettings();
void print(int model=-1, const QString & filename="");
void onFirmwareChanged();
+75 -120
View File
@@ -175,7 +175,7 @@ bool writeFirmware(const QString & filename, ProgressWidget * progress)
return flashProcess.run();
}
bool readEeprom(const QString & filename, ProgressWidget * progress)
bool readSettings(const QString & filename, ProgressWidget * progress)
{
Board::Type board = getCurrentBoard();
@@ -186,64 +186,84 @@ bool readEeprom(const QString & filename, ProgressWidget * progress)
return false;
}
if (IS_FAMILY_HORUS_OR_T16(board)) {
QString radioPath = findMassstoragePath("RADIO", true);
qDebug() << "Searching for SD card, found" << radioPath;
if (radioPath.isEmpty()) {
QMessageBox::critical(progress, CPN_STR_TTL_ERROR,
QCoreApplication::translate("RadioInterface", "Unable to find radio SD card!"));
return false;
}
RadioData radioData;
Storage inputStorage(radioPath);
if (!inputStorage.load(radioData)) {
QMessageBox::critical(progress, CPN_STR_TTL_ERROR, inputStorage.error());
return false;
}
Storage outputStorage(filename);
if (!outputStorage.write(radioData)) {
QMessageBox::critical(progress, CPN_STR_TTL_ERROR, outputStorage.error());
return false;
}
if (Boards::getCapability(board, Board::HasSDCard))
readSettingsSDCard(filename, progress);
else
readSettingsEeprom(filename, progress);
}
if (getCurrentBoard() == Board::BOARD_JUMPER_T16 && inputStorage.getBoard() == Board::BOARD_X10) {
if (displayT16ImportWarning() == false)
return false;
}
bool readSettingsSDCard(const QString & filename, ProgressWidget * progress)
{
QString radioPath = findMassstoragePath("RADIO", true);
qDebug() << "Searching for SD card, found" << radioPath;
if (radioPath.isEmpty()) {
QMessageBox::critical(progress, CPN_STR_TTL_ERROR,
QCoreApplication::translate("RadioInterface", "Unable to find radio SD card!"));
return false;
}
else {
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()) {
RadioNotFoundDialog dialog(progress);
dialog.exec();
// if radio.yml it is a converted radio
// if radio.bin unconverted pre 2.6
// if neither then unconverted eeprom or empty
if (!QFile::exists(radioPath % "/RADIO/radio.yml") && !QFile::exists(radioPath % "/RADIO/radio.bin"))
return readSettingsEeprom(filename, progress);
RadioData radioData;
Storage inputStorage(radioPath);
if (!inputStorage.load(radioData)) {
QMessageBox::critical(progress, CPN_STR_TTL_ERROR, inputStorage.error());
return false;
}
Storage outputStorage(filename);
if (!outputStorage.write(radioData)) {
QMessageBox::critical(progress, CPN_STR_TTL_ERROR, outputStorage.error());
return false;
}
if (getCurrentBoard() == Board::BOARD_JUMPER_T16 && inputStorage.getBoard() == Board::BOARD_X10) {
if (displayT16ImportWarning() == false)
return false;
}
CopyProcess copyProcess(path, filename, progress);
if (!copyProcess.run()) {
return false;
}
}
return QFileInfo(filename).exists();
}
if (!IS_STM32(board)) {
FlashProcess flashProcess(getRadioInterfaceCmd(), getReadEEpromCmd(filename), progress);
if (!flashProcess.run()) {
return false;
}
bool readSettingsEeprom(const QString & filename, ProgressWidget * progress)
{
Board::Type board = getCurrentBoard();
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()) {
RadioNotFoundDialog dialog(progress);
dialog.exec();
return false;
}
CopyProcess copyProcess(path, filename, progress);
if (!copyProcess.run()) {
return false;
}
if (!IS_STM32(board)) {
FlashProcess flashProcess(getRadioInterfaceCmd(), getReadEEpromCmd(filename), progress);
if (!flashProcess.run()) {
return false;
}
}
return QFileInfo(filename).exists();
}
bool writeEeprom(const QString & filename, ProgressWidget * progress)
bool writeSettings(const QString & filename, ProgressWidget * progress)
{
Board::Type board = getCurrentBoard();
@@ -272,94 +292,29 @@ bool writeEeprom(const QString & filename, ProgressWidget * progress)
return false;
}
#if (QT_VERSION < QT_VERSION_CHECK(5, 4, 0))
#if defined WIN32 || !defined __GNUC__
#include <windows.h>
bool isRemovableMedia(const QString & vol)
{
char szDosDeviceName[MAX_PATH];
QString volume = vol;
UINT driveType = GetDriveType(volume.replace("/", "\\").toLatin1());
if (driveType != DRIVE_REMOVABLE)
return false;
QueryDosDevice(volume.replace("/", "").toLatin1(), szDosDeviceName, MAX_PATH);
if (strstr(szDosDeviceName, "\\Floppy") != NULL) { // it's a floppy
return false;
}
return true;
}
#else
#include "mountlist.h"
#endif // defined WIN32 || !defined __GNUC__
#endif // (QT_VERSION < QT_VERSION_CHECK(5, 4, 0))
QString findMassstoragePath(const QString & filename, bool onlyPath)
{
QString temppath;
QString eepromfile;
QString probefile;
bool found = false;
QRegularExpression fstypeRe("^(v?fat|msdos)", QRegularExpression::CaseInsensitiveOption); // Linux: "vfat"; macOS: "msdos"; Win: "FAT32"
#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0))
foreach(const QStorageInfo & si, QStorageInfo::mountedVolumes()) {
//qDebug() << si.rootPath() << si.name() << si.device() << si.displayName() << si.fileSystemType() << si.isReady();
if (!si.isReady() || !QString(si.fileSystemType()).contains(fstypeRe))
continue;
temppath = si.rootPath();
eepromfile = temppath % "/" % filename;
qDebug() << "Searching for" << eepromfile;
if (QFile::exists(eepromfile)) {
probefile = temppath % "/" % filename;
qDebug() << "Searching for" << probefile;
if (QFile::exists(probefile)) {
found = true;
break;
}
}
#elif defined WIN32 || !defined __GNUC__
static QStringList blacklist;
foreach(const QFileInfo & drive, QDir::drives()) {
temppath = drive.absolutePath();
if (blacklist.contains(temppath))
continue;
if (!isRemovableMedia(temppath)) {
blacklist.append(temppath);
continue;
}
WCHAR szVolumeName[256] ;
WCHAR szFileSystemName[256];
DWORD dwSerialNumber = 0;
DWORD dwMaxFileNameLength=256;
DWORD dwFileSystemFlags=0;
if (!GetVolumeInformationW( (WCHAR *) drive.absolutePath().utf16(),szVolumeName,256,&dwSerialNumber,&dwMaxFileNameLength,&dwFileSystemFlags,szFileSystemName,256))
continue;
eepromfile = temppath % "/" % filename;
qDebug() << "Searching for" << eepromfile;
if (QFile::exists(eepromfile)) {
found = true;
break;
}
}
#else
const static QStringList blacklist = QStringList() << "/" << "/net" << "/proc" << "/run";
QStringList drives;
struct mount_entry *entry;
struct mount_entry *firstEntry;
firstEntry = entry = read_file_system_list(true);
while (entry != NULL) {
temppath = entry->me_mountdir;
if (!drives.contains(entry->me_devname) && !blacklist.contains(temppath) && QString(entry->me_type).contains(fstypeRe)) {
drives.append(entry->me_devname);
eepromfile = temppath % "/" % filename;
qDebug() << "Searching for" << eepromfile;
if (QFile::exists(eepromfile)) {
found = true;
break;
}
}
entry = entry->me_next;
}
free_file_system_list(firstEntry);
#endif
if (found)
return onlyPath ? temppath : eepromfile;
return onlyPath ? temppath : probefile;
else
return QString();
}
+4 -2
View File
@@ -40,7 +40,9 @@ 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);
bool readSettings(const QString &filename, ProgressWidget *progress);
bool readSettingsSDCard(const QString &filename, ProgressWidget *progress);
bool readSettingsEeprom(const QString &filename, ProgressWidget *progress);
bool writeSettings(const QString &filename, ProgressWidget *progress);
#endif // _RADIOINTERFACE_H_