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

[Companion] Horus models export for simulation now OK

This commit is contained in:
Bertrand Songis 2016-11-27 00:45:24 +01:00
parent 0ca0785912
commit 8854cf9e87
9 changed files with 429 additions and 325 deletions

View file

@ -1634,8 +1634,8 @@ void registerEEpromInterfaces()
eepromInterfaces.push_back(new OpenTxEepromInterface(BOARD_TARANIS_X9D)); eepromInterfaces.push_back(new OpenTxEepromInterface(BOARD_TARANIS_X9D));
eepromInterfaces.push_back(new OpenTxEepromInterface(BOARD_TARANIS_X9DP)); eepromInterfaces.push_back(new OpenTxEepromInterface(BOARD_TARANIS_X9DP));
eepromInterfaces.push_back(new OpenTxEepromInterface(BOARD_TARANIS_X9E)); eepromInterfaces.push_back(new OpenTxEepromInterface(BOARD_TARANIS_X9E));
eepromInterfaces.push_back(new Ersky9xInterface()); // eepromInterfaces.push_back(new Ersky9xInterface());
eepromInterfaces.push_back(new Er9xInterface()); // eepromInterfaces.push_back(new Er9xInterface());
} }
void unregisterEEpromInterfaces() void unregisterEEpromInterfaces()

View file

