diff --git a/companion/src/firmwares/boards.cpp b/companion/src/firmwares/boards.cpp index af164355c..344b3119e 100644 --- a/companion/src/firmwares/boards.cpp +++ b/companion/src/firmwares/boards.cpp @@ -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; } diff --git a/companion/src/firmwares/boards.h b/companion/src/firmwares/boards.h index ea0476bda..050cf87e3 100644 --- a/companion/src/firmwares/boards.h +++ b/companion/src/firmwares/boards.h @@ -145,7 +145,8 @@ namespace Board { NumTrimSwitches, HasRTC, HasColorLcd, - NumFunctionSwitches + NumFunctionSwitches, + HasSDCard }; struct SwitchInfo diff --git a/companion/src/firmwares/eeprominterface.h b/companion/src/firmwares/eeprominterface.h index d8e3fff1f..df7c6d9f4 100644 --- a/companion/src/firmwares/eeprominterface.h +++ b/companion/src/firmwares/eeprominterface.h @@ -164,7 +164,8 @@ enum Capability { HasTelemetryBaudrate, TopBarZones, FunctionSwitches, - HasModelList + Has, + HasModelsList }; class EEPROMInterface diff --git a/companion/src/flasheepromdialog.cpp b/companion/src/flasheepromdialog.cpp index 6c210f940..87cb08fb7 100644 --- a/companion/src/flasheepromdialog.cpp +++ b/companion/src/flasheepromdialog.cpp @@ -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(); } diff --git a/companion/src/flashfirmwaredialog.cpp b/companion/src/flashfirmwaredialog.cpp index fc45a89ff..97f37f15a 100644 --- a/companion/src/flashfirmwaredialog.cpp +++ b/companion/src/flashfirmwaredialog.cpp @@ -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)) { diff --git a/companion/src/mainwindow.cpp b/companion/src/mainwindow.cpp index e1465f9f3..c76351781 100644 --- a/companion/src/mainwindow.cpp +++ b/companion/src/mainwindow.cpp @@ -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); diff --git a/companion/src/mainwindow.h b/companion/src/mainwindow.h index 78178d7f8..87202acf2 100644 --- a/companion/src/mainwindow.h +++ b/companion/src/mainwindow.h @@ -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; diff --git a/companion/src/mdichild.cpp b/companion/src/mdichild.cpp index 2c8732b4e..e1d59e041 100644 --- a/companion/src/mdichild.cpp +++ b/companion/src/mdichild.cpp @@ -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 { diff --git a/companion/src/mdichild.h b/companion/src/mdichild.h index b44047aba..af5aa49e8 100644 --- a/companion/src/mdichild.h +++ b/companion/src/mdichild.h @@ -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(); diff --git a/companion/src/radiointerface.cpp b/companion/src/radiointerface.cpp index 2d9524521..21fd4af5c 100644 --- a/companion/src/radiointerface.cpp +++ b/companion/src/radiointerface.cpp @@ -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 -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(); } diff --git a/companion/src/radiointerface.h b/companion/src/radiointerface.h index 37053fac5..76c635e83 100644 --- a/companion/src/radiointerface.h +++ b/companion/src/radiointerface.h @@ -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_