diff --git a/companion/src/eeprominterface.cpp b/companion/src/eeprominterface.cpp index 8d7383c04..4acbf4cf6 100644 --- a/companion/src/eeprominterface.cpp +++ b/companion/src/eeprominterface.cpp @@ -1634,8 +1634,8 @@ void registerEEpromInterfaces() eepromInterfaces.push_back(new OpenTxEepromInterface(BOARD_TARANIS_X9D)); eepromInterfaces.push_back(new OpenTxEepromInterface(BOARD_TARANIS_X9DP)); eepromInterfaces.push_back(new OpenTxEepromInterface(BOARD_TARANIS_X9E)); - eepromInterfaces.push_back(new Ersky9xInterface()); - eepromInterfaces.push_back(new Er9xInterface()); + // eepromInterfaces.push_back(new Ersky9xInterface()); + // eepromInterfaces.push_back(new Er9xInterface()); } void unregisterEEpromInterfaces() diff --git a/companion/src/eeprominterface.h b/companion/src/eeprominterface.h index ecd2f488e..136c23603 100644 --- a/companion/src/eeprominterface.h +++ b/companion/src/eeprominterface.h @@ -1240,6 +1240,7 @@ class GeneralSettings { unsigned int sticksGain; unsigned int rotarySteps; unsigned int countryCode; + bool jitterFilter; unsigned int imperial; bool crosstrim; char ttsLanguage[2+1]; @@ -1411,15 +1412,15 @@ class EEPROMInterface inline BoardEnum getBoard() { return board; } - virtual unsigned long load(RadioData &radioData, const uint8_t *eeprom, int size) = 0; + virtual unsigned long load(RadioData &radioData, const uint8_t * eeprom, int size) = 0; - virtual unsigned long loadBackup(RadioData &radioData, uint8_t *eeprom, int esize, int index) = 0; + virtual unsigned long loadBackup(RadioData & radioData, const uint8_t * eeprom, int esize, int index) = 0; virtual bool loadRadioSettings(GeneralSettings & model, const QByteArray & data) { return false; } virtual bool loadModel(ModelData & model, const QByteArray & data) { return false; } - virtual unsigned long loadxml(RadioData &radioData, QDomDocument &doc) = 0; + virtual unsigned long loadxml(RadioData & radioData, QDomDocument &doc) = 0; virtual int save(uint8_t * eeprom, RadioData & radioData, uint8_t version=0, uint32_t variant=0) = 0; @@ -1430,7 +1431,11 @@ class EEPROMInterface virtual const int getEEpromSize() = 0; virtual const int getMaxModels() = 0; - + + virtual int loadFile(RadioData & radioData, const QString & filename) = 0; + + virtual int saveFile(const RadioData & radioData, const QString & filename) = 0; + protected: BoardEnum board; diff --git a/companion/src/firmwares/opentx/opentxeeprom.cpp b/companion/src/firmwares/opentx/opentxeeprom.cpp index 3b4c9bd4c..55f43f3e6 100644 --- a/companion/src/firmwares/opentx/opentxeeprom.cpp +++ b/companion/src/firmwares/opentx/opentxeeprom.cpp @@ -33,8 +33,9 @@ #define MAX_VIEWS(board) (HAS_LARGE_LCD(board) ? 2 : 256) #define MAX_POTS(board, version) (board == BOARD_X7D ? 2 : (IS_TARANIS(board) ? (IS_TARANIS_X9E(board) ? 4 : (version >= 216 ? 3 : 2)) : 3)) #define MAX_SLIDERS(board) (IS_HORUS(board) ? 4 : (board == BOARD_X7D ? 0 : (IS_TARANIS(board) ? (IS_TARANIS_X9E(board) ? 4 : 2) : 0))) -#define MAX_SWITCHES(board, version) (board == BOARD_X7D ? 6 : (IS_TARANIS(board) ? (IS_TARANIS_X9E(board) ? 18 : 8) : 7)) -#define MAX_SWITCHES_POSITION(board, version) (board == BOARD_X7D ? 6*3 : (IS_TARANIS_X9E(board) ? 18*3 : (IS_TARANIS(board) ? 8*3 : 9))) +#define MAX_MOUSE_ANALOGS(board) (IS_HORUS(board) ? 2 : 0) +#define MAX_SWITCHES(board, version) (IS_HORUS(board) ? 8 : (board == BOARD_X7D ? 6 : (IS_TARANIS(board) ? (IS_TARANIS_X9E(board) ? 18 : 8) : 7))) +#define MAX_SWITCHES_POSITION(board, version) (IS_HORUS(board) ? 24 : (board == BOARD_X7D ? 6*3 : (IS_TARANIS_X9E(board) ? 18*3 : (IS_TARANIS(board) ? 8*3 : 9)))) #define MAX_ROTARY_ENCODERS(board) (IS_2560(board) ? 2 : (IS_SKY9X(board) ? 1 : 0)) #define MAX_FLIGHT_MODES(board, version) (IS_ARM(board) ? 9 : (IS_DBLRAM(board, version) ? 6 : 5)) #define MAX_TIMERS(board, version) ((IS_ARM(board) && version >= 217) ? 3 : 2) @@ -3451,7 +3452,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, BoardEnum bo generalData(generalData), board(board), version(version), - inputsCount(CPN_MAX_STICKS+MAX_POTS(board, version)+MAX_SLIDERS(board)) + inputsCount(CPN_MAX_STICKS+MAX_POTS(board, version)+MAX_SLIDERS(board)+MAX_MOUSE_ANALOGS(board)) { eepromImportDebug() << QString("OpenTxGeneralData::OpenTxGeneralData(board: %1, version:%2, variant:%3)").arg(board).arg(version).arg(variant); @@ -3485,8 +3486,10 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, BoardEnum bo } internalField.Append(new UnsignedField<16>(chkSum)); - internalField.Append(new UnsignedField<8>(generalData.currModel)); - internalField.Append(new UnsignedField<8>(generalData.contrast)); + if (!IS_HORUS(board)) { + internalField.Append(new UnsignedField<8>(generalData.currModel)); + internalField.Append(new UnsignedField<8>(generalData.contrast)); + } internalField.Append(new UnsignedField<8>(generalData.vBatWarn)); internalField.Append(new SignedField<8>(generalData.txVoltageCalibration)); internalField.Append(new SignedField<8>(generalData.backlightMode)); @@ -3550,11 +3553,11 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, BoardEnum bo internalField.Append(new SignedField<8>(generalData.PPM_Multiplier)); internalField.Append(new SignedField<8>(generalData.hapticLength)); - if (version < 216 || (version < 218 && !IS_9X(board)) || (!IS_9X(board) && !IS_TARANIS(board))) { + if (version < 216 || (version < 218 && !IS_9X(board)) || (!IS_9X(board) && !IS_TARANIS(board) && !IS_HORUS(board))) { internalField.Append(new UnsignedField<8>(generalData.reNavigation)); } - if (version >= 216 && !IS_TARANIS(board)) { + if (version >= 216 && !IS_TARANIS(board) && !IS_HORUS(board)) { internalField.Append(new UnsignedField<8>(generalData.stickReverse)); } @@ -3591,21 +3594,28 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, BoardEnum bo if (version >= 214) { if (version < 218) internalField.Append(new UnsignedField<8>(generalData.rotarySteps)); // TODO internalField.Append(new UnsignedField<8>(generalData.countryCode)); - internalField.Append(new UnsignedField<8>(generalData.imperial)); + internalField.Append(new UnsignedField<1>(generalData.imperial)); + if (version >= 218) { + internalField.Append(new BoolField<1>(generalData.jitterFilter)); + internalField.Append(new SpareBitsField<6>()); + } + else { + internalField.Append(new SpareBitsField<7>()); + } } if (version >= 215) { internalField.Append(new CharField<2>(generalData.ttsLanguage)); - if (version < 218) { - internalField.Append(new SignedField<8>(generalData.beepVolume)); - internalField.Append(new SignedField<8>(generalData.wavVolume)); - internalField.Append(new SignedField<8>(generalData.varioVolume)); - } - else { + if (version >= 218) { internalField.Append(new SignedField<4>(generalData.beepVolume)); internalField.Append(new SignedField<4>(generalData.wavVolume)); internalField.Append(new SignedField<4>(generalData.varioVolume)); internalField.Append(new SignedField<4>(generalData.backgroundVolume)); } + else { + internalField.Append(new SignedField<8>(generalData.beepVolume)); + internalField.Append(new SignedField<8>(generalData.wavVolume)); + internalField.Append(new SignedField<8>(generalData.varioVolume)); + } if (version >= 216) { internalField.Append(new SignedField<8>(generalData.varioPitch)); internalField.Append(new SignedField<8>(generalData.varioRange)); @@ -3618,8 +3628,14 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, BoardEnum bo internalField.Append(new ArmCustomFunctionField(generalData.customFn[i], board, version, variant)); } } - if (IS_TARANIS(board) && version >= 216) { - if (version >= 217) { + if (IS_STM32(board) && version >= 216) { + if (version >= 218) { + internalField.Append(new UnsignedField<4>(generalData.hw_uartMode)); + for (uint8_t i=0; i<4; i++) { + internalField.Append(new UnsignedField<1>(generalData.sliderConfig[i])); + } + } + else if (version >= 217) { internalField.Append(new UnsignedField<6>(generalData.hw_uartMode)); if (IS_TARANIS_X9E(board)) { internalField.Append(new UnsignedField<1>(generalData.sliderConfig[2])); @@ -3632,13 +3648,17 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, BoardEnum bo else { internalField.Append(new UnsignedField<8>(generalData.hw_uartMode)); } + if (IS_HORUS(board)) { + internalField.Append(new SpareBitsField<32>()); // switchConfig + } for (int i=0; i<4; i++) { if (i < MAX_POTS(board, version)) internalField.Append(new UnsignedField<2>(generalData.potConfig[i])); else internalField.Append(new SpareBitsField<2>()); } - internalField.Append(new UnsignedField<8>(generalData.backlightColor)); + if (!IS_HORUS(board)) + internalField.Append(new UnsignedField<8>(generalData.backlightColor)); } if (IS_TARANIS_X9E(board)) @@ -3652,7 +3672,23 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, BoardEnum bo } } - if (IS_TARANIS(board) && version >= 217) { + if (IS_HORUS(board)) { + for (int i=0; i(generalData.switchName[i])); + } + for (int i=0; i(generalData.stickName[i])); + } + for (int i=0; i(generalData.potName[i])); + } + for (int i=0; i(generalData.sliderName[i])); + } + static char * modelName = "model1.bin\0 "; + internalField.Append(new CharField<16>(modelName)); + } + else if (IS_TARANIS(board) && version >= 217) { for (int i=0; i(generalData.switchConfig[i])); } diff --git a/companion/src/firmwares/opentx/opentxinterface.cpp b/companion/src/firmwares/opentx/opentxinterface.cpp index 3fad124c9..69a411b68 100644 --- a/companion/src/firmwares/opentx/opentxinterface.cpp +++ b/companion/src/firmwares/opentx/opentxinterface.cpp @@ -24,6 +24,7 @@ #include "opentxeeprom.h" #include "rlefile.h" #include "appdata.h" +#include "storage_sdcard.h" #define OPENTX_FIRMWARE_DOWNLOADS "http://downloads-22.open-tx.org/firmware" #define OPENTX_NIGHT_FIRMWARE_DOWNLOADS "http://downloads-22.open-tx.org/nightly/firmware" @@ -36,9 +37,9 @@ /// convert model number 0..MAX_MODELS-1 int fileId #define FILE_MODEL(n) (1+n) -template +template inline -size_t SizeOfArray( T(&)[ N ] ) +size_t SizeOfArray(T(&)[N]) { return N; } @@ -126,100 +127,91 @@ const int OpenTxEepromInterface::getMaxModels() return 16; } -bool OpenTxEepromInterface::loadModel(uint8_t version, ModelData & model, uint8_t * data, int index, unsigned int variant) +bool OpenTxEepromInterface::loadRadioSettingsFromRLE(GeneralSettings & settings, RleFile * rleFile, uint8_t version) { - OpenTxModelData modelDataFactory(model, board, version, variant); - - if (!data) { - // load from EEPROM - QByteArray eepromData(sizeof(model), 0); // ModelData should be always bigger than the EEPROM struct - efile->openRd(FILE_MODEL(index)); - int numbytes = efile->readRlc2((uint8_t *)eepromData.data(), eepromData.size()); - if (numbytes) { - modelDataFactory.Import(eepromData); - // modelDataFactory.Dump(); - model.used = true; - } - else { - model.clear(); - } - } - else { - // load from SD Backup, size is stored in index - QByteArray backupData((char *)data, index); - QByteArray modelData; - if (IS_SKY9X(board)) - modelData = backupData; - else - importRlc(modelData, backupData); - if (modelData.size()) { - modelDataFactory.Import(modelData); - // modelDataFactory.Dump(); - model.used = true; - } - else { - model.clear(); - } - } - - return true; -} - -bool OpenTxEepromInterface::loadRadioSettings(GeneralSettings & settings, const QByteArray & data) -{ - // TODO check the 8 first bytes (fourcc + version + 'M' + size) - QByteArray raw = data.right(data.size() - 8); - OpenTxGeneralData importer(settings, board, 218, 0); // TODO board and 218 should be the version taken from the header - importer.Import(raw); - importer.Dump(); // Dumps the structure so that it's easy to check with firmware datastructs.h - return true; -} - -bool OpenTxEepromInterface::loadModel(ModelData & model, const QByteArray & data) -{ - // TODO check the 8 first bytes (fourcc + version + 'M' + size) - QByteArray raw = data.right(data.size() - 8); - OpenTxModelData modelData(model, board, 218, 0); // TODO board and 218 should be the version taken from the header - modelData.Import(raw); - modelData.Dump(); // Dumps the structure so that it's easy to check with firmware datastructs.h - model.used = true; - return true; -} - -bool OpenTxEepromInterface::loadRadioSettings(GeneralSettings & settings, uint8_t version) -{ - QByteArray eepromData(sizeof(settings), 0); // GeneralSettings should be always bigger than the EEPROM struct + QByteArray data(sizeof(settings), 0); // GeneralSettings should be always bigger than the EEPROM struct OpenTxGeneralData open9xSettings(settings, board, version); efile->openRd(FILE_GENERAL); - int sz = efile->readRlc2((uint8_t *)eepromData.data(), eepromData.size()); - if (sz) { - open9xSettings.Import(eepromData); + int size = rleFile->readRlc2((uint8_t *)data.data(), data.size()); + if (size) { + open9xSettings.Import(data); return checkVariant(settings.version, settings.variant); } + else { + std::cout << " error when loading general settings"; + return false; + } +} - std::cout << " error when loading general settings"; +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) == 0) { + model.used = true; + return true; + } + } + std::cout << " error when loading model"; + model.clear(); return false; } -template -bool OpenTxEepromInterface::saveRadioSettings(GeneralSettings & settings, BoardEnum board, uint8_t version, uint32_t variant) +template +bool OpenTxEepromInterface::saveToByteArray(const T & src, QByteArray & data, uint8_t version) +{ + QByteArray raw; + M manager((T&)src, board, version, 0); + // manager.Dump(); + manager.Export(raw); + data.resize(8); + *((uint32_t*)&data.data()[0]) = 0x3178396F; + 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) +{ + M manager(dest, board, version, variant); + manager.Import(data); + // 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) +{ + uint8_t version = data[4]; + QByteArray raw = data.right(data.size() - 8); + return loadFromByteArray(dest, raw, version); +} + +template +bool +OpenTxEepromInterface::saveRadioSettings(GeneralSettings &settings, BoardEnum board, uint8_t version, uint32_t variant) { T open9xSettings(settings, board, version, variant); // open9xSettings.Dump(); QByteArray eeprom; open9xSettings.Export(eeprom); - int sz = efile->writeRlc2(FILE_GENERAL, FILE_TYP_GENERAL, (const uint8_t*)eeprom.constData(), eeprom.size()); + int sz = efile->writeRlc2(FILE_GENERAL, FILE_TYP_GENERAL, (const uint8_t *) eeprom.constData(), eeprom.size()); return (sz == eeprom.size()); } -template -bool OpenTxEepromInterface::saveModel(unsigned int index, ModelData & model, uint8_t version, uint32_t variant) +template +bool OpenTxEepromInterface::saveModel(unsigned int index, ModelData &model, uint8_t version, uint32_t variant) { T open9xModel(model, board, version, variant); // open9xModel.Dump(); QByteArray eeprom; open9xModel.Export(eeprom); - int sz = efile->writeRlc2(FILE_MODEL(index), FILE_TYP_MODEL, (const uint8_t*)eeprom.constData(), eeprom.size()); + int sz = efile->writeRlc2(FILE_MODEL(index), FILE_TYP_MODEL, (const uint8_t *) eeprom.constData(), eeprom.size()); return (sz == eeprom.size()); } @@ -230,18 +222,74 @@ unsigned long OpenTxEepromInterface::loadxml(RadioData &radioData, QDomDocument return errors.to_ulong(); } -unsigned long OpenTxEepromInterface::load(RadioData & radioData, const uint8_t * eeprom, int size) +int OpenTxEepromInterface::loadFile(RadioData &radioData, const QString & filename) +{ + StorageSdcard storage; + + storage.read(filename); + + // models.txt + QString modelList = QString(storage.modelList); + qDebug() << "Models: size" << modelList.size() << "contents" << modelList; + + // radio.bin + qDebug() << "Radio settings:" << storage.radio.size(); + loadRadioSettings(radioData.generalSettings, storage.radio); + + // all models + QList models = storage.getModelsFileNames(); + qDebug() << "We have" << models.size() << "models:"; + + int index = 0; + for (QList::iterator it = storage.models.begin(); it != storage.models.end(); ++it, ++index) { + loadFromByteArray(radioData.models[index], it->data); + radioData.models[index].used = true; + } + + return 0; +} + +int OpenTxEepromInterface::saveFile(const RadioData & radioData, const QString & filename) +{ + StorageSdcard storage; + uint8_t version = getLastDataVersion(board); + + // models.txt + storage.modelList = QByteArray("[Models]\n"); + + // radio.bin + saveToByteArray(radioData.generalSettings, storage.radio, version); + + // all models + for (int i=0; i(model, modelData, version); + ModelFile modelFile = { modelFilename, modelData }; + storage.models.append(modelFile); + storage.modelList.append(QString(" ") + modelFilename + "\n"); + } + } + + storage.write(filename); + + return 0; +} + +unsigned long OpenTxEepromInterface::load(RadioData &radioData, const uint8_t * eeprom, int size) { std::cout << "trying " << getName() << " import..."; - + std::bitset errors; - + if (size != getEEpromSize()) { - if (size==4096) { - int notnull=false; - for (int i=2048; i<4096; i++) { - if (eeprom[i]!=255) { - notnull=true; + if (size == 4096) { + int notnull = false; + for (int i = 2048; i < 4096; i++) { + if (eeprom[i] != 255) { + notnull = true; } } if (notnull) { @@ -252,108 +300,103 @@ unsigned long OpenTxEepromInterface::load(RadioData & radioData, const uint8_t * else { errors.set(HAS_WARNINGS); errors.set(WARNING_WRONG_FIRMWARE); - size=2048; + size = 2048; } - } else { + } + else { std::cout << " wrong size (" << size << "/" << getEEpromSize() << ")\n"; errors.set(WRONG_SIZE); return errors.to_ulong(); } } - - if (!efile->EeFsOpen((uint8_t *)eeprom, size, board)) { + + if (!efile->EeFsOpen((uint8_t *) eeprom, size, board)) { std::cout << " wrong file system\n"; errors.set(WRONG_FILE_SYSTEM); return errors.to_ulong(); } - + efile->openRd(FILE_GENERAL); - + uint8_t version; if (efile->readRlc2(&version, 1) != 1) { std::cout << " no\n"; errors.set(UNKNOWN_ERROR); return errors.to_ulong(); } - - std::cout << " version " << (unsigned int)version; - + + std::cout << " 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) { + } + else if (version_error == NOT_OPENTX) { std::cout << " not open9x\n"; errors.set(version_error); return errors.to_ulong(); } - - if (!loadRadioSettings(radioData.generalSettings, version)) { + + if (!loadRadioSettingsFromRLE(radioData.generalSettings, efile, version)) { std::cout << " ko\n"; errors.set(UNKNOWN_ERROR); return errors.to_ulong(); } - + std::cout << " variant " << radioData.generalSettings.variant; - for (int i=0; iEeFsCreate(eeprom, size, board, version); - + if (board == BOARD_M128) { variant |= M128_VARIANT; } else if (board == BOARD_TARANIS_X9E) { variant |= TARANIS_X9E_VARIANT; } - + int result = saveRadioSettings(radioData.generalSettings, board, version, variant); if (!result) { return 0; } - - for (int i=0; i(i, radioData.models[i], version, variant); if (!result) { @@ -361,10 +404,10 @@ int OpenTxEepromInterface::save(uint8_t * eeprom, RadioData & radioData, uint8_t } } } - + if (!EEPROMWarnings.empty()) { QString msg; - int noErrorsToDisplay = std::min((int)EEPROMWarnings.size(),10); + int noErrorsToDisplay = std::min((int) EEPROMWarnings.size(), 10); for (int n = 0; n < noErrorsToDisplay; n++) { msg += "-" + EEPROMWarnings.front() + "\n"; EEPROMWarnings.pop_front(); @@ -374,61 +417,61 @@ int OpenTxEepromInterface::save(uint8_t * eeprom, RadioData & radioData, uint8_t } EEPROMWarnings.clear(); QMessageBox::warning(NULL, - QObject::tr("Warning"), - QObject::tr("EEPROM saved with these warnings:") + "\n" + msg); + QObject::tr("Warning"), + QObject::tr("EEPROM saved with these warnings:") + "\n" + msg); } - + return size; } -int OpenTxEepromInterface::getSize(const ModelData & model) +int OpenTxEepromInterface::getSize(const ModelData &model) { if (IS_SKY9X(board)) return 0; - + if (model.isEmpty()) return 0; - + QByteArray tmp(EESIZE_MAX, 0); - efile->EeFsCreate((uint8_t *)tmp.data(), EESIZE_MAX, board, 255/*version max*/); - - OpenTxModelData open9xModel((ModelData &)model, board, 255/*version max*/, GetCurrentFirmware()->getVariantNumber()); - + efile->EeFsCreate((uint8_t *) tmp.data(), EESIZE_MAX, board, 255/*version max*/); + + OpenTxModelData open9xModel((ModelData &) model, 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()); + 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) +int OpenTxEepromInterface::getSize(const GeneralSettings &settings) { if (IS_SKY9X(board)) return 0; - + QByteArray tmp(EESIZE_MAX, 0); - efile->EeFsCreate((uint8_t *)tmp.data(), EESIZE_MAX, board, 255); - - OpenTxGeneralData open9xGeneral((GeneralSettings &)settings, board, 255, GetCurrentFirmware()->getVariantNumber()); + efile->EeFsCreate((uint8_t *) tmp.data(), EESIZE_MAX, board, 255); + + OpenTxGeneralData open9xGeneral((GeneralSettings &) settings, 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()); + 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) +Firmware * OpenTxFirmware::getFirmwareVariant(const QString &id) { if (id == getId()) { return this; } - else if (id.contains(getId()+"-") || (!id.contains("-") && id.contains(getId()))) { + else if (id.contains(getId() + "-") || (!id.contains("-") && id.contains(getId()))) { Firmware * result = new OpenTxFirmware(id, this); // TODO result.variant = firmware->getVariant(id); return result; @@ -447,7 +490,7 @@ int OpenTxFirmware::getCapability(Capability capability) else return id.contains("imperial") ? 1 : 0; case ModelImage: - return (board==BOARD_TARANIS_X9D || board==BOARD_TARANIS_X9DP || board==BOARD_TARANIS_X9E); + return (board == BOARD_TARANIS_X9D || board == BOARD_TARANIS_X9DP || board == BOARD_TARANIS_X9E); case HasBeeper: return (!IS_ARM(board)); case HasPxxCountry: @@ -544,15 +587,15 @@ int OpenTxFirmware::getCapability(Capability capability) return 7; case SwitchesPositions: if (IS_TARANIS_X9E(board)) - return 18*3; + return 18 * 3; else if (IS_TARANIS(board)) - return 8*3; + return 8 * 3; else return 9; case CustomFunctions: if (IS_ARM(board)) return 64; - else if (IS_2560(board) || board==BOARD_M128) + else if (IS_2560(board) || board == BOARD_M128) return 24; else return 16; @@ -567,7 +610,7 @@ int OpenTxFirmware::getCapability(Capability capability) if (IS_ARM(board)) return getCapability(LogicalSwitches); else - return 15/*4bits*/-9/*sw positions*/; + return 15/*4bits*/- 9/*sw positions*/; case LogicalSwitchesExt: return (IS_ARM(board) ? true : false); case RotaryEncoders: @@ -584,7 +627,7 @@ int OpenTxFirmware::getCapability(Capability capability) case VoicesAsNumbers: return (IS_ARM(board) ? 0 : 1); case VoicesMaxLength: - return (IS_ARM(board) ? (IS_TARANIS(board) ? 8 : 6) : 0); + return (IS_ARM(board) ? (IS_TARANIS(board) ? 8 : 6) : 0); case MultiLangVoice: return (IS_ARM(board) ? 1 : 0); case SoundPitch: @@ -620,7 +663,7 @@ int OpenTxFirmware::getCapability(Capability capability) return (IS_TARANIS(board) ? 1 : 0); case Telemetry: if (IS_2560(board) || IS_ARM(board) || id.contains("frsky") || id.contains("telemetrez")) - return TM_HASTELEMETRY|TM_HASOFFSET|TM_HASWSHH; + return TM_HASTELEMETRY | TM_HASOFFSET | TM_HASWSHH; else return 0; case TelemetryBars: @@ -642,7 +685,7 @@ int OpenTxFirmware::getCapability(Capability capability) case SYMLimits: return 1; case OptrexDisplay: - return (board==BOARD_SKY9X ? true : false); + return (board == BOARD_SKY9X ? true : false); case HasVario: return 1; case HasVarioSink: @@ -689,7 +732,7 @@ int OpenTxFirmware::getCapability(Capability capability) else return 1; case GetThrSwitch: - return (IS_TARANIS(board) ? SWITCH_SF1 : SWITCH_THR) ; + return (IS_TARANIS(board) ? SWITCH_SF1 : SWITCH_THR); case HasDisplayText: return IS_ARM(board) ? 1 : 0; case HasTopLcd: @@ -749,33 +792,33 @@ int OpenTxFirmware::getCapability(Capability capability) Firmware::Switch OpenTxFirmware::getSwitch(unsigned int index) { if (board == BOARD_X7D) { - const Switch switches[] = { { SWITCH_3POS, "SA" }, - { SWITCH_3POS, "SB" }, - { SWITCH_3POS, "SC" }, - { SWITCH_3POS, "SD" }, - { SWITCH_2POS, "SF" }, - { SWITCH_TOGGLE, "SH" } }; + const Switch switches[] = {{SWITCH_3POS, "SA"}, + {SWITCH_3POS, "SB"}, + {SWITCH_3POS, "SC"}, + {SWITCH_3POS, "SD"}, + {SWITCH_2POS, "SF"}, + {SWITCH_TOGGLE, "SH"}}; return switches[index]; } else if (IS_TARANIS(board) || board == BOARD_HORUS) { - const Switch switches[] = { { SWITCH_3POS, "SA" }, - { SWITCH_3POS, "SB" }, - { SWITCH_3POS, "SC" }, - { SWITCH_3POS, "SD" }, - { SWITCH_3POS, "SE" }, - { SWITCH_2POS, "SF" }, - { SWITCH_3POS, "SG" }, - { SWITCH_TOGGLE, "SH" }, - { SWITCH_3POS, "SI" }, - { SWITCH_3POS, "SJ" }, - { SWITCH_3POS, "SK" }, - { SWITCH_3POS, "SL" }, - { SWITCH_3POS, "SM" }, - { SWITCH_3POS, "SN" }, - { SWITCH_3POS, "SO" }, - { SWITCH_3POS, "SP" }, - { SWITCH_3POS, "SQ" }, - { SWITCH_3POS, "SR" } }; + const Switch switches[] = {{SWITCH_3POS, "SA"}, + {SWITCH_3POS, "SB"}, + {SWITCH_3POS, "SC"}, + {SWITCH_3POS, "SD"}, + {SWITCH_3POS, "SE"}, + {SWITCH_2POS, "SF"}, + {SWITCH_3POS, "SG"}, + {SWITCH_TOGGLE, "SH"}, + {SWITCH_3POS, "SI"}, + {SWITCH_3POS, "SJ"}, + {SWITCH_3POS, "SK"}, + {SWITCH_3POS, "SL"}, + {SWITCH_3POS, "SM"}, + {SWITCH_3POS, "SN"}, + {SWITCH_3POS, "SO"}, + {SWITCH_3POS, "SP"}, + {SWITCH_3POS, "SQ"}, + {SWITCH_3POS, "SR"}}; return switches[index]; } else { @@ -804,10 +847,10 @@ bool OpenTxFirmware::isTelemetrySourceAvailable(int source) { if (IS_TARANIS(board) && (source == TELEMETRY_SOURCE_RSSI_TX)) return false; - + if (source == TELEMETRY_SOURCE_DTE) return false; - + return true; } @@ -836,7 +879,7 @@ int OpenTxFirmware::isAvailable(PulsesProtocol proto, int port) case PULSES_PXX_XJT_X16: case PULSES_PXX_XJT_D8: case PULSES_PXX_XJT_LR12: - //case PULSES_PXX_DJT: // Unavailable for now + //case PULSES_PXX_DJT: // Unavailable for now case PULSES_LP45: case PULSES_DSM2: case PULSES_DSMX: @@ -894,7 +937,7 @@ int OpenTxFirmware::isAvailable(PulsesProtocol proto, int port) case PULSES_DSMX: case PULSES_LP45: case PULSES_DSM2: - // case PULSES_PXX_DJT: // Unavailable for now + // case PULSES_PXX_DJT: // Unavailable for now case PULSES_PPM16: case PULSES_PPMSIM: return 1; @@ -905,13 +948,14 @@ int OpenTxFirmware::isAvailable(PulsesProtocol proto, int port) } template -size_t getSizeA(T (&)[SIZE]) { - return SIZE; +size_t getSizeA(T (&)[SIZE]) +{ + return SIZE; } EepromLoadErrors OpenTxEepromInterface::checkVersion(unsigned int version) { - switch(version) { + switch (version) { case 201: // first version case 202: @@ -927,7 +971,7 @@ EepromLoadErrors OpenTxEepromInterface::checkVersion(unsigned int version) // telemetry changes (bars) case 205: // mixer changes (differential, negative curves)... - // case 206: + // case 206: case 207: // V4: Rotary Encoders position in FlightModes case 208: @@ -961,7 +1005,7 @@ EepromLoadErrors OpenTxEepromInterface::checkVersion(unsigned int version) default: return NOT_OPENTX; } - + return ALL_OK; } @@ -970,7 +1014,7 @@ bool OpenTxEepromInterface::checkVariant(unsigned int version, unsigned int vari if (board == BOARD_M128 && !(variant & M128_VARIANT)) { if (version == 212) { uint8_t tmp[1000]; - for (int i=1; i<31; i++) { + for (int i = 1; i < 31; i++) { efile->openRd(i); int sz = efile->readRlc2(tmp, sizeof(tmp)); if (sz == 849) { @@ -994,23 +1038,44 @@ bool OpenTxEepromInterface::checkVariant(unsigned int version, unsigned int vari return false; } } - + return true; } -unsigned long OpenTxEepromInterface::loadBackup(RadioData & radioData, uint8_t * eeprom, int esize, int index) +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) == 0) { + 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; - + std::cout << "trying " << getName() << " backup import..."; - + if (esize < 8 || memcmp(eeprom, "o9x", 3) != 0) { std::cout << " no\n"; errors.set(WRONG_SIZE); return errors.to_ulong(); } - - BoardEnum backupBoard = (BoardEnum)-1; + + BoardEnum backupBoard = (BoardEnum) -1; switch (eeprom[3]) { case 0x33: backupBoard = BOARD_TARANIS_X9D; @@ -1026,20 +1091,20 @@ unsigned long OpenTxEepromInterface::loadBackup(RadioData & radioData, uint8_t * errors.set(UNKNOWN_BOARD); return errors.to_ulong(); } - + if (backupBoard != board) { std::cout << " not right board\n"; 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]; - - std::cout << " version " << (unsigned int)version << " "; - + uint16_t size = ((uint16_t) eeprom[7] << 8) + eeprom[6]; + uint16_t variant = ((uint16_t) eeprom[9] << 8) + eeprom[8]; + + std::cout << " version " << (unsigned int) version << " "; + EepromLoadErrors version_error = checkVersion(version); if (version_error == OLD_VERSION) { errors.set(version_error); @@ -1050,15 +1115,15 @@ unsigned long OpenTxEepromInterface::loadBackup(RadioData & radioData, uint8_t * errors.set(version_error); return errors.to_ulong(); } - - if (size > esize-8) { + + if (size > esize - 8) { std::cout << " wrong size\n"; errors.set(WRONG_SIZE); return errors.to_ulong(); } - - if (bcktype=='M') { - if (!loadModel(version, radioData.models[index], &eeprom[8], size, variant)) { + + if (bcktype == 'M') { + if (!loadModelFromBackup(radioData.models[index], &eeprom[8], size, version, variant)) { std::cout << " ko\n"; errors.set(UNKNOWN_ERROR); return errors.to_ulong(); @@ -1069,7 +1134,7 @@ unsigned long OpenTxEepromInterface::loadBackup(RadioData & radioData, uint8_t * errors.set(BACKUP_NOT_SUPPORTED); return errors.to_ulong(); } - + std::cout << " ok\n"; errors.set(ALL_OK); return errors.to_ulong(); @@ -1090,9 +1155,9 @@ QString OpenTxFirmware::getFirmwareUrl() QByteArray data = QUrl::toPercentEncoding(id); if (IS_ARM(board)) - url.append(QString("/getfw.php?fw=%1.bin").arg((QString)data)); + url.append(QString("/getfw.php?fw=%1.bin").arg((QString) data)); else - url.append(QString("/getfw.php?fw=%1.hex").arg((QString)data)); + url.append(QString("/getfw.php?fw=%1.hex").arg((QString) data)); return url; } @@ -1114,7 +1179,9 @@ void addOpenTxCommonOptions(OpenTxFirmware * firmware) { firmware->addOption("ppmus", QObject::tr("Channel values displayed in us")); firmware->addOption("nooverridech", QObject::tr("No OverrideCH functions available")); - Option fai_options[] = { { "faichoice", QObject::tr("Possibility to enable FAI MODE (no telemetry) at field") }, { "faimode", QObject::tr("FAI MODE (no telemetry) always enabled") }, { NULL } }; + Option fai_options[] = {{"faichoice", QObject::tr("Possibility to enable FAI MODE (no telemetry) at field")}, + {"faimode", QObject::tr("FAI MODE (no telemetry) always enabled")}, + {NULL}}; firmware->addOptions(fai_options); } @@ -1124,7 +1191,9 @@ void addOpenTxFrskyOptions(OpenTxFirmware * firmware) firmware->addOption("noheli", QObject::tr("Disable HELI menu and cyclic mix support")); firmware->addOption("nogvars", QObject::tr("Disable Global variables")); firmware->addOption("lua", QObject::tr("Support for Lua model scripts")); - Option usb_options[] = { { "massstorage", QObject::tr("Instead of Joystick emulation, USB connection is Mass Storage (as in the Bootloader)") }, { "cli", QObject::tr("Instead of Joystick emulation, USB connection is Command Line Interface") }, { NULL } }; + Option usb_options[] = {{"massstorage", QObject::tr("Instead of Joystick emulation, USB connection is Mass Storage (as in the Bootloader)")}, + {"cli", QObject::tr("Instead of Joystick emulation, USB connection is Command Line Interface")}, + {NULL}}; firmware->addOptions(usb_options); firmware->addOption("eu", QObject::tr("Removes D8 FrSky protocol support which is not legal for use in the EU on radios sold after Jan 1st, 2015")); firmware->addOption("multimodule", QObject::tr("Support for the DIY-Multiprotocol-TX-Module")); @@ -1141,12 +1210,12 @@ void addOpenTxTaranisOptions(OpenTxFirmware * firmware) void addOpenTxLcdOptions(OpenTxFirmware * firmware) { Option lcd_options[] = { - { "ST7565P", QObject::tr("ST7565P LCD or compatible") }, - { "ST7565R", QObject::tr("ST7565R LCD or compatible") }, - { "ERC12864FSF", QObject::tr("ERC12864FSF LCD") }, - { "ST7920", QObject::tr("ST7920 LCD") }, - { "KS108", QObject::tr("KS108 LCD") }, - { NULL } + {"ST7565P", QObject::tr("ST7565P LCD or compatible")}, + {"ST7565R", QObject::tr("ST7565R LCD or compatible")}, + {"ERC12864FSF", QObject::tr("ERC12864FSF LCD")}, + {"ST7920", QObject::tr("ST7920 LCD")}, + {"KS108", QObject::tr("KS108 LCD")}, + {NULL} }; firmware->addOptions(lcd_options); } @@ -1154,41 +1223,56 @@ void addOpenTxLcdOptions(OpenTxFirmware * firmware) void registerOpenTxFirmwares() { OpenTxFirmware * firmware; - - Option ext_options[] = { { "frsky", QObject::tr("Support for frsky telemetry mod"), FRSKY_VARIANT }, { "telemetrez", QObject::tr("Support for telemetry easy board"), FRSKY_VARIANT }, { "jeti", QObject::tr("Support for jeti telemetry mod"), 0 }, { "ardupilot", QObject::tr("Support for receiving ardupilot data"), 0 }, { "nmea", QObject::tr("Support for receiving NMEA data"), 0 }, { "mavlink", QObject::tr("Support for MAVLINK devices"), MAVLINK_VARIANT }, { NULL } }; - Option extr_options[] = { { "frsky", QObject::tr("Support for frsky telemetry mod"), FRSKY_VARIANT }, { "jeti", QObject::tr("Support for jeti telemetry mod"), 0 }, { "ardupilot", QObject::tr("Support for receiving ardupilot data"), 0 }, { "nmea", QObject::tr("Support for receiving NMEA data"), 0 }, { "mavlink", QObject::tr("Support for MAVLINK devices"), MAVLINK_VARIANT }, { NULL } }; - Option nav_options[] = { { "rotenc", QObject::tr("Rotary Encoder use in menus navigation") }, { "potscroll", QObject::tr("Pots use in menus navigation") }, { NULL } }; - Option dsm2_options[] = { { "DSM2", QObject::tr("Support for DSM2 modules"), 0 }, { "DSM2PPM", QObject::tr("Support for DSM2 modules using ppm instead of true serial"), 0 }, { NULL } }; - + + Option ext_options[] = {{"frsky", QObject::tr("Support for frsky telemetry mod"), FRSKY_VARIANT}, + {"telemetrez", QObject::tr("Support for telemetry easy board"), FRSKY_VARIANT}, + {"jeti", QObject::tr("Support for jeti telemetry mod"), 0}, + {"ardupilot", QObject::tr("Support for receiving ardupilot data"), 0}, + {"nmea", QObject::tr("Support for receiving NMEA data"), 0}, + {"mavlink", QObject::tr("Support for MAVLINK devices"), MAVLINK_VARIANT}, + {NULL}}; + Option extr_options[] = {{"frsky", QObject::tr("Support for frsky telemetry mod"), FRSKY_VARIANT}, + {"jeti", QObject::tr("Support for jeti telemetry mod"), 0}, + {"ardupilot", QObject::tr("Support for receiving ardupilot data"), 0}, + {"nmea", QObject::tr("Support for receiving NMEA data"), 0}, + {"mavlink", QObject::tr("Support for MAVLINK devices"), MAVLINK_VARIANT}, + {NULL}}; + Option nav_options[] = {{"rotenc", QObject::tr("Rotary Encoder use in menus navigation")}, + {"potscroll", QObject::tr("Pots use in menus navigation")}, + {NULL}}; + Option dsm2_options[] = {{"DSM2", QObject::tr("Support for DSM2 modules"), 0}, + {"DSM2PPM", QObject::tr("Support for DSM2 modules using ppm instead of true serial"), 0}, + {NULL}}; + /* FrSky Taranis X9D+ board */ firmware = new OpenTxFirmware("opentx-x9d+", QObject::tr("FrSky Taranis X9D+"), BOARD_TARANIS_X9DP); addOpenTxTaranisOptions(firmware); firmwares.push_back(firmware); - + /* FrSky Taranis X9D board */ firmware = new OpenTxFirmware("opentx-x9d", QObject::tr("FrSky Taranis X9D"), BOARD_TARANIS_X9D); firmware->addOption("haptic", QObject::tr("Haptic module installed")); addOpenTxTaranisOptions(firmware); firmwares.push_back(firmware); - + /* FrSky Taranis X9E board */ firmware = new OpenTxFirmware("opentx-x9e", QObject::tr("FrSky Taranis X9E"), BOARD_TARANIS_X9E); firmware->addOption("shutdownconfirm", QObject::tr("Confirmation before radio shutdown")); firmware->addOption("horussticks", QObject::tr("Horus gimbals installed (Hall sensors)")); addOpenTxTaranisOptions(firmware); firmwares.push_back(firmware); - + /* FrSky X7D board */ firmware = new OpenTxFirmware("opentx-x7d", QObject::tr("FrSky X7D"), BOARD_X7D); addOpenTxTaranisOptions(firmware); firmwares.push_back(firmware); - + /* FrSky Horus board */ firmware = new OpenTxFirmware("opentx-horus", QObject::tr("FrSky Horus"), BOARD_HORUS); addOpenTxFrskyOptions(firmware); firmware->addOption("pcbdev", QObject::tr("Use ONLY with first DEV pcb version")); firmwares.push_back(firmware); - + /* 9XR-Pro */ firmware = new OpenTxFirmware("opentx-9xrpro", QObject::tr("Turnigy 9XR-PRO"), BOARD_9XRPRO); firmware->addOption("heli", QObject::tr("Enable HELI menu and cyclic mix support")); @@ -1208,7 +1292,7 @@ void registerOpenTxFirmwares() firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font")); addOpenTxCommonOptions(firmware); firmwares.push_back(firmware); - + /* 9XR board with M128 chip */ firmware = new OpenTxFirmware("opentx-9xr128", QObject::tr("Turnigy 9XR with m128 chip"), BOARD_M128); firmware->addOptions(extr_options); @@ -1237,7 +1321,7 @@ void registerOpenTxFirmwares() firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font")); addOpenTxCommonOptions(firmware); firmwares.push_back(firmware); - + /* 9XR board */ firmware = new OpenTxFirmware("opentx-9xr", QObject::tr("Turnigy 9XR"), BOARD_STOCK); firmware->addOptions(extr_options); @@ -1271,7 +1355,7 @@ void registerOpenTxFirmwares() firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font")); addOpenTxCommonOptions(firmware); firmwares.push_back(firmware); - + /* 9x board */ firmware = new OpenTxFirmware("opentx-9x", QObject::tr("9X with stock board"), BOARD_STOCK); firmware->addOptions(ext_options); @@ -1308,7 +1392,7 @@ void registerOpenTxFirmwares() firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font")); addOpenTxCommonOptions(firmware); firmwares.push_back(firmware); - + /* 9x board with M128 chip */ firmware = new OpenTxFirmware("opentx-9x128", QObject::tr("9X with stock board and m128 chip"), BOARD_M128); firmware->addOptions(ext_options); @@ -1339,7 +1423,7 @@ void registerOpenTxFirmwares() firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font")); addOpenTxCommonOptions(firmware); firmwares.push_back(firmware); - + /* ar9x board */ firmware = new OpenTxFirmware("opentx-ar9x", QObject::tr("9X with AR9X board"), BOARD_AR9X); firmware->addOption("heli", QObject::tr("Enable HELI menu and cyclic mix support")); @@ -1362,7 +1446,7 @@ void registerOpenTxFirmwares() // firmware->addOption("volume", QObject::tr("i2c volume control added")); addOpenTxCommonOptions(firmware); firmwares.push_back(firmware); - + /* Sky9x board */ firmware = new OpenTxFirmware("opentx-sky9x", QObject::tr("9X with Sky9x board"), BOARD_SKY9X); firmware->addOption("heli", QObject::tr("Enable HELI menu and cyclic mix support")); @@ -1383,7 +1467,7 @@ void registerOpenTxFirmwares() firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font")); addOpenTxCommonOptions(firmware); firmwares.push_back(firmware); - + /* Gruvin9x board */ firmware = new OpenTxFirmware("opentx-gruvin9x", QObject::tr("9X with Gruvin9x board"), BOARD_GRUVIN9X); firmware->addOption("heli", QObject::tr("Enable heli menu and cyclic mix support")); @@ -1409,7 +1493,7 @@ void registerOpenTxFirmwares() firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font")); addOpenTxCommonOptions(firmware); firmwares.push_back(firmware); - + /* MEGA2560 board */ firmware = new OpenTxFirmware("opentx-mega2560", QObject::tr("DIY MEGA2560 radio"), BOARD_MEGA2560); addOpenTxLcdOptions(firmware); @@ -1440,14 +1524,14 @@ void registerOpenTxFirmwares() firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font")); addOpenTxCommonOptions(firmware); firmwares.push_back(firmware); - + default_firmware_variant = GetFirmware("opentx-x9d+"); current_firmware_variant = default_firmware_variant; } void unregisterOpenTxFirmwares() { - foreach (Firmware * f, firmwares) { - delete f; - } + foreach (Firmware * f, firmwares) { + delete f; + } } diff --git a/companion/src/firmwares/opentx/opentxinterface.h b/companion/src/firmwares/opentx/opentxinterface.h index df3a25de6..e801dcc47 100644 --- a/companion/src/firmwares/opentx/opentxinterface.h +++ b/companion/src/firmwares/opentx/opentxinterface.h @@ -37,21 +37,23 @@ class OpenTxEepromInterface : public EEPROMInterface virtual const int getMaxModels(); - virtual unsigned long load(RadioData &, const uint8_t *eeprom, int size); - - virtual unsigned long loadBackup(RadioData &, uint8_t *eeprom, int esize, int index); + 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 unsigned long loadxml(RadioData & radioData, QDomDocument & doc); - virtual bool loadRadioSettings(GeneralSettings & model, const QByteArray & data); - - virtual bool loadModel(ModelData & model, const QByteArray & data); - virtual int save(uint8_t * eeprom, RadioData & radioData, uint8_t version=0, uint32_t variant=0); virtual int getSize(const ModelData &); virtual int getSize(const GeneralSettings &); + + virtual int loadFile(RadioData & radioData, const QString & filename); + + virtual int saveFile(const RadioData & radioData, const QString & filename); protected: @@ -61,21 +63,33 @@ class OpenTxEepromInterface : public EEPROMInterface bool checkVariant(unsigned int version, unsigned int variant); - bool loadModel(uint8_t version, ModelData &model, uint8_t *data, int index, unsigned int variant); + template + bool loadFromByteArray(T & dest, const QByteArray & data, uint8_t version, uint32_t variant=0); + + template + bool loadFromByteArray(T & dest, const QByteArray & data); + + template + bool saveToByteArray(const T & src, QByteArray & data, uint8_t version); + bool loadRadioSettingsFromRLE(GeneralSettings & settings, RleFile * rleFile, uint8_t version); + + bool loadModelFromRLE(ModelData & model, RleFile * rleFile, unsigned int index, uint8_t version, uint32_t variant); + template bool saveModel(unsigned int index, ModelData & model, uint8_t version, uint32_t variant); - - bool loadRadioSettings(GeneralSettings & settings, uint8_t version); - + template bool saveRadioSettings(GeneralSettings & settings, BoardEnum board, uint8_t version, uint32_t variant); - - RleFile *efile; + + uint8_t getLastDataVersion(BoardEnum board); + + RleFile * efile; }; -class OpenTxFirmware: public Firmware { +class OpenTxFirmware: public Firmware +{ public: OpenTxFirmware(const QString & id, OpenTxFirmware * parent): Firmware(parent, id, parent->getName(), parent->getBoard(), parent->eepromInterface) diff --git a/companion/src/helpers.cpp b/companion/src/helpers.cpp index 0b55311cc..41da88481 100644 --- a/companion/src/helpers.cpp +++ b/companion/src/helpers.cpp @@ -822,9 +822,7 @@ void startSimulation(QWidget * parent, RadioData & radioData, int modelIdx) SimulatorDialog * dialog; if (board == BOARD_HORUS) { dialog = new SimulatorDialogHorus(parent, simulator, flags); - StorageSdcard storage; - QString sdPath = g.profile[g.id()].sdPath(); - storage.write(sdPath); + GetEepromInterface()->saveFile(*simuData, g.profile[g.id()].sdPath()); dialog->start(NULL); } else if (board == BOARD_FLAMENCO) { diff --git a/companion/src/mdichild.cpp b/companion/src/mdichild.cpp index 269d27a9c..264312c3c 100644 --- a/companion/src/mdichild.cpp +++ b/companion/src/mdichild.cpp @@ -343,51 +343,17 @@ bool MdiChild::loadFile(const QString & fileName, bool resetCurrentFile) return true; } else if (fileType == FILE_TYPE_OTX) { //read zip archive - if (loadOtxFile(fileName)) { + if (!GetEepromInterface()->loadFile(radioData, fileName)) { ui->modelsList->refreshList(); if (resetCurrentFile) setCurrentFile(fileName); + return true; } } return false; } -bool MdiChild::loadOtxFile(const QString & fileName) -{ - // example of StorageSdcard usage - - StorageSdcard storage; - - storage.read(fileName); - - // display models.txt - QString modelList = QString(storage.modelList); - qDebug() << "Models: size" << modelList.size() << "contents" << modelList; - - // info about radio.bin - qDebug() << "Radio settings:" << storage.radio.size(); - - // info about all models - QList models = storage.getModelsFileNames(); - qDebug() << "We have" << models.size() << "models:"; -#if 0 - foreach(QString filename, models) { - QList::const_iterator i = storage.getModelIterator(filename); - if (i != storage.models.end()) { - qDebug() << "\tModel:" << i->filename << "size" << i->data.size(); - } - } -#endif - - int index = 0; - for (QList::iterator i = storage.models.begin(); i != storage.models.end(); ++i, ++index) { - GetEepromInterface()->loadModel(radioData.models[index], i->data); - } - - return true; -} - bool MdiChild::save() { if (isUntitled) { diff --git a/companion/src/storage/storage_sdcard.cpp b/companion/src/storage/storage_sdcard.cpp index d471dd6b7..65378fe49 100644 --- a/companion/src/storage/storage_sdcard.cpp +++ b/companion/src/storage/storage_sdcard.cpp @@ -163,6 +163,7 @@ void StorageSdcard::writeFile(const QByteArray & data, const QString & path) QFile file(path); if (!file.open(QFile::WriteOnly)) { lastErrorMessage = QObject::tr("Error opening file %1:\n%2.").arg(path).arg(file.errorString()); + qDebug() << "File" << path << "write error"; throw StorageSdcardWriteFileError(); } file.write(data.data(), data.size()); @@ -176,12 +177,12 @@ int StorageSdcard::writeSdcard(const QString & path) QDir dir(path); dir.mkdir("RADIO"); writeFile(radio, path + "/RADIO/radio.bin"); - writeFile(modelList, path + "RADIO/models.txt"); + writeFile(modelList, path + "/RADIO/models.txt"); dir.mkdir("MODELS"); for (QList::const_iterator i = models.begin(); i != models.end(); ++i) { qDebug() << "writing" << i->filename; - writeFile(i->data, path + "MODELS/" + i->filename); + writeFile(i->data, path + "/MODELS/" + i->filename); } } catch (StorageSdcardWriteFileError) { diff --git a/radio/src/datastructs.h b/radio/src/datastructs.h index a841ecc5d..70cd0d6f3 100644 --- a/radio/src/datastructs.h +++ b/radio/src/datastructs.h @@ -913,8 +913,8 @@ PACK(struct TrainerData { #elif defined(PCBFLAMENCO) #define EXTRA_GENERAL_FIELDS \ EXTRA_GENERAL_FIELDS_ARM \ - uint8_t serial2Mode:6; \ - uint8_t spare:2; \ + uint8_t serial2Mode:4; \ + uint8_t spare:4; \ uint32_t switchConfig; \ uint8_t potsType; /*two bits for every pot*/\ char switchNames[NUM_SWITCHES][LEN_SWITCH_NAME]; \