@ -1240,6 +1240,7 @@ class GeneralSettings {
unsigned int sticksGain; unsigned int sticksGain;
unsigned int rotarySteps; unsigned int rotarySteps;
unsigned int countryCode; unsigned int countryCode;
bool jitterFilter;
unsigned int imperial; unsigned int imperial;
bool crosstrim; bool crosstrim;
char ttsLanguage[2+1]; char ttsLanguage[2+1];
@ -1411,15 +1412,15 @@ class EEPROMInterface
inline BoardEnum getBoard() { return board; } 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 loadRadioSettings(GeneralSettings & model, const QByteArray & data) { return false; }
virtual bool loadModel(ModelData & 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; 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 getEEpromSize() = 0;
virtual const int getMaxModels() = 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: protected:
BoardEnum board; BoardEnum board;

View file

@ -33,8 +33,9 @@
#define MAX_VIEWS(board) (HAS_LARGE_LCD(board) ? 2 : 256) #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_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_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_MOUSE_ANALOGS(board) (IS_HORUS(board) ? 2 : 0)
#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_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_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_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) #define MAX_TIMERS(board, version) ((IS_ARM(board) && version >= 217) ? 3 : 2)
@ -3451,7 +3452,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, BoardEnum bo
generalData(generalData), generalData(generalData),
board(board), board(board),
version(version), 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); 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<16>(chkSum));
internalField.Append(new UnsignedField<8>(generalData.currModel)); if (!IS_HORUS(board)) {
internalField.Append(new UnsignedField<8>(generalData.contrast)); internalField.Append(new UnsignedField<8>(generalData.currModel));
internalField.Append(new UnsignedField<8>(generalData.contrast));
}
internalField.Append(new UnsignedField<8>(generalData.vBatWarn)); internalField.Append(new UnsignedField<8>(generalData.vBatWarn));
internalField.Append(new SignedField<8>(generalData.txVoltageCalibration)); internalField.Append(new SignedField<8>(generalData.txVoltageCalibration));
internalField.Append(new SignedField<8>(generalData.backlightMode)); 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.PPM_Multiplier));
internalField.Append(new SignedField<8>(generalData.hapticLength)); 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)); 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)); internalField.Append(new UnsignedField<8>(generalData.stickReverse));
} }
@ -3591,21 +3594,28 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, BoardEnum bo
if (version >= 214) { if (version >= 214) {
if (version < 218) internalField.Append(new UnsignedField<8>(generalData.rotarySteps)); // TODO if (version < 218) internalField.Append(new UnsignedField<8>(generalData.rotarySteps)); // TODO
internalField.Append(new UnsignedField<8>(generalData.countryCode)); 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) { if (version >= 215) {
internalField.Append(new CharField<2>(generalData.ttsLanguage)); internalField.Append(new CharField<2>(generalData.ttsLanguage));
if (version < 218) { 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 {
internalField.Append(new SignedField<4>(generalData.beepVolume)); internalField.Append(new SignedField<4>(generalData.beepVolume));
internalField.Append(new SignedField<4>(generalData.wavVolume)); internalField.Append(new SignedField<4>(generalData.wavVolume));
internalField.Append(new SignedField<4>(generalData.varioVolume)); internalField.Append(new SignedField<4>(generalData.varioVolume));
internalField.Append(new SignedField<4>(generalData.backgroundVolume)); 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) { if (version >= 216) {
internalField.Append(new SignedField<8>(generalData.varioPitch)); internalField.Append(new SignedField<8>(generalData.varioPitch));
internalField.Append(new SignedField<8>(generalData.varioRange)); 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)); internalField.Append(new ArmCustomFunctionField(generalData.customFn[i], board, version, variant));
} }
} }
if (IS_TARANIS(board) && version >= 216) { if (IS_STM32(board) && version >= 216) {
if (version >= 217) { 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)); internalField.Append(new UnsignedField<6>(generalData.hw_uartMode));
if (IS_TARANIS_X9E(board)) { if (IS_TARANIS_X9E(board)) {
internalField.Append(new UnsignedField<1>(generalData.sliderConfig[2])); internalField.Append(new UnsignedField<1>(generalData.sliderConfig[2]));
@ -3632,13 +3648,17 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, BoardEnum bo
else { else {
internalField.Append(new UnsignedField<8>(generalData.hw_uartMode)); 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++) { for (int i=0; i<4; i++) {
if (i < MAX_POTS(board, version)) if (i < MAX_POTS(board, version))
internalField.Append(new UnsignedField<2>(generalData.potConfig[i])); internalField.Append(new UnsignedField<2>(generalData.potConfig[i]));
else else
internalField.Append(new SpareBitsField<2>()); 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)) 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<MAX_SWITCHES(board, version); ++i) {
internalField.Append(new ZCharField<3>(generalData.switchName[i]));
}
for (int i=0; i<CPN_MAX_STICKS; ++i) {
internalField.Append(new ZCharField<3>(generalData.stickName[i]));
}
for (int i=0; i<MAX_POTS(board, version); ++i) {
internalField.Append(new ZCharField<3>(generalData.potName[i]));
}
for (int i=0; i<MAX_SLIDERS(board); ++i) {
internalField.Append(new ZCharField<3>(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<MAX_SWITCHES(board, version); i++) { for (int i=0; i<MAX_SWITCHES(board, version); i++) {
internalField.Append(new UnsignedField<2>(generalData.switchConfig[i])); internalField.Append(new UnsignedField<2>(generalData.switchConfig[i]));
} }

View file

@ -24,6 +24,7 @@
#include "opentxeeprom.h" #include "opentxeeprom.h"
#include "rlefile.h" #include "rlefile.h"
#include "appdata.h" #include "appdata.h"
#include "storage_sdcard.h"
#define OPENTX_FIRMWARE_DOWNLOADS "http://downloads-22.open-tx.org/firmware" #define OPENTX_FIRMWARE_DOWNLOADS "http://downloads-22.open-tx.org/firmware"
#define OPENTX_NIGHT_FIRMWARE_DOWNLOADS "http://downloads-22.open-tx.org/nightly/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 /// convert model number 0..MAX_MODELS-1 int fileId
#define FILE_MODEL(n) (1+n) #define FILE_MODEL(n) (1+n)
template <typename T, size_t N> template<typename T, size_t N>
inline inline
size_t SizeOfArray( T(&)[ N ] ) size_t SizeOfArray(T(&)[N])
{ {
return N; return N;
} }
@ -126,100 +127,91 @@ const int OpenTxEepromInterface::getMaxModels()
return 16; 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); QByteArray data(sizeof(settings), 0); // GeneralSettings should be always bigger than the EEPROM struct
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
OpenTxGeneralData open9xSettings(settings, board, version); OpenTxGeneralData open9xSettings(settings, board, version);
efile->openRd(FILE_GENERAL); efile->openRd(FILE_GENERAL);
int sz = efile->readRlc2((uint8_t *)eepromData.data(), eepromData.size()); int size = rleFile->readRlc2((uint8_t *)data.data(), data.size());
if (sz) { if (size) {
open9xSettings.Import(eepromData); open9xSettings.Import(data);
return checkVariant(settings.version, settings.variant); 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<ModelData, OpenTxModelData>(model, data, version, variant) == 0) {
model.used = true;
return true;
}
}
std::cout << " error when loading model";
model.clear();
return false; return false;
} }
template <class T> template <class T, class M>
bool OpenTxEepromInterface::saveRadioSettings(GeneralSettings & settings, BoardEnum board, uint8_t version, uint32_t variant) 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 <class T, class M>
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 <class T, class M>
bool OpenTxEepromInterface::loadFromByteArray(T & dest, const QByteArray & data)
{
uint8_t version = data[4];
QByteArray raw = data.right(data.size() - 8);
return loadFromByteArray<T, M>(dest, raw, version);
}
template<class T>
bool
OpenTxEepromInterface::saveRadioSettings(GeneralSettings &settings, BoardEnum board, uint8_t version, uint32_t variant)
{ {
T open9xSettings(settings, board, version, variant); T open9xSettings(settings, board, version, variant);
// open9xSettings.Dump(); // open9xSettings.Dump();
QByteArray eeprom; QByteArray eeprom;
open9xSettings.Export(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()); return (sz == eeprom.size());
} }
template <class T> template<class T>
bool OpenTxEepromInterface::saveModel(unsigned int index, ModelData & model, uint8_t version, uint32_t variant) bool OpenTxEepromInterface::saveModel(unsigned int index, ModelData &model, uint8_t version, uint32_t variant)
{ {
T open9xModel(model, board, version, variant); T open9xModel(model, board, version, variant);
// open9xModel.Dump(); // open9xModel.Dump();
QByteArray eeprom; QByteArray eeprom;
open9xModel.Export(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()); return (sz == eeprom.size());
} }
@ -230,18 +222,74 @@ unsigned long OpenTxEepromInterface::loadxml(RadioData &radioData, QDomDocument
return errors.to_ulong(); 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<QString> models = storage.getModelsFileNames();
qDebug() << "We have" << models.size() << "models:";
int index = 0;
for (QList<ModelFile>::iterator it = storage.models.begin(); it != storage.models.end(); ++it, ++index) {
loadFromByteArray<ModelData, OpenTxModelData>(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<GeneralSettings, OpenTxGeneralData>(radioData.generalSettings, storage.radio, version);
// all models
for (int i=0; i<CPN_MAX_MODELS; i++) {
const ModelData & model = radioData.models[i];
if (!model.isEmpty()) {
QString modelFilename = QString().sprintf("model%d.bin", i+1);
QByteArray modelData;
saveToByteArray<ModelData, OpenTxModelData>(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::cout << "trying " << getName() << " import...";
std::bitset<NUM_ERRORS> errors; std::bitset<NUM_ERRORS> errors;
if (size != getEEpromSize()) { if (size != getEEpromSize()) {
if (size==4096) { if (size == 4096) {
int notnull=false; int notnull = false;
for (int i=2048; i<4096; i++) { for (int i = 2048; i < 4096; i++) {
if (eeprom[i]!=255) { if (eeprom[i] != 255) {
notnull=true; notnull = true;
} }
} }
if (notnull) { if (notnull) {
@ -252,108 +300,103 @@ unsigned long OpenTxEepromInterface::load(RadioData & radioData, const uint8_t *
else { else {
errors.set(HAS_WARNINGS); errors.set(HAS_WARNINGS);
errors.set(WARNING_WRONG_FIRMWARE); errors.set(WARNING_WRONG_FIRMWARE);
size=2048; size = 2048;
} }
} else { }
else {
std::cout << " wrong size (" << size << "/" << getEEpromSize() << ")\n"; std::cout << " wrong size (" << size << "/" << getEEpromSize() << ")\n";
errors.set(WRONG_SIZE); errors.set(WRONG_SIZE);
return errors.to_ulong(); 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"; std::cout << " wrong file system\n";
errors.set(WRONG_FILE_SYSTEM); errors.set(WRONG_FILE_SYSTEM);
return errors.to_ulong(); return errors.to_ulong();
} }
efile->openRd(FILE_GENERAL); efile->openRd(FILE_GENERAL);
uint8_t version; uint8_t version;
if (efile->readRlc2(&version, 1) != 1) { if (efile->readRlc2(&version, 1) != 1) {
std::cout << " no\n"; std::cout << " no\n";
errors.set(UNKNOWN_ERROR); errors.set(UNKNOWN_ERROR);
return errors.to_ulong(); return errors.to_ulong();
} }
std::cout << " version " << (unsigned int)version; std::cout << " version " << (unsigned int) version;
EepromLoadErrors version_error = checkVersion(version); EepromLoadErrors version_error = checkVersion(version);
if (version_error == OLD_VERSION) { if (version_error == OLD_VERSION) {
errors.set(version_error); errors.set(version_error);
errors.set(HAS_WARNINGS); errors.set(HAS_WARNINGS);
} else if (version_error == NOT_OPENTX) { }
else if (version_error == NOT_OPENTX) {
std::cout << " not open9x\n"; std::cout << " not open9x\n";
errors.set(version_error); errors.set(version_error);
return errors.to_ulong(); return errors.to_ulong();
} }
if (!loadRadioSettings(radioData.generalSettings, version)) { if (!loadRadioSettingsFromRLE(radioData.generalSettings, efile, version)) {
std::cout << " ko\n"; std::cout << " ko\n";
errors.set(UNKNOWN_ERROR); errors.set(UNKNOWN_ERROR);
return errors.to_ulong(); return errors.to_ulong();
} }
std::cout << " variant " << radioData.generalSettings.variant; std::cout << " variant " << radioData.generalSettings.variant;
for (int i=0; i<getMaxModels(); i++) { for (int i = 0; i < getMaxModels(); i++) {
if (!loadModel(version, radioData.models[i], NULL, i, radioData.generalSettings.variant)) { if (!loadModelFromRLE(radioData.models[i], efile, i, version, radioData.generalSettings.variant)) {
std::cout << " ko\n"; std::cout << " ko\n";
errors.set(UNKNOWN_ERROR); errors.set(UNKNOWN_ERROR);
return errors.to_ulong(); return errors.to_ulong();
} }
} }
std::cout << " ok\n"; std::cout << " ok\n";
errors.set(ALL_OK); errors.set(ALL_OK);
return errors.to_ulong(); return errors.to_ulong();
} }
uint8_t OpenTxEepromInterface::getLastDataVersion(BoardEnum board)
{
switch (board) {
case BOARD_STOCK:
return 216;
case BOARD_GRUVIN9X:
case BOARD_MEGA2560:
case BOARD_M128:
return 217;
default:
return 218;
}
}
int OpenTxEepromInterface::save(uint8_t * eeprom, RadioData & radioData, uint8_t version, uint32_t variant) int OpenTxEepromInterface::save(uint8_t * eeprom, RadioData & radioData, uint8_t version, uint32_t variant)
{ {
EEPROMWarnings.clear(); EEPROMWarnings.clear();
if (version == 0) { if (version == 0) {
switch (board) { version = getLastDataVersion(board);
case BOARD_X7D:
case BOARD_TARANIS_X9D:
case BOARD_TARANIS_X9DP:
case BOARD_TARANIS_X9E:
case BOARD_SKY9X:
case BOARD_AR9X:
case BOARD_9XRPRO:
case BOARD_FLAMENCO:
case BOARD_HORUS:
version = 218;
break;
case BOARD_GRUVIN9X:
case BOARD_MEGA2560:
version = 217;
break;
case BOARD_M128:
version = 217;
break;
case BOARD_STOCK:
version = 216;
break;
}
} }
int size = getEEpromSize(); int size = getEEpromSize();
efile->EeFsCreate(eeprom, size, board, version); efile->EeFsCreate(eeprom, size, board, version);
if (board == BOARD_M128) { if (board == BOARD_M128) {
variant |= M128_VARIANT; variant |= M128_VARIANT;
} }
else if (board == BOARD_TARANIS_X9E) { else if (board == BOARD_TARANIS_X9E) {
variant |= TARANIS_X9E_VARIANT; variant |= TARANIS_X9E_VARIANT;
} }
int result = saveRadioSettings<OpenTxGeneralData>(radioData.generalSettings, board, version, variant); int result = saveRadioSettings<OpenTxGeneralData>(radioData.generalSettings, board, version, variant);
if (!result) { if (!result) {
return 0; return 0;
} }
for (int i=0; i<getMaxModels(); i++) { for (int i = 0; i < getMaxModels(); i++) {
if (!radioData.models[i].isEmpty()) { if (!radioData.models[i].isEmpty()) {
result = saveModel<OpenTxModelData>(i, radioData.models[i], version, variant); result = saveModel<OpenTxModelData>(i, radioData.models[i], version, variant);
if (!result) { if (!result) {
@ -361,10 +404,10 @@ int OpenTxEepromInterface::save(uint8_t * eeprom, RadioData & radioData, uint8_t
} }
} }
} }
if (!EEPROMWarnings.empty()) { if (!EEPROMWarnings.empty()) {
QString msg; 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++) { for (int n = 0; n < noErrorsToDisplay; n++) {
msg += "-" + EEPROMWarnings.front() + "\n"; msg += "-" + EEPROMWarnings.front() + "\n";
EEPROMWarnings.pop_front(); EEPROMWarnings.pop_front();
@ -374,61 +417,61 @@ int OpenTxEepromInterface::save(uint8_t * eeprom, RadioData & radioData, uint8_t
} }
EEPROMWarnings.clear(); EEPROMWarnings.clear();
QMessageBox::warning(NULL, QMessageBox::warning(NULL,
QObject::tr("Warning"), QObject::tr("Warning"),
QObject::tr("EEPROM saved with these warnings:") + "\n" + msg); QObject::tr("EEPROM saved with these warnings:") + "\n" + msg);
} }
return size; return size;
} }
int OpenTxEepromInterface::getSize(const ModelData & model) int OpenTxEepromInterface::getSize(const ModelData &model)
{ {
if (IS_SKY9X(board)) if (IS_SKY9X(board))
return 0; return 0;
if (model.isEmpty()) if (model.isEmpty())
return 0; return 0;
QByteArray tmp(EESIZE_MAX, 0); QByteArray tmp(EESIZE_MAX, 0);
efile->EeFsCreate((uint8_t *)tmp.data(), EESIZE_MAX, board, 255/*version max*/); efile->EeFsCreate((uint8_t *) tmp.data(), EESIZE_MAX, board, 255/*version max*/);
OpenTxModelData open9xModel((ModelData &)model, board, 255/*version max*/, GetCurrentFirmware()->getVariantNumber()); OpenTxModelData open9xModel((ModelData &) model, board, 255/*version max*/, GetCurrentFirmware()->getVariantNumber());
QByteArray eeprom; QByteArray eeprom;
open9xModel.Export(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()) { if (sz != eeprom.size()) {
return -1; return -1;
} }
return efile->size(0); return efile->size(0);
} }
int OpenTxEepromInterface::getSize(const GeneralSettings & settings) int OpenTxEepromInterface::getSize(const GeneralSettings &settings)
{ {
if (IS_SKY9X(board)) if (IS_SKY9X(board))
return 0; return 0;
QByteArray tmp(EESIZE_MAX, 0); QByteArray tmp(EESIZE_MAX, 0);
efile->EeFsCreate((uint8_t *)tmp.data(), EESIZE_MAX, board, 255); efile->EeFsCreate((uint8_t *) tmp.data(), EESIZE_MAX, board, 255);
OpenTxGeneralData open9xGeneral((GeneralSettings &)settings, board, 255, GetCurrentFirmware()->getVariantNumber()); OpenTxGeneralData open9xGeneral((GeneralSettings &) settings, board, 255, GetCurrentFirmware()->getVariantNumber());
// open9xGeneral.Dump(); // open9xGeneral.Dump();
QByteArray eeprom; QByteArray eeprom;
open9xGeneral.Export(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()) { if (sz != eeprom.size()) {
return -1; return -1;
} }
return efile->size(0); return efile->size(0);
} }
Firmware * OpenTxFirmware::getFirmwareVariant(const QString & id) Firmware * OpenTxFirmware::getFirmwareVariant(const QString &id)
{ {
if (id == getId()) { if (id == getId()) {
return this; 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); Firmware * result = new OpenTxFirmware(id, this);
// TODO result.variant = firmware->getVariant(id); // TODO result.variant = firmware->getVariant(id);
return result; return result;
@ -447,7 +490,7 @@ int OpenTxFirmware::getCapability(Capability capability)
else else
return id.contains("imperial") ? 1 : 0; return id.contains("imperial") ? 1 : 0;
case ModelImage: 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: case HasBeeper:
return (!IS_ARM(board)); return (!IS_ARM(board));
case HasPxxCountry: case HasPxxCountry:
@ -544,15 +587,15 @@ int OpenTxFirmware::getCapability(Capability capability)
return 7; return 7;
case SwitchesPositions: case SwitchesPositions:
if (IS_TARANIS_X9E(board)) if (IS_TARANIS_X9E(board))
return 18*3; return 18 * 3;
else if (IS_TARANIS(board)) else if (IS_TARANIS(board))
return 8*3; return 8 * 3;
else else
return 9; return 9;
case CustomFunctions: case CustomFunctions:
if (IS_ARM(board)) if (IS_ARM(board))
return 64; return 64;
else if (IS_2560(board) || board==BOARD_M128) else if (IS_2560(board) || board == BOARD_M128)
return 24; return 24;
else else
return 16; return 16;
@ -567,7 +610,7 @@ int OpenTxFirmware::getCapability(Capability capability)
if (IS_ARM(board)) if (IS_ARM(board))
return getCapability(LogicalSwitches); return getCapability(LogicalSwitches);
else else
return 15/*4bits*/-9/*sw positions*/; return 15/*4bits*/- 9/*sw positions*/;
case LogicalSwitchesExt: case LogicalSwitchesExt:
return (IS_ARM(board) ? true : false); return (IS_ARM(board) ? true : false);
case RotaryEncoders: case RotaryEncoders:
@ -584,7 +627,7 @@ int OpenTxFirmware::getCapability(Capability capability)
case VoicesAsNumbers: case VoicesAsNumbers:
return (IS_ARM(board) ? 0 : 1); return (IS_ARM(board) ? 0 : 1);
case VoicesMaxLength: case VoicesMaxLength:
return (IS_ARM(board) ? (IS_TARANIS(board) ? 8 : 6) : 0); return (IS_ARM(board) ? (IS_TARANIS(board) ? 8 : 6) : 0);
case MultiLangVoice: case MultiLangVoice:
return (IS_ARM(board) ? 1 : 0); return (IS_ARM(board) ? 1 : 0);
case SoundPitch: case SoundPitch:
@ -620,7 +663,7 @@ int OpenTxFirmware::getCapability(Capability capability)
return (IS_TARANIS(board) ? 1 : 0); return (IS_TARANIS(board) ? 1 : 0);
case Telemetry: case Telemetry:
if (IS_2560(board) || IS_ARM(board) || id.contains("frsky") || id.contains("telemetrez")) 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 else
return 0; return 0;
case TelemetryBars: case TelemetryBars:
@ -642,7 +685,7 @@ int OpenTxFirmware::getCapability(Capability capability)
case SYMLimits: case SYMLimits:
return 1; return 1;
case OptrexDisplay: case OptrexDisplay:
return (board==BOARD_SKY9X ? true : false); return (board == BOARD_SKY9X ? true : false);
case HasVario: case HasVario:
return 1; return 1;
case HasVarioSink: case HasVarioSink:
@ -689,7 +732,7 @@ int OpenTxFirmware::getCapability(Capability capability)
else else
return 1; return 1;
case GetThrSwitch: case GetThrSwitch:
return (IS_TARANIS(board) ? SWITCH_SF1 : SWITCH_THR) ; return (IS_TARANIS(board) ? SWITCH_SF1 : SWITCH_THR);
case HasDisplayText: case HasDisplayText:
return IS_ARM(board) ? 1 : 0; return IS_ARM(board) ? 1 : 0;
case HasTopLcd: case HasTopLcd:
@ -749,33 +792,33 @@ int OpenTxFirmware::getCapability(Capability capability)
Firmware::Switch OpenTxFirmware::getSwitch(unsigned int index) Firmware::Switch OpenTxFirmware::getSwitch(unsigned int index)
{ {
if (board == BOARD_X7D) { if (board == BOARD_X7D) {
const Switch switches[] = { { SWITCH_3POS, "SA" }, const Switch switches[] = {{SWITCH_3POS, "SA"},
{ SWITCH_3POS, "SB" }, {SWITCH_3POS, "SB"},
{ SWITCH_3POS, "SC" }, {SWITCH_3POS, "SC"},
{ SWITCH_3POS, "SD" }, {SWITCH_3POS, "SD"},
{ SWITCH_2POS, "SF" }, {SWITCH_2POS, "SF"},
{ SWITCH_TOGGLE, "SH" } }; {SWITCH_TOGGLE, "SH"}};
return switches[index]; return switches[index];
} }
else if (IS_TARANIS(board) || board == BOARD_HORUS) { else if (IS_TARANIS(board) || board == BOARD_HORUS) {
const Switch switches[] = { { SWITCH_3POS, "SA" }, const Switch switches[] = {{SWITCH_3POS, "SA"},
{ SWITCH_3POS, "SB" }, {SWITCH_3POS, "SB"},
{ SWITCH_3POS, "SC" }, {SWITCH_3POS, "SC"},
{ SWITCH_3POS, "SD" }, {SWITCH_3POS, "SD"},
{ SWITCH_3POS, "SE" }, {SWITCH_3POS, "SE"},
{ SWITCH_2POS, "SF" }, {SWITCH_2POS, "SF"},
{ SWITCH_3POS, "SG" }, {SWITCH_3POS, "SG"},
{ SWITCH_TOGGLE, "SH" }, {SWITCH_TOGGLE, "SH"},
{ SWITCH_3POS, "SI" }, {SWITCH_3POS, "SI"},
{ SWITCH_3POS, "SJ" }, {SWITCH_3POS, "SJ"},
{ SWITCH_3POS, "SK" }, {SWITCH_3POS, "SK"},
{ SWITCH_3POS, "SL" }, {SWITCH_3POS, "SL"},
{ SWITCH_3POS, "SM" }, {SWITCH_3POS, "SM"},
{ SWITCH_3POS, "SN" }, {SWITCH_3POS, "SN"},
{ SWITCH_3POS, "SO" }, {SWITCH_3POS, "SO"},
{ SWITCH_3POS, "SP" }, {SWITCH_3POS, "SP"},
{ SWITCH_3POS, "SQ" }, {SWITCH_3POS, "SQ"},
{ SWITCH_3POS, "SR" } }; {SWITCH_3POS, "SR"}};
return switches[index]; return switches[index];
} }
else { else {
@ -804,10 +847,10 @@ bool OpenTxFirmware::isTelemetrySourceAvailable(int source)
{ {
if (IS_TARANIS(board) && (source == TELEMETRY_SOURCE_RSSI_TX)) if (IS_TARANIS(board) && (source == TELEMETRY_SOURCE_RSSI_TX))
return false; return false;
if (source == TELEMETRY_SOURCE_DTE) if (source == TELEMETRY_SOURCE_DTE)
return false; return false;
return true; return true;
} }
@ -836,7 +879,7 @@ int OpenTxFirmware::isAvailable(PulsesProtocol proto, int port)
case PULSES_PXX_XJT_X16: case PULSES_PXX_XJT_X16:
case PULSES_PXX_XJT_D8: case PULSES_PXX_XJT_D8:
case PULSES_PXX_XJT_LR12: case PULSES_PXX_XJT_LR12:
//case PULSES_PXX_DJT: // Unavailable for now //case PULSES_PXX_DJT: // Unavailable for now
case PULSES_LP45: case PULSES_LP45:
case PULSES_DSM2: case PULSES_DSM2:
case PULSES_DSMX: case PULSES_DSMX:
@ -894,7 +937,7 @@ int OpenTxFirmware::isAvailable(PulsesProtocol proto, int port)
case PULSES_DSMX: case PULSES_DSMX:
case PULSES_LP45: case PULSES_LP45:
case PULSES_DSM2: case PULSES_DSM2:
// case PULSES_PXX_DJT: // Unavailable for now // case PULSES_PXX_DJT: // Unavailable for now
case PULSES_PPM16: case PULSES_PPM16:
case PULSES_PPMSIM: case PULSES_PPMSIM:
return 1; return 1;
@ -905,13 +948,14 @@ int OpenTxFirmware::isAvailable(PulsesProtocol proto, int port)
} }
template<typename T, size_t SIZE> template<typename T, size_t SIZE>
size_t getSizeA(T (&)[SIZE]) { size_t getSizeA(T (&)[SIZE])
return SIZE; {
return SIZE;
} }
EepromLoadErrors OpenTxEepromInterface::checkVersion(unsigned int version) EepromLoadErrors OpenTxEepromInterface::checkVersion(unsigned int version)
{ {
switch(version) { switch (version) {
case 201: case 201:
// first version // first version
case 202: case 202:
@ -927,7 +971,7 @@ EepromLoadErrors OpenTxEepromInterface::checkVersion(unsigned int version)
// telemetry changes (bars) // telemetry changes (bars)
case 205: case 205:
// mixer changes (differential, negative curves)... // mixer changes (differential, negative curves)...
// case 206: // case 206:
case 207: case 207:
// V4: Rotary Encoders position in FlightModes // V4: Rotary Encoders position in FlightModes
case 208: case 208:
@ -961,7 +1005,7 @@ EepromLoadErrors OpenTxEepromInterface::checkVersion(unsigned int version)
default: default:
return NOT_OPENTX; return NOT_OPENTX;
} }
return ALL_OK; return ALL_OK;
} }
@ -970,7 +1014,7 @@ bool OpenTxEepromInterface::checkVariant(unsigned int version, unsigned int vari
if (board == BOARD_M128 && !(variant & M128_VARIANT)) { if (board == BOARD_M128 && !(variant & M128_VARIANT)) {
if (version == 212) { if (version == 212) {
uint8_t tmp[1000]; uint8_t tmp[1000];
for (int i=1; i<31; i++) { for (int i = 1; i < 31; i++) {
efile->openRd(i); efile->openRd(i);
int sz = efile->readRlc2(tmp, sizeof(tmp)); int sz = efile->readRlc2(tmp, sizeof(tmp));
if (sz == 849) { if (sz == 849) {
@ -994,23 +1038,44 @@ bool OpenTxEepromInterface::checkVariant(unsigned int version, unsigned int vari
return false; return false;
} }
} }
return true; 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<ModelData, OpenTxModelData>(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<NUM_ERRORS> errors; std::bitset<NUM_ERRORS> errors;
std::cout << "trying " << getName() << " backup import..."; std::cout << "trying " << getName() << " backup import...";
if (esize < 8 || memcmp(eeprom, "o9x", 3) != 0) { if (esize < 8 || memcmp(eeprom, "o9x", 3) != 0) {
std::cout << " no\n"; std::cout << " no\n";
errors.set(WRONG_SIZE); errors.set(WRONG_SIZE);
return errors.to_ulong(); return errors.to_ulong();
} }
BoardEnum backupBoard = (BoardEnum)-1; BoardEnum backupBoard = (BoardEnum) -1;
switch (eeprom[3]) { switch (eeprom[3]) {
case 0x33: case 0x33:
backupBoard = BOARD_TARANIS_X9D; backupBoard = BOARD_TARANIS_X9D;
@ -1026,20 +1091,20 @@ unsigned long OpenTxEepromInterface::loadBackup(RadioData & radioData, uint8_t *
errors.set(UNKNOWN_BOARD); errors.set(UNKNOWN_BOARD);
return errors.to_ulong(); return errors.to_ulong();
} }
if (backupBoard != board) { if (backupBoard != board) {
std::cout << " not right board\n"; std::cout << " not right board\n";
errors.set(WRONG_BOARD); errors.set(WRONG_BOARD);
return errors.to_ulong(); return errors.to_ulong();
} }
uint8_t version = eeprom[4]; uint8_t version = eeprom[4];
uint8_t bcktype = eeprom[5]; uint8_t bcktype = eeprom[5];
uint16_t size = ((uint16_t)eeprom[7] << 8) + eeprom[6]; uint16_t size = ((uint16_t) eeprom[7] << 8) + eeprom[6];
uint16_t variant = ((uint16_t)eeprom[9] << 8) + eeprom[8]; uint16_t variant = ((uint16_t) eeprom[9] << 8) + eeprom[8];
std::cout << " version " << (unsigned int)version << " "; std::cout << " version " << (unsigned int) version << " ";
EepromLoadErrors version_error = checkVersion(version); EepromLoadErrors version_error = checkVersion(version);
if (version_error == OLD_VERSION) { if (version_error == OLD_VERSION) {
errors.set(version_error); errors.set(version_error);
@ -1050,15 +1115,15 @@ unsigned long OpenTxEepromInterface::loadBackup(RadioData & radioData, uint8_t *
errors.set(version_error); errors.set(version_error);
return errors.to_ulong(); return errors.to_ulong();
} }
if (size > esize-8) { if (size > esize - 8) {
std::cout << " wrong size\n"; std::cout << " wrong size\n";
errors.set(WRONG_SIZE); errors.set(WRONG_SIZE);
return errors.to_ulong(); return errors.to_ulong();
} }
if (bcktype=='M') { if (bcktype == 'M') {
if (!loadModel(version, radioData.models[index], &eeprom[8], size, variant)) { if (!loadModelFromBackup(radioData.models[index], &eeprom[8], size, version, variant)) {
std::cout << " ko\n"; std::cout << " ko\n";
errors.set(UNKNOWN_ERROR); errors.set(UNKNOWN_ERROR);
return errors.to_ulong(); return errors.to_ulong();
@ -1069,7 +1134,7 @@ unsigned long OpenTxEepromInterface::loadBackup(RadioData & radioData, uint8_t *
errors.set(BACKUP_NOT_SUPPORTED); errors.set(BACKUP_NOT_SUPPORTED);
return errors.to_ulong(); return errors.to_ulong();
} }
std::cout << " ok\n"; std::cout << " ok\n";
errors.set(ALL_OK); errors.set(ALL_OK);
return errors.to_ulong(); return errors.to_ulong();
@ -1090,9 +1155,9 @@ QString OpenTxFirmware::getFirmwareUrl()
QByteArray data = QUrl::toPercentEncoding(id); QByteArray data = QUrl::toPercentEncoding(id);
if (IS_ARM(board)) 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 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; return url;
} }
@ -1114,7 +1179,9 @@ void addOpenTxCommonOptions(OpenTxFirmware * firmware)
{ {
firmware->addOption("ppmus", QObject::tr("Channel values displayed in us")); firmware->addOption("ppmus", QObject::tr("Channel values displayed in us"));
firmware->addOption("nooverridech", QObject::tr("No OverrideCH functions available")); 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); 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("noheli", QObject::tr("Disable HELI menu and cyclic mix support"));
firmware->addOption("nogvars", QObject::tr("Disable Global variables")); firmware->addOption("nogvars", QObject::tr("Disable Global variables"));
firmware->addOption("lua", QObject::tr("Support for Lua model scripts")); 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->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("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")); firmware->addOption("multimodule", QObject::tr("Support for the DIY-Multiprotocol-TX-Module"));
@ -1141,12 +1210,12 @@ void addOpenTxTaranisOptions(OpenTxFirmware * firmware)
void addOpenTxLcdOptions(OpenTxFirmware * firmware) void addOpenTxLcdOptions(OpenTxFirmware * firmware)
{ {
Option lcd_options[] = { Option lcd_options[] = {
{ "ST7565P", QObject::tr("ST7565P LCD or compatible") }, {"ST7565P", QObject::tr("ST7565P LCD or compatible")},
{ "ST7565R", QObject::tr("ST7565R LCD or compatible") }, {"ST7565R", QObject::tr("ST7565R LCD or compatible")},
{ "ERC12864FSF", QObject::tr("ERC12864FSF LCD") }, {"ERC12864FSF", QObject::tr("ERC12864FSF LCD")},
{ "ST7920", QObject::tr("ST7920 LCD") }, {"ST7920", QObject::tr("ST7920 LCD")},
{ "KS108", QObject::tr("KS108 LCD") }, {"KS108", QObject::tr("KS108 LCD")},
{ NULL } {NULL}
}; };
firmware->addOptions(lcd_options); firmware->addOptions(lcd_options);
} }
@ -1154,41 +1223,56 @@ void addOpenTxLcdOptions(OpenTxFirmware * firmware)
void registerOpenTxFirmwares() void registerOpenTxFirmwares()
{ {
OpenTxFirmware * firmware; 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 ext_options[] = {{"frsky", QObject::tr("Support for frsky telemetry mod"), FRSKY_VARIANT},
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 } }; {"telemetrez", QObject::tr("Support for telemetry easy board"), FRSKY_VARIANT},
Option nav_options[] = { { "rotenc", QObject::tr("Rotary Encoder use in menus navigation") }, { "potscroll", QObject::tr("Pots use in menus navigation") }, { NULL } }; {"jeti", QObject::tr("Support for jeti telemetry mod"), 0},
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 } }; {"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 */ /* FrSky Taranis X9D+ board */
firmware = new OpenTxFirmware("opentx-x9d+", QObject::tr("FrSky Taranis X9D+"), BOARD_TARANIS_X9DP); firmware = new OpenTxFirmware("opentx-x9d+", QObject::tr("FrSky Taranis X9D+"), BOARD_TARANIS_X9DP);
addOpenTxTaranisOptions(firmware); addOpenTxTaranisOptions(firmware);
firmwares.push_back(firmware); firmwares.push_back(firmware);
/* FrSky Taranis X9D board */ /* FrSky Taranis X9D board */
firmware = new OpenTxFirmware("opentx-x9d", QObject::tr("FrSky Taranis X9D"), BOARD_TARANIS_X9D); firmware = new OpenTxFirmware("opentx-x9d", QObject::tr("FrSky Taranis X9D"), BOARD_TARANIS_X9D);
firmware->addOption("haptic", QObject::tr("Haptic module installed")); firmware->addOption("haptic", QObject::tr("Haptic module installed"));
addOpenTxTaranisOptions(firmware); addOpenTxTaranisOptions(firmware);
firmwares.push_back(firmware); firmwares.push_back(firmware);
/* FrSky Taranis X9E board */ /* FrSky Taranis X9E board */
firmware = new OpenTxFirmware("opentx-x9e", QObject::tr("FrSky Taranis X9E"), BOARD_TARANIS_X9E); firmware = new OpenTxFirmware("opentx-x9e", QObject::tr("FrSky Taranis X9E"), BOARD_TARANIS_X9E);
firmware->addOption("shutdownconfirm", QObject::tr("Confirmation before radio shutdown")); firmware->addOption("shutdownconfirm", QObject::tr("Confirmation before radio shutdown"));
firmware->addOption("horussticks", QObject::tr("Horus gimbals installed (Hall sensors)")); firmware->addOption("horussticks", QObject::tr("Horus gimbals installed (Hall sensors)"));
addOpenTxTaranisOptions(firmware); addOpenTxTaranisOptions(firmware);
firmwares.push_back(firmware); firmwares.push_back(firmware);
/* FrSky X7D board */ /* FrSky X7D board */
firmware = new OpenTxFirmware("opentx-x7d", QObject::tr("FrSky X7D"), BOARD_X7D); firmware = new OpenTxFirmware("opentx-x7d", QObject::tr("FrSky X7D"), BOARD_X7D);
addOpenTxTaranisOptions(firmware); addOpenTxTaranisOptions(firmware);
firmwares.push_back(firmware); firmwares.push_back(firmware);
/* FrSky Horus board */ /* FrSky Horus board */
firmware = new OpenTxFirmware("opentx-horus", QObject::tr("FrSky Horus"), BOARD_HORUS); firmware = new OpenTxFirmware("opentx-horus", QObject::tr("FrSky Horus"), BOARD_HORUS);
addOpenTxFrskyOptions(firmware); addOpenTxFrskyOptions(firmware);
firmware->addOption("pcbdev", QObject::tr("Use ONLY with first DEV pcb version")); firmware->addOption("pcbdev", QObject::tr("Use ONLY with first DEV pcb version"));
firmwares.push_back(firmware); firmwares.push_back(firmware);
/* 9XR-Pro */ /* 9XR-Pro */
firmware = new OpenTxFirmware("opentx-9xrpro", QObject::tr("Turnigy 9XR-PRO"), BOARD_9XRPRO); firmware = new OpenTxFirmware("opentx-9xrpro", QObject::tr("Turnigy 9XR-PRO"), BOARD_9XRPRO);
firmware->addOption("heli", QObject::tr("Enable HELI menu and cyclic mix support")); 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")); firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
addOpenTxCommonOptions(firmware); addOpenTxCommonOptions(firmware);
firmwares.push_back(firmware); firmwares.push_back(firmware);
/* 9XR board with M128 chip */ /* 9XR board with M128 chip */
firmware = new OpenTxFirmware("opentx-9xr128", QObject::tr("Turnigy 9XR with m128 chip"), BOARD_M128); firmware = new OpenTxFirmware("opentx-9xr128", QObject::tr("Turnigy 9XR with m128 chip"), BOARD_M128);
firmware->addOptions(extr_options); firmware->addOptions(extr_options);
@ -1237,7 +1321,7 @@ void registerOpenTxFirmwares()
firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font")); firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
addOpenTxCommonOptions(firmware); addOpenTxCommonOptions(firmware);
firmwares.push_back(firmware); firmwares.push_back(firmware);
/* 9XR board */ /* 9XR board */
firmware = new OpenTxFirmware("opentx-9xr", QObject::tr("Turnigy 9XR"), BOARD_STOCK); firmware = new OpenTxFirmware("opentx-9xr", QObject::tr("Turnigy 9XR"), BOARD_STOCK);
firmware->addOptions(extr_options); firmware->addOptions(extr_options);
@ -1271,7 +1355,7 @@ void registerOpenTxFirmwares()
firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font")); firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
addOpenTxCommonOptions(firmware); addOpenTxCommonOptions(firmware);
firmwares.push_back(firmware); firmwares.push_back(firmware);
/* 9x board */ /* 9x board */
firmware = new OpenTxFirmware("opentx-9x", QObject::tr("9X with stock board"), BOARD_STOCK); firmware = new OpenTxFirmware("opentx-9x", QObject::tr("9X with stock board"), BOARD_STOCK);
firmware->addOptions(ext_options); firmware->addOptions(ext_options);
@ -1308,7 +1392,7 @@ void registerOpenTxFirmwares()
firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font")); firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
addOpenTxCommonOptions(firmware); addOpenTxCommonOptions(firmware);
firmwares.push_back(firmware); firmwares.push_back(firmware);
/* 9x board with M128 chip */ /* 9x board with M128 chip */
firmware = new OpenTxFirmware("opentx-9x128", QObject::tr("9X with stock board and m128 chip"), BOARD_M128); firmware = new OpenTxFirmware("opentx-9x128", QObject::tr("9X with stock board and m128 chip"), BOARD_M128);
firmware->addOptions(ext_options); firmware->addOptions(ext_options);
@ -1339,7 +1423,7 @@ void registerOpenTxFirmwares()
firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font")); firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
addOpenTxCommonOptions(firmware); addOpenTxCommonOptions(firmware);
firmwares.push_back(firmware); firmwares.push_back(firmware);
/* ar9x board */ /* ar9x board */
firmware = new OpenTxFirmware("opentx-ar9x", QObject::tr("9X with AR9X board"), BOARD_AR9X); 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")); 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")); // firmware->addOption("volume", QObject::tr("i2c volume control added"));
addOpenTxCommonOptions(firmware); addOpenTxCommonOptions(firmware);
firmwares.push_back(firmware); firmwares.push_back(firmware);
/* Sky9x board */ /* Sky9x board */
firmware = new OpenTxFirmware("opentx-sky9x", QObject::tr("9X with Sky9x board"), BOARD_SKY9X); 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")); 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")); firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
addOpenTxCommonOptions(firmware); addOpenTxCommonOptions(firmware);
firmwares.push_back(firmware); firmwares.push_back(firmware);
/* Gruvin9x board */ /* Gruvin9x board */
firmware = new OpenTxFirmware("opentx-gruvin9x", QObject::tr("9X with Gruvin9x board"), BOARD_GRUVIN9X); 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")); 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")); firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
addOpenTxCommonOptions(firmware); addOpenTxCommonOptions(firmware);
firmwares.push_back(firmware); firmwares.push_back(firmware);
/* MEGA2560 board */ /* MEGA2560 board */
firmware = new OpenTxFirmware("opentx-mega2560", QObject::tr("DIY MEGA2560 radio"), BOARD_MEGA2560); firmware = new OpenTxFirmware("opentx-mega2560", QObject::tr("DIY MEGA2560 radio"), BOARD_MEGA2560);
addOpenTxLcdOptions(firmware); addOpenTxLcdOptions(firmware);
@ -1440,14 +1524,14 @@ void registerOpenTxFirmwares()
firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font")); firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
addOpenTxCommonOptions(firmware); addOpenTxCommonOptions(firmware);
firmwares.push_back(firmware); firmwares.push_back(firmware);
default_firmware_variant = GetFirmware("opentx-x9d+"); default_firmware_variant = GetFirmware("opentx-x9d+");
current_firmware_variant = default_firmware_variant; current_firmware_variant = default_firmware_variant;
} }
void unregisterOpenTxFirmwares() void unregisterOpenTxFirmwares()
{ {
foreach (Firmware * f, firmwares) { foreach (Firmware * f, firmwares) {
delete f; delete f;
} }
} }

View file

@ -37,21 +37,23 @@ class OpenTxEepromInterface : public EEPROMInterface
virtual const int getMaxModels(); virtual const int getMaxModels();
virtual unsigned long load(RadioData &, const uint8_t *eeprom, int size); virtual unsigned long load(RadioData &, const uint8_t * eeprom, int size);
virtual unsigned long loadBackup(RadioData &, uint8_t *eeprom, int esize, int index); 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 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 save(uint8_t * eeprom, RadioData & radioData, uint8_t version=0, uint32_t variant=0);
virtual int getSize(const ModelData &); virtual int getSize(const ModelData &);
virtual int getSize(const GeneralSettings &); virtual int getSize(const GeneralSettings &);
virtual int loadFile(RadioData & radioData, const QString & filename);
virtual int saveFile(const RadioData & radioData, const QString & filename);
protected: protected:
@ -61,21 +63,33 @@ class OpenTxEepromInterface : public EEPROMInterface
bool checkVariant(unsigned int version, unsigned int variant); bool checkVariant(unsigned int version, unsigned int variant);
bool loadModel(uint8_t version, ModelData &model, uint8_t *data, int index, unsigned int variant); template <class T, class M>
bool loadFromByteArray(T & dest, const QByteArray & data, uint8_t version, uint32_t variant=0);
template <class T, class M>
bool loadFromByteArray(T & dest, const QByteArray & data);
template <class T, class M>
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 <class T> template <class T>
bool saveModel(unsigned int index, ModelData & model, uint8_t version, uint32_t variant); bool saveModel(unsigned int index, ModelData & model, uint8_t version, uint32_t variant);
bool loadRadioSettings(GeneralSettings & settings, uint8_t version);
template <class T> template <class T>
bool saveRadioSettings(GeneralSettings & settings, BoardEnum board, uint8_t version, uint32_t variant); 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: public:
OpenTxFirmware(const QString & id, OpenTxFirmware * parent): OpenTxFirmware(const QString & id, OpenTxFirmware * parent):
Firmware(parent, id, parent->getName(), parent->getBoard(), parent->eepromInterface) Firmware(parent, id, parent->getName(), parent->getBoard(), parent->eepromInterface)

View file

@ -822,9 +822,7 @@ void startSimulation(QWidget * parent, RadioData & radioData, int modelIdx)
SimulatorDialog * dialog; SimulatorDialog * dialog;
if (board == BOARD_HORUS) { if (board == BOARD_HORUS) {
dialog = new SimulatorDialogHorus(parent, simulator, flags); dialog = new SimulatorDialogHorus(parent, simulator, flags);
StorageSdcard storage; GetEepromInterface()->saveFile(*simuData, g.profile[g.id()].sdPath());
QString sdPath = g.profile[g.id()].sdPath();
storage.write(sdPath);
dialog->start(NULL); dialog->start(NULL);
} }
else if (board == BOARD_FLAMENCO) { else if (board == BOARD_FLAMENCO) {

View file

@ -343,51 +343,17 @@ bool MdiChild::loadFile(const QString & fileName, bool resetCurrentFile)
return true; return true;
} }
else if (fileType == FILE_TYPE_OTX) { //read zip archive else if (fileType == FILE_TYPE_OTX) { //read zip archive
if (loadOtxFile(fileName)) { if (!GetEepromInterface()->loadFile(radioData, fileName)) {
ui->modelsList->refreshList(); ui->modelsList->refreshList();
if (resetCurrentFile) if (resetCurrentFile)
setCurrentFile(fileName); setCurrentFile(fileName);
return true;
} }
} }
return false; 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<QString> models = storage.getModelsFileNames();
qDebug() << "We have" << models.size() << "models:";
#if 0
foreach(QString filename, models) {
QList<ModelFile>::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<ModelFile>::iterator i = storage.models.begin(); i != storage.models.end(); ++i, ++index) {
GetEepromInterface()->loadModel(radioData.models[index], i->data);
}
return true;
}
bool MdiChild::save() bool MdiChild::save()
{ {
if (isUntitled) { if (isUntitled) {

View file

@ -163,6 +163,7 @@ void StorageSdcard::writeFile(const QByteArray & data, const QString & path)
QFile file(path); QFile file(path);
if (!file.open(QFile::WriteOnly)) { if (!file.open(QFile::WriteOnly)) {
lastErrorMessage = QObject::tr("Error opening file %1:\n%2.").arg(path).arg(file.errorString()); lastErrorMessage = QObject::tr("Error opening file %1:\n%2.").arg(path).arg(file.errorString());
qDebug() << "File" << path << "write error";
throw StorageSdcardWriteFileError(); throw StorageSdcardWriteFileError();
} }
file.write(data.data(), data.size()); file.write(data.data(), data.size());
@ -176,12 +177,12 @@ int StorageSdcard::writeSdcard(const QString & path)
QDir dir(path); QDir dir(path);
dir.mkdir("RADIO"); dir.mkdir("RADIO");
writeFile(radio, path + "/RADIO/radio.bin"); writeFile(radio, path + "/RADIO/radio.bin");
writeFile(modelList, path + "RADIO/models.txt"); writeFile(modelList, path + "/RADIO/models.txt");
dir.mkdir("MODELS"); dir.mkdir("MODELS");
for (QList<ModelFile>::const_iterator i = models.begin(); i != models.end(); ++i) { for (QList<ModelFile>::const_iterator i = models.begin(); i != models.end(); ++i) {
qDebug() << "writing" << i->filename; qDebug() << "writing" << i->filename;
writeFile(i->data, path + "MODELS/" + i->filename); writeFile(i->data, path + "/MODELS/" + i->filename);
} }
} }
catch (StorageSdcardWriteFileError) { catch (StorageSdcardWriteFileError) {

View file

@ -913,8 +913,8 @@ PACK(struct TrainerData {
#elif defined(PCBFLAMENCO) #elif defined(PCBFLAMENCO)
#define EXTRA_GENERAL_FIELDS \ #define EXTRA_GENERAL_FIELDS \
EXTRA_GENERAL_FIELDS_ARM \ EXTRA_GENERAL_FIELDS_ARM \
uint8_t serial2Mode:6; \ uint8_t serial2Mode:4; \
uint8_t spare:2; \ uint8_t spare:4; \
uint32_t switchConfig; \ uint32_t switchConfig; \
uint8_t potsType; /*two bits for every pot*/\ uint8_t potsType; /*two bits for every pot*/\
char switchNames[NUM_SWITCHES][LEN_SWITCH_NAME]; \ char switchNames[NUM_SWITCHES][LEN_SWITCH_NAME]; \