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_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()

View file

@ -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];
@ -1413,7 +1414,7 @@ class EEPROMInterface
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; }
@ -1431,6 +1432,10 @@ class EEPROMInterface
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;

View file

@ -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));
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,12 +3648,16 @@ 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>());
}
if (!IS_HORUS(board))
internalField.Append(new UnsignedField<8>(generalData.backlightColor));
}
@ -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++) {
internalField.Append(new UnsignedField<2>(generalData.switchConfig[i]));
}

View file

@ -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"
@ -126,83 +127,74 @@ 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;
}
}
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;
}
template <class T, class M>
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)
bool
OpenTxEepromInterface::saveRadioSettings(GeneralSettings &settings, BoardEnum board, uint8_t version, uint32_t variant)
{
T open9xSettings(settings, board, version, variant);
// open9xSettings.Dump();
@ -230,6 +222,62 @@ unsigned long OpenTxEepromInterface::loadxml(RadioData &radioData, QDomDocument
return errors.to_ulong();
}
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...";
@ -254,7 +302,8 @@ unsigned long OpenTxEepromInterface::load(RadioData & radioData, const uint8_t *
errors.set(WARNING_WRONG_FIRMWARE);
size = 2048;
}
} else {
}
else {
std::cout << " wrong size (" << size << "/" << getEEpromSize() << ")\n";
errors.set(WRONG_SIZE);
return errors.to_ulong();
@ -282,13 +331,14 @@ unsigned long OpenTxEepromInterface::load(RadioData & radioData, const uint8_t *
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();
@ -296,45 +346,38 @@ unsigned long OpenTxEepromInterface::load(RadioData & radioData, const uint8_t *
std::cout << " variant " << radioData.generalSettings.variant;
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";
errors.set(UNKNOWN_ERROR);
return errors.to_ulong();
}
}
std::cout << " ok\n";
errors.set(ALL_OK);
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)
{
EEPROMWarnings.clear();
if (version == 0) {
switch (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;
}
version = getLastDataVersion(board);
}
int size = getEEpromSize();
@ -905,7 +948,8 @@ int OpenTxFirmware::isAvailable(PulsesProtocol proto, int port)
}
template<typename T, size_t SIZE>
size_t getSizeA(T (&)[SIZE]) {
size_t getSizeA(T (&)[SIZE])
{
return SIZE;
}
@ -998,7 +1042,28 @@ bool OpenTxEepromInterface::checkVariant(unsigned int version, unsigned int vari
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;
@ -1058,7 +1123,7 @@ unsigned long OpenTxEepromInterface::loadBackup(RadioData & radioData, uint8_t *
}
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";
errors.set(UNKNOWN_ERROR);
return errors.to_ulong();
@ -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"));
@ -1155,10 +1224,25 @@ 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);

View file

@ -39,20 +39,22 @@ class OpenTxEepromInterface : public EEPROMInterface
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 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:
const char * getName();
@ -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 <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>
bool saveModel(unsigned int index, ModelData & model, uint8_t version, uint32_t variant);
bool loadRadioSettings(GeneralSettings & settings, uint8_t version);
template <class T>
bool saveRadioSettings(GeneralSettings & settings, BoardEnum board, uint8_t version, uint32_t variant);
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)

View file

@ -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) {

View file

@ -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<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()
{
if (isUntitled) {

View file

@ -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<ModelFile>::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) {

View file

@ -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]; \