5 * th9x - http://code.google.com/p/th9x
6 * er9x - http://code.google.com/p/er9x
7 * gruvin9x - http://code.google.com/p/gruvin9x
9 * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
21 #include "opentxinterface.h"
22 #include "opentxeeprom.h"
26 #include <QMessageBox>
29 #include <companion/src/storage/storage.h>
31 using namespace Board
;
33 const char * const OPENTX_FIRMWARE_DOWNLOAD_URL
[] = {
34 "https://downloads.open-tx.org/2.2/release/firmware",
35 "https://downloads.open-tx.org/2.2/rc/firmware",
36 "https://downloads.open-tx.org/2.2/nightlies/firmware"
39 #define FILE_TYP_GENERAL 1
40 #define FILE_TYP_MODEL 2
42 /// fileId of general file
43 #define FILE_GENERAL 0
44 /// convert model number 0..MAX_MODELS-1 int fileId
45 #define FILE_MODEL(n) (1+n)
47 template<typename T
, size_t N
>
49 size_t SizeOfArray(T(&)[N
])
54 OpenTxEepromInterface::OpenTxEepromInterface(OpenTxFirmware
* firmware
):
55 EEPROMInterface(firmware
->getBoard()),
61 OpenTxEepromInterface::~OpenTxEepromInterface()
66 const char * OpenTxEepromInterface::getName()
70 return "OpenTX for 9X board";
72 return "OpenTX for M128 / 9X board";
74 return "OpenTX for MEGA2560 board";
76 return "OpenTX for Gruvin9x board / 9X";
77 case BOARD_TARANIS_X9D
:
78 return "OpenTX for FrSky Taranis X9D";
79 case BOARD_TARANIS_X9DP
:
80 return "OpenTX for FrSky Taranis X9D+";
81 case BOARD_TARANIS_X9E
:
82 return "OpenTX for FrSky Taranis X9E";
83 case BOARD_TARANIS_X7
:
84 return "OpenTX for FrSky Taranis X7";
86 return "OpenTX for Sky9x board / 9X";
88 return "OpenTX for 9XR-PRO";
90 return "OpenTX for ar9x board / 9X";
92 return "OpenTX for Flamenco experimental";
94 return "OpenTX for FrSky Horus";
96 return "OpenTX for FrSky X10";
98 return "OpenTX for an unknown board";
102 bool OpenTxEepromInterface::loadRadioSettingsFromRLE(GeneralSettings
& settings
, RleFile
* rleFile
, uint8_t version
)
104 QByteArray
data(sizeof(settings
), 0); // GeneralSettings should be always bigger than the EEPROM struct
105 OpenTxGeneralData
open9xSettings(settings
, board
, version
);
106 efile
->openRd(FILE_GENERAL
);
107 int size
= rleFile
->readRlc2((uint8_t *)data
.data(), data
.size());
109 open9xSettings
.Import(data
);
110 return checkVariant(settings
.version
, settings
.variant
);
113 qWarning() << " error when loading general settings";
118 bool OpenTxEepromInterface::loadModelFromRLE(ModelData
& model
, RleFile
* rleFile
, unsigned int index
, uint8_t version
, uint32_t variant
)
120 QByteArray
data(sizeof(model
), 0); // ModelData should be always bigger than the EEPROM struct
121 rleFile
->openRd(FILE_MODEL(index
));
122 int size
= rleFile
->readRlc2((uint8_t *)data
.data(), data
.size());
124 if (loadFromByteArray
<ModelData
, OpenTxModelData
>(model
, data
, version
, variant
)) {
134 template <class T
, class M
>
135 bool OpenTxEepromInterface::saveToByteArray(const T
& src
, QByteArray
& data
, uint8_t version
)
138 version
= getLastDataVersion(getBoard());
141 T
srcCopy(src
); // work on a copy of radio data, because Export() will modify it!
142 M
manager(srcCopy
, board
, version
, 0);
146 *((uint32_t*)&data
.data()[0]) = StorageFormat::getFourCC(board
);
149 *((uint16_t*)&data
.data()[6]) = raw
.size();
154 template <class T
, class M
>
155 bool OpenTxEepromInterface::loadFromByteArray(T
& dest
, const QByteArray
& data
, uint8_t version
, uint32_t variant
)
157 M
manager(dest
, board
, version
, variant
);
158 if (manager
.Import(data
) != 0) {
161 // manager.Dump(); // Dumps the structure so that it's easy to check with firmware datastructs.h
165 template <class T
, class M
>
166 bool OpenTxEepromInterface::loadFromByteArray(T
& dest
, const QByteArray
& data
)
168 uint32_t fourcc
= *((uint32_t*)&data
.data()[0]);
169 if (StorageFormat::getFourCC(board
) != fourcc
) {
170 if (IS_HORUS(board
) && fourcc
== 0x3178396F) {
171 qDebug() << QString().sprintf("%s: Deprecated fourcc used %x vs %x", getName(), fourcc
, StorageFormat::getFourCC(board
));
174 qDebug() << QString().sprintf("%s: Wrong fourcc %x vs %x", getName(), fourcc
, StorageFormat::getFourCC(board
));
178 qDebug() << QString().sprintf("%s: OK", getName());
179 uint8_t version
= data
[4];
180 QByteArray raw
= data
.right(data
.size() - 8);
181 return loadFromByteArray
<T
, M
>(dest
, raw
, version
);
184 unsigned long OpenTxEepromInterface::load(RadioData
&radioData
, const uint8_t * eeprom
, int size
)
186 QDebug dbg
= qDebug();
187 dbg
.setAutoInsertSpaces(false);
188 dbg
<< "trying " << getName() << " import...";
190 std::bitset
<NUM_ERRORS
> errors
;
192 if (size
!= Boards::getEEpromSize(board
)) {
195 for (int i
= 2048; i
< 4096; i
++) {
196 if (eeprom
[i
] != 255) {
201 dbg
<< " wrong size (" << size
<< ")";
202 errors
.set(WRONG_SIZE
);
203 return errors
.to_ulong();
206 errors
.set(HAS_WARNINGS
);
207 errors
.set(WARNING_WRONG_FIRMWARE
);
212 dbg
<< " wrong size (" << size
<< "/" << Boards::getEEpromSize(board
) << ")";
213 errors
.set(WRONG_SIZE
);
214 return errors
.to_ulong();
218 if (!efile
->EeFsOpen((uint8_t *) eeprom
, size
, board
)) {
219 dbg
<< " wrong file system";
220 errors
.set(WRONG_FILE_SYSTEM
);
221 return errors
.to_ulong();
224 efile
->openRd(FILE_GENERAL
);
227 if (efile
->readRlc2(&version
, 1) != 1) {
229 errors
.set(UNKNOWN_ERROR
);
230 return errors
.to_ulong();
233 dbg
<< " version " << (unsigned int) version
;
235 EepromLoadErrors version_error
= checkVersion(version
);
236 if (version_error
== OLD_VERSION
) {
237 errors
.set(version_error
);
238 errors
.set(HAS_WARNINGS
);
239 ShowEepromWarnings(NULL
, QObject::tr("Warning"), errors
.to_ulong());
241 else if (version_error
== NOT_OPENTX
) {
242 dbg
<< " not open9x";
243 errors
.set(version_error
);
244 return errors
.to_ulong();
247 if (!loadRadioSettingsFromRLE(radioData
.generalSettings
, efile
, version
)) {
249 errors
.set(UNKNOWN_ERROR
);
250 return errors
.to_ulong();
253 dbg
<< " variant " << radioData
.generalSettings
.variant
;
254 if (getCurrentFirmware()->getCapability(Models
) == 0) {
255 radioData
.models
.resize(firmware
->getCapability(Models
));
257 for (int i
= 0; i
< firmware
->getCapability(Models
); i
++) {
258 if (i
< (int)radioData
.models
.size() && !loadModelFromRLE(radioData
.models
[i
], efile
, i
, version
, radioData
.generalSettings
.variant
)) {
260 errors
.set(UNKNOWN_ERROR
);
261 if (getCurrentFirmware()->getCapability(Models
) == 0) {
262 radioData
.models
.resize(i
);
264 return errors
.to_ulong();
269 return errors
.to_ulong();
272 uint8_t OpenTxEepromInterface::getLastDataVersion(Board::Type board
)
286 void OpenTxEepromInterface::showErrors(const QString
& title
, const QStringList
& errors
)
289 if (errors
.empty()) {
290 msg
= QObject::tr("Unknown error");
293 int noErrorsToDisplay
= std::min((int)errors
.size(), 10);
294 for (int n
= 0; n
< noErrorsToDisplay
; n
++) {
295 msg
+= " -" + errors
.at(n
) + "\n";
297 if (noErrorsToDisplay
< errors
.size()) {
298 msg
+= QObject::tr(" ... plus %1 errors").arg(errors
.size() - noErrorsToDisplay
) + "\n" + msg
;
302 QMessageBox::warning(NULL
,
303 QObject::tr("Error"),
307 int OpenTxEepromInterface::save(uint8_t * eeprom
, const RadioData
& radioData
, uint8_t version
, uint32_t variant
)
309 // TODO QMessageBox::warning should not be called here
312 version
= getLastDataVersion(board
);
315 int size
= Boards::getEEpromSize(board
);
317 efile
->EeFsCreate(eeprom
, size
, board
, version
);
319 if (board
== BOARD_M128
) {
320 variant
|= M128_VARIANT
;
322 else if (IS_TARANIS_X9E(board
)) {
323 variant
|= TARANIS_X9E_VARIANT
;
325 else if (IS_TARANIS_X7(board
)) {
326 variant
|= TARANIS_X7_VARIANT
;
329 OpenTxGeneralData
generator((GeneralSettings
&)radioData
.generalSettings
, board
, version
, variant
);
332 generator
.Export(data
);
333 int sz
= efile
->writeRlc2(FILE_GENERAL
, FILE_TYP_GENERAL
, (const uint8_t *)data
.constData(), data
.size());
334 if (sz
== 0 || generator
.errors().count() > 0) {
335 showErrors(QObject::tr("Cannot write radio settings"), generator
.errors());
339 for (int i
= 0; i
< getCurrentFirmware()->getCapability(Models
); i
++) {
340 if (!radioData
.models
[i
].isEmpty()) {
341 OpenTxModelData
generator((ModelData
&)radioData
.models
[i
], board
, version
, variant
);
344 generator
.Export(data
);
345 int sz
= efile
->writeRlc2(FILE_MODEL(i
), FILE_TYP_MODEL
, (const uint8_t *)data
.constData(), data
.size());
346 if (sz
== 0 || generator
.errors().count() > 0) {
347 showErrors(QObject::tr("Cannot write model %1").arg(radioData
.models
[i
].name
), generator
.errors());
356 int OpenTxEepromInterface::getSize(const ModelData
&model
)
364 QByteArray
tmp(Boards::getEEpromSize(Board::BOARD_UNKNOWN
), 0);
365 efile
->EeFsCreate((uint8_t *) tmp
.data(), Boards::getEEpromSize(Board::BOARD_UNKNOWN
), board
, 255/*version max*/);
367 OpenTxModelData
open9xModel((ModelData
&) model
, board
, 255/*version max*/, getCurrentFirmware()->getVariantNumber());
370 open9xModel
.Export(eeprom
);
371 int sz
= efile
->writeRlc2(0, FILE_TYP_MODEL
, (const uint8_t *) eeprom
.constData(), eeprom
.size());
372 if (sz
!= eeprom
.size()) {
375 return efile
->size(0);
378 int OpenTxEepromInterface::getSize(const GeneralSettings
&settings
)
383 QByteArray
tmp(Boards::getEEpromSize(Board::BOARD_UNKNOWN
), 0);
384 efile
->EeFsCreate((uint8_t *) tmp
.data(), Boards::getEEpromSize(Board::BOARD_UNKNOWN
), board
, 255);
386 OpenTxGeneralData
open9xGeneral((GeneralSettings
&) settings
, board
, 255, getCurrentFirmware()->getVariantNumber());
387 // open9xGeneral.Dump();
390 open9xGeneral
.Export(eeprom
);
391 int sz
= efile
->writeRlc2(0, FILE_TYP_GENERAL
, (const uint8_t *) eeprom
.constData(), eeprom
.size());
392 if (sz
!= eeprom
.size()) {
395 return efile
->size(0);
398 Firmware
* OpenTxFirmware::getFirmwareVariant(const QString
&id
)
403 else if (id
.contains(getId() + "-") || (!id
.contains("-") && id
.contains(getId()))) {
404 Firmware
* result
= new OpenTxFirmware(id
, this);
405 // TODO result.variant = firmware->getVariant(id);
413 int OpenTxFirmware::getCapability(::Capability capability
)
415 switch (capability
) {
419 else if (IS_ARM(board
))
421 else if (board
== BOARD_M128
)
423 else if (IS_2560(board
))
431 return id
.contains("imperial") ? 1 : 0;
433 return (board
== BOARD_TARANIS_X9D
|| IS_TARANIS_PLUS(board
) || IS_HORUS(board
));
435 return (!IS_ARM(board
));
438 case HasGeneralUnits
:
443 case HasNegAndSwitches
:
444 return IS_ARM(board
);
452 else if (IS_2560(board
))
456 case FlightModesHaveFades
:
459 if (IS_HORUS_OR_TARANIS(board
))
460 return id
.contains("noheli") ? 0 : 1;
462 return id
.contains("heli") ? 1 : 0;
464 if (IS_HORUS_OR_TARANIS(board
))
465 return id
.contains("nogvars") ? 0 : 9;
466 else if (id
.contains("gvars"))
467 return IS_ARM(board
) ? 9 : 5;
471 return (IS_HORUS(board
) ? 15 : (HAS_LARGE_LCD(board
) ? 12 : 10));
472 case FlightModesName
:
473 return (IS_HORUS_OR_TARANIS(board
) ? 10 : 6);
475 return (IS_9X(board
) ? 0 : 3);
480 case GvarsFlightModes
:
481 return ((IS_ARM(board
) || IS_2560(board
)) ? 1 : 0);
483 return (IS_ARM(board
) ? 64 : 32);
485 return (IS_ARM(board
) ? 500 : 245);
487 return (IS_ARM(board
) ? 3 : 2);
489 if (HAS_LARGE_LCD(board
))
491 else if (IS_ARM(board
))
496 return (IS_2560(board
) || IS_ARM(board
));
497 case CustomFunctions
:
500 else if (IS_2560(board
) || board
== BOARD_M128
)
504 case SafetyChannelCustomFunction
:
505 return id
.contains("nooverridech") ? 0 : 1;
506 case LogicalSwitches
:
511 case CustomAndSwitches
:
513 return getCapability(LogicalSwitches
);
515 return 15/*4bits*/- 9/*sw positions*/;
516 case LogicalSwitchesExt
:
517 return (IS_ARM(board
) ? true : false);
519 if (board
== BOARD_GRUVIN9X
)
521 else if (IS_SKY9X(board
))
526 return (IS_ARM(board
) ? 32 : 16);
528 return (IS_ARM(board
) ? 512 : 104);
529 case VoicesAsNumbers
:
530 return (IS_ARM(board
) ? 0 : 1);
531 case VoicesMaxLength
:
532 return (IS_ARM(board
) ? (IS_TARANIS_X9(board
) ? 8 : 6) : 0);
534 return (IS_ARM(board
) ? 1 : 0);
538 return (IS_2560(board
) || IS_SKY9X(board
) || IS_TARANIS_PLUS(board
) || IS_TARANIS_X7(board
) || IS_TARANIS_X9E(board
) || IS_HORUS(board
) || id
.contains("haptic"));
539 case ModelTrainerEnable
:
540 if (IS_HORUS_OR_TARANIS(board
))
545 return (IS_ARM(board
) ? 23 : 7);
547 if (IS_TARANIS_X7(board
))
552 if (IS_TARANIS_X9(board
))
557 return (IS_ARM(board
) ? 1 : 0);
562 case ExtendedTrimsRange
:
567 return (HAS_LARGE_LCD(board
) ? 32 : (IS_ARM(board
) ? 16 : 8));
569 return (IS_ARM(board
) ? (IS_TARANIS_X9(board
) ? 8 : 6) : false);
571 return (IS_ARM(board
) ? (IS_TARANIS_X9(board
) ? 8 : 6) : false);
573 return (IS_HORUS_OR_TARANIS(board
) ? false : true);
575 return (IS_ARM(board
) ? (HAS_LARGE_LCD(board
) ? 6 : 4) : 0);
577 return (IS_ARM(board
) ? 1 : 0);
579 if (IS_2560(board
) || IS_ARM(board
) || id
.contains("frsky") || id
.contains("telemetrez"))
580 return TM_HASTELEMETRY
| TM_HASOFFSET
| TM_HASWSHH
;
585 case TelemetryCustomScreens
:
589 return IS_ARM(board
) ? 4 : 2;
590 case TelemetryCustomScreensFieldsPerLine
:
591 return HAS_LARGE_LCD(board
) ? 3 : 2;
592 case NoTelemetryProtocol
:
593 return IS_HORUS_OR_TARANIS(board
) ? 1 : 0;
596 case TelemetryMaxMultiplier
:
597 return (IS_ARM(board
) ? 32 : 8);
599 return (IS_HORUS_OR_TARANIS(board
) ? 500 : (id
.contains("ppmca") ? 125 : 0));
600 case PPMUnitMicroseconds
:
601 return id
.contains("ppmus") ? 1 : 0;
605 return (board
== BOARD_SKY9X
? true : false);
609 return ((IS_2560(board
) || IS_ARM(board
)) ? true : false);
611 return (IS_ARM(board
) ? 32 : 0);
613 return (IS_ARM(board
) ? 2 : 1);
615 return (IS_ARM(board
) ? true : false);
616 case HastxCurrentCalibration
:
617 return (IS_SKY9X(board
) ? true : false);
619 return (IS_ARM(board
) ? true : false);
621 return (IS_ARM(board
) ? true : false);
625 return (IS_ARM(board
) ? 10 : 2);
627 return (IS_ARM(board
) ? 250 : 15);
631 return ((IS_2560(board
) || IS_ARM(board
)) ? true : false);
635 else if (IS_TARANIS_X7(board
))
637 else if (IS_TARANIS(board
))
649 else if (IS_TARANIS_X7(board
))
651 else if (IS_TARANIS(board
))
656 return (IS_HORUS_OR_TARANIS(board
) ? SWITCH_SF1
: SWITCH_THR
);
658 return IS_ARM(board
) ? 1 : 0;
660 return IS_TARANIS_X9E(board
) ? 1 : 0;
661 case GlobalFunctions
:
662 return IS_ARM(board
) ? 64 : 0;
664 return IS_ARM(board
) ? 32 : 0;
666 return HAS_LARGE_LCD(board
) ? 4 : 3;
668 return IS_ARM(board
) ? 16 : 8;
670 return IS_ARM(board
) || IS_2560(board
) ? 1 : 0;
672 return IS_HORUS_OR_TARANIS(board
) && id
.contains("lua") ? 7 : 0;
673 case LuaInputsPerScript
:
674 return IS_HORUS_OR_TARANIS(board
) ? 10 : 0;
675 case LuaOutputsPerScript
:
676 return IS_HORUS_OR_TARANIS(board
) ? 6 : 0;
679 return IS_ARM(board
);
681 return (IS_STOCK(board
) ? false : true);
682 case HasMahPersistent
:
683 return (IS_ARM(board
) ? true : false);
685 return IS_HORUS_OR_TARANIS(board
) ? 3 : 0;
686 case MultiposPotsPositions
:
687 return IS_HORUS_OR_TARANIS(board
) ? 6 : 0;
688 case SimulatorVariant
:
689 if (board
== BOARD_STOCK
)
690 return SIMU_STOCK_VARIANTS
;
691 else if (board
== BOARD_M128
)
692 return SIMU_M128_VARIANTS
;
693 else if (IS_TARANIS_X9E(board
))
694 return TARANIS_X9E_VARIANT
;
695 else if (IS_TARANIS_X7(board
))
696 return TARANIS_X7_VARIANT
;
699 case MavlinkTelemetry
:
700 return id
.contains("mavlink") ? 1 : 0;
702 return IS_ARM(board
) ? 1 : 0;
705 return (IS_HORUS_OR_TARANIS(board
) ? true : false);
706 case HasBatMeterRange
:
707 return (IS_HORUS_OR_TARANIS(board
) ? true : id
.contains("battgraph"));
708 case DangerousFunctions
:
709 return id
.contains("danger") ? 1 : 0;
710 case HasModelCategories
:
711 return IS_HORUS(board
);
717 QString
OpenTxFirmware::getAnalogInputName(unsigned int index
)
719 if ((int)index
< getBoardCapability(board
, Board::Sticks
)) {
720 const QString sticks
[] = {
726 return sticks
[index
];
729 index
-= getBoardCapability(board
, Board::Sticks
);
731 if (IS_9X(board
) || IS_2560(board
) || IS_SKY9X(board
)) {
732 const QString pots
[] = {
737 return CHECK_IN_ARRAY(pots
, index
);
739 else if (IS_TARANIS_X9E(board
)) {
740 const QString pots
[] = {
750 return CHECK_IN_ARRAY(pots
, index
);
752 else if (IS_TARANIS(board
)) {
753 const QString pots
[] = {
760 return CHECK_IN_ARRAY(pots
, index
);
762 else if (IS_HORUS(board
)) {
763 const QString pots
[] = {
774 return CHECK_IN_ARRAY(pots
, index
);
781 QTime
OpenTxFirmware::getMaxTimerStart()
783 if (IS_HORUS_OR_TARANIS(board
))
784 return QTime(23, 59, 59);
785 else if (IS_ARM(board
))
786 return QTime(8, 59, 59);
788 return QTime(0, 59, 59);
791 int OpenTxFirmware::isAvailable(PulsesProtocol proto
, int port
)
793 if (IS_HORUS_OR_TARANIS(board
)) {
798 case PULSES_PXX_XJT_X16
:
799 case PULSES_PXX_XJT_LR12
:
801 case PULSES_PXX_XJT_D8
:
802 return id
.contains("eu") ? 0 : 1;
804 return id
.contains("internalppm") ? 1 : 0;
813 case PULSES_PXX_XJT_X16
:
814 case PULSES_PXX_XJT_D8
:
815 case PULSES_PXX_XJT_LR12
:
817 //case PULSES_PXX_DJT: // Unavailable for now
821 case PULSES_CROSSFIRE
:
824 case PULSES_MULTIMODULE
:
825 return id
.contains("multimodule") ? 1 : 0;
842 else if (IS_SKY9X(board
)) {
847 case PULSES_PXX_XJT_X16
:
848 case PULSES_PXX_XJT_D8
:
849 case PULSES_PXX_XJT_LR12
:
856 case PULSES_MULTIMODULE
:
857 return id
.contains("multimodule") ? 1 : 0;
880 // case PULSES_PXX_DJT: // Unavailable for now
890 template<typename T
, size_t SIZE
>
891 size_t getSizeA(T (&)[SIZE
])
896 EepromLoadErrors
OpenTxEepromInterface::checkVersion(unsigned int version
)
902 // channel order is now always RUD - ELE - THR - AIL
904 // ppmFrameLength added
907 // mixers changed (for the trims use for change the offset of a mix)
908 // telemetry offset raised to -127 +127
909 // function switches now have a param on 4 bits
911 // telemetry changes (bars)
913 // mixer changes (differential, negative curves)...
916 // V4: Rotary Encoders position in FlightModes
918 // Trim value in 16bits
919 // FrSky A1/A2 offset on 12bits
920 // ARM: More Mixers / Expos / CSW / FSW / CHNOUT
922 // Add TrmR, TrmE, TrmT, TrmA as Mix sources
923 // Trims are now OFF / ON / Rud / Ele / Thr / Ail
925 // Add names in Mixes / Expos
926 // Add a new telemetry screen
927 // Add support for Play Track <filename>
931 // Big changes in mixers / limitse
933 // GVARS / Variants introduction
935 // Massive EEPROM change!
937 // M128 revert because too much RAM used!
939 // A lot of things (first github release)
941 // 3 logical switches removed on M128 / gruvin9x boards
952 bool OpenTxEepromInterface::checkVariant(unsigned int version
, unsigned int variant
)
954 if (board
== BOARD_M128
&& !(variant
& M128_VARIANT
)) {
955 if (version
== 212) {
957 for (int i
= 1; i
< 31; i
++) {
959 int sz
= efile
->readRlc2(tmp
, sizeof(tmp
));
961 qWarning() << " warning: M128 variant not set (but model size seems ok)";
966 qWarning() << " wrong variant (" << variant
<< ")";
969 else if (IS_TARANIS_X9E(board
)) {
970 if (variant
!= TARANIS_X9E_VARIANT
) {
971 qWarning() << " wrong variant (" << variant
<< ")";
975 else if (IS_TARANIS_X7(board
)) {
976 if (variant
!= TARANIS_X7_VARIANT
) {
977 qWarning() << " wrong variant (" << variant
<< ")";
981 else if (IS_TARANIS(board
)) {
983 qWarning() << " wrong variant (" << variant
<< ")";
992 OpenTxEepromInterface::loadModelFromBackup(ModelData
& model
, const uint8_t * data
, unsigned int size
, uint8_t version
, uint32_t variant
)
994 QByteArray
backupData((char *) data
, size
);
995 QByteArray modelData
;
996 if (IS_SKY9X(board
)) {
997 modelData
= QByteArray((char *) data
, size
);
1000 importRlc(modelData
, backupData
);
1002 if (modelData
.size()) {
1003 if (loadFromByteArray
<ModelData
, OpenTxModelData
>(model
, modelData
, version
, variant
)) {
1012 unsigned long OpenTxEepromInterface::loadBackup(RadioData
&radioData
, const uint8_t * eeprom
, int esize
, int index
)
1014 std::bitset
<NUM_ERRORS
> errors
;
1016 QDebug dbg
= qDebug();
1017 dbg
.setAutoInsertSpaces(false);
1018 dbg
<< "trying " << getName() << " backup import...";
1020 if (esize
< 8 || memcmp(eeprom
, "o9x", 3) != 0) {
1022 errors
.set(WRONG_SIZE
);
1023 return errors
.to_ulong();
1026 Type backupBoard
= (Type
) -1;
1027 switch (eeprom
[3]) {
1029 backupBoard
= BOARD_TARANIS_X9D
;
1032 backupBoard
= BOARD_SKY9X
;
1035 backupBoard
= BOARD_GRUVIN9X
;
1038 dbg
<< " unknown board";
1039 errors
.set(UNKNOWN_BOARD
);
1040 return errors
.to_ulong();
1043 if (backupBoard
!= board
) {
1044 dbg
<< " not right board";
1045 errors
.set(WRONG_BOARD
);
1046 return errors
.to_ulong();
1049 uint8_t version
= eeprom
[4];
1050 uint8_t bcktype
= eeprom
[5];
1051 uint16_t size
= ((uint16_t) eeprom
[7] << 8) + eeprom
[6];
1052 uint16_t variant
= ((uint16_t) eeprom
[9] << 8) + eeprom
[8];
1054 dbg
<< " version " << (unsigned int) version
<< " ";
1056 EepromLoadErrors version_error
= checkVersion(version
);
1057 if (version_error
== OLD_VERSION
) {
1058 errors
.set(version_error
);
1059 errors
.set(HAS_WARNINGS
);
1061 else if (version_error
== NOT_OPENTX
) {
1062 dbg
<< " not open9x";
1063 errors
.set(version_error
);
1064 return errors
.to_ulong();
1067 if (size
> esize
- 8) {
1068 dbg
<< " wrong size";
1069 errors
.set(WRONG_SIZE
);
1070 return errors
.to_ulong();
1073 if (bcktype
== 'M') {
1074 if (!loadModelFromBackup(radioData
.models
[index
], &eeprom
[8], size
, version
, variant
)) {
1076 errors
.set(UNKNOWN_ERROR
);
1077 return errors
.to_ulong();
1081 dbg
<< " backup type not supported";
1082 errors
.set(BACKUP_NOT_SUPPORTED
);
1083 return errors
.to_ulong();
1088 return errors
.to_ulong();
1091 QString
OpenTxFirmware::getFirmwareBaseUrl()
1093 return OPENTX_FIRMWARE_DOWNLOAD_URL
[g
.boundedOpenTxBranch()];
1096 QString
OpenTxFirmware::getFirmwareUrl()
1098 QString url
= getFirmwareBaseUrl();
1099 QByteArray data
= QUrl::toPercentEncoding(id
);
1102 url
.append(QString("/getfw.php?fw=%1.bin").arg((QString
) data
));
1104 url
.append(QString("/getfw.php?fw=%1.hex").arg((QString
) data
));
1108 QString
OpenTxFirmware::getReleaseNotesUrl()
1110 QString url
= getFirmwareBaseUrl();
1111 url
.append("/releasenotes.txt");
1115 QString
OpenTxFirmware::getStampUrl()
1117 QString url
= getFirmwareBaseUrl();
1118 url
.append("/stamp-opentx.txt");
1122 void addOpenTxCommonOptions(OpenTxFirmware
* firmware
)
1124 firmware
->addOption("ppmus", QObject::tr("Channel values displayed in us"));
1125 firmware
->addOption("nooverridech", QObject::tr("No OverrideCH functions available"));
1126 Option fai_options
[] = {{"faichoice", QObject::tr("Possibility to enable FAI MODE (no telemetry) at field")},
1127 {"faimode", QObject::tr("FAI MODE (no telemetry) always enabled")},
1129 firmware
->addOptions(fai_options
);
1132 void addOpenTxArmOptions(OpenTxFirmware
* firmware
)
1134 firmware
->addOption("multimodule", QObject::tr("Support for the DIY-Multiprotocol-TX-Module"));
1135 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"));
1138 void addOpenTxFrskyOptions(OpenTxFirmware
* firmware
)
1140 addOpenTxCommonOptions(firmware
);
1141 addOpenTxArmOptions(firmware
);
1142 firmware
->addOption("noheli", QObject::tr("Disable HELI menu and cyclic mix support"));
1143 firmware
->addOption("nogvars", QObject::tr("Disable Global variables"));
1144 firmware
->addOption("lua", QObject::tr("Enable Lua custom scripts screen"));
1145 firmware
->addOption("luac", QObject::tr("Enable Lua compiler"));
1146 firmware
->addOption("bindopt", QObject::tr("Enable bindings options"));
1149 void addOpenTxTaranisOptions(OpenTxFirmware
* firmware
)
1151 addOpenTxFrskyOptions(firmware
);
1152 firmware
->addOption("internalppm", QObject::tr("Support for PPM internal module hack"));
1153 firmware
->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
1156 void addOpenTxLcdOptions(OpenTxFirmware
* firmware
)
1158 Option lcd_options
[] = {
1159 {"ST7565P", QObject::tr("ST7565P LCD or compatible")},
1160 {"ST7565R", QObject::tr("ST7565R LCD or compatible")},
1161 {"ERC12864FSF", QObject::tr("ERC12864FSF LCD")},
1162 {"ST7920", QObject::tr("ST7920 LCD")},
1163 {"KS108", QObject::tr("KS108 LCD")},
1166 firmware
->addOptions(lcd_options
);
1169 void addOpenTxVoiceOptions(OpenTxFirmware
* firmware
)
1171 Option voice_options
[] = {
1172 {"WTV20", QObject::tr("WTV20 voice module")},
1173 {"JQ6500", QObject::tr("JQ6500 voice module")},
1176 firmware
->addOptions(voice_options
);
1179 QList
<OpenTxEepromInterface
*> opentxEEpromInterfaces
;
1181 void registerOpenTxFirmware(OpenTxFirmware
* firmware
)
1183 OpenTxEepromInterface
* eepromInterface
= new OpenTxEepromInterface(firmware
);
1184 firmware
->setEEpromInterface(eepromInterface
);
1185 opentxEEpromInterfaces
.push_back(eepromInterface
);
1186 eepromInterfaces
.push_back(eepromInterface
);
1187 Firmware::addRegisteredFirmware(firmware
);
1190 void registerOpenTxFirmwares()
1192 OpenTxFirmware
* firmware
;
1194 Option ext_options
[] = {{"frsky", QObject::tr("Support for frsky telemetry mod"), FRSKY_VARIANT
},
1195 {"telemetrez", QObject::tr("Support for telemetry easy board"), FRSKY_VARIANT
},
1196 {"jeti", QObject::tr("Support for jeti telemetry mod"), 0},
1197 {"ardupilot", QObject::tr("Support for receiving ardupilot data"), 0},
1198 {"nmea", QObject::tr("Support for receiving NMEA data"), 0},
1199 {"mavlink", QObject::tr("Support for MAVLINK devices"), MAVLINK_VARIANT
},
1201 Option extr_options
[] = {{"frsky", QObject::tr("Support for frsky telemetry mod"), FRSKY_VARIANT
},
1202 {"jeti", QObject::tr("Support for jeti telemetry mod"), 0},
1203 {"ardupilot", QObject::tr("Support for receiving ardupilot data"), 0},
1204 {"nmea", QObject::tr("Support for receiving NMEA data"), 0},
1205 {"mavlink", QObject::tr("Support for MAVLINK devices"), MAVLINK_VARIANT
},
1207 Option nav_options
[] = {{"rotenc", QObject::tr("Rotary Encoder use in menus navigation")},
1208 {"potscroll", QObject::tr("Pots use in menus navigation")},
1210 Option dsm2_options
[] = {{"DSM2", QObject::tr("Support for DSM2 modules"), 0},
1211 {"DSM2PPM", QObject::tr("Support for DSM2 modules using ppm instead of true serial"), 0},
1214 /* FrSky Taranis X9D+ board */
1215 firmware
= new OpenTxFirmware("opentx-x9d+", QObject::tr("FrSky Taranis X9D+"), BOARD_TARANIS_X9DP
);
1216 addOpenTxTaranisOptions(firmware
);
1217 registerOpenTxFirmware(firmware
);
1219 /* FrSky Taranis X9D board */
1220 firmware
= new OpenTxFirmware("opentx-x9d", QObject::tr("FrSky Taranis X9D"), BOARD_TARANIS_X9D
);
1221 firmware
->addOption("haptic", QObject::tr("Haptic module installed"));
1222 addOpenTxTaranisOptions(firmware
);
1223 registerOpenTxFirmware(firmware
);
1225 /* FrSky Taranis X9E board */
1226 firmware
= new OpenTxFirmware("opentx-x9e", QObject::tr("FrSky Taranis X9E"), BOARD_TARANIS_X9E
);
1227 firmware
->addOption("shutdownconfirm", QObject::tr("Confirmation before radio shutdown"));
1228 firmware
->addOption("horussticks", QObject::tr("Horus gimbals installed (Hall sensors)"));
1229 addOpenTxTaranisOptions(firmware
);
1230 registerOpenTxFirmware(firmware
);
1232 /* FrSky X7 board */
1233 firmware
= new OpenTxFirmware("opentx-x7", QObject::tr("FrSky Taranis X7 / X7S"), BOARD_TARANIS_X7
);
1234 // No mixersmon for now
1235 addOpenTxFrskyOptions(firmware
);
1236 firmware
->addOption("internalppm", QObject::tr("Support for PPM internal module hack"));
1237 firmware
->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
1238 registerOpenTxFirmware(firmware
);
1240 /* FrSky X10 board */
1241 firmware
= new OpenTxFirmware("opentx-x10", QObject::tr("FrSky Horus X10 / X10S"), BOARD_X10
);
1242 addOpenTxFrskyOptions(firmware
);
1243 registerOpenTxFirmware(firmware
);
1245 /* FrSky Horus board */
1246 firmware
= new OpenTxFirmware("opentx-x12s", QObject::tr("FrSky Horus X12S"), BOARD_X12S
);
1247 addOpenTxFrskyOptions(firmware
);
1248 firmware
->addOption("pcbdev", QObject::tr("Use ONLY with first DEV pcb version"));
1249 registerOpenTxFirmware(firmware
);
1252 firmware
= new OpenTxFirmware("opentx-9xrpro", QObject::tr("Turnigy 9XR-PRO"), BOARD_9XRPRO
);
1253 firmware
->addOption("heli", QObject::tr("Enable HELI menu and cyclic mix support"));
1254 firmware
->addOption("nofp", QObject::tr("No flight modes"));
1255 firmware
->addOption("gvars", QObject::tr("Global variables"), GVARS_VARIANT
);
1256 firmware
->addOption("potscroll", QObject::tr("Pots use in menus navigation"));
1257 firmware
->addOption("autosource", QObject::tr("In model setup menus automatically set source by moving the control"));
1258 firmware
->addOption("autoswitch", QObject::tr("In model setup menus automatically set switch by moving the control"));
1259 firmware
->addOption("nographics", QObject::tr("No graphical check boxes and sliders"));
1260 firmware
->addOption("battgraph", QObject::tr("Battery graph"));
1261 firmware
->addOption("nobold", QObject::tr("Don't use bold font for highlighting active items"));
1262 firmware
->addOption("bluetooth", QObject::tr("Bluetooth interface"));
1263 firmware
->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
1264 addOpenTxArmOptions(firmware
);
1265 addOpenTxCommonOptions(firmware
);
1266 registerOpenTxFirmware(firmware
);
1268 /* 9XR board with M128 chip */
1269 firmware
= new OpenTxFirmware("opentx-9xr128", QObject::tr("Turnigy 9XR with m128 chip"), BOARD_M128
);
1270 firmware
->addOptions(extr_options
);
1271 firmware
->addOption("heli", QObject::tr("Enable heli menu and cyclic mix support"));
1272 firmware
->addOption("templates", QObject::tr("Enable TEMPLATES menu"));
1273 firmware
->addOption("nosplash", QObject::tr("No splash screen"));
1274 firmware
->addOption("nofp", QObject::tr("No flight modes"));
1275 firmware
->addOption("nocurves", QObject::tr("Disable curves menus"));
1276 firmware
->addOption("audio", QObject::tr("Support for radio modified with regular speaker"));
1277 firmware
->addOption("voice", QObject::tr("Used if you have modified your radio with voice mode"));
1278 firmware
->addOption("haptic", QObject::tr("Used if you have modified your radio with haptic mode"));
1279 // NOT TESTED firmware->addOption("PXX", QObject::tr("Support of FrSky PXX protocol"));
1280 firmware
->addOption("DSM2", QObject::tr("Support for DSM2 modules"));
1281 firmware
->addOption("ppmca", QObject::tr("PPM center adjustment in limits"));
1282 firmware
->addOption("gvars", QObject::tr("Global variables"), GVARS_VARIANT
);
1283 firmware
->addOption("symlimits", QObject::tr("Symetrical Limits"));
1284 firmware
->addOption("potscroll", QObject::tr("Pots use in menus navigation"));
1285 firmware
->addOption("autosource", QObject::tr("In model setup menus automatically set source by moving the control"));
1286 firmware
->addOption("autoswitch", QObject::tr("In model setup menus automatically set switch by moving the control"));
1287 firmware
->addOption("nographics", QObject::tr("No graphical check boxes and sliders"));
1288 firmware
->addOption("battgraph", QObject::tr("Battery graph"));
1289 firmware
->addOption("nobold", QObject::tr("Don't use bold font for highlighting active items"));
1290 firmware
->addOption("thrtrace", QObject::tr("Enable the throttle trace in Statistics"));
1291 firmware
->addOption("pgbar", QObject::tr("EEprom write Progress bar"));
1292 firmware
->addOption("imperial", QObject::tr("Imperial units"));
1293 firmware
->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
1294 addOpenTxCommonOptions(firmware
);
1295 registerOpenTxFirmware(firmware
);
1298 firmware
= new OpenTxFirmware("opentx-9xr", QObject::tr("Turnigy 9XR"), BOARD_STOCK
);
1299 firmware
->addOptions(extr_options
);
1300 firmware
->addOption("heli", QObject::tr("Enable heli menu and cyclic mix support"));
1301 firmware
->addOption("templates", QObject::tr("Enable TEMPLATES menu"));
1302 firmware
->addOption("nosplash", QObject::tr("No splash screen"));
1303 firmware
->addOption("nofp", QObject::tr("No flight modes"));
1304 firmware
->addOption("nocurves", QObject::tr("Disable curves menus"));
1305 firmware
->addOption("audio", QObject::tr("Support for radio modified with regular speaker"));
1306 firmware
->addOption("voice", QObject::tr("Used if you have modified your radio with voice mode"));
1307 firmware
->addOption("haptic", QObject::tr("Used if you have modified your radio with haptic mode"));
1308 // NOT TESTED firmware->addOption("PXX", QObject::tr("Support of FrSky PXX protocol"));
1309 firmware
->addOption("DSM2", QObject::tr("Support for DSM2 modules"));
1310 firmware
->addOption("ppmca", QObject::tr("PPM center adjustment in limits"));
1311 firmware
->addOption("gvars", QObject::tr("Global variables"), GVARS_VARIANT
);
1312 firmware
->addOption("symlimits", QObject::tr("Symetrical Limits"));
1313 firmware
->addOption("potscroll", QObject::tr("Pots use in menus navigation"));
1314 firmware
->addOption("autosource", QObject::tr("In model setup menus automatically set source by moving the control"));
1315 firmware
->addOption("autoswitch", QObject::tr("In model setup menus automatically set switch by moving the control"));
1316 firmware
->addOption("nographics", QObject::tr("No graphical check boxes and sliders"));
1317 firmware
->addOption("battgraph", QObject::tr("Battery graph"));
1318 firmware
->addOption("nobold", QObject::tr("Don't use bold font for highlighting active items"));
1319 firmware
->addOption("thrtrace", QObject::tr("Enable the throttle trace in Statistics"));
1320 firmware
->addOption("pgbar", QObject::tr("EEprom write Progress bar"));
1321 firmware
->addOption("imperial", QObject::tr("Imperial units"));
1322 firmware
->addOption("nowshh", QObject::tr("No Winged Shadow How High support"));
1323 firmware
->addOption("novario", QObject::tr("No vario support"));
1324 firmware
->addOption("nogps", QObject::tr("No GPS support"));
1325 firmware
->addOption("nogauges", QObject::tr("No gauges in the custom telemetry screen"));
1326 firmware
->addOption("stickrev", QObject::tr("Add support for reversing stick inputs (e.g. needed for FrSky gimbals)"));
1327 firmware
->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
1328 addOpenTxCommonOptions(firmware
);
1329 registerOpenTxFirmware(firmware
);
1332 firmware
= new OpenTxFirmware("opentx-9x", QObject::tr("9X with stock board"), BOARD_STOCK
);
1333 firmware
->addOptions(ext_options
);
1334 firmware
->addOption("heli", QObject::tr("Enable heli menu and cyclic mix support"));
1335 firmware
->addOption("templates", QObject::tr("Enable TEMPLATES menu"));
1336 firmware
->addOption("nosplash", QObject::tr("No splash screen"));
1337 firmware
->addOption("nofp", QObject::tr("No flight modes"));
1338 firmware
->addOption("nocurves", QObject::tr("Disable curves menus"));
1339 firmware
->addOption("audio", QObject::tr("Support for radio modified with regular speaker"));
1340 firmware
->addOption("voice", QObject::tr("Used if you have modified your radio with voice mode"));
1341 firmware
->addOption("haptic", QObject::tr("Used if you have modified your radio with haptic mode"));
1342 // NOT TESTED firmware->addOption("PXX", QObject::tr("Support of FrSky PXX protocol"));
1343 firmware
->addOption("DSM2", QObject::tr("Support for DSM2 modules"));
1344 firmware
->addOption("ppmca", QObject::tr("PPM center adjustment in limits"));
1345 firmware
->addOption("gvars", QObject::tr("Global variables"), GVARS_VARIANT
);
1346 firmware
->addOption("symlimits", QObject::tr("Symetrical Limits"));
1347 firmware
->addOptions(nav_options
);
1348 firmware
->addOption("sp22", QObject::tr("SmartieParts 2.2 Backlight support"));
1349 firmware
->addOption("autosource", QObject::tr("In model setup menus automatically set source by moving the control"));
1350 firmware
->addOption("autoswitch", QObject::tr("In model setup menus automatically set switch by moving the control"));
1351 firmware
->addOption("dblkeys", QObject::tr("Enable resetting values by pressing up and down at the same time"));
1352 firmware
->addOption("nographics", QObject::tr("No graphical check boxes and sliders"));
1353 firmware
->addOption("battgraph", QObject::tr("Battery graph"));
1354 firmware
->addOption("nobold", QObject::tr("Don't use bold font for highlighting active items"));
1355 firmware
->addOption("thrtrace", QObject::tr("Enable the throttle trace in Statistics"));
1356 firmware
->addOption("pgbar", QObject::tr("EEprom write progress bar"));
1357 firmware
->addOption("imperial", QObject::tr("Imperial units"));
1358 firmware
->addOption("nowshh", QObject::tr("No Winged Shadow How High support"));
1359 firmware
->addOption("novario", QObject::tr("No vario support"));
1360 firmware
->addOption("nogps", QObject::tr("No GPS support"));
1361 firmware
->addOption("nogauges", QObject::tr("No gauges in the custom telemetry screen"));
1362 firmware
->addOption("fasoffset", QObject::tr("Allow compensating for offset errors in FrSky FAS current sensors"));
1363 firmware
->addOption("stickrev", QObject::tr("Add support for reversing stick inputs (e.g. needed for FrSky gimbals)"));
1364 firmware
->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
1365 addOpenTxCommonOptions(firmware
);
1366 registerOpenTxFirmware(firmware
);
1368 /* 9x board with M128 chip */
1369 firmware
= new OpenTxFirmware("opentx-9x128", QObject::tr("9X with stock board and m128 chip"), BOARD_M128
);
1370 firmware
->addOptions(ext_options
);
1371 firmware
->addOption("heli", QObject::tr("Enable heli menu and cyclic mix support"));
1372 firmware
->addOption("templates", QObject::tr("Enable TEMPLATES menu"));
1373 firmware
->addOption("nosplash", QObject::tr("No splash screen"));
1374 firmware
->addOption("nofp", QObject::tr("No flight modes"));
1375 firmware
->addOption("nocurves", QObject::tr("Disable curves menus"));
1376 firmware
->addOption("audio", QObject::tr("Support for radio modified with regular speaker"));
1377 firmware
->addOption("voice", QObject::tr("Used if you have modified your radio with voice mode"));
1378 firmware
->addOption("haptic", QObject::tr("Used if you have modified your radio with haptic mode"));
1379 // NOT TESTED firmware->addOption("PXX", QObject::tr("Support of FrSky PXX protocol"));
1380 firmware
->addOption("DSM2", QObject::tr("Support for DSM2 modules"));
1381 firmware
->addOption("ppmca", QObject::tr("PPM center adjustment in limits"));
1382 firmware
->addOption("gvars", QObject::tr("Global variables"), GVARS_VARIANT
);
1383 firmware
->addOption("symlimits", QObject::tr("Symetrical Limits"));
1384 firmware
->addOptions(nav_options
);
1385 firmware
->addOption("sp22", QObject::tr("SmartieParts 2.2 Backlight support"));
1386 firmware
->addOption("autosource", QObject::tr("In model setup menus automatically set source by moving the control"));
1387 firmware
->addOption("autoswitch", QObject::tr("In model setup menus automatically set switch by moving the control"));
1388 firmware
->addOption("dblkeys", QObject::tr("Enable resetting values by pressing up and down at the same time"));
1389 firmware
->addOption("nographics", QObject::tr("No graphical check boxes and sliders"));
1390 firmware
->addOption("battgraph", QObject::tr("Battery graph"));
1391 firmware
->addOption("nobold", QObject::tr("Don't use bold font for highlighting active items"));
1392 firmware
->addOption("thrtrace", QObject::tr("Enable the throttle trace in Statistics"));
1393 firmware
->addOption("pgbar", QObject::tr("EEprom write Progress bar"));
1394 firmware
->addOption("imperial", QObject::tr("Imperial units"));
1395 firmware
->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
1396 addOpenTxCommonOptions(firmware
);
1397 registerOpenTxFirmware(firmware
);
1400 firmware
= new OpenTxFirmware("opentx-ar9x", QObject::tr("9X with AR9X board"), BOARD_AR9X
);
1401 firmware
->addOption("heli", QObject::tr("Enable HELI menu and cyclic mix support"));
1402 firmware
->addOption("nofp", QObject::tr("No flight modes"));
1403 firmware
->addOption("gvars", QObject::tr("Global variables"), GVARS_VARIANT
);
1404 firmware
->addOption("potscroll", QObject::tr("Pots use in menus navigation"));
1405 firmware
->addOption("autosource", QObject::tr("In model setup menus automatically set source by moving the control"));
1406 firmware
->addOption("autoswitch", QObject::tr("In model setup menus automatically set switch by moving the control"));
1407 firmware
->addOption("dblkeys", QObject::tr("Enable resetting values by pressing up and down at the same time"));
1408 firmware
->addOption("nographics", QObject::tr("No graphical check boxes and sliders"));
1409 firmware
->addOption("battgraph", QObject::tr("Battery graph"));
1410 firmware
->addOption("nobold", QObject::tr("Don't use bold font for highlighting active items"));
1411 firmware
->addOption("bluetooth", QObject::tr("Bluetooth interface"));
1412 firmware
->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
1413 // firmware->addOption("rtc", QObject::tr("Optional RTC added"));
1414 // firmware->addOption("volume", QObject::tr("i2c volume control added"));
1415 addOpenTxArmOptions(firmware
);
1416 addOpenTxCommonOptions(firmware
);
1417 registerOpenTxFirmware(firmware
);
1420 firmware
= new OpenTxFirmware("opentx-sky9x", QObject::tr("9X with Sky9x board"), BOARD_SKY9X
);
1421 firmware
->addOption("heli", QObject::tr("Enable HELI menu and cyclic mix support"));
1422 firmware
->addOption("nofp", QObject::tr("No flight modes"));
1423 firmware
->addOption("gvars", QObject::tr("Global variables"), GVARS_VARIANT
);
1424 firmware
->addOption("potscroll", QObject::tr("Pots use in menus navigation"));
1425 firmware
->addOption("autosource", QObject::tr("In model setup menus automatically set source by moving the control"));
1426 firmware
->addOption("autoswitch", QObject::tr("In model setup menus automatically set switch by moving the control"));
1427 firmware
->addOption("dblkeys", QObject::tr("Enable resetting values by pressing up and down at the same time"));
1428 firmware
->addOption("nographics", QObject::tr("No graphical check boxes and sliders"));
1429 firmware
->addOption("battgraph", QObject::tr("Battery graph"));
1430 firmware
->addOption("nobold", QObject::tr("Don't use bold font for highlighting active items"));
1431 firmware
->addOption("bluetooth", QObject::tr("Bluetooth interface"));
1432 firmware
->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
1433 addOpenTxArmOptions(firmware
);
1434 addOpenTxCommonOptions(firmware
);
1435 registerOpenTxFirmware(firmware
);
1437 /* Gruvin9x board */
1438 firmware
= new OpenTxFirmware("opentx-gruvin9x", QObject::tr("9X with Gruvin9x board"), BOARD_GRUVIN9X
);
1439 firmware
->addOption("heli", QObject::tr("Enable heli menu and cyclic mix support"));
1440 firmware
->addOption("templates", QObject::tr("Enable TEMPLATES menu"));
1441 firmware
->addOption("nofp", QObject::tr("No flight modes"));
1442 firmware
->addOption("nocurves", QObject::tr("Disable curves menus"));
1443 firmware
->addOption("sdcard", QObject::tr("Support for SD memory card"));
1444 firmware
->addOption("voice", QObject::tr("Used if you have modified your radio with voice mode"));
1445 firmware
->addOption("PXX", QObject::tr("Support of FrSky PXX protocol"));
1446 firmware
->addOptions(dsm2_options
);
1447 firmware
->addOption("ppmca", QObject::tr("PPM center adjustment in limits"));
1448 firmware
->addOption("gvars", QObject::tr("Global variables"), GVARS_VARIANT
);
1449 firmware
->addOption("symlimits", QObject::tr("Symetrical Limits"));
1450 firmware
->addOption("potscroll", QObject::tr("Pots use in menus navigation"));
1451 firmware
->addOption("autosource", QObject::tr("In model setup menus automatically set source by moving the control"));
1452 firmware
->addOption("autoswitch", QObject::tr("In model setup menus automatically set switch by moving the control"));
1453 firmware
->addOption("dblkeys", QObject::tr("Enable resetting values by pressing up and down at the same time"));
1454 firmware
->addOption("nographics", QObject::tr("No graphical check boxes and sliders"));
1455 firmware
->addOption("battgraph", QObject::tr("Battery graph"));
1456 firmware
->addOption("nobold", QObject::tr("Don't use bold font for highlighting active items"));
1457 firmware
->addOption("pgbar", QObject::tr("EEprom write Progress bar"));
1458 firmware
->addOption("imperial", QObject::tr("Imperial units"));
1459 firmware
->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
1460 addOpenTxCommonOptions(firmware
);
1461 registerOpenTxFirmware(firmware
);
1463 /* MEGA2560 board */
1464 firmware
= new OpenTxFirmware("opentx-mega2560", QObject::tr("DIY MEGA2560 radio"), BOARD_MEGA2560
);
1465 addOpenTxLcdOptions(firmware
);
1466 firmware
->addOption("PWR", QObject::tr("Power management by soft-off circuitry"));
1467 firmware
->addOptions(ext_options
);
1468 firmware
->addOption("PXX", QObject::tr("Support of FrSky PXX protocol"));
1469 firmware
->addOptions(dsm2_options
);
1470 firmware
->addOption("heli", QObject::tr("Enable heli menu and cyclic mix support"));
1471 firmware
->addOption("templates", QObject::tr("Enable TEMPLATES menu"));
1472 firmware
->addOption("nofp", QObject::tr("No flight modes"));
1473 firmware
->addOption("nocurves", QObject::tr("Disable curves menus"));
1474 firmware
->addOption("sdcard", QObject::tr("Support for SD memory card"));
1475 firmware
->addOption("audio", QObject::tr("Support for radio modified with regular speaker"));
1476 //firmware->addOption("voice", QObject::tr("Used if you have modified your radio with voice mode"));
1477 addOpenTxVoiceOptions(firmware
);
1478 firmware
->addOption("haptic", QObject::tr("Used if you have modified your radio with haptic mode"));
1479 firmware
->addOption("ppmca", QObject::tr("PPM center adjustment in limits"));
1480 firmware
->addOption("gvars", QObject::tr("Global variables"), GVARS_VARIANT
);
1481 firmware
->addOption("symlimits", QObject::tr("Symetrical Limits"));
1482 firmware
->addOption("autosource", QObject::tr("In model setup menus automatically set source by moving the control"));
1483 firmware
->addOption("autoswitch", QObject::tr("In model setup menus automatically set switch by moving the control"));
1484 firmware
->addOption("dblkeys", QObject::tr("Enable resetting values by pressing up and down at the same time"));
1485 firmware
->addOption("nographics", QObject::tr("No graphical check boxes and sliders"));
1486 firmware
->addOption("battgraph", QObject::tr("Battery graph"));
1487 firmware
->addOption("nobold", QObject::tr("Don't use bold font for highlighting active items"));
1488 firmware
->addOption("pgbar", QObject::tr("EEprom write Progress bar"));
1489 firmware
->addOption("imperial", QObject::tr("Imperial units"));
1490 firmware
->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
1491 addOpenTxCommonOptions(firmware
);
1492 registerOpenTxFirmware(firmware
);
1494 Firmware::setDefaultVariant(Firmware::getFirmwareForId("opentx-x9d+"));
1495 Firmware::setCurrentVariant(Firmware::getDefaultVariant());
1498 void unregisterOpenTxFirmwares()
1500 foreach (Firmware
* f
, Firmware::getRegisteredFirmwares()) {
1503 unregisterEEpromInterfaces();
1506 template <class T
, class M
>
1507 OpenTxEepromInterface
* loadFromByteArray(T
& dest
, const QByteArray
& data
)
1509 foreach(OpenTxEepromInterface
* eepromInterface
, opentxEEpromInterfaces
) {
1510 if (eepromInterface
->loadFromByteArray
<T
, M
>(dest
, data
)) {
1511 return eepromInterface
;
1517 template <class T
, class M
>
1518 bool saveToByteArray(const T
& dest
, QByteArray
& data
)
1520 Board::Type board
= getCurrentBoard();
1521 foreach(OpenTxEepromInterface
* eepromInterface
, opentxEEpromInterfaces
) {
1522 if (eepromInterface
->getBoard() == board
) {
1523 return eepromInterface
->saveToByteArray
<T
, M
>(dest
, data
);
1529 OpenTxEepromInterface
* loadModelFromByteArray(ModelData
& model
, const QByteArray
& data
)
1531 return loadFromByteArray
<ModelData
, OpenTxModelData
>(model
, data
);
1534 OpenTxEepromInterface
* loadRadioSettingsFromByteArray(GeneralSettings
& settings
, const QByteArray
& data
)
1536 return loadFromByteArray
<GeneralSettings
, OpenTxGeneralData
>(settings
, data
);
1539 bool writeModelToByteArray(const ModelData
& model
, QByteArray
& data
)
1541 return saveToByteArray
<ModelData
, OpenTxModelData
>(model
, data
);
1544 bool writeRadioSettingsToByteArray(const GeneralSettings
& settings
, QByteArray
& data
)
1546 return saveToByteArray
<GeneralSettings
, OpenTxGeneralData
>(settings
, data
);