From ebb5d39a140b7d4eb0f6e7e109fea73d724c5199 Mon Sep 17 00:00:00 2001 From: Neil Horne <15316949+elecpower@users.noreply.github.com> Date: Fri, 22 Nov 2024 11:27:19 +1100 Subject: [PATCH] chore(cpn): remove binary file format models and settings support (#5653) --- companion/src/CMakeLists.txt | 1 - companion/src/constants.h | 4 +- companion/src/firmwares/CMakeLists.txt | 3 - companion/src/firmwares/eepromimportexport.h | 834 ---- companion/src/firmwares/eeprominterface.cpp | 97 +- companion/src/firmwares/eeprominterface.h | 115 +- companion/src/firmwares/er9x/er9xeeprom.cpp | 482 --- companion/src/firmwares/er9x/er9xeeprom.h | 266 -- .../src/firmwares/er9x/er9xinterface.cpp | 342 -- companion/src/firmwares/er9x/er9xinterface.h | 83 - .../src/firmwares/ersky9x/ersky9xeeprom.cpp | 731 ---- .../src/firmwares/ersky9x/ersky9xeeprom.h | 437 -- .../firmwares/ersky9x/ersky9xinterface.cpp | 395 -- .../src/firmwares/ersky9x/ersky9xinterface.h | 83 - .../src/firmwares/opentx/opentxeeprom.cpp | 3517 ----------------- companion/src/firmwares/opentx/opentxeeprom.h | 163 - .../src/firmwares/opentx/opentxinterface.cpp | 819 ---- .../src/firmwares/opentx/opentxinterface.h | 71 +- companion/src/flasheepromdialog.cpp | 316 -- companion/src/flasheepromdialog.h | 62 - companion/src/flasheepromdialog.ui | 198 - companion/src/flashfirmwaredialog.cpp | 51 +- companion/src/mainwindow.cpp | 11 +- companion/src/mdichild.cpp | 40 +- companion/src/modelprinter.cpp | 5 - companion/src/modelprinter.h | 1 - companion/src/radiointerface.cpp | 6 +- .../src/simulation/simulatorstartupdialog.cpp | 2 +- companion/src/simulation/simulatorwidget.cpp | 29 +- companion/src/storage/CMakeLists.txt | 3 - companion/src/storage/labeled.cpp | 181 +- companion/src/storage/labeled.h | 5 - companion/src/storage/otx.cpp | 116 - companion/src/storage/otx.h | 49 - companion/src/storage/sdcard.h | 5 +- companion/src/storage/storage.cpp | 106 +- companion/src/storage/storage.h | 20 +- 37 files changed, 101 insertions(+), 9548 deletions(-) delete mode 100644 companion/src/firmwares/eepromimportexport.h delete mode 100644 companion/src/firmwares/er9x/er9xeeprom.cpp delete mode 100644 companion/src/firmwares/er9x/er9xeeprom.h delete mode 100644 companion/src/firmwares/er9x/er9xinterface.cpp delete mode 100644 companion/src/firmwares/er9x/er9xinterface.h delete mode 100644 companion/src/firmwares/ersky9x/ersky9xeeprom.cpp delete mode 100644 companion/src/firmwares/ersky9x/ersky9xeeprom.h delete mode 100644 companion/src/firmwares/ersky9x/ersky9xinterface.cpp delete mode 100644 companion/src/firmwares/ersky9x/ersky9xinterface.h delete mode 100644 companion/src/firmwares/opentx/opentxeeprom.cpp delete mode 100644 companion/src/firmwares/opentx/opentxeeprom.h delete mode 100644 companion/src/flasheepromdialog.cpp delete mode 100644 companion/src/flasheepromdialog.h delete mode 100644 companion/src/flasheepromdialog.ui delete mode 100644 companion/src/storage/otx.cpp delete mode 100644 companion/src/storage/otx.h diff --git a/companion/src/CMakeLists.txt b/companion/src/CMakeLists.txt index f592d0357..5a671294a 100644 --- a/companion/src/CMakeLists.txt +++ b/companion/src/CMakeLists.txt @@ -224,7 +224,6 @@ set(companion_NAMES burnconfigdialog comparedialog customizesplashdialog - flasheepromdialog flashfirmwaredialog helpers_html labels diff --git a/companion/src/constants.h b/companion/src/constants.h index b35aea503..0d822189c 100644 --- a/companion/src/constants.h +++ b/companion/src/constants.h @@ -72,15 +72,15 @@ #define BIN_FILES_FILTER "BIN " % CPN_STR_FILES % " (*.bin);;" #define DFU_FILES_FILTER "DFU " % CPN_STR_FILES % " (*.dfu);;" #define EEPE_FILES_FILTER "EEPE " % CPN_STR_FILES % " (*.eepe);;" -#define OTX_FILES_FILTER "OpenTX " % CPN_STR_FILES % " (*.otx);;" #define ETX_FILES_FILTER "EdgeTX " % CPN_STR_FILES % " (*.etx);;" #define YML_FILES_FILTER "EdgeTX YAML " % CPN_STR_FILES % " (*.yml);;" -#define EEPROM_FILES_FILTER CPN_STR_RAD_MOD_SETTINGS % " " % CPN_STR_FILES % " (*.etx *.yml *.otx *.eepe *.bin *.hex);;" % ETX_FILES_FILTER % YML_FILES_FILTER % OTX_FILES_FILTER % EEPE_FILES_FILTER % BIN_FILES_FILTER % HEX_FILES_FILTER +#define EEPROM_FILES_FILTER CPN_STR_RAD_MOD_SETTINGS % " " % CPN_STR_FILES % " (*.etx *.yml);;" % ETX_FILES_FILTER % YML_FILES_FILTER #define FLASH_FILES_FILTER "FLASH " % CPN_STR_FILES % " (*.bin *.hex *.dfu);;" % BIN_FILES_FILTER % HEX_FILES_FILTER % DFU_FILES_FILTER #define EXTERNAL_EEPROM_FILES_FILTER "EEPROM " % CPN_STR_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 SIMU_FILES_FILTER ETX_FILES_FILTER #define CPN_STR_APP_SETTINGS QCoreApplication::translate("Companion", "Application Settings") #define CPN_STR_APP_SETTINGS_FILES CPN_STR_APP_SETTINGS % " " % CPN_STR_FILES diff --git a/companion/src/firmwares/CMakeLists.txt b/companion/src/firmwares/CMakeLists.txt index b7dc976b9..165e324e1 100644 --- a/companion/src/firmwares/CMakeLists.txt +++ b/companion/src/firmwares/CMakeLists.txt @@ -31,9 +31,6 @@ set(${PROJECT_NAME}_NAMES sourcenumref telem_data timerdata - ersky9x/ersky9xeeprom - ersky9x/ersky9xinterface - opentx/opentxeeprom opentx/opentxinterface edgetx/edgetxinterface edgetx/yaml_calibdata diff --git a/companion/src/firmwares/eepromimportexport.h b/companion/src/firmwares/eepromimportexport.h deleted file mode 100644 index 4efc22638..000000000 --- a/companion/src/firmwares/eepromimportexport.h +++ /dev/null @@ -1,834 +0,0 @@ -/* - * Copyright (C) EdgeTX - * - * Based on code named - * opentx - https://github.com/opentx/opentx - * th9x - http://code.google.com/p/th9x - * er9x - http://code.google.com/p/er9x - * gruvin9x - http://code.google.com/p/gruvin9x - * - * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef _EEPROMIMPORTEXPORT_H_ -#define _EEPROMIMPORTEXPORT_H_ - -#include "customdebug.h" -#include -#include -#include - -class DataField { - Q_DECLARE_TR_FUNCTIONS(DataField) - - public: - explicit DataField(DataField * parent, const char * name=""): - parent(parent), - name(name) - { - } - - virtual ~DataField() - = default; - - virtual const QString & getName() - { - return name; - } - - virtual unsigned int size() = 0; // size in bits - virtual void ExportBits(QBitArray & output) = 0; - virtual void ImportBits(const QBitArray & input) = 0; - - static QBitArray bytesToBits(QByteArray bytes) - { - QBitArray bits(bytes.count()*8); - // Convert from QByteArray to QBitArray - for (int i=0; isetError(error); - } - else { - qWarning() << qPrintable(error); - } - } - - DataField * parent; - QString name; -}; - -//class ProxyField: public DataField { -// public: -// explicit ProxyField(DataField * parent): -// DataField(parent, "Proxy") -// { -// } -// -// virtual DataField * getField() = 0; -// -//}; - -template -class BaseUnsignedField: public DataField { - public: - BaseUnsignedField(DataField * parent, container & field): - DataField(parent, "Unsigned"), - field(field), - min(0), - max(std::numeric_limits::max()) - { - } - - BaseUnsignedField(DataField * parent, container & field, const char * name): - DataField(parent, name), - field(field), - min(0), - max(std::numeric_limits::max()) - { - } - - BaseUnsignedField(DataField * parent, container & field, container min, container max, const char * name="Unsigned"): - DataField(parent, name), - field(field), - min(min), - max(max) - { - } - - BaseUnsignedField() = delete; - - void ExportBits(QBitArray & output) override - { - container value = field; - if (value > max) value = max; - if (value < min) value = min; - - output.resize(N); - for (int i=0; i: 0x%3(%4)").arg(name).arg(N).arg(field, 0, 16).arg(field); - } - - unsigned int size() override - { - return N; - } - - protected: - container & field; - container min; - container max; -}; - -template -class UnsignedField : public BaseUnsignedField -{ - public: - UnsignedField(DataField * parent, unsigned int & field): - BaseUnsignedField(parent, field) - { - } - - UnsignedField(DataField * parent, unsigned int & field, const char *name): - BaseUnsignedField(parent, field, name) - { - } - - UnsignedField(DataField * parent, unsigned int & field, unsigned int min, unsigned int max, const char *name="Unsigned"): - BaseUnsignedField(parent, field, min, max, name) - { - } -}; - -template -class BoolField: public DataField { - public: - explicit BoolField(DataField * parent, bool & field): - DataField(parent, "Bool"), - field(field) - { - } - - BoolField() = delete; - - void ExportBits(QBitArray & output) override - { - output.resize(N); - if (field) { - output.setBit(0); - } - } - - void ImportBits(const QBitArray & input) override - { - field = input[0]; - qCDebug(eepromImport) << QString("\timported %1<%2>: 0x%3(%4)").arg(name).arg(N).arg(field, 0, 16).arg(field); - } - - unsigned int size() override - { - return N; - } - - protected: - bool & field; -}; - -template -class SignedField: public DataField { - public: - SignedField(DataField * parent, int & field): - DataField(parent, "Signed"), - field(field) - { - } - - SignedField(DataField * parent, int & field, const char *name): - DataField(parent, name), - field(field) - { - } - - SignedField(DataField * parent, int & field, int min, int max, const char *name="Signed"): - DataField(parent, name), - field(field), - min(min), - max(max) - { - } - - void ExportBits(QBitArray & output) override - { - int value = field; - if (value > max) value = max; - if (value < min) value = min; - - output.resize(N); - for (int i=0; i: 0x%3(%4)").arg(name).arg(N).arg(field, 0, 16).arg(field); - } - - unsigned int size() override - { - return N; - } - - protected: - int & field; - int min = INT_MIN; - int max = INT_MAX; -}; - -template -class SpareBitsField: public UnsignedField { - public: - explicit SpareBitsField(DataField * parent): - UnsignedField(parent, spare, 0, 0, "Spare"), - spare(0) - { - } - - protected: - unsigned int spare; -}; - -template -class CharField: public DataField { - public: - CharField(DataField * parent, char * field, bool truncate=true, const char * name="Char"): - DataField(parent, name), - field(field), - truncate(truncate) - { - } - - void ExportBits(QBitArray & output) override - { - output.resize(N*8); - int b = 0; - int len = truncate ? strlen(field) : N; - for (int i=0; i=len ? 0 : field[i]); - for (int j=0; j<8; j++, b++) { - if (idx & (1<: '%3'").arg(name).arg(N).arg(field); - } - - unsigned int size() override - { - return 8 * N; - } - - protected: - char * field; - bool truncate; -}; - -static const char specialCharsTab[] = "_-.,"; -static inline int8_t char2zchar(char c) -{ - if (c==' ') return 0; - if (c>='A' && c<='Z') return 1+c-'A'; - if (c>='a' && c<='z') return -1-c+'a'; - if (c>='0' && c<='9') return 27+c-'0'; - for (int8_t i=0;;i++) { - char cc = specialCharsTab[i]; - if (cc==0) return 0; - if (cc==c) return 37+i; - } -} - -#define ZCHAR_MAX 40 -static inline char zchar2char(int8_t idx) -{ - if (idx == 0) return ' '; - if (idx < 0) { - if (idx > -27) return 'a' - idx - 1; - idx = -idx; - } - if (idx < 27) return 'A' + idx - 1; - if (idx < 37) return '0' + idx - 27; - if (idx <= ZCHAR_MAX) return specialCharsTab[idx-37]; - return ' '; -} - -template -class ZCharField: public DataField { - public: - ZCharField(DataField * parent, char * field, const char * name = "ZChar"): - DataField(parent, name), - field(field) - { - } - - void ExportBits(QBitArray & output) override - { - output.resize(N*8); - int b = 0; - int len = strlen(field); - for (int i=0; i=len ? 0 : char2zchar(field[i]); - for (int j=0; j<8; j++, b++) { - if (idx & (1<=0; i--) { - if (field[i] == ' ') - field[i] = '\0'; - else - break; - } - qCDebug(eepromImport) << QString("\timported %1<%2>: '%3'").arg(name).arg(N).arg(field); - } - - unsigned int size() override - { - return 8*N; - } - - protected: - char * field; -}; - -class StructField: public DataField { - public: - explicit StructField(DataField * parent, const char * name = "Struct"): - DataField(parent, name) - { - } - - ~StructField() override { - foreach(DataField * field, fields) { - delete field; - } - } - - inline void Append(DataField * field) { - //qCDebug(eepromImport) << QString("StructField(%1) appending field: %2").arg(name).arg(field->getName()); - fields.append(field); - } - - void ExportBits(QBitArray & output) override - { - int offset = 0; - output.resize(size()); - foreach(DataField *field, fields) { - QBitArray bits; - field->ExportBits(bits); - for (int i=0; isize(); - QBitArray bits(size); - for (unsigned int i=0; iImportBits(bits); - } - } - - unsigned int size() override - { - unsigned int result = 0; - foreach(DataField *field, fields) { - result += field->size(); - } - return result; - } - - int dump(int level=0, int offset=0) override - { - for (int i=0; idump(level+1, offset); - } - return offset; - } - - protected: - QList fields; -}; - -class TransformedField: public DataField { - public: - TransformedField(DataField * parent, DataField & field): - DataField(parent), - field(field) - { - } - - ~TransformedField() override - = default; - - void ExportBits(QBitArray & output) override - { - beforeExport(); - field.ExportBits(output); - } - - void ImportBits(const QBitArray & input) override - { - qCDebug(eepromImport) << QString("\timporting TransformedField %1:").arg(field.getName()); - field.ImportBits(input); - afterImport(); - } - - - const QString & getName() override - { - return field.getName(); - } - - unsigned int size() override - { - return field.size(); - } - - virtual void beforeExport() = 0; - - virtual void afterImport() = 0; - - int dump(int level=0, int offset=0) override - { - beforeExport(); - return field.dump(level, offset); - } - - protected: - DataField & field; -}; - -template -class UnionField: public DataField { - public: - - class UnionMember { - public: - virtual ~UnionMember() = default; - virtual bool select(const selectorT& attr) const = 0; - virtual DataField* getField() = 0; - }; - - class TransformedMember: public UnionMember, public TransformedField { - public: - TransformedMember(DataField* parent, DataField& field): - TransformedField(parent, field) - { - } - - virtual DataField* getField() - { - return this; - } - }; - - UnionField(DataField * parent, selectorT& selectField, const char * name="Union"): - DataField(parent, name), selectField(selectField), maxSize(0) - { - } - - ~UnionField() override { - foreach(UnionMember *member, members) { - delete member; - } - } - - inline void Append(UnionMember * member) { - members.append(member); - if (member->getField()->size() > maxSize) - maxSize = member->getField()->size(); - } - - void ExportBits(QBitArray & output) override - { - foreach(UnionMember *member, members) { - if (member->select(selectField)) { - member->getField()->ExportBits(output); - break; - } - } - output.resize(maxSize); - } - - void ImportBits(const QBitArray & input) override - { - foreach(UnionMember *member, members) { - if (member->select(selectField)) { - member->getField()->ImportBits(input); - break; - } - } - } - - unsigned int size() override - { - return maxSize; - } - - protected: - selectorT& selectField; - QList members; - unsigned int maxSize; -}; - -class ConversionTable { - - public: - bool exportValue(const int before, int &after) - { - after = 0; - - for (auto & tuple : exportTable) { - if (before == tuple.a) { - after = tuple.b; - return true; - } - } - - return false; - } - - bool importValue(const int before, int &after) - { - after = 0; - - for (auto & tuple : importTable) { - if (before == tuple.b) { - after = tuple.a; - return true; - } - } - - return false; - } - - protected: - - class ConversionTuple { - public: - ConversionTuple(const int a, const int b): - a(a), - b(b) - { - } - - int a; - int b; - }; - - void addConversion(const int a, const int b) - { - ConversionTuple conversion(a, b); - importTable.push_back(conversion); - exportTable.push_back(conversion); - } - -// void addImportConversion(const int a, const int b) -// { -// importTable.push_back(ConversionTuple(a, b)); -// } -// -// void addExportConversion(const int a, const int b) -// { -// exportTable.push_back(ConversionTuple(a, b)); -// } - - std::list importTable; - std::list exportTable; -}; - -template -class ConversionField: public TransformedField { - public: - ConversionField(DataField * parent, int & field, ConversionTable *table, const char *name, QString error = ""): - TransformedField(parent, internalField), - internalField(this, _field, name), - field(field), - table(table), - error(std::move(error)) - { - } - - ConversionField(DataField * parent, unsigned int & field, ConversionTable *table, const char *name, QString error = ""): - TransformedField(parent, internalField), - internalField(this, (unsigned int &)_field, name), - field((int &)field), - table(table), - error(std::move(error)) - { - } - - ConversionField(DataField * parent, int & field, int (*exportFunc)(int), int (*importFunc)(int)): - TransformedField(parent, internalField), - internalField(this, _field), - field(field), - exportFunc(exportFunc), - importFunc(importFunc) - { - } - - ConversionField(DataField * parent, int & field, int shift, int scale=0, int min=INT_MIN, int max=INT_MAX, const char *name = "Signed shifted"): - TransformedField(parent, internalField), - internalField(this, _field, name), - field(field), - shift(shift), - scale(scale), - min(min), - max(max) - { - } - - ConversionField(DataField * parent, unsigned int & field, int shift, int scale=0): - TransformedField(parent, internalField), - internalField(this, (unsigned int &)_field), - field((int &)field), - shift(shift), - scale(scale) - { - } - - void beforeExport() override - { - _field = scale ? field / scale : field; - - if (table) { - if (!table->exportValue(_field, _field)) { - setError(error.isEmpty() ? DataField::tr("Conversion error on field %1").arg(name) : error); - } - return; - } - - if (shift) { - if (_field < min) - _field = min + shift; - else if (_field > max) - _field = max + shift; - else - _field += shift; - } - - if (exportFunc) { - _field = exportFunc(_field); - } - } - - void afterImport() override - { - field = _field; - - if (table) { - if (table->importValue(field, field)) - return; - } - - if (shift) { - field -= shift; - } - - if (importFunc) { - field = importFunc(field); - } - - if (scale) { - field *= scale; - } - - qCDebug(eepromImport) << QString("\timported ConversionField<%1>:").arg(internalField.getName()) << QString(" before: %1, after: %2").arg(_field).arg(field); - } - - protected: - T internalField; - int & field; - int _field = 0; - ConversionTable * table = nullptr; - int shift = 0; - int scale = 0; - int min = INT_MIN; - int max = INT_MAX; - int (*exportFunc)(int) = nullptr; - int (*importFunc)(int) = nullptr; - const QString error = ""; -}; - -#endif // _EEPROMIMPORTEXPORT_H_ diff --git a/companion/src/firmwares/eeprominterface.cpp b/companion/src/firmwares/eeprominterface.cpp index 863b07fa5..862d7967e 100644 --- a/companion/src/firmwares/eeprominterface.cpp +++ b/companion/src/firmwares/eeprominterface.cpp @@ -20,7 +20,6 @@ */ #include "eeprominterface.h" -#include "firmwares/opentx/opentxeeprom.h" #include "firmwareinterface.h" #include "boardfactories.h" @@ -30,97 +29,24 @@ float ValToTim(int value) { - return ((value < -109 ? 129+value : (value < 7 ? (113+value)*5 : (53+value)*10))/10.0); + return ((value < -109 ? 129 + value : (value < 7 ? (113 + value) * 5 : (53 + value) * 10)) / 10.0); } int TimToVal(float value) { int temp; - if (value>60) { - temp=136+round((value-60)); + if (value > 60) { + temp = 136 + round((value - 60)); } - else if (value>2) { - temp=20+round((value-2.0)*2.0); + else if (value > 2) { + temp = 20 + round((value - 2.0) * 2.0); } else { - temp=round(value*10.0); + temp = round(value * 10.0); } - return (temp-129); + return (temp - 129); } - -/* - * EEpromInterface globals - */ - -// TODO: No globals - -QList eepromInterfaces; - -void unregisterEEpromInterfaces() -{ - foreach(EEPROMInterface * intf, eepromInterfaces) { - // qDebug() << "UnregisterEepromInterfaces(): deleting " << QString::number( reinterpret_cast(intf), 16 ); - delete intf; - } - OpenTxEepromCleanup(); -} - -#if 0 // TODO: remove if unused, currently commented out in mdiChild.cpp -// TODO: No GUI here, e.g. return string list instead -void EEPROMInterface::showEepromErrors(QWidget *parent, const QString &title, const QString &mainMessage, unsigned long errorsFound) -{ - std::bitset errors((unsigned long long)errorsFound); - QStringList errorsList; - - errorsList << tr("Possible causes for this:"); - - if (errors.test(UNSUPPORTED_NEWER_VERSION)) { errorsList << tr("- Eeprom is from a newer version of OpenTX"); } - if (errors.test(NOT_OPENTX)) { errorsList << tr("- Eeprom is not from OpenTX"); } - if (errors.test(NOT_ERSKY9X)) { errorsList << tr("- Eeprom is not from ErSky9X"); } - if (errors.test(WRONG_SIZE)) { errorsList << tr("- Eeprom size is invalid"); } - if (errors.test(WRONG_FILE_SYSTEM)) { errorsList << tr("- Eeprom file system is invalid"); } - if (errors.test(UNKNOWN_BOARD)) { errorsList << tr("- Eeprom is from a unknown board"); } - if (errors.test(WRONG_BOARD)) { errorsList << tr("- Eeprom is from the wrong board"); } - if (errors.test(BACKUP_NOT_SUPPORTED)) { errorsList << tr("- Eeprom backup not supported"); } - - if (errors.test(UNKNOWN_ERROR)) { errorsList << tr("- Something that couldn't be guessed, sorry"); } - - if (errors.test(HAS_WARNINGS)) { - errorsList << tr("Warning:"); - if (errors.test(WARNING_WRONG_FIRMWARE)) { errorsList << tr("- Your radio probably uses a wrong firmware,\n eeprom size is 4096 but only the first 2048 are used"); } - } - - QMessageBox msgBox(parent); - msgBox.setWindowTitle(title); - msgBox.setIcon(QMessageBox::Critical); - msgBox.setText(mainMessage); - msgBox.setInformativeText(errorsList.join("\n")); - msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.exec(); -} -#endif - -// TODO: No GUI here, e.g. return string list instead -QString EEPROMInterface::getEepromWarnings(unsigned long errorsFound) -{ - std::bitset errors((unsigned long long)errorsFound); - QStringList warningsList; - if (errors.test(WARNING_WRONG_FIRMWARE)) { - warningsList << tr("- Your radio probably uses a wrong firmware,\n eeprom size is 4096 but only the first 2048 are used"); - } - if (errors.test(OLD_VERSION)) { - warningsList << tr("- Your eeprom is from an old version of OpenTX, upgrading!\n To keep your original file as a backup, please choose File -> Save As specifying a different name."); - } - - return warningsList.join("\n"); -} - - -/* - * Firmware - */ - Firmware::Firmware(Firmware * base, const QString & id, const QString & name, Board::Type board, const QString & downloadId, const QString & simulatorId, const QString & hwdefnId) : id(id), @@ -128,7 +54,6 @@ Firmware::Firmware(Firmware * base, const QString & id, const QString & name, Bo board(board), variantBase(0), base(base), - eepromInterface(nullptr), downloadId(downloadId), simulatorId(simulatorId), hwdefnId(hwdefnId) @@ -158,10 +83,10 @@ unsigned int Firmware::getVariantNumber() { unsigned int result = 0; const Firmware * base = getFirmwareBase(); - QStringList options = id.mid(base->getId().length()+1).split("-", Qt::SkipEmptyParts); - foreach(QString option, options) { - foreach(OptionsGroup group, base->opts) { - foreach(Option opt, group) { + QStringList options = id.mid(base->getId().length() + 1).split("-", Qt::SkipEmptyParts); + foreach (QString option, options) { + foreach (OptionsGroup group, base->opts) { + foreach (Option opt, group) { if (opt.name == option) { result += opt.variant; } diff --git a/companion/src/firmwares/eeprominterface.h b/companion/src/firmwares/eeprominterface.h index 54cb711a2..4e667c73c 100644 --- a/companion/src/firmwares/eeprominterface.h +++ b/companion/src/firmwares/eeprominterface.h @@ -19,8 +19,7 @@ * GNU General Public License for more details. */ -#ifndef _EEPROMINTERFACE_H_ -#define _EEPROMINTERFACE_H_ +#pragma once #include "boards.h" #include "macros.h" @@ -149,7 +148,6 @@ enum Capability { EnhancedCurves, HasFasOffset, HasMahPersistent, - SimulatorVariant, MavlinkTelemetry, HasInputDiff, HasMixerExpo, @@ -178,98 +176,12 @@ enum Capability { BacklightLevelMin, }; -class EEPROMInterface -{ - Q_DECLARE_TR_FUNCTIONS(EEPROMInterface) - - public: - - EEPROMInterface(Board::Type board): - board(board) - { - } - - virtual ~EEPROMInterface() {} - - inline Board::Type getBoard() { return board; } - - virtual unsigned long load(RadioData &radioData, const uint8_t * eeprom, int size) = 0; - - virtual unsigned long loadBackup(RadioData & radioData, const uint8_t * eeprom, int esize, int index) = 0; - - virtual int save(uint8_t * eeprom, const RadioData & radioData, uint8_t version=0, uint32_t variant=0) = 0; - - virtual int getSize(const ModelData &) = 0; - - virtual int getSize(const GeneralSettings &) = 0; - - //static void showEepromErrors(QWidget *parent, const QString &title, const QString &mainMessage, unsigned long errorsFound); - static QString getEepromWarnings(unsigned long errorsFound); - - protected: - - Board::Type board; - - private: - - EEPROMInterface(); - -}; - -/* EEPROM string conversion function (used only by er9xeeprom and ersky9xeeprom) */ -inline void getEEPROMString(char *dst, const char *src, int size) -{ - memcpy(dst, src, size); - dst[size] = '\0'; - for (int i=size-1; i>=0; i--) { - if (dst[i] == ' ') - dst[i] = '\0'; - else - break; - } -} - -// (used only by er9xeeprom and ersky9xeeprom) -inline int applyStickMode(int stick, unsigned int mode) -{ - if (mode == 0 || mode > 4) { - std::cerr << "Incorrect stick mode" << mode; - return stick; - } - - if (stick >= 1 && stick <= 4) - return modn12x3[mode-1][stick-1]; - else - return stick; -} - float ValToTim(int value); int TimToVal(float value); -void registerEEpromInterfaces(); -void unregisterEEpromInterfaces(); void registerOpenTxFirmwares(); void unregisterOpenTxFirmwares(); -enum EepromLoadErrors { - ALL_OK, - UNKNOWN_ERROR, - UNSUPPORTED_NEWER_VERSION, - WRONG_SIZE, - WRONG_FILE_SYSTEM, - NOT_OPENTX, - NOT_ERSKY9X, - UNKNOWN_BOARD, - WRONG_BOARD, - BACKUP_NOT_SUPPORTED, - - HAS_WARNINGS, - OLD_VERSION, - WARNING_WRONG_FIRMWARE, - - NUM_ERRORS -}; - constexpr char FIRMWARE_ID_PREFIX[] = { "edgetx-" }; class Firmware @@ -330,16 +242,6 @@ class Firmware return board; } - void setEEpromInterface(EEPROMInterface * eeprom) - { - eepromInterface = eeprom; - } - - EEPROMInterface * getEEpromInterface() - { - return eepromInterface; - } - QString getName() const { return name; @@ -429,7 +331,6 @@ class Firmware Board::Type board; unsigned int variantBase; Firmware * base; - EEPROMInterface * eepromInterface; QString downloadId; QString simulatorId; QString hwdefnId; @@ -449,11 +350,6 @@ inline Firmware * getCurrentFirmware() return Firmware::getCurrentVariant(); } -inline EEPROMInterface * getCurrentEEpromInterface() -{ - return Firmware::getCurrentVariant()->getEEpromInterface(); -} - inline Board::Type getCurrentBoard() { return Firmware::getCurrentVariant()->getBoard(); @@ -461,15 +357,10 @@ inline Board::Type getCurrentBoard() 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); } inline int calcRESXto100(int x) { - return divRoundClosest(x*100, 1024); + return divRoundClosest(x * 100, 1024); } - -extern QList eepromInterfaces; - - -#endif // _EEPROMINTERFACE_H_ diff --git a/companion/src/firmwares/er9x/er9xeeprom.cpp b/companion/src/firmwares/er9x/er9xeeprom.cpp deleted file mode 100644 index a14371fa6..000000000 --- a/companion/src/firmwares/er9x/er9xeeprom.cpp +++ /dev/null @@ -1,482 +0,0 @@ -/* - * Copyright (C) EdgeTX - * - * Based on code named - * opentx - https://github.com/opentx/opentx - * th9x - http://code.google.com/p/th9x - * er9x - http://code.google.com/p/er9x - * gruvin9x - http://code.google.com/p/gruvin9x - * - * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include "er9xeeprom.h" -#include "helpers.h" -#include - -RawSwitch er9xToSwitch(int8_t sw) -{ - uint8_t swa = abs(sw); - if (swa == 0) - return RawSwitch(SWITCH_TYPE_NONE); - else if (swa <= 9) - return RawSwitch(SWITCH_TYPE_SWITCH, sw); - else if (swa <= 21) - return RawSwitch(SWITCH_TYPE_VIRTUAL, sw > 0 ? sw-9 : sw+9); - else if (sw == 22) - return RawSwitch(SWITCH_TYPE_ON); - else if (sw == -22) - return RawSwitch(SWITCH_TYPE_OFF); - else if (swa <= 22+9) - return RawSwitch(SWITCH_TYPE_SWITCH, sw > 0 ? sw-22 : sw+22); - else - return RawSwitch(SWITCH_TYPE_VIRTUAL, sw > 0 ? sw-22-9 : sw+22+9); -} - -t_Er9xTrainerMix::t_Er9xTrainerMix() -{ - memset(this, 0, sizeof(t_Er9xTrainerMix)); -} - -t_Er9xTrainerMix::operator TrainerMix() -{ - TrainerMix c9x; - c9x.src = srcChn; - c9x.swtch = er9xToSwitch(swtch); - c9x.weight = (25 * studWeight) / 8; - c9x.mode = mode; - return c9x; -} - -t_Er9xTrainerData::t_Er9xTrainerData() -{ - memset(reinterpret_cast(this), 0, sizeof(t_Er9xTrainerData)); -} - -t_Er9xTrainerData::operator TrainerData () -{ - TrainerData c9x; - for (int i=0; i(this), 0, sizeof(t_Er9xGeneral)); -} - -Er9xGeneral::operator GeneralSettings () -{ - GeneralSettings result; - result.version = myVers; - for (int i=0; i125) { - int gvar; - if (weight>0) { - gvar=weight-125; - } else { - gvar=weight+131; - } - gvar+=10000; - c9x.weight=gvar; - } else { - c9x.weight = weight; - } - if (abs(sOffset)>125) { - int gvar; - if (sOffset>0) { - gvar=sOffset-125; - } else { - gvar=sOffset+131; - } - gvar+=10000; - c9x.sOffset=gvar; - } else { - c9x.sOffset=sOffset; - } - c9x.swtch = er9xToSwitch(swtch); - - if (srcRaw == 0) { - c9x.srcRaw = RawSource(SOURCE_TYPE_NONE); - } - else if (srcRaw <= 7) { - c9x.srcRaw = RawSource(SOURCE_TYPE_INPUT, srcRaw-1); - } - else if (srcRaw == 8) { - c9x.srcRaw = RawSource(SOURCE_TYPE_MAX); - } - else if (srcRaw == 9) { - if (swtch < 0) { - c9x.srcRaw = RawSource(SOURCE_TYPE_SWITCH, swtch < -3 ? -swtch-3 : -swtch); - c9x.weight = -weight; - } - else if (swtch > 0) { - c9x.srcRaw = RawSource(SOURCE_TYPE_SWITCH, swtch > 3 ? swtch-3 : swtch); - } - else { - c9x.srcRaw = RawSource(SOURCE_TYPE_MAX); - } - if (mltpx != MLTPX_REP) - c9x.swtch = RawSwitch(SWITCH_TYPE_NONE); - } - else if (srcRaw <= 12) { - c9x.srcRaw = RawSource(SOURCE_TYPE_CYC, srcRaw-10); - } - else if (srcRaw <= 20) { - c9x.srcRaw = RawSource(SOURCE_TYPE_PPM, srcRaw-13); - } - else if (srcRaw <=37) { - c9x.srcRaw = RawSource(SOURCE_TYPE_CH, srcRaw-21); - } - else { - c9x.srcRaw = RawSource(SOURCE_TYPE_GVAR, srcRaw-38); - } - - if (differential==1) { - c9x.curve.type = CurveReference::CURVE_REF_DIFF; - c9x.curve.value = differential; - } - else if (curve > 6) { - c9x.curve.type = CurveReference::CURVE_REF_CUSTOM; - c9x.curve.value = curve - 6; - } - else if (curve > 0) { - c9x.curve.type = CurveReference::CURVE_REF_FUNC; - c9x.curve.value = curve; - } - - // c9x.lateOffset=lateOffset; - c9x.delayUp = delayUp; - c9x.delayDown = delayDown; - c9x.speedUp = speedUp; - c9x.speedDown = speedDown; - c9x.carryTrim = carryTrim; - c9x.mltpx = (MltpxValue)mltpx; - c9x.mixWarn = mixWarn; - // c9x.enableFmTrim=enableFmTrim; - return c9x; -} - -RawSource er9xToSource(int8_t value) -{ - if (value == 0) { - return RawSource(SOURCE_TYPE_NONE); - } - else if (value <= 7) { - return RawSource(SOURCE_TYPE_INPUT, value - 1); - } - else if (value == 8) { - return RawSource(SOURCE_TYPE_MAX); - } - else if (value == 9) { - return RawSource(SOURCE_TYPE_MAX); - } - else if (value <= 12) { - return RawSource(SOURCE_TYPE_CYC, value-10); - } - else if (value <= 20) { - return RawSource(SOURCE_TYPE_PPM, value-13); - } - else if (value <= 36) { - return RawSource(SOURCE_TYPE_CH, value-21); - } - else { - return RawSource(SOURCE_TYPE_TELEMETRY, value-36); - } -} - -Er9xLogicalSwitchData::operator LogicalSwitchData () -{ - LogicalSwitchData c9x; - c9x.func = func; - c9x.val1 = v1; - c9x.val2 = v2; - - if ((c9x.func >= LS_FN_VPOS && c9x.func <= LS_FN_ANEG) || c9x.func >= LS_FN_EQUAL) { - c9x.val1 = er9xToSource(v1).toValue(); - } - - if (c9x.func >= LS_FN_EQUAL) { - c9x.val2 = er9xToSource(v2).toValue(); - } - - if (c9x.func >= LS_FN_AND && c9x.func <= LS_FN_XOR) { - c9x.val1 = er9xToSwitch(v1).toValue(); - c9x.val2 = er9xToSwitch(v2).toValue(); - } - - return c9x; -} - - -t_Er9xSafetySwData::t_Er9xSafetySwData() -{ - memset(this, 0, sizeof(t_Er9xSafetySwData)); -} - -t_Er9xFrSkyChannelData::t_Er9xFrSkyChannelData() -{ - memset(this, 0, sizeof(t_Er9xFrSkyChannelData)); -} - -t_Er9xFrSkyChannelData::operator FrSkyChannelData () -{ - FrSkyChannelData c9x; - c9x.ratio = ratio; - c9x.alarms[0].value = alarms_value[0]; - c9x.alarms[0].level = alarms_level & 3; - c9x.alarms[0].greater = alarms_greater & 1; - c9x.alarms[1].value = alarms_value[1]; - c9x.alarms[1].level = (alarms_level >> 2) & 3; - c9x.alarms[1].greater = (alarms_greater >> 1) & 1; - if (type==2) { - c9x.type = 0; - c9x.multiplier=1; - } else { - c9x.type = type; - } - return c9x; -} - -t_Er9xFrSkyData::t_Er9xFrSkyData() -{ - memset(reinterpret_cast(this), 0, sizeof(t_Er9xFrSkyData)); -} - -t_Er9xFrSkyData::operator FrSkyData () -{ - FrSkyData c9x; - c9x.channels[0] = channels[0]; - c9x.channels[1] = channels[1]; - return c9x; -} - -RawSwitch getEr9xTimerMode(int mode) -{ - /* - if (mode <= -33) - return TimerMode(TMRMODE_FIRST_NEG_SWITCH+(mode+33)); - else if (mode <= -1) - return TimerMode(TMRMODE_FIRST_NEG_SWITCH+(mode+1)); - else if (mode < 16) - return TimerMode(mode); - else if (mode < 16+21) - return TimerMode(TMRMODE_FIRST_SWITCH+(mode-16)); - else - return TimerMode(TMRMODE_FIRST_SWITCH+(mode-16-21)); - */ - return RawSwitch(); -} - -t_Er9xModelData::operator ModelData () -{ - ModelData c9x; - c9x.used = true; - getEEPROMString(c9x.name, name, sizeof(name)); - c9x.timers[0].mode = getEr9xTimerMode(tmrMode); - c9x.timers[0].val = tmrVal; - switch(protocol) { - case 1: - c9x.moduleData[0].protocol = PULSES_PXX_DJT; - break; - case 2: - c9x.moduleData[0].protocol = PULSES_DSM2; - break; - case 3: - c9x.moduleData[0].protocol = PULSES_PPM16; - break; - default: - c9x.moduleData[0].protocol = PULSES_PPM; - break; - } - c9x.moduleData[0].ppm.frameLength=ppmFrameLength; - c9x.moduleData[0].channelsCount = 8 + 2 * ppmNCH; - c9x.thrTrim = thrTrim; - c9x.trimInc = trimInc-2; - c9x.moduleData[0].ppm.delay = 300 + 50 * ppmDelay; - c9x.customFn[0].func = FuncInstantTrim; - if (trimSw) { - c9x.customFn[0].swtch = er9xToSwitch(trimSw); - } - c9x.beepANACenter = beepANACenter; - c9x.moduleData[0].ppm.pulsePol = pulsePol; - c9x.extendedLimits = extendedLimits; - c9x.swashRingData.elevatorWeight = swashInvertELE ? -100 : 100; - c9x.swashRingData.aileronWeight = swashInvertAIL ? -100 : 100; - c9x.swashRingData.collectiveWeight = swashInvertCOL ? -100 : 100; - c9x.swashRingData.type = swashType; - c9x.swashRingData.collectiveSource = er9xToSource(swashCollectiveSource); - c9x.swashRingData.value = swashRingValue; - - for (int i=0; i -#include "eeprominterface.h" - -//eeprom data -#define ER9X_MAX_MIXERS 32 -#define ER9X_MAX_CURVE5 8 -#define ER9X_MAX_CURVE9 8 -#define ER9X_MAX_CSFUNC 13 - -#define MDVERS 10 - -#define ER9X_NUM_CHNOUT 16 //number of real outputchannels CH1-CH8 -#define ER9X_NUM_CSW 12 //number of custom switches -#define CPN_MAX_STICKSnPOTS 7 //number of sticks and pots -#define ER9X_MAX_GVARS 7 - -#define ER9X_MAX_MODES 4 - -PACK(typedef struct t_Er9xTrainerMix { - uint8_t srcChn:3; //0-7 = ch1-8 - int8_t swtch:5; - int8_t studWeight:6; - uint8_t mode:2; // off, add-mode, subst-mode - - operator TrainerMix(); - t_Er9xTrainerMix(); -}) Er9xTrainerMix; // - -PACK(typedef struct t_Er9xTrainerData { - int16_t calib[4]; - Er9xTrainerMix mix[4]; - - operator TrainerData(); - t_Er9xTrainerData(); -}) Er9xTrainerData; - -PACK(typedef struct t_Er9xGeneral { - uint8_t myVers; - int16_t calibMid[CPN_MAX_STICKSnPOTS]; - int16_t calibSpanNeg[CPN_MAX_STICKSnPOTS]; - int16_t calibSpanPos[CPN_MAX_STICKSnPOTS]; - uint16_t chkSum; - uint8_t currModel; //0..15 - uint8_t contrast; - uint8_t vBatWarn; - int8_t txVoltageCalibration; - int8_t lightSw; - Er9xTrainerData trainer; - uint8_t view; - uint8_t disableThrottleWarning:1; - uint8_t disableSwitchWarning:1; - uint8_t disableMemoryWarning:1; - uint8_t beeperVal:3; - uint8_t reserveWarning:1; - uint8_t disableAlarmWarning:1; - uint8_t stickMode; - int8_t inactivityTimer; - uint8_t throttleReversed:1; - uint8_t minuteBeep:1; - uint8_t preBeep:1; - uint8_t flashBeep:1; - uint8_t disableSplashScreen:1; - uint8_t disablePotScroll:1; - uint8_t disableBG:1; - uint8_t frskyinternalalarm:1; - uint8_t spare_filter ; // No longer needed, left for eepe compatibility for now - uint8_t lightAutoOff; - uint8_t templateSetup; //RETA order according to chout_ar array - int8_t PPM_Multiplier; - uint8_t unused1; - uint8_t unused2:4; - uint8_t hideNameOnSplash:1; - uint8_t enablePpmsim:1; - uint8_t blightinv:1; - uint8_t stickScroll:1; - uint8_t speakerPitch; - uint8_t hapticStrength; - uint8_t speakerMode; - uint8_t lightOnStickMove; - - char ownerName[10]; - uint8_t switchWarningStates; - uint8_t volume ; - uint8_t res[3]; - uint8_t crosstrim:1; - uint8_t spare1:7; - - operator GeneralSettings(); - t_Er9xGeneral(); -}) Er9xGeneral; - -PACK(typedef struct t_Er9xExpoData { - int8_t expo[3][2][2]; - int8_t drSw1; - int8_t drSw2; - - t_Er9xExpoData() { memset(this, 0, sizeof(t_Er9xExpoData)); } -}) Er9xExpoData; - - -PACK(typedef struct t_Er9xLimitData { - int8_t min; - int8_t max; - bool revert; - int16_t offset; - - operator LimitData(); - t_Er9xLimitData(); -}) Er9xLimitData; - -#define MLTPX_ADD 0 -#define MLTPX_MUL 1 -#define MLTPX_REP 2 - -PACK(typedef struct t_Er9xMixData { - uint8_t destCh; // 1..CPN_MAX_CHNOUT - uint8_t srcRaw; // - int8_t weight; - int8_t swtch; - uint8_t curve; //0=symmetrisch 1=no neg 2=no pos - uint8_t delayUp:4; - uint8_t delayDown:4; - uint8_t speedUp:4; // Servogeschwindigkeit aus Tabelle (10ms Cycle) - uint8_t speedDown:4; // 0 nichts - uint8_t carryTrim:1; - uint8_t mltpx:2; // multiplex method 0=+ 1=* 2=replace - uint8_t lateOffset:1; // Add offset later - uint8_t mixWarn:2; // mixer warning - uint8_t enableFmTrim:1; - uint8_t differential:1; - int8_t sOffset; - int8_t res; - - operator MixData(); - t_Er9xMixData(); -}) Er9xMixData; - - -PACK(typedef struct t_Er9xLogicalSwitchData { // Custom Switches data - int8_t v1; //input - int8_t v2; //offset - uint8_t func:4; - uint8_t andsw:4; - - operator LogicalSwitchData(); - t_Er9xLogicalSwitchData() { memset(this, 0, sizeof(t_Er9xLogicalSwitchData)); } -}) Er9xLogicalSwitchData; - -PACK(typedef struct t_Er9xSafetySwData { // Custom Switches data - int8_t swtch; - int8_t val; - - t_Er9xSafetySwData(); -}) Er9xSafetySwData; - -PACK(typedef struct t_Er9xFrSkyChannelData { - uint8_t ratio; // 0.0 means not used, 0.1V steps EG. 6.6 Volts = 66. 25.1V = 251, etc. - uint8_t alarms_value[2]; // 0.1V steps EG. 6.6 Volts = 66. 25.1V = 251, etc. - uint8_t alarms_level:4; - uint8_t alarms_greater:2; // 0=LT(<), 1=GT(>) - uint8_t type:2; // future use: 0=volts, ... - - operator FrSkyChannelData(); - t_Er9xFrSkyChannelData(); -}) Er9xFrSkyChannelData; - -PACK(typedef struct t_Er9xFrSkyData { - Er9xFrSkyChannelData channels[2]; - - operator FrSkyData(); - t_Er9xFrSkyData(); -}) Er9xFrSkyData; - -PACK(typedef struct t_gvar { - int8_t gvar ; - uint8_t gvsource ; -// int8_t gvswitch ; -}) Er9xGvarData ; - -PACK(typedef struct t_FlightModeData { - // Trim store as -1001 to -1, trim value-501, 0-5 use trim of phase 0-5 - int16_t trim[4]; // -500..500 => trim value, 501 => use trim of phase 0, 502, 503, 504 => use trim of modes 1|2|3|4 instead - int8_t swtch; // Try 0-5 use trim of phase 0-5, 1000-2000, trim + 1500 ??? - uint8_t fadeIn:4; - uint8_t fadeOut:4; -}) Er9xFlightModeData; - -PACK(typedef struct t_Er9xModelData { - char name[10]; // 10 must be first for eeLoadModelName - uint8_t modelVoice ; // Index to model name voice (260+value) - int8_t tmrMode; // timer trigger source -> off, abs, stk, stk%, sw/!sw, !m_sw/!m_sw - uint8_t tmrDir:1; //0=>Count Down, 1=>Count Up - uint8_t traineron:1; // 0 disable trainer, 1 allow trainer - uint8_t t2throttle:1 ; // Start timer2 using throttle - uint8_t FrSkyUsrProto:1 ; // Protocol in FrSky User Data, 0=FrSky Hub, 1=WS HowHigh - uint8_t FrSkyGpsAlt:1 ; // Use Gps Altitude as main altitude reading - uint8_t FrSkyImperial:1 ; // Convert FrSky values to imperial units - uint8_t FrSkyAltAlarm:2; - uint16_t tmrVal; - uint8_t protocol; - int8_t ppmNCH; - uint8_t thrTrim:1; // Enable Throttle Trim - uint8_t xnumBlades:2; // RPM scaling - uint8_t spare10:1; - uint8_t thrExpo:1; // Enable Throttle Expo - uint8_t ppmStart:3 ; // Start channel for PPM - int8_t trimInc; // Trim Increments - int8_t ppmDelay; - int8_t trimSw; - uint8_t beepANACenter; // 1<<0->A1.. 1<<6->A7 - uint8_t pulsePol:1; - uint8_t extendedLimits:1; - uint8_t swashInvertELE:1; - uint8_t swashInvertAIL:1; - uint8_t swashInvertCOL:1; - uint8_t swashType:3; - uint8_t swashCollectiveSource; - uint8_t swashRingValue; - int8_t ppmFrameLength; - Er9xMixData mixData[ER9X_MAX_MIXERS]; - Er9xLimitData limitData[ER9X_NUM_CHNOUT]; - Er9xExpoData expoData[4]; - int8_t trim[4]; - int8_t curves5[ER9X_MAX_CURVE5][5]; - int8_t curves9[ER9X_MAX_CURVE9][9]; - Er9xLogicalSwitchData logicalSw[ER9X_NUM_CSW]; - uint8_t frSkyVoltThreshold ; - int8_t tmrModeB; - uint8_t numVoice; - Er9xSafetySwData safetySw[ER9X_NUM_CHNOUT]; - Er9xFrSkyData frsky; - uint8_t numBlades ; - uint8_t unused1[8] ; - uint8_t CustomDisplayIndex[6] ; - Er9xGvarData gvars[ER9X_MAX_GVARS] ; - Er9xFlightModeData flightModeData[ER9X_MAX_MODES] ; - - operator ModelData(); - t_Er9xModelData() { memset(reinterpret_cast(this), 0, sizeof(t_Er9xModelData)); } -}) Er9xModelData; - -#endif // _ER9XEEPROM_H_ diff --git a/companion/src/firmwares/er9x/er9xinterface.cpp b/companion/src/firmwares/er9x/er9xinterface.cpp deleted file mode 100644 index 3246efe37..000000000 --- a/companion/src/firmwares/er9x/er9xinterface.cpp +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Copyright (C) EdgeTX - * - * Based on code named - * opentx - https://github.com/opentx/opentx - * th9x - http://code.google.com/p/th9x - * er9x - http://code.google.com/p/er9x - * gruvin9x - http://code.google.com/p/gruvin9x - * - * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "er9xinterface.h" -#include "er9xeeprom.h" -#include "rlefile.h" -// #include "appdata.h" -// #include -#include - -#define FILE_TYP_GENERAL 1 -#define FILE_TYP_MODEL 2 - -#define FILE_GENERAL 0 -#define FILE_MODEL(n) (1+n) - -Er9xInterface::Er9xInterface(): - EEPROMInterface(Board::BOARD_9X_M64), - efile(new RleFile()) -{ -} - -Er9xInterface::~Er9xInterface() -{ - delete efile; -} - -const char * Er9xInterface::getName() -{ - return "Er9x"; -} - -inline void applyStickModeToModel(Er9xModelData & model, unsigned int mode) -{ - for (int i=0; i<2; i++) { - int stick = applyStickMode(i+1, mode) - 1; - { - int tmp = model.trim[i]; - model.trim[i] = model.trim[stick]; - model.trim[stick] = tmp; - } - { - Er9xExpoData tmp = model.expoData[i]; - model.expoData[i] = model.expoData[stick]; - model.expoData[stick] = tmp; - } - } - for (int i=0; i errors; - - Er9xGeneral er9xGeneral; - memset(&er9xGeneral,0,sizeof(er9xGeneral)); - if (!loadRadioSettingsDataXML(&doc, &er9xGeneral)) { - errors.set(UNKNOWN_ERROR); - return errors.to_ulong(); - } - else { - radioData.generalSettings=er9xGeneral; - dbg << "version " << (unsigned int)er9xGeneral.myVers << " "; - } - for (int i=0; i errors; - - if (size != Boards::getEEpromSize(Board::BOARD_9X_M64)) { - dbg << "wrong size"; - errors.set(WRONG_SIZE); - return errors.to_ulong(); - } - - if (!efile->EeFsOpen((uint8_t *)eeprom, size, Board::BOARD_9X_M64)) { - dbg << "wrong file system"; - errors.set(WRONG_FILE_SYSTEM); - return errors.to_ulong(); - } - - efile->openRd(FILE_GENERAL); - Er9xGeneral er9xGeneral; - - if (efile->readRlc1((uint8_t*)&er9xGeneral, 1) != 1) { - dbg << "no"; - errors.set(UNKNOWN_ERROR); - return errors.to_ulong(); - } - - dbg << "version " << (unsigned int)er9xGeneral.myVers << " "; - - switch(er9xGeneral.myVers) { - case 3: - dbg << "(old gruvin9x) "; - case 4: -// case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - break; - default: - dbg << "not er9x"; - errors.set(NOT_ER9X); - return errors.to_ulong(); - } - - efile->openRd(FILE_GENERAL); - if (!efile->readRlc1((uint8_t*)&er9xGeneral, sizeof(Er9xGeneral))) { - dbg << "ko"; - errors.set(UNKNOWN_ERROR); - return errors.to_ulong(); - - } - radioData.generalSettings = er9xGeneral; - - for (int i=0; iopenRd(FILE_MODEL(i)); - if (!efile->readRlc1((uint8_t*)&er9xModel, sizeof(Er9xModelData))) { - radioData.models[i].clear(); - } - else { - applyStickModeToModel(er9xModel, radioData.generalSettings.stickMode+1); - radioData.models[i] = er9xModel; - } - } - - dbg << "ok"; - errors.set(ALL_OK); - return errors.to_ulong(); -} - -unsigned long Er9xInterface::loadBackup(RadioData &radioData, const uint8_t *eeprom, int esize, int index) -{ - std::bitset errors; - errors.set(UNKNOWN_ERROR); - return errors.to_ulong(); -} - -int Er9xInterface::getSize(const ModelData &model) -{ - return 0; -} - -int Er9xInterface::getSize(const GeneralSettings &settings) -{ - return 0; -} - -bool Er9xInterface::isAvailable(PulsesProtocol prot, int port) -{ - switch (prot) { - case PULSES_PPM: - case PULSES_DSM2: - case PULSES_PXX_DJT: - case PULSES_PPM16: - return 1; - default: - return 0; - } -} - -void Er9xInterface::appendTextElement(QDomDocument * qdoc, QDomElement * pe, QString name, QString value) -{ - QDomElement e = qdoc->createElement(name); - QDomText t = qdoc->createTextNode(name); - t.setNodeValue(value); - e.appendChild(t); - pe->appendChild(e); -} - -void Er9xInterface::appendNumberElement(QDomDocument * qdoc, QDomElement * pe,QString name, int value, bool forceZeroWrite) -{ - if(value || forceZeroWrite) { - QDomElement e = qdoc->createElement(name); - QDomText t = qdoc->createTextNode(name); - t.setNodeValue(QString("%1").arg(value)); - e.appendChild(t); - pe->appendChild(e); - } -} - -void Er9xInterface::appendCDATAElement(QDomDocument * qdoc, QDomElement * pe,QString name, const char * data, int size) -{ - QDomElement e = qdoc->createElement(name); - QDomCDATASection t = qdoc->createCDATASection(name); - t.setData(QByteArray(data, size).toBase64()); - e.appendChild(t); - pe->appendChild(e); -} - -QDomElement Er9xInterface::getGeneralDataXML(QDomDocument * qdoc, Er9xGeneral * tgen) -{ - QDomElement gd = qdoc->createElement("GENERAL_DATA"); - appendNumberElement(qdoc, &gd, "Version", tgen->myVers, true); // have to write value here - appendTextElement(qdoc, &gd, "Owner", QString::fromLatin1(tgen->ownerName,sizeof(tgen->ownerName)).trimmed()); - appendCDATAElement(qdoc, &gd, "Data", (const char *)tgen,sizeof(Er9xGeneral)); - return gd; -} - -QDomElement Er9xInterface::getModelDataXML(QDomDocument * qdoc, Er9xModelData * tmod, int modelNum, int mdver) -{ - QDomElement md = qdoc->createElement("MODEL_DATA"); - md.setAttribute("number", modelNum); - appendNumberElement(qdoc, &md, "Version", mdver, true); // have to write value here - appendTextElement(qdoc, &md, "Name", QString::fromLatin1(tmod->name,sizeof(tmod->name)).trimmed()); - appendCDATAElement(qdoc, &md, "Data", (const char *)tmod,sizeof(Er9xModelData)); - return md; -} - -bool Er9xInterface::loadRadioSettingsDataXML(QDomDocument * qdoc, Er9xGeneral * tgen) -{ - // look for "GENERAL_DATA" tag - QDomElement gde = qdoc->elementsByTagName("GENERAL_DATA").at(0).toElement(); - - if(gde.isNull()) // couldn't find - return false; - - // load cdata into tgen - QDomNode n = gde.elementsByTagName("Data").at(0).firstChild();// get all children in Data - while (!n.isNull()) { - if (n.isCDATASection()) { - QString ds = n.toCDATASection().data(); - QByteArray ba = QByteArray::fromBase64(ds.toLatin1()); - const char * data = ba.data(); - memcpy(tgen, data, sizeof(Er9xGeneral)); - break; - } - n = n.nextSibling(); - } - // check version? - return true; -} - -bool Er9xInterface::loadModelDataXML(QDomDocument * qdoc, Er9xModelData * tmod, int modelNum) -{ - // look for MODEL_DATA with modelNum attribute. - // if modelNum = -1 then just pick the first one - QDomNodeList ndl = qdoc->elementsByTagName("MODEL_DATA"); - - // cycle through nodes to find correct model number - QDomNode k = ndl.at(0); - if(modelNum>=0) { - while(!k.isNull()) { - int a = k.toElement().attribute("number").toInt(); - if(a==modelNum) - break; - k = k.nextSibling(); - } - } - - if (k.isNull()) // couldn't find - return false; - - - // load cdata into tgen - QDomNode n = k.toElement().elementsByTagName("Data").at(0).firstChild();// get all children in Data - while (!n.isNull()) { - if (n.isCDATASection()) { - QString ds = n.toCDATASection().data(); - QByteArray ba = QByteArray::fromBase64(ds.toLatin1()); - const char * data = ba.data(); - memcpy(tmod, data, sizeof(Er9xModelData)); - break; - } - n = n.nextSibling(); - } - // check version? - return true; -} - -int Er9xInterface::getCapability(Capability capability) -{ - switch (capability) { - case Models: - return 16; - default: - return 0; - } -} - -QString Er9xInterface::getCapabilityStr(Capability capability) -{ - return QString(); -} diff --git a/companion/src/firmwares/er9x/er9xinterface.h b/companion/src/firmwares/er9x/er9xinterface.h deleted file mode 100644 index cbebf4087..000000000 --- a/companion/src/firmwares/er9x/er9xinterface.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) EdgeTX - * - * Based on code named - * opentx - https://github.com/opentx/opentx - * th9x - http://code.google.com/p/th9x - * er9x - http://code.google.com/p/er9x - * gruvin9x - http://code.google.com/p/gruvin9x - * - * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef _ER9XINTERFACE_H_ -#define _ER9XINTERFACE_H_ - -#include -#include "eeprominterface.h" -#include "er9xeeprom.h" - -class RleFile; - -class Er9xInterface : public EEPROMInterface -{ - public: - - Er9xInterface(); - - virtual ~Er9xInterface(); - - virtual const char * getName(); - - virtual unsigned long load(RadioData &, const uint8_t * eeprom, int size); - - virtual unsigned long loadBackup(RadioData &, const uint8_t * eeprom, int esize, int index); - - virtual unsigned long loadxml(RadioData &radioData, QDomDocument &doc); - - virtual int save(uint8_t * eeprom, const RadioData & radioData, uint8_t version=0, uint32_t variant=0) - { - return 0; - } - - virtual int getSize(const ModelData &); - - virtual int getSize(const GeneralSettings &settings); - - virtual bool isAvailable(PulsesProtocol proto, int port=0); - - virtual int getCapability(Capability capability); - - virtual QString getCapabilityStr(Capability); - - protected: - - RleFile * efile; - - private: - void appendTextElement(QDomDocument * qdoc, QDomElement * pe, QString name, QString value); - - void appendNumberElement(QDomDocument * qdoc, QDomElement * pe,QString name, int value, bool forceZeroWrite = false); - - void appendCDATAElement(QDomDocument * qdoc, QDomElement * pe,QString name, const char * data, int size); - - QDomElement getGeneralDataXML(QDomDocument * qdoc, Er9xGeneral * tgen); //parse out data to XML format - - QDomElement getModelDataXML(QDomDocument * qdoc, Er9xModelData * tmod, int modelNum, int mdver); //parse out data to XML format - - bool loadRadioSettingsDataXML(QDomDocument * qdoc, Er9xGeneral * tgen); // get data from XML - - bool loadModelDataXML(QDomDocument * qdoc, Er9xModelData * tmod, int modelNum = -1); // get data from XML - -}; - -#endif // _ER9XINTERFACE_H_ diff --git a/companion/src/firmwares/ersky9x/ersky9xeeprom.cpp b/companion/src/firmwares/ersky9x/ersky9xeeprom.cpp deleted file mode 100644 index a37a842a9..000000000 --- a/companion/src/firmwares/ersky9x/ersky9xeeprom.cpp +++ /dev/null @@ -1,731 +0,0 @@ -/* - * Copyright (C) EdgeTX - * - * Based on code named - * opentx - https://github.com/opentx/opentx - * th9x - http://code.google.com/p/th9x - * er9x - http://code.google.com/p/er9x - * gruvin9x - http://code.google.com/p/gruvin9x - * - * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include "helpers.h" -#include "ersky9xeeprom.h" -#include - -extern RawSwitch er9xToSwitch(int8_t sw); - -RawSwitch getErSky9xTimerMode(int mode) -{ - if (mode<4) - return RawSwitch(SWITCH_TYPE_TIMER_MODE, mode); - else - return RawSwitch(); -} - -RawSwitch ersky9xToSwitch(int8_t sw) -{ - uint8_t swa = abs(sw); - if (swa == 0) - return RawSwitch(SWITCH_TYPE_NONE); - else if (swa <= 9) - return RawSwitch(SWITCH_TYPE_SWITCH, sw); - else if (swa <= 33) - return RawSwitch(SWITCH_TYPE_VIRTUAL, sw > 0 ? sw-9 : sw+9); - else if (sw == 34) - return RawSwitch(SWITCH_TYPE_ON); - else if (sw == -34) - return RawSwitch(SWITCH_TYPE_OFF); - else if (swa <= 34+9) - return RawSwitch(SWITCH_TYPE_SWITCH, sw > 0 ? sw-34 : sw+34); - else - return RawSwitch(SWITCH_TYPE_VIRTUAL, sw > 0 ? sw-34-9 : sw+34+9); -} - -t_Ersky9xTrainerMix::t_Ersky9xTrainerMix() -{ - memset(reinterpret_cast(this), 0, sizeof(t_Ersky9xTrainerMix)); -} - -t_Ersky9xTrainerMix::operator TrainerMix() -{ - TrainerMix c9x; - c9x.src = srcChn; - c9x.swtch = er9xToSwitch(swtch); - c9x.weight = (25 * studWeight) / 8; - c9x.mode = mode; - return c9x; -} - -t_Ersky9xTrainerData::t_Ersky9xTrainerData() -{ - memset(reinterpret_cast(this), 0, sizeof(t_Ersky9xTrainerData)); -} - -t_Ersky9xTrainerData::operator TrainerData () -{ - TrainerData c9x; - for (int i=0; i(this), 0, sizeof(t_Ersky9xGeneral)); -} - -Ersky9xGeneral::operator GeneralSettings () -{ - GeneralSettings result; - - result.version = myVers; - - for (int i=0; i(this), 0, sizeof(t_Ersky9xLimitData)); -} - -t_Ersky9xLimitData::operator LimitData () -{ - LimitData c9x; - c9x.min = 10*(min-100); - c9x.max = 10*(max+100); - c9x.revert = revert; - c9x.offset = offset; - return c9x; -} - -t_Ersky9xMixData_v10::t_Ersky9xMixData_v10() -{ - memset(reinterpret_cast(this), 0, sizeof(t_Ersky9xMixData_v10)); -} - -t_Ersky9xMixData_v10::operator MixData () -{ - MixData c9x; - c9x.destCh = destCh; - c9x.weight = weight; - c9x.swtch = er9xToSwitch(swtch); - - if (srcRaw == 0) { - c9x.srcRaw = RawSource(SOURCE_TYPE_NONE); - } - else if (srcRaw <= 7) { - c9x.srcRaw = RawSource(SOURCE_TYPE_INPUT, srcRaw-1); - } - else if (srcRaw == 8) { - c9x.srcRaw = RawSource(SOURCE_TYPE_MAX); - } - else if (srcRaw == 9) { - if (swtch < 0) { - c9x.srcRaw = RawSource(SOURCE_TYPE_SWITCH, swtch < -3 ? -swtch-3 : -swtch); - c9x.weight = -weight; - } - else if (swtch > 0) { - c9x.srcRaw = RawSource(SOURCE_TYPE_SWITCH, swtch > 3 ? swtch-3 : swtch); - } - else { - c9x.srcRaw = RawSource(SOURCE_TYPE_MAX); - } - if (mltpx != MLTPX_REP) - c9x.swtch = RawSwitch(SWITCH_TYPE_NONE); - } - else if (srcRaw == 37) { - c9x.srcRaw = RawSource(SOURCE_TYPE_SWITCH, 0); - } - else if (srcRaw <= 12) { - c9x.srcRaw = RawSource(SOURCE_TYPE_CYC, srcRaw-10); - } - else if (srcRaw <= 20) { - c9x.srcRaw = RawSource(SOURCE_TYPE_PPM, srcRaw-13); - } - else { - c9x.srcRaw = RawSource(SOURCE_TYPE_CH, srcRaw-21); - } - - if (curve > 6) { - c9x.curve.type = CurveReference::CURVE_REF_CUSTOM; - c9x.curve.value = curve - 6; - } - else if (curve > 0) { - c9x.curve.type = CurveReference::CURVE_REF_FUNC; - c9x.curve.value = curve; - } - - c9x.delayUp = delayUp; - c9x.delayDown = delayDown; - c9x.speedUp = speedUp; - c9x.speedDown = speedDown; - c9x.carryTrim = carryTrim; - c9x.mltpx = (MltpxValue)mltpx; - c9x.mixWarn = mixWarn; - // c9x.enableFmTrim=enableFmTrim; - c9x.sOffset = sOffset; - return c9x; -} - - -t_Ersky9xMixData_v11::t_Ersky9xMixData_v11() -{ - memset(reinterpret_cast(this), 0, sizeof(t_Ersky9xMixData_v11)); -} - -t_Ersky9xMixData_v11::operator MixData () -{ - MixData c9x; - c9x.destCh = destCh; - c9x.weight = weight; - c9x.swtch = ersky9xToSwitch(swtch); - - if (srcRaw == 0) { - c9x.srcRaw = RawSource(SOURCE_TYPE_NONE); - } - else if (srcRaw <= 7) { - c9x.srcRaw = RawSource(SOURCE_TYPE_INPUT, srcRaw-1); - } - else if (srcRaw == 8) { - c9x.srcRaw = RawSource(SOURCE_TYPE_MAX); - } - else if (srcRaw == 9) { - if (swtch < 0) { - c9x.srcRaw = RawSource(SOURCE_TYPE_SWITCH, swtch < -3 ? -swtch-3 : -swtch); - c9x.weight = -weight; - } - else if (swtch > 0) { - c9x.srcRaw = RawSource(SOURCE_TYPE_SWITCH, swtch > 3 ? swtch-3 : swtch); - } - else { - c9x.srcRaw = RawSource(SOURCE_TYPE_MAX); - } - if (mltpx != MLTPX_REP) - c9x.swtch = RawSwitch(SWITCH_TYPE_NONE); - } - else if (srcRaw == 45) { - c9x.srcRaw = RawSource(SOURCE_TYPE_SWITCH, 0); - } - else if (srcRaw > 45) { - c9x.srcRaw = RawSource(SOURCE_TYPE_GVAR, srcRaw-46); - } - else if (srcRaw <= 12) { - c9x.srcRaw = RawSource(SOURCE_TYPE_CYC, srcRaw-10); - } - else if (srcRaw <= 20) { - c9x.srcRaw = RawSource(SOURCE_TYPE_PPM, srcRaw-13); - } - else { - c9x.srcRaw = RawSource(SOURCE_TYPE_CH, srcRaw-21); - } - - if (curve > 6) { - c9x.curve.type = CurveReference::CURVE_REF_CUSTOM; - c9x.curve.value = curve - 6; - } - else if (curve > 0) { - c9x.curve.type = CurveReference::CURVE_REF_FUNC; - c9x.curve.value = curve; - } - - c9x.delayUp = delayUp; - c9x.delayDown = delayDown; - c9x.speedUp = speedUp; - c9x.speedDown = speedDown; - c9x.carryTrim = carryTrim; - c9x.mltpx = (MltpxValue)mltpx; - c9x.mixWarn = mixWarn; - // c9x.enableFmTrim=enableFmTrim; - c9x.sOffset = sOffset; - return c9x; -} - -RawSource ersky9xToSource_v10(int8_t value) -{ - if (value == 0) { - return RawSource(SOURCE_TYPE_NONE); - } - else if (value <= 7) { - return RawSource(SOURCE_TYPE_INPUT, value - 1); - } - else if (value == 8) { - return RawSource(SOURCE_TYPE_MAX); - } - else if (value == 9) { - return RawSource(SOURCE_TYPE_MAX); - } - else if (value <= 12) { - return RawSource(SOURCE_TYPE_CYC, value-10); - } - else if (value <= 20) { - return RawSource(SOURCE_TYPE_PPM, value-13); - } - else if (value <= 36) { - return RawSource(SOURCE_TYPE_CH, value-21); - } - else { - return RawSource(SOURCE_TYPE_TELEMETRY, value-36); - } -} - -RawSource ersky9xToSource_v11(int8_t value) -{ - if (value == 0) { - return RawSource(SOURCE_TYPE_NONE); - } - else if (value <= 7) { - return RawSource(SOURCE_TYPE_INPUT, value - 1); - } - else if (value == 8) { - return RawSource(SOURCE_TYPE_MAX); - } - else if (value == 9) { - return RawSource(SOURCE_TYPE_MAX); - } - else if (value <= 12) { - return RawSource(SOURCE_TYPE_CYC, value-10); - } - else if (value <= 20) { - return RawSource(SOURCE_TYPE_PPM, value-13); - } - else if (value <= 36) { - return RawSource(SOURCE_TYPE_CH, value-21); - } - else { - return RawSource(SOURCE_TYPE_TELEMETRY, value-36); - } -} - -Ersky9xLogicalSwitchData_v10::operator LogicalSwitchData () -{ - LogicalSwitchData c9x; - c9x.func = func; - c9x.val1 = v1; - c9x.val2 = v2; - - if ((c9x.func >= LS_FN_VPOS && c9x.func <= LS_FN_ANEG) || c9x.func >= LS_FN_EQUAL) { - c9x.val1 = ersky9xToSource_v10(v1).toValue(); - } - - if (c9x.func >= LS_FN_EQUAL) { - c9x.val2 = ersky9xToSource_v10(v2).toValue(); - } - - if (c9x.func >= LS_FN_AND && c9x.func <= LS_FN_XOR) { - c9x.val1 = er9xToSwitch(v1).toValue(); - c9x.val2 = er9xToSwitch(v2).toValue(); - } - - return c9x; -} - -Ersky9xLogicalSwitchData_v11::operator LogicalSwitchData () -{ - LogicalSwitchData c9x; - c9x.func = func; - c9x.val1 = v1; - c9x.val2 = v2; - - if ((c9x.func >= LS_FN_VPOS && c9x.func <= LS_FN_ANEG) || c9x.func >= LS_FN_EQUAL) { - c9x.val1 = ersky9xToSource_v11(v1).toValue(); - } - - if (c9x.func >= LS_FN_EQUAL) { - c9x.val2 = ersky9xToSource_v11(v2).toValue(); - } - - if (c9x.func >= LS_FN_AND && c9x.func <= LS_FN_XOR) { - c9x.val1 = er9xToSwitch(v1).toValue(); - c9x.val2 = er9xToSwitch(v2).toValue(); - } - - return c9x; -} - -t_Ersky9xSafetySwData_v10::t_Ersky9xSafetySwData_v10() -{ - memset(reinterpret_cast(this), 0, sizeof(t_Ersky9xSafetySwData_v10)); -} - -t_Ersky9xSafetySwData_v11::t_Ersky9xSafetySwData_v11() -{ - memset(reinterpret_cast(this), 0, sizeof(t_Ersky9xSafetySwData_v11)); -} - -t_Ersky9xFrSkyChannelData_v10::t_Ersky9xFrSkyChannelData_v10() -{ - memset(reinterpret_cast(this), 0, sizeof(t_Ersky9xFrSkyChannelData_v10)); -} - -t_Ersky9xFrSkyChannelData_v10::operator FrSkyChannelData () -{ - FrSkyChannelData c9x; - c9x.ratio = ratio; - c9x.alarms[0].value = alarms_value[0]; - c9x.alarms[0].level = alarms_level & 3; - c9x.alarms[0].greater = alarms_greater & 1; - c9x.alarms[1].value = alarms_value[1]; - c9x.alarms[1].level = (alarms_level >> 2) & 3; - c9x.alarms[1].greater = (alarms_greater >> 1) & 1; - if (type==2) { - c9x.type = 0; - c9x.multiplier=1; - } else { - c9x.type = type; - } - return c9x; -} - -t_Ersky9xFrSkyChannelData_v11::t_Ersky9xFrSkyChannelData_v11() -{ - memset(reinterpret_cast(this), 0, sizeof(t_Ersky9xFrSkyChannelData_v11)); -} - -t_Ersky9xFrSkyChannelData_v11::operator FrSkyChannelData () -{ - FrSkyChannelData c9x; - c9x.ratio = ratio; - c9x.alarms[0].value = alarms_value[0]; - c9x.alarms[0].level = alarms_level & 3; - c9x.alarms[0].greater = alarms_greater & 1; - c9x.alarms[1].value = alarms_value[1]; - c9x.alarms[1].level = (alarms_level >> 2) & 3; - c9x.alarms[1].greater = (alarms_greater >> 1) & 1; - if (type==2) { - c9x.type = 0; - c9x.multiplier=1; - } else { - c9x.type = type; - } - return c9x; -} - -t_Ersky9xFrSkyData_v10::t_Ersky9xFrSkyData_v10() -{ - memset(reinterpret_cast(this), 0, sizeof(t_Ersky9xFrSkyData_v10)); -} - -t_Ersky9xFrSkyData_v10::operator FrSkyData () -{ - FrSkyData c9x; - c9x.channels[0] = channels[0]; - c9x.channels[1] = channels[1]; - return c9x; -} - -t_Ersky9xFrSkyData_v11::t_Ersky9xFrSkyData_v11() -{ - memset(reinterpret_cast(this), 0, sizeof(t_Ersky9xFrSkyData_v11)); -} - -t_Ersky9xFrSkyData_v11::operator FrSkyData () -{ - FrSkyData c9x; - c9x.channels[0] = channels[0]; - c9x.channels[1] = channels[1]; - return c9x; -} - -t_Ersky9xModelData_v10::operator ModelData () -{ - ModelData c9x; - c9x.used = true; - getEEPROMString(c9x.name, name, sizeof(name)); - for (int i=0; i<2; i++) { - c9x.timers[i].mode = timer[i].tmrModeA < 4 ? timer[i].tmrModeA : 0; - c9x.timers[i].val = timer[i].tmrVal; - } - switch(protocol) { - case 1: - c9x.moduleData[0].protocol = PULSES_PXX_DJT; - break; - case 2: - c9x.moduleData[0].protocol = PULSES_DSM2; - break; - case 3: - c9x.moduleData[0].protocol = PULSES_PPM16; - break; - default: - c9x.moduleData[0].protocol = PULSES_PPM; - break; - } - c9x.moduleData[0].ppm.frameLength=ppmFrameLength; - c9x.moduleData[0].channelsCount = 8 + 2 * ppmNCH; - c9x.thrTrim = thrTrim; - c9x.trimInc = trimInc-2; - c9x.moduleData[0].ppm.delay = 300 + 50 * ppmDelay; - c9x.customFn[0].func = FuncInstantTrim; - if (trimSw) { - c9x.customFn[0].swtch = er9xToSwitch(trimSw); - } - c9x.beepANACenter = beepANACenter; - c9x.moduleData[0].ppm.pulsePol = pulsePol; - c9x.extendedLimits = extendedLimits; - c9x.swashRingData.elevatorWeight = swashInvertELE ? -100 : 100; - c9x.swashRingData.aileronWeight = swashInvertAIL ? -100 : 100; - c9x.swashRingData.collectiveWeight = swashInvertCOL ? -100 : 100; - c9x.swashRingData.type = swashType; - c9x.swashRingData.collectiveSource = ersky9xToSource_v10(swashCollectiveSource); - c9x.swashRingData.value = swashRingValue; - for (int i=0; i -#include "eeprominterface.h" - -extern RawSwitch getEr9xTimerMode(int mode); - -//eeprom data -#define ERSKY9X_MAX_MIXERS_V10 32 -#define ERSKY9X_MAX_MIXERS_V11 48 -#define ERSKY9X_MAX_CURVE5 8 -#define ERSKY9X_MAX_CURVE9 8 -#define ERSKY9X_MAX_CSFUNC 13 - -#define ERSKY9X_MDVERS10 10 -#define ERSKY9X_MDVERS11 11 - -#define ERSKY9X_GENERAL_OWNER_NAME_LEN 10 -#define ERSKY9X_NUM_CHNOUT_V10 16 //number of real outputchannels CH1-CH8 -#define ERSKY9X_NUM_CHNOUT_V11 24 //number of real outputchannels CH1-CH8 -#define ERSKY9X_NUM_CSW_V10 12 //number of custom switches -#define ERSKY9X_NUM_CSW_V11 24 -#define ERSKY9X_NUM_FSW 16 -#define ERSKY9X_NUM_VOICE 8 -#define ERSKY9X_MAX_GVARS 7 - -#define CPN_MAX_STICKSnPOTS 7 //number of sticks and pots - -PACK(typedef struct t_Ersky9xTrainerMix { - uint8_t srcChn:3; //0-7 = ch1-8 - int8_t swtch:5; - int8_t studWeight:6; - uint8_t mode:2; // off, add-mode, subst-mode - - operator TrainerMix(); - t_Ersky9xTrainerMix(); -}) Ersky9xTrainerMix; // - -PACK(typedef struct t_Ersky9xTrainerData { - int16_t calib[4]; - Ersky9xTrainerMix mix[4]; - - operator TrainerData(); - t_Ersky9xTrainerData(); -}) Ersky9xTrainerData; - -PACK(typedef struct t_Ersky9xGeneral { - uint8_t myVers; - int16_t calibMid[CPN_MAX_STICKSnPOTS]; - int16_t calibSpanNeg[CPN_MAX_STICKSnPOTS]; - int16_t calibSpanPos[CPN_MAX_STICKSnPOTS]; - uint16_t chkSum; - uint8_t currModel; //0..15 - uint8_t contrast; - uint8_t vBatWarn; - int8_t txVoltageCalibration; - int8_t lightSw; - Ersky9xTrainerData trainer; - uint8_t view; - uint8_t disableThrottleWarning:1; - uint8_t disableSwitchWarning:1; - uint8_t disableMemoryWarning:1; - uint8_t beeperVal:3; - uint8_t reserveWarning:1; - uint8_t disableAlarmWarning:1; - uint8_t stickMode; - int8_t inactivityTimer; - uint8_t throttleReversed:1; - uint8_t minuteBeep:1; - uint8_t preBeep:1; - uint8_t alarmsFlash:1; - uint8_t disableSplashScreen:1; - uint8_t disablePotScroll:1; - uint8_t disableBG:1; - uint8_t res1:1; - uint8_t filterInput; - uint8_t lightAutoOff; - uint8_t templateSetup; //RETA order according to chout_ar array - int8_t PPM_Multiplier; - uint8_t FRSkyYellow:4; - uint8_t FRSkyOrange:4; - uint8_t FRSkyRed:4; //mike please check these are correct - uint8_t hideNameOnSplash:1; - uint8_t optrexDisplay:1; - uint8_t spare:2; - uint8_t speakerPitch; - uint8_t hapticStrength; - uint8_t speakerMode; - uint8_t lightOnStickMove; - - char ownerName[10]; - uint8_t switchWarningStates; - uint8_t volume ; - uint8_t bright ; // backlight - uint8_t stickGain; - uint8_t mAh_alarm ; - uint16_t mAh_used ; - uint16_t run_time ; - int8_t current_calib ; - uint8_t bt_baudrate ; - uint8_t rotaryDivisor ; - operator GeneralSettings(); - t_Ersky9xGeneral(); -}) Ersky9xGeneral; - -PACK(typedef struct t_Ersky9xExpoData { - int8_t expo[3][2][2]; - int8_t drSw1; - int8_t drSw2; - - t_Ersky9xExpoData() { memset(reinterpret_cast(this), 0, sizeof(t_Ersky9xExpoData)); } -}) Ersky9xExpoData; - - -PACK(typedef struct t_Ersky9xLimitData { - int8_t min; - int8_t max; - bool revert; - int16_t offset; - - operator LimitData(); - t_Ersky9xLimitData() ; -}) Ersky9xLimitData; - -#define MLTPX_ADD 0 -#define MLTPX_MUL 1 -#define MLTPX_REP 2 - -PACK(typedef struct t_Ersky9xMixData_v10 { - uint8_t destCh; // 1..CPN_MAX_CHNOUT - uint8_t srcRaw; // - int8_t weight; - int8_t swtch; - uint8_t curve; //0=symmetrisch 1=no neg 2=no pos - uint8_t delayUp:4; - uint8_t delayDown:4; - uint8_t speedUp:4; // Servogeschwindigkeit aus Tabelle (10ms Cycle) - uint8_t speedDown:4; // 0 nichts - uint8_t carryTrim:1; - uint8_t mltpx:3; // multiplex method 0=+ 1=* 2=replace - uint8_t mixWarn:2; // mixer warning - uint8_t enableFmTrim:1; - uint8_t mixres:1; - int8_t sOffset; - int8_t res; - - operator MixData(); - t_Ersky9xMixData_v10(); -}) Ersky9xMixData_v10; - -PACK(typedef struct t_Ersky9xMixData_v11 { - uint8_t destCh; // 1..CPN_MAX_CHNOUT - uint8_t srcRaw; // - int8_t weight; - int8_t swtch; - uint8_t curve; //0=symmetrisch 1=no neg 2=no pos - uint8_t delayUp; - uint8_t delayDown; - uint8_t speedUp; // Servogeschwindigkeit aus Tabelle (10ms Cycle) - uint8_t speedDown; // 0 nichts - uint8_t carryTrim:1; - uint8_t mltpx:3; // multiplex method 0=+ 1=* 2=replace - uint8_t mixWarn:2; // mixer warning - uint8_t enableFmTrim:1; - uint8_t mixres:1; - int8_t sOffset; - uint8_t res[4]; - operator MixData(); - t_Ersky9xMixData_v11(); -}) Ersky9xMixData_v11; - -PACK(typedef struct t_Ersky9xLogicalSwitchData_v10 { // Custom Switches data - int8_t v1; //input - int8_t v2; //offset - uint8_t func; - - operator LogicalSwitchData(); - t_Ersky9xLogicalSwitchData_v10() { memset(reinterpret_cast(this), 0, sizeof(t_Ersky9xLogicalSwitchData_v10)); } -}) Ersky9xLogicalSwitchData_v10; - -PACK(typedef struct t_Ersky9xLogicalSwitchData_v11 { // Custom Switches data - int8_t v1; //input - int8_t v2; //offset - uint8_t func; - uint8_t andsw; - uint8_t res ; - - operator LogicalSwitchData(); - t_Ersky9xLogicalSwitchData_v11() { memset(reinterpret_cast(this), 0, sizeof(t_Ersky9xLogicalSwitchData_v11)); } -}) Ersky9xLogicalSwitchData_v11; - -PACK(typedef struct t_Ersky9xSafetySwData_v10 { // Custom Switches data - int8_t swtch; - int8_t val; - - t_Ersky9xSafetySwData_v10(); -}) Ersky9xSafetySwData_v10; - -PACK(typedef struct t_Ersky9xSafetySwData_v11 { // Custom Switches data - union opt { - struct ss { - int8_t swtch ; - uint8_t mode ; - int8_t val ; - uint8_t res ; - } ss ; - struct vs { - uint8_t vswtch ; - uint8_t vmode ; // ON, OFF, BOTH, 15Secs, 30Secs, 60Secs, Varibl - uint8_t vval; - uint8_t vres ; - } vs ; - } opt ; - - t_Ersky9xSafetySwData_v11(); -}) Ersky9xSafetySwData_v11; - -PACK(typedef struct t_Ersky9xgvar { - int8_t gvar ; - uint8_t gvsource ; -// int8_t gvswitch ; -}) Ersky9xGvarData ; - -PACK(typedef struct t_Ersky9xFlightModeData { - int16_t trim[4]; // -500..500 => trim value, 501 => use trim of phase 0, 502, 503, 504 => use trim of phases 1|2|3|4 instead - int8_t swtch; // swtch of phase[0] is not used - char name[6]; - uint8_t fadeIn:4; - uint8_t fadeOut:4; - uint16_t spare ; // Future expansion -}) Ersky9xFlightModeData; - -PACK(typedef struct t_Ersky9xCustomFunctionData { // Function Switches data - int8_t swtch; //input - uint8_t func; - char param[6]; - uint8_t delay; - uint8_t spare; -}) Ersky9xCustomFunctionData; - -PACK(typedef struct t_Ersky9xFrSkyChannelData_v10 { - uint8_t ratio; // 0.0 means not used, 0.1V steps EG. 6.6 Volts = 66. 25.1V = 251, etc. - uint8_t alarms_value[2]; // 0.1V steps EG. 6.6 Volts = 66. 25.1V = 251, etc. - uint8_t alarms_level:4; - uint8_t alarms_greater:2; // 0=LT(<), 1=GT(>) - uint8_t type:2; // future use: 0=volts, ... - - operator FrSkyChannelData(); - t_Ersky9xFrSkyChannelData_v10(); -}) Ersky9xFrSkyChannelData_v10; - -PACK(typedef struct t_Ersky9xFrSkyData_v10 { - Ersky9xFrSkyChannelData_v10 channels[2]; - - operator FrSkyData(); - t_Ersky9xFrSkyData_v10(); -}) Ersky9xFrSkyData_v10; - -PACK(typedef struct t_Ersky9xFrSkyChannelData_v11 { - uint8_t ratio ; // 0.0 means not used, 0.1V steps EG. 6.6 Volts = 66. 25.1V = 251, etc. - uint8_t offset ; // - uint8_t gain ; // - uint8_t alarms_value[2] ; // 0.1V steps EG. 6.6 Volts = 66. 25.1V = 251, etc. - uint8_t alarms_level ; - uint8_t alarms_greater ; // 0=LT(<), 1=GT(>) - uint8_t type ; // 0=volts, 1=raw, 2=volts*2, 3=Amps - - operator FrSkyChannelData(); - t_Ersky9xFrSkyChannelData_v11(); -}) Ersky9xFrSkyChannelData_v11; - -PACK(typedef struct t_Ersky9xFrSkyData_v11 { - Ersky9xFrSkyChannelData_v11 channels[2]; - - operator FrSkyData(); - t_Ersky9xFrSkyData_v11(); -}) Ersky9xFrSkyData_v11; - -PACK(typedef struct t_Ersky9xFrSkyalarms_v11 { - uint8_t frskyAlarmType ; - uint8_t frskyAlarmLimit ; - uint8_t frskyAlarmSound ; -}) Ersky9xFrSkyAlData_v11; - -PACK(typedef struct t_Ersky9xFrSkyAlarmData_v11 { - Ersky9xFrSkyAlData_v11 alarmData[8] ; -}) Ersky9xFrSkyAlarmData_v11; - -PACK(typedef struct t_Ersky9xTimerMode_v10 { - uint8_t tmrModeA:7 ; // timer trigger source -> off, abs, stk, stk%, cx% - uint8_t tmrDir:1 ; // Timer direction - int8_t tmrModeB ; // timer trigger source -> !sw, none, sw, m_sw - uint16_t tmrVal ; -}) Ersky9xTimerMode_v10; - -PACK(typedef struct t_Ersky9xTimerMode_v11 { - uint8_t tmrModeA:7 ; // timer trigger source -> off, abs, stk, stk%, cx% - uint8_t tmrDir:1 ; // Timer direction - int8_t tmrModeB ; // timer trigger source -> !sw, none, sw, m_sw - uint16_t tmrVal ; -}) Ersky9xTimerMode_v11; - -PACK(typedef struct te_Ersky9xswVoice { - uint8_t swtch ; - uint8_t mode ; // ON, OFF, BOTH, 15Secs, 30Secs, 60Secs - uint8_t val ; - uint8_t vres ; -}) Ersky9xvoiceSwData ; - -PACK(typedef struct t_Ersky9xModelData_v10 { - char name[10]; // 10 must be first for eeLoadModelName - uint8_t reserved_spare; //used to be MDVERS - now depreciated - int8_t spare21; // was timer trigger source -> off, abs, stk, stk%, sw/!sw, !m_sw/!m_sw - // uint8_t sparex:1; // was tmrDir, now use tmrVal>0 => count down - uint8_t sparex:1; // was tmrDir, now use tmrVal>0 => count down - // uint8_t tmrDir:1; // was tmrDir, now use tmrVal>0 => count down - uint8_t traineron:1; // 0 disable trainer, 1 allow trainer - uint8_t spare22:1 ; // Start timer2 using throttle - uint8_t FrSkyUsrProto:1 ; // Protocol in FrSky User Data, 0=FrSky Hub, 1=WS HowHigh - uint8_t FrSkyGpsAlt:1 ; // Use Gps Altitude as main altitude reading - uint8_t FrSkyImperial:1 ; // Convert FrSky values to imperial units - uint8_t FrSkyAltAlarm:2; - uint16_t spare_u16 ; // Was timerval - uint8_t protocol; - int8_t ppmNCH; - int8_t thrTrim:4; // Enable Throttle Trim - int8_t thrExpo:4; // Enable Throttle Expo - int8_t trimInc; // Trim Increments - int8_t ppmDelay; - int8_t trimSw; - uint8_t beepANACenter; // 1<<0->A1.. 1<<6->A7 - uint8_t pulsePol:1; - uint8_t extendedLimits:1; - uint8_t swashInvertELE:1; - uint8_t swashInvertAIL:1; - uint8_t swashInvertCOL:1; - uint8_t swashType:3; - uint8_t swashCollectiveSource; - uint8_t swashRingValue; - int8_t ppmFrameLength; //0=22.5 (10msec-30msec) 0.5msec increments - Ersky9xMixData_v10 mixData[ERSKY9X_MAX_MIXERS_V10]; - Ersky9xLimitData limitData[ERSKY9X_NUM_CHNOUT_V10]; - Ersky9xExpoData expoData[4]; - int8_t trim[4]; - int8_t curves5[ERSKY9X_MAX_CURVE5][5]; - int8_t curves9[ERSKY9X_MAX_CURVE9][9]; - Ersky9xLogicalSwitchData_v10 logicalSw[ERSKY9X_NUM_CSW_V10]; - uint8_t frSkyVoltThreshold ; - uint8_t res3[2]; - Ersky9xSafetySwData_v10 safetySw[ERSKY9X_NUM_CHNOUT_V10]; - Ersky9xFrSkyData_v10 frsky; - Ersky9xTimerMode_v10 timer[2] ; - operator ModelData(); - t_Ersky9xModelData_v10() { memset(reinterpret_cast(this), 0, sizeof(t_Ersky9xModelData_v10)); } -}) Ersky9xModelData_v10; - -PACK(typedef struct t_Ersky9xModelData_v11 { - char name[10]; // 10 must be first for eeLoadModelName - uint8_t modelVoice ; // Index to model name voice (261+value) - uint8_t RxNum ; // was timer trigger source, now RxNum for model match - uint8_t sparex:1; // was tmrDir, now use tmrVal>0 => count down - uint8_t traineron:1; // 0 disable trainer, 1 allow trainer - uint8_t spare22:1 ; // Start timer2 using throttle - uint8_t FrSkyUsrProto:1 ; // Protocol in FrSky User Data, 0=FrSky Hub, 1=WS HowHigh - uint8_t FrSkyGpsAlt:1 ; // Use Gps Altitude as main altitude reading - uint8_t FrSkyImperial:1 ; // Convert FrSky values to imperial units - uint8_t FrSkyAltAlarm:2; - uint8_t version ; - uint8_t protocol; - int8_t ppmNCH; - uint8_t thrTrim:1; // Enable Throttle Trim - uint8_t numBlades:2; // RPM scaling - uint8_t spare10:1; - uint8_t thrExpo:1; // Enable Throttle Expo - uint8_t spare11:3; - int8_t trimInc; // Trim Increments - int8_t ppmDelay; - int8_t trimSw; - uint8_t beepANACenter; // 1<<0->A1.. 1<<6->A7 - uint8_t pulsePol:1; - uint8_t extendedLimits:1; - uint8_t swashInvertELE:1; - uint8_t swashInvertAIL:1; - uint8_t swashInvertCOL:1; - uint8_t swashType:3; - uint8_t swashCollectiveSource; - uint8_t swashRingValue; - int8_t ppmFrameLength; //0=22.5 (10msec-30msec) 0.5msec increments - Ersky9xMixData_v11 mixData[ERSKY9X_MAX_MIXERS_V11]; - Ersky9xLimitData limitData[ERSKY9X_NUM_CHNOUT_V11]; - Ersky9xExpoData expoData[4]; - int8_t trim[4]; - int8_t curves5[ERSKY9X_MAX_CURVE5][5]; - int8_t curves9[ERSKY9X_MAX_CURVE9][9]; - int8_t curvexy[18]; - Ersky9xLogicalSwitchData_v11 logicalSw[ERSKY9X_NUM_CSW_V11]; - uint8_t frSkyVoltThreshold ; - uint8_t bt_telemetry; - uint8_t numVoice; // 0-16, rest are Safety switches - Ersky9xSafetySwData_v11 safetySw[ERSKY9X_NUM_CHNOUT_V11]; - Ersky9xvoiceSwData voiceSwitches[ERSKY9X_NUM_VOICE] ; - Ersky9xFrSkyData_v11 frsky; - Ersky9xTimerMode_v11 timer[2] ; - Ersky9xFrSkyAlarmData_v11 frskyAlarms ; -// Add 6 bytes for custom telemetry screen - uint8_t customDisplayIndex[6] ; - Ersky9xCustomFunctionData customFn[ERSKY9X_NUM_FSW]; - Ersky9xFlightModeData flightModeData[6] ; - Ersky9xGvarData gvars[ERSKY9X_MAX_GVARS] ; - - operator ModelData(); - t_Ersky9xModelData_v11() { memset(reinterpret_cast(this), 0, sizeof(t_Ersky9xModelData_v11)); } -}) Ersky9xModelData_v11; - -#endif // _ERSKY9XEEPROM_H_ diff --git a/companion/src/firmwares/ersky9x/ersky9xinterface.cpp b/companion/src/firmwares/ersky9x/ersky9xinterface.cpp deleted file mode 100644 index 00d6fa8d7..000000000 --- a/companion/src/firmwares/ersky9x/ersky9xinterface.cpp +++ /dev/null @@ -1,395 +0,0 @@ -/* - * Copyright (C) EdgeTX - * - * Based on code named - * opentx - https://github.com/opentx/opentx - * th9x - http://code.google.com/p/th9x - * er9x - http://code.google.com/p/er9x - * gruvin9x - http://code.google.com/p/gruvin9x - * - * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "ersky9xinterface.h" -#include "ersky9xeeprom.h" -#include "rlefile.h" -#include -#include - -#define FILE_TYP_GENERAL 1 -#define FILE_TYP_MODEL 2 - -/// fileId of general file -#define FILE_GENERAL 0 -/// convert model number 0..MAX_MODELS-1 int fileId -#define FILE_MODEL(n) (1+n) -#define FILE_TMP (1+16) - -Ersky9xInterface::Ersky9xInterface(): -EEPROMInterface(Board::BOARD_SKY9X), -efile(new RleFile()) -{ -} - -Ersky9xInterface::~Ersky9xInterface() -{ - delete efile; -} - -const char * Ersky9xInterface::getName() -{ - return "Ersky9x"; -} - -inline void applyStickModeToModel(Ersky9xModelData_v10 & model, unsigned int mode) -{ - for (int i=0; i<2; i++) { - int stick = applyStickMode(i+1, mode) - 1; - { - int tmp = model.trim[i]; - model.trim[i] = model.trim[stick]; - model.trim[stick] = tmp; - } - { - Ersky9xExpoData tmp = model.expoData[i]; - model.expoData[i] = model.expoData[stick]; - model.expoData[stick] = tmp; - } - } - for (int i=0; i errors; - - Ersky9xGeneral ersky9xGeneral; - memset(&ersky9xGeneral,0,sizeof(ersky9xGeneral)); - if(!loadRadioSettingsDataXML(&doc, &ersky9xGeneral)) { - errors.set(UNKNOWN_ERROR); - return errors.to_ulong(); - } - else { - radioData.generalSettings=ersky9xGeneral; - dbg << "version " << (unsigned int)ersky9xGeneral.myVers << " "; - } - for(int i=0; i(&doc, &radioData.models[i], i, radioData.generalSettings.stickMode+1)) { - dbg << "ko"; - errors.set(UNKNOWN_ERROR); - return errors.to_ulong(); - } - } - else { - if (!loadModelDataXML(&doc, &radioData.models[i], i, radioData.generalSettings.stickMode+1)) { - dbg << "ko"; - errors.set(UNKNOWN_ERROR); - return errors.to_ulong(); - } - } - } - dbg << "ok"; - errors.set(ALL_OK); - return errors.to_ulong(); -} -#endif - -unsigned long Ersky9xInterface::load(RadioData &radioData, const uint8_t *eeprom, int size) -{ - QDebug dbg = qDebug(); - dbg.setAutoInsertSpaces(false); - dbg << "trying ersky9x import... "; - - std::bitset errors; - - if (size != Boards::getEEpromSize(Board::BOARD_SKY9X)) { - dbg << "wrong size"; - errors.set(WRONG_SIZE); - return errors.to_ulong(); - } - - if (!efile->EeFsOpen((uint8_t *)eeprom, size, Board::BOARD_SKY9X)) { - dbg << "wrong file system"; - errors.set(WRONG_FILE_SYSTEM); - return errors.to_ulong(); - } - - efile->openRd(FILE_GENERAL); - Ersky9xGeneral ersky9xGeneral; - - if (efile->readRlc2((uint8_t*)&ersky9xGeneral, 1) != 1) { - dbg << "no"; - errors.set(UNKNOWN_ERROR); - return errors.to_ulong(); - } - - dbg << "version " << (unsigned int)ersky9xGeneral.myVers << " "; - - switch(ersky9xGeneral.myVers) { - case 10: - break; - case 11: - break; - default: - dbg << "not ersky9x"; - errors.set(NOT_ERSKY9X); - return errors.to_ulong(); - } - efile->openRd(FILE_GENERAL); - if (!efile->readRlc2((uint8_t*)&ersky9xGeneral, sizeof(Ersky9xGeneral))) { - dbg << "ko"; - errors.set(UNKNOWN_ERROR); - return errors.to_ulong(); - } - radioData.generalSettings = ersky9xGeneral; - - for (int i=0; iopenRd(FILE_MODEL(i)); - -// if (!efile->readRlc2((uint8_t*)&ersky9xModel, sizeof(Ersky9xModelData))) { - size = efile->readRlc2(buffer, 4096); - if (!size) { - radioData.models[i].clear(); - } - else { - if (size<720) { - Ersky9xModelData_v10 ersky9xModel; - memcpy(&ersky9xModel, buffer, sizeof(ersky9xModel)); - applyStickModeToModel(ersky9xModel, radioData.generalSettings.stickMode+1); - radioData.models[i] = ersky9xModel; - } else { - Ersky9xModelData_v11 ersky9xModel; - memcpy(&ersky9xModel, buffer, sizeof(ersky9xModel)); - applyStickModeToModel(ersky9xModel, radioData.generalSettings.stickMode+1); - radioData.models[i] = ersky9xModel; - } - } - } - - dbg << "ok"; - errors.set(ALL_OK); - return errors.to_ulong(); -} - -unsigned long Ersky9xInterface::loadBackup(RadioData &radioData, const uint8_t *eeprom, int esize, int index) -{ - std::bitset errors; - errors.set(UNKNOWN_ERROR); - return errors.to_ulong(); -} - -int Ersky9xInterface::getSize(const ModelData & model) -{ - return 0; -} - -int Ersky9xInterface::getSize(const GeneralSettings & settings) -{ - return 0; -} - -bool Ersky9xInterface::isAvailable(PulsesProtocol prot, int port) -{ - switch (prot) { - case PULSES_PPM: - case PULSES_DSM2: - case PULSES_PXX_DJT: - case PULSES_PPM16: - return 1; - default: - return 0; - } -} - -void Ersky9xInterface::appendTextElement(QDomDocument * qdoc, QDomElement * pe, QString name, QString value) -{ - QDomElement e = qdoc->createElement(name); - QDomText t = qdoc->createTextNode(name); - t.setNodeValue(value); - e.appendChild(t); - pe->appendChild(e); -} - -void Ersky9xInterface::appendNumberElement(QDomDocument * qdoc, QDomElement * pe,QString name, int value, bool forceZeroWrite) -{ - if(value || forceZeroWrite) { - QDomElement e = qdoc->createElement(name); - QDomText t = qdoc->createTextNode(name); - t.setNodeValue(QString("%1").arg(value)); - e.appendChild(t); - pe->appendChild(e); - } -} - -void Ersky9xInterface::appendCDATAElement(QDomDocument * qdoc, QDomElement * pe,QString name, const char * data, int size) -{ - QDomElement e = qdoc->createElement(name); - QDomCDATASection t = qdoc->createCDATASection(name); - t.setData(QByteArray(data, size).toBase64()); - e.appendChild(t); - pe->appendChild(e); -} - -QDomElement Ersky9xInterface::getGeneralDataXML(QDomDocument * qdoc, Ersky9xGeneral * tgen) -{ - QDomElement gd = qdoc->createElement("GENERAL_DATA"); - appendNumberElement(qdoc, &gd, "Version", tgen->myVers, true); // have to write value here - appendTextElement(qdoc, &gd, "Owner", QString::fromLatin1(tgen->ownerName,sizeof(tgen->ownerName)).trimmed()); - appendCDATAElement(qdoc, &gd, "Data", (const char *)tgen,sizeof(Ersky9xGeneral)); - return gd; -} - -QDomElement Ersky9xInterface::getModelDataXML(QDomDocument * qdoc, Ersky9xModelData_v11 * tmod, int modelNum, int mdver) -{ - QDomElement md = qdoc->createElement("MODEL_DATA"); - md.setAttribute("number", modelNum); - appendNumberElement(qdoc, &md, "Version", mdver, true); // have to write value here - appendTextElement(qdoc, &md, "Name", QString::fromLatin1(tmod->name,sizeof(tmod->name)).trimmed()); - appendCDATAElement(qdoc, &md, "Data", (const char *)tmod,sizeof(Ersky9xModelData_v11)); - return md; -} - -bool Ersky9xInterface::loadRadioSettingsDataXML(QDomDocument * qdoc, Ersky9xGeneral * tgen) -{ - // look for "GENERAL_DATA" tag - QDomElement gde = qdoc->elementsByTagName("GENERAL_DATA").at(0).toElement(); - - if(gde.isNull()) // couldn't find - return false; - - // load cdata into tgen - QDomNode n = gde.elementsByTagName("Data").at(0).firstChild();// get all children in Data - while (!n.isNull()) { - if (n.isCDATASection()) { - QString ds = n.toCDATASection().data(); - QByteArray ba = QByteArray::fromBase64(ds.toLatin1()); - const char * data = ba.data(); - memcpy(tgen, data, std::min((unsigned int)ba.size(), (unsigned int)sizeof(Ersky9xGeneral))); - break; - } - n = n.nextSibling(); - } - // check version? - return true; -} - -template -bool Ersky9xInterface::loadModelDataXML(QDomDocument * qdoc, ModelData *model, int modelNum, int stickMode) -{ - T ersky9xModel; - memset(&ersky9xModel, 0, sizeof(ersky9xModel)); - - // look for MODEL_DATA with modelNum attribute. - //if modelNum = -1 then just pick the first one - QDomNodeList ndl = qdoc->elementsByTagName("MODEL_DATA"); - - // cycle through nodes to find correct model number - QDomNode k = ndl.at(0); - if (modelNum>=0) { - while(!k.isNull()) { - int a = k.toElement().attribute("number").toInt(); - if(a==modelNum) - break; - k = k.nextSibling(); - } - } - - if (k.isNull()) // couldn't find - return false; - - // load cdata into tgen - QDomNode n = k.toElement().elementsByTagName("Data").at(0).firstChild();// get all children in Data - while (!n.isNull()) { - if (n.isCDATASection()) { - QString ds = n.toCDATASection().data(); - QByteArray ba = QByteArray::fromBase64(ds.toLatin1()); - const char * data = ba.data(); - memcpy(&ersky9xModel, data, std::min(ba.size(), (int)sizeof(ersky9xModel))); - break; - } - n = n.nextSibling(); - } - - applyStickModeToModel(ersky9xModel, stickMode); - *model = ersky9xModel; - return true; -} - -int Ersky9xInterface::getCapability(Capability capability) -{ - switch (capability) { - case Models: - return 20; - default: - return 0; - } -} - -QString Ersky9xInterface::getCapabilityStr(Capability capability) -{ - return QString(); -} diff --git a/companion/src/firmwares/ersky9x/ersky9xinterface.h b/companion/src/firmwares/ersky9x/ersky9xinterface.h deleted file mode 100644 index 54e999f37..000000000 --- a/companion/src/firmwares/ersky9x/ersky9xinterface.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) EdgeTX - * - * Based on code named - * opentx - https://github.com/opentx/opentx - * th9x - http://code.google.com/p/th9x - * er9x - http://code.google.com/p/er9x - * gruvin9x - http://code.google.com/p/gruvin9x - * - * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef _ERSKY9XINTERFACE_H_ -#define _ERSKY9XINTERFACE_H_ - -#include -#include "eeprominterface.h" -#include "ersky9xeeprom.h" - -class RleFile; - -class Ersky9xInterface : public EEPROMInterface -{ - public: - - Ersky9xInterface(); - - virtual ~Ersky9xInterface(); - - virtual const char * getName(); - - - virtual unsigned long load(RadioData &, const uint8_t * eeprom, int size); - - virtual unsigned long loadBackup(RadioData &, const uint8_t * eeprom, int esize, int index); - - virtual int save(uint8_t * eeprom, const RadioData & radioData, uint8_t version=0, uint32_t variant=0) - { - return 0; - } - - virtual int getSize(const ModelData &); - - virtual int getSize(const GeneralSettings & settings); - - virtual bool isAvailable(PulsesProtocol proto, int port=0); - - virtual int getCapability(Capability capability); - - virtual QString getCapabilityStr(Capability); - - protected: - - RleFile * efile; - - private: - void appendTextElement(QDomDocument * qdoc, QDomElement * pe, QString name, QString value); - - void appendNumberElement(QDomDocument * qdoc, QDomElement * pe,QString name, int value, bool forceZeroWrite = false); - - void appendCDATAElement(QDomDocument * qdoc, QDomElement * pe,QString name, const char * data, int size); - - QDomElement getGeneralDataXML(QDomDocument * qdoc, Ersky9xGeneral * tgen); //parse out data to XML format - - QDomElement getModelDataXML(QDomDocument * qdoc, Ersky9xModelData_v11 * tmod, int modelNum, int mdver); //parse out data to XML format - - bool loadRadioSettingsDataXML(QDomDocument * qdoc, Ersky9xGeneral * tgen); // get data from XML - - template - bool loadModelDataXML(QDomDocument * qdoc, ModelData * model, int modelNum, int stickMode); // get data from XML - -}; - -#endif // _ERSKY9XINTERFACE_H_ diff --git a/companion/src/firmwares/opentx/opentxeeprom.cpp b/companion/src/firmwares/opentx/opentxeeprom.cpp deleted file mode 100644 index 6c3193012..000000000 --- a/companion/src/firmwares/opentx/opentxeeprom.cpp +++ /dev/null @@ -1,3517 +0,0 @@ -/* - * Copyright (C) EdgeTX - * - * Based on code named - * opentx - https://github.com/opentx/opentx - * th9x - http://code.google.com/p/th9x - * er9x - http://code.google.com/p/er9x - * gruvin9x - http://code.google.com/p/gruvin9x - * - * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include "boards.h" -#include "helpers.h" -#include "opentxeeprom.h" -#include "customdebug.h" -#include "opentxinterface.h" -#include "sourcenumref.h" -#include "adjustmentreference.h" - -using namespace Board; - -#define MAX_VIEWS(board) (HAS_LARGE_LCD(board) ? 2 : 256) -inline int MAX_SWITCHES(Board::Type board, int version) -{ - if (version <= 218) { - if (IS_TARANIS_X7(board)) - return 6; - if (IS_TARANIS_X9D(board) || IS_FAMILY_HORUS_OR_T16(board)) - return 8; - if (IS_TARANIS_XLITE(board)) - return 4; - } - - if (IS_TARANIS_X9D(board)) - return 9; - - if (IS_JUMPER_TPROV1(board)) - return 10; - - if (IS_JUMPER_TPROV2(board) || IS_JUMPER_BUMBLEBEE(board)) - return 14; - - if (IS_FAMILY_T12(board)) - return 8; - - if (IS_TARANIS_X7(board)) - return 8; - - //return Boards::getCapability(board, Board::Switches); - if (IS_TARANIS_X9E(board)) - return 18; - else if (board == Board::BOARD_TARANIS_X9LITE) - return 5; - else if (board == Board::BOARD_TARANIS_X9LITES) - return 7; - else if (board == BOARD_TARANIS_X7_ACCESS) - return 7; - else if (board == BOARD_TARANIS_X7) - return 8; - else if (board == BOARD_JUMPER_TLITE || board == BOARD_JUMPER_TLITE_F4 || - board == BOARD_JUMPER_TPRO || board == BOARD_BETAFPV_LR3PRO || - board == BOARD_IFLIGHT_COMMANDO8) - return 4; - else if (board == BOARD_FLYSKY_NV14) - return 8; - else if (board == BOARD_RADIOMASTER_TX12_MK2 || board == BOARD_RADIOMASTER_BOXER) - return 6; - else if (IS_FAMILY_T12(board)) - return 8; - else if (IS_TARANIS_XLITE(board)) - return 6; - else if (board == Board::BOARD_TARANIS_X9DP_2019) - return 9; - else if (IS_TARANIS(board)) - return 8; - else if (IS_FAMILY_HORUS_OR_T16(board)) - return 10; - else - return 7; -} - -inline int MAX_SWITCHES_SOURCE(Board::Type board, int version) -{ - //if (IS_JUMPER_TPRO(board)) // 10 switches are allocated in EEprom but 6 are reserved for FS - //return Boards::getCapability(board, Board::Switches); - //else - return MAX_SWITCHES(board, version); -} - -inline int MAX_SWITCHES_POSITION(Board::Type board, int version) -{ - //if (IS_JUMPER_TPRO(board)) - //return Boards::getCapability(board, Board::SwitchesPositions); - //else - if (IS_HORUS_OR_TARANIS(board) || IS_FLYSKY_NV14(board)) - return MAX_SWITCHES(board, version) * 3; - else { - //return Boards::getCapability(board, Board::SwitchesPositions); - //if (IS_HORUS_OR_TARANIS(board) || IS_FLYSKY_NV14(board)) - // return getCapability(board, Board::Switches) * 3; - //else - return 9; - } -} - -inline int MAX_FUNCTIONSWITCHES(Board::Type board, int version) -{ - //return Boards::getCapability(board, Board::FunctionSwitches); - return (IS_JUMPER_TPRO(board) ? 6 : 0); -} - -inline int MAX_FUNCTIONSWITCHES_POSITION(Board::Type board, int version) -{ - //return Boards::getCapability(board, Board::NumFunctionSwitchesPositions); - return MAX_FUNCTIONSWITCHES(board, version) * 3; -} - -inline int POTS_CONFIG_SIZE(Board::Type board, int version) -{ - if (version >= 219 && IS_FAMILY_HORUS_OR_T16(board)) - return 16; - - return 8; -} - -inline int MAX_POTS(Board::Type board, int version) -{ - if (version <= 218 && IS_FAMILY_HORUS_OR_T16(board)) - return 3; - if (version <= 220 && (IS_HORUS_X10(board) || IS_FAMILY_T16(board))) - return 5; - if (IS_FAMILY_T12(board)) - return 2; - - //return Boards::getCapability(board, Board::Pots); - if (IS_TARANIS_X9LITE(board)) - return 1; - else if (IS_JUMPER_TLITE(board) || IS_BETAFPV_LR3PRO(board) || IS_IFLIGHT_COMMANDO8(board)) - return 0; - else if (IS_RADIOMASTER_BOXER(board)) - return 3; - else if (IS_TARANIS_SMALL(board) || IS_JUMPER_TPRO(board)) - return 2; - else if (IS_TARANIS_X9E(board)) - return 4; - else if (IS_HORUS_X10(board) || IS_FAMILY_T16(board)) - return 7; - else if (IS_HORUS_X12S(board)) - return 3; - else if (IS_FLYSKY_NV14(board)) - return 2; - else - return 3; -} - -inline int MAX_FUNCTION_SWITCHES(Board::Type board, int version) -{ - if (IS_JUMPER_TPRO(board)) - return 6; - return 0; -} - -inline int MAX_POTS_STORAGE(Board::Type board, int version) -{ - if (version <= 218 && IS_FAMILY_HORUS_OR_T16(board)) - return 3; - if (version <= 220 && IS_FAMILY_HORUS_OR_T16(board) && !IS_FLYSKY_NV14(board) && !IS_FLYSKY_PL18(board)) - return 5; - if (IS_FAMILY_T12(board)) - return 2; - //return Boards::getCapability(board, Board::Pots); - return MAX_POTS(board, version); -} - -inline int MAX_POTS_SOURCES(Board::Type board, int version) -{ - if (version <= 218 && IS_FAMILY_HORUS_OR_T16(board)) - return 3; - if (version <= 220 && (IS_HORUS_X10(board) || IS_FAMILY_T16(board))) - return 5; - if (IS_FAMILY_T12(board)) - return 2; - //return Boards::getCapability(board, Board::Pots); - return MAX_POTS(board, version); -} - -inline int MAX_XPOTS(Board::Type board, int version) -{ - if (version <= 218 && IS_FAMILY_HORUS_OR_T16(board)) - return 3; - if (version <= 220 && (IS_HORUS_X10(board) || IS_FAMILY_T16(board))) - return 5; - if (IS_FAMILY_T12(board)) - return 2; - //return Boards::getCapability(board, Board::MultiposPots); - if (IS_HORUS_OR_TARANIS(board) && !IS_FLYSKY_NV14(board)) { - //return getCapability(board, Board::Pots); - return MAX_POTS(board, version); - } - else - return 0; - -} - -inline int MAX_SLIDERS_STORAGE(Board::Type board, int version) -{ - if (version >= 219 && (IS_FAMILY_HORUS_OR_T16(board) && !IS_FLYSKY_NV14(board) && !IS_FLYSKY_PL18(board))) - return 4; - //return Boards::getCapability(board, Board::Sliders); - if (IS_HORUS_X12S(board) || IS_TARANIS_X9E(board)) - return 4; - else if (IS_TARANIS_X9D(board) || IS_HORUS_X10(board) || IS_FAMILY_T16(board)) - return 2; - else - return 0; -} - -inline int MAX_SLIDERS_SOURCES(Board::Type board, int version) -{ - if (version <= 218 && IS_FAMILY_HORUS_OR_T16(board)) - return 2; - //return Boards::getCapability(board, Board::Sliders); - if (IS_HORUS_X12S(board) || IS_TARANIS_X9E(board)) - return 4; - else if (IS_TARANIS_X9D(board) || IS_HORUS_X10(board) || IS_FAMILY_T16(board)) - return 2; - else - return 0; -} - -inline int SLIDERS_CONFIG_SIZE(Board::Type board, int version) -{ - if (version >= 219 && IS_FAMILY_HORUS_OR_T16(board)) - return 8; - - return 4; -} - -inline int SWITCHES_CONFIG_SIZE(Board::Type board, int version) -{ - if (IS_TARANIS_X9E(board)) - return 64; - - if (IS_FAMILY_HORUS_OR_T16(board)) - return 32; - - if (version >= 219 && (IS_TARANIS_X9D(board) || IS_JUMPER_TPRO(board))) - return 32; - - return 16; -} - -inline int MAX_MOUSE_ANALOG_SOURCES(Board::Type board, int version) -{ - if (IS_FAMILY_HORUS_OR_T16(board) && !IS_FLYSKY_NV14(board) && !IS_FLYSKY_PL18(board)) - return 2; - else - return 0; -} - -inline int MAX_GYRO_ANALOGS(Board::Type board, int version) -{ - if (version <= 220) { - if (IS_FAMILY_HORUS_OR_T16(board)) - return 0; - } - - //return Boards::getCapability(board, Board::GyroAxes); - if (IS_TARANIS_XLITES(board) || IS_FAMILY_HORUS_OR_T16(board)) - return 2; - else - return 0; -} - -#define MAX_ROTARY_ENCODERS(board) 0 -#define MAX_FLIGHT_MODES(board, version) 9 -#define MAX_TIMERS(board, version) 3 -#define MAX_MIXERS(board, version) 64 -#define MAX_CHANNELS(board, version) 32 -//#define MAX_TRIMS(board) (Boards::getCapability(board, Board::NumTrims)) -inline int MAX_TRIMS(Board::Type board) -{ - if (IS_FAMILY_HORUS_OR_T16(board) && !IS_FLYSKY_NV14(board)) - return 6; - else if (IS_IFLIGHT_COMMANDO8(board)) - return 0; - else - return 4; -} -#define MAX_EXPOS(board, version) (IS_HORUS_OR_TARANIS(board) ? 64 : 32) -#define MAX_LOGICAL_SWITCHES(board, version) (version >= 218 ? 64 : 32) -#define MAX_CUSTOM_FUNCTIONS(board, version) 64 -#define MAX_CURVES(board, version) ((version >= 219 || HAS_LARGE_LCD(board)) ? 32 : 16) -#define MAX_GVARS(board, version) 9 -#define MAX_SCRIPTS(board) (IS_FAMILY_HORUS_OR_T16(board) ? 9 : 7) -#define MAX_TELEMETRY_SENSORS(board, version) (version <= 218 ? 32 : ((IS_FAMILY_HORUS_OR_T16(board) || IS_TARANIS_X9(board) || IS_FLYSKY_NV14(board) || IS_FLYSKY_PL18(board)) ? 60 : 40)) -#define NUM_PPM_INPUTS(board, version) 16 -#define ROTENC_COUNT(board, version) ((IS_STM32(board) && version >= 218) ? 0 : 1) -#define MAX_AUX_TRIMS(board) ((IS_FAMILY_HORUS_OR_T16(board) && !IS_FLYSKY_NV14(board) && !IS_FLYSKY_PL18(board)) ? 2 : 0) -#define MAX_SOURCE_TYPE_SPECIAL(board, version) SOURCE_TYPE_SPECIAL_COUNT -#define MAX_TIMERS(board, version) 3 - -inline int switchIndex(int i, Board::Type board, unsigned int version) -{ - if (!IS_HORUS_OR_TARANIS(board)) - return (i<=3 ? i+3 : (i<=6 ? i-3 : i)); - else - return i; -} - -class SwitchesConversionTable: public ConversionTable { - - public: - SwitchesConversionTable(Board::Type board, unsigned int version, bool timer=false) - { - int val = 0; - int offset = 0; - if (timer) { - offset = 4; - for (int i=0; i<5; i++) { - addConversion(RawSwitch(SWITCH_TYPE_TIMER_MODE, i), val++); - } - } - else { - addConversion(RawSwitch(SWITCH_TYPE_NONE), val++); - } - - for (int i=1; i<=MAX_SWITCHES_POSITION(board, version); i++) { - int s = switchIndex(i, board, version); - addConversion(RawSwitch(SWITCH_TYPE_SWITCH, s), val); - addConversion(RawSwitch(SWITCH_TYPE_SWITCH, -s), -val+offset); - val++; - } - - for (int i=1; i<=MAX_FUNCTIONSWITCHES_POSITION(board, version); i++) { - int s = switchIndex(i, board, version); - addConversion(RawSwitch(SWITCH_TYPE_FUNCTIONSWITCH, s), val); - addConversion(RawSwitch(SWITCH_TYPE_FUNCTIONSWITCH, -s), -val+offset); - val++; - } - - if (IS_HORUS_OR_TARANIS(board)) { - const int adc_offset = 4 * 6; // num sticks * multi pot posns as adc assumes ALL inputs can be multi pos - for (int i=1; i<=MAX_XPOTS(board, version)*6; i++) { - addConversion(RawSwitch(SWITCH_TYPE_MULTIPOS_POT, -i - adc_offset), -val+offset); - addConversion(RawSwitch(SWITCH_TYPE_MULTIPOS_POT, i + adc_offset), val++); - } - } - - for (int i=1; i<=2*MAX_TRIMS(board); i++) { - addConversion(RawSwitch(SWITCH_TYPE_TRIM, -i), -val+offset); - addConversion(RawSwitch(SWITCH_TYPE_TRIM, i), val++); - } - - for (int i=1; i<=MAX_ROTARY_ENCODERS(board); i++) { - addConversion(RawSwitch(SWITCH_TYPE_ROTARY_ENCODER, -i), -val+offset); - addConversion(RawSwitch(SWITCH_TYPE_ROTARY_ENCODER, i), val++); - } - - for (int i=1; i<=MAX_LOGICAL_SWITCHES(board, version); i++) { - addConversion(RawSwitch(SWITCH_TYPE_VIRTUAL, -i), -val+offset); - addConversion(RawSwitch(SWITCH_TYPE_VIRTUAL, i), val++); - } - - addConversion(RawSwitch(SWITCH_TYPE_OFF), -val+offset); - addConversion(RawSwitch(SWITCH_TYPE_ON), val++); - - addConversion(RawSwitch(SWITCH_TYPE_ONE, -1), -val+offset); - addConversion(RawSwitch(SWITCH_TYPE_ONE, 1), val++); - for (int i=1; i<=MAX_FLIGHT_MODES(board, version); i++) { - addConversion(RawSwitch(SWITCH_TYPE_FLIGHT_MODE, -i), -val+offset); - addConversion(RawSwitch(SWITCH_TYPE_FLIGHT_MODE, i), val++); - } - - if (version >= 218) { - addConversion(RawSwitch(SWITCH_TYPE_TELEMETRY, -1), -val+offset); - addConversion(RawSwitch(SWITCH_TYPE_TELEMETRY, 1), val++); - for (int i=1; i<=MAX_TELEMETRY_SENSORS(board, version); i++) { - addConversion(RawSwitch(SWITCH_TYPE_SENSOR, -i), -val+offset); - addConversion(RawSwitch(SWITCH_TYPE_SENSOR, i), val++); - } - } - if (version >= 219) { - addConversion(RawSwitch(SWITCH_TYPE_ACT, -1), -val+offset); - addConversion(RawSwitch(SWITCH_TYPE_ACT, 1), val++); - } - } - - - protected: - - void addConversion(const RawSwitch & sw, const int b) - { - ConversionTable::addConversion(sw.toValue(), b); - } - - class Cache { - public: - Cache(Board::Type board, unsigned int version, unsigned long flags, SwitchesConversionTable * table): - board(board), - version(version), - flags(flags), - table(table) - { - } - Board::Type board; - unsigned int version; - unsigned long flags; - SwitchesConversionTable * table; - }; - - static std::list internalCache; - - public: - - static SwitchesConversionTable * getInstance(Board::Type board, unsigned int version, unsigned long flags=0) - { - for (auto & element : internalCache) { - if (element.board == board && element.version == version && element.flags == flags) - return element.table; - } - - Cache element(board, version, flags, new SwitchesConversionTable(board, version, flags)); - internalCache.push_back(element); - return element.table; - } - static void Cleanup() - { - for (auto & element : internalCache) { - delete element.table; - } - internalCache.clear(); - } -}; - -std::list SwitchesConversionTable::internalCache; - -#define FLAG_NONONE 0x01 -#define FLAG_NOSWITCHES 0x02 -#define FLAG_NOTELEMETRY 0x04 - -class SourcesConversionTable: public ConversionTable { - public: - SourcesConversionTable(Board::Type board, unsigned int version, unsigned int variant, unsigned long flags=0) - { - int val=0; - - if (!(flags & FLAG_NONONE)) { - addConversion(RawSource(SOURCE_TYPE_NONE), val++); - } - - if (version >= 218 || IS_STM32(board)) { - for (int i=1; i<=32; i++) { - addConversion(RawSource(SOURCE_TYPE_VIRTUAL_INPUT, i), val++); - } - } - - if (IS_STM32(board)) { - for (int i = 0; i < MAX_SCRIPTS(board); i++) { - for (int j = 0; j < 6; j++) { - addConversion(RawSource(SOURCE_TYPE_LUA_OUTPUT, i * 16 + j + 1), val++); - } - } - } - -// qDebug() << "bd:" << Boards::getBoardName(board) -// << "ptsrc:" << MAX_POTS_SOURCES(board, version) << "ptstore:" << MAX_POTS_STORAGE(board, version) -// << "slsrcs:" << MAX_SLIDERS_SOURCES(board, version) << "slstore:" << MAX_SLIDERS_STORAGE(board, version) -// << "ms:" << MAX_MOUSE_ANALOG_SOURCES(board, version) -// << "gyro:" << MAX_GYRO_ANALOGS(board, version); - - for (int i = 0; i < CPN_MAX_STICKS + - MAX_POTS_SOURCES(board, version) + - MAX_SLIDERS_SOURCES(board, version) + - MAX_MOUSE_ANALOG_SOURCES(board, version) + - MAX_GYRO_ANALOGS(board, version); i++) { - int offset = 0; - if (version <= 218 && IS_HORUS_X10(board) && i >= CPN_MAX_STICKS + MAX_POTS_STORAGE(board, version)) - offset += 2; - - // ADC refactor shuffles - - //if (version <= 220 && (IS_HORUS_X10(board) || IS_FAMILY_T16(board)) && i >= CPN_MAX_STICKS + MAX_POTS_STORAGE(board, version)) - // offset += 2; - - if (IS_FAMILY_HORUS_OR_T16(board)) { - if (i >= 7 && i <= 8) - offset += 2; - else if (i >= 9 && i <= 10) - offset -= 2; - } - else if (IS_TARANIS_X9E(board)) { - if (i >= 8 && i <= 9) - offset += 2; - else if (i >= 10 && i <= 11) - offset -= 2; - } - // end ADC refactor shuffles - - addConversion(RawSource(SOURCE_TYPE_INPUT, i + offset + 1), val++); - // qDebug() << "i:" << i << "offset:" << offset << "index:" << i + offset + 1 << "desc:" << RawSource(SOURCE_TYPE_STICK, i + offset).toString() << "val:" << val; - } - - for (int i = 1; i <= MAX_ROTARY_ENCODERS(board); i++) { - addConversion(RawSource(SOURCE_TYPE_ROTARY_ENCODER, 0), val++); - } - - addConversion(RawSource(SOURCE_TYPE_MAX), val++); - - for (int i = 1; i <= 3; i++) - addConversion(RawSource(SOURCE_TYPE_CYC, i), val++); - - for (int i = 1; i <= MAX_TRIMS(board); i++) - addConversion(RawSource(SOURCE_TYPE_TRIM, i), val++); - - if (!(flags & FLAG_NOSWITCHES)) { - for (int i = 1; i <= MAX_SWITCHES_SOURCE(board, version); i++) { - addConversion(RawSource(SOURCE_TYPE_SWITCH, i), val++); - } - for (int i = 1; i <= MAX_FUNCTIONSWITCHES(board, version); i++) { - addConversion(RawSource(SOURCE_TYPE_FUNCTIONSWITCH, i), val++); - } - for (int i = 1; i <= MAX_LOGICAL_SWITCHES(board, version); i++) { - addConversion(RawSource(SOURCE_TYPE_CUSTOM_SWITCH, i), val++); - } - } - - for (int i = 1; i <= NUM_PPM_INPUTS(board, version); i++) { - addConversion(RawSource(SOURCE_TYPE_PPM, i), val++); - } - - for (int i = 1; i <= MAX_CHANNELS(board, version); i++) { - addConversion(RawSource(SOURCE_TYPE_CH, i), val++); - } - - if (!(flags & FLAG_NOTELEMETRY)) { - for (int i = 1; i <= MAX_GVARS(board, version); i++) - addConversion(RawSource(SOURCE_TYPE_GVAR, i), val++); - for (int i = 1; i < MAX_SOURCE_TYPE_SPECIAL(board, version); i++) // exception '<' NOT '<=' due to moving TIMERS to own TYPE - addConversion(RawSource(SOURCE_TYPE_SPECIAL, i), val++); - for (int i = 1; i <= MAX_TIMERS(board, version); i++) - addConversion(RawSource(SOURCE_TYPE_TIMER, i), val++); - for (int i = 1; i <= MAX_TELEMETRY_SENSORS(board, version)*3; ++i) { - addConversion(RawSource(SOURCE_TYPE_TELEMETRY, i), val++); - } - } - } - - protected: - - void addConversion(const RawSource & source, const int b) - { - ConversionTable::addConversion(source.toValue(), b); - } - - class Cache { - public: - Cache(Board::Type board, unsigned int version, unsigned int variant, unsigned long flags, SourcesConversionTable * table): - board(board), - version(version), - variant(variant), - flags(flags), - table(table) - { - } - Board::Type board; - unsigned int version; - unsigned int variant; - unsigned long flags; - SourcesConversionTable * table; - }; - static std::list internalCache; - - public: - - static SourcesConversionTable * getInstance(Board::Type board, unsigned int version, unsigned int variant, unsigned long flags=0) - { - for (std::list::iterator it=internalCache.begin(); it!=internalCache.end(); it++) { - Cache & element = *it; - if (element.board == board && element.version == version && element.variant == variant && element.flags == flags) - return element.table; - } - - Cache element(board, version, variant, flags, new SourcesConversionTable(board, version, variant, flags)); - internalCache.push_back(element); - return element.table; - } - static void Cleanup() - { - for (std::list::iterator it=internalCache.begin(); it!=internalCache.end(); it++) { - Cache & element = *it; - if (element.table) - delete element.table; - } - internalCache.clear(); - } -}; - -std::list SourcesConversionTable::internalCache; - -void OpenTxEepromCleanup(void) -{ - SourcesConversionTable::Cleanup(); - SwitchesConversionTable::Cleanup(); -} - -template -class SwitchField: public ConversionField< SignedField > { - public: - SwitchField(DataField * parent, RawSwitch & sw, Board::Type board, unsigned int version, unsigned long flags=0): - ConversionField< SignedField >(parent, _switch, SwitchesConversionTable::getInstance(board, version, flags), DataField::tr("Switch").toLatin1(), - DataField::tr("Switch ").toLatin1() + sw.toString(board) + DataField::tr(" cannot be exported on this board!").toLatin1()), - sw(sw), - _switch(0), - board(board) - { - } - - virtual ~SwitchField() - { - } - - void beforeExport() override - { - _switch = sw.toValue(); - ConversionField< SignedField >::beforeExport(); - } - - void afterImport() override - { - ConversionField< SignedField >::afterImport(); - sw = RawSwitch(_switch); - qCDebug(eepromImport) << QString("imported %1: %2").arg(ConversionField< SignedField >::internalField.getName()).arg(sw.toString(board)); - } - - protected: - RawSwitch & sw; - int _switch; - Board::Type board; -}; - -template -class SourceField: public ConversionField< UnsignedField > { - public: - SourceField(DataField * parent, RawSource & source, Board::Type board, unsigned int version, unsigned int variant, unsigned long flags=0): - ConversionField< UnsignedField >(parent, _source, SourcesConversionTable::getInstance(board, version, variant, flags), - DataField::tr("Source").toLatin1(), DataField::tr("Source %1 cannot be exported on this board!").arg(source.toString())), - source(source), - _source(0) - { - } - - virtual ~SourceField() - { - } - - void beforeExport() override - { - _source = source.toValue(); - ConversionField< UnsignedField >::beforeExport(); - } - - void afterImport() override - { - ConversionField< UnsignedField >::afterImport(); - source = RawSource(_source); - qCDebug(eepromImport) << QString("imported %1: %2").arg(ConversionField< UnsignedField >::internalField.getName()).arg(source.toString()); - } - - protected: - RawSource & source; - unsigned int _source; -}; - - -int smallGvarImport(int gvar) -{ - if (gvar < -10000) { - gvar = 128 + gvar + 10000; - } - else if (gvar > 10000) { - gvar = -128 +gvar - 10001; - } - return gvar; -} - -int smallGvarExport(int gvar) -{ - if (gvar > 110) { - gvar = gvar - 128 - 10000; - } - else if (gvar < -110) { - gvar = gvar + 128 + 10001; - } - return gvar; -} - -void splitGvarParam(const int gvar, int & _gvar, unsigned int & _gvarParam, const Board::Type board, const int version) -{ - if (gvar < -10000) { - _gvarParam = 0; - _gvar = 256 + gvar + 10000; - } - else if (gvar > 10000) { - _gvarParam = 1; - _gvar = gvar - 10001; - } - else { - if (gvar < 0) _gvarParam = 1; - else _gvarParam = 0; - _gvar = gvar; // save routine throws away all unused bits; therefore no 2er complement compensation needed here - } -} - -void concatGvarParam(int & gvar, const int _gvar, const unsigned int _gvarParam, const Board::Type board, const int version) -{ - gvar = _gvar; - if (gvar<0) gvar+=256; // remove 2er complement, because 8bit part is in this case unsigned - if (_gvarParam) { // here is the real sign bit - gvar|=-256; // set all higher bits to simulate negative value - } - - if (gvar>245) { - gvar = gvar-256 - 10000; - } - else if (gvar<-245) { - gvar = gvar+256 + 10001; - } - -} - -void exportGvarParam(const int gvar, int & _gvar, int version) -{ - int GV1 = 1024; - - if (gvar < -10000) { - _gvar = GV1 + gvar + 10000; - } - else if (gvar > 10000) { - _gvar = GV1 + gvar - 10001; - } - else { - _gvar = gvar; - } -} - -void importGvarParam(int & gvar, const int _gvar, int version) -{ - int GV1 = 1024; - - if (_gvar >= GV1) { - gvar = 10001 + _gvar - GV1; - } - else if (_gvar >= GV1-9) { - gvar = -10000 + _gvar - GV1; - } - else if (_gvar < -GV1) { - gvar = -10000 + _gvar + GV1 + 1; - } - else if (_gvar < -GV1+9) { - gvar = 10000 + _gvar + GV1 + 1; - } - else { - gvar = _gvar; - } - - // qDebug() << QString("import") << _gvar << gvar; -} - -class CurveReferenceField: public TransformedField { - public: - CurveReferenceField(DataField * parent, CurveReference & curve, Board::Type board, unsigned int version): - TransformedField(parent, internalField), - internalField(this), - curve(curve), - _curve_type(0), - _curve_value(0) - { - internalField.Append(new UnsignedField<8>(this, _curve_type)); - internalField.Append(new SignedField<8>(this, _curve_value)); - } - - void beforeExport() override - { - if (curve.value != 0) { - _curve_type = (unsigned int)curve.type; - _curve_value = smallGvarImport(curve.value); - } - else { - _curve_type = 0; - _curve_value = 0; - } - } - - void afterImport() override - { - curve.type = (CurveReference::CurveRefType)_curve_type; - curve.value = smallGvarExport(_curve_value); - // 2,11 num or gvar changed to SourceNumRef - if ((curve.type == CurveReference::CURVE_REF_DIFF || curve.type == CurveReference::CURVE_REF_EXPO) && - AdjustmentReference(curve.value).type == AdjustmentReference::ADJUST_REF_GVAR) - curve.value = RawSource(SOURCE_TYPE_GVAR, AdjustmentReference(curve.value).value).toValue(); - - qCDebug(eepromImport) << QString("imported CurveReference(%1)").arg(curve.toString()); - } - - protected: - StructField internalField; - CurveReference & curve; - unsigned int _curve_type; - int _curve_value; -}; - -static int exportHeliInversionWeight(int source) { - return (source < 0) ? 1 : 0; -} - -static int importHeliInversionWeight(int source) { - return source ? -100: 100; -} - -class HeliField: public StructField { - public: - HeliField(DataField * parent, SwashRingData & heli, Board::Type board, unsigned int version, unsigned int variant): - StructField(parent, "Heli") - { - if (version >= 218 || IS_STM32(board)) { - Append(new UnsignedField<8>(this, heli.type)); - Append(new UnsignedField<8>(this, heli.value)); - Append(new SourceField<8>(this, heli.collectiveSource, board, version, variant)); - Append(new SourceField<8>(this, heli.aileronSource, board, version, variant)); - Append(new SourceField<8>(this, heli.elevatorSource, board, version, variant)); - Append(new SignedField<8>(this, heli.collectiveWeight)); - Append(new SignedField<8>(this, heli.aileronWeight)); - Append(new SignedField<8>(this, heli.elevatorWeight)); - } - else { - Append(new ConversionField< SignedField<1> >(this, heli.elevatorWeight, exportHeliInversionWeight, importHeliInversionWeight)); - Append(new ConversionField< SignedField<1> >(this, heli.aileronWeight, exportHeliInversionWeight, importHeliInversionWeight)); - Append(new ConversionField< SignedField<1> >(this, heli.collectiveWeight, exportHeliInversionWeight, importHeliInversionWeight)); - Append(new UnsignedField<5>(this, heli.type)); - Append(new SourceField<8>(this, heli.collectiveSource, board, version, variant)); - //, FLAG_NOSWITCHES)); Fix shift in collective - Append(new UnsignedField<8>(this, heli.value)); - } - } -}; - -class FlightModeField: public TransformedField { - public: - FlightModeField(DataField * parent, FlightModeData & phase, int index, Board::Type board, unsigned int version): - TransformedField(parent, internalField), - internalField(this, "FlightMode"), - phase(phase), - index(index), - board(board), - version(version), - rotencCount(ROTENC_COUNT(board, version)) - { - if (version >= 218) { - for (int i=0; i(this, phase.trim[i])); - internalField.Append(new UnsignedField<5>(this, trimMode[i])); - } - } - else if (IS_TARANIS(board)) { - for (int i=0; i(this, phase.trim[i])); - internalField.Append(new UnsignedField<5>(this, trimMode[i])); - } - } - else { - for (int i=0; i(this, trimBase[i])); - } - } - if (version >= 218) { - if (version >= 220) { - if (HAS_LARGE_LCD(board)) - internalField.Append(new CharField<10>(this, phase.name, "Flight mode name")); - else - internalField.Append(new CharField<6>(this, phase.name, "Flight mode name")); - } - else { - if (HAS_LARGE_LCD(board)) - internalField.Append(new ZCharField<10>(this, phase.name, "Flight mode name")); - else - internalField.Append(new ZCharField<6>(this, phase.name, "Flight mode name")); - } - internalField.Append(new SwitchField<9>(this, phase.swtch, board, version)); - internalField.Append(new SpareBitsField<7>(this)); - } - else { - internalField.Append(new SwitchField<8>(this, phase.swtch, board, version)); - if (HAS_LARGE_LCD(board)) - internalField.Append(new ZCharField<10>(this, phase.name)); - else - internalField.Append(new ZCharField<6>(this, phase.name)); - } - internalField.Append(new UnsignedField<8>(this, phase.fadeIn)); - internalField.Append(new UnsignedField<8>(this, phase.fadeOut)); - - if (version < 219) { - for (int i = 0; i < rotencCount; i++) { - internalField.Append(new SignedField<16>(this, phase.rotaryEncoders[i])); - } - } - - for (int i = 0; i < MAX_GVARS(board, version); i++) { - internalField.Append(new SignedField<16>(this, phase.gvars[i])); - } - } - - void beforeExport() override - { - for (int i=0; i= 218) { - if (phase.trimMode[i] < 0) - trimMode[i] = TRIM_MODE_NONE; - else - trimMode[i] = 2*phase.trimRef[i] + phase.trimMode[i]; - } - else { - int trim; - if (phase.trimMode[i] < 0) - trim = 0; - else if (phase.trimRef[i] != index) - trim = 501 + phase.trimRef[i] - (phase.trimRef[i] > index ? 1 : 0); - else - trim = std::max(-500, std::min(500, phase.trim[i])); - trimBase[i] = trim; - } - } - } - - void afterImport() override - { - for (int i=0; i= 218) { - if (trimMode[i] == TRIM_MODE_NONE) { - phase.trimMode[i] = -1; - } - else { - phase.trimMode[i] = trimMode[i] % 2; - phase.trimRef[i] = trimMode[i] / 2; - } - } - else { - if (phase.swtch == RawSwitch(SWITCH_TYPE_NONE) && index > 0) { - phase.trimRef[i] = 0; - phase.trimMode[i] = 0; - phase.trim[i] = 0; - } - else { - int trim = trimBase[i]; - if (trim > 500) { - phase.trimRef[i] = trim - 501; - if (phase.trimRef[i] >= index) - phase.trimRef[i] += 1; - phase.trimMode[i] = 0; - phase.trim[i] = 0; - } - else { - phase.trimRef[i] = index/*own trim*/; - phase.trimMode[i] = 0; - phase.trim[i] = trim; - } - } - } - } - qCDebug(eepromImport) << QString("imported %1: '%2'").arg(internalField.getName()).arg(phase.name); - } - - protected: - StructField internalField; - FlightModeData & phase; - int index; - Board::Type board; - unsigned int version; - int rotencCount; - int trimBase[CPN_MAX_TRIMS]; - int trimExt[CPN_MAX_TRIMS]; - unsigned int trimMode[CPN_MAX_TRIMS]; -}; - -class MixField: public TransformedField { - public: - MixField(DataField * parent, MixData & mix, Board::Type board, unsigned int version, ModelData * model): - TransformedField(parent, internalField), - internalField(this, "Mix"), - mix(mix), - board(board), - version(version), - model(model) - { - if (version >= 218) { - internalField.Append(new SignedField<11>(this, _weight)); - internalField.Append(new UnsignedField<5>(this, _destCh)); - internalField.Append(new SourceField<10>(this, mix.srcRaw, board, version, FLAG_NOTELEMETRY)); - internalField.Append(new UnsignedField<1>(this, (unsigned int &)mix.carryTrim)); - internalField.Append(new UnsignedField<2>(this, mix.mixWarn)); - internalField.Append(new UnsignedField<2>(this, (unsigned int &)mix.mltpx)); - internalField.Append(new SpareBitsField<1>(this)); - internalField.Append(new SignedField<14>(this, _offset)); - internalField.Append(new SwitchField<9>(this, mix.swtch, board, version)); - internalField.Append(new UnsignedField<9>(this, mix.flightModes)); - internalField.Append(new CurveReferenceField(this, mix.curve, board, version)); - internalField.Append(new UnsignedField<8>(this, mix.delayUp)); - internalField.Append(new UnsignedField<8>(this, mix.delayDown)); - internalField.Append(new UnsignedField<8>(this, mix.speedUp)); - internalField.Append(new UnsignedField<8>(this, mix.speedDown)); - if (version >= 220) - internalField.Append(new CharField<6>(this, mix.name)); - else { - if (IS_FAMILY_HORUS_OR_T16(board)) - internalField.Append(new ZCharField<6>(this, mix.name)); - else if (HAS_LARGE_LCD(board) && version <= 218) - internalField.Append(new ZCharField<8>(this, mix.name)); - else - internalField.Append(new ZCharField<6>(this, mix.name)); - } - } - else if (IS_TARANIS(board)) { - internalField.Append(new UnsignedField<8>(this, _destCh)); - internalField.Append(new UnsignedField<9>(this, mix.flightModes)); - internalField.Append(new UnsignedField<2>(this, (unsigned int &)mix.mltpx)); - internalField.Append(new UnsignedField<1>(this, (unsigned int &)mix.carryTrim)); - internalField.Append(new UnsignedField<4>(this, mix.mixWarn)); - internalField.Append(new SignedField<16>(this, _weight)); - internalField.Append(new SourceField<10>(this, mix.srcRaw, board, version, FLAG_NOTELEMETRY)); - internalField.Append(new SignedField<14>(this, _offset)); - internalField.Append(new SwitchField<8>(this, mix.swtch, board, version)); - internalField.Append(new CurveReferenceField(this, mix.curve, board, version)); - internalField.Append(new UnsignedField<8>(this, mix.delayUp)); - internalField.Append(new UnsignedField<8>(this, mix.delayDown)); - internalField.Append(new UnsignedField<8>(this, mix.speedUp)); - internalField.Append(new UnsignedField<8>(this, mix.speedDown)); - internalField.Append(new ZCharField<8>(this, mix.name)); - } - else { - internalField.Append(new UnsignedField<5>(this, _destCh)); - internalField.Append(new UnsignedField<3>(this, mix.mixWarn)); - internalField.Append(new UnsignedField<9>(this, mix.flightModes)); - internalField.Append(new BoolField<1>(this, _curveMode)); - internalField.Append(new BoolField<1>(this, mix.noExpo)); - internalField.Append(new SignedField<3>(this, mix.carryTrim)); - internalField.Append(new UnsignedField<2>(this, (unsigned int &)mix.mltpx)); - internalField.Append(new SignedField<16>(this, _weight)); - internalField.Append(new SwitchField<8>(this, mix.swtch, board, version)); - internalField.Append(new SignedField<8>(this, _curveParam)); - internalField.Append(new UnsignedField<8>(this, mix.delayUp)); - internalField.Append(new UnsignedField<8>(this, mix.delayDown)); - internalField.Append(new UnsignedField<8>(this, mix.speedUp)); - internalField.Append(new UnsignedField<8>(this, mix.speedDown)); - internalField.Append(new SourceField<8>(this, mix.srcRaw, board, version, FLAG_NOTELEMETRY)); - internalField.Append(new SignedField<16>(this, _offset)); - internalField.Append(new ZCharField<6>(this, mix.name)); - } - } - - void beforeExport() override - { - if (mix.destCh && mix.srcRaw.type != SOURCE_TYPE_NONE) { - _destCh = mix.destCh - 1; - if (mix.curve.type == CurveReference::CURVE_REF_CUSTOM) { - _curveMode = true; - if (mix.curve.value > 0) { - _curveParam = 6 + mix.curve.value; - } - else { - _curveParam = mix.curve.value; - } - } - else if (mix.curve.type == CurveReference::CURVE_REF_FUNC) { - _curveMode = true; - _curveParam = mix.curve.value; - } - else if (mix.curve.type == CurveReference::CURVE_REF_DIFF) { - _curveMode = false; - _curveParam = smallGvarImport(mix.curve.value); - } - } - else { - mix.clear(); - _destCh = 0; - _curveMode = false; - _curveParam = 0; - } - - exportGvarParam(mix.weight, _weight, version); - if (version >= 214) - exportGvarParam(mix.sOffset, _offset, version); - else - splitGvarParam(mix.sOffset, _offset, _offsetMode, board, version); - } - - void afterImport() override - { - if (mix.srcRaw.type != SOURCE_TYPE_NONE) { - mix.destCh = _destCh + 1; - if (!IS_STM32(board) && version < 218) { - if (!_curveMode) - mix.curve = CurveReference(CurveReference::CURVE_REF_DIFF, smallGvarExport(_curveParam)); - else if (_curveParam > 6) - mix.curve = CurveReference(CurveReference::CURVE_REF_CUSTOM, _curveParam-6); - else if (_curveParam < 0) - mix.curve = CurveReference(CurveReference::CURVE_REF_CUSTOM, _curveParam); - else - mix.curve = CurveReference(CurveReference::CURVE_REF_FUNC, _curveParam); - } - } - - // 2.11 - if ((mix.curve.type == CurveReference::CURVE_REF_DIFF || mix.curve.type == CurveReference::CURVE_REF_EXPO) && - AdjustmentReference(mix.curve.value).type == AdjustmentReference::ADJUST_REF_GVAR) - mix.curve.value = RawSource(SOURCE_TYPE_GVAR, AdjustmentReference(mix.curve.value).value).toValue(); - - importGvarParam(mix.weight, _weight, version); - // 2.11 - if (AdjustmentReference(mix.weight).type == AdjustmentReference::ADJUST_REF_GVAR) - mix.weight = RawSource(SOURCE_TYPE_GVAR, AdjustmentReference(mix.weight).value).toValue(); - - importGvarParam(mix.sOffset, _offset, version); - // 2.11 - if (AdjustmentReference(mix.sOffset).type == AdjustmentReference::ADJUST_REF_GVAR) - mix.sOffset = RawSource(SOURCE_TYPE_GVAR, AdjustmentReference(mix.sOffset).value).toValue(); - - qCDebug(eepromImport) << QString("imported %1: ch %2, name '%3'").arg(internalField.getName()).arg(mix.destCh).arg(mix.name); - } - - protected: - StructField internalField; - MixData & mix; - Board::Type board; - unsigned int version; - ModelData * model; - unsigned int _destCh = 0; - bool _curveMode = false; - int _curveParam = 0; - int _weight = 0; - int _offset = 0; - unsigned int _offsetMode = 0; -}; - -class InputField: public TransformedField { - public: - InputField(DataField * parent, ExpoData & expo, Board::Type board, unsigned int version): - TransformedField(parent, internalField), - internalField(this, "Input"), - expo(expo), - board(board), - version(version) - { - if (version >= 218) { - internalField.Append(new UnsignedField<2>(this, expo.mode, "Mode")); - internalField.Append(new UnsignedField<14>(this, expo.scale, "Scale")); - internalField.Append(new SourceField<10>(this, expo.srcRaw, board, version, 0)); - internalField.Append(new SignedField<6>(this, expo.carryTrim, "CarryTrim")); - internalField.Append(new UnsignedField<5>(this, expo.chn, "Channel")); - internalField.Append(new SwitchField<9>(this, expo.swtch, board, version)); - internalField.Append(new UnsignedField<9>(this, expo.flightModes)); - internalField.Append(new SignedField<8>(this, _weight, "Weight")); - internalField.Append(new SpareBitsField<1>(this)); - if (version >= 220) - internalField.Append(new CharField<6>(this, expo.name)); - else { - if (IS_FAMILY_HORUS_OR_T16(board)) - internalField.Append(new ZCharField<6>(this, expo.name)); - else if (HAS_LARGE_LCD(board) && version <= 218) - internalField.Append(new ZCharField<8>(this, expo.name)); - else - internalField.Append(new ZCharField<6>(this, expo.name)); - } - internalField.Append(new SignedField<8>(this, _offset, "Offset")); - internalField.Append(new CurveReferenceField(this, expo.curve, board, version)); - } - else if (IS_TARANIS(board)) { - internalField.Append(new SourceField<10>(this, expo.srcRaw, board, version, 0)); - internalField.Append(new UnsignedField<14>(this, expo.scale, "Scale")); - internalField.Append(new UnsignedField<8>(this, expo.chn, "Channel")); - internalField.Append(new SwitchField<8>(this, expo.swtch, board, version)); - internalField.Append(new UnsignedField<16>(this, expo.flightModes)); - internalField.Append(new SignedField<8>(this, _weight, "Weight")); - internalField.Append(new SignedField<6>(this, expo.carryTrim, "CarryTrim")); - internalField.Append(new UnsignedField<2>(this, expo.mode, "Mode")); - internalField.Append(new ZCharField<8>(this, expo.name)); - internalField.Append(new SignedField<8>(this, _offset, "Offset")); - internalField.Append(new CurveReferenceField(this, expo.curve, board, version)); - } - else { - internalField.Append(new UnsignedField<2>(this, expo.mode, "Mode")); - internalField.Append(new UnsignedField<3>(this, expo.chn, "Channel")); - internalField.Append(new BoolField<2>(this, _curveMode)); - internalField.Append(new UnsignedField<9>(this, expo.flightModes, "Phases")); - internalField.Append(new SwitchField<8>(this, expo.swtch, board, version)); - internalField.Append(new SignedField<8>(this, _weight, "Weight")); - internalField.Append(new ZCharField<6>(this, expo.name)); - internalField.Append(new SignedField<8>(this, _curveParam)); - } - } - - void beforeExport() override - { - _weight = smallGvarImport(expo.weight); - - if (IS_HORUS_OR_TARANIS(board) || version >= 218) { - _offset = smallGvarImport(expo.offset); - } - - if (!IS_TARANIS(board) && version < 218) { - if (expo.curve.type==CurveReference::CURVE_REF_FUNC && expo.curve.value) { - _curveMode = true; - _curveParam = expo.curve.value; - } - else if (expo.curve.type==CurveReference::CURVE_REF_CUSTOM && expo.curve.value) { - _curveMode = true; - _curveParam = expo.curve.value+6; - } - else { - _curveMode = false; - _curveParam = smallGvarImport(expo.curve.value); - } - } - } - - void afterImport() override - { - if (!IS_STM32(board) && expo.mode) { - expo.srcRaw = RawSource(SOURCE_TYPE_INPUT, expo.chn); - } - - expo.weight = smallGvarExport(_weight); - // 2.11 - if (AdjustmentReference(expo.weight).type == AdjustmentReference::ADJUST_REF_GVAR) - expo.weight = RawSource(SOURCE_TYPE_GVAR, AdjustmentReference(expo.weight).value).toValue(); - - if (IS_STM32(board) || version >= 218) { - expo.offset = smallGvarExport(_offset); - // 2.11 - if (AdjustmentReference(expo.offset).type == AdjustmentReference::ADJUST_REF_GVAR) - expo.offset = RawSource(SOURCE_TYPE_GVAR, AdjustmentReference(expo.offset).value).toValue(); - } - - if (!IS_TARANIS(board) && version < 218) { - if (!_curveMode) - expo.curve = CurveReference(CurveReference::CURVE_REF_EXPO, smallGvarExport(_curveParam)); - else if (_curveParam > 6) - expo.curve = CurveReference(CurveReference::CURVE_REF_CUSTOM, _curveParam-6); - else - expo.curve = CurveReference(CurveReference::CURVE_REF_FUNC, _curveParam); - } - - // 2.11 - if ((expo.curve.type == CurveReference::CURVE_REF_DIFF || expo.curve.type == CurveReference::CURVE_REF_EXPO) && - AdjustmentReference(expo.curve.value).type == AdjustmentReference::ADJUST_REF_GVAR) - expo.curve.value = RawSource(SOURCE_TYPE_GVAR, AdjustmentReference(expo.curve.value).value).toValue(); - - - qCDebug(eepromImport) << QString("imported %1: ch %2 name '%3'").arg(internalField.getName()).arg(expo.chn).arg(expo.name); - } - - protected: - StructField internalField; - ExpoData & expo; - Board::Type board; - unsigned int version; - bool _curveMode = false; - int _weight = 0; - int _offset = 0; - int _curveParam = 0; -}; - -class LimitField: public StructField { - public: - template - static int exportLimitValue(int value) - { - if (value > 10000) { - return -GV1 + value - 10001; - } - if (value < -10000) { - return GV1 + value + 10000; - } - return value + shift; - } - - template - static int importLimitValue(int value) - { - if (value >= GV1) { - return 10001 + value - GV1; - } - if (value >= GV1-9) { - return -10000 + value - GV1; - } - if (value < -GV1) { - return -10000 + value + GV1 + 1; - } - if (value < -GV1+9) { - return 10000 + value + GV1 + 1; - } - return value - shift; - } - - LimitField(DataField * parent, LimitData & limit, Board::Type board, unsigned int version): - StructField(parent, "Limit") - { - if (version >= 218) { - Append(new ConversionField< SignedField<11> >(this, limit.min, exportLimitValue<1000, 1024>, importLimitValue<1000, 1024>)); - Append(new ConversionField< SignedField<11> >(this, limit.max, exportLimitValue<-1000, 1024>, importLimitValue<-1000, 1024>)); - Append(new SignedField<10>(this, limit.ppmCenter)); - Append(new ConversionField< SignedField<11> >(this, limit.offset, exportLimitValue<0, 1024>, importLimitValue<0, 1024>)); - Append(new BoolField<1>(this, limit.symetrical)); - Append(new BoolField<1>(this, limit.revert)); - Append(new SpareBitsField<3>(this)); - Append(new SignedField<8>(this, limit.curve.value)); - if (version >= 220) { - if (HAS_LARGE_LCD(board)) - Append(new CharField<6>(this, limit.name)); - else - Append(new CharField<4>(this, limit.name)); - } - else { - if (HAS_LARGE_LCD(board)) - Append(new ZCharField<6>(this, limit.name)); - else - Append(new ZCharField<4>(this, limit.name)); - } - } - else if (IS_TARANIS(board)) { - Append(new ConversionField< SignedField<11> >(this, limit.min, exportLimitValue<1000, 1024>, importLimitValue<1000, 1024>)); - Append(new ConversionField< SignedField<11> >(this, limit.max, exportLimitValue<-1000, 1024>, importLimitValue<-1000, 1024>)); - Append(new SignedField<10>(this, limit.ppmCenter)); - Append(new ConversionField< SignedField<11> >(this, limit.offset, exportLimitValue<0, 1024>, importLimitValue<0, 1024>)); - Append(new BoolField<1>(this, limit.symetrical)); - Append(new BoolField<1>(this, limit.revert)); - Append(new SpareBitsField<3>(this)); - Append(new SignedField<8>(this, limit.curve.value)); - Append(new ZCharField<6>(this, limit.name)); - } - else { - Append(new ConversionField< SignedField<8> >(this, limit.min, +100, 10)); - Append(new ConversionField< SignedField<8> >(this, limit.max, -100, 10)); - Append(new SignedField<8>(this, limit.ppmCenter)); - Append(new SignedField<14>(this, limit.offset)); - Append(new BoolField<1>(this, limit.symetrical)); - Append(new BoolField<1>(this, limit.revert)); - if (HAS_LARGE_LCD(board)) { - Append(new ZCharField<6>(this, limit.name)); - } - } - } -}; - -class CurvesField: public TransformedField { - public: - CurvesField(DataField * parent, CurveData * curves, Board::Type board, unsigned int version): - TransformedField(parent, internalField), - internalField(this, "Curves"), - curves(curves), - board(board), - version(version), - maxCurves(MAX_CURVES(board, version)), - maxPoints(512) - { - for (int i=0; i= 218) { - internalField.Append(new UnsignedField<1>(this, (unsigned int &)curves[i].type)); - internalField.Append(new BoolField<1>(this, curves[i].smooth)); - internalField.Append(new ConversionField< SignedField<6> >(this, curves[i].count, -5)); - if (version >= 220) - internalField.Append(new CharField<3>(this, curves[i].name)); - else - internalField.Append(new ZCharField<3>(this, curves[i].name)); - } - else if (IS_TARANIS(board)) { - internalField.Append(new UnsignedField<3>(this, (unsigned int &)curves[i].type)); - internalField.Append(new BoolField<1>(this, curves[i].smooth)); - internalField.Append(new SpareBitsField<4>(this)); - internalField.Append(new ConversionField< SignedField<8> >(this, curves[i].count, -5)); - } - else { - internalField.Append(new SignedField<16>(this, _curves[i])); - } - } - - for (int i=0; i(this, _points[i])); - } - } - - void beforeExport() override - { - memset(_points, 0, sizeof(_points)); - - int * cur = &_points[0]; - int offset = 0; - - for (int i=0; itype == CurveData::CURVE_TYPE_CUSTOM ? curve->count * 2 - 2 : curve->count); - if (offset > maxPoints) { - setError(DataField::tr("OpenTX only accepts %1 points in all curves").arg(maxPoints)); - break; - } - } - else { - offset += (curve->type == CurveData::CURVE_TYPE_CUSTOM ? curve->count * 2 - 2 : curve->count) - 5; - if (offset > maxPoints - 5 * maxCurves) { - setError(DataField::tr("OpenTx only accepts %1 points in all curves").arg(maxPoints)); - break; - } - _curves[i] = offset; - } - for (int j=0; jcount; j++) { - *cur++ = curve->points[j].y; - } - if (curve->type == CurveData::CURVE_TYPE_CUSTOM) { - for (int j=1; jcount-1; j++) { - *cur++ = curve->points[j].x; - } - } - } - } - - void afterImport() override - { - int * cur = &_points[0]; - - for (int i=0; icount = (size / 2) + 1; - curve->type = CurveData::CURVE_TYPE_CUSTOM; - } - else { - curve->count = size; - curve->type = CurveData::CURVE_TYPE_STANDARD; - } - } - - if (curve->count > 17) { - qDebug() << "Wrong points count" << curve->count; - curve->count = 0; - for (int j=0; jclear(5); - } - return; - } - - for (int j=0; jcount; j++) { - curve->points[j].y = *cur++; - } - - if (curve->type == CurveData::CURVE_TYPE_CUSTOM) { - curve->points[0].x = -100; - for (int j=1; jcount-1; j++) - curve->points[j].x = *cur++; - curve->points[curve->count-1].x = +100; - } - qCDebug(eepromImport) << QString("imported curve: %3 points").arg(curve->count); - } - } - - protected: - StructField internalField; - CurveData * curves; - Board::Type board; - unsigned int version; - int maxCurves; - int maxPoints; - int _curves[CPN_MAX_CURVES] = {}; - int _points[CPN_MAX_CURVES*CPN_MAX_POINTS*2] = {}; -}; - -class LogicalSwitchesFunctionsTable: public ConversionTable { - - public: - LogicalSwitchesFunctionsTable(Board::Type board, unsigned int version) - { - int val=0; - addConversion(LS_FN_OFF, val++); - addConversion(LS_FN_VEQUAL, val++); - addConversion(LS_FN_VALMOSTEQUAL, val++); - addConversion(LS_FN_VPOS, val++); - addConversion(LS_FN_VNEG, val++); - val++; // later RANGE - addConversion(LS_FN_APOS, val++); - addConversion(LS_FN_ANEG, val++); - addConversion(LS_FN_AND, val++); - addConversion(LS_FN_OR, val++); - addConversion(LS_FN_XOR, val++); - addConversion(LS_FN_EDGE, val++); - addConversion(LS_FN_EQUAL, val++); - addConversion(LS_FN_GREATER, val++); - addConversion(LS_FN_LESS, val++); - addConversion(LS_FN_DPOS, val++); - addConversion(LS_FN_DAPOS, val++); - addConversion(LS_FN_TIMER, val++); - addConversion(LS_FN_STICKY, val++); - } -}; - -class LogicalSwitchField: public TransformedField { - public: - LogicalSwitchField(DataField * parent, LogicalSwitchData & csw, Board::Type board, unsigned int version, unsigned int variant, ModelData * model=nullptr): - TransformedField(parent, internalField), - internalField(this, "LogicalSwitch"), - csw(csw), - board(board), - version(version), - variant(variant), - model(model), - functionsConversionTable(board, version), - sourcesConversionTable(SourcesConversionTable::getInstance(board, version, variant, 0)), - switchesConversionTable(SwitchesConversionTable::getInstance(board, version)) - { - if (version >= 218) { - internalField.Append(new ConversionField< UnsignedField<8> >(this, csw.func, &functionsConversionTable, "Function")); - internalField.Append(new SignedField<10>(this, v1)); - internalField.Append(new SignedField<10>(this, v3)); - internalField.Append(new ConversionField< SignedField<9> >(this, (int &)csw.andsw, switchesConversionTable, "AND switch")); - internalField.Append(new SpareBitsField<1>(this)); // TODO extra switch mode - internalField.Append(new SpareBitsField<2>(this)); - internalField.Append(new SignedField<16>(this, v2)); - } - else { - internalField.Append(new ConversionField< UnsignedField<6> >(this, csw.func, &functionsConversionTable, "Function")); - internalField.Append(new SignedField<10>(this, v1)); - internalField.Append(new SignedField<16>(this, v2)); - internalField.Append(new SignedField<16>(this, v3)); - } - - int scale = 0; - internalField.Append(new ConversionField< UnsignedField<8> >(this, csw.delay, 0, scale)); - internalField.Append(new ConversionField< UnsignedField<8> >(this, csw.duration, 0, scale)); - if (version == 217) { - internalField.Append(new ConversionField< SignedField<8> >(this, (int &)csw.andsw, switchesConversionTable, "AND switch")); - } - } - - ~LogicalSwitchField() override - = default; - - void beforeExport() override - { - if (csw.func == LS_FN_TIMER) { - v1 = csw.val1; - v2 = csw.val2; - } - else if (csw.func == LS_FN_EDGE) { - switchesConversionTable->exportValue(csw.val1, v1); - v2 = csw.val2; - v3 = csw.val3; - } - else if ((csw.func >= LS_FN_AND && csw.func <= LS_FN_XOR) || csw.func == LS_FN_STICKY) { - switchesConversionTable->exportValue(csw.val1, v1); - switchesConversionTable->exportValue(csw.val2, v2); - } - else if (csw.func >= LS_FN_EQUAL && csw.func <= LS_FN_ELESS) { - sourcesConversionTable->exportValue(csw.val1, v1); - sourcesConversionTable->exportValue(csw.val2, v2); - } - else if (csw.func != LS_FN_OFF) { - sourcesConversionTable->exportValue(csw.val1, v1); - v2 = csw.val2; - } - } - - void afterImport() override - { - if (csw.func == LS_FN_TIMER) { - csw.val1 = v1; - csw.val2 = v2; - } - else if (csw.func == LS_FN_EDGE) { - switchesConversionTable->importValue(v1, csw.val1); - csw.val2 = v2; - csw.val3 = v3; - } - else if ((csw.func >= LS_FN_AND && csw.func <= LS_FN_XOR) || csw.func == LS_FN_STICKY) { - switchesConversionTable->importValue(v1, csw.val1); - switchesConversionTable->importValue(v2, csw.val2); - } - else if (csw.func >= LS_FN_EQUAL && csw.func <= LS_FN_ELESS) { - sourcesConversionTable->importValue((uint32_t)v1, csw.val1); - sourcesConversionTable->importValue((uint32_t)v2, csw.val2); - } - else if (csw.func != LS_FN_OFF) { - sourcesConversionTable->importValue((uint32_t)v1, csw.val1); - csw.val2 = v2; - RawSource val1(csw.val1); - } - qCDebug(eepromImport) << QString("imported %1: %2").arg(internalField.getName()).arg(csw.funcToString()); - } - - protected: - StructField internalField; - LogicalSwitchData & csw; - Board::Type board; - unsigned int version; - unsigned int variant; - ModelData * model; - LogicalSwitchesFunctionsTable functionsConversionTable; - SourcesConversionTable * sourcesConversionTable; - SwitchesConversionTable * switchesConversionTable; - int v1 = 0; - int v2 = 0; - int v3 = 0; -}; - -class CustomFunctionsConversionTable: public ConversionTable { - - public: - CustomFunctionsConversionTable(Board::Type board, unsigned int version) - { - int val = 0; - - for (int i=0; i -class SwitchesWarningField: public TransformedField { - public: - SwitchesWarningField(DataField * parent, uint64_t & sw, Board::Type board, unsigned int version): - TransformedField(parent, internalField), - internalField(this, _sw, "SwitchesWarning"), - sw(sw), - board(board), - version(version) - { - } - - void beforeExport() override - { - _sw = sw; - } - - void afterImport() override - { - sw = _sw; - qCDebug(eepromImport) << QString("imported %1").arg(internalField.getName()); - } - - protected: - BaseUnsignedField internalField; - uint64_t & sw; - uint64_t _sw = 0; - Board::Type board; - unsigned int version; -}; - -class ArmCustomFunctionField: public TransformedField { - public: - ArmCustomFunctionField(DataField * parent, CustomFunctionData & fn, Board::Type board, unsigned int version, unsigned int variant): - TransformedField(parent, internalField), - internalField(this, "CustomFunction"), - fn(fn), - board(board), - version(version), - variant(variant), - functionsConversionTable(board, version), - sourcesConversionTable(SourcesConversionTable::getInstance(board, version, variant, 0)) - { - memset(_param, 0, sizeof(_param)); - - if (version >= 218) { - internalField.Append(new SwitchField<9>(this, fn.swtch, board, version)); - internalField.Append(new ConversionField< UnsignedField<7> >(this, _func, &functionsConversionTable, "Function", DataField::tr("OpenTX on this board doesn't accept this function"))); - } - else { - internalField.Append(new SwitchField<8>(this, fn.swtch, board, version)); - internalField.Append(new ConversionField< UnsignedField<8> >(this, _func, &functionsConversionTable, "Function", DataField::tr("OpenTX on this board doesn't accept this function"))); - } - - if (IS_TARANIS(board)) - internalField.Append(new CharField<8>(this, _param, false)); - else - internalField.Append(new CharField<6>(this, _param, false)); - - internalField.Append(new SignedField<8>(this, _active)); - } - - static bool hasRepeatParam(const CustomFunctionData & fn) - { - return (fn.func == FuncPlaySound || fn.func == FuncPlayPrompt || fn.func == FuncPlayValue || fn.func == FuncPlayHaptic || fn.func == FuncSetScreen); - } - - void beforeExport() override - { - if (fn.swtch.type != SWITCH_TYPE_NONE) { - _func = fn.func; - - if (hasRepeatParam(fn)) - _active = fn.repeatParam; - else - _active = (fn.enabled ? 1 : 0); - - if (fn.func >= FuncOverrideCH1 && fn.func <= FuncOverrideCHLast) { - *((uint16_t *)_param) = fn.param; - *((uint8_t *)(_param+3)) = fn.func - FuncOverrideCH1; - } - else if (fn.func >= FuncTrainer && fn.func <= FuncTrainerChannels) { - *((uint8_t *)(_param+3)) = fn.func - FuncTrainer; - } - else if (fn.func >= FuncSetTimer1 && fn.func <= FuncSetTimerLast) { - *((uint16_t *)_param) = fn.param; - *((uint8_t *)(_param+3)) = fn.func - FuncSetTimer1; - } - else if (fn.func >= FuncRangeCheckInternalModule && fn.func <= FuncRangeCheckExternalModule) { - *((uint16_t *)_param) = fn.func - FuncRangeCheckInternalModule; - } - else if (fn.func >= FuncBindInternalModule && fn.func <= FuncBindExternalModule) { - *((uint16_t *)_param) = fn.func - FuncBindInternalModule; - } - else if (fn.func == FuncPlayPrompt || fn.func == FuncBackgroundMusic || fn.func == FuncPlayScript) { - memcpy(_param, fn.paramarm, sizeof(_param)); - } - else if (fn.func >= FuncAdjustGV1 && fn.func <= FuncAdjustGVLast) { - *((uint8_t *)(_param+2)) = fn.adjustMode; - *((uint8_t *)(_param+3)) = fn.func - FuncAdjustGV1; - unsigned int value; - if (fn.adjustMode == FUNC_ADJUST_GVAR_SOURCE || fn.adjustMode == FUNC_ADJUST_GVAR_SOURCERAW) - sourcesConversionTable->exportValue(fn.param, (int &)value); - else if (fn.adjustMode == FUNC_ADJUST_GVAR_GVAR) - value = RawSource(fn.param).index; - else - value = fn.param; - *((uint16_t *)_param) = value; - } - else if (fn.func == FuncPlayValue || fn.func == FuncVolume || fn.func == FuncBacklight) { - unsigned int value; - sourcesConversionTable->exportValue(fn.param, (int &)value); - *((uint16_t *)_param) = value; - } - else if (fn.func == FuncReset) { - *((uint32_t *)_param) = fn.param; - } - else { - *((uint32_t *)_param) = fn.param; - } - } - } - - void afterImport() override - { - fn.func = (AssignFunc)_func; - - if (hasRepeatParam(fn)) - fn.repeatParam = _active; - else - fn.enabled = (_active & 0x01); - - unsigned int value=0, mode=0, index=0; - value = *((uint16_t *)_param); - mode = *((uint8_t *)(_param+2)); - index = *((uint8_t *)(_param+3)); - - if (fn.func >= FuncOverrideCH1 && fn.func <= FuncOverrideCHLast) { - fn.func = AssignFunc(fn.func + index); - fn.param = (int16_t)(uint16_t)value; - } - else if (fn.func >= FuncSetTimer1 && fn.func <= FuncSetTimerLast) { - fn.func = AssignFunc(fn.func + index); - fn.param = (int)value; - } - else if (fn.func >= FuncTrainer && fn.func <= FuncTrainerChannels) { - fn.func = AssignFunc(fn.func + index); - fn.param = value; - } - else if (fn.func == FuncPlayPrompt || fn.func == FuncBackgroundMusic || fn.func == FuncPlayScript) { - memcpy(fn.paramarm, _param, sizeof(fn.paramarm)); - } - else if (fn.func == FuncVolume || fn.func == FuncBacklight) { - sourcesConversionTable->importValue(value, (int &)fn.param); - } - else if (fn.func >= FuncAdjustGV1 && fn.func <= FuncAdjustGVLast) { - fn.func = AssignFunc(fn.func + index); - fn.adjustMode = mode; - if (fn.adjustMode == FUNC_ADJUST_GVAR_SOURCE || fn.adjustMode == FUNC_ADJUST_GVAR_SOURCERAW) - sourcesConversionTable->importValue(value, (int &)fn.param); - else if (fn.adjustMode == FUNC_ADJUST_GVAR_GVAR) - fn.param = RawSource(SOURCE_TYPE_GVAR, value + 1).toValue(); - else - fn.param = (int16_t)value; - } - else if (fn.func == FuncPlayValue) { - sourcesConversionTable->importValue(value, (int &)fn.param); - } - else if (fn.func == FuncReset) { - fn.param = value; - if (fn.param > 4) // EdgeTx 2.11 Trims inserted before telemetry - fn.param += 1; - } - else { - fn.param = value; - } - qCDebug(eepromImport) << QString("imported %1").arg(internalField.getName()); - } - - protected: - StructField internalField; - CustomFunctionData & fn; - Board::Type board; - unsigned int version; - unsigned int variant; - CustomFunctionsConversionTable functionsConversionTable; - SourcesConversionTable * sourcesConversionTable; - unsigned int _func = 0; - char _param[10] = {}; - int _active = 0; -}; - -class FrskyScreenField: public DataField { - public: - FrskyScreenField(DataField * parent, FrSkyScreenData & screen, Board::Type board, unsigned int version, unsigned int variant): - DataField(parent, "Frsky Screen"), - screen(screen), - board(board), - version(version), - none(this), - bars(this), - numbers(this), - script(this) - { - for (int i=0; i<4; i++) { - if (IS_TARANIS(board)) - bars.Append(new SourceField<16>(this, screen.body.bars[i].source, board, version, variant)); - else - bars.Append(new SourceField<8>(this, screen.body.bars[i].source, board, version, variant)); - bars.Append(new SignedField<16>(this, screen.body.bars[i].barMin)); - bars.Append(new SignedField<16>(this, screen.body.bars[i].barMax)); - } - - int columns = (HAS_LARGE_LCD(board) ? 3 : 2); - for (int i=0; i<4; i++) { - for (int j=0; j(this, screen.body.lines[i].source[j], board, version, variant)); - else - numbers.Append(new SourceField<8>(this, screen.body.lines[i].source[j], board, version, variant)); - } - } - for (unsigned i=numbers.size(); i(this)); - } - - if (IS_TARANIS(board)) { - script.Append(new CharField<8>(this, screen.body.script.filename, true, "Script name")); - script.Append(new SpareBitsField<16*8>(this)); - } - - if (IS_TARANIS(board)) - none.Append(new SpareBitsField<24*8>(this)); - else - none.Append(new SpareBitsField<20*8>(this)); - } - - void ExportBits(QBitArray & output) override - { - if (screen.type == TELEMETRY_SCREEN_SCRIPT) - script.ExportBits(output); - else if (screen.type == TELEMETRY_SCREEN_NUMBERS) - numbers.ExportBits(output); - else if (screen.type == TELEMETRY_SCREEN_BARS) - bars.ExportBits(output); - else - none.ExportBits(output); - } - - void ImportBits(const QBitArray & input) override - { - qCDebug(eepromImport) << QString("importing %1: type: %2").arg(name).arg(screen.type); - - // NOTA: screen.type should have been imported first! - if (screen.type == TELEMETRY_SCREEN_SCRIPT) - script.ImportBits(input); - else if (screen.type == TELEMETRY_SCREEN_NUMBERS) - numbers.ImportBits(input); - else if (screen.type == TELEMETRY_SCREEN_BARS) - bars.ImportBits(input); - else - none.ImportBits(input); - } - - unsigned int size() override - { - // NOTA: screen.type should have been imported first! - if (screen.type == TELEMETRY_SCREEN_SCRIPT) - return script.size(); - else if (screen.type == TELEMETRY_SCREEN_NUMBERS) - return numbers.size(); - else if (screen.type == TELEMETRY_SCREEN_BARS) - return bars.size(); - else - return none.size(); - } - - protected: - FrSkyScreenData & screen; - Board::Type board; - unsigned int version; - StructField none; - StructField bars; - StructField numbers; - StructField script; -}; - -class RSSIConversionTable: public ConversionTable -{ - public: - explicit RSSIConversionTable(int index) - { - addConversion(0, 2-index); - addConversion(1, 3-index); - addConversion(2, index ? 3 : 0); - addConversion(3, 1-index); - } - - RSSIConversionTable() - = default; -}; - -class TelemetryVarioSourceConversionTable: public ConversionTable -{ - public: - TelemetryVarioSourceConversionTable(Board::Type board, unsigned int version) - { - int val = 0; - if (!IS_HORUS_OR_TARANIS(board)) { - addConversion(TELEMETRY_VARIO_SOURCE_ALTI, val++); - addConversion(TELEMETRY_VARIO_SOURCE_ALTI_PLUS, val++); - } - addConversion(TELEMETRY_VARIO_SOURCE_VSPEED, val++); - addConversion(TELEMETRY_VARIO_SOURCE_A1, val++); - addConversion(TELEMETRY_VARIO_SOURCE_A2, val++); - if (IS_HORUS_OR_TARANIS(board)) { - addConversion(TELEMETRY_VARIO_SOURCE_DTE, val++); - } - } -}; - -class TelemetryVoltsSourceConversionTable: public ConversionTable -{ - public: - TelemetryVoltsSourceConversionTable(Board::Type board, unsigned int version) - { - int val = 0; - addConversion(TELEMETRY_VOLTS_SOURCE_A1, val++); - addConversion(TELEMETRY_VOLTS_SOURCE_A2, val++); - addConversion(TELEMETRY_VOLTS_SOURCE_A3, val++); - addConversion(TELEMETRY_VOLTS_SOURCE_A4, val++); - addConversion(TELEMETRY_VOLTS_SOURCE_FAS, val++); - addConversion(TELEMETRY_VOLTS_SOURCE_CELLS, val++); - } -}; - -class ScreenTypesConversionTable: public ConversionTable -{ - public: - ScreenTypesConversionTable(Board::Type board, unsigned int version) - { - int val = 0; - addConversion(TELEMETRY_SCREEN_NONE, val++); - addConversion(TELEMETRY_SCREEN_NUMBERS, val++); - addConversion(TELEMETRY_SCREEN_BARS, val++); - } -}; - -class TelemetryCurrentSourceConversionTable: public ConversionTable -{ - public: - TelemetryCurrentSourceConversionTable(Board::Type board, unsigned int version) - { - int val = 0; - addConversion(TELEMETRY_CURRENT_SOURCE_NONE, val++); - addConversion(TELEMETRY_CURRENT_SOURCE_A1, val++); - addConversion(TELEMETRY_CURRENT_SOURCE_A2, val++); - addConversion(TELEMETRY_CURRENT_SOURCE_A3, val++); - addConversion(TELEMETRY_CURRENT_SOURCE_A4, val++); - addConversion(TELEMETRY_CURRENT_SOURCE_FAS, val++); - } -}; - -class Frsky218Field: public StructField { - public: - Frsky218Field(DataField * parent, FrSkyData & frsky, RSSIAlarmData & rssiAlarms, Board::Type board, unsigned int version, unsigned int variant): - StructField(parent, "FrSky"), - telemetryVarioSourceConversionTable(board, version), - screenTypesConversionTable(board, version), - telemetryVoltsSourceConversionTable(board, version), - telemetryCurrentSourceConversionTable(board, version) - { - if (version <= 218) { - rssiConversionTable[0] = RSSIConversionTable(0); - rssiConversionTable[1] = RSSIConversionTable(1); - - if (!IS_FAMILY_HORUS_OR_T16(board)) { - Append(new UnsignedField<8>(this, frsky.voltsSource, "Volts Source")); - Append(new UnsignedField<8>(this, frsky.altitudeSource, "Altitude Source")); - - for (int i = 0; i < 4; i++) { - Append(new UnsignedField<2>(this, frsky.screens[i].type)); - } - for (int i = 0; i < 4; i++) { - Append(new FrskyScreenField(this, frsky.screens[i], board, version, variant)); - } - } - } - - Append(new UnsignedField<7>(this, frsky.varioSource, "Vario Source")); - Append(new BoolField<1>(this, frsky.varioCenterSilent)); - Append(new SignedField<8>(this, frsky.varioCenterMax)); - Append(new SignedField<8>(this, frsky.varioCenterMin)); - Append(new SignedField<8>(this, frsky.varioMin)); - Append(new SignedField<8>(this, frsky.varioMax)); - if (version <= 218) { - Append(new BoolField<1>(this, rssiAlarms.disabled)); - Append(new SpareBitsField<1>(this)); - Append(new ConversionField >(this, rssiAlarms.warning, -45)); - Append(new SpareBitsField<2>(this)); - Append(new ConversionField >(this, rssiAlarms.critical, -42)); - } - } - - protected: - RSSIConversionTable rssiConversionTable[2]; - TelemetryVarioSourceConversionTable telemetryVarioSourceConversionTable; - ScreenTypesConversionTable screenTypesConversionTable; - TelemetryVoltsSourceConversionTable telemetryVoltsSourceConversionTable; - TelemetryCurrentSourceConversionTable telemetryCurrentSourceConversionTable; -}; - -class VarioField: public StructField { - public: - VarioField(DataField * parent, FrSkyData & frsky, Board::Type board, unsigned int version, unsigned int variant): - StructField(parent, "Vario") - { - Append(new UnsignedField<7>(this, frsky.varioSource, "Vario Source")); - Append(new BoolField<1>(this, frsky.varioCenterSilent)); - Append(new SignedField<8>(this, frsky.varioCenterMax)); - Append(new SignedField<8>(this, frsky.varioCenterMin)); - Append(new SignedField<8>(this, frsky.varioMin)); - Append(new SignedField<8>(this, frsky.varioMax)); - } -}; - -/* - * TODO - */ -#if 0 -class CustomScreenField: public StructField { - public: - CustomScreenField(CustomScreenData & customScreen): - StructField("Custom Screen"), - customScreen(customScreen) - { - } - - protected: - CustomScreenData & customScreen; -}; -#endif - -class SensorField: public TransformedField { - public: - SensorField(DataField * parent, const ModelData & model, SensorData & sensor, Board::Type board, unsigned int version): - TransformedField(parent, internalField), - internalField(this, "Sensor"), - sensor(sensor), - model(model), - version(version) - { - internalField.Append(new UnsignedField<16>(this, _id, "id/persistentValue")); - internalField.Append(new UnsignedField<8>(this, _instance, "instance/formula")); - if (version>= 220) - internalField.Append(new CharField<4>(this, sensor.label)); - else - internalField.Append(new ZCharField<4>(this, sensor.label)); - if (version >= 219) { - internalField.Append(new UnsignedField<8>(this, _subid, "subid")); - internalField.Append(new UnsignedField<2>(this, sensor.type, "type")); - internalField.Append(new UnsignedField<6>(this, sensor.unit, "unit")); - internalField.Append(new UnsignedField<2>(this, sensor.prec, "prec")); - internalField.Append(new BoolField<1>(this, sensor.autoOffset)); - internalField.Append(new BoolField<1>(this, sensor.filter)); - internalField.Append(new BoolField<1>(this, sensor.logs)); - internalField.Append(new BoolField<1>(this, sensor.persistent)); - internalField.Append(new BoolField<1>(this, sensor.onlyPositive)); - internalField.Append(new SpareBitsField<1>(this)); - } - else { - internalField.Append(new UnsignedField<1>(this, sensor.type, "type")); - internalField.Append(new UnsignedField<5>(this, sensor.unit, "unit")); - internalField.Append(new UnsignedField<2>(this, sensor.prec, "prec")); - internalField.Append(new BoolField<1>(this, sensor.autoOffset)); - internalField.Append(new BoolField<1>(this, sensor.filter)); - internalField.Append(new BoolField<1>(this, sensor.logs)); - internalField.Append(new BoolField<1>(this, sensor.persistent)); - internalField.Append(new BoolField<1>(this, sensor.onlyPositive)); - internalField.Append(new UnsignedField<3>(this, _subid, "subid")); - } - internalField.Append(new UnsignedField<32>(this, _param, "param")); - } - - void beforeExport() override - { - if (sensor.type == SensorData::TELEM_TYPE_CUSTOM) { - _id = sensor.id; - _subid = sensor.subid; - _instance = sensor.instance == 0 ? 0 : ((sensor.instance - 1) & 0x1F) | (sensor.rxIdx << 5) | (sensor.moduleIdx << 7); - _ratio = sensor.ratio; - _offset = sensor.offset; - } - else { - _id = sensor.persistentValue; - _instance = sensor.formula; - if (sensor.formula == SensorData::TELEM_FORMULA_CELL) - _param = (sensor.source) + (sensor.index << 8); - else if (sensor.formula == SensorData::TELEM_FORMULA_ADD || sensor.formula == SensorData::TELEM_FORMULA_AVERAGE || sensor.formula == SensorData::TELEM_FORMULA_MULTIPLY || sensor.formula == SensorData::TELEM_FORMULA_MIN || sensor.formula == SensorData::TELEM_FORMULA_MAX) - _param = ((uint8_t)sensor.sources[0]) + ((uint8_t)sensor.sources[1] << 8) + ((uint8_t)sensor.sources[2] << 16) + ((uint8_t)sensor.sources[3] << 24); - else if (sensor.formula == SensorData::TELEM_FORMULA_DIST) - _param = (sensor.gps) + (sensor.alt << 8); - else if (sensor.formula == SensorData::TELEM_FORMULA_CONSUMPTION || sensor.formula == SensorData::TELEM_FORMULA_TOTALIZE) - _param = (sensor.amps); - } - } - - void afterImport() override - { - if (sensor.type == SensorData::TELEM_TYPE_CUSTOM) { - if (strlen(sensor.label) == 0) { - sensor.clear(); - } - else { - sensor.id = _id; - sensor.subid = _subid; - sensor.instance = (_instance & 0x1F) + (version <= 218 ? 0 : 1); // 5 bits instance - sensor.rxIdx = (_instance >> 5) & 0x03; // 2 bits Rx idx - sensor.moduleIdx = (_instance >> 7) & 0x1; // 1 bit module idx - sensor.ratio = _ratio; - sensor.offset = _offset; - } - } - else { - sensor.persistentValue = _id; - sensor.formula = _instance; - if (sensor.formula == SensorData::TELEM_FORMULA_CELL) - (sensor.source = _sources[0], sensor.index = _sources[1]); - else if (sensor.formula == SensorData::TELEM_FORMULA_ADD || sensor.formula == SensorData::TELEM_FORMULA_AVERAGE || sensor.formula == SensorData::TELEM_FORMULA_MULTIPLY || sensor.formula == SensorData::TELEM_FORMULA_MIN || sensor.formula == SensorData::TELEM_FORMULA_MAX) - for (int i=0; i<4; ++i) - sensor.sources[i] = _sources[i]; - else if (sensor.formula == SensorData::TELEM_FORMULA_DIST) - (sensor.gps = _sources[0], sensor.alt = _sources[1]); - else if (sensor.formula == SensorData::TELEM_FORMULA_CONSUMPTION || sensor.formula == SensorData::TELEM_FORMULA_TOTALIZE) - sensor.amps = _sources[0]; - } - - if (version < 218) { - if (sensor.unit > SensorData::UNIT_WATTS) - sensor.unit++; - if (sensor.unit > SensorData::UNIT_DEGREE) - sensor.unit++; - } - - if (version < 219) { - if (sensor.unit > SensorData::UNIT_FLOZ) { - sensor.unit += 11; - } - } - - // Cells 7 and 8 introduced in v2.8 requiring Highest and Delta to be shifted + 2 - if (version < 221) { - if (sensor.formula == SensorData::TELEM_FORMULA_CELL && sensor.index > 6) - sensor.index += 2; - } - - qCDebug(eepromImport) << QString("imported %1").arg(internalField.getName()); - } - - protected: - StructField internalField; - SensorData & sensor; - const ModelData& model; - unsigned int version; - unsigned int _id = 0; - unsigned int _subid = 0; - unsigned int _instance = 0; - union { - unsigned int _param = 0; - uint8_t _sources[4]; - struct { - uint16_t _ratio; - int16_t _offset; - }; - }; -}; - -int exportPpmDelay(int delay) { return (delay - 300) / 50; } -int importPpmDelay(int delay) { return 300 + 50 * delay; } - -class ModuleUnionField: public UnionField { - - class PPMField: public UnionField::UnionMember, public StructField { - public: - PPMField(DataField * parent, ModuleData::PPM& ppm): - StructField(parent, "PPM") - { - Append(new ConversionField< SignedField<6> >(parent, ppm.delay, exportPpmDelay, importPpmDelay)); - Append(new BoolField<1>(parent, ppm.pulsePol)); - Append(new BoolField<1>(parent, ppm.outputType)); - Append(new SignedField<8>(parent, ppm.frameLength)); - } - - bool select(const unsigned int & attr) const override - { - return true; // take what's left - } - - DataField * getField() override - { - return this; - } - }; - - class MultiField: public UnionField::TransformedMember { - public: - MultiField(DataField * parent, ModuleData& module): - UnionField::TransformedMember(parent, internalField), - internalField(this, "Multi"), - module(module), - rfProtExtra(0) - { - ModuleData::Multi & multi = module.multi; - internalField.Append(new UnsignedField<3>(this, rfProtExtra)); - internalField.Append(new BoolField<1>(this, multi.disableTelemetry)); - internalField.Append(new BoolField<1>(this, multi.disableMapping)); - internalField.Append(new SpareBitsField<1>(this)); - internalField.Append(new BoolField<1>(this, multi.autoBindMode)); - internalField.Append(new BoolField<1>(this, multi.lowPowerMode)); - internalField.Append(new SignedField<8>(this, multi.optionValue)); - } - - bool select(const unsigned int & attr) const override - { - return attr == PULSES_MULTIMODULE; - } - - void beforeExport() override - { - rfProtExtra = (module.multi.rfProtocol & 0x70) >> 4; - } - - void afterImport() override - { - module.multi.rfProtocol = (rfProtExtra << 4) + (module.rfProtocol & 0xf); - } - - private: - StructField internalField; - ModuleData & module; - unsigned int rfProtExtra; - }; - - class PxxField: public UnionField::TransformedMember { - public: - PxxField(DataField * parent, ModuleData& module, unsigned int version): - UnionField::TransformedMember(parent, internalField), - internalField(this, "Pxx"), - module(module), - version(version) - { - ModuleData::PXX& pxx = module.pxx; - internalField.Append(new UnsignedField<2>(this, pxx.power)); - internalField.Append(new SpareBitsField<2>(this)); - internalField.Append(new BoolField<1>(this, pxx.receiverTelemetryOff)); - internalField.Append(new BoolField<1>(this, pxx.receiverHigherChannels)); - internalField.Append(new SignedField<2>(this, pxx.antennaMode)); - internalField.Append(new SpareBitsField<8>(this)); - } - - bool select(const unsigned int& attr) const override { - return (attr >= PULSES_PXX_XJT_X16 && attr <= PULSES_PXX_XJT_LR12) || - attr==PULSES_PXX_DJT || - attr==PULSES_PXX_R9M || - attr==PULSES_PXX_R9M_LITE; - } - - void beforeExport() override - { - } - - void afterImport() override - { - if (module.protocol == PULSES_PXX_XJT_X16) { - if (version <= 218) - module.protocol += module.rfProtocol; - else - module.protocol += module.subType; - } - } - - private: - StructField internalField; - ModuleData& module; - unsigned int version; - }; - - class AccessField: public UnionField::TransformedMember { - public: - AccessField(DataField * parent, ModuleData& module): - UnionField::TransformedMember(parent, internalField), - internalField(this, "Access"), - module(module) - { - internalField.Append(new UnsignedField<3>(this, module.access.receivers)); - internalField.Append(new SpareBitsField<4>(this)); - internalField.Append(new UnsignedField<1>(this, module.access.racingMode)); - - for (int i = 0; i < PXX2_MAX_RECEIVERS_PER_MODULE; i++) - internalField.Append(new CharField<8>(this, receiverName[i])); - - memset(receiverName, 0, sizeof(receiverName)); - } - - bool select(const unsigned int & attr) const override - { - return attr >= PULSES_ACCESS_ISRM && attr <= PULSES_ACCESS_R9M_LITE_PRO; - } - - void beforeExport() override - { - for (int i=0; i(this, module.ghost.raw12bits)); - internalField.Append(new SpareBitsField<7>(this)); - } - - bool select(const unsigned int & attr) const override - { - return attr == PULSES_GHOST; - } - - void beforeExport() override {} - - void afterImport() override {} - - private: - StructField internalField; - }; - - public: - ModuleUnionField(DataField * parent, ModuleData & module, Board::Type board, unsigned int version): - UnionField(parent, module.protocol) - { - if (version >= 219) { - Append(new AccessField(parent, module)); - Append(new GhostField(parent, module)); - } - Append(new PxxField(parent, module, version)); - Append(new MultiField(parent, module)); - Append(new PPMField(parent, module.ppm)); - } -}; - - -class ModuleField: public TransformedField { - public: - ModuleField(DataField * parent, ModuleData & module, ModelData & model, Board::Type board, unsigned int version): - TransformedField(parent, internalField), - internalField(this, "Module"), - module(module), - protocolsConversionTable(board, version) - { - internalField.Append(new ConversionField >(this, module.protocol, &protocolsConversionTable, "Protocol", DataField::tr("OpenTX doesn't accept this radio protocol"))); - internalField.Append(new SignedField<4>(this, module.rfProtocol)); - internalField.Append(new UnsignedField<8>(this, module.channelsStart)); - internalField.Append(new ConversionField >(this, module.channelsCount, -8)); - internalField.Append(new UnsignedField<4>(this, module.failsafeMode)); - internalField.Append(new UnsignedField<3>(this, module.subType)); - internalField.Append(new BoolField<1>(this, module.invertedSerial)); - if (version <= 218) { - for (int i = 0; i < 32; i++) { - internalField.Append(new SignedField<16>(this, model.limitData[i].failsafe)); - } - } - - internalField.Append(new ModuleUnionField(parent, module, board, version)); - } - - void beforeExport() override - { - if (module.protocol >= PULSES_LP45 && module.protocol <= PULSES_DSMX) { - module.rfProtocol = module.protocol - PULSES_LP45; - } - else if (module.protocol == PULSES_ACCST_ISRM_D16 || module.protocol == PULSES_ACCESS_ISRM) { - module.subType = module.protocol - PULSES_ACCESS_ISRM; - } - else if (module.protocol >= PULSES_PXX_XJT_X16 && module.protocol <= PULSES_PXX_XJT_LR12) { - module.subType = module.protocol - PULSES_PXX_XJT_X16; - } - else if (module.protocol == PULSES_MULTIMODULE) { - module.rfProtocol = module.multi.rfProtocol & 0x0F; - } - } - - void afterImport() override - { - if (module.protocol == PULSES_LP45) { - module.protocol += module.rfProtocol; - } - } - - private: - StructField internalField; - ModuleData& module; - ProtocolsConversionTable protocolsConversionTable; -}; - -class TimerField: public TransformedField { - public: - TimerField(DataField * parent, TimerData & timer, Board::Type board, unsigned int version): - TransformedField(parent, internalField), - internalField(this, "Timer"), - timer(timer), - board(board), - version(version), - switchesConversionTable(SwitchesConversionTable::getInstance(board, version)) - { - if (version >= 220) { - internalField.Append(new UnsignedField<22>(this, timer.val)); - internalField.Append(new SwitchField<10>(this, _swtch, board, version)); - internalField.Append(new SignedField<22>(this, timer.pvalue)); - internalField.Append(new UnsignedField<3>(this, _mode)); - internalField.Append(new UnsignedField<2>(this, timer.countdownBeep)); - internalField.Append(new BoolField<1>(this, timer.minuteBeep)); - internalField.Append(new UnsignedField<2>(this, timer.persistent)); - internalField.Append(new SignedField<2>(this, timer.countdownStart)); - if (HAS_LARGE_LCD(board)) - internalField.Append(new CharField<8>(this, timer.name, "Timer name")); - else - internalField.Append(new CharField<3>(this, timer.name, "Timer name")); - } - else if (version >= 218) { - internalField.Append(new SignedField<9>(this, _mode_pre220)); - internalField.Append(new UnsignedField<23>(this, timer.val)); - internalField.Append(new SignedField<24>(this, timer.pvalue)); - internalField.Append(new UnsignedField<2>(this, timer.countdownBeep)); - internalField.Append(new BoolField<1>(this, timer.minuteBeep)); - internalField.Append(new UnsignedField<2>(this, timer.persistent)); - internalField.Append(new SignedField<2>(this, timer.countdownStart)); - internalField.Append(new SpareBitsField<1>(this)); // direction - if (HAS_LARGE_LCD(board)) - internalField.Append(new ZCharField<8>(this, timer.name, "Timer name")); - else - internalField.Append(new ZCharField<3>(this, timer.name, "Timer name")); - } - else { - internalField.Append(new SignedField<8>(this, _mode_pre220)); - internalField.Append(new UnsignedField<24>(this, timer.val)); - internalField.Append(new SignedField<24>(this, timer.pvalue)); - internalField.Append(new UnsignedField<2>(this, timer.countdownBeep)); - internalField.Append(new BoolField<1>(this, timer.minuteBeep)); - internalField.Append(new UnsignedField<2>(this, timer.persistent)); - internalField.Append(new SpareBitsField<3>(this)); - if (IS_TARANIS(board)) - internalField.Append(new ZCharField<8>(this, timer.name, "Timer name")); - else - internalField.Append(new ZCharField<3>(this, timer.name, "Timer name")); - } - } - - void beforeExport() override - { - _swtch = timer.swtch; - _mode = timer.mode; - } - - void afterImport() override - { - if (version >= 220) { - timer.swtch = _swtch; - timer.mode = _mode; - } - else { - if (_mode_pre220 >= 0 and _mode_pre220 <= 4) { - timer.swtch = _swtch; - timer.mode = _mode_pre220; - if (timer.mode >= TimerData::TIMERMODE_START) - timer.mode += 1; - } - else { - timer.mode = TimerData::TIMERMODE_ON; - if (_mode_pre220 > 0) - _mode_pre220 -= 4; - switchesConversionTable->importValue(_mode_pre220, _sw1); - timer.swtch = RawSwitch(_sw1); - } - - timer.countdownStart = (timer.countdownStart * -1) - 1; - } - } - - protected: - StructField internalField; - TimerData & timer; - Board::Type board; - unsigned int version; - SwitchesConversionTable * switchesConversionTable; - int _mode_pre220 = 0; - unsigned int _mode = 0; - RawSwitch _swtch = RawSwitch(SWITCH_TYPE_NONE, 0); - int _sw1; -}; - -class ZoneOptionValueUnionField: public UnionField { - - class ZOVUnsignedField: public UnionField::UnionMember, public StructField { - public: - ZOVUnsignedField(DataField * parent, ZoneOptionValueTyped & option, Board::Type board, unsigned int version): - StructField(this, "ZOV unsigned") - { - Append(new UnsignedField<32>(this, option.value.unsignedValue)); - } - - bool select(const ZoneOptionValueEnum & attr) const override { - return attr == ZOV_Unsigned; - } - - DataField * getField() override - { - return this; - } -}; - - class ZOVSignedField: public UnionField::UnionMember, public StructField { - public: - ZOVSignedField(DataField * parent, ZoneOptionValueTyped & option, Board::Type board, unsigned int version): - StructField(this, "ZOV signed") - { - Append(new SignedField<32>(this, option.value.signedValue)); - } - - bool select(const ZoneOptionValueEnum & attr) const override { - return attr == ZOV_Signed; - } - - DataField * getField() override - { - return this; - } - }; - - class ZOVBoolField: public UnionField::UnionMember, public StructField { - public: - ZOVBoolField(DataField * parent, ZoneOptionValueTyped & option, Board::Type board, unsigned int version): - StructField(this, "ZOV bool") - { - Append(new UnsignedField<32>(this, option.value.boolValue)); - } - - bool select(const ZoneOptionValueEnum & attr) const override { - return attr == ZOV_Bool; - } - - DataField * getField() override - { - return this; - } - }; - - class ZOVStringField: public UnionField::UnionMember, public StructField { - public: - ZOVStringField(DataField * parent, ZoneOptionValueTyped & option, Board::Type board, unsigned int version): - StructField(this, "ZOV string") - { - Append(new CharField(this, option.value.stringValue)); - } - - bool select(const ZoneOptionValueEnum & attr) const override { - return attr == ZOV_String; - } - - DataField * getField() override - { - return this; - } - }; - - public: - ZoneOptionValueUnionField(DataField * parent, ZoneOptionValueTyped & option, Board::Type board, unsigned int version): - UnionField(parent, option.type, "Zone Option Value Union") - { - Append(new ZOVUnsignedField(parent, option, board, version)); - Append(new ZOVSignedField(parent, option, board, version)); - Append(new ZOVBoolField(parent, option, board, version)); - Append(new ZOVStringField(parent, option, board, version)); - } -}; - -class ZoneOptionValueTypedField: public StructField { - public: - ZoneOptionValueTypedField(DataField * parent, ZoneOptionValueTyped & option, Board::Type board, unsigned int version): - StructField(this, "Zone Option Value Typed") - { - Append(new SignedField<32>(this, (int &)option.type, "Zone Option Value Enum")); - Append(new ZoneOptionValueUnionField(this, option, board, version)); - } -}; - -class WidgetPersistentDataField: public StructField { - public: - WidgetPersistentDataField(DataField * parent, WidgetPersistentData & persistentData, Board::Type board, unsigned int version): - StructField(this, "Widget Persistent") - { - for (int i = 0; i < MAX_WIDGET_OPTIONS; i++) { - Append(new ZoneOptionValueTypedField(this, persistentData.options[i], board, version)); - } - } -}; - -class ZonePersistentDataField: public StructField { - public: - ZonePersistentDataField(DataField * parent, ZonePersistentData & persistentData, Board::Type board, unsigned int version): - StructField(this, "Zone Persistent") - { - Append(new CharField(this, persistentData.widgetName, "Widget name")); - //Append(new SpareBitsField<16>(this)); // pad to word boundary - Append(new WidgetPersistentDataField(this, persistentData.widgetData, board, version)); - } -}; - -template -class WidgetsContainerPersistentField: public StructField { - public: - WidgetsContainerPersistentField(DataField * parent, container & persistentData, int zonecnt, int optioncnt, Board::Type board, unsigned int version): - StructField(this, "Widgets Container Persistent") - { - for (int i = 0; i < zonecnt; i++) { - Append(new ZonePersistentDataField(this, persistentData.zones[i], board, version)); - } - - for (int i = 0; i < optioncnt; i++) { - Append(new ZoneOptionValueTypedField(this, persistentData.options[i], board, version)); - } - } -}; - -class CustomScreenField: public StructField { - public: - CustomScreenField(DataField * parent, RadioLayout::CustomScreenData & customScreen, Board::Type board, unsigned int version): - StructField(this, "Custom Screen") - { - Append(new CharField<10>(this, customScreen.layoutId, "Layout id")); - //Append(new SpareBitsField<16>(this)); // pad to word boundary not required in this case - Append(new WidgetsContainerPersistentField(this, customScreen.layoutPersistentData, MAX_LAYOUT_ZONES, MAX_LAYOUT_OPTIONS, board, version)); - //dump(); - } -}; - -class TopBarField: public StructField { - public: - TopBarField(DataField * parent, TopBarPersistentData & topBar, Board::Type board, unsigned int version): - StructField(parent, "Top Bar") - { - Append(new WidgetsContainerPersistentField(this, topBar, IS_FLYSKY_NV14(board) ? 2 : 4, MAX_TOPBAR_OPTIONS, board, version)); - //dump(); - } -}; - -OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsigned int version, unsigned int variant): - TransformedField(nullptr, internalField), - internalField(this, "ModelData"), - modelData(modelData), - board(board), - version(version), - variant(variant) -{ - sprintf(name, "Model %s", modelData.name); - - qDebug() << QString("OpenTxModelData::OpenTxModelData(name: %1, board: %2, ver: %3, var: %4)").arg(name).arg(board).arg(version).arg(variant); - - if (version >= 220) { - if (IS_FAMILY_HORUS_OR_T16(board)) - internalField.Append(new CharField<15>(this, modelData.name, "Model name")); - else if (HAS_LARGE_LCD(board)) - internalField.Append(new CharField<12>(this, modelData.name, "Model name")); - else - internalField.Append(new CharField<10>(this, modelData.name, "Model name")); - } - else { - if (IS_FAMILY_HORUS_OR_T16(board)) - internalField.Append(new ZCharField<15>(this, modelData.name, "Model name")); - else if (HAS_LARGE_LCD(board)) - internalField.Append(new ZCharField<12>(this, modelData.name, "Model name")); - else - internalField.Append(new ZCharField<10>(this, modelData.name, "Model name")); - } - - internalField.Append(new UnsignedField<8>(this, modelData.moduleData[0].modelId)); - internalField.Append(new UnsignedField<8>(this, modelData.moduleData[1].modelId)); - - if (HAS_LARGE_LCD(board)) { - if (version >= 219 && IS_FAMILY_HORUS_OR_T16(board)) - internalField.Append(new CharField<14>(this, modelData.bitmap, true, "Model bitmap")); - else - internalField.Append(new CharField<10>(this, modelData.bitmap, true, "Model bitmap")); - } - - for (int i = 0; i < MAX_TIMERS(board, version); i++) { - internalField.Append(new TimerField(this, modelData.timers[i], board, version)); - } - - internalField.Append(new UnsignedField<3>(this, modelData.telemetryProtocol)); - internalField.Append(new BoolField<1>(this, modelData.thrTrim)); - internalField.Append(new BoolField<1>(this, modelData.noGlobalFunctions)); - internalField.Append(new UnsignedField<2>(this, modelData.trimsDisplay)); - internalField.Append(new BoolField<1>(this, modelData.frsky.ignoreSensorIds)); - internalField.Append(new SignedField<3>(this, modelData.trimInc)); - internalField.Append(new BoolField<1>(this, modelData.disableThrottleWarning)); - internalField.Append(new BoolField<1>(this, modelData.displayChecklist)); - internalField.Append(new BoolField<1>(this, modelData.extendedLimits)); - internalField.Append(new BoolField<1>(this, modelData.extendedTrims)); - internalField.Append(new BoolField<1>(this, modelData.throttleReversed)); - internalField.Append(new UnsignedField<16>(this, modelData.beepANACenter)); - - for (int i=0; i(this, modelData.thrTraceSrc, "Throttle Source")); - - if (IS_FAMILY_HORUS_OR_T16(board)) - internalField.Append(new SwitchesWarningField<32>(this, modelData.switchWarningStates, board, version)); - else if (IS_TARANIS_X9E(board)) - internalField.Append(new SwitchesWarningField<64>(this, modelData.switchWarningStates, board, version)); - else if (version >= 219 && (IS_TARANIS_X9D(board) || IS_JUMPER_TPRO(board))) - internalField.Append(new SwitchesWarningField<32>(this, modelData.switchWarningStates, board, version)); - else if (IS_TARANIS(board)) - internalField.Append(new SwitchesWarningField<16>(this, modelData.switchWarningStates, board, version)); - else - internalField.Append(new SwitchesWarningField<8>(this, modelData.switchWarningStates, board, version)); - - if (IS_TARANIS_X9E(board)) - internalField.Append(new UnsignedField<32>(this, modelData.switchWarningEnable)); - else if (version >= 219 && (IS_TARANIS_X9D(board) || IS_JUMPER_TPRO(board))) - internalField.Append(new UnsignedField<16>(this, modelData.switchWarningEnable)); - else if (!IS_FAMILY_HORUS_OR_T16(board)) - internalField.Append(new UnsignedField<8>(this, modelData.switchWarningEnable)); - - for (int i = 0; i < MAX_GVARS(board, version); i++) { - if (version >= 218) { - if (version >= 220) - internalField.Append(new CharField<3>(this, modelData.gvarData[i].name, "GVar name")); - else - internalField.Append(new ZCharField<3>(this, modelData.gvarData[i].name, "GVar name")); - internalField.Append(new UnsignedField<12>(this, (unsigned &)modelData.gvarData[i].min)); - internalField.Append(new UnsignedField<12>(this, (unsigned &)modelData.gvarData[i].max)); - internalField.Append(new BoolField<1>(this, modelData.gvarData[i].popup)); - internalField.Append(new UnsignedField<1>(this, modelData.gvarData[i].prec)); - internalField.Append(new UnsignedField<2>(this, modelData.gvarData[i].unit)); - internalField.Append(new SpareBitsField<4>(this)); - } - else { - internalField.Append(new ZCharField<3>(this, modelData.gvarData[i].name, "GVar name")); - internalField.Append(new SpareBitsField<3*8>(this)); - internalField.Append(new BoolField<1>(this, modelData.gvarData[i].popup)); - internalField.Append(new SpareBitsField<7>(this)); - } - } - - if (version <= 218) { - internalField.Append(new Frsky218Field(this, modelData.frsky, modelData.rssiAlarms, board, version, variant)); - } - else { - internalField.Append(new VarioField(this, modelData.frsky, board, version, variant)); - internalField.Append(new UnsignedField<8>(this, modelData.rssiSource)); - - if (IS_TARANIS_X9(board)) { - internalField.Append(new UnsignedField<8>(this, modelData.frsky.voltsSource)); - internalField.Append(new UnsignedField<8>(this, modelData.frsky.altitudeSource)); - } - - internalField.Append(new BoolField<1>(this, modelData.rssiAlarms.disabled)); - internalField.Append(new SpareBitsField<1>(this)); - internalField.Append(new ConversionField >(this, modelData.rssiAlarms.warning, -45)); - internalField.Append(new SpareBitsField<2>(this)); - internalField.Append(new ConversionField >(this, modelData.rssiAlarms.critical, -42)); - } - - if (IS_STM32(board) && version <= 218) { - internalField.Append(new SpareBitsField<3>(this)); - internalField.Append(new UnsignedField<3>(this, modelData.trainerMode)); - internalField.Append(new UnsignedField<2>(this, modelData.potsWarningMode)); - } - else { - internalField.Append(new SpareBitsField<3>(this)); - internalField.Append(new UnsignedField<3>(this, modelData.thrTrimSwitch)); - internalField.Append(new UnsignedField<2>(this, modelData.potsWarningMode)); - } - - int modulesCount = (version <= 218 ? 3 : 2); - for (int module = 0; module < modulesCount; module++) { - internalField.Append(new ModuleField(this, modelData.moduleData[module], modelData, board, version)); - } - - if (version >= 219) { - for (int i = 0; i < 32; i++) { - internalField.Append(new SignedField<16>(this, modelData.limitData[i].failsafe)); - } - } - - if (version >= 219) { - // Trainer PPM settings - internalField.Append(new UnsignedField<3>(this, modelData.trainerMode)); - internalField.Append(new SpareBitsField<5>(this)); - internalField.Append(new UnsignedField<8>(this, modelData.moduleData[2].channelsStart)); - internalField.Append(new ConversionField >(this, modelData.moduleData[2].channelsCount, -8)); - internalField.Append(new SignedField<8>(this, modelData.moduleData[2].ppm.frameLength)); - internalField.Append(new ConversionField >(this, modelData.moduleData[2].ppm.delay, exportPpmDelay, importPpmDelay)); - internalField.Append(new BoolField<1>(this, modelData.moduleData[2].ppm.pulsePol)); - internalField.Append(new SpareBitsField<1>(this)); - } - - if (IS_TARANIS(board) && version < 218) { - for (int i = 0; i < MAX_CURVES(board, version); i++) { - internalField.Append(new ZCharField<6>(this, modelData.curves[i].name, "Curve name")); - } - } - - if (IS_STM32(board)) { - if (version >= 218) { - for (int i = 0; i < MAX_SCRIPTS(board); i++) { - ScriptData & script = modelData.scriptData[i]; - internalField.Append(new CharField<6>(this, script.filename, true, "Script filename")); - if (version >= 220) - internalField.Append(new CharField<6>(this, script.name, "Script name")); - else - internalField.Append(new ZCharField<6>(this, script.name, "Script name")); - for (int j = 0; j < 6; j++) { - internalField.Append(new SignedField<16>(this, script.inputs[j])); - } - } - } - else { - for (int i = 0; i < 7; i++) { - ScriptData & script = modelData.scriptData[i]; - internalField.Append(new CharField<8>(this, script.filename, true, "Script filename")); - internalField.Append(new ZCharField<8>(this, script.name, "Script name")); - for (int j=0; j<8; j++) { - internalField.Append(new SignedField<8>(this, script.inputs[j])); - } - } - } - } - - for (int i = 0; i < 32; i++) { - if (version >= 220) { - if (HAS_LARGE_LCD(board)) - internalField.Append(new CharField<4>(this, modelData.inputNames[i], "Input name")); - else - internalField.Append(new CharField<3>(this, modelData.inputNames[i], "Input name")); - } - else { - if (HAS_LARGE_LCD(board)) - internalField.Append(new ZCharField<4>(this, modelData.inputNames[i], "Input name")); - else - internalField.Append(new ZCharField<3>(this, modelData.inputNames[i], "Input name")); - } - } - - for (int i = 0; i < 8; i++) { - if (i < Boards::getCapability(board, Board::Pots) + Boards::getCapability(board, Board::Sliders)) - internalField.Append(new BoolField<1>(this, modelData.potsWarnEnabled[i])); - else - internalField.Append(new SpareBitsField<1>(this)); - } - - for (int i = 0; i < MAX_POTS_STORAGE(board, version) + MAX_SLIDERS_STORAGE(board, version); i++) { - internalField.Append(new SignedField<8>(this, modelData.potsWarnPosition[i])); - } - - if (version <= 218 && IS_HORUS_X10(board)) { - internalField.Append(new SpareBitsField<16>(this)); - } - - if (IS_SKY9X(board)) { - internalField.Append(new SpareBitsField<8>(this)); - internalField.Append(new SpareBitsField<8>(this)); - } - - for (int i = 0; i < MAX_TELEMETRY_SENSORS(board, version); ++i) { - internalField.Append(new SensorField(this, modelData, modelData.sensorData[i], board, version)); - } - - if (IS_TARANIS_X9E(board)) { - internalField.Append(new UnsignedField<8>(this, modelData.toplcdTimer)); - } - - if (IS_FAMILY_HORUS_OR_T16(board)) { - if (version > 220) { // data from earlier versions cannot be converted so fields initialised in afterImport - for (int i = 0; i < MAX_CUSTOM_SCREENS; i++) { - internalField.Append(new CustomScreenField(this, modelData.customScreens.customScreenData[i], board, version)); - } - internalField.Append(new TopBarField(this, modelData.topBarData, board, version)); - internalField.Append(new UnsignedField<8>(this, modelData.view)); - } - } - else if (version >= 219) { - for (int i = 0; i < 4; i++) { - internalField.Append(new UnsignedField<2>(this, modelData.frsky.screens[i].type)); - } - for (int i = 0; i < 4; i++) { - internalField.Append(new FrskyScreenField(this, modelData.frsky.screens[i], board, version, variant)); - } - internalField.Append(new SpareBitsField<8>(this)); // current view - } - - if (version >= 220) { - internalField.Append(new CharField<8>(this, modelData.registrationId, "ACCESS Registration ID")); - } - else if (version >= 219) { - internalField.Append(new ZCharField<8>(this, modelData.registrationId, "ACCESS Registration ID")); - } - - if (IS_JUMPER_TPRO(board)) { - internalField.Append(new UnsignedField<16>(this, modelData.functionSwitchConfig)); - internalField.Append(new UnsignedField<16>(this, modelData.functionSwitchGroup)); - internalField.Append(new UnsignedField<16>(this, modelData.functionSwitchStartConfig)); - internalField.Append(new UnsignedField<8>(this, modelData.functionSwitchLogicalState)); - for (int i=0; i < Boards::getCapability(board, Board::FunctionSwitches); ++i) { - internalField.Append(new ZCharField<3>(this, modelData.functionSwitchNames[i], "Function switch name")); - } - } -} - -void OpenTxModelData::beforeExport() -{ - // qDebug() << QString("before export model") << modelData.name; - - if (IS_FAMILY_HORUS_OR_T16(board)) { - uint32_t newSwitchWarningStates = 0; - for (int i = 0; i < MAX_SWITCHES(board, version); i++) { - uint8_t value = (modelData.switchWarningStates >> (2*i)) & 0x03; - if (!(modelData.switchWarningEnable & (1 << i))) { - newSwitchWarningStates |= (value + 1) << (3*i); - } - } - modelData.switchWarningStates = newSwitchWarningStates; - } - - // TODO remove when enum not radio specific requires eeprom change and conversion - // Note: this must mirror reverse afterImport - if (!IS_FLYSKY_NV14(board) && !IS_FLYSKY_PL18(board)) - modelData.trainerMode -= 1; - - if (modelData.trainerMode > TRAINER_MODE_SLAVE_JACK) { - if (!IS_TARANIS(board)) { - modelData.trainerMode -= 2; - if (!IS_RADIOMASTER_TX16S(board)) - modelData.trainerMode -= 1; - } - } -} - -void OpenTxModelData::afterImport() -{ - qCDebug(eepromImport) << QString("OpenTxModelData::afterImport()") << modelData.name; - - if (IS_FAMILY_HORUS_OR_T16(board)) { - uint32_t newSwitchWarningStates = 0; - for (int i = 0; i < MAX_SWITCHES(board, version); i++) { - uint8_t value = (modelData.switchWarningStates >> (3*i)) & 0x07; - if (value == 0) - modelData.switchWarningEnable |= (1 << i); - else - newSwitchWarningStates |= ((value & 0x03) - 1) << (2*i); - } - modelData.switchWarningStates = newSwitchWarningStates; - - if (version <= 220) { // re-initialise as no conversion possible - const char * layoutId = "Layout2P1"; // currently all using same default though might change for NV14 - RadioLayout::init(layoutId, modelData.customScreens); - modelData.topBarData = TopBarPersistentData(); - } - } - - // EX1 / EX2 - if (version <= 218 && IS_HORUS_X10(board) && modelData.thrTraceSrc > 3) { - modelData.thrTraceSrc += 2; - } - - // EX3 / EX4 - if (version <= 220 && (IS_HORUS_X10(board) || IS_FAMILY_T16(board)) && - modelData.thrTraceSrc > 5) { - modelData.thrTraceSrc += 2; - } - - // TODO remove when enum not radio specific requires eeprom change and conversion - // Note: this must mirror reverse beforeExport - if (!IS_FLYSKY_NV14(board) && !IS_FLYSKY_PL18(board)) - modelData.trainerMode += 1; - - if (modelData.trainerMode > TRAINER_MODE_SLAVE_JACK) { - if (!IS_TARANIS(board)) { - modelData.trainerMode += 2; - if (!IS_RADIOMASTER_TX16S(board)) - modelData.trainerMode += 1; - } - } -} - -OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type board, unsigned int version, unsigned int variant): - TransformedField(nullptr, internalField), - internalField(this, "General Settings"), - generalData(generalData), - board(board), - version(version), - inputsCount(CPN_MAX_STICKS + MAX_POTS_STORAGE(board, version) + MAX_SLIDERS_STORAGE(board, version) + MAX_MOUSE_ANALOG_SOURCES(board, version)) -{ - qCDebug(eepromImport) << QString("OpenTxGeneralData::OpenTxGeneralData(board: %1, version:%2, variant:%3)").arg(board).arg(version).arg(variant); - - generalData.version = version; - generalData.variant = variant; - - internalField.Append(new UnsignedField<8>(this, generalData.version)); - internalField.Append(new UnsignedField<16>(this, generalData.variant)); - - for (int i=0, input=0; i(this, generalData.calibMid[input])); - internalField.Append(new SignedField<16>(this, generalData.calibSpanNeg[input])); - internalField.Append(new SignedField<16>(this, generalData.calibSpanPos[input])); - } - - if (version <= 218 && IS_HORUS_X10(board)) { - internalField.Append(new SpareBitsField<16*6>(this)); - } - - internalField.Append(new UnsignedField<16>(this, chkSum)); - - if (!IS_FAMILY_HORUS_OR_T16(board) || IS_FLYSKY_NV14(board) || IS_FLYSKY_PL18(board)) { - internalField.Append(new UnsignedField<8>(this, generalData.currModelIndex)); - internalField.Append(new UnsignedField<8>(this, generalData.contrast)); - } - internalField.Append(new UnsignedField<8>(this, generalData.vBatWarn)); - internalField.Append(new SignedField<8>(this, generalData.txVoltageCalibration)); - - internalField.Append(new SignedField<3>(this, generalData.backlightMode)); - if (version >= 219) - internalField.Append(new SignedField<2>(this, generalData.antennaMode)); - else - internalField.Append(new SpareBitsField<2>(this)); - internalField.Append(new BoolField<1>(this, generalData.rtcCheckDisable)); - if (IS_JUMPER_T18(board)) { - internalField.Append(new BoolField<1>(this, generalData.keysBacklight)); - internalField.Append(new SpareBitsField<1>(this)); - } - else { - internalField.Append(new SpareBitsField<2>(this)); - } - - for (int i=0; i<4; i++) { - internalField.Append(new SignedField<16>(this, generalData.trainer.calib[i])); - } - - for (int i=0; i<4; i++) { - internalField.Append(new UnsignedField<6>(this, generalData.trainer.mix[i].src)); - internalField.Append(new UnsignedField<2>(this, generalData.trainer.mix[i].mode)); - internalField.Append(new SignedField<8>(this, generalData.trainer.mix[i].weight)); - } - - internalField.Append(new UnsignedField<8>(this, generalData.view, 0, MAX_VIEWS(board)-1)); - - internalField.Append(new SpareBitsField<2>(this)); // TODO buzzerMode? - internalField.Append(new BoolField<1>(this, generalData.fai)); - internalField.Append(new SignedField<2>(this, (int &)generalData.beeperMode)); - internalField.Append(new BoolField<1>(this, generalData.alarmsFlash)); - internalField.Append(new BoolField<1>(this, generalData.disableMemoryWarning)); - internalField.Append(new BoolField<1>(this, generalData.disableAlarmWarning)); - - internalField.Append(new UnsignedField<2>(this, generalData.stickMode)); - internalField.Append(new SignedField<5>(this, generalData.timezone)); - if (IS_HORUS_OR_TARANIS(board)) { - internalField.Append(new BoolField<1>(this, generalData.adjustRTC)); - } - else { - internalField.Append(new SpareBitsField<1>(this)); - } - - internalField.Append(new UnsignedField<8>(this, generalData.inactivityTimer)); - internalField.Append(new UnsignedField<3>(this, generalData.internalModuleBaudrate)); - if (IS_FAMILY_HORUS_OR_T16(board)) - internalField.Append(new SpareBitsField<3>(this)); - else - internalField.Append(new SignedField<3>(this, generalData.splashMode)); - internalField.Append(new SignedField<2>(this, (int &)generalData.hapticMode)); - - internalField.Append(new SignedField<8>(this, generalData.switchesDelay)); - - internalField.Append(new UnsignedField<8>(this, generalData.backlightDelay)); - internalField.Append(new UnsignedField<8>(this, generalData.templateSetup)); - internalField.Append(new SignedField<8>(this, generalData.PPM_Multiplier)); - internalField.Append(new SignedField<8>(this, generalData.hapticLength)); - - if (version < 218 || (!IS_TARANIS(board) && !IS_FAMILY_HORUS_OR_T16(board)) || IS_FLYSKY_NV14(board) || IS_FLYSKY_PL18(board)) { - internalField.Append(new UnsignedField<8>(this, generalData.reNavigation)); - } - - if ((!IS_TARANIS(board) && !IS_FAMILY_HORUS_OR_T16(board)) || IS_FLYSKY_NV14(board) || IS_FLYSKY_PL18(board)) { - internalField.Append(new UnsignedField<8>(this, generalData.stickReverse)); - } - - internalField.Append(new SignedField<3>(this, generalData.beeperLength)); - internalField.Append(new SignedField<3>(this, generalData.hapticStrength)); - internalField.Append(new UnsignedField<1>(this, generalData.gpsFormat)); - internalField.Append(new SpareBitsField<1>(this)); // unexpectedShutdown - - internalField.Append(new UnsignedField<8>(this, generalData.speakerPitch)); - - internalField.Append(new ConversionField< SignedField<8> >(this, generalData.speakerVolume, -12, 0, 0, 23, "Volume")); - - internalField.Append(new SignedField<8>(this, generalData.vBatMin)); - internalField.Append(new SignedField<8>(this, generalData.vBatMax)); - - internalField.Append(new UnsignedField<8>(this, generalData.backlightBright)); - if (version < 218) internalField.Append(new SignedField<8>(this, generalData.txCurrentCalibration)); - - if (version < 218) internalField.Append(new SpareBitsField<8>(this)); - if (version < 218) internalField.Append(new UnsignedField<8>(this, generalData.mAhWarn)); - if (version < 218) internalField.Append(new UnsignedField<16>(this, generalData.mAhUsed)); - internalField.Append(new UnsignedField<32>(this, generalData.globalTimer)); - if (version < 218) internalField.Append(new SpareBitsField<8>(this)); - internalField.Append(new UnsignedField<4>(this, generalData.bluetoothBaudrate)); - internalField.Append(new UnsignedField<4>(this, generalData.bluetoothMode)); - if (version < 218) internalField.Append(new BoolField<8>(this, generalData.optrexDisplay)); - if (version < 218) internalField.Append(new UnsignedField<8>(this, generalData.sticksGain)); - - - if (version < 218) internalField.Append(new UnsignedField<8>(this, generalData.rotarySteps)); - internalField.Append(new UnsignedField<2>(this, generalData.countryCode)); - - if (version >= 219 && IS_HORUS_OR_TARANIS(board)) { - internalField.Append(new SignedField<3>(this, generalData.pwrOnSpeed, "Power On Speed")); - internalField.Append(new SignedField<3>(this, generalData.pwrOffSpeed, "Power Off Speed")); - } - else { - internalField.Append(new SpareBitsField<6>(this)); - } - - internalField.Append(new UnsignedField<1>(this, generalData.imperial)); - if (version >= 218) { - internalField.Append(new BoolField<1>(this, generalData.noJitterFilter)); - internalField.Append(new BoolField<1>(this, generalData.disableRssiPoweroffAlarm)); - internalField.Append(new UnsignedField<2>(this, generalData.usbMode)); - internalField.Append(new UnsignedField<2>(this, generalData.jackMode)); - internalField.Append(new BoolField<1>(this, generalData.sportPower)); - } - else { - internalField.Append(new SpareBitsField<7>(this)); - } - - internalField.Append(new CharField<2>(this, generalData.ttsLanguage, true, "TTS language")); - if (version >= 218) { - internalField.Append(new SignedField<4>(this, generalData.beepVolume)); - internalField.Append(new SignedField<4>(this, generalData.wavVolume)); - internalField.Append(new SignedField<4>(this, generalData.varioVolume)); - internalField.Append(new SignedField<4>(this, generalData.backgroundVolume)); - } - else { - internalField.Append(new SignedField<8>(this, generalData.beepVolume)); - internalField.Append(new SignedField<8>(this, generalData.wavVolume)); - internalField.Append(new SignedField<8>(this, generalData.varioVolume)); - } - internalField.Append(new SignedField<8>(this, generalData.varioPitch)); - internalField.Append(new SignedField<8>(this, generalData.varioRange)); - internalField.Append(new SignedField<8>(this, generalData.varioRepeat)); - if (version < 218) internalField.Append(new SignedField<8>(this, generalData.backgroundVolume)); - - if (version >= 218) { - for (int i=0; i= 218) { - internalField.Append(new UnsignedField<4>(this, generalData.serialPort[GeneralSettings::SP_AUX1])); - if (IS_FAMILY_HORUS_OR_T16(board) && version >= 219) { - internalField.Append(new UnsignedField<4>(this, generalData.serialPort[GeneralSettings::SP_AUX2])); - } - else { - for (uint8_t i=0; i(this, generalData.sliderConfig[i])); - } - } - } - else { - internalField.Append(new UnsignedField<6>(this, generalData.serialPort[GeneralSettings::SP_AUX1])); - if (IS_TARANIS_X9E(board)) { - internalField.Append(new UnsignedField<1>(this, generalData.sliderConfig[2])); - internalField.Append(new UnsignedField<1>(this, generalData.sliderConfig[3])); - } - else { - internalField.Append(new SpareBitsField<2>(this)); - } - } - - if (IS_FAMILY_HORUS_OR_T16(board)) { - for (int i=0; i(this, generalData.swtchConfig[i])); - else - internalField.Append(new SpareBitsField<2>(this)); - } - } - - for (int i=0; i= 3)) - offset += 2; - - if (i < MAX_POTS_STORAGE(board, version)) - internalField.Append(new UnsignedField<2>(this, generalData.potConfig[i+offset])); - else - internalField.Append(new SpareBitsField<2>(this)); - } - - if (IS_FAMILY_HORUS_OR_T16(board) && version >= 219) { - for (int i=0; i(this, generalData.sliderConfig[i])); - else - internalField.Append(new SpareBitsField<1>(this)); - } - } - - if (!IS_FAMILY_HORUS_OR_T16(board)) { - internalField.Append(new UnsignedField<8>(this, generalData.backlightColor)); - } - } - else if (IS_SKY9X(board) && version >= 218) { - internalField.Append(new SignedField<8>(this, generalData.txCurrentCalibration)); - internalField.Append(new SpareBitsField<8>(this)); - internalField.Append(new UnsignedField<8>(this, generalData.mAhWarn)); - internalField.Append(new UnsignedField<16>(this, generalData.mAhUsed)); - internalField.Append(new SpareBitsField<8>(this)); - internalField.Append(new BoolField<8>(this, generalData.optrexDisplay)); - internalField.Append(new UnsignedField<8>(this, generalData.sticksGain)); - internalField.Append(new UnsignedField<8>(this, generalData.rotarySteps)); - } - - if (IS_TARANIS_X9E(board)) - internalField.Append(new SpareBitsField<64>(this)); // switchUnlockStates - else if (version >= 219 && (IS_TARANIS_X9D(board) || IS_JUMPER_TPRO(board))) - internalField.Append(new SpareBitsField<32>(this)); // switchUnlockStates - else if (IS_TARANIS(board)) - internalField.Append(new SpareBitsField<16>(this)); // switchUnlockStates - - if (version == 217) { - for (int i = 0; i < MAX_CUSTOM_FUNCTIONS(board, version); i++) { - internalField.Append(new ArmCustomFunctionField(this, generalData.customFn[i], board, version, variant)); - } - } - - if (IS_FAMILY_HORUS_OR_T16(board)) { - for (int i = 0; i < MAX_SWITCHES(board, version); ++i) { - if (version >= 220) - internalField.Append(new CharField<3>(this, generalData.swtchName[i], "Switch name")); - else - internalField.Append(new ZCharField<3>(this, generalData.swtchName[i], "Switch name")); - } - for (int i = 0; i < CPN_MAX_STICKS; ++i) { - if (version >= 220) - internalField.Append(new CharField<3>(this, generalData.stickName[i], "Stick name")); - else - internalField.Append(new ZCharField<3>(this, generalData.stickName[i], "Stick name")); - } - for (int i = 0; i < MAX_POTS_STORAGE(board, version); ++i) { - if (version >= 220) - internalField.Append(new CharField<3>(this, generalData.potName[i], "Pot name")); - else - internalField.Append(new ZCharField<3>(this, generalData.potName[i], "Pot name")); - } - for (int i = 0; i < MAX_SLIDERS_STORAGE(board, version); ++i) { - if (version >= 220) - internalField.Append(new CharField<3>(this, generalData.sliderName[i], "Slider name")); - else - internalField.Append(new ZCharField<3>(this, generalData.sliderName[i], "Slider name")); - } - if (version <= 218 && IS_HORUS_X10(board)) { - internalField.Append(new SpareBitsField<48>(this)); // DUMMY_ANAS - } - internalField.Append(new CharField<17>(this, generalData.currModelFilename, true, "Current model filename")); - } - else if (IS_TARANIS(board)) { - for (int i = 0; i < SWITCHES_CONFIG_SIZE(board, version) / 2; i++) { - if (i < MAX_SWITCHES(board, version)) - internalField.Append(new UnsignedField<2>(this, generalData.swtchConfig[i])); - else - internalField.Append(new SpareBitsField<2>(this)); - } - for (int i = 0; i < MAX_SWITCHES(board, version); ++i) { - if (version >= 220) - internalField.Append(new CharField<3>(this, generalData.swtchName[i], "Switch name")); - else - internalField.Append(new ZCharField<3>(this, generalData.swtchName[i], "Switch name")); - } - for (int i = 0; i < CPN_MAX_STICKS; ++i) { - if (version >= 220) - internalField.Append(new CharField<3>(this, generalData.stickName[i], "Stick name")); - else - internalField.Append(new ZCharField<3>(this, generalData.stickName[i], "Stick name")); - } - for (int i = 0; i < MAX_POTS_STORAGE(board, version); ++i) { - if (version >= 220) - internalField.Append(new CharField<3>(this, generalData.potName[i], "Pot name")); - else - internalField.Append(new ZCharField<3>(this, generalData.potName[i], "Pot name")); - } - for (int i = 0; i < MAX_SLIDERS_STORAGE(board, version); ++i) { - if (version >= 220) - internalField.Append(new CharField<3>(this, generalData.sliderName[i], "Slider name")); - else - internalField.Append(new ZCharField<3>(this, generalData.sliderName[i], "Slider name")); - } - } - - if (IS_FAMILY_HORUS_OR_T16(board)) { - internalField.Append(new SpareBitsField<1>(this)); - internalField.Append(new UnsignedField<7>(this, generalData.backlightOffBright)); - if (version >= 220) - internalField.Append(new CharField<10>(this, generalData.bluetoothName, "Bluetooth name")); - else - internalField.Append(new ZCharField<10>(this, generalData.bluetoothName, "Bluetooth name")); - } - else if (IS_TARANIS_X9E(board) || (version >= 219 && (IS_TARANIS_X7(board) || IS_TARANIS_X9D(board) || IS_TARANIS_XLITE(board)))) { - internalField.Append(new SpareBitsField<8>(this)); - if (version >= 220) - internalField.Append(new CharField<10>(this, generalData.bluetoothName, "Bluetooth name")); - else - internalField.Append(new ZCharField<10>(this, generalData.bluetoothName, "Bluetooth name")); - } - - if (version >= 220) { - internalField.Append(new CharField<8>(this, generalData.registrationId, "ACCESS Registration ID")); - } - else if (version >= 219) { - internalField.Append(new ZCharField<8>(this, generalData.registrationId, "ACCESS Registration ID")); - } - - if (version >= 219 && IS_TARANIS_XLITES(board)) { - internalField.Append(new SignedField<8>(this, generalData.imuMax, "Gyro full scale")); - internalField.Append(new SignedField<8>(this, generalData.imuOffset, "Gyro Offset")); - } - - if (version >= 220) { - internalField.Append(new SignedField<2>(this, generalData.uartSampleMode, "Uart Sample Mode")); - internalField.Append(new UnsignedField<2>(this, generalData.rotEncMode)); - //internalField.Append(new SpareBitsField<6>(this)); // may need padding to end of 8 byte boundary - } -} - -void OpenTxGeneralData::beforeExport() -{ - uint16_t sum = 0; - - int count = 0; - for (int i = 0; i < inputsCount; i++) { - sum += generalData.calibMid[i]; - if (++count == 12) break; - sum += generalData.calibSpanNeg[i]; - if (++count == 12) break; - sum += generalData.calibSpanPos[i]; - if (++count == 12) break; - } - - chkSum = sum; - - if (Boards::getCapability((Board::Type)generalData.variant, - Board::SportMaxBaudRate) >= 400000) - generalData.internalModuleBaudrate = - (generalData.internalModuleBaudrate + moduleBaudratesList.size() - 1) % - moduleBaudratesList.size(); -} - -void OpenTxGeneralData::afterImport() -{ - if (Boards::getCapability((Board::Type)generalData.variant, - Board::SportMaxBaudRate) >= 400000) - generalData.internalModuleBaudrate = - (generalData.internalModuleBaudrate + 1) % moduleBaudratesList.size(); -} diff --git a/companion/src/firmwares/opentx/opentxeeprom.h b/companion/src/firmwares/opentx/opentxeeprom.h deleted file mode 100644 index 64eafe78b..000000000 --- a/companion/src/firmwares/opentx/opentxeeprom.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (C) EdgeTX - * - * Based on code named - * opentx - https://github.com/opentx/opentx - * th9x - http://code.google.com/p/th9x - * er9x - http://code.google.com/p/er9x - * gruvin9x - http://code.google.com/p/gruvin9x - * - * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef _OPENTXEEPROM_H_ -#define _OPENTXEEPROM_H_ - -#include -#include "eeprominterface.h" -#include "eepromimportexport.h" -#include - -#define GVARS_VARIANT 0x0001 -#define FRSKY_VARIANT 0x0002 -#define M128_VARIANT 0x8000 -#define TARANIS_X9E_VARIANT 0x8000 -#define TARANIS_X7_VARIANT 0x4000 -#define TARANIS_XLITE_VARIANT 0x2000 -#define TARANIS_XLITES_VARIANT 0x1000 -#define TARANIS_X9LITE_VARIANT 0x0800 -#define TARANIS_X9LITES_VARIANT 0x0801 -#define JUMPER_T12_VARIANT 0x4001 -#define RADIOMASTER_TX12_VARIANT 0x4002 -#define JUMPER_TLITE_VARIANT 0x4003 -#define RADIOMASTER_T8_VARIANT 0x4004 -#define JUMPER_TPRO_VARIANT 0x4005 -#define RADIOMASTER_ZORRO_VARIANT 0x4006 -#define BETAFPV_LR3PRO_VARIANT 0x4007 -#define RADIOMASTER_TX12_MK2_VARIANT 0x4008 -#define IFLIGHT_COMMANDO8_VARIANT 0x4009 - -class OpenTxGeneralData: public TransformedField { - public: - OpenTxGeneralData(GeneralSettings & generalData, Board::Type board, unsigned int version, unsigned int variant=0); - - virtual const QString & getName() { return internalField.getName(); } - - QStringList errors() - { - return _errors; - } - - protected: - virtual void beforeExport(); - virtual void afterImport(); - - virtual void setError(const QString & error) - { - qWarning() << error; - _errors << error; - } - - StructField internalField; - GeneralSettings & generalData; - Board::Type board; - unsigned int version; - int inputsCount; - unsigned int chkSum; - QStringList _errors; -}; - -class ProtocolsConversionTable: public ConversionTable -{ - public: - ProtocolsConversionTable(Board::Type board, int version) - { - int val = 0; - addConversion(PULSES_OFF, val++); - addConversion(PULSES_PPM, val++); - - addConversion(PULSES_PXX_XJT_X16, val); - addConversion(PULSES_PXX_XJT_D8, val); - addConversion(PULSES_PXX_XJT_LR12, val++); - - if (version >= 219) { - addConversion(PULSES_ACCESS_ISRM, val); - addConversion(PULSES_ACCST_ISRM_D16, val++); - } - - addConversion(PULSES_LP45, val); - addConversion(PULSES_DSM2, val); - addConversion(PULSES_DSMX, val++); - - addConversion(PULSES_CROSSFIRE, val++); - addConversion(PULSES_MULTIMODULE, val++); - - addConversion(PULSES_PXX_R9M, val++); - addConversion(PULSES_ACCESS_R9M, val++); - addConversion(PULSES_PXX_R9M_LITE, val++); - addConversion(PULSES_ACCESS_R9M_LITE, val++); - addConversion(PULSES_GHOST, val++); - addConversion(PULSES_ACCESS_R9M_LITE_PRO, val++); - - addConversion(PULSES_SBUS, val++); - - addConversion(PULSES_XJT_LITE_X16, val); - addConversion(PULSES_XJT_LITE_D8, val); - addConversion(PULSES_XJT_LITE_LR12, val++); - } -}; - -class ChannelsConversionTable: public ConversionTable -{ - public: - ChannelsConversionTable() - { - for (int i=4; i<=16; i+= 2) - addConversion(i, -4+i/2); - } -}; - - -class OpenTxModelData: public TransformedField { - public: - OpenTxModelData(ModelData & modelData, Board::Type board, unsigned int version, unsigned int variant); - - virtual const QString & getName() { return internalField.getName(); } - - QStringList errors() - { - return _errors; - } - - protected: - virtual void beforeExport(); - virtual void afterImport(); - - virtual void setError(const QString & error) - { - qWarning() << error; - _errors << error; - } - - StructField internalField; - ModelData & modelData; - Board::Type board; - unsigned int version; - unsigned int variant; - char name[256]; - int subprotocols[CPN_MAX_MODULES+1/*trainer*/]; - ChannelsConversionTable channelsConversionTable; - QStringList _errors; -}; - -void OpenTxEepromCleanup(void); -#endif // _OPENTXEEPROM_H_ diff --git a/companion/src/firmwares/opentx/opentxinterface.cpp b/companion/src/firmwares/opentx/opentxinterface.cpp index 2e62ea717..8b16d4906 100644 --- a/companion/src/firmwares/opentx/opentxinterface.cpp +++ b/companion/src/firmwares/opentx/opentxinterface.cpp @@ -20,8 +20,6 @@ */ #include "opentxinterface.h" -#include "opentxeeprom.h" -#include "rlefile.h" #include "appdata.h" #include "constants.h" @@ -42,463 +40,6 @@ using namespace Board; -QList opentxEEpromInterfaces; - -OpenTxEepromInterface::OpenTxEepromInterface(OpenTxFirmware * firmware): - EEPROMInterface(firmware->getBoard()), - efile(new RleFile()), - firmware(firmware) -{ -} - -OpenTxEepromInterface::~OpenTxEepromInterface() -{ - delete efile; -} - -const char * OpenTxEepromInterface::getName() -{ - switch (board) { - case BOARD_JUMPER_T12: - return "EdgeTX for Jumper T12"; - case BOARD_JUMPER_TLITE: - return "EdgeTX for Jumper T-Lite"; - case BOARD_JUMPER_TLITE_F4: - return "EdgeTX for Jumper T-Lite (F4 MCU)"; - case BOARD_JUMPER_TPRO: - return "EdgeTX for Jumper T-Pro"; - case BOARD_JUMPER_TPROV2: - return "EdgeTX for Jumper T-Pro V2"; - case BOARD_JUMPER_TPROS: - return "EdgeTX for Jumper T-Pro S"; - case BOARD_JUMPER_BUMBLEBEE: - return "EdgeTX for Jumper Bumblebee"; - case BOARD_JUMPER_T12MAX: - return "EdgeTX for Jumper T12 MAX"; - case BOARD_JUMPER_T14: - return "EdgeTX for Jumper T14"; - case BOARD_JUMPER_T15: - return "EdgeTX for Jumper T15"; - case BOARD_JUMPER_T16: - return "EdgeTX for Jumper T16"; - case BOARD_JUMPER_T18: - return "EdgeTX for Jumper T18"; - case BOARD_JUMPER_T20: - return "EdgeTX for Jumper T20"; - case BOARD_JUMPER_T20V2: - return "EdgeTX for Jumper T20 V2"; - case BOARD_RADIOMASTER_TX16S: - return "EdgeTX for Radiomaster TX16S"; - case BOARD_RADIOMASTER_TX12: - return "EdgeTX for Radiomaster TX12"; - case BOARD_RADIOMASTER_TX12_MK2: - return "EdgeTX for Radiomaster TX12 Mark II"; - case BOARD_RADIOMASTER_ZORRO: - return "EdgeTX for Radiomaster Zorro"; - case BOARD_RADIOMASTER_BOXER: - return "EdgeTX for Radiomaster Boxer"; - case BOARD_RADIOMASTER_POCKET: - return "EdgeTX for Radiomaster Pocket"; - case BOARD_RADIOMASTER_T8: - return "EdgeTX for Radiomaster T8"; - case BOARD_TARANIS_X9D: - return "EdgeTX for FrSky Taranis X9D"; - case BOARD_TARANIS_X9DP: - return "EdgeTX for FrSky Taranis X9D+"; - case BOARD_TARANIS_X9DP_2019: - return "EdgeTX for FrSky Taranis X9D+ 2019"; - case BOARD_TARANIS_X9E: - return "EdgeTX for FrSky Taranis X9E"; - case BOARD_TARANIS_X7: - return "EdgeTX for FrSky Taranis X7"; - case BOARD_TARANIS_X7_ACCESS: - return "EdgeTX for FrSky Taranis X7 Access"; - case BOARD_TARANIS_X9LITES: - return "EdgeTX for FrSky Taranis X9-Lite S"; - case BOARD_TARANIS_X9LITE: - return "EdgeTX for FrSky Taranis X9-Lite"; - case BOARD_TARANIS_XLITE: - return "EdgeTX for FrSky Taranis X-Lite"; - case BOARD_TARANIS_XLITES: - return "EdgeTX for FrSky Taranis X-Lite S/Pro"; - case BOARD_SKY9X: - return "EdgeTX for Sky9x board / 9X"; - case BOARD_9XRPRO: - return "EdgeTX for 9XR-PRO"; - case BOARD_AR9X: - return "EdgeTX for ar9x board / 9X"; - case BOARD_HORUS_X12S: - return "EdgeTX for FrSky Horus"; - case BOARD_X10: - return "EdgeTX for FrSky X10"; - case BOARD_X10_EXPRESS: - return "EdgeTX for FrSky X10 Express"; - case BOARD_FLYSKY_NV14: - return "EdgeTX for FlySky NV14"; - case BOARD_FLYSKY_EL18: - return "EdgeTX for FlySky EL18"; - case BOARD_FLYSKY_PL18: - return "EdgeTX for FlySky PL18"; - case BOARD_BETAFPV_LR3PRO: - return "EdgeTx for BETAFPV LR3PRO"; - case BOARD_IFLIGHT_COMMANDO8: - return "EdgeTX for iFlight Commando 8"; - case BOARD_FATFISH_F16: - return "EdgeTX for Fatfish F16"; - case BOARD_HELLORADIOSKY_V16: - return "EdgeTX for HelloRadioSky V16"; - default: - return "Board is unknown to EdgeTX"; - } -} - -bool OpenTxEepromInterface::loadRadioSettingsFromRLE(GeneralSettings & settings, RleFile * rleFile, uint8_t version) -{ - // Companion loads the current profile firmware and associated board hardware definition ONLY!!!! - // For each OpenTxEepromInterface create a firmware variant to force the associated base firmware board hardware definition to be loaded. - // Note: The base firmware instance does not do load its hardware definition to save unnecessary processing. - // To create the variant take the base id and append the language from the current radio profile. - Firmware *fw = Firmware::getFirmwareForId(firmware->getId().append("-%1").arg(g.currentProfile().fwType().split('-').last())); - if (!fw) { - qWarning() << " error unable to create firmware variant"; - return false; - } - - QByteArray data(sizeof(settings), 0); // GeneralSettings should be always bigger than the EEPROM struct - OpenTxGeneralData open9xSettings(settings, board, version); - efile->openRd(FILE_GENERAL); - int size = rleFile->readRlc2((uint8_t *)data.data(), data.size()); - if (size) { - open9xSettings.Import(data); - return checkVariant(settings.version, settings.variant); - } - else { - qWarning() << " error when loading general settings"; - return false; - } -} - -bool OpenTxEepromInterface::loadModelFromRLE(ModelData & model, RleFile * rleFile, unsigned int index, uint8_t version, uint32_t variant) -{ - QByteArray data(sizeof(model), 0); // ModelData should be always bigger than the EEPROM struct - rleFile->openRd(FILE_MODEL(index)); - int size = rleFile->readRlc2((uint8_t *)data.data(), data.size()); - if (size) { - if (loadFromByteArray(model, data, version, variant)) { - model.used = true; - } - } - else { - model.clear(); - } - return true; -} - -template -bool OpenTxEepromInterface::saveToByteArray(const T & src, QByteArray & data, uint8_t version) -{ - if (version == 0) { - version = getLastDataVersion(getBoard()); - } - QByteArray raw; - T srcCopy(src); // work on a copy of radio data, because Export() will modify it! - M manager(srcCopy, board, version, 0); - // manager.dump(); - manager.Export(raw); - data.resize(8); - *((uint32_t*)&data.data()[0]) = Boards::getFourCC(board); - data[4] = version; - data[5] = 'M'; - *((uint16_t*)&data.data()[6]) = raw.size(); - data.append(raw); - return true; -} - -template -bool OpenTxEepromInterface::loadFromByteArray(T & dest, const QByteArray & data, uint8_t version, uint32_t variant) -{ - // Companion loads the current profile firmware and associated board hardware definition ONLY!!!! - // For each OpenTxEepromInterface create a firmware variant to force the associated base firmware board hardware definition to be loaded. - // Note: The base firmware instance does not do load its hardware definition to save unnecessary processing. - // To create the variant take the base id and append the language from the current radio profile. - Firmware *fw = Firmware::getFirmwareForId(firmware->getId().append("-%1").arg(g.currentProfile().fwType().split('-').last())); - if (!fw) { - qWarning() << " error unable to create firmware variant"; - return false; - } - - M manager(dest, board, version, variant); - if (manager.Import(data) != 0) { - return false; - } - // manager.dump(); // Dumps the structure so that it's easy to check with firmware datastructs.h - return true; -} - -template -bool OpenTxEepromInterface::loadFromByteArray(T & dest, const QByteArray & data) -{ - uint32_t fourcc = *((uint32_t*)&data.data()[0]); - if (Boards::getFourCC(board) != fourcc) { - if (IS_FAMILY_HORUS_OR_T16(board) && fourcc == 0x3178396F) { - qDebug() << QString("%1: Deprecated fourcc used %2 vs %3").arg(getName()).arg(fourcc).arg(Boards::getFourCC(board)); - } - else { - qDebug() << QString("%1: Wrong fourcc %2 vs %3").arg(getName()).arg(fourcc).arg(Boards::getFourCC(board)); - return false; - } - } - - if (Boards::getFourCC(board) == Boards::getFourCC(getCurrentBoard()) && - board != getCurrentFirmware()->getBoard()) { - qDebug() << QString("%1: Fourcc not unique and does not match profile board: %2").arg(getName()).arg(Boards::getBoardName(getCurrentBoard())); - return false; - } - - qDebug() << QString("%1: OK").arg(getName()); - uint8_t version = data[4]; - QByteArray raw = data.right(data.size() - 8); - return loadFromByteArray(dest, raw, version); -} - -unsigned long OpenTxEepromInterface::load(RadioData &radioData, const uint8_t * eeprom, int size) -{ - QDebug dbg = qDebug(); - dbg.setAutoInsertSpaces(false); - dbg << "trying " << getName() << " import..."; - - std::bitset errors; - - if (size != Boards::getEEpromSize(board)) { - if (size == 4096) { - int notnull = false; - for (int i = 2048; i < 4096; i++) { - if (eeprom[i] != 255) { - notnull = true; - } - } - if (notnull) { - dbg << " wrong size (" << size << ")"; - errors.set(WRONG_SIZE); - return errors.to_ulong(); - } - else { - errors.set(HAS_WARNINGS); - errors.set(WARNING_WRONG_FIRMWARE); - size = 2048; - } - } - else { - dbg << " wrong size (" << size << "/" << Boards::getEEpromSize(board) << ")"; - errors.set(WRONG_SIZE); - return errors.to_ulong(); - } - } - - if (!efile->EeFsOpen((uint8_t *) eeprom, size, board)) { - dbg << " wrong file system"; - errors.set(WRONG_FILE_SYSTEM); - return errors.to_ulong(); - } - - efile->openRd(FILE_GENERAL); - - uint8_t version; - if (efile->readRlc2(&version, 1) != 1) { - dbg << " no"; - errors.set(UNKNOWN_ERROR); - return errors.to_ulong(); - } - - dbg << " version " << (unsigned int) version; - - EepromLoadErrors version_error = checkVersion(version); - if (version_error == OLD_VERSION) { - errors.set(version_error); - errors.set(HAS_WARNINGS); - } - else if (version_error == NOT_OPENTX) { - dbg << " not OpenTX"; - errors.set(version_error); - return errors.to_ulong(); - } - - if (!loadRadioSettingsFromRLE(radioData.generalSettings, efile, version)) { - dbg << " ko"; - errors.set(UNKNOWN_ERROR); - return errors.to_ulong(); - } - - dbg << " variant " << radioData.generalSettings.variant; - if (getCurrentFirmware()->getCapability(Models) == 0) { - radioData.models.resize(firmware->getCapability(Models)); - } - for (int i = 0; i < firmware->getCapability(Models); i++) { - if (i < (int)radioData.models.size() && !loadModelFromRLE(radioData.models[i], efile, i, version, radioData.generalSettings.variant)) { - dbg << " ko"; - errors.set(UNKNOWN_ERROR); - if (getCurrentFirmware()->getCapability(Models) == 0) { - radioData.models.resize(i); - } - return errors.to_ulong(); - } - } - dbg << " ok"; - errors.set(ALL_OK); - return errors.to_ulong(); -} - -uint8_t OpenTxEepromInterface::getLastDataVersion(Board::Type board) -{ - return 220; // Note: this is the last bin format before the switch to YAML introduced in Companion version 2.6 -} - -void OpenTxEepromInterface::showErrors(const QString & title, const QStringList & errors) -{ - QString msg; - if (errors.empty()) { - msg = tr("Unknown error"); - } - else { - int noErrorsToDisplay = std::min((int)errors.size(), 10); - for (int n = 0; n < noErrorsToDisplay; n++) { - msg += " -" + errors.at(n) + "\n"; - } - if (noErrorsToDisplay < errors.size()) { - msg += tr(" ... plus %1 errors").arg(errors.size() - noErrorsToDisplay) + "\n" + msg; - } - } - - QMessageBox::warning(NULL, - CPN_STR_TTL_ERROR, - title + "\n" + msg); -} - -int OpenTxEepromInterface::save(uint8_t * eeprom, const RadioData & radioData, uint8_t version, uint32_t variant) -{ - // TODO QMessageBox::warning should not be called here - - if (version == 0) { - version = getLastDataVersion(board); - } - - int size = Boards::getEEpromSize(board); - - efile->EeFsCreate(eeprom, size, board, version); - - if (IS_TARANIS_X9E(board)) { - variant |= TARANIS_X9E_VARIANT; - } - else if (IS_TARANIS_X9LITES(board)) { - variant |= TARANIS_X9LITES_VARIANT; - } - else if (IS_TARANIS_X9LITE(board)) { - variant |= TARANIS_X9LITE_VARIANT; - } - else if (IS_TARANIS_X7_ACCESS(board)) { - variant |= TARANIS_X7_VARIANT; - } - else if (IS_TARANIS_X7(board)) { - variant |= TARANIS_X7_VARIANT; - } - else if (IS_TARANIS_XLITES(board)) { - variant |= TARANIS_XLITES_VARIANT; - } - else if (IS_TARANIS_XLITE(board)) { - variant |= TARANIS_XLITE_VARIANT; - } - else if (IS_JUMPER_T12(board)) { - variant |= JUMPER_T12_VARIANT; - } - else if (IS_JUMPER_TLITE(board)) { - variant |= JUMPER_TLITE_VARIANT; - } - else if (IS_JUMPER_TPRO(board)) { - variant |= JUMPER_TPRO_VARIANT; - } - else if (IS_RADIOMASTER_TX12(board)) { - variant |= RADIOMASTER_TX12_VARIANT; - } - else if (IS_RADIOMASTER_TX12_MK2(board)) { - variant |= RADIOMASTER_TX12_MK2_VARIANT; - } - else if (IS_RADIOMASTER_ZORRO(board)) { - variant |= RADIOMASTER_ZORRO_VARIANT; - } - else if (IS_RADIOMASTER_T8(board)) { - variant |= RADIOMASTER_T8_VARIANT; - } - OpenTxGeneralData generator((GeneralSettings &)radioData.generalSettings, board, version, variant); - // generator.dump(); - QByteArray data; - generator.Export(data); - int sz = efile->writeRlc2(FILE_GENERAL, FILE_TYP_GENERAL, (const uint8_t *)data.constData(), data.size()); - if (sz == 0 || generator.errors().count() > 0) { - showErrors(tr("Cannot write radio settings"), generator.errors()); - return 0; - } - - for (int i = 0; i < getCurrentFirmware()->getCapability(Models); i++) { - if (i < (int)radioData.models.size() && !radioData.models[i].isEmpty()) { - OpenTxModelData generator((ModelData &)radioData.models[i], board, version, variant); - // generator.dump(); - QByteArray data; - generator.Export(data); - int sz = efile->writeRlc2(FILE_MODEL(i), FILE_TYP_MODEL, (const uint8_t *)data.constData(), data.size()); - if (sz == 0 || generator.errors().count() > 0) { - showErrors(tr("Cannot write model %1").arg(radioData.models[i].name), generator.errors()); - return 0; - } - } - } - - return size; -} - -int OpenTxEepromInterface::getSize(const ModelData &model) -{ - if (IS_SKY9X(board)) - return 0; - - if (model.isEmpty()) - return 0; - - QByteArray tmp(Boards::getEEpromSize(Board::BOARD_UNKNOWN), 0); - efile->EeFsCreate((uint8_t *) tmp.data(), Boards::getEEpromSize(Board::BOARD_UNKNOWN), board, 255/*version max*/); - - ModelData srcCopy(model); // work on a copy of model data, because Export() may modify it! - OpenTxModelData open9xModel(srcCopy, board, 255/*version max*/, getCurrentFirmware()->getVariantNumber()); - - QByteArray eeprom; - open9xModel.Export(eeprom); - int sz = efile->writeRlc2(0, FILE_TYP_MODEL, (const uint8_t *) eeprom.constData(), eeprom.size()); - if (sz != eeprom.size()) { - return -1; - } - return efile->size(0); -} - -int OpenTxEepromInterface::getSize(const GeneralSettings &settings) -{ - if (IS_SKY9X(board)) - return 0; - - QByteArray tmp(Boards::getEEpromSize(Board::BOARD_UNKNOWN), 0); - efile->EeFsCreate((uint8_t *) tmp.data(), Boards::getEEpromSize(Board::BOARD_UNKNOWN), board, 255); - - GeneralSettings srcCopy(settings); // work on a copy of settings data, because Export() may modify it! - OpenTxGeneralData open9xGeneral(srcCopy, board, 255, getCurrentFirmware()->getVariantNumber()); - // open9xGeneral.dump(); - - QByteArray eeprom; - open9xGeneral.Export(eeprom); - int sz = efile->writeRlc2(0, FILE_TYP_GENERAL, (const uint8_t *) eeprom.constData(), eeprom.size()); - if (sz != eeprom.size()) { - return -1; - } - return efile->size(0); -} - Firmware * OpenTxFirmware::getFirmwareVariant(const QString &id) { if (id == getId()) { @@ -736,33 +277,6 @@ int OpenTxFirmware::getCapability(::Capability capability) return true; case HasMahPersistent: return true; - case SimulatorVariant: - if (IS_TARANIS_X9E(board)) - return TARANIS_X9E_VARIANT; - else if (IS_TARANIS_X9LITES(board)) - return TARANIS_X9LITES_VARIANT; - else if (IS_TARANIS_X9LITE(board)) - return TARANIS_X9LITE_VARIANT; - else if (IS_TARANIS_X7(board)) - return TARANIS_X7_VARIANT; - else if (IS_TARANIS_XLITES(board)) - return TARANIS_XLITES_VARIANT; - else if (IS_TARANIS_XLITE(board)) - return TARANIS_XLITE_VARIANT; - else if (IS_BETAFPV_LR3PRO(board)) - return BETAFPV_LR3PRO_VARIANT; - else if (IS_IFLIGHT_COMMANDO8(board)) - return IFLIGHT_COMMANDO8_VARIANT; - else if (IS_JUMPER_T12(board)) - return JUMPER_T12_VARIANT; - else if (IS_JUMPER_TLITE(board)) - return JUMPER_TLITE_VARIANT; - else if (IS_RADIOMASTER_TX12(board)) - return RADIOMASTER_TX12_VARIANT; - else if (IS_RADIOMASTER_T8(board)) - return RADIOMASTER_T8_VARIANT; - else - return 0; case MavlinkTelemetry: return id.contains("mavlink") ? 1 : 0; case SportTelemetry: @@ -873,273 +387,6 @@ size_t getSizeA(T (&)[SIZE]) return SIZE; } -EepromLoadErrors OpenTxEepromInterface::checkVersion(unsigned int version) -{ - switch (version) { - case 201: - // first version - case 202: - // channel order is now always RUD - ELE - THR - AIL - // changes in timers - // ppmFrameLength added - // thrTraceSrc added - case 203: - // mixers changed (for the trims use for change the offset of a mix) - // telemetry offset raised to -127 +127 - // function switches now have a param on 4 bits - case 204: - // telemetry changes (bars) - case 205: - // mixer changes (differential, negative curves)... - // case 206: - case 207: - // V4: Rotary Encoders position in FlightModes - case 208: - // Trim value in 16bits - // FrSky A1/A2 offset on 12bits - // ARM: More Mixers / Expos / CSW / FSW / CHNOUT - case 209: - // Add TrmR, TrmE, TrmT, TrmA as Mix sources - // Trims are now OFF / ON / Rud / Ele / Thr / Ail - case 210: - // Add names in Mixes / Expos - // Add a new telemetry screen - // Add support for Play Track - case 211: - // Curves big change - case 212: - // Big changes in mixers / limitse - case 213: - // GVARS / Variants introduction - case 214: - // Massive EEPROM change! - case 215: - // M128 revert because too much RAM used! - case 216: - // A lot of things (first github release) - case 217: - // 3 logical switches removed on M128 / gruvin9x boards - return OLD_VERSION; - case 218: - // ACCESS - // switches add for X7/X10/X12S - // 60 sensors for X12 - return OLD_VERSION; - - case 219: - // 60 (Horus / X9) / 40 (others) telemetry sensors instead of 32 - // ALL: ReceiverData array added - // ALL: registrationId added - // ALL: failsafeChannels moved from ModuleData to ModelData - // ALL: ModuleData / TrainerModuleData modified - // PCBX9 : 6 chars for expos / mixes names instead of 8 - // on X7: 2 additional switches - // on X9D / X9D+: 1 additional switch - // on xlite : 2 more storage switches - // on X10: 2 additional pots => 12 multipos switches - return OLD_VERSION; - - case 220: - // Refer radio/src/storage/conversions/conversions_219_220.cpp - // ALL: TimerData split mode into separate mode and switch and change modes - // ALL: TimerData countdownStart invert value - // ALL: convert more fields from zchar to normal string - // COLORLCD: change CustomScreenData and TopBarPersistentData - return OLD_VERSION; - - case 221: - // ALL: YAML storage - // X10PCB: add pots EXT3 and EXT4 (conversion required as shifts slider settings in multiple fields) - // RM TX16S: add Flysky gimbals firmware build option and repurpose EXT3 and EXT4 if selected - // ??: add source TX GPS - break; - - default: - return NOT_OPENTX; - } - - return ALL_OK; -} - -bool OpenTxEepromInterface::checkVariant(unsigned int version, unsigned int variant) -{ - bool variantError = false; - if (IS_TARANIS_X9E(board)) { - if (variant != TARANIS_X9E_VARIANT) { - variantError = true; - } - } - else if (IS_TARANIS_X7(board)) { - if (variant != TARANIS_X7_VARIANT) { - variantError = true; - } - } - else if (IS_TARANIS_XLITES(board)) { - if (variant != TARANIS_XLITES_VARIANT) { - variantError = true; - } - } - else if (IS_TARANIS_XLITE(board)) { - if (variant != TARANIS_XLITE_VARIANT) { - variantError = true; - } - } - else if (IS_TARANIS_X9LITES(board)) { - if (variant != TARANIS_X9LITES_VARIANT) { - variantError = true; - } - } - else if (IS_TARANIS_X9LITE(board)) { - if (variant != TARANIS_X9LITE_VARIANT) { - variantError = true; - } - } - else if (IS_JUMPER_T12(board)) { - if (variant != JUMPER_T12_VARIANT) { - variantError = true; - } - } - else if (IS_JUMPER_TLITE(board)) { - if (variant != JUMPER_TLITE_VARIANT) { - variantError = true; - } - } - else if (IS_JUMPER_TPRO(board)) { - if (variant != JUMPER_TPRO_VARIANT) { - variantError = true; - } - } - else if (IS_RADIOMASTER_TX12(board)) { - if (variant != RADIOMASTER_TX12_VARIANT) { - variantError = true; - } - } - else if (IS_RADIOMASTER_TX12_MK2(board)) { - if (variant != RADIOMASTER_TX12_MK2_VARIANT) { - variantError = true; - } - } - else if (IS_RADIOMASTER_ZORRO(board)) { - if (variant != RADIOMASTER_ZORRO_VARIANT) { - variantError = true; - } - } - else if (IS_RADIOMASTER_T8(board)) { - if (variant != RADIOMASTER_T8_VARIANT) { - variantError = true; - } - } - else if (IS_TARANIS(board)) { - if (variant != 0) { - variantError = true; - } - } - - if (variantError) { - qWarning() << " wrong variant (" << variant << ")"; - return false; - } - - return true; -} - -bool -OpenTxEepromInterface::loadModelFromBackup(ModelData & model, const uint8_t * data, unsigned int size, uint8_t version, uint32_t variant) -{ - QByteArray backupData((char *) data, size); - QByteArray modelData; - if (IS_SKY9X(board)) { - modelData = QByteArray((char *) data, size); - } - else { - importRlc(modelData, backupData); - } - if (modelData.size()) { - if (loadFromByteArray(model, modelData, version, variant)) { - model.used = true; - return true; - } - } - model.clear(); - return false; -} - -unsigned long OpenTxEepromInterface::loadBackup(RadioData &radioData, const uint8_t * eeprom, int esize, int index) -{ - std::bitset errors; - - QDebug dbg = qDebug(); - dbg.setAutoInsertSpaces(false); - dbg << "trying " << getName() << " backup import..."; - - if (esize < 8 || memcmp(eeprom, "o9x", 3) != 0) { - dbg << " no\n"; - errors.set(WRONG_SIZE); - return errors.to_ulong(); - } - - Type backupBoard = (Type) -1; - switch (eeprom[3]) { - case 0x33: - backupBoard = BOARD_TARANIS_X9D; - break; - case 0x32: - backupBoard = BOARD_SKY9X; - break; - default: - dbg << " unknown board"; - errors.set(UNKNOWN_BOARD); - return errors.to_ulong(); - } - - if (backupBoard != board) { - dbg << " not right board"; - errors.set(WRONG_BOARD); - return errors.to_ulong(); - } - - uint8_t version = eeprom[4]; - uint8_t bcktype = eeprom[5]; - uint16_t size = ((uint16_t) eeprom[7] << 8) + eeprom[6]; - uint16_t variant = ((uint16_t) eeprom[9] << 8) + eeprom[8]; - - dbg << " version " << (unsigned int) version << " "; - - EepromLoadErrors version_error = checkVersion(version); - if (version_error == OLD_VERSION) { - errors.set(version_error); - errors.set(HAS_WARNINGS); - } - else if (version_error == NOT_OPENTX) { - dbg << " not open9x"; - errors.set(version_error); - return errors.to_ulong(); - } - - if (size > esize - 8) { - dbg << " wrong size"; - errors.set(WRONG_SIZE); - return errors.to_ulong(); - } - - if (bcktype == 'M') { - if (!loadModelFromBackup(radioData.models[index], &eeprom[8], size, version, variant)) { - dbg << " ko"; - errors.set(UNKNOWN_ERROR); - return errors.to_ulong(); - } - } - else { - dbg << " backup type not supported"; - errors.set(BACKUP_NOT_SUPPORTED); - return errors.to_ulong(); - } - - dbg << " ok"; - errors.set(ALL_OK); - return errors.to_ulong(); -} - QString OpenTxFirmware::getReleaseNotesUrl() { return QString("%1/downloads").arg(EDGETX_HOME_PAGE_URL); @@ -1150,10 +397,6 @@ QString OpenTxFirmware::getReleaseNotesUrl() void registerOpenTxFirmware(OpenTxFirmware * firmware, bool deprecated = false) { - OpenTxEepromInterface * eepromInterface = new OpenTxEepromInterface(firmware); - firmware->setEEpromInterface(eepromInterface); - opentxEEpromInterfaces.push_back(eepromInterface); - eepromInterfaces.push_back(eepromInterface); if (!deprecated) Firmware::addRegisteredFirmware(firmware); } @@ -1215,24 +458,6 @@ void addOpenTxTaranisOptions(OpenTxFirmware * firmware) addOpenTxFontOptions(firmware); } -void addOpenTxArm9xOptions(OpenTxFirmware * firmware, bool dblkeys = true) -{ - addOpenTxCommonOptions(firmware); - firmware->addOption("heli", Firmware::tr("Enable HELI menu and cyclic mix support")); - firmware->addOption("gvars", Firmware::tr("Global variables"), GVARS_VARIANT); - firmware->addOption("potscroll", Firmware::tr("Pots use in menus navigation")); - firmware->addOption("autosource", Firmware::tr("In model setup menus automatically set source by moving the control")); - firmware->addOption("autoswitch", Firmware::tr("In model setup menus automatically set switch by moving the control")); - firmware->addOption("nographics", Firmware::tr("No graphical check boxes and sliders")); - firmware->addOption("battgraph", Firmware::tr("Battery graph")); - firmware->addOption("nobold", Firmware::tr("Don't use bold font for highlighting active items")); - //firmware->addOption("bluetooth", Firmware::tr("Bluetooth interface")); - if (dblkeys) - firmware->addOption("dblkeys", Firmware::tr("Enable resetting values by pressing up and down at the same time")); - addOpenTxFontOptions(firmware); - addOpenTxRfOptions(firmware, FLEX); -} - // TODO: refactoring OpenTxFirmware constructor - need to check if used elsewhere and how #define FIRMWAREID(flavour) std::string(FIRMWARE_ID_PREFIX).append(flavour).c_str() @@ -1585,48 +810,4 @@ void unregisterOpenTxFirmwares() foreach (Firmware * f, Firmware::getRegisteredFirmwares()) { delete f; } - unregisterEEpromInterfaces(); -} - -template -OpenTxEepromInterface * loadFromByteArray(T & dest, const QByteArray & data) -{ - foreach(OpenTxEepromInterface * eepromInterface, opentxEEpromInterfaces) { - if (eepromInterface->loadFromByteArray(dest, data)) { - return eepromInterface; - } - } - return NULL; -} - -template -bool saveToByteArray(const T & dest, QByteArray & data) -{ - Board::Type board = getCurrentBoard(); - foreach(OpenTxEepromInterface * eepromInterface, opentxEEpromInterfaces) { - if (eepromInterface->getBoard() == board) { - return eepromInterface->saveToByteArray(dest, data); - } - } - return false; -} - -OpenTxEepromInterface * loadModelFromByteArray(ModelData & model, const QByteArray & data) -{ - return loadFromByteArray(model, data); -} - -OpenTxEepromInterface * loadRadioSettingsFromByteArray(GeneralSettings & settings, const QByteArray & data) -{ - return loadFromByteArray(settings, data); -} - -bool writeModelToByteArray(const ModelData & model, QByteArray & data) -{ - return saveToByteArray(model, data); -} - -bool writeRadioSettingsToByteArray(const GeneralSettings & settings, QByteArray & data) -{ - return saveToByteArray(settings, data); } diff --git a/companion/src/firmwares/opentx/opentxinterface.h b/companion/src/firmwares/opentx/opentxinterface.h index ae2a16dd0..2d569e293 100644 --- a/companion/src/firmwares/opentx/opentxinterface.h +++ b/companion/src/firmwares/opentx/opentxinterface.h @@ -19,70 +19,12 @@ * GNU General Public License for more details. */ -#ifndef _OPENTXINTERFACE_H_ -#define _OPENTXINTERFACE_H_ +#pragma once #include "eeprominterface.h" #include -class RleFile; -class OpenTxFirmware; - -class OpenTxEepromInterface : public EEPROMInterface -{ - Q_DECLARE_TR_FUNCTIONS(OpenTxEepromInterface) - - public: - - OpenTxEepromInterface(OpenTxFirmware * firmware); - - virtual ~OpenTxEepromInterface(); - - virtual unsigned long load(RadioData &, const uint8_t * eeprom, int size); - - bool loadModelFromBackup(ModelData & model, const uint8_t * data, unsigned int size, uint8_t version, uint32_t variant); - - virtual unsigned long loadBackup(RadioData &, const uint8_t * eeprom, int esize, int index); - - virtual int save(uint8_t * eeprom, const RadioData & radioData, uint8_t version=0, uint32_t variant=0); - - virtual int getSize(const ModelData &); - - virtual int getSize(const GeneralSettings &); - - protected: - - const char * getName(); - - EepromLoadErrors checkVersion(unsigned int version); - - bool checkVariant(unsigned int version, unsigned int variant); - - template - bool loadFromByteArray(T & dest, const QByteArray & data, uint8_t version, uint32_t variant=0); - - public: - template - bool loadFromByteArray(T & dest, const QByteArray & data); - - template - bool saveToByteArray(const T & src, QByteArray & data, uint8_t version=0); - - bool loadRadioSettingsFromRLE(GeneralSettings & settings, RleFile * rleFile, uint8_t version); - - bool loadModelFromRLE(ModelData & model, RleFile * rleFile, unsigned int index, uint8_t version, uint32_t variant); - - void showErrors(const QString & title, const QStringList & errors); - - uint8_t getLastDataVersion(Board::Type board); - - RleFile * efile; - - OpenTxFirmware * firmware; - -}; - class OpenTxFirmware: public Firmware { Q_DECLARE_TR_FUNCTIONS(OpenTxFirmware) @@ -92,7 +34,6 @@ class OpenTxFirmware: public Firmware Firmware(parent, id, parent->getName(), parent->getBoard(), parent->getDownloadId(), parent->getSimulatorId(), parent->getHwDefnId()) { - setEEpromInterface(parent->getEEpromInterface()); } OpenTxFirmware(const QString & id, const QString & name, const Board::Type board, @@ -157,13 +98,3 @@ class OpenTxFirmware: public Firmware void registerOpenTxFirmwares(); void unregisterOpenTxFirmwares(); - -extern QList opentxEEpromInterfaces; - -OpenTxEepromInterface * loadModelFromByteArray(ModelData & model, const QByteArray & data); -OpenTxEepromInterface * loadRadioSettingsFromByteArray(GeneralSettings & settings, const QByteArray & data); - -bool writeModelToByteArray(const ModelData & model, QByteArray & data); -bool writeRadioSettingsToByteArray(const GeneralSettings & settings, QByteArray & data); - -#endif // _OPENTXINTERFACE_H_ diff --git a/companion/src/flasheepromdialog.cpp b/companion/src/flasheepromdialog.cpp deleted file mode 100644 index a4acd9022..000000000 --- a/companion/src/flasheepromdialog.cpp +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Copyright (C) EdgeTX - * - * Based on code named - * opentx - https://github.com/opentx/opentx - * th9x - http://code.google.com/p/th9x - * er9x - http://code.google.com/p/er9x - * gruvin9x - http://code.google.com/p/gruvin9x - * - * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "flasheepromdialog.h" -#include "ui_flasheepromdialog.h" -#include "eeprominterface.h" -#include "helpers.h" -#include "storage.h" -#include "appdata.h" -#include "progressdialog.h" -#include "radiointerface.h" -#include "splashlibrarydialog.h" - -FlashEEpromDialog::FlashEEpromDialog(QWidget *parent, const QString &filename): - QDialog(parent), - ui(new Ui::FlashEEpromDialog), - eepromFilename(filename) -{ - 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.profile[g.id()].pBackupDir(); - if (backupPath.isEmpty()) { - backupPath = g.backupDir(); - ui->backupBeforeWrite->setChecked(g.enableBackup() || g.profile[g.id()].penableBackup()); - } - if (backupPath.isEmpty() || !QDir(backupPath).exists()) { - ui->backupBeforeWrite->setEnabled(false); - } -} - -FlashEEpromDialog::~FlashEEpromDialog() -{ - delete ui; -} - -void FlashEEpromDialog::showEvent(QShowEvent *) -{ - updateUI(); -} - -void FlashEEpromDialog::updateUI() -{ - // ui->burnButton->setEnabled(true); - ui->eepromFilename->setText(eepromFilename); - if (!eepromFilename.isEmpty() && 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()==(CPN_MAX_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(), EXTERNAL_EEPROM_FILES_FILTER); - if (!filename.isEmpty()) { - eepromFilename = filename; - updateUI(); - } -} - -int FlashEEpromDialog::getEEpromVersion(const QString & filename) -{ - int result = -1; - QSharedPointer radioData = QSharedPointer(new RadioData()); - Storage storage(filename); - if (storage.load(*radioData)) { - result = radioData->generalSettings.version; - } - else { - QMessageBox::warning(this, CPN_STR_TTL_ERROR, storage.error()); - } - return result; -} - -bool FlashEEpromDialog::patchCalibration(RadioData * radioData) -{ - QString calib = g.profile[g.id()].stickPotCalib(); - QString trainercalib = g.profile[g.id()].trainerCalib(); - int potsnum = getBoardCapability(getCurrentBoard(), Board::Pots); - int8_t txVoltageCalibration = (int8_t) g.profile[g.id()].txVoltageCalibration(); - int8_t txCurrentCalibration = (int8_t) g.profile[g.id()].txCurrentCalibration(); - int8_t PPM_Multiplier = (int8_t) g.profile[g.id()].ppmMultiplier(); - - if ((calib.length()==(CPN_MAX_STICKS+potsnum)*12) && (trainercalib.length()==16)) { - QString Byte; - int16_t byte16; - bool ok; - for (int i=0; igeneralSettings.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.txCurrentCalibration = txCurrentCalibration; - radioData->generalSettings.txVoltageCalibration = txVoltageCalibration; - radioData->generalSettings.PPM_Multiplier = PPM_Multiplier; - return true; - } - else { - QMessageBox::critical(this, CPN_STR_TTL_WARNING, tr("Wrong radio calibration data in profile, Settings not patched")); - return false; - } -} - -bool FlashEEpromDialog::patchHardwareSettings(RadioData * radioData) -{ - 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, CPN_STR_TTL_WARNING, tr("Wrong radio setting data in profile, Settings not patched")); - return false; - } -} - -void FlashEEpromDialog::on_burnButton_clicked() -{ - QString filename = eepromFilename; - bool patch = false; - - if (ui->patchCalibration->isChecked() || ui->patchHardwareSettings->isChecked()) { - QSharedPointer radioData = QSharedPointer(new RadioData()); - Storage storage(eepromFilename); - if (storage.load(*radioData)) { - if (ui->patchCalibration->isChecked()) - patch |= patchCalibration(radioData.data()); - if (ui->patchHardwareSettings->isChecked()) - patch |= patchHardwareSettings(radioData.data()); - } - - if (patch) { - filename = generateProcessUniqueTempFileName("patched.bin"); - QFile file(filename); - uint8_t *eeprom = (uint8_t*)malloc(Boards::getEEpromSize(getCurrentBoard())); - int eeprom_size = getCurrentEEpromInterface()->save(eeprom, *radioData, 0, getCurrentFirmware()->getVariantNumber()); - if (eeprom_size == 0) { - return; - } - if (!file.open(QIODevice::WriteOnly)) { - QMessageBox::warning(this, CPN_STR_TTL_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, CPN_STR_TTL_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; - QString backupPath; - if (ui->backupBeforeWrite->isChecked()) { - backupPath = g.profile[g.id()].pBackupDir(); - if (backupPath.isEmpty()) { - backupPath=g.backupDir(); - } - backupFilename = backupPath + "/backup-" + QDateTime().currentDateTime().toString("yyyy-MM-dd-HHmmss") + ".bin"; - } - else if (ui->checkFirmwareCompatibility->isChecked()) { - backupFilename = generateProcessUniqueTempFileName("eeprom.bin"); - } - if (!backupFilename.isEmpty()) { - if (!readSettings(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, CPN_STR_TTL_WARNING, tr("The radio firmware belongs to another product family, check file and preferences!")); - return; - } - else if (compatVersion < eepromVersion) { - QMessageBox::warning(this, CPN_STR_TTL_WARNING, tr("The radio firmware is outdated, please upgrade!")); - return; - } - filename = compatEEprom; - } - else if (QMessageBox::question(this, CPN_STR_TTL_ERROR, tr("Cannot check Models and Settings compatibility! Continue anyway?"), QMessageBox::Yes|QMessageBox::No) == QMessageBox::No) { - return; - } - qunlink(firmwareFilename); - } - - // and write... - bool result = writeSettings(filename, progressDialog.progress()); - if (!result && !progressDialog.isEmpty()) { - progressDialog.exec(); - } -} - -void FlashEEpromDialog::on_cancelButton_clicked() -{ - close(); -} - -void FlashEEpromDialog::shrink() -{ - resize(0, 0); -} - diff --git a/companion/src/flasheepromdialog.h b/companion/src/flasheepromdialog.h deleted file mode 100644 index a2ff9a6c4..000000000 --- a/companion/src/flasheepromdialog.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) EdgeTX - * - * Based on code named - * opentx - https://github.com/opentx/opentx - * th9x - http://code.google.com/p/th9x - * er9x - http://code.google.com/p/er9x - * gruvin9x - http://code.google.com/p/gruvin9x - * - * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef _FLASHEEPROMDIALOG_H_ -#define _FLASHEEPROMDIALOG_H_ - -#include -#include - -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(RadioData * radioData); - bool patchHardwareSettings(RadioData * radioData); - virtual void showEvent(QShowEvent *); - -private: - Ui::FlashEEpromDialog *ui; - QString eepromFilename; -}; - -#endif // _FLASHEEPROMDIALOG_H_ diff --git a/companion/src/flasheepromdialog.ui b/companion/src/flasheepromdialog.ui deleted file mode 100644 index b57c82fb7..000000000 --- a/companion/src/flasheepromdialog.ui +++ /dev/null @@ -1,198 +0,0 @@ - - - FlashEEpromDialog - - - - 0 - 0 - 399 - 201 - - - - - 0 - 0 - - - - - 0 - 0 - - - - Write Models and Settings to Radio - - - - :/themes/classic/16/write_eeprom.png:/themes/classic/16/write_eeprom.png - - - - - - - - true - - - - 0 - 0 - - - - - 250 - 0 - - - - true - - - - - - - - 0 - 0 - - - - Load... - - - - - - - - - - 75 - true - - - - Current Profile - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - Allows Companion to write to older version of the firmware - - - Check Firmware compatibility - - - - - - - - 0 - 0 - - - - <html><head/><body><p>Saves a dated copy of your eeprom to the backup folder you specified in the Companion settings before writing the current model to the radio.</p></body></html> - - - Backup before Write - - - - - - - <html><head/><body><p>Modify calibration parameters using settings from current profile</p></body></html> - - - Patch calibration setting from profile - - - - - - - <html><head/><body><p>Modify HW parameters using settings from current profile</p></body></html> - - - Patch HW settings from profile - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 90 - 0 - - - - Cancel - - - - - - - false - - - - 90 - 0 - - - - Write to TX - - - - - - - - - burnButton - eepromFilename - eepromLoad - cancelButton - - - - - - diff --git a/companion/src/flashfirmwaredialog.cpp b/companion/src/flashfirmwaredialog.cpp index a6acffe9c..b06cadb1c 100644 --- a/companion/src/flashfirmwaredialog.cpp +++ b/companion/src/flashfirmwaredialog.cpp @@ -267,7 +267,7 @@ void FlashFirmwareDialog::shrink() void FlashFirmwareDialog::startFlash(const QString &filename) { - bool backup = g.backupOnFlash(); +// bool backup = g.backupOnFlash(); close(); @@ -297,34 +297,35 @@ void FlashFirmwareDialog::startFlash(const QString &filename) if (checkPassed) { // backup if requested - bool result = true; - QString backupFilename; - QString backupPath; - if (backup) { - backupPath = g.profile[g.id()].pBackupDir(); - if (backupPath.isEmpty()) { - backupPath=g.backupDir(); - } - backupFilename = backupPath + "/backup-" + QDateTime().currentDateTime().toString("yyyy-MM-dd-HHmmss") + ".bin"; - result = readSettings(backupFilename, progressDialog.progress()); - sleep(2); - } +// bool result = true; +// QString backupFilename; +// QString backupPath; +// if (backup) { +// backupPath = g.profile[g.id()].pBackupDir(); +// if (backupPath.isEmpty()) { +// backupPath=g.backupDir(); +// } +// backupFilename = backupPath + "/backup-" + QDateTime().currentDateTime().toString("yyyy-MM-dd-HHmmss") + ".bin"; +// result = readSettings(backupFilename, progressDialog.progress()); +// sleep(2); +// } // flash - result = (result && writeFirmware(filename, progressDialog.progress())); + //result = (result && writeFirmware(filename, progressDialog.progress())); + 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 (!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)); - } - } +// 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 (!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")); } diff --git a/companion/src/mainwindow.cpp b/companion/src/mainwindow.cpp index 991f6fec2..dc00e5b39 100644 --- a/companion/src/mainwindow.cpp +++ b/companion/src/mainwindow.cpp @@ -29,7 +29,6 @@ #include "printdialog.h" #include "version.h" #include "customizesplashdialog.h" -#include "flasheepromdialog.h" #include "flashfirmwaredialog.h" #include "hexinterface.h" #include "warnings.h" @@ -125,7 +124,7 @@ MainWindow::MainWindow(): if (!str.isEmpty()) { int fileType = getStorageType(str); - if (fileType==STORAGE_TYPE_EEPE || fileType==STORAGE_TYPE_EEPM || fileType==STORAGE_TYPE_BIN || fileType==STORAGE_TYPE_ETX) { + if (fileType == STORAGE_TYPE_ETX) { MdiChild * child = createMdiChild(); if (child->loadFile(str)) { if (!(printing && model >= 0 && (getCurrentFirmware()->getCapability(Models) == 0 || modelgetCapability(Models)) && !printfilename.isEmpty())) { @@ -582,13 +581,7 @@ bool MainWindow::readSettingsFromRadio(const QString & filename) void MainWindow::writeBackup() { - if (IS_FAMILY_HORUS_OR_T16(getCurrentBoard())) { - QMessageBox::information(this, CPN_STR_APP_NAME, tr("This function is not yet implemented")); - return; - // TODO implementation - } - FlashEEpromDialog *cd = new FlashEEpromDialog(this); - cd->exec(); + QMessageBox::information(this, CPN_STR_APP_NAME, tr("This function is not yet implemented")); } void MainWindow::writeFlash(QString fileToFlash) diff --git a/companion/src/mdichild.cpp b/companion/src/mdichild.cpp index c7a8f1416..2fe03a3d1 100644 --- a/companion/src/mdichild.cpp +++ b/companion/src/mdichild.cpp @@ -25,7 +25,6 @@ #include "generaledit/generaledit.h" #include "burnconfigdialog.h" #include "printdialog.h" -#include "flasheepromdialog.h" #include "helpers.h" #include "appdata.h" #include "wizarddialog.h" @@ -1500,36 +1499,21 @@ void MdiChild::writeSettings(StatusDialog * status) // write to Tx return; } - Board::Type board = getCurrentBoard(); + QString radioPath = findMassstoragePath("RADIO", true); + qDebug() << "Searching for SD card, found" << radioPath; + if (radioPath.isEmpty()) { + qDebug() << "Radio SD card not found"; + QMessageBox::critical(this, CPN_STR_TTL_ERROR, tr("Unable to find radio SD card!")); + return; + } - if (Boards::getCapability(board, Board::HasSDCard)) { - QString radioPath = findMassstoragePath("RADIO", true); - qDebug() << "Searching for SD card, found" << radioPath; - if (radioPath.isEmpty()) { - 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)) { - status->hide(); - QMessageBox::information(this, CPN_STR_TTL_INFO, tr("Models and settings written to radio")); - } - else { - qDebug() << "MdiChild::writeEeprom(): saveFile error"; - status->hide(); - QMessageBox::critical(this, CPN_STR_TTL_ERROR, tr("Error writing models and settings to radio!")); - } + if (saveFile(radioPath, false)) { + status->hide(); + QMessageBox::information(this, CPN_STR_TTL_INFO, tr("Models and settings written to radio")); } else { - QString tempFile = generateProcessUniqueTempFileName("temp.bin"); - saveFile(tempFile, false); - if (!QFileInfo(tempFile).exists()) { - QMessageBox::critical(this, CPN_STR_TTL_ERROR, tr("Cannot write temporary file!")); - return; - } - FlashEEpromDialog * cd = new FlashEEpromDialog(this, tempFile); - cd->exec(); + status->hide(); + QMessageBox::critical(this, CPN_STR_TTL_ERROR, tr("Error writing models and settings to radio!")); } } diff --git a/companion/src/modelprinter.cpp b/companion/src/modelprinter.cpp index f17d09d49..64b11dbc2 100644 --- a/companion/src/modelprinter.cpp +++ b/companion/src/modelprinter.cpp @@ -154,11 +154,6 @@ QString ModelPrinter::printBoolean(const bool val, const int typ) } } -QString ModelPrinter::printEEpromSize() -{ - return QString("%1 ").arg(getCurrentEEpromInterface()->getSize(model)) + tr("bytes"); -} - QString ModelPrinter::printChannelName(int idx) { QString str = RawSource(SOURCE_TYPE_CH, idx + 1).toString(&model, &generalSettings); diff --git a/companion/src/modelprinter.h b/companion/src/modelprinter.h index e0617de8b..7f9143a82 100644 --- a/companion/src/modelprinter.h +++ b/companion/src/modelprinter.h @@ -41,7 +41,6 @@ class ModelPrinter: public QObject virtual ~ModelPrinter(); QString printBoolean(const bool val, const int typ); - QString printEEpromSize(); QString printTrimIncrementMode(); QString printThrottle(); QString printFlightModeSwitch(const RawSwitch & swtch); diff --git a/companion/src/radiointerface.cpp b/companion/src/radiointerface.cpp index 4e577bad0..37265cf62 100644 --- a/companion/src/radiointerface.cpp +++ b/companion/src/radiointerface.cpp @@ -81,11 +81,7 @@ QStringList getSambaArgs(const QString & tcl) QStringList getReadEEpromCmd(const QString & filename) { QStringList result; - EEPROMInterface *eepromInterface = getCurrentEEpromInterface(); - if (IS_STM32(eepromInterface->getBoard())) { - // impossible - } - else { + if (!IS_STM32(getCurrentBoard())) { result = getSambaArgs(QString("SERIALFLASH::Init 0\n") + "receive_file {SerialFlash AT25} \"" + filename + "\" 0x0 0x80000 0\n"); } return result; diff --git a/companion/src/simulation/simulatorstartupdialog.cpp b/companion/src/simulation/simulatorstartupdialog.cpp index daa3c8a20..feec393cc 100644 --- a/companion/src/simulation/simulatorstartupdialog.cpp +++ b/companion/src/simulation/simulatorstartupdialog.cpp @@ -304,7 +304,7 @@ void SimulatorStartupDialog::onRadioTypeChanged(int index) void SimulatorStartupDialog::onDataFileSelect(bool) { - QString filter = EEPROM_FILES_FILTER % tr("All files (*.*)"); + QString filter = SIMU_FILES_FILTER; QString file = QFileDialog::getSaveFileName(this, tr("Select a data file"), ui->dataFile->text(), filter, NULL, QFileDialog::DontConfirmOverwrite); if (!file.isEmpty()) { diff --git a/companion/src/simulation/simulatorwidget.cpp b/companion/src/simulation/simulatorwidget.cpp index dd605a7dc..eab467626 100644 --- a/companion/src/simulation/simulatorwidget.cpp +++ b/companion/src/simulation/simulatorwidget.cpp @@ -316,8 +316,10 @@ bool SimulatorWidget::setStartupData(const QByteArray & dataSource, bool fromFil } // Assume a byte array of radio data was passed, load it. else if (!dataSource.isEmpty()) { - ret = firmware->getEEpromInterface()->load(simuData, (uint8_t *)dataSource.constData(), Boards::getEEpromSize(m_board)); - startupData = dataSource; // save the data for start() + //ret = firmware->getEEpromInterface()->load(simuData, (uint8_t *)dataSource.constData(), Boards::getEEpromSize(m_board)); + //startupData = dataSource; // save the data for start() + error = tr("Unable to handle byte array."); + ret = 0; } // we're :-( else { @@ -352,11 +354,11 @@ bool SimulatorWidget::setRadioData(RadioData * radioData) if (ret) { if (!hasSdCard) { startupData.fill(0, Boards::getEEpromSize(m_board)); - if (firmware->getEEpromInterface()->save( - (uint8_t *)startupData.data(), *radioData, 0, - firmware->getCapability(SimulatorVariant)) <= 0) { + //if (firmware->getEEpromInterface()->save( + // (uint8_t *)startupData.data(), *radioData, 0, + // firmware->getCapability(SimulatorVariant)) <= 0) { ret = false; - } + //} } else { ret = saveRadioData(radioData, radioDataPath); } @@ -452,13 +454,14 @@ bool SimulatorWidget::saveTempData() fh.close(); } - if (!firmware->getEEpromInterface()->load(radioData, (uint8_t *)startupData.constData(), Boards::getEEpromSize(m_board))) { - error = tr("Error saving data: could not get data from simulator interface."); - } - else { - radioData.fixModelFilenames(); - ret = true; - } + qDebug() << "ERROR: WE DO NOT WANT TO BE HERE"; +// if (!firmware->getEEpromInterface()->load(radioData, (uint8_t *)startupData.constData(), Boards::getEEpromSize(m_board))) { +// error = tr("Error saving data: could not get data from simulator interface."); +// } +// else { +// radioData.fixModelFilenames(); +// ret = true; +// } } } else { diff --git a/companion/src/storage/CMakeLists.txt b/companion/src/storage/CMakeLists.txt index 3080b850e..d5984f563 100644 --- a/companion/src/storage/CMakeLists.txt +++ b/companion/src/storage/CMakeLists.txt @@ -4,17 +4,14 @@ project(storage) set(${PROJECT_NAME}_NAMES hexinterface mountlist - rlefile appdata firmwareinterface storage - bineeprom eepe hexeeprom labeled sdcard etx - otx yaml crc minizinterface diff --git a/companion/src/storage/labeled.cpp b/companion/src/storage/labeled.cpp index 39ebc5674..235922dc9 100644 --- a/companion/src/storage/labeled.cpp +++ b/companion/src/storage/labeled.cpp @@ -25,159 +25,20 @@ #include -bool LabelsStorageFormat::load(RadioData & radioData) -{ - StorageType st = getStorageType(filename); - if (st == STORAGE_TYPE_UNKNOWN) { - st = probeFormat(); - } - if (st == STORAGE_TYPE_ETX || st == STORAGE_TYPE_YML - || st == STORAGE_TYPE_UNKNOWN) { - return loadYaml(radioData); - } else { - return loadBin(radioData); - } -} - -bool LabelsStorageFormat::write(const RadioData & radioData) -{ - StorageType st = getStorageType(filename); - if (st == STORAGE_TYPE_ETX || st == STORAGE_TYPE_YML || - st == STORAGE_TYPE_UNKNOWN) { - return writeYaml(radioData); - } - - return false; -} - StorageType LabelsStorageFormat::probeFormat() { if (QFile(filename + "/RADIO/radio.yml").exists()) // converted return getStorageType("radio.yml"); - else if (QFile(filename + "/RADIO/radio.bin").exists()) // unconverted - return getStorageType("radio.bin"); else return getStorageType(filename); } -bool LabelsStorageFormat::loadBin(RadioData & radioData) +bool LabelsStorageFormat::load(RadioData & radioData) { - QByteArray radioSettingsBuffer; - if (!loadFile(radioSettingsBuffer, "RADIO/radio.bin")) { - setError(tr("Cannot extract RADIO/radio.bin")); - return false; - } + StorageType st = getStorageType(filename); + if (st == STORAGE_TYPE_UNKNOWN) + st = probeFormat(); - OpenTxEepromInterface * loadInterface = loadRadioSettingsFromByteArray(radioData.generalSettings, radioSettingsBuffer); - if (!loadInterface) { - return false; - } - - - board = loadInterface->getBoard(); - - radioData.generalSettings.convertLegacyConfiguration(board); - - QByteArray modelsListBuffer; - if (!loadFile(modelsListBuffer, "RADIO/models.txt")) { - setError(tr("Cannot extract RADIO/models.txt")); - return false; - } - - QList lines = modelsListBuffer.split('\n'); - int modelIndex = 0; - foreach (const QByteArray & lineArray, lines) { - QString line = QString(lineArray).trimmed(); - if (line.isEmpty()) continue; - // qDebug() << "parsing line" << line; - - if (line.startsWith('[') && line.endsWith(']')) { - continue; - } - - // determine if we have a model number - QStringList parts = line.split(QRegExp("\\s+"), Qt::SkipEmptyParts); - if (parts.size() == 2) { - // parse model number - int modelNumber = parts[0].toInt(); - if (modelNumber > 0 && modelNumber > modelIndex && modelNumber < getCurrentFirmware()->getCapability(Models)) { - modelIndex = modelNumber; - qDebug() << "advanced model number to" << modelIndex; - } - else { - if (modelNumber != modelIndex) qDebug() << "Invalid model number" << parts[0]; - } - parts.removeFirst(); - } - if (parts.size() == 1) { - // parse model file name and load - QString fileName = parts[0]; - qDebug() << "Loading model from file" << fileName << "into slot" << modelIndex; - QByteArray modelBuffer; - if (!loadFile(modelBuffer, QString("MODELS/%1").arg(fileName))) { - setError(tr("Cannot extract %1").arg(fileName)); - return false; - } - if ((int)radioData.models.size() <= modelIndex) { - radioData.models.resize(modelIndex + 1); - } - if (!loadModelFromByteArray(radioData.models[modelIndex], modelBuffer)) { - setError(tr("Error loading models")); - return false; - } - strncpy(radioData.models[modelIndex].filename, qPrintable(fileName), sizeof(radioData.models[modelIndex].filename)); - if (IS_FAMILY_HORUS_OR_T16(board) && !strcmp(radioData.generalSettings.currModelFilename, qPrintable(fileName))) { - radioData.generalSettings.currModelIndex = modelIndex; - qDebug() << "currModelIndex =" << modelIndex; - } - radioData.models[modelIndex].used = true; - modelIndex++; - continue; - } - - // invalid line - // TODO add to parsing report - qDebug() << "Invalid line" <getCapability(HasModelLabels)) { - RadioData::LabelData ld = { tr("Favorites"), false }; - radioData.labels.append(ld); - } - return true; -} - -bool LabelsStorageFormat::writeBin(const RadioData & radioData) -{ - QByteArray radioSettingsData; // radio.bin - size_t numModels = radioData.models.size(); - size_t numCategories = radioData.labels.size(); - std::vector> sortedModels(numCategories); - - writeRadioSettingsToByteArray(radioData.generalSettings, radioSettingsData); - if (!writeFile(radioSettingsData, "RADIO/radio.bin")) { - return false; - } - - for (size_t m=0; m filelist; - if (!getFileList(filelist)) { + if (!getFileList(filelist)) return false; - } const std::regex yml_regex("MODELS/(model([0-9]+)\\.yml)"); + for(const auto& f : filelist) { std::smatch match; if (std::regex_match(f, match, yml_regex)) { @@ -302,10 +163,8 @@ bool LabelsStorageFormat::loadYaml(RadioData & radioData) model.modelIndex = modelIdx; strncpy(model.filename, mc.filename.c_str(), sizeof(model.filename)-1); - if (hasLabels && !strncmp(radioData.generalSettings.currModelFilename, - model.filename, sizeof(model.filename))) { + if (hasLabels && !strncmp(radioData.generalSettings.currModelFilename, model.filename, sizeof(model.filename))) radioData.generalSettings.currModelIndex = modelIdx; - } model.used = true; modelIdx++; @@ -325,16 +184,14 @@ bool LabelsStorageFormat::loadYaml(RadioData & radioData) return true; } -bool LabelsStorageFormat::writeYaml(const RadioData & radioData) +bool LabelsStorageFormat::write(const RadioData & radioData) { QByteArray radioSettingsBuffer; - if (!writeRadioSettingsToYaml(radioData.generalSettings, radioSettingsBuffer)) { + if (!writeRadioSettingsToYaml(radioData.generalSettings, radioSettingsBuffer)) return false; - } - if (!writeFile(radioSettingsBuffer, "RADIO/radio.yml")) { + if (!writeFile(radioSettingsBuffer, "RADIO/radio.yml")) return false; - } bool hasLabels = getCurrentFirmware()->getCapability(HasModelLabels); @@ -347,7 +204,7 @@ bool LabelsStorageFormat::writeYaml(const RadioData & radioData) // Delete all old modelxx.yml from radio MODELS folder before writing new modelxx.yml files const std::regex yml_regex("MODELS/(model([0-9s]+)\\.yml)"); - for(const auto& f : filelist) { + for (const auto& f : filelist) { std::smatch match; if (std::regex_match(f, match, yml_regex)) { if (match.size() == 3) { @@ -368,28 +225,22 @@ bool LabelsStorageFormat::writeYaml(const RadioData & radioData) QString modelFilename; if (hasLabels) { std::string ymlFilename = patchFilenameToYaml(model.filename); - modelFilename = - QString("MODELS/%1").arg(QString::fromStdString(ymlFilename)); - modelFiles.push_back( - {ymlFilename, std::string(model.name)}); + modelFilename = QString("MODELS/%1").arg(QString::fromStdString(ymlFilename)); + modelFiles.push_back({ymlFilename, std::string(model.name)}); } else { - modelFilename = QString("MODELS/model%1.yml") - .arg(model.modelIndex, 2, 10, QLatin1Char('0')); + modelFilename = QString("MODELS/model%1.yml").arg(model.modelIndex, 2, 10, QLatin1Char('0')); } QByteArray modelData; writeModelToYaml(model, modelData); - if (!writeFile(modelData, modelFilename)) { + if (!writeFile(modelData, modelFilename)) return false; - } } if (hasLabels) { QByteArray labelsListBuffer; - if (!writeLabelsListToYaml(radioData, labelsListBuffer) - || !writeFile(labelsListBuffer, "MODELS/labels.yml")) { + if (!writeLabelsListToYaml(radioData, labelsListBuffer) || !writeFile(labelsListBuffer, "MODELS/labels.yml")) return false; - } } return true; diff --git a/companion/src/storage/labeled.h b/companion/src/storage/labeled.h index 2e6a9e5ff..0f9a0c8a7 100644 --- a/companion/src/storage/labeled.h +++ b/companion/src/storage/labeled.h @@ -47,10 +47,5 @@ class LabelsStorageFormat : public StorageFormat virtual bool getFileList(std::list& filelist) = 0; virtual bool deleteFile(const QString & fileName) = 0; - virtual bool loadBin(RadioData & radioData); - virtual bool writeBin(const RadioData & radioData); - virtual bool loadYaml(RadioData & radioData); - virtual bool writeYaml(const RadioData & radioData); - StorageType probeFormat(); }; diff --git a/companion/src/storage/otx.cpp b/companion/src/storage/otx.cpp deleted file mode 100644 index db07536bb..000000000 --- a/companion/src/storage/otx.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) EdgeTX - * - * Based on code named - * opentx - https://github.com/opentx/opentx - * th9x - http://code.google.com/p/th9x - * er9x - http://code.google.com/p/er9x - * gruvin9x - http://code.google.com/p/gruvin9x - * - * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "otx.h" -#include - -#define MZ_ALLOCATION_SIZE (32*1024) - -bool OtxFormat::load(RadioData & radioData) -{ - QFile file(filename); - - if (!file.open(QFile::ReadOnly)) { - setError(tr("Error opening file %1:\n%2.").arg(filename).arg(file.errorString())); - return false; - } - - QByteArray archiveContents = file.readAll(); - - qDebug() << "File" << filename << "read, size:" << archiveContents.size(); - - // open zip file - memset(&zip_archive, 0, sizeof(zip_archive)); - if (!mz_zip_reader_init_mem(&zip_archive, archiveContents.data(), archiveContents.size(), 0)) { - qDebug() << tr("Error opening OpenTX archive %1").arg(filename); - return false; - } - - bool result = LabelsStorageFormat::load(radioData); - mz_zip_reader_end(&zip_archive); - return result; -} - -bool OtxFormat::write(const RadioData & radioData) -{ - qDebug() << "Saving to archive" << filename; - - memset(&zip_archive, 0, sizeof(zip_archive)); - if (!mz_zip_writer_init_heap(&zip_archive, 0, MZ_ALLOCATION_SIZE)) { - setError(tr("Error initializing OpenTX archive writer")); - return false; - } - - bool result = LabelsStorageFormat::write(radioData); - if (result) { - // finalize archive and get contents - char * archiveContents; - size_t archiveSize; - if (mz_zip_writer_finalize_heap_archive(&zip_archive, (void **)&archiveContents, &archiveSize)) { - qDebug() << "Archive size" << archiveSize; - // write contents to file - QFile file(filename); - if (file.open(QIODevice::WriteOnly)) { - qint64 len = file.write(archiveContents, archiveSize); - if (len != (qint64)archiveSize) { - setError(tr("Error writing file %1:\n%2.").arg(filename).arg(file.errorString())); - result = false; - } - } - else { - setError(tr("Error creating OpenTX file %1:\n%2.").arg(filename).arg(file.errorString())); - result = false; - } - } - else { - setError(tr("Error creating OpenTX archive")); - result = false; - } - } - - mz_zip_writer_end(&zip_archive); - return result; -} - -bool OtxFormat::loadFile(QByteArray & filedata, const QString & filename) -{ - size_t size; - void * data = mz_zip_reader_extract_file_to_heap(&zip_archive, qPrintable(filename), &size, 0); - if (!data) { - return false; - } - - qDebug() << QString("Extracted file %1, size=%2").arg(filename).arg(size); - filedata.clear(); - filedata.append((char *)data, size); - mz_free(data); - return true; -} - -bool OtxFormat::writeFile(const QByteArray & filedata, const QString & filename) -{ - if (!mz_zip_writer_add_mem(&zip_archive, filename.toStdString().c_str(), filedata.data(), filedata.size(), MZ_DEFAULT_LEVEL)) { - setError(tr("Error adding %1 to OpenTX archive").arg(filename)); - return false; - } - - return true; -} diff --git a/companion/src/storage/otx.h b/companion/src/storage/otx.h deleted file mode 100644 index 1f902814e..000000000 --- a/companion/src/storage/otx.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) EdgeTX - * - * Based on code named - * opentx - https://github.com/opentx/opentx - * th9x - http://code.google.com/p/th9x - * er9x - http://code.google.com/p/er9x - * gruvin9x - http://code.google.com/p/gruvin9x - * - * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#pragma once - -#include "labeled.h" - -#include - -class OtxFormat : public LabelsStorageFormat -{ - Q_DECLARE_TR_FUNCTIONS(OtxFormat) - - public: - OtxFormat(const QString & filename): - LabelsStorageFormat(filename) - { - } - - virtual QString name() { return "otx"; } - virtual bool load(RadioData & radioData); - virtual bool write(const RadioData & radioData); - - protected: - virtual bool loadFile(QByteArray & fileData, const QString & fileName); - virtual bool writeFile(const QByteArray & fileData, const QString & fileName); - virtual bool getFileList(std::list& filelist) { return false; } - virtual bool deleteFile(const QString & fileName) { return false; } - - mz_zip_archive zip_archive; -}; diff --git a/companion/src/storage/sdcard.h b/companion/src/storage/sdcard.h index a9839bac6..6065ef7aa 100644 --- a/companion/src/storage/sdcard.h +++ b/companion/src/storage/sdcard.h @@ -19,8 +19,7 @@ * GNU General Public License for more details. */ -#ifndef _SDCARD_H2_ -#define _SDCARD_H2_ +#pragma once #include "labeled.h" @@ -56,5 +55,3 @@ class SdcardStorageFactory : public DefaultStorageFactory virtual bool probe(const QString & name); }; - -#endif // _SDCARD_H2_ diff --git a/companion/src/storage/storage.cpp b/companion/src/storage/storage.cpp index e872094e6..ab3d307d4 100644 --- a/companion/src/storage/storage.cpp +++ b/companion/src/storage/storage.cpp @@ -19,32 +19,17 @@ * GNU General Public License for more details. */ -#include "bineeprom.h" -#include "eepe.h" -#include "otx.h" #include "etx.h" -#include "sdcard.h" #include "yaml.h" -#include "firmwareinterface.h" -#include "eeprominterface.h" +#include "sdcard.h" + #include StorageType getStorageType(const QString & filename) { QString suffix = QFileInfo(filename).suffix().toUpper(); - if (suffix == "HEX") - return STORAGE_TYPE_HEX; - else if (suffix == "BIN") - return STORAGE_TYPE_BIN; - else if (suffix == "EEPM") - return STORAGE_TYPE_EEPM; - else if (suffix == "EEPE") - return STORAGE_TYPE_EEPE; - else if (suffix == "XML") - return STORAGE_TYPE_XML; - else if (suffix == "OTX") - return STORAGE_TYPE_OTX; - else if (suffix == "ETX") + + if (suffix == "ETX") return STORAGE_TYPE_ETX; else if (suffix == "YML") return STORAGE_TYPE_YML; @@ -64,10 +49,6 @@ void registerStorageFactory(StorageFactory * factory) void registerStorageFactories() { - registerStorageFactory(new DefaultStorageFactory("bin")); - registerStorageFactory(new DefaultStorageFactory("eepe")); - registerStorageFactory(new DefaultStorageFactory("hex")); - registerStorageFactory(new DefaultStorageFactory("otx")); registerStorageFactory(new DefaultStorageFactory("etx")); registerStorageFactory(new DefaultStorageFactory("yml")); registerStorageFactory(new SdcardStorageFactory()); @@ -88,7 +69,7 @@ bool Storage::load(RadioData & radioData) } bool ret = false; - foreach(StorageFactory * factory, registeredStorageFactories) { + foreach (StorageFactory * factory, registeredStorageFactories) { if (factory->probe(filename)) { StorageFormat * format = factory->instance(filename); if (format->load(radioData)) { @@ -111,7 +92,7 @@ bool Storage::load(RadioData & radioData) bool Storage::write(const RadioData & radioData) { bool ret = false; - foreach(StorageFactory * factory, registeredStorageFactories) { + foreach (StorageFactory * factory, registeredStorageFactories) { if (factory->probe(filename)) { StorageFormat * format = factory->instance(filename); ret = format->write(radioData); @@ -125,7 +106,7 @@ bool Storage::write(const RadioData & radioData) bool Storage::writeModel(const RadioData & radioData, const int modelIndex) { bool ret = false; - foreach(StorageFactory * factory, registeredStorageFactories) { + foreach (StorageFactory * factory, registeredStorageFactories) { if (factory->probe(filename)) { StorageFormat * format = factory->instance(filename); ret = format->writeModel(radioData, modelIndex); @@ -135,76 +116,3 @@ bool Storage::writeModel(const RadioData & radioData, const int modelIndex) } return ret; } - -bool convertEEprom(const QString & sourceEEprom, const QString & destinationEEprom, const QString & firmwareFilename) -{ - FirmwareInterface firmware(firmwareFilename); - if (!firmware.isValid()) - return false; - - uint8_t version = firmware.getEEpromVersion(); - unsigned int variant = firmware.getEEpromVariant(); - - QSharedPointer radioData = QSharedPointer(new RadioData()); - Storage storage(sourceEEprom); - if (!storage.load(*radioData)) - return false; - - QByteArray eeprom(Boards::getEEpromSize(Board::BOARD_UNKNOWN), 0); - int size = getCurrentEEpromInterface()->save((uint8_t *)eeprom.data(), *radioData, version, variant); - if (size == 0) { - return false; - } - - QFile destinationFile(destinationEEprom); - if (!destinationFile.open(QIODevice::WriteOnly)) { - return false; - } - - int result = destinationFile.write(eeprom.constData(), size); - destinationFile.close(); - return (result == size); -} - -#if 0 -unsigned long LoadBackup(RadioData & radioData, uint8_t * eeprom, int size, int index) -{ - std::bitset errors; - - foreach(EEPROMInterface *eepromInterface, eepromInterfaces) { - std::bitset result((unsigned long long)eepromInterface->loadBackup(radioData, eeprom, size, index)); - if (result.test(ALL_OK)) { - return result.to_ulong(); - } - else { - errors |= result; - } - } - - if (errors.none()) { - errors.set(UNKNOWN_ERROR); - } - return errors.to_ulong(); -} - - -unsigned long LoadEepromXml(RadioData & radioData, QDomDocument & doc) -{ - std::bitset errors; - - foreach(EEPROMInterface *eepromInterface, eepromInterfaces) { - std::bitset result((unsigned long long)eepromInterface->loadxml(radioData, doc)); - if (result.test(ALL_OK)) { - return result.to_ulong(); - } - else { - errors |= result; - } - } - - if (errors.none()) { - errors.set(UNKNOWN_ERROR); - } - return errors.to_ulong(); -} -#endif diff --git a/companion/src/storage/storage.h b/companion/src/storage/storage.h index cf8ccc520..8999ab7bc 100644 --- a/companion/src/storage/storage.h +++ b/companion/src/storage/storage.h @@ -19,8 +19,7 @@ * GNU General Public License for more details. */ -#ifndef _STORAGE_H_ -#define _STORAGE_H_ +#pragma once #include "radiodata.h" @@ -31,13 +30,8 @@ enum StorageType { STORAGE_TYPE_UNKNOWN, - STORAGE_TYPE_BIN, - STORAGE_TYPE_HEX, - STORAGE_TYPE_EEPE, - STORAGE_TYPE_EEPM, - STORAGE_TYPE_XML, + STORAGE_TYPE_HEX, // needed for FirmwareInterface STORAGE_TYPE_SDCARD, - STORAGE_TYPE_OTX, STORAGE_TYPE_ETX, STORAGE_TYPE_YML }; @@ -164,13 +158,3 @@ class Storage : public StorageFormat void registerStorageFactories(); void unregisterStorageFactories(); - -#if 0 -unsigned long LoadBackup(RadioData &radioData, uint8_t *eeprom, int esize, int index); -unsigned long LoadEeprom(RadioData &radioData, const uint8_t *eeprom, int size); -unsigned long LoadEepromXml(RadioData &radioData, QDomDocument &doc); -#endif - -bool convertEEprom(const QString & sourceEEprom, const QString & destinationEEprom, const QString & firmware); - -#endif // _STORAGE_H_