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>
30 using namespace Board
;
32 #define OPENTX_FIRMWARE_DOWNLOADS "http://downloads-22.open-tx.org/firmware"
33 #define OPENTX_NIGHT_FIRMWARE_DOWNLOADS "http://downloads-22.open-tx.org/nightly/firmware"
35 #define FILE_TYP_GENERAL 1
36 #define FILE_TYP_MODEL 2
38 /// fileId of general file
39 #define FILE_GENERAL 0
40 /// convert model number 0..MAX_MODELS-1 int fileId
41 #define FILE_MODEL(n) (1+n)
43 template<typename T
, size_t N
>
45 size_t SizeOfArray(T(&)[N
])
50 OpenTxEepromInterface::OpenTxEepromInterface(OpenTxFirmware
* firmware
):
51 EEPROMInterface(firmware
->getBoard()),
57 OpenTxEepromInterface::~OpenTxEepromInterface()
62 const char * OpenTxEepromInterface::getName()
66 return "OpenTX for 9X board";
68 return "OpenTX for M128 / 9X board";
70 return "OpenTX for MEGA2560 board";
72 return "OpenTX for Gruvin9x board / 9X";
73 case BOARD_TARANIS_X9D
:
74 return "OpenTX for FrSky Taranis X9D";
75 case BOARD_TARANIS_X9DP
:
76 return "OpenTX for FrSky Taranis X9D+";
77 case BOARD_TARANIS_X9E
:
78 return "OpenTX for FrSky Taranis X9E";
79 case BOARD_TARANIS_X7
:
80 return "OpenTX for FrSky Taranis X7";
82 return "OpenTX for Sky9x board / 9X";
84 return "OpenTX for 9XR-PRO";
86 return "OpenTX for ar9x board / 9X";
88 return "OpenTX for Flamenco experimental";
90 return "OpenTX for FrSky Horus";
92 return "OpenTX for FrSky X10";
94 return "OpenTX for an unknown board";
98 uint32_t OpenTxEepromInterface::getFourCC()
104 case BOARD_TARANIS_X7
:
106 case BOARD_TARANIS_X9E
:
108 case BOARD_TARANIS_X9D
:
109 case BOARD_TARANIS_X9DP
:
122 bool OpenTxEepromInterface::loadRadioSettingsFromRLE(GeneralSettings
& settings
, RleFile
* rleFile
, uint8_t version
)
124 QByteArray
data(sizeof(settings
), 0); // GeneralSettings should be always bigger than the EEPROM struct
125 OpenTxGeneralData
open9xSettings(settings
, board
, version
);
126 efile
->openRd(FILE_GENERAL
);
127 int size
= rleFile
->readRlc2((uint8_t *)data
.data(), data
.size());
129 open9xSettings
.Import(data
);
130 return checkVariant(settings
.version
, settings
.variant
);
133 std::cout
<< " error when loading general settings";
138 bool OpenTxEepromInterface::loadModelFromRLE(ModelData
& model
, RleFile
* rleFile
, unsigned int index
, uint8_t version
, uint32_t variant
)
140 QByteArray
data(sizeof(model
), 0); // ModelData should be always bigger than the EEPROM struct
141 rleFile
->openRd(FILE_MODEL(index
));
142 int size
= rleFile
->readRlc2((uint8_t *)data
.data(), data
.size());
144 if (loadFromByteArray
<ModelData
, OpenTxModelData
>(model
, data
, version
, variant
)) {
154 template <class T
, class M
>
155 bool OpenTxEepromInterface::saveToByteArray(const T
& src
, QByteArray
& data
, uint8_t version
)
158 version
= getLastDataVersion(getBoard());
161 T
srcCopy(src
); // work on a copy of radio data, because Export() will modify it!
162 M
manager(srcCopy
, board
, version
, 0);
166 *((uint32_t*)&data
.data()[0]) = getFourCC();
169 *((uint16_t*)&data
.data()[6]) = raw
.size();
174 template <class T
, class M
>
175 bool OpenTxEepromInterface::loadFromByteArray(T
& dest
, const QByteArray
& data
, uint8_t version
, uint32_t variant
)
177 M
manager(dest
, board
, version
, variant
);
178 if (manager
.Import(data
) != 0) {
181 // manager.Dump(); // Dumps the structure so that it's easy to check with firmware datastructs.h
185 template <class T
, class M
>
186 bool OpenTxEepromInterface::loadFromByteArray(T
& dest
, const QByteArray
& data
)
188 uint32_t fourcc
= *((uint32_t*)&data
.data()[0]);
189 if (getFourCC() != fourcc
) {
190 if (IS_HORUS(board
) && fourcc
== 0x3178396F) {
191 qDebug() << QString().sprintf("%s: Deprecated fourcc used %x vs %x", getName(), fourcc
, getFourCC());
194 qDebug() << QString().sprintf("%s: Wrong fourcc %x vs %x", getName(), fourcc
, getFourCC());
198 qDebug() << QString().sprintf("%s: OK", getName());
199 uint8_t version
= data
[4];
200 QByteArray raw
= data
.right(data
.size() - 8);
201 return loadFromByteArray
<T
, M
>(dest
, raw
, version
);
204 unsigned long OpenTxEepromInterface::load(RadioData
&radioData
, const uint8_t * eeprom
, int size
)
206 std::cout
<< "trying " << getName() << " import...";
208 std::bitset
<NUM_ERRORS
> errors
;
210 if (size
!= Boards::getEEpromSize(board
)) {
213 for (int i
= 2048; i
< 4096; i
++) {
214 if (eeprom
[i
] != 255) {
219 std::cout
<< " wrong size (" << size
<< ")\n";
220 errors
.set(WRONG_SIZE
);
221 return errors
.to_ulong();
224 errors
.set(HAS_WARNINGS
);
225 errors
.set(WARNING_WRONG_FIRMWARE
);
230 std::cout
<< " wrong size (" << size
<< "/" << Boards::getEEpromSize(board
) << ")\n";
231 errors
.set(WRONG_SIZE
);
232 return errors
.to_ulong();
236 if (!efile
->EeFsOpen((uint8_t *) eeprom
, size
, board
)) {
237 std::cout
<< " wrong file system\n";
238 errors
.set(WRONG_FILE_SYSTEM
);
239 return errors
.to_ulong();
242 efile
->openRd(FILE_GENERAL
);
245 if (efile
->readRlc2(&version
, 1) != 1) {
246 std::cout
<< " no\n";
247 errors
.set(UNKNOWN_ERROR
);
248 return errors
.to_ulong();
251 std::cout
<< " version " << (unsigned int) version
;
253 EepromLoadErrors version_error
= checkVersion(version
);
254 if (version_error
== OLD_VERSION
) {
255 errors
.set(version_error
);
256 errors
.set(HAS_WARNINGS
);
257 ShowEepromWarnings(NULL
, QObject::tr("Warning"), errors
.to_ulong());
259 else if (version_error
== NOT_OPENTX
) {
260 std::cout
<< " not open9x\n";
261 errors
.set(version_error
);
262 return errors
.to_ulong();
265 if (!loadRadioSettingsFromRLE(radioData
.generalSettings
, efile
, version
)) {
266 std::cout
<< " ko\n";
267 errors
.set(UNKNOWN_ERROR
);
268 return errors
.to_ulong();
271 std::cout
<< " variant " << radioData
.generalSettings
.variant
;
272 if (getCurrentFirmware()->getCapability(Models
) == 0) {
273 radioData
.models
.resize(firmware
->getCapability(Models
));
275 for (int i
= 0; i
< firmware
->getCapability(Models
); i
++) {
276 if (!loadModelFromRLE(radioData
.models
[i
], efile
, i
, version
, radioData
.generalSettings
.variant
)) {
277 std::cout
<< " ko\n";
278 errors
.set(UNKNOWN_ERROR
);
279 if (getCurrentFirmware()->getCapability(Models
) == 0) {
280 radioData
.models
.resize(i
);
282 return errors
.to_ulong();
285 std::cout
<< " ok\n";
287 return errors
.to_ulong();
290 uint8_t OpenTxEepromInterface::getLastDataVersion(Board::Type board
)
304 void OpenTxEepromInterface::showErrors(const QString
& title
, const QStringList
& errors
)
307 if (errors
.empty()) {
308 msg
= QObject::tr("Unknown error");
311 int noErrorsToDisplay
= std::min((int)errors
.size(), 10);
312 for (int n
= 0; n
< noErrorsToDisplay
; n
++) {
313 msg
+= " -" + errors
.at(n
) + "\n";
315 if (noErrorsToDisplay
< errors
.size()) {
316 msg
+= QObject::tr(" ... plus %1 errors").arg(errors
.size() - noErrorsToDisplay
) + "\n" + msg
;
320 QMessageBox::warning(NULL
,
321 QObject::tr("Error"),
325 int OpenTxEepromInterface::save(uint8_t * eeprom
, const RadioData
& radioData
, uint8_t version
, uint32_t variant
)
327 // TODO QMessageBox::warning should not be called here
330 version
= getLastDataVersion(board
);
333 int size
= Boards::getEEpromSize(board
);
335 efile
->EeFsCreate(eeprom
, size
, board
, version
);
337 if (board
== BOARD_M128
) {
338 variant
|= M128_VARIANT
;
340 else if (IS_TARANIS_X9E(board
)) {
341 variant
|= TARANIS_X9E_VARIANT
;
343 else if (IS_TARANIS_X7(board
)) {
344 variant
|= TARANIS_X7_VARIANT
;
347 OpenTxGeneralData
generator((GeneralSettings
&)radioData
.generalSettings
, board
, version
, variant
);
350 generator
.Export(data
);
351 int sz
= efile
->writeRlc2(FILE_GENERAL
, FILE_TYP_GENERAL
, (const uint8_t *)data
.constData(), data
.size());
352 if (sz
== 0 || generator
.errors().count() > 0) {
353 showErrors(QObject::tr("Cannot write radio settings"), generator
.errors());
357 for (int i
= 0; i
< getCurrentFirmware()->getCapability(Models
); i
++) {
358 if (!radioData
.models
[i
].isEmpty()) {
359 OpenTxModelData
generator((ModelData
&)radioData
.models
[i
], board
, version
, variant
);
362 generator
.Export(data
);
363 int sz
= efile
->writeRlc2(FILE_MODEL(i
), FILE_TYP_MODEL
, (const uint8_t *)data
.constData(), data
.size());
364 if (sz
== 0 || generator
.errors().count() > 0) {
365 showErrors(QObject::tr("Cannot write model %1").arg(radioData
.models
[i
].name
), generator
.errors());
374 int OpenTxEepromInterface::getSize(const ModelData
&model
)
382 QByteArray
tmp(Boards::getEEpromSize(Board::BOARD_UNKNOWN
), 0);
383 efile
->EeFsCreate((uint8_t *) tmp
.data(), Boards::getEEpromSize(Board::BOARD_UNKNOWN
), board
, 255/*version max*/);
385 OpenTxModelData
open9xModel((ModelData
&) model
, board
, 255/*version max*/, getCurrentFirmware()->getVariantNumber());
388 open9xModel
.Export(eeprom
);
389 int sz
= efile
->writeRlc2(0, FILE_TYP_MODEL
, (const uint8_t *) eeprom
.constData(), eeprom
.size());
390 if (sz
!= eeprom
.size()) {
393 return efile
->size(0);
396 int OpenTxEepromInterface::getSize(const GeneralSettings
&settings
)
401 QByteArray
tmp(Boards::getEEpromSize(Board::BOARD_UNKNOWN
), 0);
402 efile
->EeFsCreate((uint8_t *) tmp
.data(), Boards::getEEpromSize(Board::BOARD_UNKNOWN
), board
, 255);
404 OpenTxGeneralData
open9xGeneral((GeneralSettings
&) settings
, board
, 255, getCurrentFirmware()->getVariantNumber());
405 // open9xGeneral.Dump();
408 open9xGeneral
.Export(eeprom
);
409 int sz
= efile
->writeRlc2(0, FILE_TYP_GENERAL
, (const uint8_t *) eeprom
.constData(), eeprom
.size());
410 if (sz
!= eeprom
.size()) {
413 return efile
->size(0);
416 Firmware
* OpenTxFirmware::getFirmwareVariant(const QString
&id
)
421 else if (id
.contains(getId() + "-") || (!id
.contains("-") && id
.contains(getId()))) {
422 Firmware
* result
= new OpenTxFirmware(id
, this);
423 // TODO result.variant = firmware->getVariant(id);
431 int OpenTxFirmware::getCapability(::Capability capability
)
433 switch (capability
) {
437 else if (IS_ARM(board
))
439 else if (board
== BOARD_M128
)
441 else if (IS_2560(board
))
449 return id
.contains("imperial") ? 1 : 0;
451 return (board
== BOARD_TARANIS_X9D
|| IS_TARANIS_PLUS(board
) || IS_HORUS(board
));
453 return (!IS_ARM(board
));
456 case HasGeneralUnits
:
461 case HasNegAndSwitches
:
462 return IS_ARM(board
);
470 else if (IS_2560(board
))
474 case FlightModesHaveFades
:
477 if (IS_HORUS_OR_TARANIS(board
))
478 return id
.contains("noheli") ? 0 : 1;
480 return id
.contains("heli") ? 1 : 0;
482 if (IS_HORUS_OR_TARANIS(board
))
483 return id
.contains("nogvars") ? 0 : 9;
484 else if (id
.contains("gvars"))
485 return IS_ARM(board
) ? 9 : 5;
489 return (IS_HORUS(board
) ? 15 : (HAS_LARGE_LCD(board
) ? 12 : 10));
490 case FlightModesName
:
491 return (IS_HORUS_OR_TARANIS(board
) ? 10 : 6);
493 return (IS_9X(board
) ? 0 : 3);
498 case GvarsFlightModes
:
499 return ((IS_ARM(board
) || IS_2560(board
)) ? 1 : 0);
501 return (IS_ARM(board
) ? 64 : 32);
503 return (IS_ARM(board
) ? 500 : 245);
505 return (IS_ARM(board
) ? 3 : 2);
507 if (HAS_LARGE_LCD(board
))
509 else if (IS_ARM(board
))
514 return (IS_2560(board
) || IS_ARM(board
));
515 case SwitchesPositions
:
516 if (IS_HORUS_OR_TARANIS(board
))
517 return getBoardCapability(board
, Board::Switches
) * 3;
520 case CustomFunctions
:
523 else if (IS_2560(board
) || board
== BOARD_M128
)
527 case SafetyChannelCustomFunction
:
528 return id
.contains("nooverridech") ? 0 : 1;
529 case LogicalSwitches
:
534 case CustomAndSwitches
:
536 return getCapability(LogicalSwitches
);
538 return 15/*4bits*/- 9/*sw positions*/;
539 case LogicalSwitchesExt
:
540 return (IS_ARM(board
) ? true : false);
542 if (board
== BOARD_GRUVIN9X
)
544 else if (IS_SKY9X(board
))
549 return (IS_ARM(board
) ? 32 : 16);
551 return (IS_ARM(board
) ? 512 : 104);
552 case VoicesAsNumbers
:
553 return (IS_ARM(board
) ? 0 : 1);
554 case VoicesMaxLength
:
555 return (IS_ARM(board
) ? (IS_TARANIS_X9(board
) ? 8 : 6) : 0);
557 return (IS_ARM(board
) ? 1 : 0);
561 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"));
562 case ModelTrainerEnable
:
563 if (IS_HORUS_OR_TARANIS(board
))
568 return (IS_ARM(board
) ? 23 : 7);
570 return (IS_ARM(board
) ? 1 : 0);
575 case ExtendedTrimsRange
:
580 return (HAS_LARGE_LCD(board
) ? 32 : (IS_ARM(board
) ? 16 : 8));
582 return (IS_ARM(board
) ? (IS_TARANIS_X9(board
) ? 8 : 6) : false);
584 return (IS_ARM(board
) ? (IS_TARANIS_X9(board
) ? 8 : 6) : false);
586 return (IS_HORUS_OR_TARANIS(board
) ? false : true);
588 return (IS_ARM(board
) ? (HAS_LARGE_LCD(board
) ? 6 : 4) : 0);
590 return (IS_HORUS_OR_TARANIS(board
) ? 1 : 0);
592 if (IS_2560(board
) || IS_ARM(board
) || id
.contains("frsky") || id
.contains("telemetrez"))
593 return TM_HASTELEMETRY
| TM_HASOFFSET
| TM_HASWSHH
;
598 case TelemetryCustomScreens
:
602 return IS_ARM(board
) ? 4 : 2;
603 case TelemetryCustomScreensFieldsPerLine
:
604 return HAS_LARGE_LCD(board
) ? 3 : 2;
605 case NoTelemetryProtocol
:
606 return IS_HORUS_OR_TARANIS(board
) ? 1 : 0;
609 case TelemetryMaxMultiplier
:
610 return (IS_ARM(board
) ? 32 : 8);
612 return (IS_HORUS_OR_TARANIS(board
) ? 500 : (id
.contains("ppmca") ? 125 : 0));
613 case PPMUnitMicroseconds
:
614 return id
.contains("ppmus") ? 1 : 0;
618 return (board
== BOARD_SKY9X
? true : false);
622 return ((IS_2560(board
) || IS_ARM(board
)) ? true : false);
624 return (IS_ARM(board
) ? 32 : 0);
626 return (IS_ARM(board
) ? 2 : 1);
628 return (IS_ARM(board
) ? true : false);
629 case HastxCurrentCalibration
:
630 return (IS_SKY9X(board
) ? true : false);
632 return (IS_ARM(board
) ? true : false);
634 return (IS_ARM(board
) ? true : false);
638 return (IS_ARM(board
) ? 10 : 2);
640 return (IS_ARM(board
) ? 250 : 15);
644 return ((IS_2560(board
) || IS_ARM(board
)) ? true : false);
648 else if (IS_TARANIS_X7(board
))
650 else if (IS_TARANIS(board
))
662 else if (IS_TARANIS_X7(board
))
664 else if (IS_TARANIS(board
))
669 return (IS_HORUS_OR_TARANIS(board
) ? SWITCH_SF1
: SWITCH_THR
);
671 return IS_ARM(board
) ? 1 : 0;
673 return IS_TARANIS_X9E(board
) ? 1 : 0;
674 case GlobalFunctions
:
675 return IS_ARM(board
) ? 64 : 0;
677 return IS_ARM(board
) ? 32 : 0;
679 return HAS_LARGE_LCD(board
) ? 4 : 3;
681 return IS_ARM(board
) ? 16 : 8;
683 return IS_ARM(board
) || IS_2560(board
) ? 1 : 0;
685 return IS_HORUS_OR_TARANIS(board
) && id
.contains("lua") ? 7 : 0;
686 case LuaInputsPerScript
:
687 return IS_HORUS_OR_TARANIS(board
) ? 10 : 0;
688 case LuaOutputsPerScript
:
689 return IS_HORUS_OR_TARANIS(board
) ? 6 : 0;
692 return IS_ARM(board
);
694 return (IS_STOCK(board
) ? false : true);
695 case HasMahPersistent
:
696 return (IS_ARM(board
) ? true : false);
698 return IS_HORUS_OR_TARANIS(board
) ? 3 : 0;
699 case MultiposPotsPositions
:
700 return IS_HORUS_OR_TARANIS(board
) ? 6 : 0;
701 case SimulatorVariant
:
702 if (board
== BOARD_STOCK
)
703 return SIMU_STOCK_VARIANTS
;
704 else if (board
== BOARD_M128
)
705 return SIMU_M128_VARIANTS
;
706 else if (IS_TARANIS_X9E(board
))
707 return TARANIS_X9E_VARIANT
;
708 else if (IS_TARANIS_X7(board
))
709 return TARANIS_X7_VARIANT
;
712 case MavlinkTelemetry
:
713 return id
.contains("mavlink") ? 1 : 0;
715 return IS_ARM(board
) ? 1 : 0;
718 return (IS_HORUS_OR_TARANIS(board
) ? true : false);
719 case HasBatMeterRange
:
720 return (IS_HORUS_OR_TARANIS(board
) ? true : id
.contains("battgraph"));
721 case DangerousFunctions
:
722 return id
.contains("danger") ? 1 : 0;
723 case HasModelCategories
:
724 return IS_HORUS(board
);
730 QString
OpenTxFirmware::getAnalogInputName(unsigned int index
)
732 if ((int)index
< getBoardCapability(board
, Board::Sticks
)) {
733 const QString sticks
[] = {
739 return sticks
[index
];
742 index
-= getBoardCapability(board
, Board::Sticks
);
744 if (IS_9X(board
) || IS_2560(board
) || IS_SKY9X(board
)) {
745 const QString pots
[] = {
750 return CHECK_IN_ARRAY(pots
, index
);
752 else if (IS_TARANIS_X9E(board
)) {
753 const QString pots
[] = {
763 return CHECK_IN_ARRAY(pots
, index
);
765 else if (IS_TARANIS(board
)) {
766 const QString pots
[] = {
773 return CHECK_IN_ARRAY(pots
, index
);
775 else if (IS_HORUS(board
)) {
776 const QString pots
[] = {
787 return CHECK_IN_ARRAY(pots
, index
);
794 QTime
OpenTxFirmware::getMaxTimerStart()
796 if (IS_HORUS_OR_TARANIS(board
))
797 return QTime(23, 59, 59);
798 else if (IS_ARM(board
))
799 return QTime(8, 59, 59);
801 return QTime(0, 59, 59);
804 int OpenTxFirmware::isAvailable(PulsesProtocol proto
, int port
)
806 if (IS_HORUS_OR_TARANIS(board
)) {
811 case PULSES_PXX_XJT_X16
:
812 case PULSES_PXX_XJT_LR12
:
814 case PULSES_PXX_XJT_D8
:
815 return id
.contains("eu") ? 0 : 1;
817 return id
.contains("internalppm") ? 1 : 0;
826 case PULSES_PXX_XJT_X16
:
827 case PULSES_PXX_XJT_D8
:
828 case PULSES_PXX_XJT_LR12
:
829 //case PULSES_PXX_DJT: // Unavailable for now
833 case PULSES_CROSSFIRE
:
835 case PULSES_MULTIMODULE
:
836 return id
.contains("multimodule") ? 1 : 0;
853 else if (IS_SKY9X(board
)) {
858 case PULSES_PXX_XJT_X16
:
859 case PULSES_PXX_XJT_D8
:
860 case PULSES_PXX_XJT_LR12
:
865 case PULSES_MULTIMODULE
:
866 return id
.contains("multimodule") ? 1 : 0;
889 // case PULSES_PXX_DJT: // Unavailable for now
899 template<typename T
, size_t SIZE
>
900 size_t getSizeA(T (&)[SIZE
])
905 EepromLoadErrors
OpenTxEepromInterface::checkVersion(unsigned int version
)
911 // channel order is now always RUD - ELE - THR - AIL
913 // ppmFrameLength added
916 // mixers changed (for the trims use for change the offset of a mix)
917 // telemetry offset raised to -127 +127
918 // function switches now have a param on 4 bits
920 // telemetry changes (bars)
922 // mixer changes (differential, negative curves)...
925 // V4: Rotary Encoders position in FlightModes
927 // Trim value in 16bits
928 // FrSky A1/A2 offset on 12bits
929 // ARM: More Mixers / Expos / CSW / FSW / CHNOUT
931 // Add TrmR, TrmE, TrmT, TrmA as Mix sources
932 // Trims are now OFF / ON / Rud / Ele / Thr / Ail
934 // Add names in Mixes / Expos
935 // Add a new telemetry screen
936 // Add support for Play Track <filename>
940 // Big changes in mixers / limitse
942 // GVARS / Variants introduction
944 // Massive EEPROM change!
946 // M128 revert because too much RAM used!
948 // A lot of things (first github release)
950 // 3 logical switches removed on M128 / gruvin9x boards
961 bool OpenTxEepromInterface::checkVariant(unsigned int version
, unsigned int variant
)
963 if (board
== BOARD_M128
&& !(variant
& M128_VARIANT
)) {
964 if (version
== 212) {
966 for (int i
= 1; i
< 31; i
++) {
968 int sz
= efile
->readRlc2(tmp
, sizeof(tmp
));
970 std::cout
<< " warning: M128 variant not set (but model size seems ok)";
975 std::cout
<< " wrong variant (" << variant
<< ")";
978 else if (IS_TARANIS_X9E(board
)) {
979 if (variant
!= TARANIS_X9E_VARIANT
) {
980 std::cout
<< " wrong variant (" << variant
<< ")";
984 else if (IS_TARANIS_X7(board
)) {
985 if (variant
!= TARANIS_X7_VARIANT
) {
986 std::cout
<< " wrong variant (" << variant
<< ")";
990 else if (IS_TARANIS(board
)) {
992 std::cout
<< " wrong variant (" << variant
<< ")";
1001 OpenTxEepromInterface::loadModelFromBackup(ModelData
& model
, const uint8_t * data
, unsigned int size
, uint8_t version
, uint32_t variant
)
1003 QByteArray
backupData((char *) data
, size
);
1004 QByteArray modelData
;
1005 if (IS_SKY9X(board
)) {
1006 modelData
= QByteArray((char *) data
, size
);
1009 importRlc(modelData
, backupData
);
1011 if (modelData
.size()) {
1012 if (loadFromByteArray
<ModelData
, OpenTxModelData
>(model
, modelData
, version
, variant
)) {
1021 unsigned long OpenTxEepromInterface::loadBackup(RadioData
&radioData
, const uint8_t * eeprom
, int esize
, int index
)
1023 std::bitset
<NUM_ERRORS
> errors
;
1025 std::cout
<< "trying " << getName() << " backup import...";
1027 if (esize
< 8 || memcmp(eeprom
, "o9x", 3) != 0) {
1028 std::cout
<< " no\n";
1029 errors
.set(WRONG_SIZE
);
1030 return errors
.to_ulong();
1033 Type backupBoard
= (Type
) -1;
1034 switch (eeprom
[3]) {
1036 backupBoard
= BOARD_TARANIS_X9D
;
1039 backupBoard
= BOARD_SKY9X
;
1042 backupBoard
= BOARD_GRUVIN9X
;
1045 std::cout
<< " unknown board\n";
1046 errors
.set(UNKNOWN_BOARD
);
1047 return errors
.to_ulong();
1050 if (backupBoard
!= board
) {
1051 std::cout
<< " not right board\n";
1052 errors
.set(WRONG_BOARD
);
1053 return errors
.to_ulong();
1056 uint8_t version
= eeprom
[4];
1057 uint8_t bcktype
= eeprom
[5];
1058 uint16_t size
= ((uint16_t) eeprom
[7] << 8) + eeprom
[6];
1059 uint16_t variant
= ((uint16_t) eeprom
[9] << 8) + eeprom
[8];
1061 std::cout
<< " version " << (unsigned int) version
<< " ";
1063 EepromLoadErrors version_error
= checkVersion(version
);
1064 if (version_error
== OLD_VERSION
) {
1065 errors
.set(version_error
);
1066 errors
.set(HAS_WARNINGS
);
1068 else if (version_error
== NOT_OPENTX
) {
1069 std::cout
<< " not open9x\n";
1070 errors
.set(version_error
);
1071 return errors
.to_ulong();
1074 if (size
> esize
- 8) {
1075 std::cout
<< " wrong size\n";
1076 errors
.set(WRONG_SIZE
);
1077 return errors
.to_ulong();
1080 if (bcktype
== 'M') {
1081 if (!loadModelFromBackup(radioData
.models
[index
], &eeprom
[8], size
, version
, variant
)) {
1082 std::cout
<< " ko\n";
1083 errors
.set(UNKNOWN_ERROR
);
1084 return errors
.to_ulong();
1088 std::cout
<< " backup type not supported\n";
1089 errors
.set(BACKUP_NOT_SUPPORTED
);
1090 return errors
.to_ulong();
1093 std::cout
<< " ok\n";
1095 return errors
.to_ulong();
1098 QString
OpenTxFirmware::getFirmwareBaseUrl()
1100 #if defined(ALLOW_NIGHTLY_BUILDS)
1101 return (g
.useFirmwareNightlyBuilds() ? OPENTX_NIGHT_FIRMWARE_DOWNLOADS
: OPENTX_FIRMWARE_DOWNLOADS
);
1103 return OPENTX_FIRMWARE_DOWNLOADS
;
1107 QString
OpenTxFirmware::getFirmwareUrl()
1109 QString url
= getFirmwareBaseUrl();
1110 QByteArray data
= QUrl::toPercentEncoding(id
);
1113 url
.append(QString("/getfw.php?fw=%1.bin").arg((QString
) data
));
1115 url
.append(QString("/getfw.php?fw=%1.hex").arg((QString
) data
));
1119 QString
OpenTxFirmware::getReleaseNotesUrl()
1121 QString url
= getFirmwareBaseUrl();
1122 url
.append("/releasenotes.txt");
1126 QString
OpenTxFirmware::getStampUrl()
1128 QString url
= getFirmwareBaseUrl();
1129 url
.append("/stamp-opentx.txt");
1133 void addOpenTxCommonOptions(OpenTxFirmware
* firmware
)
1135 firmware
->addOption("ppmus", QObject::tr("Channel values displayed in us"));
1136 firmware
->addOption("nooverridech", QObject::tr("No OverrideCH functions available"));
1137 Option fai_options
[] = {{"faichoice", QObject::tr("Possibility to enable FAI MODE (no telemetry) at field")},
1138 {"faimode", QObject::tr("FAI MODE (no telemetry) always enabled")},
1140 firmware
->addOptions(fai_options
);
1143 void addOpenTxArmOptions(OpenTxFirmware
* firmware
)
1145 firmware
->addOption("multimodule", QObject::tr("Support for the DIY-Multiprotocol-TX-Module"));
1146 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"));
1149 void addOpenTxFrskyOptions(OpenTxFirmware
* firmware
)
1151 addOpenTxCommonOptions(firmware
);
1152 addOpenTxArmOptions(firmware
);
1153 firmware
->addOption("noheli", QObject::tr("Disable HELI menu and cyclic mix support"));
1154 firmware
->addOption("nogvars", QObject::tr("Disable Global variables"));
1155 firmware
->addOption("lua", QObject::tr("Support for Lua model scripts"));
1156 firmware
->addOption("luac", QObject::tr("Enable Lua compiler"));
1157 Option usb_options
[] = {{"massstorage", QObject::tr("Instead of Joystick emulation, USB connection is Mass Storage (as in the Bootloader)")},
1158 {"cli", QObject::tr("Instead of Joystick emulation, USB connection is Command Line Interface")},
1160 firmware
->addOptions(usb_options
);
1163 void addOpenTxTaranisOptions(OpenTxFirmware
* firmware
)
1165 addOpenTxFrskyOptions(firmware
);
1166 firmware
->addOption("internalppm", QObject::tr("Support for PPM internal module hack"));
1167 firmware
->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
1170 void addOpenTxLcdOptions(OpenTxFirmware
* firmware
)
1172 Option lcd_options
[] = {
1173 {"ST7565P", QObject::tr("ST7565P LCD or compatible")},
1174 {"ST7565R", QObject::tr("ST7565R LCD or compatible")},
1175 {"ERC12864FSF", QObject::tr("ERC12864FSF LCD")},
1176 {"ST7920", QObject::tr("ST7920 LCD")},
1177 {"KS108", QObject::tr("KS108 LCD")},
1180 firmware
->addOptions(lcd_options
);
1183 void addOpenTxVoiceOptions(OpenTxFirmware
* firmware
)
1185 Option voice_options
[] = {
1186 {"WTV20", QObject::tr("WTV20 voice module")},
1187 {"JQ6500", QObject::tr("JQ6500 voice module")},
1190 firmware
->addOptions(voice_options
);
1193 QList
<OpenTxEepromInterface
*> opentxEEpromInterfaces
;
1195 void registerOpenTxFirmware(OpenTxFirmware
* firmware
)
1197 OpenTxEepromInterface
* eepromInterface
= new OpenTxEepromInterface(firmware
);
1198 firmware
->setEEpromInterface(eepromInterface
);
1199 opentxEEpromInterfaces
.push_back(eepromInterface
);
1200 eepromInterfaces
.push_back(eepromInterface
);
1201 Firmware::addRegisteredFirmware(firmware
);
1204 void registerOpenTxFirmwares()
1206 OpenTxFirmware
* firmware
;
1208 Option ext_options
[] = {{"frsky", QObject::tr("Support for frsky telemetry mod"), FRSKY_VARIANT
},
1209 {"telemetrez", QObject::tr("Support for telemetry easy board"), FRSKY_VARIANT
},
1210 {"jeti", QObject::tr("Support for jeti telemetry mod"), 0},
1211 {"ardupilot", QObject::tr("Support for receiving ardupilot data"), 0},
1212 {"nmea", QObject::tr("Support for receiving NMEA data"), 0},
1213 {"mavlink", QObject::tr("Support for MAVLINK devices"), MAVLINK_VARIANT
},
1215 Option extr_options
[] = {{"frsky", QObject::tr("Support for frsky telemetry mod"), FRSKY_VARIANT
},
1216 {"jeti", QObject::tr("Support for jeti telemetry mod"), 0},
1217 {"ardupilot", QObject::tr("Support for receiving ardupilot data"), 0},
1218 {"nmea", QObject::tr("Support for receiving NMEA data"), 0},
1219 {"mavlink", QObject::tr("Support for MAVLINK devices"), MAVLINK_VARIANT
},
1221 Option nav_options
[] = {{"rotenc", QObject::tr("Rotary Encoder use in menus navigation")},
1222 {"potscroll", QObject::tr("Pots use in menus navigation")},
1224 Option dsm2_options
[] = {{"DSM2", QObject::tr("Support for DSM2 modules"), 0},
1225 {"DSM2PPM", QObject::tr("Support for DSM2 modules using ppm instead of true serial"), 0},
1228 /* FrSky Taranis X9D+ board */
1229 firmware
= new OpenTxFirmware("opentx-x9d+", QObject::tr("FrSky Taranis X9D+"), BOARD_TARANIS_X9DP
);
1230 addOpenTxTaranisOptions(firmware
);
1231 registerOpenTxFirmware(firmware
);
1233 /* FrSky Taranis X9D board */
1234 firmware
= new OpenTxFirmware("opentx-x9d", QObject::tr("FrSky Taranis X9D"), BOARD_TARANIS_X9D
);
1235 firmware
->addOption("haptic", QObject::tr("Haptic module installed"));
1236 addOpenTxTaranisOptions(firmware
);
1237 registerOpenTxFirmware(firmware
);
1239 /* FrSky Taranis X9E board */
1240 firmware
= new OpenTxFirmware("opentx-x9e", QObject::tr("FrSky Taranis X9E"), BOARD_TARANIS_X9E
);
1241 firmware
->addOption("shutdownconfirm", QObject::tr("Confirmation before radio shutdown"));
1242 firmware
->addOption("horussticks", QObject::tr("Horus gimbals installed (Hall sensors)"));
1243 addOpenTxTaranisOptions(firmware
);
1244 registerOpenTxFirmware(firmware
);
1246 /* FrSky X7 board */
1247 firmware
= new OpenTxFirmware("opentx-x7", QObject::tr("FrSky Taranis X7"), BOARD_TARANIS_X7
);
1248 // No mixersmon for now
1249 addOpenTxFrskyOptions(firmware
);
1250 firmware
->addOption("internalppm", QObject::tr("Support for PPM internal module hack"));
1251 firmware
->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
1252 registerOpenTxFirmware(firmware
);
1254 /* FrSky Horus board */
1255 firmware
= new OpenTxFirmware("opentx-x12s", QObject::tr("FrSky Horus"), BOARD_X12S
);
1256 addOpenTxFrskyOptions(firmware
);
1257 firmware
->addOption("pcbdev", QObject::tr("Use ONLY with first DEV pcb version"));
1258 registerOpenTxFirmware(firmware
);
1261 /* FrSky X10 board */
1263 firmware = new OpenTxFirmware("opentx-x10", QObject::tr("FrSky X10"), BOARD_X10);
1264 addOpenTxFrskyOptions(firmware);
1265 registerOpenTxFirmware(firmware);
1268 firmware
= new OpenTxFirmware("opentx-9xrpro", QObject::tr("Turnigy 9XR-PRO"), BOARD_9XRPRO
);
1269 firmware
->addOption("heli", QObject::tr("Enable HELI menu and cyclic mix support"));
1270 firmware
->addOption("nofp", QObject::tr("No flight modes"));
1271 firmware
->addOption("gvars", QObject::tr("Global variables"), GVARS_VARIANT
);
1272 firmware
->addOption("potscroll", QObject::tr("Pots use in menus navigation"));
1273 firmware
->addOption("autosource", QObject::tr("In model setup menus automatically set source by moving the control"));
1274 firmware
->addOption("autoswitch", QObject::tr("In model setup menus automatically set switch by moving the control"));
1275 firmware
->addOption("nographics", QObject::tr("No graphical check boxes and sliders"));
1276 firmware
->addOption("battgraph", QObject::tr("Battery graph"));
1277 firmware
->addOption("nobold", QObject::tr("Don't use bold font for highlighting active items"));
1278 firmware
->addOption("bluetooth", QObject::tr("Bluetooth interface"));
1279 firmware
->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
1280 addOpenTxArmOptions(firmware
);
1281 addOpenTxCommonOptions(firmware
);
1282 registerOpenTxFirmware(firmware
);
1284 /* 9XR board with M128 chip */
1285 firmware
= new OpenTxFirmware("opentx-9xr128", QObject::tr("Turnigy 9XR with m128 chip"), BOARD_M128
);
1286 firmware
->addOptions(extr_options
);
1287 firmware
->addOption("heli", QObject::tr("Enable heli menu and cyclic mix support"));
1288 firmware
->addOption("templates", QObject::tr("Enable TEMPLATES menu"));
1289 firmware
->addOption("nosplash", QObject::tr("No splash screen"));
1290 firmware
->addOption("nofp", QObject::tr("No flight modes"));
1291 firmware
->addOption("nocurves", QObject::tr("Disable curves menus"));
1292 firmware
->addOption("audio", QObject::tr("Support for radio modified with regular speaker"));
1293 firmware
->addOption("voice", QObject::tr("Used if you have modified your radio with voice mode"));
1294 firmware
->addOption("haptic", QObject::tr("Used if you have modified your radio with haptic mode"));
1295 // NOT TESTED firmware->addOption("PXX", QObject::tr("Support of FrSky PXX protocol"));
1296 firmware
->addOption("DSM2", QObject::tr("Support for DSM2 modules"));
1297 firmware
->addOption("ppmca", QObject::tr("PPM center adjustment in limits"));
1298 firmware
->addOption("gvars", QObject::tr("Global variables"), GVARS_VARIANT
);
1299 firmware
->addOption("symlimits", QObject::tr("Symetrical Limits"));
1300 firmware
->addOption("potscroll", QObject::tr("Pots use in menus navigation"));
1301 firmware
->addOption("autosource", QObject::tr("In model setup menus automatically set source by moving the control"));
1302 firmware
->addOption("autoswitch", QObject::tr("In model setup menus automatically set switch by moving the control"));
1303 firmware
->addOption("nographics", QObject::tr("No graphical check boxes and sliders"));
1304 firmware
->addOption("battgraph", QObject::tr("Battery graph"));
1305 firmware
->addOption("nobold", QObject::tr("Don't use bold font for highlighting active items"));
1306 firmware
->addOption("thrtrace", QObject::tr("Enable the throttle trace in Statistics"));
1307 firmware
->addOption("pgbar", QObject::tr("EEprom write Progress bar"));
1308 firmware
->addOption("imperial", QObject::tr("Imperial units"));
1309 firmware
->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
1310 addOpenTxCommonOptions(firmware
);
1311 registerOpenTxFirmware(firmware
);
1314 firmware
= new OpenTxFirmware("opentx-9xr", QObject::tr("Turnigy 9XR"), BOARD_STOCK
);
1315 firmware
->addOptions(extr_options
);
1316 firmware
->addOption("heli", QObject::tr("Enable heli menu and cyclic mix support"));
1317 firmware
->addOption("templates", QObject::tr("Enable TEMPLATES menu"));
1318 firmware
->addOption("nosplash", QObject::tr("No splash screen"));
1319 firmware
->addOption("nofp", QObject::tr("No flight modes"));
1320 firmware
->addOption("nocurves", QObject::tr("Disable curves menus"));
1321 firmware
->addOption("audio", QObject::tr("Support for radio modified with regular speaker"));
1322 firmware
->addOption("voice", QObject::tr("Used if you have modified your radio with voice mode"));
1323 firmware
->addOption("haptic", QObject::tr("Used if you have modified your radio with haptic mode"));
1324 // NOT TESTED firmware->addOption("PXX", QObject::tr("Support of FrSky PXX protocol"));
1325 firmware
->addOption("DSM2", QObject::tr("Support for DSM2 modules"));
1326 firmware
->addOption("ppmca", QObject::tr("PPM center adjustment in limits"));
1327 firmware
->addOption("gvars", QObject::tr("Global variables"), GVARS_VARIANT
);
1328 firmware
->addOption("symlimits", QObject::tr("Symetrical Limits"));
1329 firmware
->addOption("potscroll", QObject::tr("Pots use in menus navigation"));
1330 firmware
->addOption("autosource", QObject::tr("In model setup menus automatically set source by moving the control"));
1331 firmware
->addOption("autoswitch", QObject::tr("In model setup menus automatically set switch by moving the control"));
1332 firmware
->addOption("nographics", QObject::tr("No graphical check boxes and sliders"));
1333 firmware
->addOption("battgraph", QObject::tr("Battery graph"));
1334 firmware
->addOption("nobold", QObject::tr("Don't use bold font for highlighting active items"));
1335 firmware
->addOption("thrtrace", QObject::tr("Enable the throttle trace in Statistics"));
1336 firmware
->addOption("pgbar", QObject::tr("EEprom write Progress bar"));
1337 firmware
->addOption("imperial", QObject::tr("Imperial units"));
1338 firmware
->addOption("nowshh", QObject::tr("No Winged Shadow How High support"));
1339 firmware
->addOption("novario", QObject::tr("No vario support"));
1340 firmware
->addOption("nogps", QObject::tr("No GPS support"));
1341 firmware
->addOption("nogauges", QObject::tr("No gauges in the custom telemetry screen"));
1342 firmware
->addOption("stickrev", QObject::tr("Add support for reversing stick inputs (e.g. needed for FrSky gimbals)"));
1343 firmware
->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
1344 addOpenTxCommonOptions(firmware
);
1345 registerOpenTxFirmware(firmware
);
1348 firmware
= new OpenTxFirmware("opentx-9x", QObject::tr("9X with stock board"), BOARD_STOCK
);
1349 firmware
->addOptions(ext_options
);
1350 firmware
->addOption("heli", QObject::tr("Enable heli menu and cyclic mix support"));
1351 firmware
->addOption("templates", QObject::tr("Enable TEMPLATES menu"));
1352 firmware
->addOption("nosplash", QObject::tr("No splash screen"));
1353 firmware
->addOption("nofp", QObject::tr("No flight modes"));
1354 firmware
->addOption("nocurves", QObject::tr("Disable curves menus"));
1355 firmware
->addOption("audio", QObject::tr("Support for radio modified with regular speaker"));
1356 firmware
->addOption("voice", QObject::tr("Used if you have modified your radio with voice mode"));
1357 firmware
->addOption("haptic", QObject::tr("Used if you have modified your radio with haptic mode"));
1358 // NOT TESTED firmware->addOption("PXX", QObject::tr("Support of FrSky PXX protocol"));
1359 firmware
->addOption("DSM2", QObject::tr("Support for DSM2 modules"));
1360 firmware
->addOption("ppmca", QObject::tr("PPM center adjustment in limits"));
1361 firmware
->addOption("gvars", QObject::tr("Global variables"), GVARS_VARIANT
);
1362 firmware
->addOption("symlimits", QObject::tr("Symetrical Limits"));
1363 firmware
->addOptions(nav_options
);
1364 firmware
->addOption("sp22", QObject::tr("SmartieParts 2.2 Backlight support"));
1365 firmware
->addOption("autosource", QObject::tr("In model setup menus automatically set source by moving the control"));
1366 firmware
->addOption("autoswitch", QObject::tr("In model setup menus automatically set switch by moving the control"));
1367 firmware
->addOption("dblkeys", QObject::tr("Enable resetting values by pressing up and down at the same time"));
1368 firmware
->addOption("nographics", QObject::tr("No graphical check boxes and sliders"));
1369 firmware
->addOption("battgraph", QObject::tr("Battery graph"));
1370 firmware
->addOption("nobold", QObject::tr("Don't use bold font for highlighting active items"));
1371 firmware
->addOption("thrtrace", QObject::tr("Enable the throttle trace in Statistics"));
1372 firmware
->addOption("pgbar", QObject::tr("EEprom write progress bar"));
1373 firmware
->addOption("imperial", QObject::tr("Imperial units"));
1374 firmware
->addOption("nowshh", QObject::tr("No Winged Shadow How High support"));
1375 firmware
->addOption("novario", QObject::tr("No vario support"));
1376 firmware
->addOption("nogps", QObject::tr("No GPS support"));
1377 firmware
->addOption("nogauges", QObject::tr("No gauges in the custom telemetry screen"));
1378 firmware
->addOption("fasoffset", QObject::tr("Allow compensating for offset errors in FrSky FAS current sensors"));
1379 firmware
->addOption("stickrev", QObject::tr("Add support for reversing stick inputs (e.g. needed for FrSky gimbals)"));
1380 firmware
->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
1381 addOpenTxCommonOptions(firmware
);
1382 registerOpenTxFirmware(firmware
);
1384 /* 9x board with M128 chip */
1385 firmware
= new OpenTxFirmware("opentx-9x128", QObject::tr("9X with stock board and m128 chip"), BOARD_M128
);
1386 firmware
->addOptions(ext_options
);
1387 firmware
->addOption("heli", QObject::tr("Enable heli menu and cyclic mix support"));
1388 firmware
->addOption("templates", QObject::tr("Enable TEMPLATES menu"));
1389 firmware
->addOption("nosplash", QObject::tr("No splash screen"));
1390 firmware
->addOption("nofp", QObject::tr("No flight modes"));
1391 firmware
->addOption("nocurves", QObject::tr("Disable curves menus"));
1392 firmware
->addOption("audio", QObject::tr("Support for radio modified with regular speaker"));
1393 firmware
->addOption("voice", QObject::tr("Used if you have modified your radio with voice mode"));
1394 firmware
->addOption("haptic", QObject::tr("Used if you have modified your radio with haptic mode"));
1395 // NOT TESTED firmware->addOption("PXX", QObject::tr("Support of FrSky PXX protocol"));
1396 firmware
->addOption("DSM2", QObject::tr("Support for DSM2 modules"));
1397 firmware
->addOption("ppmca", QObject::tr("PPM center adjustment in limits"));
1398 firmware
->addOption("gvars", QObject::tr("Global variables"), GVARS_VARIANT
);
1399 firmware
->addOption("symlimits", QObject::tr("Symetrical Limits"));
1400 firmware
->addOptions(nav_options
);
1401 firmware
->addOption("sp22", QObject::tr("SmartieParts 2.2 Backlight support"));
1402 firmware
->addOption("autosource", QObject::tr("In model setup menus automatically set source by moving the control"));
1403 firmware
->addOption("autoswitch", QObject::tr("In model setup menus automatically set switch by moving the control"));
1404 firmware
->addOption("dblkeys", QObject::tr("Enable resetting values by pressing up and down at the same time"));
1405 firmware
->addOption("nographics", QObject::tr("No graphical check boxes and sliders"));
1406 firmware
->addOption("battgraph", QObject::tr("Battery graph"));
1407 firmware
->addOption("nobold", QObject::tr("Don't use bold font for highlighting active items"));
1408 firmware
->addOption("thrtrace", QObject::tr("Enable the throttle trace in Statistics"));
1409 firmware
->addOption("pgbar", QObject::tr("EEprom write Progress bar"));
1410 firmware
->addOption("imperial", QObject::tr("Imperial units"));
1411 firmware
->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
1412 addOpenTxCommonOptions(firmware
);
1413 registerOpenTxFirmware(firmware
);
1416 firmware
= new OpenTxFirmware("opentx-ar9x", QObject::tr("9X with AR9X board"), BOARD_AR9X
);
1417 firmware
->addOption("heli", QObject::tr("Enable HELI menu and cyclic mix support"));
1418 firmware
->addOption("nofp", QObject::tr("No flight modes"));
1419 firmware
->addOption("gvars", QObject::tr("Global variables"), GVARS_VARIANT
);
1420 firmware
->addOption("potscroll", QObject::tr("Pots use in menus navigation"));
1421 firmware
->addOption("autosource", QObject::tr("In model setup menus automatically set source by moving the control"));
1422 firmware
->addOption("autoswitch", QObject::tr("In model setup menus automatically set switch by moving the control"));
1423 firmware
->addOption("dblkeys", QObject::tr("Enable resetting values by pressing up and down at the same time"));
1424 firmware
->addOption("nographics", QObject::tr("No graphical check boxes and sliders"));
1425 firmware
->addOption("battgraph", QObject::tr("Battery graph"));
1426 firmware
->addOption("nobold", QObject::tr("Don't use bold font for highlighting active items"));
1427 firmware
->addOption("bluetooth", QObject::tr("Bluetooth interface"));
1428 firmware
->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
1429 // firmware->addOption("rtc", QObject::tr("Optional RTC added"));
1430 // firmware->addOption("volume", QObject::tr("i2c volume control added"));
1431 addOpenTxArmOptions(firmware
);
1432 addOpenTxCommonOptions(firmware
);
1433 registerOpenTxFirmware(firmware
);
1436 firmware
= new OpenTxFirmware("opentx-sky9x", QObject::tr("9X with Sky9x board"), BOARD_SKY9X
);
1437 firmware
->addOption("heli", QObject::tr("Enable HELI menu and cyclic mix support"));
1438 firmware
->addOption("nofp", QObject::tr("No flight modes"));
1439 firmware
->addOption("gvars", QObject::tr("Global variables"), GVARS_VARIANT
);
1440 firmware
->addOption("potscroll", QObject::tr("Pots use in menus navigation"));
1441 firmware
->addOption("autosource", QObject::tr("In model setup menus automatically set source by moving the control"));
1442 firmware
->addOption("autoswitch", QObject::tr("In model setup menus automatically set switch by moving the control"));
1443 firmware
->addOption("dblkeys", QObject::tr("Enable resetting values by pressing up and down at the same time"));
1444 firmware
->addOption("nographics", QObject::tr("No graphical check boxes and sliders"));
1445 firmware
->addOption("battgraph", QObject::tr("Battery graph"));
1446 firmware
->addOption("nobold", QObject::tr("Don't use bold font for highlighting active items"));
1447 firmware
->addOption("bluetooth", QObject::tr("Bluetooth interface"));
1448 firmware
->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
1449 addOpenTxArmOptions(firmware
);
1450 addOpenTxCommonOptions(firmware
);
1451 registerOpenTxFirmware(firmware
);
1453 /* Gruvin9x board */
1454 firmware
= new OpenTxFirmware("opentx-gruvin9x", QObject::tr("9X with Gruvin9x board"), BOARD_GRUVIN9X
);
1455 firmware
->addOption("heli", QObject::tr("Enable heli menu and cyclic mix support"));
1456 firmware
->addOption("templates", QObject::tr("Enable TEMPLATES menu"));
1457 firmware
->addOption("nofp", QObject::tr("No flight modes"));
1458 firmware
->addOption("nocurves", QObject::tr("Disable curves menus"));
1459 firmware
->addOption("sdcard", QObject::tr("Support for SD memory card"));
1460 firmware
->addOption("voice", QObject::tr("Used if you have modified your radio with voice mode"));
1461 firmware
->addOption("PXX", QObject::tr("Support of FrSky PXX protocol"));
1462 firmware
->addOptions(dsm2_options
);
1463 firmware
->addOption("ppmca", QObject::tr("PPM center adjustment in limits"));
1464 firmware
->addOption("gvars", QObject::tr("Global variables"), GVARS_VARIANT
);
1465 firmware
->addOption("symlimits", QObject::tr("Symetrical Limits"));
1466 firmware
->addOption("potscroll", QObject::tr("Pots use in menus navigation"));
1467 firmware
->addOption("autosource", QObject::tr("In model setup menus automatically set source by moving the control"));
1468 firmware
->addOption("autoswitch", QObject::tr("In model setup menus automatically set switch by moving the control"));
1469 firmware
->addOption("dblkeys", QObject::tr("Enable resetting values by pressing up and down at the same time"));
1470 firmware
->addOption("nographics", QObject::tr("No graphical check boxes and sliders"));
1471 firmware
->addOption("battgraph", QObject::tr("Battery graph"));
1472 firmware
->addOption("nobold", QObject::tr("Don't use bold font for highlighting active items"));
1473 firmware
->addOption("pgbar", QObject::tr("EEprom write Progress bar"));
1474 firmware
->addOption("imperial", QObject::tr("Imperial units"));
1475 firmware
->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
1476 addOpenTxCommonOptions(firmware
);
1477 registerOpenTxFirmware(firmware
);
1479 /* MEGA2560 board */
1480 firmware
= new OpenTxFirmware("opentx-mega2560", QObject::tr("DIY MEGA2560 radio"), BOARD_MEGA2560
);
1481 addOpenTxLcdOptions(firmware
);
1482 firmware
->addOption("PWR", QObject::tr("Power management by soft-off circuitry"));
1483 firmware
->addOptions(ext_options
);
1484 firmware
->addOption("PXX", QObject::tr("Support of FrSky PXX protocol"));
1485 firmware
->addOptions(dsm2_options
);
1486 firmware
->addOption("heli", QObject::tr("Enable heli menu and cyclic mix support"));
1487 firmware
->addOption("templates", QObject::tr("Enable TEMPLATES menu"));
1488 firmware
->addOption("nofp", QObject::tr("No flight modes"));
1489 firmware
->addOption("nocurves", QObject::tr("Disable curves menus"));
1490 firmware
->addOption("sdcard", QObject::tr("Support for SD memory card"));
1491 firmware
->addOption("audio", QObject::tr("Support for radio modified with regular speaker"));
1492 //firmware->addOption("voice", QObject::tr("Used if you have modified your radio with voice mode"));
1493 addOpenTxVoiceOptions(firmware
);
1494 firmware
->addOption("haptic", QObject::tr("Used if you have modified your radio with haptic mode"));
1495 firmware
->addOption("ppmca", QObject::tr("PPM center adjustment in limits"));
1496 firmware
->addOption("gvars", QObject::tr("Global variables"), GVARS_VARIANT
);
1497 firmware
->addOption("symlimits", QObject::tr("Symetrical Limits"));
1498 firmware
->addOption("autosource", QObject::tr("In model setup menus automatically set source by moving the control"));
1499 firmware
->addOption("autoswitch", QObject::tr("In model setup menus automatically set switch by moving the control"));
1500 firmware
->addOption("dblkeys", QObject::tr("Enable resetting values by pressing up and down at the same time"));
1501 firmware
->addOption("nographics", QObject::tr("No graphical check boxes and sliders"));
1502 firmware
->addOption("battgraph", QObject::tr("Battery graph"));
1503 firmware
->addOption("nobold", QObject::tr("Don't use bold font for highlighting active items"));
1504 firmware
->addOption("pgbar", QObject::tr("EEprom write Progress bar"));
1505 firmware
->addOption("imperial", QObject::tr("Imperial units"));
1506 firmware
->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
1507 addOpenTxCommonOptions(firmware
);
1508 registerOpenTxFirmware(firmware
);
1510 Firmware::setDefaultVariant(Firmware::getFirmwareForId("opentx-x9d+"));
1511 Firmware::setCurrentVariant(Firmware::getDefaultVariant());
1514 void unregisterOpenTxFirmwares()
1516 foreach (Firmware
* f
, Firmware::getRegisteredFirmwares()) {
1519 unregisterEEpromInterfaces();
1522 template <class T
, class M
>
1523 OpenTxEepromInterface
* loadFromByteArray(T
& dest
, const QByteArray
& data
)
1525 foreach(OpenTxEepromInterface
* eepromInterface
, opentxEEpromInterfaces
) {
1526 if (eepromInterface
->loadFromByteArray
<T
, M
>(dest
, data
)) {
1527 return eepromInterface
;
1533 template <class T
, class M
>
1534 bool saveToByteArray(const T
& dest
, QByteArray
& data
)
1536 Board::Type board
= getCurrentBoard();
1537 foreach(OpenTxEepromInterface
* eepromInterface
, opentxEEpromInterfaces
) {
1538 if (eepromInterface
->getBoard() == board
) {
1539 return eepromInterface
->saveToByteArray
<T
, M
>(dest
, data
);
1545 OpenTxEepromInterface
* loadModelFromByteArray(ModelData
& model
, const QByteArray
& data
)
1547 return loadFromByteArray
<ModelData
, OpenTxModelData
>(model
, data
);
1550 OpenTxEepromInterface
* loadRadioSettingsFromByteArray(GeneralSettings
& settings
, const QByteArray
& data
)
1552 return loadFromByteArray
<GeneralSettings
, OpenTxGeneralData
>(settings
, data
);
1555 bool writeModelToByteArray(const ModelData
& model
, QByteArray
& data
)
1557 return saveToByteArray
<ModelData
, OpenTxModelData
>(model
, data
);
1560 bool writeRadioSettingsToByteArray(const GeneralSettings
& settings
, QByteArray
& data
)
1562 return saveToByteArray
<GeneralSettings
, OpenTxGeneralData
>(settings
, data
);