diff --git a/CMakeLists.txt b/CMakeLists.txt index d22e65cc7..69c809f6e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ set(VERSION_REVISION "0") set(VERSION_SUFFIX $ENV{OPENTX_VERSION_SUFFIX}) set(VERSION_FAMILY ${VERSION_MAJOR}.${VERSION_MINOR}) set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}${VERSION_SUFFIX}) -set(SDCARD_REVISION "0019") +set(SDCARD_REVISION "0020") set(SDCARD_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}V${SDCARD_REVISION}) cmake_minimum_required(VERSION 2.8) @@ -193,4 +193,15 @@ add_subdirectory(${RADIO_SRC_DIRECTORY}) if(Qt5Core_FOUND AND NOT DISABLE_COMPANION) add_subdirectory(${COMPANION_SRC_DIRECTORY}) + add_custom_target(gtests DEPENDS gtests-radio gtests-companion) + add_custom_target(tests + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/gtests-radio && ${CMAKE_CURRENT_BINARY_DIR}/gtests-companion + DEPENDS gtests + ) +else() + add_custom_target(gtests DEPENDS gtests-radio) + add_custom_target(tests + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/gtests-radio + DEPENDS gtests + ) endif() diff --git a/CREDITS.txt b/CREDITS.txt index af9c13330..84e03e4f3 100644 --- a/CREDITS.txt +++ b/CREDITS.txt @@ -1533,3 +1533,5 @@ Sascha Heinrich James Snodgrass Alain Labonne Darko Perković +Pierre Malriq +Donald Manson diff --git a/companion/src/CMakeLists.txt b/companion/src/CMakeLists.txt index d5fd9976d..c2cccc6d1 100644 --- a/companion/src/CMakeLists.txt +++ b/companion/src/CMakeLists.txt @@ -326,6 +326,10 @@ set(simu_SRCS simulator.cpp ) add_executable(${SIMULATOR_NAME} MACOSX_BUNDLE ${WIN_EXECUTABLE_TYPE} ${simu_SRCS} ${icon_RC}) target_link_libraries(${SIMULATOR_NAME} PRIVATE ${CPN_COMMON_LIB}) +if(NOT MSVC) + add_subdirectory(tests) +endif() + ############# Install #################### # Generate list of simulator plugins, used by all platforms @@ -341,6 +345,8 @@ if(PCB STREQUAL X7 AND PCBREV STREQUAL T12) set(FLAVOUR t12) elseif(PCB STREQUAL X9D+ AND PCBREV STREQUAL 2019) set(FLAVOUR x9d+2019) +elseif(PCB STREQUAL X10 AND PCBREV STREQUAL EXPRESS) + set(FLAVOUR x10express) else() string(TOLOWER ${PCB} FLAVOUR) endif() diff --git a/companion/src/apppreferencesdialog.cpp b/companion/src/apppreferencesdialog.cpp index 6ee389b89..36c46a5b4 100644 --- a/companion/src/apppreferencesdialog.cpp +++ b/companion/src/apppreferencesdialog.cpp @@ -188,7 +188,7 @@ void AppPreferencesDialog::initSettings() ui->backLightColor->setCurrentIndex(g.backLight()); ui->volumeGain->setValue(profile.volumeGain() / 10.0); - if (IS_TARANIS(getCurrentBoard())) { + if (IS_HORUS_OR_TARANIS(getCurrentBoard())) { ui->backLightColor->setEnabled(false); } diff --git a/companion/src/firmwares/boards.cpp b/companion/src/firmwares/boards.cpp index f753b354e..ee4edd921 100644 --- a/companion/src/firmwares/boards.cpp +++ b/companion/src/firmwares/boards.cpp @@ -59,6 +59,7 @@ uint32_t Boards::getFourCC(Type board) case BOARD_X12S: return 0x3478746F; case BOARD_X10: + case BOARD_X10_EXPRESS: return 0x3778746F; case BOARD_TARANIS_XLITE: return 0x3978746F; @@ -122,6 +123,7 @@ const int Boards::getEEpromSize(Board::Type board) return EESIZE_MAX; case BOARD_X12S: case BOARD_X10: + case BOARD_X10_EXPRESS: return 0; } @@ -155,6 +157,7 @@ const int Boards::getFlashSize(Type board) return FSIZE_TARANIS; case BOARD_X12S: case BOARD_X10: + case BOARD_X10_EXPRESS: return FSIZE_HORUS; case BOARD_UNKNOWN: return FSIZE_MAX; @@ -333,14 +336,12 @@ const int Boards::getCapability(Board::Type board, Board::Capability capability) return 8; else if (IS_JUMPER_T12(board)) return 6; - else if (IS_TARANIS_XLITES(board)) - return 6; else if (IS_TARANIS_XLITE(board)) return 6; - else if (IS_TARANIS(board)) - return 8; else if (board == Board::BOARD_TARANIS_X9DP_2019) return 9; + else if (IS_TARANIS(board)) + return 8; else if (IS_HORUS(board)) return 10; else @@ -524,6 +525,8 @@ const QString Boards::getBoardName(Board::Type board) return "Horus X12S"; case BOARD_X10: return "Horus X10/X10S"; + case BOARD_X10_EXPRESS: + return "Horus X10 Express"; default: return tr("Unknown"); } diff --git a/companion/src/firmwares/boards.h b/companion/src/firmwares/boards.h index 1533107c3..545d06551 100644 --- a/companion/src/firmwares/boards.h +++ b/companion/src/firmwares/boards.h @@ -46,6 +46,7 @@ namespace Board { BOARD_TARANIS_X9E, BOARD_X12S, BOARD_X10, + BOARD_X10_EXPRESS, BOARD_TARANIS_XLITE, BOARD_TARANIS_XLITES, BOARD_TARANIS_X9LITE, @@ -206,12 +207,11 @@ class Boards #define IS_TARANIS(board) (IS_TARANIS_X9(board) || IS_TARANIS_X7(board) || IS_TARANIS_X9LITE(board) || IS_TARANIS_XLITE(board) || IS_JUMPER_T12(board)) #define IS_TARANIS_SMALL(board) (IS_TARANIS_X7(board) || IS_TARANIS_XLITE(board) || IS_TARANIS_X9LITE(board) || IS_JUMPER_T12(board)) #define IS_HORUS_X12S(board) (board==Board::BOARD_X12S) -#define IS_HORUS_X10(board) (board==Board::BOARD_X10) +#define IS_HORUS_X10(board) (board==Board::BOARD_X10 || board==Board::BOARD_X10_EXPRESS) #define IS_HORUS(board) (IS_HORUS_X12S(board) || IS_HORUS_X10(board)) #define IS_HORUS_OR_TARANIS(board) (IS_HORUS(board) || IS_TARANIS(board)) #define IS_STM32(board) (IS_TARANIS(board) || IS_HORUS(board)) #define IS_ARM(board) (IS_STM32(board) || IS_SKY9X(board)) -#define IS_ACCESS_RADIO(board) (IS_TARANIS_X9LITE(board) || IS_TARANIS_XLITES(board)) #define HAS_LARGE_LCD(board) (IS_HORUS(board) || IS_TARANIS_X9(board)) #endif // _BOARDS_H_ diff --git a/companion/src/firmwares/eepromimportexport.h b/companion/src/firmwares/eepromimportexport.h index e5cbab7e5..be562fb41 100644 --- a/companion/src/firmwares/eepromimportexport.h +++ b/companion/src/firmwares/eepromimportexport.h @@ -585,6 +585,78 @@ class TransformedField: public DataField { DataField & field; }; +template +class UnionField: public DataField { + public: + + class UnionMember { + public: + virtual ~UnionMember() {} + virtual bool select(const selectorT& attr) const = 0; + virtual DataField* getField() = 0; + }; + + class TransformedMember: public UnionMember, public TransformedField { + public: + TransformedMember(DataField* parent, DataField& field): + TransformedField(parent, field) + { + } + virtual DataField* getField() + { + return this; + } + }; + + UnionField(DataField * parent, selectorT& selectField, const char * name="Union"): + DataField(parent, name), selectField(selectField), maxSize(0) + { + } + + ~UnionField() { + foreach(UnionMember *member, members) { + delete member; + } + } + + inline void Append(UnionMember * member) { + members.append(member); + if (member->getField()->size() > maxSize) + maxSize = member->getField()->size(); + } + + virtual void ExportBits(QBitArray & output) + { + foreach(UnionMember *member, members) { + if (member->select(selectField)) { + member->getField()->ExportBits(output); + break; + } + } + output.resize(maxSize); + } + + virtual void ImportBits(const QBitArray & input) + { + foreach(UnionMember *member, members) { + if (member->select(selectField)) { + member->getField()->ImportBits(input); + break; + } + } + } + + virtual unsigned int size() + { + return maxSize; + } + + protected: + selectorT& selectField; + QList members; + unsigned int maxSize; +}; + class ConversionTable { public: diff --git a/companion/src/firmwares/eeprominterface.cpp b/companion/src/firmwares/eeprominterface.cpp index c1aee1b7b..d4121a8a4 100644 --- a/companion/src/firmwares/eeprominterface.cpp +++ b/companion/src/firmwares/eeprominterface.cpp @@ -103,20 +103,18 @@ void EEPROMInterface::showEepromErrors(QWidget *parent, const QString &title, co #endif // TODO: No GUI here, e.g. return string list instead -void EEPROMInterface::showEepromWarnings(QWidget *parent, const QString &title, unsigned long errorsFound) +QString EEPROMInterface::getEepromWarnings(unsigned long errorsFound) { std::bitset errors((unsigned long long)errorsFound); QStringList warningsList; - if (errors.test(WARNING_WRONG_FIRMWARE)) { warningsList << tr("- Your radio probably uses a wrong firmware,\n eeprom size is 4096 but only the first 2048 are used"); } - if (errors.test(OLD_VERSION)) { warningsList << tr("- Your eeprom is from an old version of OpenTX, upgrading!\n To keep your original file as a backup, please choose File -> Save As specifying a different name."); } + if (errors.test(WARNING_WRONG_FIRMWARE)) { + warningsList << tr("- Your radio probably uses a wrong firmware,\n eeprom size is 4096 but only the first 2048 are used"); + } + if (errors.test(OLD_VERSION)) { + warningsList << tr("- Your eeprom is from an old version of OpenTX, upgrading!\n To keep your original file as a backup, please choose File -> Save As specifying a different name."); + } - QMessageBox msgBox(parent); - msgBox.setWindowTitle(title); - msgBox.setIcon(QMessageBox::Warning); - msgBox.setText(tr("Warnings!")); - msgBox.setInformativeText(warningsList.join("\n")); - msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.exec(); + return warningsList.join("\n"); } diff --git a/companion/src/firmwares/eeprominterface.h b/companion/src/firmwares/eeprominterface.h index b562f50e9..9632af1ac 100644 --- a/companion/src/firmwares/eeprominterface.h +++ b/companion/src/firmwares/eeprominterface.h @@ -178,7 +178,7 @@ class EEPROMInterface virtual int getSize(const GeneralSettings &) = 0; //static void showEepromErrors(QWidget *parent, const QString &title, const QString &mainMessage, unsigned long errorsFound); - static void showEepromWarnings(QWidget *parent, const QString &title, unsigned long errorsFound); + static QString getEepromWarnings(unsigned long errorsFound); protected: @@ -345,7 +345,7 @@ class Firmware virtual QTime getMaxTimerStart() = 0; - virtual int isAvailable(PulsesProtocol proto, int port=0) = 0; + virtual bool isAvailable(PulsesProtocol proto, int port=0) = 0; const int getFlashSize(); diff --git a/companion/src/firmwares/er9x/er9xinterface.cpp b/companion/src/firmwares/er9x/er9xinterface.cpp index e3ef6d424..65bc81804 100644 --- a/companion/src/firmwares/er9x/er9xinterface.cpp +++ b/companion/src/firmwares/er9x/er9xinterface.cpp @@ -203,7 +203,7 @@ int Er9xInterface::getSize(const GeneralSettings &settings) return 0; } -int Er9xInterface::isAvailable(PulsesProtocol prot, int port) +bool Er9xInterface::isAvailable(PulsesProtocol prot, int port) { switch (prot) { case PULSES_PPM: diff --git a/companion/src/firmwares/er9x/er9xinterface.h b/companion/src/firmwares/er9x/er9xinterface.h index 469ad9cd0..ec3d9cc1a 100644 --- a/companion/src/firmwares/er9x/er9xinterface.h +++ b/companion/src/firmwares/er9x/er9xinterface.h @@ -52,7 +52,7 @@ class Er9xInterface : public EEPROMInterface virtual int getSize(const GeneralSettings &settings); - virtual int isAvailable(PulsesProtocol proto, int port=0); + virtual bool isAvailable(PulsesProtocol proto, int port=0); virtual int getCapability(Capability capability); diff --git a/companion/src/firmwares/ersky9x/ersky9xinterface.cpp b/companion/src/firmwares/ersky9x/ersky9xinterface.cpp index 0e7e87e01..5c2a35edb 100644 --- a/companion/src/firmwares/ersky9x/ersky9xinterface.cpp +++ b/companion/src/firmwares/ersky9x/ersky9xinterface.cpp @@ -251,7 +251,7 @@ int Ersky9xInterface::getSize(const GeneralSettings & settings) return 0; } -int Ersky9xInterface::isAvailable(PulsesProtocol prot, int port) +bool Ersky9xInterface::isAvailable(PulsesProtocol prot, int port) { switch (prot) { case PULSES_PPM: diff --git a/companion/src/firmwares/ersky9x/ersky9xinterface.h b/companion/src/firmwares/ersky9x/ersky9xinterface.h index 6d815190f..c5aabdb07 100644 --- a/companion/src/firmwares/ersky9x/ersky9xinterface.h +++ b/companion/src/firmwares/ersky9x/ersky9xinterface.h @@ -51,7 +51,7 @@ class Ersky9xInterface : public EEPROMInterface virtual int getSize(const GeneralSettings & settings); - virtual int isAvailable(PulsesProtocol proto, int port=0); + virtual bool isAvailable(PulsesProtocol proto, int port=0); virtual int getCapability(Capability capability); diff --git a/companion/src/firmwares/modeldata.cpp b/companion/src/firmwares/modeldata.cpp index b615fd649..b3d4f82fa 100644 --- a/companion/src/firmwares/modeldata.cpp +++ b/companion/src/firmwares/modeldata.cpp @@ -163,8 +163,9 @@ void ModelData::clear() moduleData[0].ppm.delay = 300; moduleData[1].ppm.delay = 300; moduleData[2].ppm.delay = 300; - int board = getCurrentBoard(); - if (IS_ACCESS_RADIO(board)) { + Firmware * firmware = Firmware::getCurrentVariant(); + int board = firmware->getBoard(); + if (firmware->isAvailable(PULSES_ACCESS_ISRM, 0)) { moduleData[0].protocol = PULSES_ACCESS_ISRM; moduleData[1].protocol = PULSES_OFF; } diff --git a/companion/src/firmwares/moduledata.cpp b/companion/src/firmwares/moduledata.cpp index cd72f01f1..d2cc4fd1b 100644 --- a/companion/src/firmwares/moduledata.cpp +++ b/companion/src/firmwares/moduledata.cpp @@ -30,6 +30,20 @@ void ModuleData::convert(RadioDataConversionState & cstate) } } +bool ModuleData::isPxx2Module() const +{ + switch(protocol){ + case PULSES_ACCESS_ISRM: + case PULSES_ACCESS_R9M: + case PULSES_ACCESS_R9M_LITE: + case PULSES_ACCESS_R9M_LITE_PRO: + case PULSES_XJT_LITE_X16: + return true; + default: + return false; + } +} + QString ModuleData::rfProtocolToString() const { switch (protocol) { @@ -105,11 +119,13 @@ QString ModuleData::protocolToString(unsigned protocol) "DIY Multiprotocol Module", "FrSky PXX R9M", "FrSky PXX R9M Lite", + "FrSky PXX R9M Lite Pro", "SBUS output at VBat", - "FrSky ACCESS ISRM", + "FrSky ACCESS ISRM", "FrSky ACCST ISRM D16", "FrSky ACCESS R9M", "FrSky ACCESS R9M Lite", - "FrSky ACCESS R9M Lite Pro" + "FrSky ACCESS R9M Lite Pro", + "FrSky XJT lite (D16)", "FrSky XJT lite (D8)", "FrSky XJT lite (LR12)" }; return CHECK_IN_ARRAY(strings, protocol); diff --git a/companion/src/firmwares/moduledata.h b/companion/src/firmwares/moduledata.h index d431b6e3c..e87d7475f 100644 --- a/companion/src/firmwares/moduledata.h +++ b/companion/src/firmwares/moduledata.h @@ -48,11 +48,16 @@ enum PulsesProtocol { PULSES_MULTIMODULE, PULSES_PXX_R9M, PULSES_PXX_R9M_LITE, + PULSES_PXX_R9M_LITE_PRO, PULSES_SBUS, PULSES_ACCESS_ISRM, + PULSES_ACCST_ISRM_D16, PULSES_ACCESS_R9M, PULSES_ACCESS_R9M_LITE, PULSES_ACCESS_R9M_LITE_PRO, + PULSES_XJT_LITE_X16, + PULSES_XJT_LITE_D8, + PULSES_XJT_LITE_LR12, PULSES_PROTOCOL_LAST }; @@ -128,13 +133,18 @@ enum ModuleSubtypeR9M { MODULE_SUBTYPE_R9M_LAST=MODULE_SUBTYPE_R9M_AUPLUS }; +constexpr int PXX2_MAX_RECEIVERS_PER_MODULE = 3; +constexpr int PXX2_LEN_RX_NAME = 8; + class ModuleData { Q_DECLARE_TR_FUNCTIONS(ModuleData) public: ModuleData() { clear(); } unsigned int modelId; - int protocol; + unsigned int protocol; // type in datastructs.h + int rfProtocol; // rfProtocol in datastructs.h + unsigned int subType; bool invertedSerial; unsigned int channelsStart; @@ -142,14 +152,14 @@ class ModuleData { unsigned int failsafeMode; int failsafeChannels[CPN_MAX_CHNOUT]; - struct { + struct PPM { int delay; bool pulsePol; // false = positive bool outputType; // false = open drain, true = push pull int frameLength; } ppm; - struct { + struct Multi { unsigned int rfProtocol; bool autoBindMode; bool lowPowerMode; @@ -157,22 +167,22 @@ class ModuleData { int optionValue; } multi; - struct { - int power; // 0 10 mW, 1 100 mW, 2 500 mW, 3 1W + struct PXX { + unsigned int power; // 0 10 mW, 1 100 mW, 2 500 mW, 3 1W bool receiver_telem_off; // false = receiver telem enabled bool receiver_channel_9_16; // false = pwm out 1-8, true 9-16 bool external_antenna; // false = internal antenna, true = external antenna bool sport_out; } pxx; - struct { - // unsigned int receivers; - // char receiverName[3][8]; - char data[1 + 3 * 8]; + struct Access { + unsigned int receivers; + char receiverName[PXX2_MAX_RECEIVERS_PER_MODULE][PXX2_LEN_RX_NAME+1]; } access; void clear() { memset(this, 0, sizeof(ModuleData)); } void convert(RadioDataConversionState & cstate); + bool isPxx2Module() const; QString polarityToString() const { return ppm.pulsePol ? tr("Positive") : tr("Negative"); } QString rfProtocolToString() const; QString subTypeToString(int type = -1) const; diff --git a/companion/src/firmwares/opentx/opentxeeprom.cpp b/companion/src/firmwares/opentx/opentxeeprom.cpp index b50228604..48f678b93 100644 --- a/companion/src/firmwares/opentx/opentxeeprom.cpp +++ b/companion/src/firmwares/opentx/opentxeeprom.cpp @@ -40,7 +40,13 @@ inline int MAX_SWITCHES(Board::Type board, int version) return Boards::getCapability(board, Board::Switches); } -#define MAX_KNOBS(board, version) (IS_HORUS(board) ? 8 : 4) +inline int MAX_KNOBS(Board::Type board, int version) +{ + if (version >= 219 && IS_HORUS(board)) + return 8; + + return 4; +} inline int MAX_POTS(Board::Type board, int version) { @@ -56,6 +62,14 @@ inline int MAX_POTS_STORAGE(Board::Type board, int version) return Boards::getCapability(board, Board::PotsStorage); } +inline int MAX_SLIDERS_SLOTS(Board::Type board, int version) +{ + if (version >= 219 && IS_HORUS(board)) + return 8; + + return 4; +} + // bitsize of swconfig_t / 2 (see radio/src/datastructs.h) inline int MAX_SWITCH_SLOTS(Board::Type board, int version) { @@ -71,7 +85,17 @@ inline int MAX_SWITCH_SLOTS(Board::Type board, int version) return 8; } -#define MAX_SWITCHES_POSITION(board, version) (Boards::getCapability(board, Board::SwitchPositions)) +inline int MAX_SWITCHES_POSITION(Board::Type board, int version) +{ + if (version < 219) { + if (IS_TARANIS_X7(board) || IS_HORUS(board)) + return Boards::getCapability(board, Board::SwitchPositions) - 2*3; + } + + return Boards::getCapability(board, Board::SwitchPositions); +} + +//#define MAX_SWITCHES_POSITION(board, version) (Boards::getCapability(board, Board::SwitchPositions)) #define MAX_ROTARY_ENCODERS(board) (IS_SKY9X(board) ? 1 : 0) #define MAX_FLIGHT_MODES(board, version) 9 #define MAX_TIMERS(board, version) 3 @@ -244,8 +268,13 @@ class SourcesConversionTable: public ConversionTable { } } - for (int i=0; i=CPN_MAX_STICKS+MAX_POTS_STORAGE(board, version)) + offset += 2; + + addConversion(RawSource(SOURCE_TYPE_STICK, i + offset), val++); } for (int i=0; i> 5) & 0x03; // 2 bits Rx idx + sensor.moduleIdx = (_instance >> 7) & 0x1; // 1 bit module idx sensor.ratio = _ratio; sensor.offset = _offset; } @@ -1939,14 +1971,239 @@ class SensorField: public TransformedField { int exportPpmDelay(int delay) { return (delay - 300) / 50; } int importPpmDelay(int delay) { return 300 + 50 * delay; } +class ModuleUnionField: public UnionField { + + class PPMField: public UnionField::UnionMember, public StructField { + public: + PPMField(DataField * parent, ModuleData::PPM& ppm): + StructField(parent, "PPM") + { + Append(new ConversionField< SignedField<6> >(parent, ppm.delay, exportPpmDelay, importPpmDelay)); + Append(new BoolField<1>(parent, ppm.pulsePol)); + Append(new BoolField<1>(parent, ppm.outputType)); + Append(new SignedField<8>(parent, ppm.frameLength)); + } + + virtual bool select(const unsigned int& attr) const + { + return true; // take what's left + } + + virtual DataField* getField() + { + return this; + } + }; + + class MultiField: public UnionField::TransformedMember { + public: + MultiField(DataField * parent, ModuleData& module): + UnionField::TransformedMember(parent, internalField), + internalField(this, "Multi"), + module(module), + rfProtExtra(0) + { + ModuleData::Multi& multi = module.multi; + internalField.Append(new UnsignedField<2>(this, rfProtExtra)); + internalField.Append(new SpareBitsField<3>(this)); + internalField.Append(new BoolField<1>(this, multi.autoBindMode)); + internalField.Append(new BoolField<1>(this, multi.lowPowerMode)); + internalField.Append(new BoolField<1>(this, multi.customProto)); + internalField.Append(new SignedField<8>(this, multi.optionValue)); + } + + virtual bool select(const unsigned int& attr) const + { + return attr==PULSES_MULTIMODULE; + } + + virtual void beforeExport() + { + module.rfProtocol = module.multi.rfProtocol & 0xf; + rfProtExtra = (module.multi.rfProtocol >> 4) & 0x03; + } + + virtual void afterImport() + { + module.multi.rfProtocol = + (rfProtExtra & 0x3) << 4 | (module.rfProtocol & 0xf); + } + + private: + StructField internalField; + ModuleData& module; + unsigned int rfProtExtra; + }; + + class PxxField: public UnionField::TransformedMember { + public: + PxxField(DataField * parent, ModuleData& module): + UnionField::TransformedMember(parent, internalField), + internalField(this, "Pxx"), + module(module) + { + ModuleData::PXX& pxx = module.pxx; + internalField.Append(new UnsignedField<2>(this, pxx.power)); + internalField.Append(new SpareBitsField<2>(this)); + internalField.Append(new BoolField<1>(this, pxx.receiver_telem_off)); + internalField.Append(new BoolField<1>(this, pxx.receiver_channel_9_16)); + internalField.Append(new BoolField<1>(this, pxx.external_antenna)); + internalField.Append(new BoolField<1>(this, pxx.sport_out)); + } + + bool select(const unsigned int& attr) const { + return attr==PULSES_PXX_XJT_X16 || + attr==PULSES_PXX_DJT || + attr==PULSES_PXX_R9M || + attr==PULSES_PXX_R9M_LITE; + } + + virtual void beforeExport() + { + if (module.protocol >= PULSES_PXX_XJT_X16 && module.protocol <= PULSES_PXX_XJT_LR12) { + module.subType = module.protocol - PULSES_PXX_XJT_X16; + } + } + + virtual void afterImport() + { + if (module.protocol == PULSES_PXX_XJT_X16) { + module.protocol += module.subType; + } + } + + private: + StructField internalField; + ModuleData& module; + }; + + class AccessField: public UnionField::TransformedMember { + public: + AccessField(DataField * parent, ModuleData& module): + UnionField::TransformedMember(parent, internalField), + internalField(this, "Access"), + module(module) + { + internalField.Append(new UnsignedField<3>(this, module.access.receivers)); + internalField.Append(new SpareBitsField<5>(this)); + + for (int i=0; i(this, receiverName[i])); + } + + bool select(const unsigned int& attr) const { + return attr >= PULSES_ACCESS_ISRM && attr <= PULSES_ACCESS_R9M_LITE_PRO; + } + + virtual void beforeExport() + { + if (module.protocol == PULSES_ACCST_ISRM_D16 || + module.protocol == PULSES_ACCESS_ISRM) { + module.subType = module.protocol - PULSES_ACCESS_ISRM; + } + for (int i=0; i(parent, module.protocol) + { + if (version >= 219) + Append(new AccessField(parent, module)); + Append(new PxxField(parent, module)); + Append(new MultiField(parent, module)); + Append(new PPMField(parent, module.ppm)); + } +}; + + +class ModuleField: public TransformedField { + public: + ModuleField(DataField * parent, ModuleData & module, Board::Type board, unsigned int version): + TransformedField(parent, internalField), + internalField(this, "Module"), + module(module), + protocolsConversionTable(board, version) + { + internalField.Append(new ConversionField >(this, module.protocol, &protocolsConversionTable, "Protocol", DataField::tr("OpenTX doesn't accept this radio protocol"))); + internalField.Append(new SignedField<4>(this, module.rfProtocol)); + internalField.Append(new UnsignedField<8>(this, module.channelsStart)); + internalField.Append(new ConversionField >(this, module.channelsCount, -8)); + internalField.Append(new UnsignedField<4>(this, module.failsafeMode)); + internalField.Append(new UnsignedField<3>(this, module.subType)); + internalField.Append(new BoolField<1>(this, module.invertedSerial)); + if (version <= 218) { + for (int i=0; i<32; i++) { + internalField.Append(new SignedField<16>(this, module.failsafeChannels[i])); + } + } + + internalField.Append(new ModuleUnionField(parent, module, board, version)); + } + + virtual void beforeExport() + { + if (module.protocol >= PULSES_LP45 && module.protocol <= PULSES_DSMX) { + module.rfProtocol = module.protocol - PULSES_LP45; + } + } + + virtual void afterImport() + { + if (module.protocol == PULSES_LP45) { + module.protocol += module.rfProtocol; + } + } + + private: + StructField internalField; + ModuleData& module; + ProtocolsConversionTable protocolsConversionTable; +}; + OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsigned int version, unsigned int variant): TransformedField(nullptr, internalField), internalField(this, "ModelData"), modelData(modelData), board(board), version(version), - variant(variant), - protocolsConversionTable(board) + variant(variant) { sprintf(name, "Model %s", modelData.name); @@ -2094,26 +2351,8 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsig int modulesCount = (version <= 218 ? 3 : 2); for (int module=0; module >(this, modelData.moduleData[module].protocol, &protocolsConversionTable, "Protocol", DataField::tr("OpenTX doesn't accept this radio protocol"))); - internalField.Append(new SignedField<4>(this, subprotocols[module])); - internalField.Append(new UnsignedField<8>(this, modelData.moduleData[module].channelsStart)); - internalField.Append(new ConversionField >(this, modelData.moduleData[module].channelsCount, -8)); - internalField.Append(new UnsignedField<4>(this, modelData.moduleData[module].failsafeMode)); - internalField.Append(new UnsignedField<3>(this, modelData.moduleData[module].subType)); - internalField.Append(new BoolField<1>(this, modelData.moduleData[module].invertedSerial)); - if (version <= 218) { - for (int i=0; i<32; i++) { - internalField.Append(new SignedField<16>(this, modelData.moduleData[module].failsafeChannels[i])); - } - } - internalField.Append(new ConversionField< SignedField<6> >(this, modelData.moduleData[module].ppm.delay, exportPpmDelay, importPpmDelay)); - internalField.Append(new BoolField<1>(this, modelData.moduleData[module].ppm.pulsePol)); - internalField.Append(new BoolField<1>(this, modelData.moduleData[module].ppm.outputType)); - internalField.Append(new SignedField<8>(this, modelData.moduleData[module].ppm.frameLength)); - if (version >= 219) { - // TODO ACCESS - internalField.Append(new CharField<1 + 3 * 8 - 2>(this, modelData.moduleData[module].access.data)); - } + + internalField.Append(new ModuleField(this, modelData.moduleData[module], board, version)); } if (version >= 219) { @@ -2221,35 +2460,6 @@ void OpenTxModelData::beforeExport() // qDebug() << QString("before export model") << modelData.name; for (int module=0; module<2; module++) { - if ((modelData.moduleData[module].protocol >= PULSES_PXX_XJT_X16 && modelData.moduleData[module].protocol <= PULSES_PXX_XJT_LR12) || - modelData.moduleData[module].protocol == PULSES_PXX_R9M) { - if (modelData.moduleData[module].protocol != PULSES_PXX_R9M) { - subprotocols[module] = modelData.moduleData[module].protocol - PULSES_PXX_XJT_X16; - } - int pxxByte = (modelData.moduleData[module].pxx.power & 0x03) - | modelData.moduleData[module].pxx.receiver_telem_off << 4 - | modelData.moduleData[module].pxx.receiver_channel_9_16 << 5; - modelData.moduleData[module].ppm.delay = 300 + 50 * pxxByte; - modelData.moduleData[module].ppm.pulsePol = modelData.moduleData[module].pxx.external_antenna; - modelData.moduleData[module].ppm.outputType = modelData.moduleData[module].pxx.sport_out; - - } - else if (modelData.moduleData[module].protocol >= PULSES_LP45 && modelData.moduleData[module].protocol <= PULSES_DSMX) { - subprotocols[module] = modelData.moduleData[module].protocol - PULSES_LP45; - } - else if (modelData.moduleData[module].protocol == PULSES_MULTIMODULE) { - // copy multi settings to ppm settings to get them written to the eeprom - // (reverse the int => ms logic of the ppm delay) since only ppm is written - subprotocols[module] = modelData.moduleData[module].multi.rfProtocol & (0x1f); - int multiByte = ((modelData.moduleData[module].multi.rfProtocol >> 4) & 0x03) | (modelData.moduleData[module].multi.customProto << 7); - modelData.moduleData[module].ppm.delay = 300 + 50 * multiByte; - modelData.moduleData[module].ppm.frameLength = modelData.moduleData[module].multi.optionValue; - modelData.moduleData[module].ppm.outputType = modelData.moduleData[module].multi.lowPowerMode; - modelData.moduleData[module].ppm.pulsePol = modelData.moduleData[module].multi.autoBindMode; - } - else { - subprotocols[module] = (module == 0 ? -1 : 0); - } } if (IS_HORUS(board)) { @@ -2268,39 +2478,11 @@ void OpenTxModelData::afterImport() { qCDebug(eepromImport) << QString("OpenTxModelData::afterImport()") << modelData.name; + // ??? what's this ??? if (IS_HORUS(board)) { modelData.moduleData[0].protocol = PULSES_PXX_XJT_X16; } - for (int module=0; module<2; module++) { - if (modelData.moduleData[module].protocol == PULSES_PXX_XJT_X16 || modelData.moduleData[module].protocol == PULSES_LP45) { - if (subprotocols[module] >= 0) - modelData.moduleData[module].protocol += subprotocols[module]; - else - modelData.moduleData[module].protocol = PULSES_OFF; - } - else if (modelData.moduleData[module].protocol == PULSES_MULTIMODULE) { - // Copy data from ppm struct to multi struct - auto multiByte = (unsigned int)((modelData.moduleData[module].ppm.delay - 300) / 50); - modelData.moduleData[module].multi.rfProtocol = (subprotocols[module] & 0x0f) | ((multiByte & 0x3) << 4); - modelData.moduleData[module].multi.customProto = (multiByte & 0x80) == 0x80; - modelData.moduleData[module].multi.optionValue = modelData.moduleData[module].ppm.frameLength; - modelData.moduleData[module].multi.lowPowerMode = modelData.moduleData[module].ppm.outputType; - modelData.moduleData[module].multi.autoBindMode = modelData.moduleData[module].ppm.pulsePol; - } - - if ((modelData.moduleData[module].protocol >= PULSES_PXX_XJT_X16 && modelData.moduleData[module].protocol <= PULSES_PXX_XJT_LR12) || - modelData.moduleData[module].protocol == PULSES_PXX_R9M) { - // Do the same for pxx - auto pxxByte = (unsigned int)((modelData.moduleData[module].ppm.delay - 300) / 50); - modelData.moduleData[module].pxx.power = pxxByte & 0x03; - modelData.moduleData[module].pxx.receiver_telem_off = static_cast(pxxByte & (1 << 4)); - modelData.moduleData[module].pxx.receiver_channel_9_16 = static_cast(pxxByte & (1 << 5)); - modelData.moduleData[module].pxx.sport_out = modelData.moduleData[module].ppm.outputType; - modelData.moduleData[module].pxx.external_antenna = modelData.moduleData[module].ppm.pulsePol; - } - } - if (IS_HORUS(board)) { uint32_t newSwitchWarningStates = 0; for (int i = 0; i < MAX_SWITCHES(board, version); i++) { @@ -2312,6 +2494,9 @@ void OpenTxModelData::afterImport() } modelData.switchWarningStates = newSwitchWarningStates; } + + if (version <= 218 && IS_HORUS_X10(board) && modelData.thrTraceSrc > 3) + modelData.thrTraceSrc += 2; } OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type board, unsigned int version, unsigned int variant): @@ -2472,13 +2657,17 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type internalField.Append(new ArmCustomFunctionField(this, generalData.customFn[i], board, version, variant)); } } - + if (IS_STM32(board)) { if (version >= 218) { internalField.Append(new UnsignedField<4>(this, generalData.hw_uartMode)); - // not on Horus... - for (uint8_t i=0; i<4; i++) { - internalField.Append(new UnsignedField<1>(this, generalData.sliderConfig[i])); + if (!IS_HORUS(board) || version < 219) { + for (uint8_t i=0; i<4; i++) { + internalField.Append(new UnsignedField<1>(this, generalData.sliderConfig[i])); + } + } + else { + internalField.Append(new SpareBitsField<4>(this)); } } else { @@ -2502,17 +2691,18 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type } for (int i=0; i= 3)) + offset += 2; if (i < Boards::getCapability(board, Board::PotsStorage)) - internalField.Append(new UnsignedField<2>(this, generalData.potConfig[i])); + internalField.Append(new UnsignedField<2>(this, generalData.potConfig[i+offset])); else internalField.Append(new SpareBitsField<2>(this)); } - if (IS_HORUS(board)) { - for (int i=0; i<8; i++) { + if (IS_HORUS(board) && version >= 219) { + for (int i=0; i(this, generalData.sliderConfig[i])); else @@ -2536,6 +2726,8 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type if (IS_TARANIS_X9E(board)) internalField.Append(new SpareBitsField<64>(this)); // switchUnlockStates + else if (version >= 219 && IS_TARANIS_X9D(board)) + internalField.Append(new SpareBitsField<32>(this)); // switchUnlockStates else if (IS_TARANIS(board)) internalField.Append(new SpareBitsField<16>(this)); // switchUnlockStates @@ -2552,11 +2744,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type for (int i=0; i(this, generalData.stickName[i], "Stick name")); } - for (int i=0; i(this, generalData.potName[i], "Pot name")); } for (int i=0; i(this, generalData.backlightOffBright)); internalField.Append(new ZCharField<10>(this, generalData.bluetoothName, "Bluetooth name")); } - else if (IS_TARANIS_X9E(board) || (version >= 219 && (IS_TARANIS_X7(board) || IS_TARANIS_XLITE(board) || IS_TARANIS_XLITES(board)))) { + else if (IS_TARANIS_X9E(board) || (version >= 219 && (IS_TARANIS_X7(board) || IS_TARANIS_X9D(board) || IS_TARANIS_XLITE(board)))) { internalField.Append(new SpareBitsField<8>(this)); internalField.Append(new ZCharField<10>(this, generalData.bluetoothName, "Bluetooth name")); } diff --git a/companion/src/firmwares/opentx/opentxeeprom.h b/companion/src/firmwares/opentx/opentxeeprom.h index b421420ba..95f75ce19 100644 --- a/companion/src/firmwares/opentx/opentxeeprom.h +++ b/companion/src/firmwares/opentx/opentxeeprom.h @@ -73,7 +73,7 @@ class OpenTxGeneralData: public TransformedField { class ProtocolsConversionTable: public ConversionTable { public: - ProtocolsConversionTable(Board::Type board) + ProtocolsConversionTable(Board::Type board, int version) { int val = 0; addConversion(PULSES_OFF, val++); @@ -83,7 +83,10 @@ class ProtocolsConversionTable: public ConversionTable addConversion(PULSES_PXX_XJT_D8, val); addConversion(PULSES_PXX_XJT_LR12, val++); - addConversion(PULSES_ACCESS_ISRM, val++); + if (version >= 219) { + addConversion(PULSES_ACCESS_ISRM, val); + addConversion(PULSES_ACCST_ISRM_D16, val++); + } addConversion(PULSES_LP45, val); addConversion(PULSES_DSM2, val); @@ -96,9 +99,14 @@ class ProtocolsConversionTable: public ConversionTable addConversion(PULSES_ACCESS_R9M, val++); addConversion(PULSES_PXX_R9M_LITE, val++); addConversion(PULSES_ACCESS_R9M_LITE, val++); + addConversion(PULSES_PXX_R9M_LITE_PRO, val++); addConversion(PULSES_ACCESS_R9M_LITE_PRO, val++); addConversion(PULSES_SBUS, val++); + + addConversion(PULSES_XJT_LITE_X16, val); + addConversion(PULSES_XJT_LITE_D8, val); + addConversion(PULSES_XJT_LITE_LR12, val++); } }; @@ -141,7 +149,6 @@ class OpenTxModelData: public TransformedField { unsigned int variant; char name[256]; int subprotocols[CPN_MAX_MODULES+1/*trainer*/]; - ProtocolsConversionTable protocolsConversionTable; ChannelsConversionTable channelsConversionTable; QStringList _errors; }; diff --git a/companion/src/firmwares/opentx/opentxinterface.cpp b/companion/src/firmwares/opentx/opentxinterface.cpp index 72483c506..f3558a245 100644 --- a/companion/src/firmwares/opentx/opentxinterface.cpp +++ b/companion/src/firmwares/opentx/opentxinterface.cpp @@ -94,6 +94,8 @@ const char * OpenTxEepromInterface::getName() return "OpenTX for FrSky Horus"; case BOARD_X10: return "OpenTX for FrSky X10"; + case BOARD_X10_EXPRESS: + return "OpenTX for FrSky X10 Express"; default: return "OpenTX for an unknown board"; } @@ -756,66 +758,67 @@ QTime OpenTxFirmware::getMaxTimerStart() return QTime(0, 59, 59); } -int OpenTxFirmware::isAvailable(PulsesProtocol proto, int port) +bool OpenTxFirmware::isAvailable(PulsesProtocol proto, int port) { if (IS_HORUS_OR_TARANIS(board)) { switch (port) { case 0: switch (proto) { case PULSES_OFF: - return 1; + return true; case PULSES_PXX_XJT_X16: case PULSES_PXX_XJT_LR12: - return (IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board)) ? 0 : 1; + return !(IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board)); case PULSES_PXX_XJT_D8: - return (IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board) || id.contains("eu")) ? 0 : 1; + return !(IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board) || id.contains("eu")); case PULSES_PPM: - return id.contains("internalppm") ? 1 : 0; + return id.contains("internalppm"); case PULSES_ACCESS_ISRM: - return (IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board)) ? 1 : 0; + return IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board) || board == BOARD_TARANIS_X9DP_2019 || board == BOARD_X10_EXPRESS || (IS_HORUS(board) && id.contains("internalaccess")); + case PULSES_ACCST_ISRM_D16: + return (IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board)); default: - return 0; + return false; } - + case 1: switch (proto) { case PULSES_OFF: case PULSES_PPM: - return 1; + return true; case PULSES_PXX_XJT_X16: case PULSES_PXX_XJT_D8: case PULSES_PXX_XJT_LR12: - return (IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board)) ? 0 : 1; + return !(IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board)); case PULSES_PXX_R9M: case PULSES_LP45: case PULSES_DSM2: case PULSES_DSMX: case PULSES_SBUS: - return 1; case PULSES_MULTIMODULE: - if(IS_JUMPER_T12(board)) - return 1; - else - return id.contains("multimodule") ? 1 : 0; case PULSES_CROSSFIRE: - return id.contains("crossfire") ? 1 : 0; + return true; case PULSES_ACCESS_R9M_LITE: case PULSES_ACCESS_R9M_LITE_PRO: - return (IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board)) ? 1 : 0; + return (IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board)); + case PULSES_XJT_LITE_X16: + case PULSES_XJT_LITE_D8: + case PULSES_XJT_LITE_LR12: + return (IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board)); default: - return 0; + return false; } case -1: switch (proto) { case PULSES_PPM: - return 1; + return true; default: - return 0; + return false; } default: - return 0; + return false; } } else if (IS_SKY9X(board)) { @@ -831,23 +834,22 @@ int OpenTxFirmware::isAvailable(PulsesProtocol proto, int port) case PULSES_DSM2: case PULSES_DSMX: case PULSES_SBUS: - return 1; case PULSES_MULTIMODULE: - return id.contains("multimodule") ? 1 : 0; + return true; default: - return 0; + return false; } break; case 1: switch (proto) { case PULSES_PPM: - return 1; + return true; default: - return 0; + return false; } break; default: - return 0; + return false; } } else { @@ -859,9 +861,9 @@ int OpenTxFirmware::isAvailable(PulsesProtocol proto, int port) // case PULSES_PXX_DJT: // Unavailable for now case PULSES_PPM16: case PULSES_PPMSIM: - return 1; + return true; default: - return 0; + return false; } } } @@ -1150,7 +1152,6 @@ void addOpenTxRfOptions(OpenTxFirmware * firmware, bool flex = true) { static const Firmware::Option opt_eu("eu", Firmware::tr("Removes D8 FrSky protocol support which is not legal for use in the EU on radios sold after Jan 1st, 2015")); static const Firmware::Option opt_fl("flexr9m", Firmware::tr("Enable non certified firmwares")); - firmware->addOption("multimodule", Firmware::tr("Support for the DIY-Multiprotocol-TX-Module")); if (flex) firmware->addOptionsGroup({opt_eu, opt_fl}); else @@ -1168,8 +1169,6 @@ void addOpenTxFrskyOptions(OpenTxFirmware * firmware) firmware->addOption("noheli", Firmware::tr("Disable HELI menu and cyclic mix support")); firmware->addOption("nogvars", Firmware::tr("Disable Global variables")); firmware->addOption("lua", Firmware::tr("Enable Lua custom scripts screen")); - firmware->addOption("luac", Firmware::tr("Enable Lua compiler")); - firmware->addOption("crossfire", Firmware::tr("Support for Crossfire TX Module")); addOpenTxRfOptions(firmware); } @@ -1260,23 +1259,28 @@ void registerOpenTxFirmwares() /* FrSky X10 board */ firmware = new OpenTxFirmware("opentx-x10", Firmware::tr("FrSky Horus X10 / X10S"), BOARD_X10); addOpenTxFrskyOptions(firmware); + firmware->addOption("internalaccess", Firmware::tr("Support for ACCESS internal module replacement")); + registerOpenTxFirmware(firmware); + + /* FrSky X10 Express board */ + firmware = new OpenTxFirmware("opentx-x10express", Firmware::tr("FrSky Horus X10 Express"), BOARD_X10_EXPRESS); + addOpenTxFrskyOptions(firmware); registerOpenTxFirmware(firmware); /* FrSky X12 (Horus) board */ firmware = new OpenTxFirmware("opentx-x12s", Firmware::tr("FrSky Horus X12S"), BOARD_X12S); addOpenTxFrskyOptions(firmware); + firmware->addOption("internalaccess", Firmware::tr("Support for ACCESS internal module replacement")); firmware->addOption("pcbdev", Firmware::tr("Use ONLY with first DEV pcb version")); registerOpenTxFirmware(firmware); /* Jumper T12 board */ firmware = new OpenTxFirmware("opentx-t12", QCoreApplication::translate("Firmware", "Jumper T12"), BOARD_JUMPER_T12); addOpenTxCommonOptions(firmware); - firmware->addOption("multimodule", Firmware::tr("Support for the DIY-Multiprotocol-TX-Module")); firmware->addOption("noheli", Firmware::tr("Disable HELI menu and cyclic mix support")); firmware->addOption("nogvars", Firmware::tr("Disable Global variables")); firmware->addOption("lua", Firmware::tr("Enable Lua custom scripts screen")); - firmware->addOption("luac", Firmware::tr("Enable Lua compiler")); - firmware->addOption("crossfire", Firmware::tr("Support for Crossfire TX Module")); + firmware->addOption("flexr9m", Firmware::tr("Enable non certified R9M firmwares")); addOpenTxFontOptions(firmware); registerOpenTxFirmware(firmware); diff --git a/companion/src/firmwares/opentx/opentxinterface.h b/companion/src/firmwares/opentx/opentxinterface.h index 277670706..b71ba9eb9 100644 --- a/companion/src/firmwares/opentx/opentxinterface.h +++ b/companion/src/firmwares/opentx/opentxinterface.h @@ -122,7 +122,7 @@ class OpenTxFirmware: public Firmware virtual QTime getMaxTimerStart(); - virtual int isAvailable(PulsesProtocol proto, int port=0); + virtual bool isAvailable(PulsesProtocol proto, int port=0); protected: diff --git a/companion/src/firmwares/rawsource.h b/companion/src/firmwares/rawsource.h index 267d6af43..e9273d399 100644 --- a/companion/src/firmwares/rawsource.h +++ b/companion/src/firmwares/rawsource.h @@ -259,11 +259,11 @@ class RawSource { bool isTimeBased(Board::Type board = Board::BOARD_UNKNOWN) const; bool isAvailable(const ModelData * const model = NULL, const GeneralSettings * const gs = NULL, Board::Type board = Board::BOARD_UNKNOWN) const; - bool operator == ( const RawSource & other) { + bool operator == ( const RawSource & other) const { return (this->type == other.type) && (this->index == other.index); } - bool operator != ( const RawSource & other) { + bool operator != ( const RawSource & other) const { return (this->type != other.type) || (this->index != other.index); } diff --git a/companion/src/firmwares/rawswitch.h b/companion/src/firmwares/rawswitch.h index 598e25f01..6d0c93700 100644 --- a/companion/src/firmwares/rawswitch.h +++ b/companion/src/firmwares/rawswitch.h @@ -91,11 +91,11 @@ class RawSwitch { QString toString(Board::Type board = Board::BOARD_UNKNOWN, const GeneralSettings * const generalSettings = NULL, const ModelData * const modelData = NULL) const; bool isAvailable(const ModelData * const model = NULL, const GeneralSettings * const gs = NULL, Board::Type board = Board::BOARD_UNKNOWN) const; - bool operator== ( const RawSwitch& other) { + bool operator== ( const RawSwitch& other) const { return (this->type == other.type) && (this->index == other.index); } - bool operator!= ( const RawSwitch& other) { + bool operator!= ( const RawSwitch& other) const { return (this->type != other.type) || (this->index != other.index); } diff --git a/companion/src/firmwares/sensordata.cpp b/companion/src/firmwares/sensordata.cpp index 56c2653fe..a88f3239a 100644 --- a/companion/src/firmwares/sensordata.cpp +++ b/companion/src/firmwares/sensordata.cpp @@ -21,6 +21,7 @@ #include "sensordata.h" #include "radiodata.h" +#include "modeldata.h" void SensorData::updateUnit() { @@ -90,3 +91,25 @@ QString SensorData::nameToString(int index) const { return RadioData::getElementName(tr("TELE"), index + 1, label); } + +QString SensorData::getRxOrModName(const ModelData* model) const +{ + if ((type != TELEM_TYPE_CUSTOM) || (!id && !instance)) + return QString(); + + const ModuleData& module = model->moduleData[moduleIdx]; + + if (module.isPxx2Module()) { + if (module.access.receivers & (1 << rxIdx)) { + return QString(module.access.receiverName[rxIdx]); + } + + // receiver does not seem to be active + return QString(); + } + + if (moduleIdx) + return tr("Internal"); + + return tr("External"); +} diff --git a/companion/src/firmwares/sensordata.h b/companion/src/firmwares/sensordata.h index a4555c414..8e95aa7f6 100644 --- a/companion/src/firmwares/sensordata.h +++ b/companion/src/firmwares/sensordata.h @@ -25,6 +25,8 @@ constexpr int CPN_MAX_SENSORS = 60; +class ModelData; + class SensorData { Q_DECLARE_TR_FUNCTIONS(SensorData) @@ -111,6 +113,8 @@ class SensorData { unsigned int id; unsigned int subid; unsigned int instance; + unsigned int rxIdx; + unsigned int moduleIdx; unsigned int persistentValue; unsigned int formula; char label[4+1]; @@ -144,6 +148,7 @@ class SensorData { void updateUnit(); QString unitString() const; QString nameToString(int index) const; + QString getRxOrModName(const ModelData* model) const; void clear() { memset(this, 0, sizeof(SensorData)); } }; diff --git a/companion/src/generaledit/generalsetup.cpp b/companion/src/generaledit/generalsetup.cpp index b96306af3..bcc61afde 100644 --- a/companion/src/generaledit/generalsetup.cpp +++ b/companion/src/generaledit/generalsetup.cpp @@ -455,6 +455,9 @@ void GeneralSetupPanel::setValues() ui->pwrOnSpeed->setValue(generalSettings.pwrOnSpeed); ui->pwrOffSpeed->setValue(generalSettings.pwrOffSpeed); + + // TODO: only if ACCESS available?? + ui->registrationId->setText(generalSettings.registrationId); } void GeneralSetupPanel::on_faimode_CB_stateChanged(int) @@ -747,6 +750,15 @@ void GeneralSetupPanel::on_blAlarm_ChkB_stateChanged() emit modified(); } +void GeneralSetupPanel::on_ownerID_editingFinished() +{ + //copy ownerID back to generalSettings.registrationId + QByteArray array = ui->registrationId->text().toLocal8Bit(); + strncpy(generalSettings.registrationId, "pafleraf", 9); + generalSettings.registrationId[8] = '\0'; + emit modified(); +} + void GeneralSetupPanel::stickReverseEdited() { generalSettings.stickReverse = ((int)ui->stickReverse1->isChecked()) | ((int)ui->stickReverse2->isChecked()<<1) | ((int)ui->stickReverse3->isChecked()<<2) | ((int)ui->stickReverse4->isChecked()<<3); diff --git a/companion/src/generaledit/generalsetup.h b/companion/src/generaledit/generalsetup.h index 9dc636768..5ad3a1afe 100644 --- a/companion/src/generaledit/generalsetup.h +++ b/companion/src/generaledit/generalsetup.h @@ -87,6 +87,7 @@ class GeneralSetupPanel : public GeneralPanel void on_vBatMinDSB_editingFinished(); void on_vBatMaxDSB_editingFinished(); void on_contrastSB_editingFinished(); + void on_ownerID_editingFinished(); void on_pwrOnSpeed_valueChanged(); void on_pwrOffSpeed_valueChanged(); diff --git a/companion/src/generaledit/generalsetup.ui b/companion/src/generaledit/generalsetup.ui index 5e2941508..88789aa8c 100644 --- a/companion/src/generaledit/generalsetup.ui +++ b/companion/src/generaledit/generalsetup.ui @@ -554,6 +554,33 @@ + + + + + 0 + 0 + + + + 23 + + + + + + + RotEnc Navigation + + + + + + + + + + @@ -567,59 +594,89 @@ - - - - Country Code - - - - - + + - If you enable FAI, only RSSI and RxBt sensors will keep working. This function cannot be disabled by the radio. - - - - - - - - FAI Mode + + + + + This is the switch selectrion for turning on the backlight (if installed). + + + + + -1 - - - - - - -14 - - - 12 - - - 0 - - - - - - - Automatically adjust the radio's clock if a GPS is connected to telemetry. - - - Qt::RightToLeft - - - Adjust RTC - - - - + + + + Backlight flash on alarm + + + + + + + Backlight Auto OFF after + + + + + + + Backlight Switch + + + + + + + ms + + + 200 + + + 1000 + + + 10 + + + 500 + + + + + + + Voice Language + + + + + + + Hz + + + 300 + + + 1100 + + + 10 + + + 700 + + @@ -653,94 +710,38 @@ - - + + - Speaker Volume + Vario repeat at zero - - - - Hz + + + + Vario pitch at zero - - 1300 + + + + + + FAI Mode + + + + + + Backlight OFF Brightness + + + + + - 2900 - - - 10 - - - 1700 - - - - - - - Vario pitch at max - - - - - - - Backlight Switch - - - - - - - - 0 - 0 - - - - 23 - - - - - - - - - Color 1 - - - - - - - 20 - - - 5 - - - Qt::Horizontal - - - - - - - Color 2 - - - - - - - - - Sound Mode + 100 @@ -772,17 +773,95 @@ - - - - Backlight color + + + + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">LCD Screen Contrast</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Values can be 20-45</span></p></body></html> + + + 1 + + + 20 + + + 1 - - + + + + Hz + + + 1300 + + + 2900 + + + 10 + + + 1700 + + + + + - Speaker Pitch (spkr only) + Timeshift from UTC + + + + + + + 5 + + + 100 + + + + + + + + America + + + + + Japan + + + + + Europe + + + + + + + + If you enable FAI, only RSSI and RxBt sensors will keep working. This function cannot be disabled by the radio. + + + @@ -810,6 +889,13 @@ + + + + Backlight Brightness + + + @@ -906,168 +992,116 @@ - - - - ms - - - 200 - - - 1000 - - - 10 - - - 500 - - - - - - - Hz - - - 300 - - - 1100 - - - 10 - - - 700 - - - - - + + - Backlight flash on alarm + Backlight color - - + + - Vario pitch at zero + Vario pitch at max - - + + - Vario repeat at zero + Speaker Pitch (spkr only) - - - - 100 - - - - - - - Backlight Auto OFF after - - - - - - - - - - - - - This is the switch selectrion for turning on the backlight (if installed). - - - - - -1 - - - - - - - - - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">LCD Screen Contrast</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Values can be 20-45</span></p></body></html> - - - 1 - - - 20 - - - 1 - - - - - - - RotEnc Navigation - - - - - - - - - - - - - - Backlight Brightness - - - - - + + - - America - + + + Color 1 + + - - Japan - + + + 20 + + + 5 + + + Qt::Horizontal + + - - Europe - + + + Color 2 + + + + + + + + Country Code + - + + + + Sound Mode + + + + + + + Speaker Volume + + + + + + + + + -14 + + + 12 + + + 0 + + + + + + + Automatically adjust the radio's clock if a GPS is connected to telemetry. + + + Qt::RightToLeft + + + Adjust RTC + + + + + + + + + Qt::Vertical @@ -1080,37 +1114,20 @@ p, li { white-space: pre-wrap; } - - + + - Voice Language + Owner Registration ID - - - - Timeshift from UTC + + + + aaaaaaAA - - - - - - - - - Backlight OFF Brightness - - - - - - - 5 - - - 100 + + 8 diff --git a/companion/src/mdichild.cpp b/companion/src/mdichild.cpp index f3001e615..4d0d7dcb8 100644 --- a/companion/src/mdichild.cpp +++ b/companion/src/mdichild.cpp @@ -1334,7 +1334,7 @@ bool MdiChild::loadFile(const QString & filename, bool resetCurrentFile) QString warning = storage.warning(); if (!warning.isEmpty()) { - // TODO EEPROMInterface::showEepromWarnings(this, CPN_STR_TTL_WARNING, warning); + QMessageBox::warning(this, CPN_STR_TTL_WARNING, warning); } if (resetCurrentFile) { diff --git a/companion/src/modeledit/channels.cpp b/companion/src/modeledit/channels.cpp index 5347efe54..57f68a5c2 100644 --- a/companion/src/modeledit/channels.cpp +++ b/companion/src/modeledit/channels.cpp @@ -162,11 +162,6 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera if (IS_HORUS_OR_TARANIS(firmware->getBoard())) { curveCB[i] = new QComboBox(this); curveCB[i]->setProperty("index", i); - int numcurves = firmware->getCapability(NumCurves); - for (int j=-numcurves; j<=numcurves; j++) { - curveCB[i]->addItem(CurveReference(CurveReference::CURVE_REF_CUSTOM, j).toString(&model, false), j); - } - curveCB[i]->setCurrentIndex(model.limitData[i].curve.value+numcurves); connect(curveCB[i], SIGNAL(currentIndexChanged(int)), this, SLOT(curveEdited())); tableLayout->addWidget(i, col++, curveCB[i]); } @@ -298,7 +293,12 @@ void Channels::updateLine(int i) chnMax[i]->setValue(model->limitData[i].max); invCB[i]->setCurrentIndex((model->limitData[i].revert) ? 1 : 0); if (IS_HORUS_OR_TARANIS(firmware->getBoard())) { - curveCB[i]->setCurrentIndex(model->limitData[i].curve.value + firmware->getCapability(NumCurves)); + int numcurves = firmware->getCapability(NumCurves); + curveCB[i]->clear(); + for (int j=-numcurves; j<=numcurves; j++) { + curveCB[i]->addItem(CurveReference(CurveReference::CURVE_REF_CUSTOM, j).toString(model, false), j); + } + curveCB[i]->setCurrentIndex(model->limitData[i].curve.value + numcurves); } if (firmware->getCapability(PPMCenter)) { centerSB[i]->setValue(model->limitData[i].ppmCenter + 1500); diff --git a/companion/src/modeledit/customfunctions.cpp b/companion/src/modeledit/customfunctions.cpp index f4f4bb6a0..552b31038 100644 --- a/companion/src/modeledit/customfunctions.cpp +++ b/companion/src/modeledit/customfunctions.cpp @@ -384,7 +384,6 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) cfn.swtch = RawSwitch(fswtchSwtch[i]->currentData().toInt()); cfn.func = func; cfn.enabled = fswtchEnable[i]->isChecked(); - cfn.adjustMode = (AssignFunc)fswtchGVmode[i]->currentIndex(); } if (!cfn.isEmpty()) { @@ -418,6 +417,7 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) int gvidx = func - FuncAdjustGV1; if (modified) cfn.adjustMode = fswtchGVmode[i]->currentIndex(); + fswtchGVmode[i]->setCurrentIndex(cfn.adjustMode); widgetsMask |= CUSTOM_FUNCTION_GV_MODE | CUSTOM_FUNCTION_ENABLE; if (cfn.adjustMode==FUNC_ADJUST_GVAR_CONSTANT || cfn.adjustMode==FUNC_ADJUST_GVAR_INCDEC) { if (modified) diff --git a/companion/src/modeledit/setup.cpp b/companion/src/modeledit/setup.cpp index 2dc74e5fe..3e07a5f42 100644 --- a/companion/src/modeledit/setup.cpp +++ b/companion/src/modeledit/setup.cpp @@ -166,19 +166,20 @@ void TimerPanel::on_name_editingFinished() #define FAILSAFE_CHANNEL_HOLD 2000 #define FAILSAFE_CHANNEL_NOPULSE 2001 -#define MASK_PROTOCOL 1 -#define MASK_CHANNELS_COUNT 2 -#define MASK_RX_NUMBER 4 -#define MASK_CHANNELS_RANGE 8 -#define MASK_PPM_FIELDS 16 -#define MASK_FAILSAFES 32 -#define MASK_OPEN_DRAIN 64 -#define MASK_MULTIMODULE 128 -#define MASK_ANTENNA 256 -#define MASK_MULTIOPTION 512 -#define MASK_R9M 1024 -#define MASK_SBUSPPM_FIELDS 2048 -#define MASK_SUBTYPES 4096 +#define MASK_PROTOCOL (1<<0) +#define MASK_CHANNELS_COUNT (1<<1) +#define MASK_RX_NUMBER (1<<2) +#define MASK_CHANNELS_RANGE (1<<3) +#define MASK_PPM_FIELDS (1<<4) +#define MASK_FAILSAFES (1<<5) +#define MASK_OPEN_DRAIN (1<<6) +#define MASK_MULTIMODULE (1<<7) +#define MASK_ANTENNA (1<<8) +#define MASK_MULTIOPTION (1<<9) +#define MASK_R9M (1<<10) +#define MASK_SBUSPPM_FIELDS (1<<11) +#define MASK_SUBTYPES (1<<12) +#define MASK_ACCESS (1<<13) quint8 ModulePanel::failsafesValueDisplayType = ModulePanel::FAILSAFE_DISPLAY_PERCENT; @@ -214,7 +215,7 @@ ModulePanel::ModulePanel(QWidget * parent, ModelData & model, ModuleData & modul } // The protocols available on this board - for (int i=0; iisAvailable((PulsesProtocol) i, moduleIdx)) { if (IS_TARANIS_XLITE(firmware->getBoard()) && i == PULSES_PXX_R9M) //TODO remove when mini are handled as a different module type ui->protocol->addItem("FrSky R9M Mini", (QVariant) i); @@ -232,6 +233,8 @@ ModulePanel::ModulePanel(QWidget * parent, ModelData & model, ModuleData & modul ui->btnGrpValueType->setId(ui->optUs, FAILSAFE_DISPLAY_USEC); ui->btnGrpValueType->button(failsafesValueDisplayType)->setChecked(true); + ui->registrationId->setText(model.registrationId); + setupFailsafes(); disableMouseScrolling(); @@ -244,6 +247,10 @@ ModulePanel::ModulePanel(QWidget * parent, ModelData & model, ModuleData & modul connect(this, &ModulePanel::channelsRangeChanged, this, &ModulePanel::setupFailsafes); connect(ui->btnGrpValueType, static_cast(&QButtonGroup::buttonClicked), this, &ModulePanel::onFailsafesDisplayValueTypeChanged); + connect(ui->clearRx1, SIGNAL(clicked()), this, SLOT(onClearAccessRxClicked())); + connect(ui->clearRx2, SIGNAL(clicked()), this, SLOT(onClearAccessRxClicked())); + connect(ui->clearRx3, SIGNAL(clicked()), this, SLOT(onClearAccessRxClicked())); + lock = false; } @@ -257,8 +264,13 @@ bool ModulePanel::moduleHasFailsafes() { return firmware->getCapability(HasFailsafe) && ( (PulsesProtocol)module.protocol == PulsesProtocol::PULSES_ACCESS_ISRM || + (PulsesProtocol)module.protocol == PulsesProtocol::PULSES_ACCST_ISRM_D16 || (PulsesProtocol)module.protocol == PulsesProtocol::PULSES_PXX_XJT_X16 || - (PulsesProtocol)module.protocol == PulsesProtocol::PULSES_PXX_R9M); + (PulsesProtocol)module.protocol == PulsesProtocol::PULSES_PXX_R9M || + (PulsesProtocol)module.protocol == PulsesProtocol::PULSES_ACCESS_R9M || + (PulsesProtocol)module.protocol == PulsesProtocol::PULSES_ACCESS_R9M_LITE || + (PulsesProtocol)module.protocol == PulsesProtocol::PULSES_ACCESS_R9M_LITE_PRO || + (PulsesProtocol)module.protocol == PulsesProtocol::PULSES_XJT_LITE_X16); } void ModulePanel::setupFailsafes() @@ -364,18 +376,30 @@ void ModulePanel::update() if (moduleIdx >= 0) { mask |= MASK_PROTOCOL; switch (protocol) { - case PULSES_ACCESS_ISRM: - mask |= MASK_CHANNELS_RANGE | MASK_CHANNELS_COUNT | MASK_RX_NUMBER; - break; case PULSES_PXX_R9M: mask |= MASK_R9M | MASK_SUBTYPES; + case PULSES_ACCESS_R9M: + case PULSES_ACCESS_R9M_LITE: + case PULSES_ACCESS_R9M_LITE_PRO: + case PULSES_ACCESS_ISRM: + case PULSES_ACCST_ISRM_D16: + case PULSES_XJT_LITE_X16: + case PULSES_XJT_LITE_D8: + case PULSES_XJT_LITE_LR12: case PULSES_PXX_XJT_X16: case PULSES_PXX_XJT_D8: case PULSES_PXX_XJT_LR12: case PULSES_PXX_DJT: mask |= MASK_CHANNELS_RANGE | MASK_CHANNELS_COUNT; - if (protocol==PULSES_PXX_XJT_X16 || protocol==PULSES_PXX_XJT_LR12 || protocol==PULSES_PXX_R9M) + // ACCST Rx ID + if (protocol==PULSES_PXX_XJT_X16 || protocol==PULSES_PXX_XJT_LR12 || + protocol==PULSES_PXX_R9M || protocol==PULSES_ACCST_ISRM_D16 || + protocol==PULSES_XJT_LITE_X16 || protocol==PULSES_XJT_LITE_LR12) mask |= MASK_RX_NUMBER; + // ACCESS + else if (protocol==PULSES_ACCESS_ISRM || protocol==PULSES_ACCESS_R9M || + protocol==PULSES_ACCESS_R9M_LITE || protocol==PULSES_ACCESS_R9M_LITE_PRO) + mask |= MASK_RX_NUMBER | MASK_ACCESS; if ((IS_HORUS(board) || board == Board::BOARD_TARANIS_XLITE) && moduleIdx == 0) mask |= MASK_ANTENNA; break; @@ -492,10 +516,17 @@ void ModulePanel::update() if (mask & MASK_SUBTYPES) { unsigned numEntries = 2; // R9M FCC/EU unsigned i = 0; - if (mask & MASK_MULTIMODULE) + switch(protocol){ + case PULSES_MULTIMODULE: numEntries = (module.multi.customProto ? 8 : pdef.numSubTypes()); - else if (firmware->getCapability(HasModuleR9MFlex)) - i = 2; + break; + case PULSES_PXX_R9M: + if (firmware->getCapability(HasModuleR9MFlex)) + i = 2; + break; + default: + break; + } numEntries += i; const QSignalBlocker blocker(ui->multiSubType); ui->multiSubType->clear(); @@ -525,6 +556,27 @@ void ModulePanel::update() ui->label_option->setText(qApp->translate("Multiprotocols", qPrintable(pdef.optionsstr))); } + if (mask & MASK_ACCESS) { + ui->rx1->setText(module.access.receiverName[0]); + ui->rx2->setText(module.access.receiverName[1]); + ui->rx3->setText(module.access.receiverName[2]); + } + + ui->registrationIdLabel->setVisible(mask & MASK_ACCESS); + ui->registrationId->setVisible(mask & MASK_ACCESS); + + ui->rx1Label->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<0))); + ui->clearRx1->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<0))); + ui->rx1->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<0))); + + ui->rx2Label->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<1))); + ui->clearRx2->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<1))); + ui->rx2->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<1))); + + ui->rx3Label->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<2))); + ui->clearRx3->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<2))); + ui->rx3->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<2))); + // Failsafes ui->label_failsafeMode->setVisible(mask & MASK_FAILSAFES); ui->failsafeMode->setVisible(mask & MASK_FAILSAFES); @@ -575,7 +627,7 @@ void ModulePanel::on_trainerMode_currentIndexChanged(int index) void ModulePanel::onProtocolChanged(int index) { - if (!lock && module.protocol != ui->protocol->itemData(index).toInt()) { + if (!lock && module.protocol != ui->protocol->itemData(index).toUInt()) { module.protocol = ui->protocol->itemData(index).toInt(); update(); emit modified(); @@ -600,7 +652,7 @@ void ModulePanel::on_antennaMode_currentIndexChanged(int index) void ModulePanel::on_r9mPower_currentIndexChanged(int index) { - if (!lock && module.pxx.power != index) { + if (!lock && module.pxx.power != (unsigned int)index) { module.pxx.power = index; emit modified(); } @@ -827,6 +879,30 @@ void ModulePanel::updateFailsafe(int channel) setChannelFailsafeValue(channel, failsafeValue, (FAILSAFE_DISPLAY_PERCENT | FAILSAFE_DISPLAY_USEC)); } +void ModulePanel::onClearAccessRxClicked() +{ + QPushButton *button = qobject_cast(sender()); + + if (button == ui->clearRx1) { + module.access.receivers &= ~(1<<0); + ui->rx1->clear(); + update(); + emit modified(); + } + else if (button == ui->clearRx2) { + module.access.receivers &= ~(1<<1); + ui->rx2->clear(); + update(); + emit modified(); + } + else if (button == ui->clearRx3) { + module.access.receivers &= ~(1<<2); + ui->rx3->clear(); + update(); + emit modified(); + } +} + /******************************************************************************/ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware): @@ -1108,7 +1184,7 @@ void SetupPanel::on_trimIncrement_currentIndexChanged(int index) void SetupPanel::on_throttleSource_currentIndexChanged(int index) { if (!lock) { - model->thrTraceSrc = index; + model->thrTraceSrc = ui->throttleSource->currentData().toUInt(); emit modified(); } } @@ -1168,14 +1244,20 @@ void SetupPanel::populateThrottleSourceCB() Board::Type board = firmware->getBoard(); lock = true; ui->throttleSource->clear(); - ui->throttleSource->addItem(tr("THR")); - for (int i=0; ithrottleSource->addItem(firmware->getAnalogInputName(4+i), i); + ui->throttleSource->addItem(tr("THR"), 0); + + int idx=1; + for (int i=0; ithrottleSource->addItem(firmware->getAnalogInputName(4+i), idx); + } } - for (int i=0; igetCapability(Outputs); i++) { - ui->throttleSource->addItem(RawSource(SOURCE_TYPE_CH, i).toString(model, &generalSettings)); + for (int i=0; igetCapability(Outputs); i++, idx++) { + ui->throttleSource->addItem(RawSource(SOURCE_TYPE_CH, i).toString(model, &generalSettings), idx); } - ui->throttleSource->setCurrentIndex(model->thrTraceSrc); + + int thrTraceSrcIdx = ui->throttleSource->findData(model->thrTraceSrc); + ui->throttleSource->setCurrentIndex(thrTraceSrcIdx); lock = false; } @@ -1373,3 +1455,4 @@ void SetupPanel::on_editText_clicked() g->exec(); } } + diff --git a/companion/src/modeledit/setup.h b/companion/src/modeledit/setup.h index f9c815ef2..fcfc495a4 100644 --- a/companion/src/modeledit/setup.h +++ b/companion/src/modeledit/setup.h @@ -95,6 +95,7 @@ class ModulePanel : public ModelPanel void onFailsafesDisplayValueTypeChanged(int type); void updateFailsafe(int channel); void on_optionValue_editingFinished(); + void onClearAccessRxClicked(); private: enum FailsafeValueDisplayTypes { FAILSAFE_DISPLAY_PERCENT = 1, FAILSAFE_DISPLAY_USEC = 2 }; diff --git a/companion/src/modeledit/setup_module.ui b/companion/src/modeledit/setup_module.ui index 2f6426870..ddf5843f6 100644 --- a/companion/src/modeledit/setup_module.ui +++ b/companion/src/modeledit/setup_module.ui @@ -7,7 +7,7 @@ 0 0 1042 - 297 + 375 @@ -239,25 +239,136 @@ - - + + + + Receiver 1 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + -1 + + + 0 + + + 0 + - + - Bind on startup + + + + true + + + false - + + + + 0 + 0 + + + + + 10 + + - Low Power + X + + + false - + + + + Receiver 2 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + true + + + + + + + + 10 + + + + X + + + false + + + + + + + + + Receiver 3 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + true + + + + + + + + 10 + + + + X + + + false + + + + + + @@ -301,6 +412,37 @@ + + + + + + Bind on startup + + + + + + + Low Power + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + @@ -535,6 +677,19 @@ + + + + Qt::Horizontal + + + + 40 + 20 + + + + @@ -577,7 +732,7 @@ - + Multi Radio Protocol @@ -587,7 +742,7 @@ - + @@ -600,14 +755,14 @@ - + Sub Type - + @@ -620,7 +775,7 @@ - + @@ -636,7 +791,7 @@ - + @@ -674,7 +829,7 @@ - + @@ -690,7 +845,7 @@ - + @@ -728,7 +883,7 @@ - + @@ -772,6 +927,39 @@ + + + + Registration ID + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + diff --git a/companion/src/modeledit/telemetry.cpp b/companion/src/modeledit/telemetry.cpp index 64d2dda46..5d6a23278 100644 --- a/companion/src/modeledit/telemetry.cpp +++ b/companion/src/modeledit/telemetry.cpp @@ -653,6 +653,9 @@ void TelemetrySensorPanel::update() ui->id->hide(); ui->instanceLabel->hide(); ui->instance->hide(); + ui->rxLabel->hide(); + ui->moduleLabel->hide(); + ui->rxOrMod->hide(); ui->formula->show(); ui->formula->setCurrentIndex(sensor.formula); isConfigurable = (sensor.formula < SensorData::TELEM_FORMULA_CELL); @@ -676,6 +679,14 @@ void TelemetrySensorPanel::update() ui->id->show(); ui->instanceLabel->show(); ui->instance->show(); + + bool is_pxx2 = model->moduleData[sensor.moduleIdx].isPxx2Module(); + ui->rxLabel->setVisible(is_pxx2); + ui->moduleLabel->setVisible(!is_pxx2); + + ui->rxOrMod->setText(sensor.getRxOrModName(model)); + ui->rxOrMod->show(); + ui->formula->hide(); isConfigurable = sensor.unit < SensorData::UNIT_FIRST_VIRTUAL; ratioFieldsDisplayed = (sensor.unit < SensorData::UNIT_FIRST_VIRTUAL); @@ -741,14 +752,24 @@ void populateTelemetrySourcesComboBox(AutoComboBox * cb, const ModelData * model cb->clear(); if (negative) { for (int i=-CPN_MAX_SENSORS; i<0; ++i) { - if (model->sensorData[-i-1].isAvailable()) - cb->addItem(QString("-%1").arg(model->sensorData[-i-1].label), i); + const SensorData& sensor = model->sensorData[-i-1]; + if (sensor.isAvailable()) { + if (sensor.type == SensorData::TELEM_TYPE_CUSTOM) + cb->addItem(QString("-%1 (%2)").arg(sensor.label, sensor.getRxOrModName(model)), i); + else + cb->addItem(QString("-%1").arg(sensor.label), i); + } } } cb->addItem("---", 0); for (unsigned i=1; i<=CPN_MAX_SENSORS; ++i) { - if (model->sensorData[i-1].isAvailable()) - cb->addItem(model->sensorData[i-1].label, i); + const SensorData& sensor = model->sensorData[i-1]; + if (sensor.isAvailable()) { + if (sensor.type == SensorData::TELEM_TYPE_CUSTOM) + cb->addItem(QString("%1 (%2)").arg(sensor.label, sensor.getRxOrModName(model)), i); + else + cb->addItem(QString("%1").arg(sensor.label), i); + } } } diff --git a/companion/src/modeledit/telemetry_sensor.ui b/companion/src/modeledit/telemetry_sensor.ui index 9966bc8ee..f6007f6d6 100644 --- a/companion/src/modeledit/telemetry_sensor.ui +++ b/companion/src/modeledit/telemetry_sensor.ui @@ -13,7 +13,7 @@ Form - + 0 @@ -28,6 +28,12 @@ 0 + + + 50 + 16777215 + + 4 @@ -114,6 +120,48 @@ + + + + Rx + + + + + + + Mod. + + + + + + + + 0 + 0 + + + + + 60 + 16777215 + + + + false + + + Qt::RightToLeft + + + 10 + + + true + + + diff --git a/companion/src/simulation/simulatorwidget.cpp b/companion/src/simulation/simulatorwidget.cpp index 2ec00381d..f25873db3 100644 --- a/companion/src/simulation/simulatorwidget.cpp +++ b/companion/src/simulation/simulatorwidget.cpp @@ -90,6 +90,7 @@ SimulatorWidget::SimulatorWidget(QWidget * parent, SimulatorInterface * simulato radioUiWidget = new SimulatedUIWidgetX12(simulator, this); break; case Board::BOARD_X10: + case Board::BOARD_X10_EXPRESS: radioUiWidget = new SimulatedUIWidgetX10(simulator, this); break; case Board::BOARD_JUMPER_T12: diff --git a/companion/src/simulation/widgets/radioswitchwidget.h b/companion/src/simulation/widgets/radioswitchwidget.h index 8943d8c6e..04fb742c1 100644 --- a/companion/src/simulation/widgets/radioswitchwidget.h +++ b/companion/src/simulation/widgets/radioswitchwidget.h @@ -42,7 +42,7 @@ class RadioSwitchWidget : public RadioWidget init(); } - explicit RadioSwitchWidget(Board::SwitchType type, const QString & labelText, int value = 0, QWidget * parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags()) : + explicit RadioSwitchWidget(Board::SwitchType type, const QString & labelText, int value = -1, QWidget * parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags()) : RadioWidget(labelText, value, parent, f), swType(type) { @@ -127,7 +127,7 @@ class RadioSwitchWidget : public RadioWidget void resetToggle() { - setValue(0); + setValue(-1); } private slots: diff --git a/companion/src/storage/bineeprom.cpp b/companion/src/storage/bineeprom.cpp index b896b2a01..5da50652c 100644 --- a/companion/src/storage/bineeprom.cpp +++ b/companion/src/storage/bineeprom.cpp @@ -43,6 +43,7 @@ bool BinEepromFormat::load(RadioData & radioData) return false; } + //TODO: show warnings if any return extract(radioData, eeprom); } @@ -94,7 +95,7 @@ bool BinEepromFormat::extract(RadioData & radioData, const QByteArray & eeprom) std::bitset result((unsigned long long)eepromInterface->load(radioData, (uint8_t *)eeprom.data(), eeprom.size())); if (result.test(ALL_OK)) { if (errors.test(HAS_WARNINGS)) { - EEPROMInterface::showEepromWarnings(NULL, CPN_STR_TTL_WARNING, errors.to_ulong()); + setWarning(EEPROMInterface::getEepromWarnings(errors.to_ulong())); } board = eepromInterface->getBoard(); return true; diff --git a/companion/src/tests/CMakeLists.txt b/companion/src/tests/CMakeLists.txt new file mode 100644 index 000000000..a7666afeb --- /dev/null +++ b/companion/src/tests/CMakeLists.txt @@ -0,0 +1,34 @@ +set(GTEST_ROOT /usr CACHE STRING "Base path to Google Test headers and source.") + +find_path(GTEST_INCDIR gtest/gtest.h HINTS "${GTEST_ROOT}/include" DOC "Path to Google Test header files folder ('gtest/gtest.h').") +find_path(GTEST_SRCDIR src/gtest-all.cc HINTS "${GTEST_ROOT}" "${GTEST_ROOT}/src/gtest" DOC "Path of Google Test 'src' folder.") + +if(GTEST_INCDIR AND GTEST_SRCDIR AND Qt5Widgets_FOUND) + add_library(gtests-companion-lib STATIC EXCLUDE_FROM_ALL ${GTEST_SRCDIR}/src/gtest-all.cc ) + target_include_directories(gtests-companion-lib PUBLIC ${GTEST_INCDIR} ${GTEST_INCDIR}/gtest ${GTEST_SRCDIR}) + add_definitions(-DGTESTS) + set(TESTS_PATH ${COMPANION_SRC_DIRECTORY}/tests) + set(RADIO_TESTS_PATH ${RADIO_SRC_DIRECTORY}/tests) + configure_file(${TESTS_PATH}/location.h.in ${CMAKE_CURRENT_BINARY_DIR}/location.h @ONLY) + + include_directories(${CMAKE_CURRENT_BINARY_DIR}) + + if(WIN32) + target_include_directories(gtests-companion-lib PUBLIC ${WIN_INCLUDE_DIRS}) + target_link_libraries(gtests-companion-lib PRIVATE ${WIN_LINK_LIBRARIES}) + endif(WIN32) + + file(GLOB TEST_SRC_FILES ${TESTS_PATH}/*.cpp) + + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 ${WARNING_FLAGS}") + + use_cxx11() # ensure gnu++11 in CXX_FLAGS with CMake < 3.1 + + add_executable(gtests-companion EXCLUDE_FROM_ALL ${TEST_SRC_FILES} ${CMAKE_CURRENT_SOURCE_DIR}/location.h) + add_dependencies(gtests-companion gtests-companion-lib) + target_link_libraries(gtests-companion gtests-companion-lib simulation firmwares storage common) + message(STATUS "Added optional gtests-companion target") +else() + message(WARNING "WARNING: gtests target will not be available (check that GTEST_INCDIR, GTEST_SRCDIR, and Qt5Widgets are configured).") +endif() diff --git a/companion/src/tests/conversions.cpp b/companion/src/tests/conversions.cpp new file mode 100644 index 000000000..0d6b34272 --- /dev/null +++ b/companion/src/tests/conversions.cpp @@ -0,0 +1,188 @@ +#include "gtests.h" +#include "location.h" +#include "storage/otx.h" +#include "storage/storage.h" +#include "firmwares/opentx/opentxinterface.h" +#include "firmwares/customfunctiondata.h" + +TEST(Conversions, ConversionX9DPFrom22) +{ + RadioData radioData; + Storage store = Storage(RADIO_TESTS_PATH "/eeprom_22_x9d+.bin"); + + ASSERT_EQ(true, store.load(radioData)); + + ASSERT_EQ(true, store.load(radioData)); + + const GeneralSettings& settings = radioData.generalSettings; + EXPECT_EQ(RawSwitch(SWITCH_TYPE_TELEMETRY,1), settings.customFn[0].swtch); + EXPECT_EQ(FuncLogs, settings.customFn[0].func); + EXPECT_EQ(20, settings.customFn[0].param); + + EXPECT_STREQ("Tes", settings.switchName[0]); + EXPECT_EQ(Board::SWITCH_3POS, settings.switchConfig[0]); + + const ModelData& model = radioData.models[0]; + EXPECT_STREQ("Test", model.name); + EXPECT_EQ(RawSwitch(SWITCH_TYPE_SWITCH,SWITCH_SA0), model.timers[0].mode); + EXPECT_EQ(80, model.mixData[0].weight); + EXPECT_EQ(900, model.limitData[0].max); // -100 + EXPECT_EQ(80, model.expoData[0].weight); + EXPECT_EQ(HELI_SWASH_TYPE_120X, model.swashRingData.type); + EXPECT_EQ(10, model.flightModeData[0].gvars[0]); + EXPECT_STREQ("Tes", model.gvarData[0].name); + EXPECT_EQ(PULSES_PXX_XJT_X16, model.moduleData[0].protocol); + EXPECT_EQ(0, model.moduleData[0].subType); + EXPECT_EQ(PULSES_PXX_R9M, model.moduleData[1].protocol); + EXPECT_EQ(MODULE_SUBTYPE_R9M_FCC, model.moduleData[1].subType); + EXPECT_STREQ("Thr", model.inputNames[0]); + EXPECT_STREQ("Tes", model.sensorData[0].label); + EXPECT_EQ(10, model.sensorData[0].id); + EXPECT_EQ(9, model.sensorData[0].instance); + EXPECT_EQ(RawSource(SOURCE_TYPE_TELEMETRY,0).toValue(), model.logicalSw[0].val1); +} + +TEST(Conversions, ConversionX7From22) +{ + RadioData radioData; + Storage store = Storage(RADIO_TESTS_PATH "/eeprom_22_x7.bin"); + + ASSERT_EQ(true, store.load(radioData)); + + const GeneralSettings& settings = radioData.generalSettings; + EXPECT_EQ(RawSwitch(SWITCH_TYPE_TELEMETRY,1), settings.customFn[0].swtch); + EXPECT_EQ(FuncLogs, settings.customFn[0].func); + EXPECT_EQ(20, settings.customFn[0].param); + + EXPECT_STREQ("Tes", settings.switchName[0]); + EXPECT_EQ(Board::SWITCH_3POS, settings.switchConfig[0]); + + const ModelData& model = radioData.models[0]; + EXPECT_STREQ("Test", model.name); + EXPECT_EQ(PULSES_PXX_R9M, model.moduleData[1].protocol); + EXPECT_EQ(MODULE_SUBTYPE_R9M_EU, model.moduleData[1].subType); + + EXPECT_EQ(80, model.mixData[0].weight); + EXPECT_EQ(80, model.expoData[0].weight); + + EXPECT_EQ(RawSource(SOURCE_TYPE_PPM,0), model.mixData[4].srcRaw); + EXPECT_EQ(RawSwitch(SWITCH_TYPE_TELEMETRY,1), model.mixData[4].swtch); + EXPECT_EQ(HELI_SWASH_TYPE_120X, model.swashRingData.type); + EXPECT_STREQ("Thr", model.inputNames[0]); + + EXPECT_STREQ("Tes", model.sensorData[0].label); + EXPECT_EQ(10, model.sensorData[0].id); + EXPECT_EQ(9, model.sensorData[0].instance); + EXPECT_EQ(900, model.limitData[0].max); // -100 + + EXPECT_EQ(10, model.flightModeData[0].gvars[0]); + EXPECT_STREQ("FMtest", model.flightModeData[1].name); + EXPECT_EQ(RawSwitch(SWITCH_TYPE_VIRTUAL,1), model.flightModeData[1].swtch); + EXPECT_STREQ("Tes", model.gvarData[0].name); + + EXPECT_EQ(LS_FN_VPOS, model.logicalSw[0].func); + EXPECT_EQ(RawSource(SOURCE_TYPE_PPM,0).toValue(), model.logicalSw[0].val1); + EXPECT_EQ(0, model.logicalSw[0].val2); + + const FrSkyScreenData& screen = model.frsky.screens[0]; + EXPECT_EQ(TELEMETRY_SCREEN_NUMBERS, screen.type); + EXPECT_EQ(RawSource(SOURCE_TYPE_PPM,0), screen.body.lines[0].source[0]); + EXPECT_EQ(RawSource(SOURCE_TYPE_SPECIAL,4), screen.body.lines[0].source[1]); +} + + +bool loadFile(QByteArray & filedata, const QString & filename) +{ + QFile file(filename); + if (!file.open(QFile::ReadOnly)) { + qDebug() << QString("Error opening file %1:\n%2.").arg(filename).arg(file.errorString()); + return false; + } + filedata = file.readAll(); + qDebug() << "File" << filename << "read, size:" << filedata.size(); + return true; +} + +TEST(Conversions, ConversionX10From22) +{ + QByteArray byteBuffer; + +#define USE_OTX + +#if defined(USE_OTX) + OtxFormat otx(RADIO_TESTS_PATH "/model_22_x10.otx"); + RadioData radio; + EXPECT_EQ(true, otx.load(radio)); + + const GeneralSettings& settings = radio.generalSettings; + const ModelData& model = radio.models[0]; +#else + ASSERT_EQ(true, loadFile(byteBuffer, RADIO_TESTS_PATH "/model_22_x10/RADIO/radio.bin")); + + GeneralSettings settings; + EXPECT_NE(nullptr, loadRadioSettingsFromByteArray(settings, byteBuffer)); +#endif + + EXPECT_EQ(100, settings.calibSpanNeg[9]); + EXPECT_EQ(500, settings.calibMid[9]); + EXPECT_EQ(900, settings.calibSpanPos[9]); + + EXPECT_EQ(200, settings.calibSpanNeg[10]); + EXPECT_EQ(400, settings.calibMid[10]); + EXPECT_EQ(600, settings.calibSpanPos[10]); + + EXPECT_EQ(-23, settings.vBatMin); + EXPECT_EQ(20, settings.speakerVolume); + EXPECT_STREQ("en", settings.ttsLanguage); + EXPECT_STREQ("model1.bin", settings.currModelFilename); + + EXPECT_EQ(RawSwitch(SWITCH_TYPE_TELEMETRY,1), settings.customFn[0].swtch); + EXPECT_EQ(FuncLogs, settings.customFn[0].func); + EXPECT_EQ(20, settings.customFn[0].param); + + EXPECT_EQ(RawSwitch(SWITCH_TYPE_ON), settings.customFn[1].swtch); + EXPECT_EQ(FuncVolume, settings.customFn[1].func); + EXPECT_EQ(RawSource(SOURCE_TYPE_STICK,4+5+1).toValue(), settings.customFn[1].param); // RS + + EXPECT_STREQ("Tes", settings.switchName[0]); + EXPECT_EQ(Board::SWITCH_3POS, settings.switchConfig[0]); + + EXPECT_STREQ("BT_X10", settings.bluetoothName); + EXPECT_STREQ("Default", settings.themeName); + +#if !defined(USE_OTX) + byteBuffer.clear(); + ASSERT_EQ(true, loadFile(byteBuffer, RADIO_TESTS_PATH "/model_22_x10/MODELS/model1.bin")); + + ModelData model; + ASSERT_NE(nullptr, loadModelFromByteArray(model, byteBuffer)); +#endif + + EXPECT_STREQ("Test", model.name); + EXPECT_EQ(0, model.noGlobalFunctions); + EXPECT_EQ(0, model.beepANACenter); + EXPECT_EQ(80, model.mixData[0].weight); + EXPECT_EQ(RawSource(SOURCE_TYPE_MAX), model.mixData[2].srcRaw); // MAX + EXPECT_EQ(RawSource(SOURCE_TYPE_STICK,4+5), model.mixData[3].srcRaw); // LS + EXPECT_EQ(RawSource(SOURCE_TYPE_PPM,0), model.mixData[5].srcRaw); + EXPECT_EQ(RawSwitch(SWITCH_TYPE_TELEMETRY,1), model.mixData[5].swtch); + EXPECT_EQ(900, model.limitData[0].max); // -100 + EXPECT_EQ(80, model.expoData[0].weight); + EXPECT_EQ(LS_FN_VPOS, model.logicalSw[0].func); + EXPECT_EQ(RawSource(SOURCE_TYPE_PPM,0).toValue(), model.logicalSw[0].val1); // TR1 + EXPECT_EQ(0, model.logicalSw[0].val2); + EXPECT_EQ(RawSource(SOURCE_TYPE_TELEMETRY,19*3).toValue(), model.logicalSw[1].val1); // TELE:20 + EXPECT_EQ(20, model.logicalSw[1].val2); + EXPECT_EQ(RawSwitch(SWITCH_TYPE_VIRTUAL,1).toValue(), model.logicalSw[1].andsw); + EXPECT_EQ(HELI_SWASH_TYPE_120X, model.swashRingData.type); + EXPECT_STREQ("Tes", model.flightModeData[0].name); + EXPECT_EQ(10, model.flightModeData[0].gvars[0]); + EXPECT_STREQ("Tes", model.gvarData[0].name); + EXPECT_EQ(PULSES_PXX_R9M, model.moduleData[1].protocol); + EXPECT_EQ(MODULE_SUBTYPE_R9M_EU, model.moduleData[1].subType); + EXPECT_STREQ("Rud", model.inputNames[0]); + EXPECT_STREQ("Tes", model.sensorData[0].label); + EXPECT_EQ(10, model.sensorData[0].id); + EXPECT_EQ(9, model.sensorData[0].instance); + EXPECT_EQ(5 + 2 + 3, model.thrTraceSrc); // CH3 +} diff --git a/companion/src/tests/gtests.cpp b/companion/src/tests/gtests.cpp new file mode 100644 index 000000000..80c36da22 --- /dev/null +++ b/companion/src/tests/gtests.cpp @@ -0,0 +1,149 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include "gtests.h" + +#include "storage.h" +#include "opentxinterface.h" +#include "customdebug.h" + + +using ::testing::TestEventListener; +using ::testing::EmptyTestEventListener; +using ::testing::Test; +using ::testing::TestCase; +using ::testing::TestEventListeners; +using ::testing::TestInfo; +using ::testing::TestPartResult; +using ::testing::UnitTest; +using ::testing::InitGoogleTest; + +namespace { + +void printColorCode(int color) +{ +#if !GTEST_OS_WINDOWS + if (isatty(fileno(stdout))) + fprintf(stdout, "\033[0;%dm", color); +#endif +} + +/** + * Replaces gtest's PrettyUnitTestResultPrinter with something less verbose. + * Uses the default printer if/when the messages might be interesting, + * e.g. for full error info or tests summary. +*/ +class TersePrinter : public EmptyTestEventListener { + public: + explicit TersePrinter(TestEventListener * prettyPrinter) + : prettyPrinter(prettyPrinter), currentTestInfo(NULL) + { + } + void OnTestProgramStart(const UnitTest & unit_test) + { + prettyPrinter->OnTestProgramStart(unit_test); + } + void OnTestIterationStart(const UnitTest & unit_test, int iteration) + { + printColorCode(36); + fprintf(stdout, "############ "); + fprintf(stdout, "Running %d test(s) from %d test case(s), iteration: %d.\n", unit_test.test_to_run_count(), unit_test.test_case_to_run_count(), iteration + 1); + printColorCode(0); + fflush(stdout); + } + void OnTestCaseStart(const TestCase & test_case) + { + prettyPrinter->OnTestCaseStart(test_case); + } + void OnTestStart(const TestInfo & test_info) + { + currentTestInfo = &test_info; + } + void OnTestPartResult(const TestPartResult & test_part_result) + { + if (test_part_result.failed()) { + prettyPrinter->OnTestStart(*currentTestInfo); + prettyPrinter->OnTestPartResult(test_part_result); + } + } + void OnTestEnd(const TestInfo & test_info) + { + currentTestInfo = NULL; + if (test_info.result()->Failed()) { + prettyPrinter->OnTestEnd(test_info); + } + else { + printColorCode(32); + fprintf(stdout, "+"); + printColorCode(0); + fflush(stdout); + } + } + void OnTestCaseEnd(const TestCase & test_case) + { + fprintf(stdout, "\n"); + fflush(stdout); + } + void OnTestIterationEnd(const UnitTest & unit_test, int iteration) + { + prettyPrinter->OnTestIterationEnd(unit_test, iteration); + } + void OnTestProgramEnd(const UnitTest & unit_test) + { + prettyPrinter->OnTestProgramEnd(unit_test); + } + + private: + // gtest's default unit test result printer. + std::unique_ptr prettyPrinter; + // The currently running TestInfo, if any. + const TestInfo * currentTestInfo; +}; + +} // anonymous namespace + +int main(int argc, char **argv) +{ + QCoreApplication app(argc, argv); + + CustomDebug::setFilterRules(); + registerStorageFactories(); + registerOpenTxFirmwares(); + + InitGoogleTest(&argc, argv); + + // use --verbose option to revert to gtest's default output format + bool verbose = false; + if (argc > 1 && !strcmp(argv[1], "--verbose")) + verbose = true; + + if (!verbose) { + TestEventListeners & listeners = UnitTest::GetInstance()->listeners(); + TestEventListener * defaultPrinter = listeners.Release(listeners.default_result_printer()); + listeners.Append(new TersePrinter(defaultPrinter)); + } + + return RUN_ALL_TESTS(); +} diff --git a/companion/src/tests/gtests.h b/companion/src/tests/gtests.h new file mode 100644 index 000000000..29e437ddc --- /dev/null +++ b/companion/src/tests/gtests.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _GTESTS_H_ +#define _GTESTS_H_ + +#include +#include +#include + +class OpenTxTest : public testing::Test +{ + protected: // You should make the members protected s.t. they can be + // accessed from sub-classes. + + // virtual void SetUp() will be called before each test is run. You + // should define it if you need to initialize the varaibles. + // Otherwise, this can be skipped. + virtual void SetUp() + { + } +}; + +#endif // _GTESTS_H_ diff --git a/companion/src/tests/location.h.in b/companion/src/tests/location.h.in new file mode 100644 index 000000000..78617cf0a --- /dev/null +++ b/companion/src/tests/location.h.in @@ -0,0 +1,2 @@ +#define TESTS_PATH "@TESTS_PATH@" +#define RADIO_TESTS_PATH "@RADIO_TESTS_PATH@" diff --git a/radio/sdcard/horus/THEMES/Darkblue/mask_radio_spectrum_analyser.png b/radio/sdcard/horus/THEMES/Darkblue/mask_radio_spectrum_analyser.png new file mode 100755 index 000000000..2908833ec Binary files /dev/null and b/radio/sdcard/horus/THEMES/Darkblue/mask_radio_spectrum_analyser.png differ diff --git a/radio/sdcard/horus/THEMES/Default/mask_radio_spectrum_analyser.png b/radio/sdcard/horus/THEMES/Default/mask_radio_spectrum_analyser.png new file mode 100755 index 000000000..2908833ec Binary files /dev/null and b/radio/sdcard/horus/THEMES/Default/mask_radio_spectrum_analyser.png differ diff --git a/radio/src/bluetooth.cpp b/radio/src/bluetooth.cpp index 7a9b52f04..db02e6e54 100644 --- a/radio/src/bluetooth.cpp +++ b/radio/src/bluetooth.cpp @@ -600,11 +600,8 @@ enum { CMD_RET_SUCCESS = 0x40, }; -constexpr uint32_t CC26XX_FLASH_SIZE = 0x00020000; constexpr uint32_t CC26XX_BOOTLOADER_SIZE = 0x00001000; -constexpr uint32_t CC26XX_DATA_SIZE = 0x00001000; constexpr uint32_t CC26XX_FIRMWARE_BASE = CC26XX_BOOTLOADER_SIZE; -constexpr uint32_t CC26XX_FIRMWARE_SIZE = CC26XX_FLASH_SIZE - CC26XX_DATA_SIZE - CC26XX_BOOTLOADER_SIZE; constexpr uint32_t CC26XX_PAGE_ERASE_SIZE = 0x1000; constexpr uint32_t CC26XX_MAX_BYTES_PER_TRANSFER = 252; diff --git a/radio/src/dataconstants.h b/radio/src/dataconstants.h index 8e05ce0a4..a1db5ebdd 100644 --- a/radio/src/dataconstants.h +++ b/radio/src/dataconstants.h @@ -828,9 +828,7 @@ enum Functions { FUNC_HAPTIC, FUNC_LOGS, FUNC_BACKLIGHT, -#if defined(PCBTARANIS) FUNC_SCREENSHOT, -#endif #if defined(DEBUG) FUNC_TEST, // should remain the last before MAX as not added in Companion #endif @@ -861,9 +859,7 @@ enum ResetFunctionParam { FUNC_RESET_TIMER2, FUNC_RESET_TIMER3, FUNC_RESET_FLIGHT, -#if defined(TELEMETRY_FRSKY) FUNC_RESET_TELEMETRY, -#endif FUNC_RESET_PARAM_FIRST_TELEM, FUNC_RESET_PARAM_LAST_TELEM = FUNC_RESET_PARAM_FIRST_TELEM + MAX_TELEMETRY_SENSORS, FUNC_RESET_PARAMS_COUNT, diff --git a/radio/src/functions.cpp b/radio/src/functions.cpp index 62282afb6..bd840fc4a 100644 --- a/radio/src/functions.cpp +++ b/radio/src/functions.cpp @@ -194,11 +194,9 @@ void evalFunctions(const CustomFunctionData * functions, CustomFunctionsContext mainRequestFlags |= (1 << REQUEST_FLIGHT_RESET); // on systems with threads flightReset() must not be called from the mixers thread! } break; -#if defined(TELEMETRY_FRSKY) case FUNC_RESET_TELEMETRY: telemetryReset(); break; -#endif } if (CFN_PARAM(cfn)>=FUNC_RESET_PARAM_FIRST_TELEM) { uint8_t item = CFN_PARAM(cfn)-FUNC_RESET_PARAM_FIRST_TELEM; @@ -338,7 +336,7 @@ void evalFunctions(const CustomFunctionData * functions, CustomFunctionsContext } #endif -#if defined(TELEMETRY_FRSKY) && defined(VARIO) +#if defined(VARIO) case FUNC_VARIO: newActiveFunctions |= (1 << FUNCTION_VARIO); break; @@ -358,13 +356,11 @@ void evalFunctions(const CustomFunctionData * functions, CustomFunctionsContext newActiveFunctions |= (1 << FUNCTION_BACKLIGHT); break; -#if defined(PCBTARANIS) case FUNC_SCREENSHOT: if (!(functionsContext.activeSwitches & switch_mask)) { mainRequestFlags |= (1 << REQUEST_SCREENSHOT); } break; -#endif #if defined(DEBUG) case FUNC_TEST: diff --git a/radio/src/gui/128x64/gui.h b/radio/src/gui/128x64/gui.h index 0bbd83073..be69f27f7 100644 --- a/radio/src/gui/128x64/gui.h +++ b/radio/src/gui/128x64/gui.h @@ -309,11 +309,7 @@ void showAlertBox(const char * title, const char * text, const char * action , u #define LOAD_MODEL_BITMAP() #define IS_MAIN_VIEW_DISPLAYED() menuHandlers[0] == menuMainView -#if defined(TELEMETRY_FRSKY) #define IS_TELEMETRY_VIEW_DISPLAYED() menuHandlers[0] == menuViewTelemetryFrsky -#else -#define IS_TELEMETRY_VIEW_DISPLAYED() false -#endif #define IS_OTHER_VIEW_DISPLAYED() false void editCurveRef(coord_t x, coord_t y, CurveRef & curve, event_t event, LcdFlags flags); diff --git a/radio/src/gui/128x64/lcd.h b/radio/src/gui/128x64/lcd.h index 06ad69728..c415e1091 100644 --- a/radio/src/gui/128x64/lcd.h +++ b/radio/src/gui/128x64/lcd.h @@ -197,8 +197,6 @@ inline display_t getPixel(uint8_t x, uint8_t y) return ((pixel & mask) ? 0xf : 0); } -const char * writeScreenshot(); - uint8_t getTextWidth(const char * s, uint8_t len=0, LcdFlags flags=0); #endif // _LCD_H_ diff --git a/radio/src/gui/128x64/menu_model.cpp b/radio/src/gui/128x64/menu_model.cpp index 8d4f80dd0..0f64fab14 100644 --- a/radio/src/gui/128x64/menu_model.cpp +++ b/radio/src/gui/128x64/menu_model.cpp @@ -20,7 +20,6 @@ #include "opentx.h" - uint8_t editDelay(coord_t y, event_t event, uint8_t attr, const char * str, uint8_t delay) { lcdDrawTextAlignedLeft(y, str); diff --git a/radio/src/gui/128x64/menus.h b/radio/src/gui/128x64/menus.h index 94f21a27c..4f1428a6f 100644 --- a/radio/src/gui/128x64/menus.h +++ b/radio/src/gui/128x64/menus.h @@ -101,7 +101,7 @@ enum MenuModelIndexes { #if defined(LUA_MODEL_SCRIPTS) MENU_MODEL_CUSTOM_SCRIPTS, #endif - CASE_FRSKY(MENU_MODEL_TELEMETRY_FRSKY) + MENU_MODEL_TELEMETRY, MENU_MODEL_DISPLAY, MENU_MODEL_PAGES_COUNT }; @@ -124,7 +124,7 @@ void menuModelGVars(event_t event); void menuModelLogicalSwitches(event_t event); void menuModelSpecialFunctions(event_t event); void menuModelCustomScripts(event_t event); -void menuModelTelemetryFrsky(event_t event); +void menuModelTelemetry(event_t event); void menuModelSensor(event_t event); void menuModelDisplay(event_t event); void menuModelTemplates(event_t event); @@ -144,7 +144,7 @@ static const MenuHandlerFunc menuTabModel[] = { #if defined(LUA_MODEL_SCRIPTS) menuModelCustomScripts, #endif - CASE_FRSKY(menuModelTelemetryFrsky) + menuModelTelemetry, menuModelDisplay, }; diff --git a/radio/src/gui/128x64/model_failsafe.cpp b/radio/src/gui/128x64/model_failsafe.cpp index d3db3115b..f0a926074 100644 --- a/radio/src/gui/128x64/model_failsafe.cpp +++ b/radio/src/gui/128x64/model_failsafe.cpp @@ -18,7 +18,7 @@ * GNU General Public License for more details. */ -#include +#include "opentx.h" extern uint8_t g_moduleIdx; diff --git a/radio/src/gui/128x64/model_logical_switches.cpp b/radio/src/gui/128x64/model_logical_switches.cpp index 5bc3227f0..90fc08481 100644 --- a/radio/src/gui/128x64/model_logical_switches.cpp +++ b/radio/src/gui/128x64/model_logical_switches.cpp @@ -154,7 +154,6 @@ void menuModelLogicalSwitchOne(event_t event) INCDEC_ENABLE_CHECK(isSourceAvailable); } else { -#if defined(TELEMETRY_FRSKY) if (v1_val >= MIXSRC_FIRST_TELEM) { drawSourceCustomValue(CSWONE_2ND_COLUMN, y, v1_val, convertLswTelemValue(cs), attr|LEFT); v2_max = maxTelemValue(v1_val - MIXSRC_FIRST_TELEM + 1); @@ -171,7 +170,6 @@ void menuModelLogicalSwitchOne(event_t event) } } else -#endif // TELEMETRY_FRSKY { LcdFlags lf = attr | LEFT; getMixSrcRange(v1_val, v2_min, v2_max, &lf); diff --git a/radio/src/gui/128x64/model_setup.cpp b/radio/src/gui/128x64/model_setup.cpp index 04d253064..6e8709dea 100644 --- a/radio/src/gui/128x64/model_setup.cpp +++ b/radio/src/gui/128x64/model_setup.cpp @@ -192,7 +192,19 @@ enum MenuModelSetupItems { #endif #define PORT_CHANNELS_ROWS(x) (x==EXTERNAL_MODULE ? EXTERNAL_MODULE_CHANNELS_ROWS : 0) -#define EXTERNAL_MODULE_TYPE_ROWS (isModulePXX1(EXTERNAL_MODULE) || isModulePXX2(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE) || isModuleMultimodule(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0 + +inline uint8_t EXTERNAL_MODULE_TYPE_ROW() +{ + if (isModuleXJT(EXTERNAL_MODULE) || isModuleR9MNonAccess(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE)) + return 1; +#if defined(MULTIMODULE) + else if (isModuleMultimodule(EXTERNAL_MODULE)) { + return 1; + } +#endif + else + return 0; +} #define POT_WARN_ROWS ((g_model.potsWarnMode) ? (uint8_t)(NUM_POTS+NUM_SLIDERS) : (uint8_t)0) #define TIMER_ROWS 2, 0, 0, 0, 0 @@ -315,7 +327,7 @@ void menuModelSetup(event_t event) INTERNAL_MODULE_ROWS LABEL(ExternalModule), - EXTERNAL_MODULE_TYPE_ROWS, + EXTERNAL_MODULE_TYPE_ROW(), MULTIMODULE_SUBTYPE_ROWS(EXTERNAL_MODULE) EXTERNAL_MODULE_POWER_ROW, MULTIMODULE_STATUS_ROWS @@ -336,7 +348,7 @@ void menuModelSetup(event_t event) #else MENU_TAB({ HEADER_LINE_COLUMNS 0, TIMER_ROWS, TIMER_ROWS, TIMER_ROWS, 0, 1, 0, 0, 0, 0, 0, LABEL(PreflightCheck), 0, 0, NUM_SWITCHES-1, NUM_STICKS+NUM_POTS+NUM_SLIDERS-1, 0, LABEL(ExternalModule), - EXTERNAL_MODULE_TYPE_ROWS, + EXTERNAL_MODULE_TYPE_ROW(), MULTIMODULE_SUBTYPE_ROWS(EXTERNAL_MODULE) MULTIMODULE_STATUS_ROWS EXTERNAL_MODULE_CHANNELS_ROWS, @@ -764,10 +776,7 @@ void menuModelSetup(event_t event) if (menuHorizontalPosition == 0) { uint8_t moduleType = checkIncDec(event, g_model.moduleData[INTERNAL_MODULE].type, MODULE_TYPE_NONE, MODULE_TYPE_MAX, EE_MODEL, isInternalModuleAvailable); if (checkIncDec_Ret) { - // TODO this code should be common, in module.h (X10_new_UI branch) - memclear(&g_model.moduleData[INTERNAL_MODULE], sizeof(ModuleData)); - g_model.moduleData[INTERNAL_MODULE].type = moduleType; - g_model.moduleData[INTERNAL_MODULE].channelsCount = defaultModuleChannels_M8(INTERNAL_MODULE); + setModuleType(INTERNAL_MODULE, moduleType); } } else if (isModuleXJT(INTERNAL_MODULE)) { @@ -837,22 +846,9 @@ void menuModelSetup(event_t event) switch (menuHorizontalPosition) { case 0: { - uint8_t moduleType = checkIncDec(event, - g_model.moduleData[EXTERNAL_MODULE].type, - MODULE_TYPE_NONE, - IS_TRAINER_EXTERNAL_MODULE() ? MODULE_TYPE_NONE : - MODULE_TYPE_COUNT - 1, - EE_MODEL, - isExternalModuleAvailable); + uint8_t moduleType = checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].type, MODULE_TYPE_NONE, MODULE_TYPE_MAX, EE_MODEL, isExternalModuleAvailable); if (checkIncDec_Ret) { - // TODO this code should be common, in module.h (X10_new_UI branch) - memclear(&g_model.moduleData[EXTERNAL_MODULE], sizeof(ModuleData)); - g_model.moduleData[EXTERNAL_MODULE].type = moduleType; - g_model.moduleData[EXTERNAL_MODULE].channelsCount = defaultModuleChannels_M8(EXTERNAL_MODULE); - if (isModuleSBUS(EXTERNAL_MODULE)) - g_model.moduleData[EXTERNAL_MODULE].sbus.refreshRate = -31; - if (isModulePPM(EXTERNAL_MODULE)) - SET_DEFAULT_PPM_FRAME_LENGTH(EXTERNAL_MODULE); + setModuleType(EXTERNAL_MODULE, moduleType); } } break; @@ -1078,7 +1074,7 @@ void menuModelSetup(event_t event) case 1: CHECK_INCDEC_MODELVAR_CHECK(event, moduleData.channelsCount, -4, min(maxModuleChannels_M8(moduleIdx), 32-8-moduleData.channelsStart), moduleData.type == MODULE_TYPE_ISRM_PXX2 ? isPxx2IsrmChannelsCountAllowed : nullptr); if (checkIncDec_Ret && moduleData.type == MODULE_TYPE_PPM) { - SET_DEFAULT_PPM_FRAME_LENGTH(moduleIdx); + setDefaultPpmFrameLength(moduleIdx); } break; } @@ -1538,7 +1534,6 @@ void menuModelSetup(event_t event) } #endif - #if 0 case ITEM_MODEL_SETUP_PPM2_PROTOCOL: lcdDrawTextAlignedLeft(y, "Port2"); @@ -1551,11 +1546,11 @@ void menuModelSetup(event_t event) switch (menuHorizontalPosition) { case 0: CHECK_INCDEC_MODELVAR_ZERO(event, g_model.moduleData[1].channelsStart, 32-8-g_model.moduleData[1].channelsCount); - SET_DEFAULT_PPM_FRAME_LENGTH(1); + setDefaultPpmFrameLength(1); break; case 1: CHECK_INCDEC_MODELVAR(event, g_model.moduleData[1].channelsCount, -4, min(8, 32-8-g_model.moduleData[1].channelsStart)); - SET_DEFAULT_PPM_FRAME_LENGTH(1); + setDefaultPpmFrameLength(1); break; } } @@ -1588,7 +1583,7 @@ void menuModelSetup(event_t event) } #if defined(PXX) - if (IS_RANGECHECK_ENABLE()) { + if (isModuleInRangeCheckMode()) { showMessageBox("RSSI: "); lcdDrawNumber(WARNING_LINE_X, 5*FH, TELEMETRY_RSSI(), BOLD); } diff --git a/radio/src/gui/128x64/model_telemetry.cpp b/radio/src/gui/128x64/model_telemetry.cpp index 3b98cad70..04a6a26c9 100644 --- a/radio/src/gui/128x64/model_telemetry.cpp +++ b/radio/src/gui/128x64/model_telemetry.cpp @@ -54,28 +54,25 @@ enum MenuModelTelemetryFrskyItems { #define TELEM_COL3 (17 * FW) -#define CHANNELS_ROWS -#define SENSOR_ROWS(x) (isTelemetryFieldAvailable(x) ? (uint8_t)0 : HIDDEN_ROW) -#define SENSORS_ROWS LABEL(Sensors), SENSOR_ROWS(0), SENSOR_ROWS(1), SENSOR_ROWS(2), SENSOR_ROWS(3), SENSOR_ROWS(4), SENSOR_ROWS(5), SENSOR_ROWS(6), SENSOR_ROWS(7), SENSOR_ROWS(8), SENSOR_ROWS(9), SENSOR_ROWS(10), SENSOR_ROWS(11), SENSOR_ROWS(12), SENSOR_ROWS(13), SENSOR_ROWS(14), SENSOR_ROWS(15), SENSOR_ROWS(16), SENSOR_ROWS(17), SENSOR_ROWS(18), SENSOR_ROWS(19), SENSOR_ROWS(20), SENSOR_ROWS(21), SENSOR_ROWS(22), SENSOR_ROWS(23), SENSOR_ROWS(24), SENSOR_ROWS(25), SENSOR_ROWS(26), SENSOR_ROWS(27), SENSOR_ROWS(28), SENSOR_ROWS(29), SENSOR_ROWS(30), SENSOR_ROWS(31), SENSOR_ROWS(32), SENSOR_ROWS(33), SENSOR_ROWS(34), SENSOR_ROWS(35), SENSOR_ROWS(36), SENSOR_ROWS(37), SENSOR_ROWS(38), SENSOR_ROWS(39), 0, 0, 0, 0, - -#define USRDATA_ROWS - -#define RSSI_ROWS LABEL(RSSI), 0, 0, 0, 1, - -#define SCREEN_TYPE_ROWS 0 - -#define VARIO_ROWS LABEL(Vario), 0, 1, 2, - -#if defined (PCBTARANIS) - #define TELEMETRY_TYPE_SHOW_TELEMETRY (! IS_INTERNAL_MODULE_ENABLED() && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM) ? (uint8_t)0 : HIDDEN_ROW +#define RSSI_ROWS LABEL(RSSI), 0, 0, 0, 0, +#define SENSOR_ROWS(x) (isTelemetryFieldAvailable(x) ? (uint8_t)0 : HIDDEN_ROW) +#define SENSORS_ROWS LABEL(Sensors), SENSOR_ROWS(0), SENSOR_ROWS(1), SENSOR_ROWS(2), SENSOR_ROWS(3), SENSOR_ROWS(4), SENSOR_ROWS(5), SENSOR_ROWS(6), SENSOR_ROWS(7), SENSOR_ROWS(8), SENSOR_ROWS(9), SENSOR_ROWS(10), SENSOR_ROWS(11), SENSOR_ROWS(12), SENSOR_ROWS(13), SENSOR_ROWS(14), SENSOR_ROWS(15), SENSOR_ROWS(16), SENSOR_ROWS(17), SENSOR_ROWS(18), SENSOR_ROWS(19), SENSOR_ROWS(20), SENSOR_ROWS(21), SENSOR_ROWS(22), SENSOR_ROWS(23), SENSOR_ROWS(24), SENSOR_ROWS(25), SENSOR_ROWS(26), SENSOR_ROWS(27), SENSOR_ROWS(28), SENSOR_ROWS(29), SENSOR_ROWS(30), SENSOR_ROWS(31), SENSOR_ROWS(32), SENSOR_ROWS(33), SENSOR_ROWS(34), SENSOR_ROWS(35), SENSOR_ROWS(36), SENSOR_ROWS(37), SENSOR_ROWS(38), SENSOR_ROWS(39), 0, 0, 0, 0, +#if defined(VARIO) + #define VARIO_ROWS LABEL(Vario), 0, 1, 2, #else - #define TELEMETRY_TYPE_SHOW_TELEMETRY (g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM) ? (uint8_t)0 : HIDDEN_ROW + #define VARIO_ROWS +#endif + +#if defined(PCBTARANIS) + #define TELEMETRY_TYPE_ROW (!IS_INTERNAL_MODULE_ENABLED() && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM) ? (uint8_t)0 : HIDDEN_ROW +#else + #define TELEMETRY_TYPE_ROW (g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM) ? (uint8_t)0 : HIDDEN_ROW #endif #if defined(REVX) - #define TELEMETRY_TYPE_ROWS TELEMETRY_TYPE_SHOW_TELEMETRY, TELEMETRY_TYPE_SHOW_TELEMETRY, + #define TELEMETRY_TYPE_ROWS TELEMETRY_TYPE_ROW, TELEMETRY_TYPE_ROW, #else - #define TELEMETRY_TYPE_ROWS TELEMETRY_TYPE_SHOW_TELEMETRY, + #define TELEMETRY_TYPE_ROWS TELEMETRY_TYPE_ROW, #endif void onSensorMenu(const char * result) @@ -121,13 +118,13 @@ void onDeleteAllSensorsConfirm(const char * result) } } -void menuModelTelemetryFrsky(event_t event) +void menuModelTelemetry(event_t event) { - MENU(STR_MENUTELEMETRY, menuTabModel, MENU_MODEL_TELEMETRY_FRSKY, HEADER_LINE+ITEM_TELEMETRY_MAX, { HEADER_LINE_COLUMNS TELEMETRY_TYPE_ROWS CHANNELS_ROWS RSSI_ROWS SENSORS_ROWS USRDATA_ROWS VARIO_ROWS}); + MENU(STR_MENUTELEMETRY, menuTabModel, MENU_MODEL_TELEMETRY, HEADER_LINE+ITEM_TELEMETRY_MAX, { HEADER_LINE_COLUMNS TELEMETRY_TYPE_ROWS RSSI_ROWS SENSORS_ROWS VARIO_ROWS }); uint8_t sub = menuVerticalPosition - HEADER_LINE; - for (uint8_t i=0; i 0) { drawRSSIGauge(); } -#endif } if (view_base < VIEW_INPUTS) { diff --git a/radio/src/gui/128x64/view_statistics.cpp b/radio/src/gui/128x64/view_statistics.cpp index 163a99743..4e132a1eb 100644 --- a/radio/src/gui/128x64/view_statistics.cpp +++ b/radio/src/gui/128x64/view_statistics.cpp @@ -184,18 +184,18 @@ void menuStatisticsDebug(event_t event) #if defined(COPROCESSOR) lcdDrawTextAlignedLeft(y, STR_COPROC_TEMP); - if (Coproc_read==0) { + if (coprocData.read==0) { lcdDrawText(MENU_DEBUG_COL1_OFS, y, "Co Proc NACK",INVERS); } - else if (Coproc_read==0x81) { + else if (coprocData.read==0x81) { lcdDrawText(MENU_DEBUG_COL1_OFS, y, "Inst.TinyApp",INVERS); } - else if (Coproc_read<3) { + else if (coprocData.read<3) { lcdDrawText(MENU_DEBUG_COL1_OFS, y, "Upgr.TinyApp",INVERS); } else { - drawValueWithUnit(MENU_DEBUG_COL1_OFS, y, Coproc_temp, UNIT_TEMPERATURE, LEFT); - drawValueWithUnit(MENU_DEBUG_COL2_OFS, y, Coproc_maxtemp, UNIT_TEMPERATURE, LEFT); + drawValueWithUnit(MENU_DEBUG_COL1_OFS, y, coprocData.temp, UNIT_TEMPERATURE, LEFT); + drawValueWithUnit(MENU_DEBUG_COL2_OFS, y, coprocData.maxtemp, UNIT_TEMPERATURE, LEFT); } y += FH; #endif diff --git a/radio/src/gui/212x64/lcd.h b/radio/src/gui/212x64/lcd.h index 382bc85ae..b55c6aa4d 100644 --- a/radio/src/gui/212x64/lcd.h +++ b/radio/src/gui/212x64/lcd.h @@ -170,7 +170,6 @@ void lcdDrawBitmap(coord_t x, coord_t y, const uint8_t * img, coord_t offset=0, void lcdClear(); uint8_t * lcdLoadBitmap(uint8_t * dest, const char * filename, uint16_t width, uint16_t height); -const char * writeScreenshot(); #if defined(BOOT) #define BLINK_ON_PHASE (0) diff --git a/radio/src/gui/212x64/menu_model.cpp b/radio/src/gui/212x64/menu_model.cpp index 94829aee5..11e58a68c 100644 --- a/radio/src/gui/212x64/menu_model.cpp +++ b/radio/src/gui/212x64/menu_model.cpp @@ -37,7 +37,7 @@ const MenuHandlerFunc menuTabModel[] = { #if defined(LUA_MODEL_SCRIPTS) menuModelCustomScripts, #endif - CASE_FRSKY(menuModelTelemetryFrsky) + menuModelTelemetry, menuModelDisplay }; diff --git a/radio/src/gui/212x64/menus.h b/radio/src/gui/212x64/menus.h index 2bbba412f..cbbd43fd1 100644 --- a/radio/src/gui/212x64/menus.h +++ b/radio/src/gui/212x64/menus.h @@ -94,7 +94,7 @@ enum MenuModelIndexes { #if defined(LUA_MODEL_SCRIPTS) MENU_MODEL_CUSTOM_SCRIPTS, #endif - MENU_MODEL_TELEMETRY_FRSKY, + MENU_MODEL_TELEMETRY, MENU_MODEL_DISPLAY, MENU_MODEL_PAGES_COUNT }; @@ -117,7 +117,7 @@ void menuModelGVars(event_t event); void menuModelLogicalSwitches(event_t event); void menuModelSpecialFunctions(event_t event); void menuModelCustomScripts(event_t event); -void menuModelTelemetryFrsky(event_t event); +void menuModelTelemetry(event_t event); void menuModelSensor(event_t event); void menuModelDisplay(event_t event); diff --git a/radio/src/gui/212x64/model_failsafe.cpp b/radio/src/gui/212x64/model_failsafe.cpp index 60c9c6177..3fdc2ee28 100644 --- a/radio/src/gui/212x64/model_failsafe.cpp +++ b/radio/src/gui/212x64/model_failsafe.cpp @@ -18,7 +18,7 @@ * GNU General Public License for more details. */ -#include +#include "opentx.h" extern uint8_t g_moduleIdx; diff --git a/radio/src/gui/212x64/model_setup.cpp b/radio/src/gui/212x64/model_setup.cpp index e7ac64a91..0372092fc 100644 --- a/radio/src/gui/212x64/model_setup.cpp +++ b/radio/src/gui/212x64/model_setup.cpp @@ -246,7 +246,7 @@ void editTimerCountdown(int timerIdx, coord_t y, LcdFlags attr, event_t event) #define TIMER_ROWS(x) 2|NAVIGATION_LINE_BY_LINE, 0, 0, 0, g_model.timers[x].countdownBeep != COUNTDOWN_SILENT ? (uint8_t) 1 : (uint8_t)0 -inline uint8_t EXTERNAL_MODULE_MODE_ROW() +inline uint8_t EXTERNAL_MODULE_TYPE_ROW() { if (isModuleXJT(EXTERNAL_MODULE) || isModuleR9MNonAccess(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE)) return 1; @@ -363,7 +363,7 @@ void menuModelSetup(event_t event) IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), // Receiver 3 LABEL(ExternalModule), - EXTERNAL_MODULE_MODE_ROW(), + EXTERNAL_MODULE_TYPE_ROW(), MULTIMODULE_STATUS_ROWS EXTERNAL_MODULE_CHANNELS_ROWS, IF_NOT_ACCESS_MODULE_RF(EXTERNAL_MODULE, EXTERNAL_MODULE_BIND_ROWS), @@ -763,10 +763,7 @@ void menuModelSetup(event_t event) if (menuHorizontalPosition == 0) { uint8_t moduleType = checkIncDec(event, g_model.moduleData[INTERNAL_MODULE].type, MODULE_TYPE_NONE, MODULE_TYPE_MAX, EE_MODEL, isInternalModuleAvailable); if (checkIncDec_Ret) { - // TODO this code should be common, in module.h (X10_new_UI branch) - memclear(&g_model.moduleData[INTERNAL_MODULE], sizeof(ModuleData)); - g_model.moduleData[INTERNAL_MODULE].type = moduleType; - g_model.moduleData[INTERNAL_MODULE].channelsCount = defaultModuleChannels_M8(INTERNAL_MODULE); + setModuleType(INTERNAL_MODULE, moduleType); } } else if (isModuleXJT(INTERNAL_MODULE)) { @@ -821,15 +818,15 @@ void menuModelSetup(event_t event) // Do not use MODEL_SETUP_3RD_COLUMN here since some the protocol string are so long that we cannot afford the 2 spaces (+6) here if (g_model.moduleData[EXTERNAL_MODULE].multi.customProto) { - lcdDrawText(lcdNextPos + FW, y, STR_MULTI_CUSTOM, menuHorizontalPosition == 1 ? attr : 0); - lcdDrawNumber(lcdNextPos + FW, y, g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false), menuHorizontalPosition == 2 ? attr : 0, 2); - lcdDrawNumber(lcdNextPos + FW, y, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition == 3 ? attr : 0, 2); + lcdDrawText(lcdNextPos + 3, y, STR_MULTI_CUSTOM, menuHorizontalPosition == 1 ? attr : 0); + lcdDrawNumber(lcdNextPos + 3, y, g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false), menuHorizontalPosition == 2 ? attr : 0, 2); + lcdDrawNumber(lcdNextPos + 3, y, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition == 3 ? attr : 0, 2); } else { - lcdDrawTextAtIndex(lcdNextPos + FW, y, STR_MULTI_PROTOCOLS, multi_rfProto, menuHorizontalPosition==1 ? attr : 0); + lcdDrawTextAtIndex(lcdNextPos + 3, y, STR_MULTI_PROTOCOLS, multi_rfProto, menuHorizontalPosition==1 ? attr : 0); const mm_protocol_definition * pdef = getMultiProtocolDefinition(multi_rfProto); if (pdef->subTypeString) { - lcdDrawTextAtIndex(lcdNextPos + FW, y, pdef->subTypeString, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); + lcdDrawTextAtIndex(lcdNextPos + 3, y, pdef->subTypeString, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); } } } @@ -838,19 +835,14 @@ void menuModelSetup(event_t event) if (s_editMode > 0) { switch (menuHorizontalPosition) { case 0: - g_model.moduleData[EXTERNAL_MODULE].type = checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].type, MODULE_TYPE_NONE, - IS_TRAINER_EXTERNAL_MODULE() ? MODULE_TYPE_NONE : MODULE_TYPE_COUNT - 1, EE_MODEL, - isExternalModuleAvailable); + { + uint8_t moduleType = checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].type, MODULE_TYPE_NONE, MODULE_TYPE_MAX, EE_MODEL, isExternalModuleAvailable); if (checkIncDec_Ret) { - g_model.moduleData[EXTERNAL_MODULE].rfProtocol = 0; - g_model.moduleData[EXTERNAL_MODULE].channelsStart = 0; - g_model.moduleData[EXTERNAL_MODULE].channelsCount = defaultModuleChannels_M8(EXTERNAL_MODULE); - if (isModuleSBUS(EXTERNAL_MODULE)) - g_model.moduleData[EXTERNAL_MODULE].sbus.refreshRate = -31; - if (isModulePPM(EXTERNAL_MODULE)) - SET_DEFAULT_PPM_FRAME_LENGTH(EXTERNAL_MODULE); + setModuleType(EXTERNAL_MODULE, moduleType); } break; + } + case 1: if (isModuleDSM2(EXTERNAL_MODULE)) CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, DSM2_PROTO_LP45, DSM2_PROTO_DSMX); @@ -1041,7 +1033,7 @@ void menuModelSetup(event_t event) case 1: CHECK_INCDEC_MODELVAR_CHECK(event, moduleData.channelsCount, -4, min(maxModuleChannels_M8(moduleIdx), 32-8-moduleData.channelsStart), moduleData.type == MODULE_TYPE_ISRM_PXX2 ? isPxx2IsrmChannelsCountAllowed : nullptr); if (checkIncDec_Ret && moduleData.type == MODULE_TYPE_PPM) { - SET_DEFAULT_PPM_FRAME_LENGTH(moduleIdx); + setDefaultPpmFrameLength(moduleIdx); } break; } @@ -1409,7 +1401,7 @@ void menuModelSetup(event_t event) } #if defined(PXX) - if (IS_RANGECHECK_ENABLE()) { + if (isModuleInRangeCheckMode()) { showMessageBox("RSSI: "); lcdDrawNumber(WARNING_LINE_X, 5*FH, TELEMETRY_RSSI(), BOLD | LEFT); } diff --git a/radio/src/gui/212x64/model_telemetry.cpp b/radio/src/gui/212x64/model_telemetry.cpp index fa1cb87b5..dd82a492d 100644 --- a/radio/src/gui/212x64/model_telemetry.cpp +++ b/radio/src/gui/212x64/model_telemetry.cpp @@ -23,6 +23,7 @@ enum MenuModelTelemetryFrskyItems { ITEM_TELEMETRY_PROTOCOL_TYPE, ITEM_TELEMETRY_RSSI_LABEL, + ITEM_TELEMETRY_RSSI_SOURCE, ITEM_TELEMETRY_RSSI_ALARM1, ITEM_TELEMETRY_RSSI_ALARM2, ITEM_TELEMETRY_DISABLE_ALARMS, @@ -45,6 +46,7 @@ enum MenuModelTelemetryFrskyItems { #define TELEM_COL2 (16*FW) #define TELEM_COL3 (30*FW+2) +#define RSSI_ROWS LABEL(RSSI), 0, 0, 0, 0, #define SENSOR_ROWS(x) (isTelemetryFieldAvailable(x) ? (uint8_t)0 : HIDDEN_ROW) #define SENSORS_ROWS LABEL(Sensors), SENSOR_ROWS(0), SENSOR_ROWS(1), SENSOR_ROWS(2), SENSOR_ROWS(3), SENSOR_ROWS(4), SENSOR_ROWS(5), SENSOR_ROWS(6), SENSOR_ROWS(7), SENSOR_ROWS(8), SENSOR_ROWS(9), SENSOR_ROWS(10), SENSOR_ROWS(11), SENSOR_ROWS(12), SENSOR_ROWS(13), SENSOR_ROWS(14), SENSOR_ROWS(15), SENSOR_ROWS(16), SENSOR_ROWS(17), SENSOR_ROWS(18), SENSOR_ROWS(19), SENSOR_ROWS(20), SENSOR_ROWS(21), SENSOR_ROWS(22), SENSOR_ROWS(23), SENSOR_ROWS(24), SENSOR_ROWS(25), SENSOR_ROWS(26), SENSOR_ROWS(27), SENSOR_ROWS(28), SENSOR_ROWS(29), SENSOR_ROWS(30), SENSOR_ROWS(31), SENSOR_ROWS(32), SENSOR_ROWS(33), SENSOR_ROWS(34), SENSOR_ROWS(35), SENSOR_ROWS(36), SENSOR_ROWS(37), SENSOR_ROWS(38), SENSOR_ROWS(39), SENSOR_ROWS(40), SENSOR_ROWS(41), SENSOR_ROWS(42), SENSOR_ROWS(43), SENSOR_ROWS(44), SENSOR_ROWS(45), SENSOR_ROWS(46), SENSOR_ROWS(47), SENSOR_ROWS(48), SENSOR_ROWS(49), SENSOR_ROWS(50), SENSOR_ROWS(51), SENSOR_ROWS(52), SENSOR_ROWS(53), SENSOR_ROWS(54), SENSOR_ROWS(55), SENSOR_ROWS(56), SENSOR_ROWS(57), SENSOR_ROWS(58), SENSOR_ROWS(59), 0, 0, 0, 0, #if defined(VARIO) @@ -52,12 +54,11 @@ enum MenuModelTelemetryFrskyItems { #else #define VARIO_ROWS #endif -#define RSSI_ROWS LABEL(RSSI), 0, 0, 0, #define TELEMETRY_TYPE_ROWS (!IS_INTERNAL_MODULE_ENABLED() && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM) ? (uint8_t)0 : HIDDEN_ROW, void onSensorMenu(const char * result) { - uint8_t index = menuVerticalPosition - ITEM_TELEMETRY_SENSOR_FIRST; + uint8_t index = menuVerticalPosition - HEADER_LINE - ITEM_TELEMETRY_SENSOR_FIRST; if (index < MAX_TELEMETRY_SENSORS) { if (result == STR_EDIT) { @@ -69,11 +70,10 @@ void onSensorMenu(const char * result) if (index= 0) { TelemetrySensor & sourceSensor = g_model.telemetrySensors[index]; TelemetrySensor & newSensor = g_model.telemetrySensors[newIndex]; @@ -90,27 +90,35 @@ void onSensorMenu(const char * result) } } -void menuModelTelemetryFrsky(event_t event) +void onDeleteAllSensorsConfirm(const char * result) { - if (warningResult) { - warningResult = 0; + if (result == STR_OK) { for (int i=0; i= (int)DIM(mstate_tab)) { + return; + } + } } LcdFlags blink = ((s_editMode>0) ? BLINK|INVERS : INVERS); - LcdFlags attr = (menuVerticalPosition == k ? blink : 0); + LcdFlags attr = (sub == k ? blink : 0); + if (k >= ITEM_TELEMETRY_SENSOR_FIRST && k <= ITEM_TELEMETRY_SENSOR_LAST) { int index = k - ITEM_TELEMETRY_SENSOR_FIRST; @@ -124,9 +132,11 @@ void menuModelTelemetryFrsky(event_t event) if (telemetryItem.isAvailable()) { bool isOld = telemetryItem.isOld(); lcdNextPos = TELEM_COL2; - if (isOld) lcdDrawChar(lcdNextPos, y, '['); + if (isOld) + lcdDrawChar(lcdNextPos, y, '['); drawSensorCustomValue(lcdNextPos, y, index, getValue(MIXSRC_FIRST_TELEM+3*index), LEFT); - if (isOld) lcdDrawChar(lcdLastRightPos, y, ']'); + if (isOld) + lcdDrawChar(lcdLastRightPos, y, ']'); } else { lcdDrawText(TELEM_COL2, y, "---", 0); // TODO shortcut @@ -164,7 +174,9 @@ void menuModelTelemetryFrsky(event_t event) case ITEM_TELEMETRY_PROTOCOL_TYPE: lcdDrawTextAlignedLeft(y, STR_TELEMETRY_TYPE); lcdDrawTextAtIndex(TELEM_COL2, y, STR_TELEMETRY_PROTOCOLS, g_model.telemetryProtocol, attr); - g_model.telemetryProtocol = checkIncDec(event, g_model.telemetryProtocol, PROTOCOL_TELEMETRY_FIRST, PROTOCOL_TELEMETRY_LAST, EE_MODEL, isTelemetryProtocolAvailable); + if (attr) { + g_model.telemetryProtocol = checkIncDec(event, g_model.telemetryProtocol, PROTOCOL_TELEMETRY_FIRST, PROTOCOL_TELEMETRY_LAST, EE_MODEL, isTelemetryProtocolAvailable); + } break; case ITEM_TELEMETRY_SENSORS_LABEL: @@ -176,7 +188,7 @@ void menuModelTelemetryFrsky(event_t event) break; case ITEM_TELEMETRY_DISCOVER_SENSORS: - lcdDrawText(0, y, allowNewSensors ? STR_STOP_DISCOVER_SENSORS : STR_DISCOVER_SENSORS, attr); + lcdDrawText(INDENT_WIDTH, y, allowNewSensors ? STR_STOP_DISCOVER_SENSORS : STR_DISCOVER_SENSORS, attr); if (attr && event==EVT_KEY_BREAK(KEY_ENTER)) { s_editMode = 0; allowNewSensors = !allowNewSensors; @@ -199,12 +211,13 @@ void menuModelTelemetryFrsky(event_t event) break; case ITEM_TELEMETRY_DELETE_ALL_SENSORS: - lcdDrawText(0, y, STR_DELETE_ALL_SENSORS, attr); - if (attr) + lcdDrawText(INDENT_WIDTH, y, STR_DELETE_ALL_SENSORS, attr); + if (attr) { s_editMode = 0; - if (attr && event==EVT_KEY_LONG(KEY_ENTER)) { - killEvents(KEY_ENTER); - POPUP_CONFIRMATION(STR_CONFIRMDELETE, nullptr); + if (event == EVT_KEY_BREAK(KEY_ENTER)) { + killEvents(KEY_ENTER); + POPUP_CONFIRMATION(STR_CONFIRMDELETE, onDeleteAllSensorsConfirm); + } } break; @@ -214,17 +227,32 @@ void menuModelTelemetryFrsky(event_t event) case ITEM_TELEMETRY_RSSI_LABEL: #if defined(MULTIMODULE) - if (g_model.moduleData[INTERNAL_MODULE].type != MODULE_TYPE_XJT_PXX1 && - g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_MULTIMODULE && - g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false) == MODULE_SUBTYPE_MULTI_FS_AFHDS2A) + if (telemetryProtocol == PROTOCOL_TELEMETRY_MULTIMODULE && g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false) == MODULE_SUBTYPE_MULTI_FS_AFHDS2A) lcdDrawTextAlignedLeft(y, "RSNR"); else -#endif + lcdDrawTextAlignedLeft(y, "RSSI"); +#else lcdDrawTextAlignedLeft(y, "RSSI"); +#endif break; + case ITEM_TELEMETRY_RSSI_SOURCE: { + lcdDrawTextAlignedLeft(y, INDENT TR_SOURCE); + drawSource(TELEM_COL2, y, g_model.rssiSource ? MIXSRC_FIRST_TELEM + 3 * (g_model.rssiSource - 1) : 0, attr); + if (g_model.rssiSource) { + TelemetrySensor * sensor = &g_model.telemetrySensors[g_model.rssiSource - 1]; + lcdDrawText(lcdNextPos, y, " ", attr); + drawReceiverName(lcdNextPos, y, sensor->frskyInstance.rxIndex >> 2, sensor->frskyInstance.rxIndex & 0x03, attr); + } + if (attr) { + g_model.rssiSource = checkIncDec(event, g_model.rssiSource, 0, MAX_TELEMETRY_SENSORS, EE_MODEL | NO_INCDEC_MARKS, isRssiSensorAvailable); + } + break; + } + case ITEM_TELEMETRY_RSSI_ALARM1: - case ITEM_TELEMETRY_RSSI_ALARM2: { + case ITEM_TELEMETRY_RSSI_ALARM2: + { bool warning = (k==ITEM_TELEMETRY_RSSI_ALARM1); lcdDrawTextAlignedLeft(y, (warning ? STR_LOWALARM : STR_CRITICALALARM)); lcdDrawNumber(TELEM_COL2, y, warning? g_model.rssiAlarms.getWarningRssi() : g_model.rssiAlarms.getCriticalRssi(), LEFT|attr, 3); @@ -236,6 +264,7 @@ void menuModelTelemetryFrsky(event_t event) } break; } + case ITEM_TELEMETRY_DISABLE_ALARMS: g_model.rssiAlarms.disabled = editCheckBox(g_model.rssiAlarms.disabled, TELEM_COL3, y, STR_DISABLE_ALARM, attr, event); break; diff --git a/radio/src/gui/212x64/radio_setup.cpp b/radio/src/gui/212x64/radio_setup.cpp index 27fe53f2b..1deb944e1 100644 --- a/radio/src/gui/212x64/radio_setup.cpp +++ b/radio/src/gui/212x64/radio_setup.cpp @@ -159,13 +159,13 @@ void menuRadioSetup(event_t event) CASE_SPLASH_PARAM(0) // disable splash CASE_PWR_BUTTON_PRESS(0) // pwr on speed CASE_PWR_BUTTON_PRESS(0) // pwr off speed - CASE_PXX2(0) + CASE_PXX2(0) // owner registration ID CASE_GPS(LABEL(GPS)) CASE_GPS(0) // timezone CASE_GPS(0) // adjust RTC CASE_GPS(0) // GPS format - CASE_PXX1(0) // country code - 0, // language + CASE_PXX1(0) // country code + 0, // voice language 0, // imperial IF_FAI_CHOICE(0) 0, // switches delay @@ -484,7 +484,7 @@ void menuRadioSetup(event_t event) break; #endif -#if defined(TELEMETRY_FRSKY) && defined(GPS) +#if defined(GPS) case ITEM_RADIO_SETUP_LABEL_GPS: lcdDrawTextAlignedLeft(y, STR_GPS); break; diff --git a/radio/src/gui/480x272/menu_model.cpp b/radio/src/gui/480x272/menu_model.cpp index e03cf34a3..93a7710e5 100644 --- a/radio/src/gui/480x272/menu_model.cpp +++ b/radio/src/gui/480x272/menu_model.cpp @@ -36,7 +36,7 @@ const MenuHandlerFunc menuTabModel[] = { #if defined(LUA_MODEL_SCRIPTS) menuModelCustomScripts, #endif - CASE_FRSKY(menuModelTelemetryFrsky) + menuModelTelemetry }; void editCurveRef(coord_t x, coord_t y, CurveRef & curve, event_t event, LcdFlags attr); diff --git a/radio/src/gui/480x272/menus.h b/radio/src/gui/480x272/menus.h index 708417b76..6b3242c7a 100644 --- a/radio/src/gui/480x272/menus.h +++ b/radio/src/gui/480x272/menus.h @@ -22,6 +22,7 @@ #define _MENUS_H_ #include "keys.h" +#include "audio.h" #define MENU_COLUMN2_X 280 #define MIXES_2ND_COLUMN 140 @@ -106,6 +107,7 @@ enum MenuIcons { ICON_MONITOR_CHANNELS3, ICON_MONITOR_CHANNELS4, ICON_MONITOR_LOGICAL_SWITCHES, + ICON_RADIO_SPECTRUM_ANALYSER, MENUS_ICONS_COUNT }; @@ -123,7 +125,7 @@ enum EnumTabModel { #if defined(LUA_MODEL_SCRIPTS) MENU_MODEL_CUSTOM_SCRIPTS, #endif - CASE_FRSKY(MENU_MODEL_TELEMETRY_FRSKY) + MENU_MODEL_TELEMETRY, MENU_MODEL_PAGES_COUNT }; @@ -177,7 +179,7 @@ bool menuModelGVars(event_t event); bool menuModelLogicalSwitches(event_t event); bool menuModelSpecialFunctions(event_t event); bool menuModelCustomScripts(event_t event); -bool menuModelTelemetryFrsky(event_t event); +bool menuModelTelemetry(event_t event); bool menuModelSensor(event_t event); bool menuModelExpoOne(event_t event); bool menuModelModuleOptions(event_t event); @@ -330,7 +332,7 @@ extern const CheckIncDecStops &stopsSwitch; (val), (val+1) int checkIncDec(event_t event, int val, int i_min, int i_max, unsigned int i_flags=0, IsValueAvailable isValueAvailable=NULL, const CheckIncDecStops &stops=stops100); -swsrc_t checkIncDecMovedSwitch(swsrc_t val); + #define checkIncDecModel(event, i_val, i_min, i_max) checkIncDec(event, i_val, i_min, i_max, EE_MODEL) #define checkIncDecModelZero(event, i_val, i_max) checkIncDec(event, i_val, 0, i_max, EE_MODEL) #define checkIncDecGen(event, i_val, i_min, i_max) checkIncDec(event, i_val, i_min, i_max, EE_GENERAL) @@ -438,11 +440,15 @@ void editCurveRef(coord_t x, coord_t y, CurveRef & curve, event_t event, LcdFlag extern uint8_t s_curveChan; -#define WARNING_TYPE_ALERT 0 -#define WARNING_TYPE_ASTERISK 1 -#define WARNING_TYPE_CONFIRM 2 -#define WARNING_TYPE_INPUT 3 -#define WARNING_TYPE_INFO 4 +enum +{ + WARNING_TYPE_WAIT, + WARNING_TYPE_INFO, + WARNING_TYPE_ASTERISK, + WARNING_TYPE_CONFIRM, + WARNING_TYPE_INPUT, + WARNING_TYPE_ALERT +}; extern const char * warningText; extern const char * warningInfoText; @@ -480,23 +486,20 @@ void insertMix(uint8_t idx); #define WARNING_INFOLINE_Y (WARNING_LINE_Y+68) void copySelection(char * dst, const char * src, uint8_t size); - void drawPopupBackgroundAndBorder(coord_t x, coord_t y, coord_t w, coord_t h); void showMessageBox(const char * title); void runPopupWarning(event_t event); -extern void (* popupFunc)(event_t event); +typedef void (* PopupFunc)(event_t event); +extern PopupFunc popupFunc; + extern uint8_t warningInfoFlags; -#define DISPLAY_WARNING(evt) (*popupFunc)(evt) -#define POPUP_INFORMATION(s) (warningText = s, warningType = WARNING_TYPE_INFO, warningInfoText = 0, popupFunc = runPopupWarning) -#define POPUP_WARNING(s) (warningType = WARNING_TYPE_ASTERISK, warningText = s, warningInfoText = 0, popupFunc = runPopupWarning) -#define POPUP_INPUT(s, func) (warningText = s, popupFunc = func) -#define SET_WARNING_INFO(info, len, flags) (warningInfoText = info, warningInfoLength = len, warningInfoFlags = flags) +inline void DISPLAY_WARNING(event_t event) +{ + (*popupFunc)(event); +} -#define POPUP_MENU_ADD_ITEM(s) do { popupMenuOffsetType = MENU_OFFSET_INTERNAL; if (popupMenuItemsCount < POPUP_MENU_MAX_LINES) popupMenuItems[popupMenuItemsCount++] = s; } while (0) -#define POPUP_MENU_SELECT_ITEM(s) popupMenuSelectedItem = (s > 0 ? (s < popupMenuItemsCount ? s : popupMenuItemsCount - 1) : 0) -#define POPUP_MENU_START(func) do { popupMenuHandler = (func); AUDIO_KEY_PRESS(); } while(0) #define POPUP_MENU_MAX_LINES 12 #define MENU_MAX_DISPLAY_LINES 9 #define MENU_LINE_LENGTH (LEN_MODEL_NAME+12) @@ -511,7 +514,71 @@ enum { extern uint8_t popupMenuOffsetType; extern uint8_t popupMenuSelectedItem; const char * runPopupMenu(event_t event); -extern void (*popupMenuHandler)(const char * result); + +typedef void (* PopupMenuHandler)(const char * result); +extern PopupMenuHandler popupMenuHandler; + +inline void POPUP_INPUT(const char * s, PopupFunc func) +{ + warningText = s; + warningInfoText = nullptr; + warningType = WARNING_TYPE_INPUT; + popupFunc = func; +} + +inline void SET_WARNING_INFO(const char * info, uint8_t length, uint8_t flags) +{ + warningInfoText = info; + warningInfoLength = length; + warningInfoFlags = flags; +} + +inline void POPUP_MENU_ADD_ITEM(const char * s) +{ + popupMenuOffsetType = MENU_OFFSET_INTERNAL; + if (popupMenuItemsCount < POPUP_MENU_MAX_LINES) + popupMenuItems[popupMenuItemsCount++] = s; +} + +inline void POPUP_MENU_SELECT_ITEM(uint8_t index) +{ + popupMenuSelectedItem = (index > 0 ? (index < popupMenuItemsCount ? index : popupMenuItemsCount - 1) : 0); +} + +inline void POPUP_MENU_START(PopupMenuHandler handler) +{ + popupMenuHandler = handler; + AUDIO_KEY_PRESS(); +} + +inline void CLEAR_POPUP() +{ + warningText = nullptr; +} + +inline void POPUP_WAIT(const char * s) +{ + warningText = s; + warningInfoText = nullptr; + warningType = WARNING_TYPE_WAIT; + popupFunc = runPopupWarning; +} + +inline void POPUP_INFORMATION(const char * s) +{ + warningText = s; + warningInfoText = nullptr; + warningType = WARNING_TYPE_INFO; + popupFunc = runPopupWarning; +} + +inline void POPUP_WARNING(const char * s) +{ + warningText = s; + warningInfoText = nullptr; + warningType = WARNING_TYPE_ASTERISK; + popupFunc = runPopupWarning; +} inline void POPUP_CONFIRMATION(const char *s, void (* confirmHandler)(const char *) = nullptr) { diff --git a/radio/src/gui/480x272/model_failsafe.cpp b/radio/src/gui/480x272/model_failsafe.cpp index 16494ccfc..269cfad75 100644 --- a/radio/src/gui/480x272/model_failsafe.cpp +++ b/radio/src/gui/480x272/model_failsafe.cpp @@ -18,7 +18,7 @@ * GNU General Public License for more details. */ -#include +#include "opentx.h" extern uint8_t g_moduleIdx; diff --git a/radio/src/gui/480x272/model_inputs.cpp b/radio/src/gui/480x272/model_inputs.cpp index 7f7346b03..00ea22caa 100644 --- a/radio/src/gui/480x272/model_inputs.cpp +++ b/radio/src/gui/480x272/model_inputs.cpp @@ -178,7 +178,6 @@ bool menuModelExpoOne(event_t event) SUBMENU_WITH_OPTIONS(STR_MENUINPUTS, ICON_MODEL_INPUTS, EXPO_FIELD_MAX, OPTION_MENU_NO_FOOTER|OPTION_MENU_NO_SCROLLBAR, { 0, 0, 0, (ed->srcRaw >= MIXSRC_FIRST_TELEM ? (uint8_t)0 : (uint8_t)HIDDEN_ROW), 0, 0, CURVE_ROWS, CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0 /*, ...*/}); lcdDrawSizedText(50, 3+FH, g_model.inputNames[ed->chn], LEN_INPUT_NAME, ZCHAR|MENU_TITLE_COLOR); - lcdDrawSolidFilledRect(0, MENU_FOOTER_TOP, 230, MENU_FOOTER_HEIGHT, HEADER_BGCOLOR); int sub = menuVerticalPosition; @@ -241,7 +240,8 @@ bool menuModelExpoOne(event_t event) case EXPO_FIELD_SOURCE: lcdDrawText(MENUS_MARGIN_LEFT, y, STR_SOURCE); drawSource(EXPO_ONE_2ND_COLUMN, y, ed->srcRaw, menuHorizontalPosition==0 ? attr : 0); - if (attr && menuHorizontalPosition==0) ed->srcRaw = checkIncDec(event, ed->srcRaw, INPUTSRC_FIRST, INPUTSRC_LAST, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isInputSourceAvailable); + if (attr && menuHorizontalPosition==0) + ed->srcRaw = checkIncDec(event, ed->srcRaw, INPUTSRC_FIRST, INPUTSRC_LAST, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isInputSourceAvailable); if (ed->srcRaw >= MIXSRC_FIRST_TELEM) { drawSensorCustomValue(EXPO_ONE_2ND_COLUMN+75, y, (ed->srcRaw - MIXSRC_FIRST_TELEM)/3, convertTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1, ed->scale), LEFT|(menuHorizontalPosition==1?attr:0)); if (attr && menuHorizontalPosition == 1) ed->scale = checkIncDec(event, ed->scale, 0, maxTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1), EE_MODEL); diff --git a/radio/src/gui/480x272/model_module_options.cpp b/radio/src/gui/480x272/model_module_options.cpp index 4d21f6b3b..4f088fd6a 100644 --- a/radio/src/gui/480x272/model_module_options.cpp +++ b/radio/src/gui/480x272/model_module_options.cpp @@ -18,7 +18,7 @@ * GNU General Public License for more details. */ -#include +#include "opentx.h" #include #define RECEIVER_OPTIONS_2ND_COLUMN 200 diff --git a/radio/src/gui/480x272/model_setup.cpp b/radio/src/gui/480x272/model_setup.cpp index 6a99fd560..ac6f03bd0 100644 --- a/radio/src/gui/480x272/model_setup.cpp +++ b/radio/src/gui/480x272/model_setup.cpp @@ -122,47 +122,22 @@ enum MenuModelSetupItems { #define MODEL_SETUP_SLIDPOT_SPACING 45 #define CURRENT_MODULE_EDITED(k) (k >= ITEM_MODEL_SETUP_EXTERNAL_MODULE_LABEL ? EXTERNAL_MODULE : INTERNAL_MODULE) -#define CURRENT_RECEIVER_EDITED(k) (k - (k >= ITEM_MODEL_SETUP_EXTERNAL_MODULE_LABEL ? k : ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_RECEIVER_1)) +#define CURRENT_RECEIVER_EDITED(k) (k - (k >= ITEM_MODEL_SETUP_EXTERNAL_MODULE_LABEL ? ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_RECEIVER_1 : ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_RECEIVER_1)) #include "common/stdlcd/model_setup_pxx1.cpp" -bool isPXX2ReceiverEmpty(uint8_t moduleIdx, uint8_t receiverIdx) -{ - return is_memclear(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], PXX2_LEN_RX_NAME); -} - -void removePXX2Receiver(uint8_t moduleIdx, uint8_t receiverIdx) -{ - memclear(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], PXX2_LEN_RX_NAME); - g_model.moduleData[moduleIdx].pxx2.receivers &= ~(1 << receiverIdx); - storageDirty(EE_MODEL); -} - -void removePXX2ReceiverIfEmpty(uint8_t moduleIdx, uint8_t receiverIdx) -{ - if (isPXX2ReceiverEmpty(moduleIdx, receiverIdx)) { - removePXX2Receiver(moduleIdx, receiverIdx); - } -} - -const char * STR_BIND_8CH_WITH_TELEM = TR("8CH with telem.", "8CH with telemetry"); -const char * STR_BIND_16CH_WITH_TELEM = TR("16CH with telem.", "16CH with telemetry"); -const char * STR_BIND_16CH_WITHOUT_TELEM = TR("16CH without telem.", "16CH without telemetry"); -const char * STR_BIND_FLEX_868 = "Flex 868MHz"; -const char * STR_BIND_FLEX_915 = "Flex 915MHz"; - void onPXX2R9MBindModeMenu(const char * result) { - if (result == STR_BIND_16CH_WITH_TELEM) { + if (result == STR_16CH_WITH_TELEMETRY) { reusableBuffer.moduleSetup.bindInformation.lbtMode = 1; } - else if (result == STR_BIND_16CH_WITHOUT_TELEM) { + else if (result == STR_16CH_WITHOUT_TELEMETRY) { reusableBuffer.moduleSetup.bindInformation.lbtMode = 2; } - else if (result == STR_BIND_FLEX_868) { + else if (result == STR_FLEX_915) { reusableBuffer.moduleSetup.bindInformation.flexMode = 0; } - else if (result == STR_BIND_FLEX_915) { + else if (result == STR_FLEX_868) { reusableBuffer.moduleSetup.bindInformation.flexMode = 1; } else { @@ -170,6 +145,7 @@ void onPXX2R9MBindModeMenu(const char * result) uint8_t moduleIdx = CURRENT_MODULE_EDITED(menuVerticalPosition); uint8_t receiverIdx = CURRENT_RECEIVER_EDITED(menuVerticalPosition); moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; + reusableBuffer.moduleSetup.bindInformation.step = 0; removePXX2ReceiverIfEmpty(moduleIdx, receiverIdx); return; } @@ -498,7 +474,7 @@ int getSwitchWarningsCount() #define TIMER_ROWS(x) NAVIGATION_LINE_BY_LINE|1, 0, 0, 0, g_model.timers[x].countdownBeep != COUNTDOWN_SILENT ? (uint8_t)1 : (uint8_t)0 -inline uint8_t EXTERNAL_MODULE_MODE_ROW() +inline uint8_t EXTERNAL_MODULE_TYPE_ROW() { if (isModuleXJT(EXTERNAL_MODULE) || isModuleR9MNonAccess(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE)) return 1; @@ -533,24 +509,6 @@ inline uint8_t EXTERNAL_MODULE_MODE_ROW() #define REGISTRATION_ID_ROWS #endif -void drawReceiverName(coord_t x, coord_t y, uint8_t moduleIdx, uint8_t receiverIdx, LcdFlags flags) -{ - if (isModulePXX2(moduleIdx)) { - if (g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx][0] != '\0') - lcdDrawSizedText(x, y, g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], effectiveLen(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], PXX2_LEN_RX_NAME), flags); - else - lcdDrawText(x, y, "---", flags); - } -#if defined(HARDWARE_INTERNAL_MODULE) - else if (moduleIdx == INTERNAL_MODULE) { - lcdDrawText(x, y, "Internal", flags); - } -#endif - else { - lcdDrawText(x, y, "External", flags); - } -} - #if defined(EXTERNAL_ANTENNA) #define ANTENNA_ROW IF_NOT_PXX2_MODULE(INTERNAL_MODULE, IF_INTERNAL_MODULE_ON(0)), // Antenna void onAntennaSwitchConfirm(const char * result) @@ -610,7 +568,7 @@ bool menuModelSetup(event_t event) IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), /* Receiver 3 */ LABEL(ExternalModule), - EXTERNAL_MODULE_MODE_ROW(), + EXTERNAL_MODULE_TYPE_ROW(), MULTIMODULE_STATUS_ROWS EXTERNAL_MODULE_CHANNELS_ROWS, IF_NOT_ACCESS_MODULE_RF(EXTERNAL_MODULE, EXTERNAL_MODULE_BIND_ROWS), @@ -790,7 +748,8 @@ bool menuModelSetup(event_t event) case ITEM_MODEL_SETUP_THROTTLE_TRACE: { lcdDrawText(MENUS_MARGIN_LEFT, y, STR_TTRACE); - if (attr) CHECK_INCDEC_MODELVAR_ZERO(event, g_model.thrTraceSrc, NUM_POTS+NUM_SLIDERS+MAX_OUTPUT_CHANNELS); + // check if source is available (EXT1 & EXT2 on X10) + if (attr) CHECK_INCDEC_MODELVAR_ZERO_CHECK(event, g_model.thrTraceSrc, NUM_POTS+NUM_SLIDERS+MAX_OUTPUT_CHANNELS, isThrottleSourceAvailable); uint8_t idx = g_model.thrTraceSrc + MIXSRC_Thr; if (idx > MIXSRC_Thr) idx += 1; @@ -992,10 +951,7 @@ bool menuModelSetup(event_t event) if (menuHorizontalPosition == 0) { uint8_t moduleType = checkIncDec(event, g_model.moduleData[INTERNAL_MODULE].type, MODULE_TYPE_NONE, MODULE_TYPE_MAX, EE_MODEL, isInternalModuleAvailable); if (checkIncDec_Ret) { - // TODO this code should be common, in module.h (X10_new_UI branch) - memclear(&g_model.moduleData[INTERNAL_MODULE], sizeof(ModuleData)); - g_model.moduleData[INTERNAL_MODULE].type = moduleType; - g_model.moduleData[INTERNAL_MODULE].channelsCount = defaultModuleChannels_M8(INTERNAL_MODULE); + setModuleType(INTERNAL_MODULE, moduleType); } } else if (isModuleXJT(INTERNAL_MODULE)) { @@ -1062,19 +1018,14 @@ bool menuModelSetup(event_t event) if (s_editMode > 0) { switch (menuHorizontalPosition) { case 0: - g_model.moduleData[EXTERNAL_MODULE].type = checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].type, - MODULE_TYPE_NONE, MODULE_TYPE_COUNT - 1, EE_MODEL, - isExternalModuleAvailable); + { + uint8_t moduleType = checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].type, MODULE_TYPE_NONE, MODULE_TYPE_MAX, EE_MODEL, isExternalModuleAvailable); if (checkIncDec_Ret) { - g_model.moduleData[EXTERNAL_MODULE].rfProtocol = 0; - g_model.moduleData[EXTERNAL_MODULE].channelsStart = 0; - g_model.moduleData[EXTERNAL_MODULE].channelsCount = defaultModuleChannels_M8(EXTERNAL_MODULE); - if (isModuleSBUS(EXTERNAL_MODULE)) - g_model.moduleData[EXTERNAL_MODULE].sbus.refreshRate = -31; - if (isModulePPM(EXTERNAL_MODULE)) - SET_DEFAULT_PPM_FRAME_LENGTH(EXTERNAL_MODULE); + setModuleType(EXTERNAL_MODULE, moduleType); } break; + } + case 1: if (isModuleDSM2(EXTERNAL_MODULE)) CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, DSM2_PROTO_LP45, DSM2_PROTO_DSMX); @@ -1110,6 +1061,7 @@ bool menuModelSetup(event_t event) g_model.moduleData[EXTERNAL_MODULE].channelsCount = defaultModuleChannels_M8(EXTERNAL_MODULE); } break; + #if defined(MULTIMODULE) case 2: if (g_model.moduleData[EXTERNAL_MODULE].multi.customProto) { @@ -1172,7 +1124,7 @@ bool menuModelSetup(event_t event) case 1: CHECK_INCDEC_MODELVAR_CHECK(event, moduleData.channelsCount, -4, min(maxModuleChannels_M8(moduleIdx), 32-8-moduleData.channelsStart), moduleData.type == MODULE_TYPE_ISRM_PXX2 ? isPxx2IsrmChannelsCountAllowed : nullptr); if (checkIncDec_Ret && moduleData.type == MODULE_TYPE_PPM) { - SET_DEFAULT_PPM_FRAME_LENGTH(moduleIdx); + setDefaultPpmFrameLength(moduleIdx); } break; } @@ -1282,6 +1234,7 @@ bool menuModelSetup(event_t event) #endif case ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_MODEL_NUM: + case ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_MODEL_NUM: { uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); lcdDrawText(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, STR_RECEIVER_NUM); @@ -1301,6 +1254,7 @@ bool menuModelSetup(event_t event) break; case ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_REGISTER_RANGE: + case ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_REGISTER_RANGE: { uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); lcdDrawText(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, STR_MODULE); @@ -1339,6 +1293,9 @@ bool menuModelSetup(event_t event) case ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_RECEIVER_1: case ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_RECEIVER_2: case ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_RECEIVER_3: + case ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_RECEIVER_1: + case ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_RECEIVER_2: + case ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_RECEIVER_3: { uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); uint8_t receiverIdx = CURRENT_RECEIVER_EDITED(k); @@ -1346,60 +1303,72 @@ bool menuModelSetup(event_t event) drawStringWithIndex(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, STR_RECEIVER, receiverIdx + 1); - if (!(g_model.moduleData[moduleIdx].pxx2.receivers & (1 << receiverIdx))) { + if (!isPXX2ReceiverUsed(moduleIdx, receiverIdx)) { drawButton(MODEL_SETUP_2ND_COLUMN, y, STR_MODULE_BIND, attr); - if (attr && s_editMode > 0) { - s_editMode = 0; - killEvents(event); - g_model.moduleData[moduleIdx].pxx2.receivers |= (1 << receiverIdx); + if (attr && event == EVT_KEY_BREAK(KEY_ENTER)) { + setPXX2ReceiverUsed(moduleIdx, receiverIdx); memclear(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], PXX2_LEN_RX_NAME); - storageDirty(EE_MODEL); - } - else { - break; + onPXX2ReceiverMenu(STR_BIND); } + break; } drawReceiverName(MODEL_SETUP_2ND_COLUMN, y, moduleIdx, receiverIdx, attr); - if (s_editMode && isModuleR9MAccess(moduleIdx) && moduleState[moduleIdx].mode == MODULE_MODE_NORMAL && moduleInformation.information.modelID) { - moduleInformation.information.modelID = 0; - moduleState[moduleIdx].startBind(&reusableBuffer.moduleSetup.bindInformation); + if (s_editMode && isModuleR9MAccess(moduleIdx) && moduleState[moduleIdx].mode == MODULE_MODE_NORMAL && reusableBuffer.moduleSetup.bindInformation.step < 0) { + if (reusableBuffer.moduleSetup.bindInformation.step == BIND_MODULE_TX_INFORMATION_REQUEST && moduleInformation.information.modelID) { + // For R9M ACCESS the module information has been requested to know if we are in EU mode. We just receive it here and continue + if (moduleInformation.information.variant == PXX2_VARIANT_EU) { + // In EU mode we will need the power of the module to know if telemetry can be proposed + reusableBuffer.moduleSetup.bindInformation.step = BIND_MODULE_TX_SETTINGS_REQUEST; +#if defined(SIMU) + reusableBuffer.moduleSetup.pxx2.moduleSettings.txPower = 14; + break; +#else + moduleState[moduleIdx].readModuleSettings(&reusableBuffer.moduleSetup.pxx2.moduleSettings); +#endif + } + else { + reusableBuffer.moduleSetup.bindInformation.step = 0; + moduleState[moduleIdx].startBind(&reusableBuffer.moduleSetup.bindInformation); + } + } + else if (reusableBuffer.moduleSetup.bindInformation.step == BIND_MODULE_TX_SETTINGS_REQUEST && reusableBuffer.moduleSetup.pxx2.moduleSettings.txPower > 0) { + // We just receive the module settings (for TX power) + reusableBuffer.moduleSetup.bindInformation.step = 0; + moduleState[moduleIdx].startBind(&reusableBuffer.moduleSetup.bindInformation); + } } - - if (attr && (moduleState[moduleIdx].mode == 0 || s_editMode == 0)) { + else if (attr && (moduleState[moduleIdx].mode == MODULE_MODE_NORMAL || s_editMode == 0)) { if (moduleState[moduleIdx].mode) { moduleState[moduleIdx].mode = 0; removePXX2ReceiverIfEmpty(moduleIdx, receiverIdx); killEvents(event); // we stopped BIND / SHARE, we don't want to re-open the menu event = 0; + CLEAR_POPUP(); } s_editMode = 0; } if (moduleState[moduleIdx].mode == MODULE_MODE_BIND) { - if (reusableBuffer.moduleSetup.bindInformation.step == BIND_INIT && reusableBuffer.moduleSetup.bindInformation.candidateReceiversCount > 0) { - popupMenuItemsCount = min(reusableBuffer.moduleSetup.bindInformation.candidateReceiversCount, PXX2_MAX_RECEIVERS_PER_MODULE); - for (uint8_t i=0; i 0) { + popupMenuItemsCount = min(reusableBuffer.moduleSetup.bindInformation.candidateReceiversCount, PXX2_MAX_RECEIVERS_PER_MODULE); + for (auto rx = 0; rx < popupMenuItemsCount; rx++) { + popupMenuItems[rx] = reusableBuffer.moduleSetup.bindInformation.candidateReceiversNames[rx]; + } + // popupMenuTitle = STR_PXX2_SELECT_RX; + POPUP_MENU_START(onPXX2BindMenu); } - //popupMenuTitle = STR_PXX2_SELECT_RX; // TODO : fix - POPUP_MENU_START(onPXX2BindMenu); } } - if (attr && EVT_KEY_MASK(event) == KEY_ENTER) { - killEvents(event); - if (isPXX2ReceiverEmpty(moduleIdx, receiverIdx)) { - onPXX2ReceiverMenu(STR_BIND); - } - else { - POPUP_MENU_ADD_ITEM(STR_BIND); - POPUP_MENU_ADD_ITEM(STR_OPTIONS); - POPUP_MENU_ADD_ITEM(STR_SHARE); - POPUP_MENU_ADD_ITEM(STR_DELETE); - POPUP_MENU_ADD_ITEM(STR_RESET); - } + if (attr && event == EVT_KEY_BREAK(KEY_ENTER)) { + POPUP_MENU_ADD_ITEM(STR_BIND); + POPUP_MENU_ADD_ITEM(STR_OPTIONS); + POPUP_MENU_ADD_ITEM(STR_SHARE); + POPUP_MENU_ADD_ITEM(STR_DELETE); + POPUP_MENU_ADD_ITEM(STR_RESET); POPUP_MENU_START(onPXX2ReceiverMenu); } } @@ -1664,7 +1633,7 @@ bool menuModelSetup(event_t event) } } - if (IS_RANGECHECK_ENABLE()) { + if (isModuleInRangeCheckMode()) { theme->drawMessageBox("RSSI :", NULL, NULL, WARNING_TYPE_INFO); lcdDrawNumber(WARNING_LINE_X, WARNING_INFOLINE_Y, TELEMETRY_RSSI(), DBLSIZE|LEFT); } @@ -1698,4 +1667,4 @@ bool menuModelSetup(event_t event) } return true; -} \ No newline at end of file +} diff --git a/radio/src/gui/480x272/model_telemetry.cpp b/radio/src/gui/480x272/model_telemetry.cpp index f89edcc2b..5cd57b1dc 100644 --- a/radio/src/gui/480x272/model_telemetry.cpp +++ b/radio/src/gui/480x272/model_telemetry.cpp @@ -23,70 +23,13 @@ enum MenuModelTelemetryFrskyItems { ITEM_TELEMETRY_PROTOCOL_TYPE, ITEM_TELEMETRY_RSSI_LABEL, + ITEM_TELEMETRY_RSSI_SOURCE, ITEM_TELEMETRY_RSSI_ALARM1, ITEM_TELEMETRY_RSSI_ALARM2, ITEM_TELEMETRY_DISABLE_ALARMS, ITEM_TELEMETRY_SENSORS_LABEL, - ITEM_TELEMETRY_SENSOR1, - ITEM_TELEMETRY_SENSOR2, - ITEM_TELEMETRY_SENSOR3, - ITEM_TELEMETRY_SENSOR4, - ITEM_TELEMETRY_SENSOR5, - ITEM_TELEMETRY_SENSOR6, - ITEM_TELEMETRY_SENSOR7, - ITEM_TELEMETRY_SENSOR8, - ITEM_TELEMETRY_SENSOR9, - ITEM_TELEMETRY_SENSOR10, - ITEM_TELEMETRY_SENSOR11, - ITEM_TELEMETRY_SENSOR12, - ITEM_TELEMETRY_SENSOR13, - ITEM_TELEMETRY_SENSOR14, - ITEM_TELEMETRY_SENSOR15, - ITEM_TELEMETRY_SENSOR16, - ITEM_TELEMETRY_SENSOR17, - ITEM_TELEMETRY_SENSOR18, - ITEM_TELEMETRY_SENSOR19, - ITEM_TELEMETRY_SENSOR20, - ITEM_TELEMETRY_SENSOR21, - ITEM_TELEMETRY_SENSOR22, - ITEM_TELEMETRY_SENSOR23, - ITEM_TELEMETRY_SENSOR24, - ITEM_TELEMETRY_SENSOR25, - ITEM_TELEMETRY_SENSOR26, - ITEM_TELEMETRY_SENSOR27, - ITEM_TELEMETRY_SENSOR28, - ITEM_TELEMETRY_SENSOR29, - ITEM_TELEMETRY_SENSOR30, - ITEM_TELEMETRY_SENSOR31, - ITEM_TELEMETRY_SENSOR32, - ITEM_TELEMETRY_SENSOR33, - ITEM_TELEMETRY_SENSOR34, - ITEM_TELEMETRY_SENSOR35, - ITEM_TELEMETRY_SENSOR36, - ITEM_TELEMETRY_SENSOR37, - ITEM_TELEMETRY_SENSOR38, - ITEM_TELEMETRY_SENSOR39, - ITEM_TELEMETRY_SENSOR40, - ITEM_TELEMETRY_SENSOR41, - ITEM_TELEMETRY_SENSOR42, - ITEM_TELEMETRY_SENSOR43, - ITEM_TELEMETRY_SENSOR44, - ITEM_TELEMETRY_SENSOR45, - ITEM_TELEMETRY_SENSOR46, - ITEM_TELEMETRY_SENSOR47, - ITEM_TELEMETRY_SENSOR48, - ITEM_TELEMETRY_SENSOR49, - ITEM_TELEMETRY_SENSOR50, - ITEM_TELEMETRY_SENSOR51, - ITEM_TELEMETRY_SENSOR52, - ITEM_TELEMETRY_SENSOR53, - ITEM_TELEMETRY_SENSOR54, - ITEM_TELEMETRY_SENSOR55, - ITEM_TELEMETRY_SENSOR56, - ITEM_TELEMETRY_SENSOR57, - ITEM_TELEMETRY_SENSOR58, - ITEM_TELEMETRY_SENSOR59, - ITEM_TELEMETRY_SENSOR60, + ITEM_TELEMETRY_SENSOR_FIRST, + ITEM_TELEMETRY_SENSOR_LAST = ITEM_TELEMETRY_SENSOR_FIRST + MAX_TELEMETRY_SENSORS - 1, ITEM_TELEMETRY_DISCOVER_SENSORS, ITEM_TELEMETRY_NEW_SENSOR, ITEM_TELEMETRY_DELETE_ALL_SENSORS, @@ -105,6 +48,7 @@ enum MenuModelTelemetryFrskyItems { #define TELEM_COL4 350 #define TELEM_COL5 425 +#define RSSI_ROWS LABEL(RSSI), 0, 0, 0, 0, #define SENSOR_ROWS(x) (isTelemetryFieldAvailable(x) ? (uint8_t)0 : HIDDEN_ROW) #define SENSORS_ROWS LABEL(Sensors), SENSOR_ROWS(0), SENSOR_ROWS(1), SENSOR_ROWS(2), SENSOR_ROWS(3), SENSOR_ROWS(4), SENSOR_ROWS(5), SENSOR_ROWS(6), SENSOR_ROWS(7), SENSOR_ROWS(8), SENSOR_ROWS(9), SENSOR_ROWS(10), SENSOR_ROWS(11), SENSOR_ROWS(12), SENSOR_ROWS(13), SENSOR_ROWS(14), SENSOR_ROWS(15), SENSOR_ROWS(16), SENSOR_ROWS(17), SENSOR_ROWS(18), SENSOR_ROWS(19), SENSOR_ROWS(20), SENSOR_ROWS(21), SENSOR_ROWS(22), SENSOR_ROWS(23), SENSOR_ROWS(24), SENSOR_ROWS(25), SENSOR_ROWS(26), SENSOR_ROWS(27), SENSOR_ROWS(28), SENSOR_ROWS(29), SENSOR_ROWS(30), \ SENSOR_ROWS(31), SENSOR_ROWS(32), SENSOR_ROWS(33), SENSOR_ROWS(34), SENSOR_ROWS(35), SENSOR_ROWS(36), SENSOR_ROWS(37), SENSOR_ROWS(38), SENSOR_ROWS(39), SENSOR_ROWS(40),SENSOR_ROWS(41), SENSOR_ROWS(42), SENSOR_ROWS(43), SENSOR_ROWS(44), SENSOR_ROWS(45), SENSOR_ROWS(46), SENSOR_ROWS(47), SENSOR_ROWS(48), SENSOR_ROWS(49), SENSOR_ROWS(50),SENSOR_ROWS(51), SENSOR_ROWS(52), SENSOR_ROWS(53), SENSOR_ROWS(54), SENSOR_ROWS(55), SENSOR_ROWS(56), SENSOR_ROWS(57), SENSOR_ROWS(58), SENSOR_ROWS(59), 0, 0, 0, 0, @@ -113,12 +57,11 @@ enum MenuModelTelemetryFrskyItems { #else #define VARIO_ROWS #endif -#define RSSI_ROWS LABEL(RSSI), 0, 0, 0, -#define TELEMETRY_TYPE_ROWS (g_model.moduleData[INTERNAL_MODULE].rfProtocol == MODULE_SUBTYPE_PXX1_OFF && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM) ? (uint8_t)0 : HIDDEN_ROW, +#define TELEMETRY_TYPE_ROWS (!IS_INTERNAL_MODULE_ENABLED() && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM) ? (uint8_t)0 : HIDDEN_ROW, void onSensorMenu(const char * result) { - uint8_t index = menuVerticalPosition - ITEM_TELEMETRY_SENSOR1; + uint8_t index = menuVerticalPosition - ITEM_TELEMETRY_SENSOR_FIRST; if (index < MAX_TELEMETRY_SENSORS) { if (result == STR_EDIT) { @@ -151,16 +94,18 @@ void onSensorMenu(const char * result) } } -bool menuModelTelemetryFrsky(event_t event) +void onDeleteAllSensorsConfirm(const char * result) { - if (warningResult) { - warningResult = 0; + if (result == STR_OK) { for (int i=0; i0) ? BLINK|INVERS : INVERS); LcdFlags attr = (menuVerticalPosition == k ? blink : 0); - if (k>=ITEM_TELEMETRY_SENSOR1 && k= ITEM_TELEMETRY_SENSOR_FIRST && k <= ITEM_TELEMETRY_SENSOR_LAST) { + int index = k - ITEM_TELEMETRY_SENSOR_FIRST; lcdDrawNumber(MENUS_MARGIN_LEFT+INDENT_WIDTH, y, index+1, LEFT|attr, 0, NULL, ":"); lcdDrawSizedText(60, y, g_model.telemetrySensors[index].label, TELEM_LABEL_LEN, ZCHAR); TelemetryItem & telemetryItem = telemetryItems[index]; @@ -233,7 +178,7 @@ bool menuModelTelemetryFrsky(event_t event) break; case ITEM_TELEMETRY_DISCOVER_SENSORS: - lcdDrawText(MENUS_MARGIN_LEFT+INDENT_WIDTH, y, allowNewSensors ? NO_INDENT(STR_STOP_DISCOVER_SENSORS) : NO_INDENT(STR_DISCOVER_SENSORS), attr); + lcdDrawText(MENUS_MARGIN_LEFT+INDENT_WIDTH, y, allowNewSensors ? STR_STOP_DISCOVER_SENSORS : STR_DISCOVER_SENSORS, attr); if (attr && event==EVT_KEY_BREAK(KEY_ENTER)) { s_editMode = 0; allowNewSensors = !allowNewSensors; @@ -256,12 +201,12 @@ bool menuModelTelemetryFrsky(event_t event) break; case ITEM_TELEMETRY_DELETE_ALL_SENSORS: - lcdDrawText(MENUS_MARGIN_LEFT+INDENT_WIDTH, y, NO_INDENT(STR_DELETE_ALL_SENSORS), attr); + lcdDrawText(MENUS_MARGIN_LEFT+INDENT_WIDTH, y, STR_DELETE_ALL_SENSORS, attr); if (attr) s_editMode = 0; - if (attr && event==EVT_KEY_LONG(KEY_ENTER)) { + if (attr && event == EVT_KEY_BREAK(KEY_ENTER)) { killEvents(KEY_ENTER); - POPUP_CONFIRMATION(STR_CONFIRMDELETE); + POPUP_CONFIRMATION(STR_CONFIRMDELETE, onDeleteAllSensorsConfirm); } break; @@ -281,6 +226,20 @@ bool menuModelTelemetryFrsky(event_t event) lcdDrawText(MENUS_MARGIN_LEFT, y, "RSSI"); break; + case ITEM_TELEMETRY_RSSI_SOURCE: { + lcdDrawText(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, STR_SOURCE); + drawSource(TELEM_COL2, y, g_model.rssiSource ? MIXSRC_FIRST_TELEM + 3 * (g_model.rssiSource - 1) : 0, attr); + if (g_model.rssiSource) { + TelemetrySensor * sensor = &g_model.telemetrySensors[g_model.rssiSource - 1]; + lcdDrawText(lcdNextPos, y, " ", attr); + drawReceiverName(lcdNextPos, y, sensor->frskyInstance.rxIndex >> 2, sensor->frskyInstance.rxIndex & 0x03, attr); + } + if (attr) { + g_model.rssiSource = checkIncDec(event, g_model.rssiSource, 0, MAX_TELEMETRY_SENSORS, EE_MODEL | NO_INCDEC_MARKS, isRssiSensorAvailable); + } + break; + } + case ITEM_TELEMETRY_RSSI_ALARM1: case ITEM_TELEMETRY_RSSI_ALARM2: { bool warning = (k==ITEM_TELEMETRY_RSSI_ALARM1); diff --git a/radio/src/gui/480x272/popups.cpp b/radio/src/gui/480x272/popups.cpp index d0773a3c7..25a28779e 100644 --- a/radio/src/gui/480x272/popups.cpp +++ b/radio/src/gui/480x272/popups.cpp @@ -20,13 +20,13 @@ #include "opentx.h" -const char *warningText = NULL; +const char *warningText = nullptr; const char *warningInfoText; uint8_t warningInfoLength; uint8_t warningType; uint8_t warningResult = 0; uint8_t warningInfoFlags = ZCHAR; -void (*popupFunc)(event_t event) = NULL; +PopupFunc popupFunc = nullptr; const char *popupMenuItems[POPUP_MENU_MAX_LINES]; uint8_t popupMenuSelectedItem = 0; uint16_t popupMenuItemsCount = 0; @@ -34,22 +34,6 @@ uint16_t popupMenuOffset = 0; uint8_t popupMenuOffsetType = MENU_OFFSET_INTERNAL; void (*popupMenuHandler)(const char * result); -void runPopupWarningBox() -{ - // theme->drawMessageBox("", "", "", MESSAGEBOX_TYPE_WARNING); - // lcdDrawSolidFilledRect(POPUP_X, POPUP_Y, POPUP_W, POPUP_H, TEXT_BGCOLOR); - // lcdDrawSolidRect(POPUP_X, POPUP_Y, POPUP_W, POPUP_H, 2, ALARM_COLOR); - // lcdDrawBitmap(POPUP_X+15, POPUP_Y+20, LBM_WARNING); -} - -void drawMessageBox() -{ - // theme->drawMessageBox("", "", "", MESSAGEBOX_TYPE_INFO); - // lcdDrawSolidFilledRect(POPUP_X, POPUP_Y, POPUP_W, POPUP_H, TEXT_BGCOLOR); - // lcdDrawSolidRect(POPUP_X, POPUP_Y, POPUP_W, POPUP_H, 2, WARNING_COLOR); - // lcdDrawBitmap(POPUP_X+15, POPUP_Y+20, LBM_MESSAGE); -} - void drawAlertBox(const char * title, const char * text, const char * action) { theme->drawMessageBox(title, text, action, WARNING_TYPE_ALERT); @@ -83,7 +67,21 @@ void runPopupWarning(event_t event) { warningResult = false; - theme->drawMessageBox(warningText, warningInfoText, warningType == WARNING_TYPE_INFO ? STR_OK : (warningType == WARNING_TYPE_ASTERISK ? STR_EXIT : STR_POPUPS_ENTER_EXIT), warningType); + const char * action; + switch (warningType) { + case WARNING_TYPE_INFO: + action = STR_OK; + break; + case WARNING_TYPE_ASTERISK: + case WARNING_TYPE_WAIT: + action = STR_EXIT; + break; + default: + action = STR_POPUPS_ENTER_EXIT; + break; + } + + theme->drawMessageBox(warningText, warningInfoText, action, warningType); switch (event) { case EVT_KEY_BREAK(KEY_ENTER): @@ -115,7 +113,7 @@ void runPopupWarning(event_t event) const char * runPopupMenu(event_t event) { - const char * result = NULL; + const char * result = nullptr; uint8_t display_count = min(popupMenuItemsCount, MENU_MAX_DISPLAY_LINES); diff --git a/radio/src/gui/480x272/radio_hardware.cpp b/radio/src/gui/480x272/radio_hardware.cpp index dc949ea6b..be5fb230e 100644 --- a/radio/src/gui/480x272/radio_hardware.cpp +++ b/radio/src/gui/480x272/radio_hardware.cpp @@ -52,6 +52,8 @@ enum MenuRadioHardwareItems { ITEM_RADIO_HARDWARE_SH, ITEM_RADIO_HARDWARE_SI, // Gimbal switch left ITEM_RADIO_HARDWARE_SJ, // Gimbal switch right + ITEM_RADIO_HARDWARE_BATTERY_CALIB, + ITEM_RADIO_HARDWARE_RTC_BATTERY, ITEM_RADIO_HARDWARE_SERIAL_BAUDRATE, ITEM_RADIO_HARDWARE_BLUETOOTH_MODE, ITEM_RADIO_HARDWARE_BLUETOOTH_PAIRING_CODE, @@ -60,7 +62,6 @@ enum MenuRadioHardwareItems { ITEM_RADIO_HARDWARE_AUX_SERIAL_MODE, #endif ITEM_RADIO_HARDWARE_JITTER_FILTER, - ITEM_RADIO_HARDWARE_BAT_CAL, ITEM_RADIO_HARDWARE_MAX }; @@ -77,7 +78,31 @@ enum MenuRadioHardwareItems { bool menuRadioHardware(event_t event) { - MENU(STR_HARDWARE, RADIO_ICONS, menuTabGeneral, MENU_RADIO_HARDWARE, ITEM_RADIO_HARDWARE_MAX, { 0, LABEL(Sticks), 0, 0, 0, 0, LABEL(Pots), POTS_ROWS, LABEL(Switches), SWITCHES_ROWS, 0, BLUETOOTH_ROWS, 0, 0, 0 }); + MENU(STR_HARDWARE, RADIO_ICONS, menuTabGeneral, MENU_RADIO_HARDWARE, ITEM_RADIO_HARDWARE_MAX, { + 0 /* calibration button */, + + LABEL(Sticks), + 0 /* stick 1 */, + 0 /* stick 2 */, + 0 /* stick 3 */, + 0 /* stick 4 */, + + LABEL(Pots), + POTS_ROWS, + + LABEL(Switches), + SWITCHES_ROWS, + + 0, /* battery */ + READONLY_ROW, /* RTC */ + + 0, /* max baudrate */ + + BLUETOOTH_ROWS, + + 0, /* aux serial mode */ + 0, /* ADC filter */ + }); uint8_t sub = menuVerticalPosition; @@ -177,11 +202,22 @@ bool menuRadioHardware(event_t event) lcdDrawMMM(HW_SETTINGS_COLUMN, y, 0); config = editChoice(HW_SETTINGS_COLUMN+50, y, STR_SWTYPES, config, SWITCH_NONE, SWITCH_TYPE_MAX(index), menuHorizontalPosition == 1 ? attr : 0, event); if (attr && checkIncDec_Ret) { - g_eeGeneral.switchConfig = bfSet(g_eeGeneral.switchConfig, config, 2*index, 2); + g_eeGeneral.switchConfig = bfSet(g_eeGeneral.switchConfig, config, 2*index, 2); } break; } + case ITEM_RADIO_HARDWARE_BATTERY_CALIB: + lcdDrawText(MENUS_MARGIN_LEFT, y, STR_BATT_CALIB); + lcdDrawNumber(HW_SETTINGS_COLUMN+50, y, getBatteryVoltage(), attr|PREC2, 0, NULL, "V"); + if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.txVoltageCalibration, -127, 127); + break; + + case ITEM_RADIO_HARDWARE_RTC_BATTERY: + lcdDrawText(MENUS_MARGIN_LEFT, y, STR_RTC_BATT); + lcdDrawNumber(HW_SETTINGS_COLUMN+50, y, getRTCBatteryVoltage(), attr|PREC2, 0, NULL, "V"); + break; + case ITEM_RADIO_HARDWARE_SERIAL_BAUDRATE: lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MAXBAUDRATE); lcdDrawNumber(HW_SETTINGS_COLUMN+50, y, CROSSFIRE_BAUDRATES[g_eeGeneral.telemetryBaudrate], attr|LEFT); @@ -232,12 +268,6 @@ bool menuRadioHardware(event_t event) g_eeGeneral.jitterFilter = 1 - editCheckBox(b, HW_SETTINGS_COLUMN+50, y, attr, event); break; } - - case ITEM_RADIO_HARDWARE_BAT_CAL: - lcdDrawText(MENUS_MARGIN_LEFT, y, STR_BATT_CALIB); - lcdDrawNumber(HW_SETTINGS_COLUMN+50, y, getBatteryVoltage(), attr|LEFT|PREC2, 0, NULL, "V"); - if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.txVoltageCalibration, -127, 127); - break; } } diff --git a/radio/src/gui/480x272/radio_power_meter.cpp b/radio/src/gui/480x272/radio_power_meter.cpp index 1e4983c19..46472d8bf 100644 --- a/radio/src/gui/480x272/radio_power_meter.cpp +++ b/radio/src/gui/480x272/radio_power_meter.cpp @@ -18,7 +18,6 @@ * GNU General Public License for more details. */ -#include #include "opentx.h" extern uint8_t g_moduleIdx; @@ -32,11 +31,11 @@ enum PowerMeterFields { POWER_METER_FIELDS_MAX }; -#define POWER_METER_MARGIN_2ND_COLUMN 180 +constexpr coord_t POWER_METER_2ND_COLUMN = 100; bool menuRadioPowerMeter(event_t event) { - SIMPLE_SUBMENU(STR_MENU_POWER_METER, ICON_RADIO, POWER_METER_FIELDS_MAX-1); + SUBMENU(STR_MENU_POWER_METER, ICON_RADIO_SPECTRUM_ANALYSER, POWER_METER_FIELDS_MAX-1, {0, 0, READONLY_ROW, READONLY_ROW, READONLY_ROW}); if (TELEMETRY_STREAMING()) { lcdDrawCenteredText(LCD_H/2, STR_TURN_OFF_RECEIVER); @@ -44,51 +43,54 @@ bool menuRadioPowerMeter(event_t event) killEvents(event); popMenu(); } - return true; + return false; } if (menuEvent) { lcdDrawCenteredText(LCD_H/2, STR_STOPPING); lcdRefresh(); - moduleState[g_moduleIdx].mode = MODULE_MODE_NORMAL; + moduleState[g_moduleIdx].readModuleInformation(&reusableBuffer.moduleSetup.pxx2.moduleInformation, PXX2_HW_INFO_TX_ID, PXX2_HW_INFO_TX_ID); /* wait 1s to resume normal operation before leaving */ watchdogSuspend(1000); RTOS_WAIT_MS(1000); - return true; + return false; } if (moduleState[g_moduleIdx].mode != MODULE_MODE_POWER_METER) { memclear(&reusableBuffer.powerMeter, sizeof(reusableBuffer.powerMeter)); reusableBuffer.powerMeter.freq = 2400000000; reusableBuffer.powerMeter.attn = 4; + reusableBuffer.powerMeter.dirty = true; moduleState[g_moduleIdx].mode = MODULE_MODE_POWER_METER; } // The warning - if (reusableBuffer.powerMeter.attn != 0) - lcdDrawCenteredText(MENU_CONTENT_TOP, STR_POWERMETER_ATTN_NEEDED, BOLD); + if (reusableBuffer.powerMeter.attn != 0) { + lcdDrawCenteredText(MENU_BODY_TOP, STR_POWERMETER_ATTN_NEEDED, BOLD | INVERS); + } for (uint8_t i=0; i 0 ? INVERS | BLINK : INVERS) : 0); - coord_t y = MENU_CONTENT_TOP + 30 + i * FH; + coord_t y = MENU_BODY_TOP + 2 * FH + i * FH; switch (i) { case POWER_METER_FREQ_RANGE: lcdDrawText(MENUS_MARGIN_LEFT, y, STR_POWERMETER_FREQ); - lcdDrawNumber(POWER_METER_MARGIN_2ND_COLUMN, y, reusableBuffer.powerMeter.freq / 1000000, LEFT | attr); + lcdDrawNumber(POWER_METER_2ND_COLUMN, y, reusableBuffer.powerMeter.freq / 1000000, LEFT | attr); lcdDrawText(lcdNextPos, y, " MHz band"); if (attr) { reusableBuffer.powerMeter.freq = checkIncDec(event, reusableBuffer.powerMeter.freq == 900000000, 0, 1) ? 900000000 : 2400000000; if (checkIncDec_Ret) { reusableBuffer.powerMeter.power = 0; reusableBuffer.powerMeter.peak = 0; + reusableBuffer.powerMeter.dirty = true; } } break; case POWER_METER_ATTENUATOR: lcdDrawText(MENUS_MARGIN_LEFT, y, STR_POWERMETER_ATTN); - lcdDrawNumber(POWER_METER_MARGIN_2ND_COLUMN, y, -10 * reusableBuffer.powerMeter.attn, LEFT | attr); + lcdDrawNumber(POWER_METER_2ND_COLUMN, y, -10 * reusableBuffer.powerMeter.attn, LEFT | attr); lcdDrawText(lcdNextPos, y, " dB"); if (attr) { reusableBuffer.powerMeter.attn = checkIncDec(event, reusableBuffer.powerMeter.attn, 0, 5, 0); @@ -97,9 +99,9 @@ bool menuRadioPowerMeter(event_t event) case POWER_METER_MAX: lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MAX); - lcdDrawNumber(POWER_METER_MARGIN_2ND_COLUMN, y, -10 + 10 * reusableBuffer.powerMeter.attn); - lcdDrawText(lcdNextPos, y, "dBm/ "); - drawPower(lcdNextPos, y, -10 + 10 * reusableBuffer.powerMeter.attn, 0); + lcdDrawNumber(POWER_METER_2ND_COLUMN, y, -10 + 10 * reusableBuffer.powerMeter.attn); + lcdDrawText(lcdNextPos + 3, y, "dBm/ "); + drawPower(lcdNextPos + 3, y, -10 + 10 * reusableBuffer.powerMeter.attn, 0); if (attr) { reusableBuffer.powerMeter.attn = checkIncDec(event, reusableBuffer.powerMeter.attn, 0, 5, 0); } @@ -108,7 +110,7 @@ bool menuRadioPowerMeter(event_t event) case POWER_METER_POWER: lcdDrawText(MENUS_MARGIN_LEFT, y, STR_POWERMETER_POWER); if (reusableBuffer.powerMeter.power) { - lcdDrawNumber(POWER_METER_MARGIN_2ND_COLUMN, y, reusableBuffer.powerMeter.power + reusableBuffer.powerMeter.attn * 1000, LEFT | PREC2); + lcdDrawNumber(POWER_METER_2ND_COLUMN, y, reusableBuffer.powerMeter.power + reusableBuffer.powerMeter.attn * 1000, LEFT | PREC2); lcdDrawText(lcdNextPos, y, "dBm"); } break; @@ -116,11 +118,12 @@ bool menuRadioPowerMeter(event_t event) case POWER_METER_PEAK: lcdDrawText(MENUS_MARGIN_LEFT, y, STR_POWERMETER_PEAK); if (reusableBuffer.powerMeter.peak) { - lcdDrawNumber(POWER_METER_MARGIN_2ND_COLUMN, y, reusableBuffer.powerMeter.peak + reusableBuffer.powerMeter.attn * 1000, LEFT | PREC2); + lcdDrawNumber(POWER_METER_2ND_COLUMN, y, reusableBuffer.powerMeter.peak + reusableBuffer.powerMeter.attn * 1000, LEFT | PREC2); lcdDrawText(lcdNextPos, y, "dBm"); } break; } } + return true; } diff --git a/radio/src/gui/480x272/radio_sdmanager.cpp b/radio/src/gui/480x272/radio_sdmanager.cpp index 800f15622..ceb3eae79 100644 --- a/radio/src/gui/480x272/radio_sdmanager.cpp +++ b/radio/src/gui/480x272/radio_sdmanager.cpp @@ -248,6 +248,29 @@ bool menuRadioSdManager(event_t _event) POPUP_MENU_ADD_ITEM(STR_FLASH_INTERNAL_MODULE); POPUP_MENU_ADD_ITEM(STR_FLASH_EXTERNAL_MODULE); } + else if (!READ_ONLY() && !strcasecmp(ext, UPDATE_FIRMWARE_EXT)) { + FrSkyFirmwareInformation information; + if (readFirmwareInformation(line, information) == nullptr) { + if (information.productFamily == FIRMWARE_FAMILY_INTERNAL_MODULE) + POPUP_MENU_ADD_ITEM(STR_FLASH_INTERNAL_MODULE); + if (information.productFamily == FIRMWARE_FAMILY_EXTERNAL_MODULE) + POPUP_MENU_ADD_ITEM(STR_FLASH_EXTERNAL_MODULE); + if (HAS_SPORT_UPDATE_CONNECTOR() && (information.productFamily == FIRMWARE_FAMILY_RECEIVER || information.productFamily == FIRMWARE_FAMILY_SENSOR)) + POPUP_MENU_ADD_ITEM(STR_FLASH_EXTERNAL_DEVICE); +#if defined(PXX2) + if (information.productFamily == FIRMWARE_FAMILY_RECEIVER) + POPUP_MENU_ADD_ITEM(STR_FLASH_RECEIVER_OTA); +#endif +#if defined(BLUETOOTH) + if (information.productFamily == FIRMWARE_FAMILY_BLUETOOTH_CHIP) + POPUP_MENU_ADD_ITEM(STR_FLASH_BLUETOOTH_MODULE); +#endif +#if defined(HARDWARE_POWER_MANAGEMENT_UNIT) + if (information.productFamily == FIRMWARE_FAMILY_POWER_MANAGEMENT_UNIT) + POPUP_MENU_ADD_ITEM(STR_FLASH_POWER_MANAGEMENT_UNIT); +#endif + } + } else if (isExtensionMatching(ext, SCRIPTS_EXT)) { POPUP_MENU_ADD_ITEM(STR_EXECUTE_FILE); } diff --git a/radio/src/gui/480x272/radio_setup.cpp b/radio/src/gui/480x272/radio_setup.cpp index a26d2d08a..58c061175 100644 --- a/radio/src/gui/480x272/radio_setup.cpp +++ b/radio/src/gui/480x272/radio_setup.cpp @@ -67,6 +67,9 @@ enum menuRadioSetupItems { ITEM_SETUP_DIM_LEVEL, ITEM_SETUP_FLASH_BEEP, CASE_PWR_BUTTON_PRESS(ITEM_SETUP_PWR_OFF_SPEED) +#if defined(PXX2) + ITEM_RADIO_SETUP_OWNER_ID, +#endif CASE_GPS(ITEM_SETUP_LABEL_GPS) CASE_GPS(ITEM_SETUP_TIMEZONE) CASE_GPS(ITEM_SETUP_ADJUST_RTC) @@ -116,8 +119,21 @@ bool menuRadioSetup(event_t event) LABEL(ALARMS), 0, 0, 0, 0, LABEL(BACKLIGHT), 0, 0, 0, 0, 0, CASE_PWR_BUTTON_PRESS(0) - CASE_GPS(LABEL(GPS)) CASE_GPS(0) CASE_GPS(0) CASE_GPS(0) - CASE_PXX1(0) 0, 0, FAI_CHOICE_ROW 0, 0, 0, 0, 1/*to force edit mode*/ }); // Country code - Voice Language - Units - Fai choice - Play delay - USB mode - Chan order - Mode (1 to 4) + CASE_PXX2(0) // owner registration ID + CASE_GPS(LABEL(GPS)) + CASE_GPS(0) // timezone + CASE_GPS(0) // adjust RTC + CASE_GPS(0) // GPS format + CASE_PXX1(0) // country code + 0, // voice language + 0, // imperial + FAI_CHOICE_ROW + 0, // switches delay + 0, // USB mode + 0, // RX channels order + 0, // sticks mode + 1 /*to force edit mode*/ + }); // Units - Fai choice - Play delay - USB mode - Chan order - Mode (1 to 4) if (event == EVT_ENTRY) { reusableBuffer.generalSettings.stickMode = g_eeGeneral.stickMode; @@ -366,6 +382,13 @@ bool menuRadioSetup(event_t event) g_eeGeneral.alarmsFlash = editCheckBox(g_eeGeneral.alarmsFlash, RADIO_SETUP_2ND_COLUMN, y, attr, event ) ; break; +#if defined(PXX2) + case ITEM_RADIO_SETUP_OWNER_ID: + lcdDrawText(MENUS_MARGIN_LEFT, y, STR_OWNER_ID); + editName(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.ownerRegistrationID, PXX2_LEN_REGISTRATION_ID, event, attr); + break; +#endif + case ITEM_SETUP_BACKLIGHT_DELAY: lcdDrawText(MENUS_MARGIN_LEFT, y, STR_BLDELAY); lcdDrawNumber(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.lightAutoOff*5, attr|LEFT, 0, NULL, "s"); diff --git a/radio/src/gui/480x272/radio_spectrum_analyser.cpp b/radio/src/gui/480x272/radio_spectrum_analyser.cpp index 734cc6dd7..260fbc767 100644 --- a/radio/src/gui/480x272/radio_spectrum_analyser.cpp +++ b/radio/src/gui/480x272/radio_spectrum_analyser.cpp @@ -30,7 +30,7 @@ enum SpectrumFields { bool menuRadioSpectrumAnalyser(event_t event) { - SUBMENU(STR_MENU_SPECTRUM_ANALYSER, ICON_RADIO, 1, {1}); + SUBMENU(STR_MENU_SPECTRUM_ANALYSER, ICON_RADIO_SPECTRUM_ANALYSER, 1, {1}); if (menuEvent) { lcdDrawCenteredText(LCD_H/2, STR_STOPPING); diff --git a/radio/src/gui/480x272/radio_tools.cpp b/radio/src/gui/480x272/radio_tools.cpp index 9ccdf3d12..72dbcf3c2 100644 --- a/radio/src/gui/480x272/radio_tools.cpp +++ b/radio/src/gui/480x272/radio_tools.cpp @@ -89,14 +89,14 @@ bool menuRadioTools(event_t event) if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[INTERNAL_MODULE].information.modelID, MODULE_OPTION_SPECTRUM_ANALYSER)) addRadioModuleTool(index++, STR_SPECTRUM_ANALYSER_INT, menuRadioSpectrumAnalyser, INTERNAL_MODULE); -// if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[INTERNAL_MODULE].information.modelID, MODULE_OPTION_POWER_METER)) -// addRadioModuleTool(index++, STR_POWER_METER_INT, menuRadioPowerMeter, INTERNAL_MODULE); + if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[INTERNAL_MODULE].information.modelID, MODULE_OPTION_POWER_METER)) + addRadioModuleTool(index++, STR_POWER_METER_INT, menuRadioPowerMeter, INTERNAL_MODULE); if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[EXTERNAL_MODULE].information.modelID, MODULE_OPTION_SPECTRUM_ANALYSER)) addRadioModuleTool(index++, STR_SPECTRUM_ANALYSER_EXT, menuRadioSpectrumAnalyser, EXTERNAL_MODULE); -// if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[EXTERNAL_MODULE].information.modelID, MODULE_OPTION_POWER_METER)) -// addRadioModuleTool(index++, STR_POWER_METER_EXT, menuRadioPowerMeter, EXTERNAL_MODULE); + if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[EXTERNAL_MODULE].information.modelID, MODULE_OPTION_POWER_METER)) + addRadioModuleTool(index++, STR_POWER_METER_EXT, menuRadioPowerMeter, EXTERNAL_MODULE); #endif #if defined(LUA) diff --git a/radio/src/gui/480x272/radio_version.cpp b/radio/src/gui/480x272/radio_version.cpp index b438782a1..33ab73607 100644 --- a/radio/src/gui/480x272/radio_version.cpp +++ b/radio/src/gui/480x272/radio_version.cpp @@ -21,22 +21,171 @@ #include "opentx.h" #include "options.h" +#if defined(PXX2) +constexpr coord_t COLUMN2_X = 200; + +void drawPXX2Version(coord_t x, coord_t y, PXX2Version version) +{ + if (version.major == 0xFF && version.minor == 0x0F && version.revision == 0x0F) { + lcdDrawText(x, y, "---"); + } + else { + lcdDrawNumber(x, y, 1 + version.major, LEFT); + lcdDrawChar(lcdNextPos, y, '.'); + lcdDrawNumber(lcdNextPos, y, version.minor, LEFT); + lcdDrawChar(lcdNextPos, y, '.'); + lcdDrawNumber(lcdNextPos, y, version.revision, LEFT); + } +} + +void drawPXX2FullVersion(coord_t x, coord_t y, PXX2Version hwVersion, PXX2Version swVersion) +{ + drawPXX2Version(x, y, hwVersion); + lcdDrawText(lcdNextPos, y, "/"); + drawPXX2Version(lcdNextPos, y, swVersion); +} + +bool menuRadioModulesVersion(event_t event) +{ + if (menuEvent) { + moduleState[INTERNAL_MODULE].mode = MODULE_MODE_NORMAL; + moduleState[EXTERNAL_MODULE].mode = MODULE_MODE_NORMAL; + return false; + } + + drawMenuTemplate(STR_MENU_MODULES_RX_VERSION, 0, RADIO_ICONS, OPTION_MENU_TITLE_BAR); + + if (event == EVT_ENTRY) { + memclear(&reusableBuffer.hardwareAndSettings.modules, sizeof(reusableBuffer.hardwareAndSettings.modules)); + } + + if (event == EVT_ENTRY || get_tmr10ms() >= reusableBuffer.hardwareAndSettings.updateTime) { + if (isModulePXX2(INTERNAL_MODULE) && IS_INTERNAL_MODULE_ON()) { + moduleState[INTERNAL_MODULE].readModuleInformation(&reusableBuffer.hardwareAndSettings.modules[INTERNAL_MODULE], PXX2_HW_INFO_TX_ID, PXX2_MAX_RECEIVERS_PER_MODULE - 1); + } + + if (isModulePXX2(EXTERNAL_MODULE) && IS_EXTERNAL_MODULE_ON()) { + moduleState[EXTERNAL_MODULE].readModuleInformation(&reusableBuffer.hardwareAndSettings.modules[EXTERNAL_MODULE], PXX2_HW_INFO_TX_ID, PXX2_MAX_RECEIVERS_PER_MODULE - 1); + } + + reusableBuffer.hardwareAndSettings.updateTime = get_tmr10ms() + 1000 /* 10s*/; + } + + coord_t y = MENU_BODY_TOP - menuVerticalOffset * FH; + + for (uint8_t module=0; module= MENU_BODY_TOP && y < MENU_FOOTER_TOP) { + if (module == INTERNAL_MODULE) + lcdDrawText(MENUS_MARGIN_LEFT, y, STR_INTERNAL_MODULE); + else if (module == EXTERNAL_MODULE) + lcdDrawText(MENUS_MARGIN_LEFT, y, STR_EXTERNAL_MODULE); + } + y += FH; + + // Module model + if (y >= MENU_BODY_TOP && y < MENU_FOOTER_TOP) { + lcdDrawText(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, STR_MODULE); + if (module == INTERNAL_MODULE) { + if (!IS_INTERNAL_MODULE_ON()) { + lcdDrawText(COLUMN2_X, y, STR_OFF); + y += FH; + continue; + } + if (!isModulePXX2(INTERNAL_MODULE)) { + lcdDrawText(COLUMN2_X, y, STR_NO_INFORMATION); + y += FH; + continue; + } + } + else if (module == EXTERNAL_MODULE) { + if (!IS_EXTERNAL_MODULE_ON()) { + lcdDrawText(COLUMN2_X, y, STR_OFF); + y += FH; + continue; + } + if (!isModulePXX2(EXTERNAL_MODULE)) { + lcdDrawText(COLUMN2_X, y, STR_NO_INFORMATION); + y += FH; + continue; + } + } + uint8_t modelId = reusableBuffer.hardwareAndSettings.modules[module].information.modelID; + lcdDrawText(COLUMN2_X, y, getPXX2ModuleName(modelId)); + } + y += FH; + + // Module version + if (y >= MENU_BODY_TOP && y < MENU_FOOTER_TOP) { + if (reusableBuffer.hardwareAndSettings.modules[module].information.modelID) { + drawPXX2FullVersion(COLUMN2_X, y, reusableBuffer.hardwareAndSettings.modules[module].information.hwVersion, reusableBuffer.hardwareAndSettings.modules[module].information.swVersion); + static const char * variants[] = {"FCC", "EU", "FLEX"}; + uint8_t variant = reusableBuffer.hardwareAndSettings.modules[module].information.variant - 1; + if (variant < DIM(variants)) { + lcdDrawText(lcdNextPos + 1, y, variants[variant]); + } + } + } + y += FH; + + for (uint8_t receiver=0; receiver= MENU_BODY_TOP && y < MENU_FOOTER_TOP) { + lcdDrawText(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, STR_RECEIVER); + lcdDrawNumber(lcdNextPos + 2, y, receiver + 1); + uint8_t modelId = reusableBuffer.hardwareAndSettings.modules[module].receivers[receiver].information.modelID; + lcdDrawText(COLUMN2_X, y, getPXX2ReceiverName(modelId)); + } + y += FH; + + // Receiver version + if (y >= MENU_BODY_TOP && y < MENU_FOOTER_TOP) { + drawPXX2FullVersion(COLUMN2_X, y, reusableBuffer.hardwareAndSettings.modules[module].receivers[receiver].information.hwVersion, reusableBuffer.hardwareAndSettings.modules[module].receivers[receiver].information.swVersion); + } + y += FH; + } + } + } + + uint8_t lines = (y - (FH + 1)) / FH + menuVerticalOffset; + if (lines > NUM_BODY_LINES) { + drawVerticalScrollbar(LCD_W-1, FH, LCD_H-FH, menuVerticalOffset, lines, NUM_BODY_LINES); + } + + switch(event) { + case EVT_ROTARY_LEFT: + if (lines > NUM_BODY_LINES) { + if (menuVerticalOffset-- == 0) + menuVerticalOffset = lines - 1; + } + break; + + case EVT_ROTARY_RIGHT: + if (lines > NUM_BODY_LINES) { + if (++menuVerticalOffset + NUM_BODY_LINES > lines) + menuVerticalOffset = 0; + } + break; + + case EVT_KEY_BREAK(KEY_EXIT): + if (menuVerticalOffset != 0) + menuVerticalOffset = 0; + else + popMenu(); + break; + } + + return true; +} +#endif + bool menuRadioVersion(event_t event) { char id[27]; - -#if 0 - if (warningResult) { - warningResult = 0; - showMessageBox(STR_STORAGE_FORMAT); - storageEraseAll(false); - NVIC_SystemReset(); - } -#endif - getCPUUniqueID(id); - SIMPLE_MENU(STR_MENUVERSION, RADIO_ICONS, menuTabGeneral, MENU_RADIO_VERSION, 0); + SIMPLE_MENU(STR_MENUVERSION, RADIO_ICONS, menuTabGeneral, MENU_RADIO_VERSION, 1); lcdDrawText(MENUS_MARGIN_LEFT, MENU_CONTENT_TOP, vers_stamp); lcdDrawText(MENUS_MARGIN_LEFT, MENU_CONTENT_TOP + FH, date_stamp); @@ -45,15 +194,6 @@ bool menuRadioVersion(event_t event) lcdDrawText(MENUS_MARGIN_LEFT, MENU_CONTENT_TOP + 4*FH, "UID:"); lcdDrawText(MENUS_MARGIN_LEFT + 64, MENU_CONTENT_TOP + 4*FH, id); -#if 0 - if (event == EVT_KEY_LONG(KEY_ENTER)) { - killEvents(event); - // POPUP_MENU_ADD_ITEM(STR_EEBACKUP); - POPUP_MENU_ADD_ITEM(STR_FACTORYRESET); - POPUP_MENU_START(onVersionMenu); - } -#endif - coord_t y = MENU_CONTENT_TOP + 5*FH; lcdDrawText(MENUS_MARGIN_LEFT, y, "OPTS:"); lcdNextPos = MENUS_MARGIN_LEFT + 64; @@ -62,15 +202,27 @@ bool menuRadioVersion(event_t event) const char * option = options[i]; coord_t width = getTextWidth(option); - if((lcdNextPos + 5 + width) > LCD_W) { + if ((lcdNextPos + 5 + width) > LCD_W) { lcdDrawText(lcdNextPos, y, ","); lcdNextPos = MENUS_MARGIN_LEFT; y += FH; } - if (i > 0 && lcdNextPos !=MENUS_MARGIN_LEFT) + if (i > 0 && lcdNextPos !=MENUS_MARGIN_LEFT) { lcdDrawText(lcdNextPos, y, ", "); + } lcdDrawText(lcdNextPos, y, option); } +#if defined(PXX2) + y += FH + FH / 2; + + lcdDrawText(MENUS_MARGIN_LEFT, y, BUTTON(TR_MODULES_RX_VERSION), menuVerticalPosition == 0 ? INVERS : 0); + y += FH; + if (menuVerticalPosition == 0 && event == EVT_KEY_BREAK(KEY_ENTER)) { + s_editMode = EDIT_SELECT_FIELD; + pushMenu(menuRadioModulesVersion); + } +#endif + return true; } diff --git a/radio/src/gui/480x272/theme.cpp b/radio/src/gui/480x272/theme.cpp index e4a60bec9..27756859a 100644 --- a/radio/src/gui/480x272/theme.cpp +++ b/radio/src/gui/480x272/theme.cpp @@ -90,10 +90,10 @@ void Theme::drawBackground() const void Theme::drawMessageBox(const char * title, const char * text, const char * action, uint32_t type) const { - //if (flags & MESSAGEBOX_TYPE_ALERT) { +// if (type == WARNING_TYPE_ALERT) { drawBackground(); lcdDrawFilledRect(0, POPUP_Y, LCD_W, POPUP_H, SOLID, TEXT_INVERTED_COLOR | OPACITY(8)); - //} +// } if (type == WARNING_TYPE_ALERT || type == WARNING_TYPE_ASTERISK) lcd->drawBitmap(POPUP_X-80, POPUP_Y+12, asterisk); diff --git a/radio/src/gui/480x272/themes/darkblue.cpp b/radio/src/gui/480x272/themes/darkblue.cpp index b79d9c0b4..017175c77 100644 --- a/radio/src/gui/480x272/themes/darkblue.cpp +++ b/radio/src/gui/480x272/themes/darkblue.cpp @@ -85,6 +85,7 @@ class DarkblueTheme: public Theme loadMenuIcon(ICON_RADIO_SETUP, "mask_radio_setup.png"); loadMenuIcon(ICON_RADIO_SD_MANAGER, "mask_radio_sd_browser.png"); loadMenuIcon(ICON_RADIO_TOOLS, "mask_radio_tools.png"); + loadMenuIcon(ICON_RADIO_SPECTRUM_ANALYSER, "/mask_radio_spectrum_analyser.png"); loadMenuIcon(ICON_RADIO_GLOBAL_FUNCTIONS, "mask_radio_global_functions.png"); loadMenuIcon(ICON_RADIO_TRAINER, "mask_radio_trainer.png"); loadMenuIcon(ICON_RADIO_HARDWARE, "mask_radio_hardware.png"); diff --git a/radio/src/gui/480x272/themes/default.cpp b/radio/src/gui/480x272/themes/default.cpp index 5172581d8..0183a601c 100644 --- a/radio/src/gui/480x272/themes/default.cpp +++ b/radio/src/gui/480x272/themes/default.cpp @@ -100,6 +100,7 @@ class DefaultTheme: public Theme loadMenuIcon(ICON_RADIO_SETUP, "mask_radio_setup.png"); loadMenuIcon(ICON_RADIO_SD_MANAGER, "mask_radio_sd_browser.png"); loadMenuIcon(ICON_RADIO_TOOLS, "mask_radio_tools.png"); + loadMenuIcon(ICON_RADIO_SPECTRUM_ANALYSER, "/mask_radio_spectrum_analyser.png"); loadMenuIcon(ICON_RADIO_GLOBAL_FUNCTIONS, "mask_radio_global_functions.png"); loadMenuIcon(ICON_RADIO_TRAINER, "mask_radio_trainer.png"); loadMenuIcon(ICON_RADIO_HARDWARE, "mask_radio_hardware.png"); diff --git a/radio/src/gui/480x272/view_statistics.cpp b/radio/src/gui/480x272/view_statistics.cpp index 5d4f4a5b0..294f8bf7c 100644 --- a/radio/src/gui/480x272/view_statistics.cpp +++ b/radio/src/gui/480x272/view_statistics.cpp @@ -154,12 +154,6 @@ bool menuStatsDebug(event_t event) lcdDrawNumber(lcdNextPos+5, y, audioStack.available(), LEFT); y += FH; -#if defined(STM32) - lcdDrawText(MENUS_MARGIN_LEFT, y, STR_RTC_BATT); - drawValueWithUnit(MENU_STATS_COLUMN1, y, getRTCBatteryVoltage(), UNIT_VOLTS, PREC2|LEFT); - y += FH; -#endif - #if defined(DISK_CACHE) && defined(DEBUG) lcdDrawText(MENUS_MARGIN_LEFT, y, "SD cache hits"); lcdDrawNumber(MENU_STATS_COLUMN1, y, diskCache.getHitRate(), PREC1|LEFT, 0, NULL, "%"); diff --git a/radio/src/gui/480x272/widgets.cpp b/radio/src/gui/480x272/widgets.cpp index 301fe575b..0e1dd5416 100644 --- a/radio/src/gui/480x272/widgets.cpp +++ b/radio/src/gui/480x272/widgets.cpp @@ -427,3 +427,21 @@ void drawShutdownAnimation(uint32_t duration, uint32_t totalDuration, const char lcdRefresh(); lastDuration = duration; } + +void drawReceiverName(coord_t x, coord_t y, uint8_t moduleIdx, uint8_t receiverIdx, LcdFlags flags) +{ + if (isModulePXX2(moduleIdx)) { + if (g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx][0] != '\0') + lcdDrawSizedText(x, y, g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], effectiveLen(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], PXX2_LEN_RX_NAME), flags); + else + lcdDrawText(x, y, "---", flags); + } +#if defined(HARDWARE_INTERNAL_MODULE) + else if (moduleIdx == INTERNAL_MODULE) { + lcdDrawText(x, y, "Internal", flags); + } +#endif + else { + lcdDrawText(x, y, "External", flags); + } +} diff --git a/radio/src/gui/480x272/widgets.h b/radio/src/gui/480x272/widgets.h index ebd7363b3..411fecdea 100644 --- a/radio/src/gui/480x272/widgets.h +++ b/radio/src/gui/480x272/widgets.h @@ -76,4 +76,6 @@ void drawTopBar(); void drawMainPots(); void drawTrims(uint8_t flightMode); +void drawReceiverName(coord_t x, coord_t y, uint8_t moduleIdx, uint8_t receiverIdx, LcdFlags flags); + #endif // _WIDGETS_H_ diff --git a/radio/src/gui/CMakeLists.txt b/radio/src/gui/CMakeLists.txt index 0e42d74ec..48d14adad 100644 --- a/radio/src/gui/CMakeLists.txt +++ b/radio/src/gui/CMakeLists.txt @@ -5,6 +5,7 @@ set(SRC ${SRC} gui/navigation/common.cpp gui/navigation/navigation_${NAVIGATION_TYPE}.cpp + gui/screenshot.cpp ) string(TOUPPER ${NAVIGATION_TYPE} NAVIGATION_TYPE) diff --git a/radio/src/gui/common/stdlcd/model_module_options.cpp b/radio/src/gui/common/stdlcd/model_module_options.cpp index a4181ac15..858e357a4 100644 --- a/radio/src/gui/common/stdlcd/model_module_options.cpp +++ b/radio/src/gui/common/stdlcd/model_module_options.cpp @@ -18,7 +18,7 @@ * GNU General Public License for more details. */ -#include +#include "opentx.h" #include #define RECEIVER_OPTIONS_2ND_COLUMN (11*FW) diff --git a/radio/src/gui/common/stdlcd/model_setup_pxx1.cpp b/radio/src/gui/common/stdlcd/model_setup_pxx1.cpp index f0e027a98..aaa1a9b1c 100644 --- a/radio/src/gui/common/stdlcd/model_setup_pxx1.cpp +++ b/radio/src/gui/common/stdlcd/model_setup_pxx1.cpp @@ -75,7 +75,6 @@ void startBindMenu(uint8_t moduleIdx) if (isTelemAllowedOnBind(moduleIdx) && g_model.moduleData[moduleIdx].pxx.receiver_telem_off) selection += 1; - POPUP_MENU_SELECT_ITEM(selection); POPUP_MENU_START(onBindMenu); } diff --git a/radio/src/gui/common/stdlcd/model_setup_pxx2.cpp b/radio/src/gui/common/stdlcd/model_setup_pxx2.cpp index 2c537d242..77c63ebb9 100644 --- a/radio/src/gui/common/stdlcd/model_setup_pxx2.cpp +++ b/radio/src/gui/common/stdlcd/model_setup_pxx2.cpp @@ -20,35 +20,6 @@ #include "opentx.h" -bool isPXX2ReceiverUsed(uint8_t moduleIdx, uint8_t receiverIdx) -{ - return g_model.moduleData[moduleIdx].pxx2.receivers & (1 << receiverIdx); -} - -void setPXX2ReceiverUsed(uint8_t moduleIdx, uint8_t receiverIdx) -{ - g_model.moduleData[moduleIdx].pxx2.receivers |= (1 << receiverIdx); -} - -bool isPXX2ReceiverEmpty(uint8_t moduleIdx, uint8_t receiverIdx) -{ - return is_memclear(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], PXX2_LEN_RX_NAME); -} - -void removePXX2Receiver(uint8_t moduleIdx, uint8_t receiverIdx) -{ - memclear(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], PXX2_LEN_RX_NAME); - g_model.moduleData[moduleIdx].pxx2.receivers &= ~(1 << receiverIdx); - storageDirty(EE_MODEL); -} - -void removePXX2ReceiverIfEmpty(uint8_t moduleIdx, uint8_t receiverIdx) -{ - if (isPXX2ReceiverEmpty(moduleIdx, receiverIdx)) { - removePXX2Receiver(moduleIdx, receiverIdx); - } -} - void onPXX2R9MBindModeMenu(const char * result) { if (result == STR_16CH_WITH_TELEMETRY) { @@ -68,6 +39,7 @@ void onPXX2R9MBindModeMenu(const char * result) uint8_t moduleIdx = CURRENT_MODULE_EDITED(menuVerticalPosition - HEADER_LINE); uint8_t receiverIdx = CURRENT_RECEIVER_EDITED(menuVerticalPosition - HEADER_LINE); moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; + reusableBuffer.moduleSetup.bindInformation.step = 0; removePXX2ReceiverIfEmpty(moduleIdx, receiverIdx); return; } @@ -279,8 +251,7 @@ void modelSetupModulePxx2ReceiverLine(uint8_t moduleIdx, uint8_t receiverIdx, co if (!isPXX2ReceiverUsed(moduleIdx, receiverIdx)) { lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_MODULE_BIND, attr); - if (attr && s_editMode > 0) { - killEvents(event); + if (attr && event == EVT_KEY_BREAK(KEY_ENTER)) { setPXX2ReceiverUsed(moduleIdx, receiverIdx); memclear(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], PXX2_LEN_RX_NAME); onPXX2ReceiverMenu(STR_BIND); @@ -341,8 +312,7 @@ void modelSetupModulePxx2ReceiverLine(uint8_t moduleIdx, uint8_t receiverIdx, co } } - if (attr && EVT_KEY_MASK(event) == KEY_ENTER) { - killEvents(event); + if (attr && event == EVT_KEY_BREAK(KEY_ENTER)) { POPUP_MENU_ADD_ITEM(STR_BIND); POPUP_MENU_ADD_ITEM(STR_OPTIONS); POPUP_MENU_ADD_ITEM(STR_SHARE); diff --git a/radio/src/gui/common/stdlcd/radio_hardware.cpp b/radio/src/gui/common/stdlcd/radio_hardware.cpp index ba91fefce..326affd5a 100644 --- a/radio/src/gui/common/stdlcd/radio_hardware.cpp +++ b/radio/src/gui/common/stdlcd/radio_hardware.cpp @@ -581,7 +581,7 @@ void menuRadioHardware(event_t event) lcdDrawTextAlignedLeft(y, STR_DEBUG); lcdDrawText(HW_SETTINGS_COLUMN2, y, STR_ANALOGS_BTN, menuHorizontalPosition == 0 ? attr : 0); lcdDrawText(lcdLastRightPos + 2, y, STR_KEYS_BTN, menuHorizontalPosition == 1 ? attr : 0); - if (attr && event == EVT_KEY_FIRST(KEY_ENTER)) { + if (attr && event == EVT_KEY_BREAK(KEY_ENTER)) { if (menuHorizontalPosition == 0) pushMenu(menuRadioDiagAnalogs); else @@ -591,7 +591,7 @@ void menuRadioHardware(event_t event) case ITEM_RADIO_BACKUP_EEPROM: lcdDrawText(LCD_W / 2, y, BUTTON(STR_EEBACKUP), attr | CENTERED); - if (attr && event == EVT_KEY_FIRST(KEY_ENTER)) { + if (attr && event == EVT_KEY_BREAK(KEY_ENTER)) { s_editMode = EDIT_SELECT_FIELD; eepromBackup(); } @@ -599,7 +599,7 @@ void menuRadioHardware(event_t event) case ITEM_RADIO_FACTORY_RESET: lcdDrawText(LCD_W / 2, y, BUTTON(STR_FACTORYRESET), attr | CENTERED); - if (attr && event == EVT_KEY_FIRST(KEY_ENTER)) { + if (attr && event == EVT_KEY_BREAK(KEY_ENTER)) { s_editMode = EDIT_SELECT_FIELD; POPUP_CONFIRMATION(STR_CONFIRMRESET, onFactoryResetConfirm); } diff --git a/radio/src/gui/common/stdlcd/radio_power_meter.cpp b/radio/src/gui/common/stdlcd/radio_power_meter.cpp index 673f671e1..589da52f0 100644 --- a/radio/src/gui/common/stdlcd/radio_power_meter.cpp +++ b/radio/src/gui/common/stdlcd/radio_power_meter.cpp @@ -18,7 +18,6 @@ * GNU General Public License for more details. */ -#include #include "opentx.h" extern uint8_t g_moduleIdx; diff --git a/radio/src/gui/common/stdlcd/radio_version.cpp b/radio/src/gui/common/stdlcd/radio_version.cpp index 2d7ffe4ce..ce6e30e59 100644 --- a/radio/src/gui/common/stdlcd/radio_version.cpp +++ b/radio/src/gui/common/stdlcd/radio_version.cpp @@ -33,8 +33,9 @@ #define MENU_BODY_TOP (FH + 1) #define MENU_BODY_BOTTOM (LCD_H) +#if defined(PXX2) constexpr uint8_t COLUMN2_X = 10 * FW; - +#endif void menuRadioFirmwareOptions(event_t event) { @@ -240,13 +241,15 @@ void menuRadioVersion(event_t event) #if defined(COPROCESSOR) lcdDrawText(FW, y, "COPR\037\033: ", SMLSIZE); - if (Coproc_valid == 1) - lcdDrawNumber(lcdNextPos, y, Coproc_read, SMLSIZE); + if (coprocData.valid == 1) + lcdDrawNumber(lcdNextPos, y, coprocData.read, SMLSIZE); else lcdDrawText(lcdNextPos, y, "---", SMLSIZE); y += FH - 1; #endif + y += 2; + #if defined(PCBTARANIS) || defined(PCBHORUS) lcdDrawText(INDENT_WIDTH, y, BUTTON(TR_FIRMWARE_OPTIONS), menuVerticalPosition == ITEM_RADIO_FIRMWARE_OPTIONS ? INVERS : 0); y += FH; @@ -255,6 +258,7 @@ void menuRadioVersion(event_t event) pushMenu(menuRadioFirmwareOptions); } #endif + #if defined(PXX2) lcdDrawText(INDENT_WIDTH, y, BUTTON(TR_MODULES_RX_VERSION), menuVerticalPosition == ITEM_RADIO_MODULES_VERSION ? INVERS : 0); y += FH; diff --git a/radio/src/gui/gui_common.cpp b/radio/src/gui/gui_common.cpp index da8bea59e..b87431be4 100644 --- a/radio/src/gui/gui_common.cpp +++ b/radio/src/gui/gui_common.cpp @@ -233,12 +233,10 @@ bool isSourceAvailableInCustomSwitches(int source) { bool result = isSourceAvailable(source); -#if defined(TELEMETRY_FRSKY) if (result && source >= MIXSRC_FIRST_TELEM && source <= MIXSRC_LAST_TELEM) { div_t qr = div(source - MIXSRC_FIRST_TELEM, 3); result = isTelemetryFieldComparisonAvailable(qr.quot); } -#endif return result; } @@ -617,7 +615,7 @@ bool isExternalModuleAvailable(int moduleType) if (moduleType == MODULE_TYPE_ISRM_PXX2) return false; // doesn't exist for now -#if !defined(PXX2) +#if !defined(PXX2) || !defined(EXTMODULE_USART) if (moduleType == MODULE_TYPE_XJT_LITE_PXX2 || moduleType == MODULE_TYPE_R9M_PXX2 || moduleType == MODULE_TYPE_R9M_LITE_PXX2 || moduleType == MODULE_TYPE_R9M_LITE_PRO_PXX2) { return false; } diff --git a/radio/src/gui/gui_common.h b/radio/src/gui/gui_common.h index 26367e882..3b63077da 100644 --- a/radio/src/gui/gui_common.h +++ b/radio/src/gui/gui_common.h @@ -39,7 +39,7 @@ typedef bool (*IsValueAvailable)(int); -int circularIncDec(int current, int inc, int min, int max, IsValueAvailable isValueAvailable=NULL); +int circularIncDec(int current, int inc, int min, int max, IsValueAvailable isValueAvailable=nullptr); int getFirstAvailable(int min, int max, IsValueAvailable isValueAvailable); bool isTrimModeAvailable(int mode); @@ -108,7 +108,7 @@ void drawSourceValue(coord_t x, coord_t y, source_t channel, LcdFlags flags=0); void drawCurve(coord_t offset=0); #if defined(COLORLCD) -void drawStringWithIndex(coord_t x, coord_t y, const char * str, int idx, LcdFlags flags=0, const char * prefix=NULL, const char * suffix=NULL); +void drawStringWithIndex(coord_t x, coord_t y, const char * str, int idx, LcdFlags flags=0, const char * prefix=nullptr, const char * suffix=nullptr); int editChoice(coord_t x, coord_t y, const char * values, int value, int min, int max, LcdFlags flags, event_t event); uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, LcdFlags flags, event_t event); swsrc_t editSwitch(coord_t x, coord_t y, swsrc_t value, LcdFlags flags, event_t event); @@ -163,4 +163,6 @@ inline uint8_t MULTIMODULE_RFPROTO_COLUMNS(uint8_t moduleIdx) void editStickHardwareSettings(coord_t x, coord_t y, int idx, event_t event, LcdFlags flags); +const char * writeScreenshot(); + #endif // _GUI_COMMON_H_ diff --git a/radio/src/gui/navigation/navigation_9x.cpp b/radio/src/gui/navigation/navigation_9x.cpp index 9e2eb5f6b..bbc958c63 100644 --- a/radio/src/gui/navigation/navigation_9x.cpp +++ b/radio/src/gui/navigation/navigation_9x.cpp @@ -242,8 +242,7 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t } - switch (event) - { + switch (event) { case EVT_ENTRY: menuEntryTime = get_tmr10ms(); l_posVert = 0; @@ -271,7 +270,7 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t case EVT_KEY_FIRST(KEY_ENTER): if (!menuTab || l_posVert>0) { if (READ_ONLY_UNLOCKED()) { - s_editMode = (s_editMode<=0); + s_editMode = (s_editMode <= 0); } } break; @@ -287,6 +286,7 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t } // no break #endif + case EVT_KEY_LONG(KEY_EXIT): s_editMode = 0; // TODO needed? we call ENTRY_UP after which does the same popMenu(); diff --git a/radio/src/gui/navigation/navigation_x7.cpp b/radio/src/gui/navigation/navigation_x7.cpp index 09e460d0c..d4b2b1f1b 100644 --- a/radio/src/gui/navigation/navigation_x7.cpp +++ b/radio/src/gui/navigation/navigation_x7.cpp @@ -262,7 +262,8 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc * menuTab, uint8_t break; case EVT_ROTARY_BREAK: - if (s_editMode > 1) break; + if (s_editMode > 1) + break; if (menuHorizontalPosition < 0 && maxcol > 0 && READ_ONLY_UNLOCKED()) { l_posHorz = 0; AUDIO_KEY_PRESS(); diff --git a/radio/src/gui/navigation/navigation_x9d.cpp b/radio/src/gui/navigation/navigation_x9d.cpp index 405e4a26d..0018ad063 100644 --- a/radio/src/gui/navigation/navigation_x9d.cpp +++ b/radio/src/gui/navigation/navigation_x9d.cpp @@ -373,7 +373,8 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t break; case EVT_KEY_BREAK(KEY_ENTER): - if (s_editMode > 1) break; + if (s_editMode > 1) + break; if (menuHorizontalPosition < 0 && maxcol > 0 && READ_ONLY_UNLOCKED()) { l_posHorz = 0; AUDIO_KEY_PRESS(); diff --git a/radio/src/gui/navigation/navigation_xlite.cpp b/radio/src/gui/navigation/navigation_xlite.cpp index 6513b35bb..9cbafda8b 100644 --- a/radio/src/gui/navigation/navigation_xlite.cpp +++ b/radio/src/gui/navigation/navigation_xlite.cpp @@ -145,7 +145,7 @@ int checkIncDec(event_t event, int val, int i_min, int i_max, unsigned int i_fla } } - if (!READ_ONLY() && i_min==0 && i_max==1 && (event==EVT_KEY_BREAK(KEY_ENTER))) { + if (!READ_ONLY() && i_min == 0 && i_max == 1 && event == EVT_KEY_BREAK(KEY_ENTER)) { s_editMode = 0; newval = !val; } @@ -318,8 +318,7 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t drawScreenIndex(curr, menuTabSize, attr); } - switch (event) - { + switch (event) { case EVT_ENTRY: menuEntryTime = get_tmr10ms(); l_posVert = 0; diff --git a/radio/src/gui/screenshot.cpp b/radio/src/gui/screenshot.cpp index 36cad1364..0a0e166bf 100644 --- a/radio/src/gui/screenshot.cpp +++ b/radio/src/gui/screenshot.cpp @@ -20,9 +20,27 @@ #include "opentx.h" +constexpr uint16_t BMP_HEADERSIZE = 0x76; + +#if defined(COLORLCD) +constexpr uint8_t BMP_BITS_PER_PIXEL = 32; +#else +constexpr uint8_t BMP_BITS_PER_PIXEL = 4; +#endif + +constexpr uint32_t BMP_FILESIZE = uint32_t(BMP_HEADERSIZE + (LCD_W * LCD_H) * BMP_BITS_PER_PIXEL / 8); + const uint8_t BMP_HEADER[] = { - 0x42, 0x4d, 0xF8, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x28, 0x00, - 0x00, 0x00, LCD_W, 0x00, 0x00, 0x00, LCD_H, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, + 'B', 'M', + /* file size */ BMP_FILESIZE & 0xFF, (BMP_FILESIZE >> 8) & 0xFF, (BMP_FILESIZE >> 16) & 0xFF, (BMP_FILESIZE >> 24) & 0xFF, + 0x00, 0x00, 0x00, 0x00, + /* header size */ BMP_HEADERSIZE, 0x00, 0x00, 0x00, + /* extra header size */ 0x28, 0x00, 0x00, 0x00, + /* width */ LCD_W & 0xFF, LCD_W >> 8, 0x00, 0x00, + /* height */ LCD_H & 0xFF, LCD_H >> 8, 0x00, 0x00, + /* planes */ 0x01, 0x00, + /* depth */ BMP_BITS_PER_PIXEL, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0xbc, 0x38, 0x00, 0x00, 0xbc, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0xee, 0xee, 0xee, 0x00, 0xdd, 0xdd, 0xdd, 0x00, 0xcc, 0xcc, 0xcc, 0x00, 0xbb, 0xbb, 0xbb, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x99, 0x99, @@ -59,18 +77,30 @@ const char * writeScreenshot() return SDCARD_ERROR(result); } - for (int y=LCD_H-1; y>=0; y-=1) { - for (int x=0; x<8*((LCD_W+7)/8); x+=2) { - uint8_t byte = getPixel(x+1, y) + (getPixel(x, y) << 4); - f_write(&bmpFile, &byte, 1, &written); - if (result != FR_OK || written != 1) { +#if defined(COLORLCD) + for (int y = LCD_H - 1; y >= 0; y--) { + for (int x = 0; x < LCD_W; x++) { + display_t pixel = *lcd->getPixelPtr(x, y); + uint32_t dst = (0xFF << 24) + (GET_RED(pixel) << 16) + (GET_GREEN(pixel) << 8) + (GET_BLUE(pixel) << 0); + if (f_write(&bmpFile, &dst, sizeof(dst), &written) != FR_OK || written != sizeof(dst)) { f_close(&bmpFile); return SDCARD_ERROR(result); } } } +#else + for (int y=LCD_H-1; y>=0; y-=1) { + for (int x=0; x<8*((LCD_W+7)/8); x+=2) { + display_t byte = getPixel(x+1, y) + (getPixel(x, y) << 4); + if (f_write(&bmpFile, &byte, 1, &written) != FR_OK || written != 1) { + f_close(&bmpFile); + return SDCARD_ERROR(result); + } + } + } +#endif f_close(&bmpFile); - return NULL; + return nullptr; } diff --git a/radio/src/helpers.h b/radio/src/helpers.h new file mode 100644 index 000000000..baef4cdce --- /dev/null +++ b/radio/src/helpers.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _HELPERS_H_ +#define _HELPERS_H_ + +template inline t min(t a, t b) { return a inline t max(t a, t b) { return a>b?a:b; } +template inline t sgn(t a) { return a>0 ? 1 : (a < 0 ? -1 : 0); } +template inline t limit(t mi, t x, t ma) { return min(max(mi,x),ma); } +template inline void SWAP(t & a, t & b) { t tmp = b; b = a; a = tmp; } + +#endif // _HELPERS_H_ diff --git a/radio/src/io/frsky_firmware_update.cpp b/radio/src/io/frsky_firmware_update.cpp index 1e793c4b3..8baeacb72 100644 --- a/radio/src/io/frsky_firmware_update.cpp +++ b/radio/src/io/frsky_firmware_update.cpp @@ -96,28 +96,6 @@ void FrskyDeviceFirmwareUpdate::processFrame(const uint8_t * frame) } } -void FrskyDeviceFirmwareUpdate::startup() -{ - switch(module) { -#if defined(INTMODULE_USART) - case INTERNAL_MODULE: - intmoduleSerialStart(INTMODULE_FLASH_BAUDRATE, true); - break; -#endif - - default: - telemetryInit(PROTOCOL_TELEMETRY_FRSKY_SPORT); - break; - } - - if (module == INTERNAL_MODULE) - INTERNAL_MODULE_ON(); - else if (module == EXTERNAL_MODULE) - EXTERNAL_MODULE_ON(); - else - SPORT_UPDATE_POWER_ON(); -} - bool FrskyDeviceFirmwareUpdate::readBuffer(uint8_t * buffer, uint8_t count, uint32_t timeout) { watchdogSuspend(timeout); @@ -310,10 +288,11 @@ const char * FrskyDeviceFirmwareUpdate::sendReqVersion() return "Version request failed"; } -const char * FrskyDeviceFirmwareUpdate::uploadFile(const char * filename) +const char * FrskyDeviceFirmwareUpdate::doFlashFirmware(const char * filename) { FIL file; - uint32_t buffer[1024 / sizeof(uint32_t)]; + const char * result; + FrSkyFirmwareInformation information; UINT count; if (f_open(&file, filename, FA_READ) != FR_OK) { @@ -322,14 +301,57 @@ const char * FrskyDeviceFirmwareUpdate::uploadFile(const char * filename) const char * ext = getFileExtension(filename); if (ext && !strcasecmp(ext, UPDATE_FIRMWARE_EXT)) { - // FrSkyFirmwareInformation * information = (FrSkyFirmwareInformation *) buffer; - if (f_read(&file, buffer, sizeof(FrSkyFirmwareInformation), &count) != FR_OK || count != sizeof(FrSkyFirmwareInformation)) { + if (f_read(&file, &information, sizeof(FrSkyFirmwareInformation), &count) != FR_OK || count != sizeof(FrSkyFirmwareInformation)) { f_close(&file); return "Format error"; } + } else { +#if defined(PCBHORUS) + information.productId = FIRMWARE_ID_XJT; +#endif } #if defined(PCBHORUS) + if (module == INTERNAL_MODULE && information.productId == FIRMWARE_ID_XJT) { + INTERNAL_MODULE_ON(); + intmoduleSerialStart(38400, true); + GPIO_SetBits(INTMODULE_BOOTCMD_GPIO, INTMODULE_BOOTCMD_GPIO_PIN); + result = uploadFileToHorusXJT(filename, &file); + GPIO_ResetBits(INTMODULE_BOOTCMD_GPIO, INTMODULE_BOOTCMD_GPIO_PIN); + f_close(&file); + return result; + } +#endif + + switch (module) { +#if defined(INTMODULE_USART) + case INTERNAL_MODULE: + intmoduleSerialStart(57600, true); + break; +#endif + + default: + telemetryInit(PROTOCOL_TELEMETRY_FRSKY_SPORT); + break; + } + + if (module == INTERNAL_MODULE) + INTERNAL_MODULE_ON(); + else if (module == EXTERNAL_MODULE) + EXTERNAL_MODULE_ON(); + else + SPORT_UPDATE_POWER_ON(); + + result = uploadFileNormal(filename, &file); + f_close(&file); + return result; +} + +#if defined(PCBHORUS) +const char * FrskyDeviceFirmwareUpdate::uploadFileToHorusXJT(const char * filename, FIL * file) +{ + uint32_t buffer[1024 / sizeof(uint32_t)]; + UINT count; uint8_t frame[8]; if (!readBuffer(frame, 8, 100) || frame[0] != 0x01) { @@ -347,11 +369,10 @@ const char * FrskyDeviceFirmwareUpdate::uploadFile(const char * filename) readBuffer(frame, 1, 100); uint8_t index = 0; - while (1) { - drawProgressScreen(getBasename(filename), STR_WRITING, file.fptr, file.obj.objsize); + while (true) { + drawProgressScreen(getBasename(filename), STR_WRITING, file->fptr, file->obj.objsize); - if (f_read(&file, buffer, 1024, &count) != FR_OK) { - f_close(&file); + if (f_read(file, buffer, 1024, &count) != FR_OK) { return "Error reading file"; } @@ -362,7 +383,6 @@ const char * FrskyDeviceFirmwareUpdate::uploadFile(const char * filename) return "Wrong request"; if (count == 0) { - f_close(&file); intmoduleSendByte(0xA1); RTOS_WAIT_MS(50); return nullptr; @@ -375,7 +395,7 @@ const char * FrskyDeviceFirmwareUpdate::uploadFile(const char * filename) intmoduleSendByte(frame[1]); uint16_t crc_16 = crc16(CRC_1189, (uint8_t *)buffer, 1024, crc16(CRC_1189, &frame[1], 1)); - for (unsigned i = 0; i < sizeof(buffer); i++) { + for (size_t i = 0; i < sizeof(buffer); i++) { intmoduleSendByte(((uint8_t *)buffer)[i]); } intmoduleSendByte(crc_16 >> 8); @@ -383,7 +403,22 @@ const char * FrskyDeviceFirmwareUpdate::uploadFile(const char * filename) index++; } -#else +} +#endif + +const char * FrskyDeviceFirmwareUpdate::uploadFileNormal(const char * filename, FIL * file) +{ + uint32_t buffer[1024 / sizeof(uint32_t)]; + UINT count; + + const char * result = sendPowerOn(); + if (result) + return result; + + result = sendReqVersion(); + if (result) + return result; + RTOS_WAIT_MS(200); telemetryClearFifo(); @@ -391,9 +426,8 @@ const char * FrskyDeviceFirmwareUpdate::uploadFile(const char * filename) startFrame(PRIM_CMD_DOWNLOAD); sendFrame(); - while (1) { - if (f_read(&file, buffer, 1024, &count) != FR_OK) { - f_close(&file); + while (true) { + if (f_read(file, buffer, 1024, &count) != FR_OK) { return "Error reading file"; } @@ -410,16 +444,16 @@ const char * FrskyDeviceFirmwareUpdate::uploadFile(const char * filename) state = SPORT_DATA_TRANSFER, sendFrame(); if (i == 0) { - drawProgressScreen(getBasename(filename), STR_WRITING, file.fptr, file.obj.objsize); + drawProgressScreen(getBasename(filename), STR_WRITING, file->fptr, file->obj.objsize); } } if (count < 256) { - f_close(&file); - return nullptr; + break; } } -#endif + + return endTransfer(); } const char * FrskyDeviceFirmwareUpdate::endTransfer() @@ -434,28 +468,6 @@ const char * FrskyDeviceFirmwareUpdate::endTransfer() return nullptr; } -const char * FrskyDeviceFirmwareUpdate::doFlashFirmware(const char * filename) -{ - const char * result; - -#if defined(PCBHORUS) - if (module == INTERNAL_MODULE) { - intmoduleSerialStart(38400, true); - GPIO_SetBits(INTMODULE_BOOTCMD_GPIO, INTMODULE_BOOTCMD_GPIO_PIN); - result = uploadFile(filename); - GPIO_ResetBits(INTMODULE_BOOTCMD_GPIO, INTMODULE_BOOTCMD_GPIO_PIN); - return result; - } -#endif - - result = sendPowerOn(); - if (!result) result = sendReqVersion(); - if (!result) result = uploadFile(filename); - if (!result) result = endTransfer(); - - return result; -} - const char * FrskyDeviceFirmwareUpdate::flashFirmware(const char * filename) { pausePulses(); @@ -476,8 +488,6 @@ const char * FrskyDeviceFirmwareUpdate::flashFirmware(const char * filename) watchdogSuspend(2000); RTOS_WAIT_MS(2000); - startup(); - const char * result = doFlashFirmware(filename); AUDIO_PLAY(AU_SPECIAL_SOUND_BEEP1 ); diff --git a/radio/src/io/frsky_firmware_update.h b/radio/src/io/frsky_firmware_update.h index e23b5cb98..9d3dcc820 100644 --- a/radio/src/io/frsky_firmware_update.h +++ b/radio/src/io/frsky_firmware_update.h @@ -24,6 +24,7 @@ #include "dataconstants.h" #include "definitions.h" #include "frsky_pxx2.h" +#include "ff.h" enum FrskyFirmwareProductFamily { FIRMWARE_FAMILY_INTERNAL_MODULE, @@ -34,6 +35,12 @@ enum FrskyFirmwareProductFamily { FIRMWARE_FAMILY_POWER_MANAGEMENT_UNIT, }; +enum FrskyFirmwareProductId { + FIRMWARE_ID_NONE, + FIRMWARE_ID_XJT = 0x01, + FIRMWARE_ID_ISRM = 0x02, +}; + PACK(struct FrSkyFirmwareInformation { uint32_t fourcc; uint8_t headerVersion; @@ -74,8 +81,6 @@ class FrskyDeviceFirmwareUpdate { ModuleIndex module; uint8_t frame[12]; - void startup(); - void startFrame(uint8_t command); void sendFrame(); @@ -89,7 +94,8 @@ class FrskyDeviceFirmwareUpdate { const char * doFlashFirmware(const char * filename); const char * sendPowerOn(); const char * sendReqVersion(); - const char * uploadFile(const char * filename); + const char * uploadFileNormal(const char * filename, FIL * file); + const char * uploadFileToHorusXJT(const char * filename, FIL * file); const char * endTransfer(); }; diff --git a/radio/src/io/frsky_sport.h b/radio/src/io/frsky_sport.h index dd648a811..10a72af96 100644 --- a/radio/src/io/frsky_sport.h +++ b/radio/src/io/frsky_sport.h @@ -23,7 +23,6 @@ #include "dataconstants.h" -#if defined(TELEMETRY_FRSKY_SPORT) PACK(union SportTelemetryPacket { struct { @@ -34,7 +33,6 @@ PACK(union SportTelemetryPacket }; uint8_t raw[8]; }); -#endif #if defined(STM32) bool isBootloader(const char * filename); diff --git a/radio/src/logs.cpp b/radio/src/logs.cpp index 822f5e7b4..2ada6d7fd 100644 --- a/radio/src/logs.cpp +++ b/radio/src/logs.cpp @@ -134,7 +134,6 @@ void writeHeader() f_puts("Time,", &g_oLogFile); #endif -#if defined(TELEMETRY_FRSKY) char label[TELEM_LABEL_LEN+7]; for (int i=0; i inline t min(t a, t b) { return a inline t max(t a, t b) { return a>b?a:b; } -template inline t sgn(t a) { return a>0 ? 1 : (a < 0 ? -1 : 0); } -template inline t limit(t mi, t x, t ma) { return min(max(mi,x),ma); } -template inline void SWAP(t & a, t & b) { t tmp = b; b = a; a = tmp; } - uint16_t isqrt32(uint32_t n); #if defined(BOOT) @@ -1238,13 +1224,8 @@ char * strcat_zchar(char *dest, const char *name, uint8_t size, const char *defa // Stick tolerance varies between transmitters, Higher is better #define STICK_TOLERANCE 64 -#if defined(TELEMETRY_FRSKY) ls_telemetry_value_t minTelemValue(source_t channel); ls_telemetry_value_t maxTelemValue(source_t channel); -#else - #define minTelemValue(channel) 255 - #define maxTelemValue(channel) 255 -#endif getvalue_t convert16bitsTelemValue(source_t channel, ls_telemetry_value_t value); getvalue_t convertLswTelemValue(LogicalSwitchData * cs); @@ -1277,7 +1258,6 @@ inline bool IS_TXBATT_WARNING() return g_vbat100mV <= g_eeGeneral.vBatWarn; } -#if defined(TELEMETRY_FRSKY) enum TelemetryViews { TELEMETRY_CUSTOM_SCREEN_1, TELEMETRY_CUSTOM_SCREEN_2, @@ -1287,7 +1267,6 @@ enum TelemetryViews { }; extern uint8_t s_frsky_view; -#endif constexpr uint32_t EARTH_RADIUS = 6371009; diff --git a/radio/src/pulses/modules_helpers.h b/radio/src/pulses/modules_helpers.h index ae5d36849..15df24165 100644 --- a/radio/src/pulses/modules_helpers.h +++ b/radio/src/pulses/modules_helpers.h @@ -18,11 +18,12 @@ * GNU General Public License for more details. */ -#ifndef _MODULES_H_ -#define _MODULES_H_ +#ifndef _MODULES_HELPERS_H_ +#define _MODULES_HELPERS_H_ #include "bitfield.h" #include "definitions.h" +#include "helpers.h" #include "telemetry/telemetry.h" #if defined(MULTIMODULE) #include "telemetry/multi.h" @@ -121,19 +122,15 @@ inline bool isExtraModule(uint8_t) } #endif -#if defined(INTERNAL_MODULE_PPM) +inline bool isModuleTypePPM(uint8_t type) +{ + return type == MODULE_TYPE_PPM; +} + inline bool isModulePPM(uint8_t idx) { - return (idx == INTERNAL_MODULE && g_model.moduleData[INTERNAL_MODULE].type == MODULE_TYPE_PPM) || - (idx == EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM); + return isModuleTypePPM(g_model.moduleData[idx].type); } -#else -inline bool isModulePPM(uint8_t idx) -{ - return isExtraModule(idx) || - (idx == EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM); -} -#endif inline bool isModuleTypeR9MNonAccess(uint8_t type) { @@ -248,29 +245,15 @@ inline bool isModuleRFAccess(uint8_t idx) } } -#if defined(DSM2) -inline bool isModuleDSM2(uint8_t idx) +inline bool isModuleDSM2(uint8_t moduleIdx) { - return idx == EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_DSM2; + return g_model.moduleData[moduleIdx].type == MODULE_TYPE_DSM2; } -#else -inline bool isModuleDSM2(uint8_t idx) -{ - return false; -} -#endif -#if defined(SBUS) -inline bool isModuleSBUS(uint8_t idx) +inline bool isModuleSBUS(uint8_t moduleIdx) { - return idx == EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_SBUS; + return g_model.moduleData[moduleIdx].type == MODULE_TYPE_SBUS; } -#else -inline bool isModuleSBUS(uint8_t idx) -{ - return false; -} -#endif // order is the same as in enum Protocols in myeeprom.h (none, ppm, pxx, pxx2, dsm, crossfire, multi, r9m, r9m2, sbus) static const int8_t maxChannelsModules[] = { 0, 8, 8, 16, -2, 8, 4, 8, 16, 8}; // relative to 8! @@ -449,4 +432,51 @@ inline bool isTelemAllowedOnBind(uint8_t moduleIndex) return true; } -#endif // _MODULES_H_ + +inline bool isPXX2ReceiverUsed(uint8_t moduleIdx, uint8_t receiverIdx) +{ + return g_model.moduleData[moduleIdx].pxx2.receivers & (1 << receiverIdx); +} + +inline void setPXX2ReceiverUsed(uint8_t moduleIdx, uint8_t receiverIdx) +{ + g_model.moduleData[moduleIdx].pxx2.receivers |= (1 << receiverIdx); +} + +inline bool isPXX2ReceiverEmpty(uint8_t moduleIdx, uint8_t receiverIdx) +{ + return is_memclear(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], PXX2_LEN_RX_NAME); +} + +inline void removePXX2Receiver(uint8_t moduleIdx, uint8_t receiverIdx) +{ + memclear(g_model.moduleData[moduleIdx].pxx2.receiverName[receiverIdx], PXX2_LEN_RX_NAME); + g_model.moduleData[moduleIdx].pxx2.receivers &= ~(1 << receiverIdx); + storageDirty(EE_MODEL); +} + +inline void removePXX2ReceiverIfEmpty(uint8_t moduleIdx, uint8_t receiverIdx) +{ + if (isPXX2ReceiverEmpty(moduleIdx, receiverIdx)) { + removePXX2Receiver(moduleIdx, receiverIdx); + } +} + +inline void setDefaultPpmFrameLength(uint8_t moduleIdx) +{ + g_model.moduleData[moduleIdx].ppm.frameLength = 4 * max(0, g_model.moduleData[moduleIdx].channelsCount); +} + +inline void setModuleType(uint8_t moduleIdx, uint8_t moduleType) +{ + ModuleData & moduleData = g_model.moduleData[moduleIdx]; + memclear(&moduleData, sizeof(ModuleData)); + moduleData.type = moduleType; + moduleData.channelsCount = defaultModuleChannels_M8(moduleIdx); + if (moduleData.type == MODULE_TYPE_SBUS) + moduleData.sbus.refreshRate = -31; + else if (moduleData.type == MODULE_TYPE_PPM) + setDefaultPpmFrameLength(moduleIdx); +} + +#endif // _MODULES_HELPERS_H_ diff --git a/radio/src/pulses/pulses.cpp b/radio/src/pulses/pulses.cpp index 7a8cae8ac..cec72d8a0 100755 --- a/radio/src/pulses/pulses.cpp +++ b/radio/src/pulses/pulses.cpp @@ -28,6 +28,18 @@ InternalModulePulsesData intmodulePulsesData __DMA; ExternalModulePulsesData extmodulePulsesData __DMA; TrainerPulsesData trainerPulsesData __DMA; +void ModuleState::startBind(BindInformation * destination, ModuleCallback bindCallback) +{ + bindInformation = destination; + callback = bindCallback; + mode = MODULE_MODE_BIND; +#if defined(SIMU) + bindInformation->candidateReceiversCount = 2; + strcpy(bindInformation->candidateReceiversNames[0], "SimuRX1"); + strcpy(bindInformation->candidateReceiversNames[1], "SimuRX2"); +#endif +} + uint8_t getModuleType(uint8_t module) { uint8_t type = g_model.moduleData[module].type; @@ -174,7 +186,7 @@ void enablePulsesExternalModule(uint8_t protocol) break; #endif -#if defined(PXX2) +#if defined(PXX2) && defined(EXTMODULE_USART) case PROTOCOL_CHANNELS_PXX2_HIGHSPEED: extmoduleInvertedSerialStart(PXX2_HIGHSPEED_BAUDRATE); break; @@ -338,7 +350,7 @@ void setupPulsesInternalModule(uint8_t protocol) #if defined(PCBTARANIS) && defined(INTERNAL_MODULE_PPM) case PROTOCOL_CHANNELS_PPM: - setupPulsesPPM(&extmodulePulsesData.ppm, g_model.moduleData[INTERNAL_MODULE].channelsStart, g_model.moduleData[INTERNAL_MODULE].channelsCount, g_model.moduleData[INTERNAL_MODULE].ppm.frameLength); + setupPulsesPPMInternalModule(); scheduleNextMixerCalculation(INTERNAL_MODULE, PPM_PERIOD(INTERNAL_MODULE)); break; #endif diff --git a/radio/src/pulses/pulses.h b/radio/src/pulses/pulses.h index d583157fb..87208e7b9 100644 --- a/radio/src/pulses/pulses.h +++ b/radio/src/pulses/pulses.h @@ -29,12 +29,6 @@ #include "modules_helpers.h" #include "ff.h" -#if NUM_MODULES > 1 - #define IS_RANGECHECK_ENABLE() (moduleState[0].mode == MODULE_MODE_RANGECHECK || moduleState[1].mode == MODULE_MODE_RANGECHECK) -#else - #define IS_RANGECHECK_ENABLE() (moduleState[0].mode == MODULE_MODE_RANGECHECK) -#endif - #if defined(PCBSKY9X) && defined(DSM2) #define DSM2_BIND_TIMEOUT 255 // 255*11ms extern uint8_t dsm2BindTimer; @@ -152,15 +146,6 @@ class OtaUpdateInformation: public BindInformation { typedef void (* ModuleCallback)(); -#if defined(SIMU) - #define BIND_INFO \ - bindInformation->candidateReceiversCount = 2; \ - strcpy(bindInformation->candidateReceiversNames[0], "SimuRX1"); \ - strcpy(bindInformation->candidateReceiversNames[1], "SimuRX2"); -#else - #define BIND_INFO -#endif - PACK(struct ModuleState { uint8_t protocol:4; uint8_t mode:4; @@ -176,13 +161,8 @@ PACK(struct ModuleState { }; ModuleCallback callback; - void startBind(BindInformation * destination, ModuleCallback bindCallback = nullptr) - { - bindInformation = destination; - callback = bindCallback; - mode = MODULE_MODE_BIND; - BIND_INFO; - } + void startBind(BindInformation * destination, ModuleCallback bindCallback = nullptr); + void readModuleInformation(ModuleInformation * destination, int8_t first, int8_t last) { moduleInformation = destination; @@ -409,5 +389,30 @@ inline void SEND_FAILSAFE_1S() // for channels not set previously to HOLD or NOPULSE void setCustomFailsafe(uint8_t moduleIndex); +inline bool isModuleInRangeCheckMode() +{ + if (moduleState[0].mode == MODULE_MODE_RANGECHECK) + return true; + +#if NUM_MODULES > 1 + if (moduleState[1].mode == MODULE_MODE_RANGECHECK) + return true; +#endif + + return false; +} + +inline bool isModuleInBeepMode() +{ + if (moduleState[0].mode >= MODULE_MODE_BEEP_FIRST) + return true; + +#if NUM_MODULES > 1 + if (moduleState[1].mode >= MODULE_MODE_BEEP_FIRST) + return true; +#endif + + return false; +} #endif // _PULSES_H_ diff --git a/radio/src/pulses/pxx2.h b/radio/src/pulses/pxx2.h index 49b6c1344..ed8c07418 100644 --- a/radio/src/pulses/pxx2.h +++ b/radio/src/pulses/pxx2.h @@ -119,16 +119,16 @@ static const uint8_t PXX2ModuleOptions[] = { #else 0b00000000, // None = no option available on unknown modules #endif - 0b11110001, // XJT - 0b11110001, // ISRM - 0b11111101, // ISRM-PRO - 0b11110101, // ISRM-S - 0b11110010, // R9M - 0b11110010, // R9MLite - 0b11110110, // R9MLite-PRO - 0b11110100, // ISRM-N - 0b11110100, // ISRM-S-X9 - 0b11110100, // ISRM-S-X10 + 0b00000001, // XJT + 0b00000001, // ISRM + 0b00001101, // ISRM-PRO + 0b00000101, // ISRM-S + 0b00000010, // R9M + 0b00000010, // R9MLite + 0b00000110, // R9MLite-PRO + 0b00000100, // ISRM-N + 0b00000100, // ISRM-S-X9 + 0b00000101, // ISRM-S-X10 }; inline uint8_t getPXX2ModuleOptions(uint8_t modelId) diff --git a/radio/src/sdcard.h b/radio/src/sdcard.h index 2b86198a4..d56c9f7bd 100644 --- a/radio/src/sdcard.h +++ b/radio/src/sdcard.h @@ -120,7 +120,7 @@ inline const char * SDCARD_ERROR(FRESULT result) #endif // NOTE: 'size' must = 0 or be a valid character position within 'filename' array -- it is NOT validated -const char * getFileExtension(const char * filename, uint8_t size=0, uint8_t extMaxLen=0, uint8_t *fnlen=NULL, uint8_t *extlen=NULL); +const char * getFileExtension(const char * filename, uint8_t size=0, uint8_t extMaxLen=0, uint8_t * fnlen=nullptr, uint8_t * extlen=nullptr); const char * getBasename(const char * path); #if defined(PCBX12S) @@ -133,7 +133,6 @@ const char * getBasename(const char * path); #define OTX_FOURCC 0x3B78746F // otx for Taranis X-Lite S #elif defined(PCBXLITE) #define OTX_FOURCC 0x3978746F // otx for Taranis X-Lite - #define O9X_FOURCC 0x3978396F // o9x for Taranis X-Lite #elif defined(RADIO_X7) #define OTX_FOURCC 0x3678746F // otx for Taranis X7 #elif defined(PCBX9LITE) @@ -142,15 +141,13 @@ const char * getBasename(const char * path); #define OTX_FOURCC 0x3378746F // otx for Taranis X9D #elif defined(PCBSKY9X) #define OTX_FOURCC 0x3278746F // otx for sky9x - #define O9X_FOURCC 0x3278396F // o9x for sky9x #elif defined(RADIO_T12) #define OTX_FOURCC 0x3D78746F // otx for Jumper T12 - #define O9X_FOURCC 0x3D78396F // o9x for Jumper T12 #endif bool isFileAvailable(const char * filename, bool exclDir = false); int findNextFileIndex(char * filename, uint8_t size, const char * directory); -bool isExtensionMatching(const char * extension, const char * pattern, char * match = NULL); +bool isExtensionMatching(const char * extension, const char * pattern, char * match = nullptr); const char * sdCopyFile(const char * src, const char * dest); const char * sdCopyFile(const char * srcFilename, const char * srcDir, const char * destFilename, const char * destDir); diff --git a/radio/src/simu.cpp b/radio/src/simu.cpp index 35bd87f0a..b92e16dab 100644 --- a/radio/src/simu.cpp +++ b/radio/src/simu.cpp @@ -360,8 +360,8 @@ long OpenTxSim::onTimeout(FXObject*, FXSelector, void*) { if (hasFocus()) { #if defined(COPROCESSOR) - Coproc_temp = 23; - Coproc_maxtemp = 28; + coprocData.temp = 23; + coprocData.maxtemp = 28; #endif updateKeysAndSwitches(); @@ -505,9 +505,6 @@ int main(int argc, char ** argv) opentxSim->show(); // Otherwise the main window gets centred across my two monitors, split down the middle. #endif -#if defined(TELEMETRY_FRSKY) && !defined(TELEMETRY_FRSKY_SPORT) - telemetryStreaming = 1; -#endif printf("Model size = %d\n", (int)sizeof(g_model)); diff --git a/radio/src/stamp.cpp b/radio/src/stamp.cpp index f112a97dc..85d5106a2 100644 --- a/radio/src/stamp.cpp +++ b/radio/src/stamp.cpp @@ -47,7 +47,7 @@ * Retrieves the version of the bootloader or firmware * @return */ -#if defined(STM32) +#if defined(STM32) && !defined(SIMU) __SECTION_USED(".fwversiondata") const char firmware_version[] = "opentx-" FLAVOUR "-" VERSION " (" GIT_STR ")"; __SECTION_USED(".bootversiondata") const char boot_version[] = "opentx-" FLAVOUR "-" VERSION " (" GIT_STR ")"; diff --git a/radio/src/storage/conversions/conversions.cpp b/radio/src/storage/conversions/conversions.cpp index 299d11d7a..fa97a4edf 100644 --- a/radio/src/storage/conversions/conversions.cpp +++ b/radio/src/storage/conversions/conversions.cpp @@ -21,8 +21,36 @@ #include "opentx.h" #include "conversions.h" +void convertRadioData(int version) +{ + TRACE("convertRadioData(%d)", version); + +#if EEPROM_CONVERSIONS < 217 + if (version == 216) { + version = 217; + convertRadioData_216_to_217(g_eeGeneral); + } +#endif + +#if EEPROM_CONVERSIONS < 218 + if (version == 217) { + version = 218; + convertRadioData_217_to_218(g_eeGeneral); + } +#endif + +#if EEPROM_CONVERSIONS < 219 + if (version == 218) { + version = 219; + convertRadioData_218_to_219(g_eeGeneral); + } +#endif +} + void convertModelData(int version) { + TRACE("convertModelData(%d)", version); + #if EEPROM_CONVERSIONS < 217 if (version == 216) { version = 217; diff --git a/radio/src/storage/conversions/conversions.h b/radio/src/storage/conversions/conversions.h index 7605edfe9..25960af4c 100644 --- a/radio/src/storage/conversions/conversions.h +++ b/radio/src/storage/conversions/conversions.h @@ -18,6 +18,7 @@ * GNU General Public License for more details. */ +void convertRadioData(int version); void convertModelData(int version); bool eeConvert(); diff --git a/radio/src/storage/conversions/conversions_218_219.cpp b/radio/src/storage/conversions/conversions_218_219.cpp index 618d52887..1b14213b8 100644 --- a/radio/src/storage/conversions/conversions_218_219.cpp +++ b/radio/src/storage/conversions/conversions_218_219.cpp @@ -58,6 +58,11 @@ int convertSource_218_to_219(int source) source += 2; #endif +#if defined(PCBX10) + if ((source == MIXSRC_EXT1) || (source == MIXSRC_EXT2)) + source += 2; +#endif + return source; } @@ -111,6 +116,12 @@ void convertModelData_218_to_219(ModelData &model) memcpy(&oldModel, &model, sizeof(ModelData_v218)); ModelData_v219 & newModel = (ModelData_v219 &) model; +#if defined(PCBHORUS) + // 4 bytes more for the ModelHeader::bitmap + memclear(&newModel.header.bitmap[10], 4); + memcpy(newModel.timers, oldModel.timers, offsetof(ModelData_v218, mixData) - offsetof(ModelData_v218, timers)); +#endif + memclear(newModel.mixData, sizeof(ModelData_v219) - offsetof(ModelData_v219, mixData)); char name[LEN_MODEL_NAME+1]; @@ -147,9 +158,9 @@ void convertModelData_218_to_219(ModelData &model) uint8_t cstate = lswFamily(sw.func); if (cstate == LS_FAMILY_OFS || cstate == LS_FAMILY_COMP || cstate == LS_FAMILY_DIFF) { LogicalSwitchData & sw = newModel.logicalSw[i]; - sw.v1 = convertSource_218_to_219((uint8_t)sw.v1); + sw.v1 = convertSource_218_to_219(sw.v1); if (cstate == LS_FAMILY_COMP) { - sw.v2 = convertSource_218_to_219((uint8_t)sw.v2); + sw.v2 = convertSource_218_to_219(sw.v2); } } else if (cstate == LS_FAMILY_BOOL || cstate == LS_FAMILY_STICKY) { @@ -159,6 +170,7 @@ void convertModelData_218_to_219(ModelData &model) else if (cstate == LS_FAMILY_EDGE) { sw.v1 = convertSwitch_218_to_219(sw.v1); } + sw.andsw = convertSwitch_218_to_219(sw.andsw); } for (uint8_t i=0; i 3) // 0=Thr, 1/2/3=Old 3 Pots, then Sliders + newModel.thrTraceSrc += 2; +#endif newModel.switchWarningState = oldModel.switchWarningState; #if !defined(COLORLCD) newModel.switchWarningEnable = oldModel.switchWarningEnable; @@ -279,9 +295,33 @@ void convertModelData_218_to_219(ModelData &model) #endif #if defined(PCBHORUS) -// memcpy(newModel.screenData, oldModel.screenData, -// sizeof(newModel.screenData) + -// sizeof(newModel.topbarData)) + memcpy(newModel.screenData, oldModel.screenData, + sizeof(newModel.screenData) + + sizeof(newModel.topbarData)); + + for (int screen=0; screenwidgetName)) + continue; + + ZoneOptionValue& option = zoneData->widgetData.options[0]; + option.unsignedValue = convertSource_218_to_219(option.unsignedValue); + } + } + + for (int zone=0; zonewidgetName)) + continue; + + ZoneOptionValue & option = zoneData->widgetData.options[0]; + option.unsignedValue = convertSource_218_to_219(option.unsignedValue); + } + #else newModel.screensType = oldModel.frsky.screensType; memmove(&newModel.screens, &oldModel.frsky.screens, sizeof(newModel.screens)); @@ -309,6 +349,8 @@ void convertModelData_218_to_219(ModelData &model) void convertRadioData_218_to_219(RadioData & settings) { + TRACE("Radio conversion from v218 to v219"); + settings.version = 219; settings.variant = EEPROM_VARIANT; @@ -318,13 +360,6 @@ void convertRadioData_218_to_219(RadioData & settings) memcpy(&oldSettings, &settings, sizeof(RadioData_v218)); #endif -#if defined(PCBX9D) || defined(PCBX9DP) || defined(PCBX7) || defined(PCBXLITE) - for (uint8_t i=0; i(g_eeGeneral.potsConfig, POT_WITHOUT_DETENT, 2, 2); // T12 comes with wrongly defined pot2 #endif +#if defined(PCBX9D) || defined(PCBX9DP) || defined(PCBX7) || defined(PCBXLITE) || defined(PCBHORUS) + for (uint8_t i=0; i= 2019 // force re-calibration settings.chkSum = 0xFFFF; setDefaultOwnerId(); #endif + settings.pwrOnSpeed = 0; + settings.pwrOffSpeed = 0; + #if defined(STM32) free(oldSettingsAllocated); #endif diff --git a/radio/src/storage/conversions/datastructs_218.h b/radio/src/storage/conversions/datastructs_218.h index 2a34b3255..62515cab9 100644 --- a/radio/src/storage/conversions/datastructs_218.h +++ b/radio/src/storage/conversions/datastructs_218.h @@ -532,10 +532,16 @@ PACK(struct ModelData_v218 { #define THEME_DATA #endif +#if defined(PCBHORUS) + #define NUM_CALIBRATION_INPUTS 13 +#else + #define NUM_CALIBRATION_INPUTS (NUM_STICKS+STORAGE_NUM_POTS+STORAGE_NUM_SLIDERS) +#endif + PACK(struct RadioData_v218 { uint8_t version; uint16_t variant; - CalibData calib[NUM_STICKS+STORAGE_NUM_POTS+STORAGE_NUM_SLIDERS+STORAGE_NUM_MOUSE_ANALOGS]; + CalibData calib[NUM_CALIBRATION_INPUTS]; uint16_t chkSum; N_HORUS_FIELD(int8_t currModel); N_HORUS_FIELD(uint8_t contrast); @@ -554,9 +560,9 @@ PACK(struct RadioData_v218 { int8_t timezone:5; uint8_t adjustRTC:1; uint8_t inactivityTimer; + uint8_t telemetryBaudrate:3; int8_t splashMode:3; int8_t hapticMode:2; - int8_t spare2:3; int8_t switchesDelay; uint8_t lightAutoOff; uint8_t templateSetup; // RETA order for receiver channels diff --git a/radio/src/storage/eeprom_common.cpp b/radio/src/storage/eeprom_common.cpp index 2f4aad44c..b31115e30 100644 --- a/radio/src/storage/eeprom_common.cpp +++ b/radio/src/storage/eeprom_common.cpp @@ -86,16 +86,24 @@ void eeLoadModelHeaders() } } -void storageReadRadioSettings() +void storageClearRadioSetting() { - if (!eepromOpen() || !eeLoadGeneral()) { + memclear(&g_eeGeneral, sizeof(RadioData)); +} + +void storageReadRadioSettings(bool allowConversion) +{ + if (g_eeGeneral.version != 0) + return; + + if (!eepromOpen() || !eeLoadGeneral(allowConversion)) { storageEraseAll(true); } else { eeLoadModelHeaders(); } - for (uint8_t i=0; languagePacks[i]!=NULL; i++) { + for (uint8_t i=0; languagePacks[i]; i++) { if (!strncmp(g_eeGeneral.ttsLanguage, languagePacks[i]->id, 2)) { currentLanguagePackIdx = i; currentLanguagePack = languagePacks[i]; @@ -110,7 +118,7 @@ void storageReadCurrentModel() void storageReadAll() { - storageReadRadioSettings(); + storageReadRadioSettings(true); storageReadCurrentModel(); } @@ -125,7 +133,7 @@ void storageEraseAll(bool warn) ALERT(STR_STORAGE_WARNING, STR_BAD_RADIO_DATA, AU_BAD_RADIODATA); } - RAISE_ALERT(STR_STORAGE_WARNING, STR_STORAGE_FORMAT, NULL, AU_NONE); + RAISE_ALERT(STR_STORAGE_WARNING, STR_STORAGE_FORMAT, nullptr, AU_NONE); storageFormat(); storageDirty(EE_GENERAL|EE_MODEL); diff --git a/radio/src/storage/eeprom_common.h b/radio/src/storage/eeprom_common.h index 00c840c03..bab56b07a 100644 --- a/radio/src/storage/eeprom_common.h +++ b/radio/src/storage/eeprom_common.h @@ -32,6 +32,7 @@ void selectModel(uint8_t sub); void eeLoadModelHeader(uint8_t id, ModelHeader *header); void eeLoadModelHeaders(); -void storageReadRadioSettings(); +void storageClearRadioSetting(); +void storageReadRadioSettings(bool allowConversion); void storageReadCurrentModel(); diff --git a/radio/src/storage/eeprom_raw.cpp b/radio/src/storage/eeprom_raw.cpp index 3e286ec49..1d329b1e3 100644 --- a/radio/src/storage/eeprom_raw.cpp +++ b/radio/src/storage/eeprom_raw.cpp @@ -256,13 +256,18 @@ void writeModel(int index) writeFile(index+1, (uint8_t *)&g_model, sizeof(g_model)); } -bool eeLoadGeneral() +bool eeLoadGeneral(bool allowConversion) { eeLoadGeneralSettingsData(); if (g_eeGeneral.version != EEPROM_VER) { TRACE("EEPROM version %d instead of %d", g_eeGeneral.version, EEPROM_VER); #if defined(PCBSKY9X) + if (!allowConversion) { + storageClearRadioSetting(); + return true; // prevent eeprom from being wiped + } + if (!eeConvert()) { return false; } diff --git a/radio/src/storage/eeprom_raw.h b/radio/src/storage/eeprom_raw.h index ca2b50f82..b8f63c191 100644 --- a/radio/src/storage/eeprom_raw.h +++ b/radio/src/storage/eeprom_raw.h @@ -24,8 +24,8 @@ #include #include -bool eeLoadGeneral( void ) ; -void eeDeleteModel( uint8_t id ) ; +bool eeLoadGeneral(bool allowConversion); +void eeDeleteModel( uint8_t id ); bool eeCopyModel(uint8_t dst, uint8_t src); void eeSwapModels(uint8_t id1, uint8_t id2); diff --git a/radio/src/storage/eeprom_rlc.cpp b/radio/src/storage/eeprom_rlc.cpp index 2534a544a..6c458f088 100644 --- a/radio/src/storage/eeprom_rlc.cpp +++ b/radio/src/storage/eeprom_rlc.cpp @@ -757,7 +757,7 @@ uint16_t eeLoadModelData(uint8_t index) return theFile.readRlc((uint8_t*)&g_model, sizeof(g_model)); } -bool eeLoadGeneral() +bool eeLoadGeneral(bool allowConversion) { theFile.openRlc(FILE_GENERAL); if (theFile.readRlc((uint8_t*)&g_eeGeneral, 3) == 3 && g_eeGeneral.version == EEPROM_VER) { @@ -796,6 +796,10 @@ bool eeLoadGeneral() #endif #if defined(EEPROM_CONVERSIONS) if (g_eeGeneral.version != EEPROM_VER) { + if (!allowConversion) { + storageClearRadioSetting(); + return true; // prevent eeprom from being wiped + } TRACE("EEPROM version %d instead of %d", g_eeGeneral.version, EEPROM_VER); if (!eeConvert()) { return false; diff --git a/radio/src/storage/eeprom_rlc.h b/radio/src/storage/eeprom_rlc.h index ab9d1a639..d9ad5d588 100644 --- a/radio/src/storage/eeprom_rlc.h +++ b/radio/src/storage/eeprom_rlc.h @@ -179,8 +179,8 @@ void loadRadioSettings(); void loadModel(int index, bool alarms=true); bool eepromOpen(); -void eeLoadModelName(uint8_t id, char *name); -bool eeLoadGeneral(); +void eeLoadModelName(uint8_t id, char * name); +bool eeLoadGeneral(bool allowConversion); // For EEPROM backup/restore inline bool isEepromStart(const void * buffer) diff --git a/radio/src/storage/modelslist.cpp b/radio/src/storage/modelslist.cpp index bc5ce99e3..be4a38adb 100644 --- a/radio/src/storage/modelslist.cpp +++ b/radio/src/storage/modelslist.cpp @@ -72,24 +72,33 @@ const BitmapBuffer * ModelCell::getBuffer() void ModelCell::loadBitmap() { + uint8_t version; + PACK(struct { ModelHeader header; TimerData timers[MAX_TIMERS]; }) partialmodel; const char * error = NULL; - buffer = new BitmapBuffer(BMP_RGB565, MODELCELL_WIDTH, MODELCELL_HEIGHT); - if (buffer == NULL) { - return; - } - if (strncmp(modelFilename, g_eeGeneral.currModelFilename, LEN_MODEL_FILENAME) == 0) { memcpy(&partialmodel.header, &g_model.header, sizeof(partialmodel)); } else { - error = readModel(modelFilename, (uint8_t *)&partialmodel.header, sizeof(partialmodel)); + error = readModel(modelFilename, (uint8_t *)&partialmodel.header, sizeof(partialmodel), &version); + // LEN_BITMAP_NAME has now 4 bytes more + if (version <= 218) { + memmove(partialmodel.timers, &(partialmodel.header.bitmap[10]), sizeof(TimerData)*MAX_TIMERS); + memclear(&(partialmodel.header.bitmap[10]), 4); + } } + if ((modelName[0] == 0) && ! error) + setModelName(partialmodel.header.name); // resets buffer!!! + + buffer = new BitmapBuffer(BMP_RGB565, MODELCELL_WIDTH, MODELCELL_HEIGHT); + if (buffer == NULL) { + return; + } buffer->clear(TEXT_BGCOLOR); if (error) { @@ -97,9 +106,6 @@ void ModelCell::loadBitmap() buffer->drawBitmapPattern(5, 23, LBM_LIBRARY_SLOT, TEXT_COLOR); } else { - if (modelName[0] == 0) - setModelName(partialmodel.header.name); - char timer[LEN_TIMER_STRING]; buffer->drawSizedText(5, 2, modelName, LEN_MODEL_NAME, SMLSIZE|TEXT_COLOR); getTimerString(timer, 0); diff --git a/radio/src/storage/sdcard_raw.cpp b/radio/src/storage/sdcard_raw.cpp index c0b129fc8..1128eee5c 100644 --- a/radio/src/storage/sdcard_raw.cpp +++ b/radio/src/storage/sdcard_raw.cpp @@ -101,16 +101,15 @@ const char * openFile(const char * fullpath, FIL * file, uint16_t * size, uint8_ return nullptr; } -const char * loadFile(const char * fullpath, uint8_t * data, uint16_t maxsize) +const char * loadFile(const char * fullpath, uint8_t * data, uint16_t maxsize, uint8_t * version) { FIL file; UINT read; uint16_t size; - uint8_t version; TRACE("loadFile(%s)", fullpath); - const char * err = openFile(fullpath, &file, &size, &version); + const char * err = openFile(fullpath, &file, &size, version); if (err) return err; @@ -121,26 +120,24 @@ const char * loadFile(const char * fullpath, uint8_t * data, uint16_t maxsize) return SDCARD_ERROR(result); } - if (version < EEPROM_VER) { - convertModelData(version); - } - f_close(&file); return nullptr; } -const char * readModel(const char * filename, uint8_t * buffer, uint32_t size) +const char * readModel(const char * filename, uint8_t * buffer, uint32_t size, uint8_t * version) { char path[256]; getModelPath(path, filename); - return loadFile(path, buffer, size); + return loadFile(path, buffer, size, version); } const char * loadModel(const char * filename, bool alarms) { + uint8_t version; + preModelLoad(); - const char * error = readModel(filename, (uint8_t *)&g_model, sizeof(g_model)); + const char * error = readModel(filename, (uint8_t *)&g_model, sizeof(g_model), &version); if (error) { TRACE("loadModel error=%s", error); } @@ -150,20 +147,34 @@ const char * loadModel(const char * filename, bool alarms) storageCheck(true); alarms = false; } + else if (version < EEPROM_VER) { + convertModelData(version); + } postModelLoad(alarms); return error; } -const char * loadRadioSettings() +const char * loadRadioSettings(const char * path) { - const char * error = loadFile(RADIO_SETTINGS_PATH, (uint8_t *)&g_eeGeneral, sizeof(g_eeGeneral)); + uint8_t version; + const char * error = loadFile(path, (uint8_t *)&g_eeGeneral, sizeof(g_eeGeneral), &version); if (error) { TRACE("loadRadioSettings error=%s", error); + return error; } - return error; + if (version < EEPROM_VER) { + convertRadioData(version); + } + + return nullptr; +} + +const char * loadRadioSettings() +{ + return loadRadioSettings(RADIO_SETTINGS_PATH); } const char * writeGeneralSettings() @@ -174,7 +185,7 @@ const char * writeGeneralSettings() void storageCheck(bool immediately) { if (storageDirtyMsk & EE_GENERAL) { - TRACE("eeprom write general"); + TRACE("Storage write general"); storageDirtyMsk -= EE_GENERAL; const char * error = writeGeneralSettings(); if (error) { @@ -183,7 +194,7 @@ void storageCheck(bool immediately) } if (storageDirtyMsk & EE_MODEL) { - TRACE("eeprom write model"); + TRACE("Storage write current model"); storageDirtyMsk -= EE_MODEL; const char * error = writeModel(); if (error) { diff --git a/radio/src/storage/sdcard_raw.h b/radio/src/storage/sdcard_raw.h index d5e71cdd9..15e3346a5 100644 --- a/radio/src/storage/sdcard_raw.h +++ b/radio/src/storage/sdcard_raw.h @@ -31,10 +31,13 @@ const char * openFile(const char * fullpath, FIL * file, uint16_t * size, uint8_ void getModelPath(char * path, const char * filename); -const char * readModel(const char * filename, uint8_t * buffer, uint32_t size); +const char * readModel(const char * filename, uint8_t * buffer, uint32_t size, uint8_t * version); const char * loadModel(const char * filename, bool alarms=true); const char * createModel(); +const char * loadRadioSettings(const char * path); +const char * loadRadioSettings(); + PACK(struct RamBackup { uint16_t size; uint8_t data[4094]; diff --git a/radio/src/switches.cpp b/radio/src/switches.cpp index 3e76e3304..8e62a3212 100644 --- a/radio/src/switches.cpp +++ b/radio/src/switches.cpp @@ -285,7 +285,6 @@ bool getLogicalSwitch(uint8_t idx) } else { mixsrc_t v1 = ls->v1; -#if defined(TELEMETRY_FRSKY) // Telemetry if (v1 >= MIXSRC_FIRST_TELEM) { if (!TELEMETRY_STREAMING() || IS_FAI_FORBIDDEN(v1-1)) { @@ -303,17 +302,6 @@ bool getLogicalSwitch(uint8_t idx) else { y = calc100toRESX(ls->v2); } -#else - if (v1 >= MIXSRC_FIRST_TELEM) { - y = (int16_t)3 * (128+ls->v2); // it's a Timer - } - else if (v1 >= MIXSRC_GVAR1) { - y = ls->v2; // it's a GVAR - } - else { - y = calc100toRESX(ls->v2); - } -#endif switch (ls->func) { case LS_FUNC_VEQUAL: @@ -370,9 +358,7 @@ bool getLogicalSwitch(uint8_t idx) } } -#if defined(TELEMETRY_FRSKY) DurationAndDelayProcessing: -#endif if (ls->delay || ls->duration) { LogicalSwitchContext &context = lswFm[mixerCurrentFlightMode].lsw[idx]; diff --git a/radio/src/targets/common/arm/CMakeLists.txt b/radio/src/targets/common/arm/CMakeLists.txt index 641468504..f47c72760 100644 --- a/radio/src/targets/common/arm/CMakeLists.txt +++ b/radio/src/targets/common/arm/CMakeLists.txt @@ -12,8 +12,8 @@ option(MODULE_SIZE_STD "Standard size TX Module" ON) option(PPM "PPM TX Module" ON) option(DSM2 "DSM2 TX Module" ON) option(SBUS "SBUS TX Module" ON) -option(CROSSFIRE "Crossfire TX Module" OFF) -option(MULTIMODULE "DIY Multiprotocol TX Module (https://github.com/pascallanger/DIY-Multiprotocol-TX-Module)" OFF) +option(CROSSFIRE "Crossfire TX Module" ON) +option(MULTIMODULE "DIY Multiprotocol TX Module (https://github.com/pascallanger/DIY-Multiprotocol-TX-Module)" ON) option(MULTI_SPORT "SPORT telemetry support" OFF) option(SUPPORT_D16_EU_ONLY "XJT module only supports D16-EU and LR12-EU" OFF) # TODO rename to XJT_EU_ONLY option(DEBUG_INTERRUPTS "Count interrupts" OFF) @@ -169,10 +169,10 @@ if(CROSSFIRE) endif() add_definitions(-DCPUARM) -add_definitions(-DTELEMETRY_FRSKY -DTELEMETRY_FRSKY_SPORT -DGPS) - +add_definitions(-DGPS) add_definitions(-DBOLD_FONT -DBATTGRAPH -DTHRTRACE) add_definitions(-DREQUIRED_SDCARD_VERSION="${SDCARD_VERSION}") + include_directories(${COOS_DIR} ${COOS_DIR}/kernel ${COOS_DIR}/portable) foreach(LANGUAGE ${TTS_LANGUAGES}) string(TOLOWER ${LANGUAGE} lang_lower) diff --git a/radio/src/targets/common/arm/stm32/CMakeLists.txt b/radio/src/targets/common/arm/stm32/CMakeLists.txt index bd40ddc5a..c050f9e94 100644 --- a/radio/src/targets/common/arm/stm32/CMakeLists.txt +++ b/radio/src/targets/common/arm/stm32/CMakeLists.txt @@ -1,7 +1,7 @@ set(LUA "NO" CACHE STRING "Lua scripts (YES/NO/NO_MODEL_SCRIPTS)") set_property(CACHE LUA PROPERTY STRINGS YES NO NO_MODEL_SCRIPTS) set(LUA_SCRIPT_LOAD_MODE "" CACHE STRING "Script loading mode and compilation flags [btTxcd] (see loadScript() API docs). Blank for default ('bt' on radio, 'T' on SIMU/DEBUG builds)") -option(LUA_COMPILER "Pre-compile and save Lua scripts" OFF) +option(LUA_COMPILER "Pre-compile and save Lua scripts" ON) option(LUA_ALLOCATOR_TRACER "Trace Lua memory (de)allocations to debug port (also needs DEBUG=YES NANO=NO)" OFF) option(USB_SERIAL "Enable USB serial (CDC)" OFF) @@ -18,6 +18,7 @@ include_directories(${STM32USB_DIR}/STM32_USB_Device_Library/Class/hid/inc) include_directories(${STM32USB_DIR}/STM32_USB_Device_Library/Class/cdc/inc) include_directories(${STM32USB_DIR}/STM32_USB_Device_Library/Core/inc/) include_directories(${STM32USB_DIR}/STM32_USB_OTG_Driver/inc) + set(STM32USB_SRC STM32_USB_OTG_Driver/src/usb_core.c STM32_USB_OTG_Driver/src/usb_dcd.c @@ -26,20 +27,19 @@ set(STM32USB_SRC STM32_USB_Device_Library/Core/src/usbd_ioreq.c STM32_USB_Device_Library/Core/src/usbd_req.c ) -set(TARGET_SRC - ${TARGET_SRC} - ../common/arm/stm32/rtc_driver.cpp - ../common/arm/stm32/cpu_id.cpp - ${AUX_SERIAL_DRIVER} - ) + set(FIRMWARE_TARGET_SRC ${FIRMWARE_TARGET_SRC} + ../common/arm/stm32/rtc_driver.cpp + ${AUX_SERIAL_DRIVER} ../common/arm/stm32/delays.cpp ../common/arm/stm32/usb_bsp.c ../common/arm/stm32/usbd_desc.c ../common/arm/stm32/usbd_usr.cpp ../common/arm/stm32/usb_driver.cpp ../common/arm/stm32/flash_driver.cpp + ../common/arm/stm32/usbd_storage_msd.cpp + ../common/arm/stm32/usbd_hid_joystick.c ) if(DEBUG OR CLI OR USB_SERIAL) @@ -62,16 +62,6 @@ set(STM32USB_SRC STM32_USB_Device_Library/Class/msc/src/usbd_msc_core.c ) -set(FIRMWARE_TARGET_SRC - ${FIRMWARE_TARGET_SRC} - ../common/arm/stm32/usbd_storage_msd.cpp - ) - -set(FIRMWARE_TARGET_SRC - ${FIRMWARE_TARGET_SRC} - ../common/arm/stm32/usbd_hid_joystick.c - ) - if(GVARS) set(GUI_SRC ${GUI_SRC} @@ -99,6 +89,11 @@ foreach(FILE ${STM32USB_SRC}) ) endforeach() +set(TARGET_SRC + ${TARGET_SRC} + ../common/arm/stm32/cpu_id.cpp + ) + set(SRC ${SRC} io/bootloader_flash.cpp diff --git a/radio/src/targets/common/arm/stm32/adc_driver.cpp b/radio/src/targets/common/arm/stm32/adc_driver.cpp index 19233a9d1..36d0e5a60 100644 --- a/radio/src/targets/common/arm/stm32/adc_driver.cpp +++ b/radio/src/targets/common/arm/stm32/adc_driver.cpp @@ -23,7 +23,7 @@ #if defined(SIMU) // not needed #elif defined(PCBX10) - const int8_t adcDirection[NUM_ANALOGS] = {1,-1,1,-1, -1,1,-1, 1,-1, 1, 1}; + const int8_t adcDirection[NUM_ANALOGS] = {1,-1,1,-1, -1,1,-1, 1,1, 1, -1}; #elif defined(PCBX9E) #if defined(HORUS_STICKS) const int8_t adcDirection[NUM_ANALOGS] = {1,-1,1,-1, -1,-1,-1,1, -1,1,-1, -1,-1,-1}; @@ -98,11 +98,11 @@ void adcInit() #if defined(PCBX10) if (STICKS_PWM_ENABLED()) { - ADC_MAIN->SQR2 = (ADC_CHANNEL_EXT1 << 0) + (ADC_CHANNEL_EXT2 << 5); - ADC_MAIN->SQR3 = (ADC_CHANNEL_POT1 << 0) + (ADC_CHANNEL_POT2 << 5) + (ADC_CHANNEL_POT3 << 10) + (ADC_CHANNEL_SLIDER1 << 15) + (ADC_CHANNEL_SLIDER2 << 20) + (ADC_CHANNEL_BATT << 25); + ADC_MAIN->SQR2 = (ADC_CHANNEL_SLIDER2 << 0) + (ADC_CHANNEL_BATT << 5); + ADC_MAIN->SQR3 = (ADC_CHANNEL_POT1 << 0) + (ADC_CHANNEL_POT2 << 5) + (ADC_CHANNEL_POT3 << 10) + (ADC_CHANNEL_EXT1 << 15) + (ADC_CHANNEL_EXT2 << 20) + (ADC_CHANNEL_SLIDER1 << 25); } else { - ADC_MAIN->SQR2 = (ADC_CHANNEL_POT3 << 0) + (ADC_CHANNEL_SLIDER1 << 5) + (ADC_CHANNEL_SLIDER2 << 10) + (ADC_CHANNEL_BATT << 15) + (ADC_CHANNEL_EXT1 << 20) + (ADC_CHANNEL_EXT2 << 25); + ADC_MAIN->SQR2 = (ADC_CHANNEL_POT3 << 0) + (ADC_CHANNEL_EXT1 << 5) + (ADC_CHANNEL_EXT2 << 10) + (ADC_CHANNEL_SLIDER1 << 15) + (ADC_CHANNEL_SLIDER2 << 20) + (ADC_CHANNEL_BATT << 25); ADC_MAIN->SQR3 = (ADC_CHANNEL_STICK_LH << 0) + (ADC_CHANNEL_STICK_LV << 5) + (ADC_CHANNEL_STICK_RV << 10) + (ADC_CHANNEL_STICK_RH << 15) + (ADC_CHANNEL_POT1 << 20) + (ADC_CHANNEL_POT2 << 25); } #elif defined(PCBX9E) @@ -248,7 +248,7 @@ void adcRead() #if defined(PCBX10) uint16_t getRTCBatteryVoltage() { - return (rtcBatteryVoltage * ADC_VREF_PREC2) / 2048; + return (rtcBatteryVoltage * 2 * ADC_VREF_PREC2) / 2048; } #else uint16_t getRTCBatteryVoltage() diff --git a/radio/src/targets/common/arm/stm32/aux_serial_driver.cpp b/radio/src/targets/common/arm/stm32/aux_serial_driver.cpp index 93a46e9a6..fc41ae08b 100644 --- a/radio/src/targets/common/arm/stm32/aux_serial_driver.cpp +++ b/radio/src/targets/common/arm/stm32/aux_serial_driver.cpp @@ -22,7 +22,7 @@ uint8_t auxSerialMode = 0; Fifo auxSerialTxFifo; -DMAFifo<32> auxSerialRxFifo __DMA (AUX_SERIAL_DMA_Stream_RX); +AuxSerialRxFifo auxSerialRxFifo __DMA (AUX_SERIAL_DMA_Stream_RX); void auxSerialSetup(unsigned int baudrate, bool dma) { diff --git a/radio/src/targets/common/arm/stm32/bootloader/boot.cpp b/radio/src/targets/common/arm/stm32/bootloader/boot.cpp index 0e7dec195..90010c956 100644 --- a/radio/src/targets/common/arm/stm32/bootloader/boot.cpp +++ b/radio/src/targets/common/arm/stm32/bootloader/boot.cpp @@ -244,6 +244,7 @@ int main() lcdInit(); backlightInit(); + backlightEnable(); #if defined(PCBTARANIS) i2cInit(); diff --git a/radio/src/targets/horus/CMakeLists.txt b/radio/src/targets/horus/CMakeLists.txt index 8f7e81233..dc4359092 100644 --- a/radio/src/targets/horus/CMakeLists.txt +++ b/radio/src/targets/horus/CMakeLists.txt @@ -27,7 +27,6 @@ if(SPLASH STREQUAL OFF) endif() if (PCB STREQUAL X10) - set(FLAVOUR x10) set(PCBREV "STD" CACHE STRING "PCB Revision") add_definitions(-DPCBX10) add_definitions(-DSOFTWARE_VOLUME) @@ -42,13 +41,17 @@ if (PCB STREQUAL X10) set(LCD_DRIVER lcd_driver.cpp) set(LUA_EXPORT lua_export_x10) if (PCBREV STREQUAL EXPRESS) + set(FLAVOUR x10express) option(INTERNAL_MODULE_PXX1 "Support for PXX1 internal module" OFF) option(INTERNAL_MODULE_PXX2 "Support for PXX2 internal module" ON) else() + set(FLAVOUR x10) option(INTERNAL_MODULE_PXX1 "Support for PXX1 internal module" ON) option(INTERNAL_MODULE_PXX2 "Support for PXX2 internal module" OFF) endif() elseif (PCB STREQUAL X12S) + option(INTERNAL_MODULE_PXX1 "Support for PXX1 internal module" ON) + option(INTERNAL_MODULE_PXX2 "Support for PXX2 internal module" OFF) set(FLAVOUR x12s) set(PCBREV "13" CACHE STRING "PCB Revision") if(${PCBREV} GREATER 10) @@ -64,7 +67,7 @@ elseif (PCB STREQUAL X12S) set(TARGET_SRC ${TARGET_SRC} audio_spi_driver.cpp - adc_driver.cpp + x12s_adc_driver.cpp gps_driver.cpp ) set(AUX_SERIAL_DRIVER ../common/arm/stm32/aux_serial_driver.cpp) @@ -136,7 +139,7 @@ if(PXX2) set(GUI_SRC ${GUI_SRC} radio_spectrum_analyser.cpp -# radio_power_meter.cpp + radio_power_meter.cpp ) endif() @@ -200,3 +203,4 @@ if(PYTHONINTERP_FOUND) DEPENDS ${RADIO_DIRECTORY}/src/datastructs.h ${RADIO_DIRECTORY}/util/generate_datacopy.py ) endif() + diff --git a/radio/src/targets/horus/board.cpp b/radio/src/targets/horus/board.cpp index 56b37ac40..85530ece2 100644 --- a/radio/src/targets/horus/board.cpp +++ b/radio/src/targets/horus/board.cpp @@ -181,6 +181,10 @@ void boardInit() #endif ledBlue(); + +#if defined(RTCLOCK) && !defined(COPROCESSOR) + rtcInit(); // RTC must be initialized before rambackupRestore() is called +#endif } void boardOff() diff --git a/radio/src/targets/horus/board.h b/radio/src/targets/horus/board.h index 62b5b7004..ff4618b87 100644 --- a/radio/src/targets/horus/board.h +++ b/radio/src/targets/horus/board.h @@ -103,15 +103,15 @@ enum { // SD driver #define BLOCK_SIZE 512 /* Block Size in Bytes */ #if !defined(SIMU) || defined(SIMU_DISKIO) -uint32_t sdIsHC(void); -uint32_t sdGetSpeed(void); +uint32_t sdIsHC(); +uint32_t sdGetSpeed(); #define SD_IS_HC() (sdIsHC()) #define SD_GET_SPEED() (sdGetSpeed()) #define SD_GET_FREE_BLOCKNR() (sdGetFreeSectors()) #define SD_CARD_PRESENT() (~SD_PRESENT_GPIO->IDR & SD_PRESENT_GPIO_PIN) -void sdInit(void); -void sdMount(void); -void sdDone(void); +void sdInit(); +void sdMount(); +void sdDone(); #define sdPoll10ms() uint32_t sdMounted(); #else @@ -134,14 +134,14 @@ DRESULT __disk_write(BYTE drv, const BYTE * buff, DWORD sector, UINT count); // Flash Write driver #define FLASH_PAGESIZE 256 -void unlockFlash(void); -void lockFlash(void); +void unlockFlash(); +void lockFlash(); void flashWrite(uint32_t * address, uint32_t * buffer); uint32_t isFirmwareStart(const uint8_t * buffer); uint32_t isBootloaderStart(const uint8_t * buffer); // SDRAM driver -void SDRAM_Init(void); +void SDRAM_Init(); // Pulses driver #define INTERNAL_MODULE_ON() GPIO_SetBits(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN) @@ -184,10 +184,10 @@ void extmoduleSendBuffer(const uint8_t * data, uint8_t size); void extmoduleSendNextFrame(); // Trainer driver -void init_trainer_ppm(void); -void stop_trainer_ppm(void); -void init_trainer_capture(void); -void stop_trainer_capture(void); +void init_trainer_ppm(); +void stop_trainer_ppm(); +void init_trainer_capture(); +void stop_trainer_capture(); // Keys driver enum EnumKeys @@ -280,9 +280,9 @@ enum EnumSwitchesPositions #define STORAGE_NUM_SWITCHES_POSITIONS (STORAGE_NUM_SWITCHES * 3) -void keysInit(void); +void keysInit(); uint32_t switchState(uint8_t index); -uint32_t readKeys(void); +uint32_t readKeys(); #define KEYS_PRESSED() (readKeys()) #define DBLKEYS_PRESSED_RGT_LFT(in) ((in & ((1< telemetryFifo; -extern DMAFifo<32> auxSerialRxFifo; +typedef DMAFifo<32> AuxSerialRxFifo; +extern AuxSerialRxFifo auxSerialRxFifo; #endif #endif // _BOARD_H_ diff --git a/radio/src/targets/horus/extmodule_driver.cpp b/radio/src/targets/horus/extmodule_driver.cpp index 99c5f811f..f453fa022 100644 --- a/radio/src/targets/horus/extmodule_driver.cpp +++ b/radio/src/targets/horus/extmodule_driver.cpp @@ -309,7 +309,7 @@ void extmoduleSendNextFrame() break; #endif -#if defined(PXX2) +#if defined(PXX2) && defined(EXTMODULE_USART) case PROTOCOL_CHANNELS_PXX2_HIGHSPEED: case PROTOCOL_CHANNELS_PXX2_LOWSPEED: extmoduleSendBuffer(extmodulePulsesData.pxx2.getData(), extmodulePulsesData.pxx2.getSize()); diff --git a/radio/src/targets/horus/hal.h b/radio/src/targets/horus/hal.h index 186bd3329..a811610dc 100644 --- a/radio/src/targets/horus/hal.h +++ b/radio/src/targets/horus/hal.h @@ -590,7 +590,6 @@ #define INTMODULE_BOOTCMD_GPIO GPIOI #define INTMODULE_BOOTCMD_GPIO_PIN GPIO_Pin_9 // PI.09 #endif -#define INTMODULE_FLASH_BAUDRATE 38400 #if defined(PCBX10) || PCBREV >= 13 #define INTMODULE_RCC_APB1Periph RCC_APB1Periph_TIM2 #define INTMODULE_RCC_APB2Periph RCC_APB2Periph_USART1 diff --git a/radio/src/targets/horus/adc_driver.cpp b/radio/src/targets/horus/x12s_adc_driver.cpp similarity index 100% rename from radio/src/targets/horus/adc_driver.cpp rename to radio/src/targets/horus/x12s_adc_driver.cpp diff --git a/radio/src/targets/simu/opentxsimulator.cpp b/radio/src/targets/simu/opentxsimulator.cpp index e30e6e2ec..bfdaae1fd 100644 --- a/radio/src/targets/simu/opentxsimulator.cpp +++ b/radio/src/targets/simu/opentxsimulator.cpp @@ -316,17 +316,12 @@ void OpenTxSimulator::setTrainerTimeout(uint16_t ms) void OpenTxSimulator::sendTelemetry(const QByteArray data) { -#if defined(TELEMETRY_FRSKY_SPORT) //OTXS_DBG << data; sportProcessTelemetryPacket((uint8_t *)data.constData()); -#else - Q_UNUSED(data) -#endif } uint8_t OpenTxSimulator::getSensorInstance(uint16_t id, uint8_t defaultValue) { -#if defined(TELEMETRY_FRSKY_SPORT) for (int i = 0; i < MAX_TELEMETRY_SENSORS; i++) { if (isTelemetryFieldAvailable(i)) { TelemetrySensor * sensor = &g_model.telemetrySensors[i]; @@ -335,15 +330,11 @@ uint8_t OpenTxSimulator::getSensorInstance(uint16_t id, uint8_t defaultValue) } } } -#else - Q_UNUSED(id) -#endif return defaultValue; } uint16_t OpenTxSimulator::getSensorRatio(uint16_t id) { -#if defined(TELEMETRY_FRSKY_SPORT) for (int i = 0; i < MAX_TELEMETRY_SENSORS; i++) { if (isTelemetryFieldAvailable(i)) { TelemetrySensor * sensor = &g_model.telemetrySensors[i]; @@ -352,9 +343,6 @@ uint16_t OpenTxSimulator::getSensorRatio(uint16_t id) } } } -#else - Q_UNUSED(id) -#endif return 0; } @@ -378,9 +366,7 @@ const int OpenTxSimulator::getCapability(Capability cap) break; case CAP_TELEM_FRSKY_SPORT : - #ifdef TELEMETRY_FRSKY_SPORT ret = 1; - #endif break; } return ret; diff --git a/radio/src/targets/simu/simpgmspace.cpp b/radio/src/targets/simu/simpgmspace.cpp index 697b1861f..68d6b95d1 100644 --- a/radio/src/targets/simu/simpgmspace.cpp +++ b/radio/src/targets/simu/simpgmspace.cpp @@ -741,3 +741,43 @@ void disableSpeaker() { } #endif + +#if defined(COPROCESSOR) +CoprocData coprocData; + +void coprocReadData(bool) +{ +} +#endif + +void rtcInit() +{ +} + +void rtcGetTime(struct gtm * t) +{ +} + +void rtcSetTime(const struct gtm * t) +{ +} + +#if defined(AUX_SERIAL) +AuxSerialRxFifo auxSerialRxFifo(nullptr); +uint8_t auxSerialMode; +void auxSerialInit(unsigned int mode, unsigned int protocol) +{ +} + +void auxSerialPutc(char c) +{ +} + +void auxSerialSbusInit() +{ +} + +void auxSerialStop() +{ +} +#endif diff --git a/radio/src/targets/sky9x/CMakeLists.txt b/radio/src/targets/sky9x/CMakeLists.txt index b4f37964b..08b120ad8 100644 --- a/radio/src/targets/sky9x/CMakeLists.txt +++ b/radio/src/targets/sky9x/CMakeLists.txt @@ -15,8 +15,8 @@ if(PCB STREQUAL 9XRPRO) add_definitions(-Dat91sam3s8 -DREVX) set(FLAVOUR 9xrpro) set(LINKER_SCRIPT targets/sky9x/sam3s8c_flash.ld) - set(TARGET_SRC - ${TARGET_SRC} + set(FIRMWARE_TARGET_SRC + ${FIRMWARE_TARGET_SRC} rtc_driver.cpp ) set(OPENRC_BOOTLOADER bootflash8.lbm) @@ -25,9 +25,9 @@ elseif(PCB STREQUAL AR9X) add_definitions(-Dat91sam3s8 -DPCBAR9X -DSOFTWARE_VOLUME) set(FLAVOUR ar9x) include_directories(${THIRDPARTY_DIR}/xdk-asf-3.31.0/sam/drivers/twi) - set(SRC ${SRC} ${THIRDPARTY_DIR}/xdk-asf-3.31.0/sam/drivers/twi/twi.c) - set(TARGET_SRC - ${TARGET_SRC} + set(FIRMWARE_TARGET_SRC + ${FIRMWARE_TARGET_SRC} + ../../${THIRDPARTY_DIR}/xdk-asf-3.31.0/sam/drivers/twi/twi.c i2c_driver.cpp rtc_ds3231_driver.cpp ) @@ -38,8 +38,8 @@ else() set(FLAVOUR sky9x) set(PCBREV "REVC" CACHE STRING "PCB Revision (REVB/REVC)") set_property(CACHE PCBREV PROPERTY STRINGS "REVB" "REVC") - set(TARGET_SRC - ${TARGET_SRC} + set(FIRMWARE_TARGET_SRC + ${FIRMWARE_TARGET_SRC} coproc_driver.cpp rotary_encoder_driver.cpp rtc_driver.cpp @@ -90,14 +90,20 @@ set(FIRMWARE_TARGET_SRC eeprom_driver.cpp lcd_driver.cpp pwr_driver.cpp + joystick.cpp + massstorage.cpp keys_driver.cpp usb/device/core/USBD_UDP.c usb/device/core/USBDDriver.c + usb_driver.cpp usb/device/massstorage/MSDDriver.c usb/device/massstorage/MSDDStateMachine.c usb/device/massstorage/MSDLun.c usb/device/massstorage/MSDDriverDescriptors.c usb/device/massstorage/SBCMethods.c + usb/device/hid-joystick/HIDDJoystickDriver.c + usb/device/hid-joystick/HIDDJoystickDriverDescriptors.c + usb/device/hid-joystick/HIDDJoystickInputReport.c usb/common/core/USBEndpointDescriptor.c usb/common/core/USBGenericRequest.c usb/common/core/USBFeatureRequest.c @@ -107,6 +113,8 @@ set(FIRMWARE_TARGET_SRC usb/common/core/USBSetConfigurationRequest.c usb/common/core/USBConfigurationDescriptor.c usb/common/core/USBGenericDescriptor.c + usb/common/hid/HIDIdleRequest.c + usb/common/hid/HIDReportRequest.c MEDSdcard.c ) @@ -119,7 +127,6 @@ set(TARGET_SRC buzzer_driver.cpp haptic_driver.cpp sdcard_driver.cpp - massstorage.cpp aux_serial_driver.cpp audio_driver.cpp trainer_driver.cpp @@ -129,3 +136,4 @@ set(SRC ${SRC} debug.cpp ) + diff --git a/radio/src/targets/sky9x/aux_serial_driver.cpp b/radio/src/targets/sky9x/aux_serial_driver.cpp index 9d8f1978c..13fd88d95 100644 --- a/radio/src/targets/sky9x/aux_serial_driver.cpp +++ b/radio/src/targets/sky9x/aux_serial_driver.cpp @@ -99,8 +99,7 @@ void SECOND_UART_Stop() extern "C" void UART0_IRQHandler() { - if ( SECOND_SERIAL_UART->UART_SR & UART_SR_RXRDY ) - { + if (SECOND_SERIAL_UART->UART_SR & UART_SR_RXRDY) { auxSerialRxFifo.push(SECOND_SERIAL_UART->UART_RHR); } } @@ -109,7 +108,6 @@ extern "C" void UART0_IRQHandler() #define SECOND_UART_Configure(...) #endif -#if defined(TELEMETRY_FRSKY) void auxSerialTelemetryInit(unsigned int /*protocol*/) { SECOND_UART_Configure(FRSKY_D_BAUDRATE, Master_frequency); @@ -119,7 +117,6 @@ bool telemetrySecondPortReceive(uint8_t & data) { return auxSerialRxFifo.pop(data); } -#endif #if defined(DEBUG) && !defined(SIMU) void serialPrintf(const char*, ... ) {} diff --git a/radio/src/targets/sky9x/board.h b/radio/src/targets/sky9x/board.h index 4ff927aa4..7ba1f781b 100644 --- a/radio/src/targets/sky9x/board.h +++ b/radio/src/targets/sky9x/board.h @@ -170,6 +170,10 @@ void lcdSetContrast(); // USB driver void usbMassStorage(); +#if !defined(SIMU) +void usbJoystickUpdate(); +#endif + #define PIN_ENABLE 0x001 #define PIN_PERIPHERAL 0x000 #define PIN_INPUT 0x002 @@ -228,6 +232,11 @@ uint32_t readTrims(); // Pulses driver void extmoduleSerialStart(uint32_t baudrate, uint32_t period_half_us, bool inverted); void extmoduleSendNextFrame(); +void module_output_active(); +inline void EXTERNAL_MODULE_ON() +{ + module_output_active(); +} // SD driver #if defined(SIMU) @@ -335,10 +344,17 @@ void coprocWriteData(uint8_t *data, uint32_t size); void coprocReadData(bool onlytemp=false); #endif extern int8_t volumeRequired; -extern uint8_t Coproc_read; -extern int8_t Coproc_valid; -extern int8_t Coproc_temp; -extern int8_t Coproc_maxtemp; + +#if defined(COPROCESSOR) +struct CoprocData { + uint8_t read; + int8_t valid; + int8_t temp; + int8_t maxtemp; +}; + +extern CoprocData coprocData; +#endif // Haptic driver #define HAPTIC_PWM @@ -377,6 +393,9 @@ void debugPutc(const char c); // Telemetry driver void telemetryPortInit(uint32_t baudrate, uint8_t mode); +inline void telemetryPortSetDirectionOutput() +{ +} uint32_t telemetryTransmitPending(); void telemetryTransmitBuffer(const uint8_t * buffer, uint32_t size); void rxPdcUsart( void (*pChProcess)(uint8_t x) ); diff --git a/radio/src/targets/sky9x/coproc_driver.cpp b/radio/src/targets/sky9x/coproc_driver.cpp index cf5ab1be3..8a4beb31c 100644 --- a/radio/src/targets/sky9x/coproc_driver.cpp +++ b/radio/src/targets/sky9x/coproc_driver.cpp @@ -25,10 +25,7 @@ uint8_t coprocReadDataPending ; uint8_t coprocWriteDataPending ; uint8_t CoProc_appgo_pending ; uint8_t Volume_read ; -uint8_t Coproc_read ; -int8_t Coproc_temp ; -int8_t Coproc_maxtemp=-127 ; -int8_t Coproc_valid ; +CoprocData coprocData; bool get_onlytemp; #if !defined(SIMU) // TODO not used? static uint8_t *Twi_read_address ; @@ -71,7 +68,7 @@ void i2cCheck() TWI0->TWI_CR = TWI_CR_STOP ; // Stop Tx } else if (coprocReadDataPending) { - Coproc_valid = 0 ; + coprocData.valid = 0 ; coprocReadDataPending = 0 ; TWI0->TWI_MMR = 0x00351000 ; // Device 35 and master is reading TwiOperation = TWI_READ_COPROC ; @@ -142,15 +139,15 @@ extern "C" void TWI0_IRQHandler() } else { - Coproc_valid = -1 ; + coprocData.valid = -1 ; } } if ( TwiOperation == TWI_WAIT_STOP ) { - Coproc_valid = 1 ; - Coproc_read = Co_proc_status[0] ; - if ( Coproc_read & 0x80 ) { + coprocData.valid = 1 ; + coprocData.read = Co_proc_status[0] ; + if ( coprocData.read & 0x80 ) { // Bootloader CoProc_appgo_pending = 1 ; // Action application } @@ -167,9 +164,9 @@ extern "C" void TWI0_IRQHandler() utm.tm_year = (Co_proc_status[6] + ( Co_proc_status[7] << 8 )) - TM_YEAR_BASE; g_rtcTime = gmktime(&utm); } - Coproc_temp = Co_proc_status[8]; - if (Coproc_temp > Coproc_maxtemp) - Coproc_maxtemp=Coproc_temp; + coprocData.temp = Co_proc_status[8]; + if (coprocData.temp > coprocData.maxtemp) + coprocData.maxtemp = coprocData.temp; } TWI0->TWI_PTCR = TWI_PTCR_RXTDIS ; // Stop transfers if ( TWI0->TWI_SR & TWI_SR_RXRDY ) { diff --git a/radio/src/targets/sky9x/joystick.cpp b/radio/src/targets/sky9x/joystick.cpp new file mode 100644 index 000000000..8f5774e3c --- /dev/null +++ b/radio/src/targets/sky9x/joystick.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "opentx.h" + +extern "C" { +#include "usb/device/hid-joystick/HIDDJoystickDriver.h" +extern void HIDDJoystickDriver_Initialize(); +unsigned char HIDDJoystickDriver_ChangeJoystickState(const HIDDJoystickInputReport *report); +extern void USBD_Connect(void); +} + +static void ConfigureUsbClock(void) +{ + /* Enable PLLB for USB */ + PMC->CKGR_PLLBR = CKGR_PLLBR_DIVB(1) + | CKGR_PLLBR_MULB(7) + | CKGR_PLLBR_PLLBCOUNT_Msk; + while((PMC->PMC_SR & PMC_SR_LOCKB) == 0); // TODO && (timeout++ < CLOCK_TIMEOUT)); + /* USB Clock uses PLLB */ + PMC->PMC_USB = PMC_USB_USBDIV(1) /* /2 */ + | PMC_USB_USBS; /* PLLB */ +} + +void usbJoystickUpdate() +{ + static bool initialized = false; + + if (usbPlugged()) { + TRACE_DEBUG("usbJoystick\n\r"); + + if (!initialized) { + ConfigureUsbClock(); + + HIDDJoystickDriver_Initialize(); + + // VBus_Configure(); + USBD_Connect(); + + initialized = true; + } + + static uint8_t HID_Buffer[11]; + + HID_Buffer[0] = 0; + HID_Buffer[1] = 0; + HID_Buffer[2] = 0; + for (int i = 0; i < 8; ++i) { + if ( channelOutputs[i+8] > 0 ) { + HID_Buffer[0] |= (1 << i); + } + if ( channelOutputs[i+16] > 0 ) { + HID_Buffer[1] |= (1 << i); + } + if ( channelOutputs[i+24] > 0 ) { + HID_Buffer[2] |= (1 << i); + } + } + + //analog values + //uint8_t * p = HID_Buffer + 1; + for (int i = 0; i < 8; ++i) { + int16_t value = channelOutputs[i] / 8; + if ( value > 127 ) value = 127; + else if ( value < -127 ) value = -127; + HID_Buffer[i+3] = static_cast(value); + } + + HIDDJoystickDriver_ChangeJoystickState((HIDDJoystickInputReport*)&HID_Buffer); + } +} diff --git a/radio/src/targets/sky9x/usb/common/hid/HIDButton.h b/radio/src/targets/sky9x/usb/common/hid/HIDButton.h new file mode 100644 index 000000000..5003586b7 --- /dev/null +++ b/radio/src/targets/sky9x/usb/common/hid/HIDButton.h @@ -0,0 +1,55 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +/* + Title: HIDButton + + About: Purpose + Definitions of constants and methods for the HID Button usage page. + + About: Usage + 1 - Use the constants declared in this file when instanciating a + Report descriptor instance. + 2 - When implementing the functionality of an HID Mouse, use the + key codes defined here to indicate keys that are being pressed and + released. +*/ + +#ifndef _HIDBUTTON_H +#define _HIDBUTTON_H + +//------------------------------------------------------------------------------ +// Constants +//------------------------------------------------------------------------------ + +/// Identifier for the HID button usage page +#define HIDButton_PAGEID 0x09 + + +#endif diff --git a/radio/src/targets/sky9x/usb/common/hid/HIDDescriptor.h b/radio/src/targets/sky9x/usb/common/hid/HIDDescriptor.h new file mode 100644 index 000000000..1a5df6b12 --- /dev/null +++ b/radio/src/targets/sky9x/usb/common/hid/HIDDescriptor.h @@ -0,0 +1,93 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +/** + \unit + + !!!Purpose + + Methods and definitions for manipulating a HID descriptor. +*/ + +#ifndef HIDDESCRIPTOR_H +#define HIDDESCRIPTOR_H + +//------------------------------------------------------------------------------ +// Definitions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// \page "HID Release Numbers" +/// ... +/// +/// !Numbers +/// - HIDDescriptor_HID1_11 + +/// Identifies version 1.11 of the HID specification. +#define HIDDescriptor_HID1_11 0x0111 +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// Types +//------------------------------------------------------------------------------ + +#ifdef __ICCARM__ // IAR +#pragma pack(1) // IAR +#define __attribute__(...) // IAR +#endif // IAR + +//------------------------------------------------------------------------------ +/// Identifies the length of type of subordinate descriptors of a HID +/// device. This particular type only supports one subordinate descriptor. +//------------------------------------------------------------------------------ +typedef struct { + + /// Size of descriptor in bytes. + unsigned char bLength; + /// Descriptor type (HIDGenericDescriptor_HID). + unsigned char bDescriptorType; + /// HID class specification release number in BCD format. + unsigned short bcdHID; + /// Country code of the device if it is localized. + unsigned char bCountryCode; + /// Number of subordinate descriptors. + unsigned char bNumDescriptors; + /// Type of the first subordinate descriptor. + unsigned char bDescriptorType0; + /// Size in bytes of the first subordinate descriptor. + unsigned short wDescriptorLength0; + +} __attribute__ ((packed)) HIDDescriptor; // GCC + +#ifdef __ICCARM__ // IAR +#pragma pack() // IAR +#endif // IAR + +#endif //#ifndef HIDDESCRIPTOR_H + diff --git a/radio/src/targets/sky9x/usb/common/hid/HIDDeviceDescriptor.h b/radio/src/targets/sky9x/usb/common/hid/HIDDeviceDescriptor.h new file mode 100644 index 000000000..41c510481 --- /dev/null +++ b/radio/src/targets/sky9x/usb/common/hid/HIDDeviceDescriptor.h @@ -0,0 +1,68 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +/** + \unit + + !!!Purpose + + Definitions used for declaring the device descriptor of a HID device. + + !!!Usage + + Use this constants when defining an instance of USBDeviceDescriptor for + an HID device. +*/ + +#ifndef HIDDEVICEDESCRIPTOR_H +#define HIDDEVICEDESCRIPTOR_H + +//------------------------------------------------------------------------------ +// Definitions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// \page "HID Device Descriptor Codes" +/// This page lists HID device class, subclass and protocol codes. +/// +/// !Codes +/// - HIDDeviceDescriptor_CLASS +/// - HIDDeviceDescriptor_SUBCLASS +/// - HIDDeviceDescriptor_PROTOCOL + +/// Class code for a HID device. +#define HIDDeviceDescriptor_CLASS 0 +/// Subclass code for a HID device. +#define HIDDeviceDescriptor_SUBCLASS 0 +/// Protocol code for a HID device. +#define HIDDeviceDescriptor_PROTOCOL 0 +//------------------------------------------------------------------------------ + +#endif //#ifndef HIDDEVICEDESCRIPTOR_H + diff --git a/radio/src/targets/sky9x/usb/common/hid/HIDGenericDescriptor.h b/radio/src/targets/sky9x/usb/common/hid/HIDGenericDescriptor.h new file mode 100644 index 000000000..0848872f6 --- /dev/null +++ b/radio/src/targets/sky9x/usb/common/hid/HIDGenericDescriptor.h @@ -0,0 +1,63 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +/** + \unit + + !!!Purpose + + Definitions for using HID-specific descriptors. +*/ + +#ifndef HIDGENERICDESCRIPTOR_H +#define HIDGENERICDESCRIPTOR_H + +//------------------------------------------------------------------------------ +// Definitions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// \page "HID Descriptors Types" +/// ... +/// +/// !Types +/// - HIDGenericDescriptor_HID +/// - HIDGenericDescriptor_REPORT +/// - HIDGenericDescriptor_PHYSICAL + +/// HID descriptor type. +#define HIDGenericDescriptor_HID 0x21 +/// Report descriptor type. +#define HIDGenericDescriptor_REPORT 0x22 +/// Physical descriptor type. +#define HIDGenericDescriptor_PHYSICAL 0x23 +//------------------------------------------------------------------------------ + +#endif //#ifndef HIDGENERICDESCRIPTOR_H + diff --git a/radio/src/targets/sky9x/usb/common/hid/HIDGenericDesktop.h b/radio/src/targets/sky9x/usb/common/hid/HIDGenericDesktop.h new file mode 100644 index 000000000..7ca5b46f6 --- /dev/null +++ b/radio/src/targets/sky9x/usb/common/hid/HIDGenericDesktop.h @@ -0,0 +1,109 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +/** + \unit + + !!!Purpose + + Constants for using the HID generic desktop usage page. + + !!!Usage + + Use these constants when declaring a Report descriptor which references + the generic desktop page. +*/ + +#ifndef HIDGENERICDESKTOP_H +#define HIDGENERICDESKTOP_H + +//------------------------------------------------------------------------------ +// Definitions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// \page "HID GenericDesktop Page ID" +/// ... +/// +/// !ID +/// - HIDGenericDesktop_PAGEID + +/// ID for the HID generic desktop usage page. +#define HIDGenericDesktop_PAGEID 0x01 +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// \page "HID GenericDesktop Usages" +/// ... +/// +/// !Usages +/// - HIDGenericDesktop_POINTER +/// - HIDGenericDesktop_MOUSE +/// - HIDGenericDesktop_JOYSTICK +/// - HIDGenericDesktop_GAMEPAD +/// - HIDGenericDesktop_KEYBOARD +/// - HIDGenericDesktop_KEYPAD +/// - HIDGenericDesktop_MULTIAXIS +/// - HIDGenericDesktop_X +/// - HIDGenericDesktop_Y +/// - HIDGenericDesktop_Z + +/// Pointer usage ID. +#define HIDGenericDesktop_POINTER 0x01 +/// Mouse usage ID. +#define HIDGenericDesktop_MOUSE 0x02 +/// Joystick usage ID. +#define HIDGenericDesktop_JOYSTICK 0x04 +/// Gamepad usage ID. +#define HIDGenericDesktop_GAMEPAD 0x05 +/// Keyboard usage ID. +#define HIDGenericDesktop_KEYBOARD 0x06 +/// Keypad usage ID. +#define HIDGenericDesktop_KEYPAD 0x07 +/// Multi-axis controller usage ID. +#define HIDGenericDesktop_MULTIAXIS 0x08 + +/// Axis Usage X direction ID. +#define HIDGenericDesktop_X_AXIS 0x30 +/// Axis Usage Y direction ID. +#define HIDGenericDesktop_Y_AXIS 0x31 +/// Axis Usage Z direction ID. +#define HIDGenericDesktop_Z_AXIS 0x32 +/// Rotation Usage X direction ID. +#define HIDGenericDesktop_X_ROTATION 0x33 +/// Rotation Usage Y direction ID. +#define HIDGenericDesktop_Y_ROTATION 0x34 +/// Rotation Usage Z direction ID. +#define HIDGenericDesktop_Z_ROTATION 0x35 +/// Slider usage ID. +#define HIDGenericDesktop_SLIDER 0x36 +//------------------------------------------------------------------------------ + +#endif //#ifndef HIDGENERICDESKTOP_H + diff --git a/radio/src/targets/sky9x/usb/common/hid/HIDGenericRequest.h b/radio/src/targets/sky9x/usb/common/hid/HIDGenericRequest.h new file mode 100644 index 000000000..ea3cfee83 --- /dev/null +++ b/radio/src/targets/sky9x/usb/common/hid/HIDGenericRequest.h @@ -0,0 +1,75 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +/* + Title: HIDGenericRequest + + About: Purpose + Definition of constants for using HID-specific requests. + + About: Usage + When constructing or receiving an HID SETUP request, use the request + codes provided by this header file. +*/ + +#ifndef HIDGENERICREQUEST_H +#define HIDGENERICREQUEST_H + +//------------------------------------------------------------------------------ +// Definitions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// \page "HID Request Codes" +/// ... +/// +/// !Codes +/// - HIDGenericRequest_GETREPORT +/// - HIDGenericRequest_GETIDLE +/// - HIDGenericRequest_GETPROTOCOL +/// - HIDGenericRequest_SETREPORT +/// - HIDGenericRequest_SETIDLE +/// - HIDGenericRequest_SETPROTOCOL + +/// GetReport request code. +#define HIDGenericRequest_GETREPORT 0x01 +/// GetIdle request code. +#define HIDGenericRequest_GETIDLE 0x02 +/// GetProtocol request code. +#define HIDGenericRequest_GETPROTOCOL 0x03 +/// SetReport request code. +#define HIDGenericRequest_SETREPORT 0x09 +/// SetIdle request code. +#define HIDGenericRequest_SETIDLE 0x0A +/// SetProtocol request code. +#define HIDGenericRequest_SETPROTOCOL 0x0B +//------------------------------------------------------------------------------ + +#endif //#ifndef HIDGENERICREQUEST_H + diff --git a/radio/src/targets/sky9x/usb/common/hid/HIDIdleRequest.c b/radio/src/targets/sky9x/usb/common/hid/HIDIdleRequest.c new file mode 100644 index 000000000..17fc4875f --- /dev/null +++ b/radio/src/targets/sky9x/usb/common/hid/HIDIdleRequest.c @@ -0,0 +1,56 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +/* + Title: HIDIdleRequest implementation + + About: Purpose + Implementation of the HIDIdleRequest methods. +*/ + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include "HIDIdleRequest.h" + +//------------------------------------------------------------------------------ +// Exported functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Retrieves the Idle rate (in milliseconds) indicated by a SET_IDLE +/// request. +/// \param request Pointer to a USBGenericRequest instance. +/// \return New idle rate for the report. +//------------------------------------------------------------------------------ +unsigned char HIDIdleRequest_GetIdleRate(const USBGenericRequest *request) +{ + return ((USBGenericRequest_GetValue(request) >> 8) & 0xFF); +} diff --git a/radio/src/targets/sky9x/usb/common/hid/HIDIdleRequest.h b/radio/src/targets/sky9x/usb/common/hid/HIDIdleRequest.h new file mode 100644 index 000000000..7a16d7a6f --- /dev/null +++ b/radio/src/targets/sky9x/usb/common/hid/HIDIdleRequest.h @@ -0,0 +1,68 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +/** + \unit + + !!!Purpose + + Methods and constants for manipulating HID-specific GET_IDLE and SET_IDLE + requests. + + !!!Usage + + -# Retrieve the idle rate indicated by a GET_IDLE or SET_IDLE request + with HIDIdleRequest_GetIdleRate. +*/ + +#ifndef HIDIDLEREQUEST_H +#define HIDIDLEREQUEST_H + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include + +//------------------------------------------------------------------------------ +// Definitions +//------------------------------------------------------------------------------ + +/// Infinite idle rate. +#define HIDIdleRequest_INFINITE 0 + +//------------------------------------------------------------------------------ +// Exported functions +//------------------------------------------------------------------------------ + +extern unsigned char HIDIdleRequest_GetIdleRate( + const USBGenericRequest *request); + +#endif //#ifndef HIDIDLEREQUEST_H + diff --git a/radio/src/targets/sky9x/usb/common/hid/HIDInterfaceDescriptor.h b/radio/src/targets/sky9x/usb/common/hid/HIDInterfaceDescriptor.h new file mode 100644 index 000000000..32e0dbcc1 --- /dev/null +++ b/radio/src/targets/sky9x/usb/common/hid/HIDInterfaceDescriptor.h @@ -0,0 +1,77 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +/** + \unit + + !!!Purpose + + Constants used when declaring an HID interface. + + !!!Usage + + Use the constants defined here when declaring a USBInterfaceDescriptor + instance for a HID interface. +*/ + +#ifndef HIDINTERFACEDESCRIPTOR_H +#define HIDINTERFACEDESCRIPTOR_H + +//------------------------------------------------------------------------------ +// Definitions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// \page "HID Interface Descriptor Codes" +/// This page lists HID Interface class, subclass and protocol codes. +/// +/// !Codes +/// - HIDInterfaceDescriptor_CLASS +/// - HIDInterfaceDescriptor_SUBCLASS_NONE +/// - HIDInterfaceDescriptor_SUBCLASS_BOOT +/// - HIDInterfaceDescriptor_PROTOCOL_NONE +/// - HIDInterfaceDescriptor_PROTOCOL_KEYBOARD +/// - HIDInterfaceDescriptor_PROTOCOL_MOUSE + +/// HID interface class code. +#define HIDInterfaceDescriptor_CLASS 0x03 +/// Indicates the interface does not implement a particular subclass. +#define HIDInterfaceDescriptor_SUBCLASS_NONE 0x00 +/// Indicates the interface is compliant with the boot specification. +#define HIDInterfaceDescriptor_SUBCLASS_BOOT 0x01 +/// Indicates the interface does not implement a particular protocol. +#define HIDInterfaceDescriptor_PROTOCOL_NONE 0x00 +/// Indicates the interface supports the boot specification as a keyboard. +#define HIDInterfaceDescriptor_PROTOCOL_KEYBOARD 0x01 +/// Indicates the interface supports the boot specification as a mouse. +#define HIDInterfaceDescriptor_PROTOCOL_MOUSE 0x02 +//------------------------------------------------------------------------------ + +#endif //#ifndef HIDINTERFACEDESCRIPTOR_H + diff --git a/radio/src/targets/sky9x/usb/common/hid/HIDReport.h b/radio/src/targets/sky9x/usb/common/hid/HIDReport.h new file mode 100644 index 000000000..d63a93023 --- /dev/null +++ b/radio/src/targets/sky9x/usb/common/hid/HIDReport.h @@ -0,0 +1,231 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +/** + \unit + + !!!Purpose + + Definitions used when declaring an HID report descriptor. + + !!!Usage + + Use the definitions provided here when declaring a report descriptor, + which shall be an unsigned char array. +*/ + +#ifndef HIDREPORT_H +#define HIDREPORT_H + +//------------------------------------------------------------------------------ +// Definitions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// \page "HID Main Item Tags" +/// This page lists the Main Item Tags defined for HID %device. +/// ( HID Spec. 6.2.2 ) +/// +/// !Tags +/// - HIDReport_INPUT +/// - HIDReport_OUPUT +/// - HIDReport_FEATURE +/// - HIDReport_COLLECTION +/// - HIDReport_ENDCOLLECTION + +/// Input item. +#define HIDReport_INPUT 0x80 +/// Output item. +#define HIDReport_OUTPUT 0x90 +/// Feature item. +#define HIDReport_FEATURE 0xB0 +/// Collection item. +#define HIDReport_COLLECTION 0xA0 +/// End of collection item. +#define HIDReport_ENDCOLLECTION 0xC0 +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// \page "HID Items for Data Fields" +/// This page lists defintions for HID Input, Output and Feature items that +/// are used to create the data fields within a report. +/// ( HID Spec. 6.2.2.5 ) +/// +/// !Items +/// - HIDReport_CONSTANT +/// - HIDReport_VARIABLE +/// - HIDReport_RELATIVE +/// - HIDReport_WRAP +/// - HIDReport_NONLINEAR +/// - HIDReport_NOPREFERRED +/// - HIDReport_NULLSTATE +/// - HIDReport_VOLATILE +/// - HIDReport_BUFFEREDBYTES + +/// The report value is constant (vs. variable). +#define HIDReport_CONSTANT (1 << 0) +/// Data reported is a variable (vs. array). +#define HIDReport_VARIABLE (1 << 1) +/// Data is relative (vs. absolute). +#define HIDReport_RELATIVE (1 << 2) +/// Value rolls over when it reach a maximum/minimum. +#define HIDReport_WRAP (1 << 3) +/// Indicates that the data reported has been processed and is no longuer +/// linear with the original measurements. +#define HIDReport_NONLINEAR (1 << 4) +/// Device has no preferred state to which it automatically returns. +#define HIDReport_NOPREFERRED (1 << 5) +/// Device has a null state, in which it does not report meaningful +/// information. +#define HIDReport_NULLSTATE (1 << 6) +/// Indicates data can change without the host intervention. +#define HIDReport_VOLATILE (1 << 7) +/// Indicates the device produces a fixed-length stream of bytes. +#define HIDReport_BUFFEREDBYTES (1 << 8) +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// \page "HID Collection Items" +/// This page lists definitions for HID Collection Items. +/// ( HID Spec. 6.2.2.6 ) +/// +/// !Items +/// - HIDReport_COLLECTION_PHYSICAL +/// - HIDReport_COLLECTION_APPLICATION +/// - HIDReport_COLLECTION_LOGICAL +/// - HIDReport_COLLECTION_REPORT +/// - HIDReport_COLLECTION_NAMEDARRAY +/// - HIDReport_COLLECTION_USAGESWITCH +/// - HIDReport_COLLECTION_USAGEMODIFIER + +/// Physical collection. +#define HIDReport_COLLECTION_PHYSICAL 0x00 +/// Application collection. +#define HIDReport_COLLECTION_APPLICATION 0x01 +/// Logical collection. +#define HIDReport_COLLECTION_LOGICAL 0x02 +/// Report collection. +#define HIDReport_COLLECTION_REPORT 0x03 +/// Named array collection. +#define HIDReport_COLLECTION_NAMEDARRAY 0x04 +/// Usage switch collection. +#define HIDReport_COLLECTION_USAGESWITCH 0x05 +/// Usage modifier collection +#define HIDReport_COLLECTION_USAGEMODIFIER 0x06 +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// \page "HID Global Items" +/// This page lists HID Global Items. +/// ( HID Spec. 6.2.2.7 ) +/// +/// !Items +/// - HIDReport_GLOBAL_USAGEPAGE +/// - HIDReport_GLOBAL_LOGICALMINIMUM +/// - HIDReport_GLOBAL_LOGICALMAXIMUM +/// - HIDReport_GLOBAL_PHYSICALMINIMUM +/// - HIDReport_GLOBAL_PHYSICALMAXIMUM +/// - HIDReport_GLOBAL_UNITEXPONENT +/// - HIDReport_GLOBAL_UNIT +/// - HIDReport_GLOBAL_REPORTSIZE +/// - HIDReport_GLOBAL_REPORTID +/// - HIDReport_GLOBAL_REPORTCOUNT +/// - HIDReport_GLOBAL_PUSH +/// - HIDReport_GLOBAL_POP + +/// Current usage page. +#define HIDReport_GLOBAL_USAGEPAGE 0x04 +/// Minimum value that a variable or array item will report. +#define HIDReport_GLOBAL_LOGICALMINIMUM 0x14 +/// Maximum value that a variable or array item will report. +#define HIDReport_GLOBAL_LOGICALMAXIMUM 0x24 +/// Minimum value for the physical extent of a variable item. +#define HIDReport_GLOBAL_PHYSICALMINIMUM 0x34 +/// Maximum value for the physical extent of a variable item. +#define HIDReport_GLOBAL_PHYSICALMAXIMUM 0x44 +/// Value of the unit exponent in base 10. +#define HIDReport_GLOBAL_UNITEXPONENT 0x54 +/// Unit values. +#define HIDReport_GLOBAL_UNIT 0x64 +/// Size of the report fields in bits. +#define HIDReport_GLOBAL_REPORTSIZE 0x74 +/// Specifies the report ID. +#define HIDReport_GLOBAL_REPORTID 0x84 +/// Number of data fields for an item. +#define HIDReport_GLOBAL_REPORTCOUNT 0x94 +/// Places a copy of the global item state table on the stack. +#define HIDReport_GLOBAL_PUSH 0xA4 +/// Replaces the item state table with the top structure from the stack. +#define HIDReport_GLOBAL_POP 0xB4 +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// \page "HID Local Items" +/// This page lists definitions for HID Local Items. +/// +/// !Items +/// - HIDReport_LOCAL_USAGE +/// - HIDReport_LOCAL_USAGEMINIMUM +/// - HIDReport_LOCAL_USAGEMAXIMUM +/// - HIDReport_LOCAL_DESIGNATORINDEX +/// - HIDReport_LOCAL_DESIGNATORMINIMUM +/// - HIDReport_LOCAL_DESIGNATORMAXIMUM +/// - HIDReport_LOCAL_STRINGINDEX +/// - HIDReport_LOCAL_STRINGMINIMUM +/// - HIDReport_LOCAL_STRINGMAXIMUM +/// - HIDReport_LOCAL_DELIMITER + +/// Suggested usage for an item or collection. +#define HIDReport_LOCAL_USAGE 0x08 +/// Defines the starting usage associated with an array or bitmap. +#define HIDReport_LOCAL_USAGEMINIMUM 0x18 +/// Defines the ending usage associated with an array or bitmap. +#define HIDReport_LOCAL_USAGEMAXIMUM 0x28 +/// Determines the body part used for a control. +#define HIDReport_LOCAL_DESIGNATORINDEX 0x38 +/// Defines the index of the starting designator associated with an array or +/// bitmap. +#define HIDReport_LOCAL_DESIGNATORMINIMUM 0x48 +/// Defines the index of the ending designator associated with an array or +/// bitmap. +#define HIDReport_LOCAL_DESIGNATORMAXIMUM 0x58 +/// String index for a string descriptor. +#define HIDReport_LOCAL_STRINGINDEX 0x78 +/// Specifies the first string index when assigning a group of sequential +/// strings to controls in an array or bitmap. +#define HIDReport_LOCAL_STRINGMINIMUM 0x88 +/// Specifies the last string index when assigning a group of sequential +/// strings to controls in an array or bitmap. +#define HIDReport_LOCAL_STRINGMAXIMUM 0x98 +/// Defines the beginning or end of a set of local items. +#define HIDReport_LOCAL_DELIMITER 0xA8 +//------------------------------------------------------------------------------ + +#endif //#ifndef HIDREPORT_H + diff --git a/radio/src/targets/sky9x/usb/common/hid/HIDReportRequest.c b/radio/src/targets/sky9x/usb/common/hid/HIDReportRequest.c new file mode 100644 index 000000000..c707f6811 --- /dev/null +++ b/radio/src/targets/sky9x/usb/common/hid/HIDReportRequest.c @@ -0,0 +1,68 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +/* + Title: HIDReportRequest implementation + + About: Purpose + Implementation of the HIDReportRequest methods. +*/ + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include "HIDReportRequest.h" + +//------------------------------------------------------------------------------ +// Exported functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Indicates the type of report targetted by a SET_REPORT or GET_REPORT +/// request. +/// \param request Pointer to a USBGenericRequest instance. +/// \return Requested report type (see "HID Report Types"). +//------------------------------------------------------------------------------ +unsigned char HIDReportRequest_GetReportType(const USBGenericRequest *request) +{ + return ((USBGenericRequest_GetValue(request) >> 8) & 0xFF); +} + +//------------------------------------------------------------------------------ +/// Indicates the ID of the report targetted by a SET_REPORT or GET_REPORT +/// request. This value should be 0 if report IDs are not used. +/// \param request Pointer to a USBGenericRequest instance. +/// \return Requested report ID. +//------------------------------------------------------------------------------ +unsigned char HIDReportRequest_GetReportId(const USBGenericRequest *request) +{ + return (USBGenericRequest_GetValue(request) & 0xFF); +} + diff --git a/radio/src/targets/sky9x/usb/common/hid/HIDReportRequest.h b/radio/src/targets/sky9x/usb/common/hid/HIDReportRequest.h new file mode 100644 index 000000000..a879e61b7 --- /dev/null +++ b/radio/src/targets/sky9x/usb/common/hid/HIDReportRequest.h @@ -0,0 +1,86 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +/** + \unit + + !!!Purpose + + Definition of a class for manipulating HID-specific GET_REPORT and + SET_REPORT requests. + + !!!Usage + + -# Receive a GET_REPORT or SET_REPORT request from the host. + -# Retrieve the report type using HIDReportRequest_GetReportType. + -# Retrieve the report ID using HIDReportRequest_GetReportId. +*/ + +#ifndef HIDREPORTREQUEST_H +#define HIDREPORTREQUEST_H + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include + +//------------------------------------------------------------------------------ +// Definitions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// \page "HID Report Types" +/// This page lists the types for USB HID Reports. +/// +/// !Types +/// - HIDReportRequest_INPUT +/// - HIDReportRequest_OUTPUT +/// - HIDReportRequest_FEATURE + +/// Input report. +#define HIDReportRequest_INPUT 1 +/// Output report. +#define HIDReportRequest_OUTPUT 2 +/// Feature report. +#define HIDReportRequest_FEATURE 3 +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// Exported functions +//------------------------------------------------------------------------------ + +extern unsigned char HIDReportRequest_GetReportType( + const USBGenericRequest *request); + +extern unsigned char HIDReportRequest_GetReportId( + const USBGenericRequest *request); + +#endif //#ifndef HIDREPORTREQUEST_H + diff --git a/radio/src/targets/sky9x/usb/device/hid-joystick/HIDDJoystickDriver.c b/radio/src/targets/sky9x/usb/device/hid-joystick/HIDDJoystickDriver.c new file mode 100644 index 000000000..48d2fecd2 --- /dev/null +++ b/radio/src/targets/sky9x/usb/device/hid-joystick/HIDDJoystickDriver.c @@ -0,0 +1,356 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include "HIDDJoystickDriver.h" +#include "HIDDJoystickDriverDescriptors.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TRACE_INFO(...) { } +#define TRACE_WARNING(...) { } + +//------------------------------------------------------------------------------ +/// Driver structure for an HID device implementing joystick functionalities. +//------------------------------------------------------------------------------ +typedef struct { + + /// Standard USB device driver instance. + USBDDriver usbdDriver; + /// Idle rate (in milliseconds) of the input report. + unsigned char inputReportIdleRate; + /// + unsigned char inputProtocol; + /// Input report instance. + HIDDJoystickInputReport inputReport; + +} HIDDJoystickDriver; + +//------------------------------------------------------------------------------ +// Internal variables +//------------------------------------------------------------------------------ + +/// Static instance of the HID joystick device driver. +static HIDDJoystickDriver hiddJoystickDriver; + +//------------------------------------------------------------------------------ +// Internal functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Returns the descriptor requested by the host. +/// \param type Descriptor type. +/// \param length Maximum number of bytes to send. +/// \return 1 if the request has been handled by this function, otherwise 0. +//------------------------------------------------------------------------------ +static unsigned char HIDDJoystickDriver_GetDescriptor(unsigned char type, + unsigned char length) +{ + extern int hiddReportDescriptorSize; + + const USBConfigurationDescriptor *pConfiguration; + HIDDescriptor *hidDescriptor; + + switch (type) { + + case HIDGenericDescriptor_REPORT: + TRACE_INFO("Report "); + + // Adjust length and send report descriptor + if (length > hiddReportDescriptorSize) { + + length = hiddReportDescriptorSize; + } + USBD_Write(0, &hiddReportDescriptor, length, 0, 0); + break; + + case HIDGenericDescriptor_HID: + TRACE_INFO("HID "); + + // Configuration descriptor is different depending on configuration + if (USBD_IsHighSpeed()) { + + pConfiguration = + hiddJoystickDriver.usbdDriver.pDescriptors->pHsConfiguration; + } + else { + + pConfiguration = + hiddJoystickDriver.usbdDriver.pDescriptors->pFsConfiguration; + } + + // Parse the device configuration to get the HID descriptor + USBConfigurationDescriptor_Parse(pConfiguration, 0, 0, + (USBGenericDescriptor **) &hidDescriptor); + + // Adjust length and send HID descriptor + if (length > sizeof(HIDDescriptor)) { + + length = sizeof(HIDDescriptor); + } + USBD_Write(0, hidDescriptor, length, 0, 0); + break; + + default: + return 0; + } + + return 1; +} + +//------------------------------------------------------------------------------ +/// Sends the current Idle rate of the input report to the host. +//------------------------------------------------------------------------------ +static void HIDDJoystickDriver_GetIdle() +{ + TRACE_INFO("gIdle "); + + USBD_Write(0, &(hiddJoystickDriver.inputReportIdleRate), 1, 0, 0); +} + +//------------------------------------------------------------------------------ +/// Retrieves the new idle rate of the input report from the USB host. +/// \param idleRate New input report idle rate. +//------------------------------------------------------------------------------ +static void HIDDJoystickDriver_SetIdle(unsigned char idleRate) +{ + TRACE_INFO("sIdle(%d) ", idleRate); + + hiddJoystickDriver.inputReportIdleRate = idleRate; + USBD_Write(0, 0, 0, 0, 0); +} + +//------------------------------------------------------------------------------ +/// Sends the requested report to the host. +/// \param type Report type. +/// \param length Maximum number of bytes to send. +//------------------------------------------------------------------------------ +static void HIDDJoystickDriver_GetReport(unsigned char type, + unsigned short length) +{ + TRACE_INFO("gReport "); + + // Check report type + switch (type) { + + case HIDReportRequest_INPUT: + TRACE_INFO("In "); + + // Adjust size and send report + if (length > sizeof(HIDDJoystickInputReport)) { + + length = sizeof(HIDDJoystickInputReport); + } + USBD_Write(0, // Endpoint #0 + &(hiddJoystickDriver.inputReport), + length, + 0, // No callback + 0); + break; + + default: + USBD_Stall(0); + } +} + +//------------------------------------------------------------------------------ +/// Retrieves the new value of a report from the host and saves it. +/// \param type Report type. +/// \param length Report length. +//------------------------------------------------------------------------------ +static void HIDDJoystickDriver_SetReport(unsigned char type, + unsigned short length) +{ + TRACE_INFO("sReport "); + + // Check report type + switch (type) { + + case HIDReportRequest_INPUT: + // SET_REPORT requests on input reports are ignored + USBD_Stall(0); + break; + + default: + USBD_Stall(0); + } +} + +//------------------------------------------------------------------------------ +// Optional RequestReceived() callback re-implementation +//------------------------------------------------------------------------------ +#if !defined(NOAUTOCALLBACK) + +//------------------------------------------------------------------------------ +/// Callback function when new request receivce from host +/// \param request Pointer to the USBGenericRequest instance +//------------------------------------------------------------------------------ +//void USBDCallbacks_RequestReceived(const USBGenericRequest *request) +//{ +// HIDDJoystickDriver_RequestHandler(request); +//} + +#endif + +//------------------------------------------------------------------------------ +// ConfigurationChanged() callback re-implementation +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Callback function when configureation changed +/// \param cfgnum New configuration number +//------------------------------------------------------------------------------ +//void USBDDriverCallbacks_ConfigurationChanged(unsigned char cfgnum) +//{ +// (void)cfgnum; +//} + +//------------------------------------------------------------------------------ +// Exported functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Initializes the HID Joystick %device driver. +//------------------------------------------------------------------------------ +void HIDDJoystickDriver_Initialize() +{ + hiddJoystickDriver.inputReportIdleRate = 0; + HIDDJoystickInputReport_Initialize(&(hiddJoystickDriver.inputReport)); + USBDDriver_Initialize(&(hiddJoystickDriver.usbdDriver), + &hiddJoystickDriverDescriptors, + 0); // Multiple interface settings not supported + USBD_Init(); +} + +//------------------------------------------------------------------------------ +/// Handles HID-specific SETUP request sent by the host. +/// \param request Pointer to a USBGenericRequest instance +//------------------------------------------------------------------------------ +void HIDDJoystickDriver_RequestHandler(const USBGenericRequest *request) +{ + TRACE_INFO("NewReq "); + + // Check if this is a standard request + if (USBGenericRequest_GetType(request) == USBGenericRequest_STANDARD) { + + // This is a standard request + switch (USBGenericRequest_GetRequest(request)) { + + case USBGenericRequest_GETDESCRIPTOR: + // Check if this is a HID descriptor, otherwise forward it to + // the standard driver + if (!HIDDJoystickDriver_GetDescriptor( + USBGetDescriptorRequest_GetDescriptorType(request), + USBGenericRequest_GetLength(request))) { + + USBDDriver_RequestHandler(&(hiddJoystickDriver.usbdDriver), + request); + } + break; + + default: + USBDDriver_RequestHandler(&(hiddJoystickDriver.usbdDriver), + request); + } + } + // Check if this is a class request + else if (USBGenericRequest_GetType(request) == USBGenericRequest_CLASS) { + + // This is a class-specific request + switch (USBGenericRequest_GetRequest(request)) { + + case HIDGenericRequest_GETIDLE: + HIDDJoystickDriver_GetIdle(); + break; + + case HIDGenericRequest_SETIDLE: + HIDDJoystickDriver_SetIdle(HIDIdleRequest_GetIdleRate(request)); + break; + + case HIDGenericRequest_GETREPORT: + HIDDJoystickDriver_GetReport( + HIDReportRequest_GetReportType(request), + USBGenericRequest_GetLength(request)); + break; + + case HIDGenericRequest_SETREPORT: + HIDDJoystickDriver_SetReport( + HIDReportRequest_GetReportType(request), + USBGenericRequest_GetLength(request)); + break; + + case HIDGenericRequest_GETPROTOCOL: + USBD_Write(0, &hiddJoystickDriver.inputProtocol, 1, 0, 0); + break; + + case HIDGenericRequest_SETPROTOCOL: + hiddJoystickDriver.inputProtocol = request->wValue; + USBD_Write(0, 0, 0, 0, 0); + break; + + default: + TRACE_WARNING( + "HIDDJoystickDriver_RequestHandler: Unknown request 0x%02X\n\r", + USBGenericRequest_GetRequest(request)); + USBD_Stall(0); + } + } + else { + + // Vendor request ? + USBD_Stall(0); + } +} + +//------------------------------------------------------------------------------ +/// Update the Joystick state via input report +/// to host +/// \param report Pointer to a HIDDJoystickInputReport instance +//------------------------------------------------------------------------------ +unsigned char HIDDJoystickDriver_ChangeJoystickState(const HIDDJoystickInputReport *report) +{ + memcpy(&(hiddJoystickDriver.inputReport), report, sizeof(HIDDJoystickInputReport)); + + // Send input report through the interrupt IN endpoint + return USBD_Write(HIDDJoystickDriverDescriptors_INTERRUPTIN, + &(hiddJoystickDriver.inputReport), + sizeof(HIDDJoystickInputReport), + 0, + 0); +} diff --git a/radio/src/targets/sky9x/usb/device/hid-joystick/HIDDJoystickDriver.h b/radio/src/targets/sky9x/usb/device/hid-joystick/HIDDJoystickDriver.h new file mode 100644 index 000000000..a4ed3bff2 --- /dev/null +++ b/radio/src/targets/sky9x/usb/device/hid-joystick/HIDDJoystickDriver.h @@ -0,0 +1,83 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +/** + \unit + + !!!Purpose + + Definition of methods for using a HID joystick device driver. + + !!!Usage + + -# Re-implement the USBDCallbacks_RequestReceived callback to forward + requests to HIDDJoystickDriver_RequestHandler. This is done + automatically unless the NOAUTOCALLBACK symbol is defined during + compilation. + -# Initialize the driver using HIDDJoystickDriver_Initialize. The + USB driver is automatically initialized by this method. + -# Call the HIDDJoystickDriver_ChangePoints method when one or more + keys are pressed/released. +*/ + +#ifndef HIDDJOYSTICKDRIVER_H +#define HIDDJOYSTICKDRIVER_H + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include +#include "HIDDJoystickInputReport.h" + +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ +// Exported functions +//------------------------------------------------------------------------------ +/* + Function: HIDDJoystickDriver_Initialize + Initializes the HID joystick device driver. +*/ +extern void HIDDJoystickDriver_Initialize(); + +/* + Function: HIDDJoystickDriver_RequestHandler + Handles HID-specific SETUP request sent by the host. + + Parameters: + request - Pointer to a USBGenericRequest instance. +*/ +extern void HIDDJoystickDriver_RequestHandler(const USBGenericRequest *request); + +extern unsigned char HIDDJoystickDriver_ChangeJoystickState(const HIDDJoystickInputReport *report); + +#endif //#ifndef HIDDJOYSTICKDRIVER_H + diff --git a/radio/src/targets/sky9x/usb/device/hid-joystick/HIDDJoystickDriverDescriptors.c b/radio/src/targets/sky9x/usb/device/hid-joystick/HIDDJoystickDriverDescriptors.c new file mode 100644 index 000000000..5de76b7e2 --- /dev/null +++ b/radio/src/targets/sky9x/usb/device/hid-joystick/HIDDJoystickDriverDescriptors.c @@ -0,0 +1,297 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +/* + Title: HIDDJoystickDriverDescriptors + + About: Purpose + Declaration of the descriptors used by the HID device joystick driver. +*/ + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include "HIDDJoystickDriverDescriptors.h" +#include "HIDDJoystickInputReport.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//------------------------------------------------------------------------------ +// Definitions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// \page "HID Joystick Device Descriptor IDs" +/// ... +/// +/// !IDs +/// - HIDDJoystickDriverDescriptors_PRODUCTID +/// - HIDDJoystickDriverDescriptors_VENDORID +/// - HIDDJoystickDriverDescriptors_RELEASE + +/// Device product ID. +#define HIDDJoystickDriverDescriptors_PRODUCTID 0x6200 +/// Device vendor ID. +#define HIDDJoystickDriverDescriptors_VENDORID 0x03EB +/// Device release number. +#define HIDDJoystickDriverDescriptors_RELEASE 0x0100 +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// Internal types +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// List of descriptors that make up the configuration descriptors of a +/// %device using the HID Joystick driver. +//------------------------------------------------------------------------------ +typedef struct { + + /// Configuration descriptor. + USBConfigurationDescriptor configuration; + /// Interface descriptor. + USBInterfaceDescriptor interface; + /// HID descriptor. + HIDDescriptor hid; + /// Interrupt IN endpoint descriptor. + USBEndpointDescriptor interruptIn; + +} __attribute__ ((packed)) HIDDJoystickDriverConfigurationDescriptors; + +//------------------------------------------------------------------------------ +// Internal variables +//------------------------------------------------------------------------------ + +#define BOARD_USB_ENDPOINTS_MAXPACKETSIZE(i) (((i == 0)||(i == 3)||(i == 4)) ? 64 :\ + (((i == 1) || (i == 2)) ? 512 : 1024)) + +/// Device descriptor. +static const USBDeviceDescriptor deviceDescriptor = { + + sizeof(USBDeviceDescriptor), + USBGenericDescriptor_DEVICE, + USBDeviceDescriptor_USB2_00, + HIDDeviceDescriptor_CLASS, + HIDDeviceDescriptor_SUBCLASS, + HIDDeviceDescriptor_PROTOCOL, + BOARD_USB_ENDPOINTS_MAXPACKETSIZE(0), + HIDDJoystickDriverDescriptors_VENDORID, + HIDDJoystickDriverDescriptors_PRODUCTID, + HIDDJoystickDriverDescriptors_RELEASE, + 1, // Index of manufacturer description + 2, // Index of product description + 3, // Index of serial number description + 1 // One possible configuration +}; + +/// Report descriptor used by the driver. +const unsigned char hiddReportDescriptor[] = { + + HIDReport_GLOBAL_USAGEPAGE + 1, HIDGenericDesktop_PAGEID, // USAGE_PAGE (Generic Desktop) + HIDReport_LOCAL_USAGE + 1, HIDGenericDesktop_GAMEPAD, // USAGE (Game Pad) + HIDReport_COLLECTION + 1, HIDReport_COLLECTION_APPLICATION, // COLLECTION (Application) + HIDReport_COLLECTION + 1, HIDReport_COLLECTION_PHYSICAL, // COLLECTION (Physical) + HIDReport_GLOBAL_USAGEPAGE + 1, HIDButton_PAGEID, // USAGE_PAGE (Button) + HIDReport_LOCAL_USAGEMINIMUM + 1, 1, // USAGE_MINIMUM (Button 1) + HIDReport_LOCAL_USAGEMAXIMUM + 1, 24, // USAGE_MAXIMUM (Button 24) + HIDReport_GLOBAL_LOGICALMINIMUM + 1, 0, // LOGICAL_MINIMUM (0) + HIDReport_GLOBAL_LOGICALMAXIMUM + 1, 1, // LOGICAL_MAXIMUM (1) + HIDReport_GLOBAL_REPORTCOUNT + 1, 24, // REPORT_COUNT (24) + HIDReport_GLOBAL_REPORTSIZE + 1, 1, // REPORT_SIZE (1) + HIDReport_INPUT + 1, HIDReport_VARIABLE, // INPUT (Data,Var,Abs) + HIDReport_GLOBAL_USAGEPAGE + 1, HIDGenericDesktop_PAGEID, // USAGE_PAGE (Generic Desktop) + HIDReport_LOCAL_USAGE + 1, HIDGenericDesktop_X_AXIS, // USAGE (X) + HIDReport_LOCAL_USAGE + 1, HIDGenericDesktop_Y_AXIS, // USAGE (Y) + HIDReport_LOCAL_USAGE + 1, HIDGenericDesktop_Z_AXIS, // USAGE (Z) + HIDReport_LOCAL_USAGE + 1, HIDGenericDesktop_X_ROTATION, // USAGE (Rx) + HIDReport_LOCAL_USAGE + 1, HIDGenericDesktop_Y_ROTATION, // USAGE (Ry) + HIDReport_LOCAL_USAGE + 1, HIDGenericDesktop_Z_ROTATION, // USAGE (Rz) + HIDReport_LOCAL_USAGE + 1, HIDGenericDesktop_SLIDER, // USAGE (Slider) + HIDReport_LOCAL_USAGE + 1, HIDGenericDesktop_SLIDER, // USAGE (Slider) + HIDReport_GLOBAL_LOGICALMINIMUM + 1, (unsigned char) -127, // LOGICAL_MINIMUM (-127) + HIDReport_GLOBAL_LOGICALMAXIMUM + 1, 127, // LOGICAL_MAXIMUM (127) + HIDReport_GLOBAL_REPORTSIZE + 1, 8, // REPORT_SIZE (8) + HIDReport_GLOBAL_REPORTCOUNT + 1, 8, // REPORT_COUNT (8) + HIDReport_INPUT + 1, HIDReport_VARIABLE, // INPUT (Data,Var,Abs) + HIDReport_ENDCOLLECTION, // END_COLLECTION + HIDReport_ENDCOLLECTION // END_COLLECTION +}; +int hiddReportDescriptorSize = sizeof(hiddReportDescriptor); + +/// Configuration descriptor. +static const HIDDJoystickDriverConfigurationDescriptors configurationDescriptors = { + + // Configuration descriptor + { + sizeof(USBConfigurationDescriptor), + USBGenericDescriptor_CONFIGURATION, + sizeof(HIDDJoystickDriverConfigurationDescriptors), + 1, // One interface in this configuration + 1, // This is configuration #1 + 0, // No associated string descriptor + BOARD_USB_BMATTRIBUTES, + USBConfigurationDescriptor_POWER(100) + }, + // Interface descriptor + { + sizeof(USBInterfaceDescriptor), + USBGenericDescriptor_INTERFACE, + 0, // This is interface #0 + 0, // This is alternate setting #0 + 1, // One endpoints used + HIDInterfaceDescriptor_CLASS, + HIDInterfaceDescriptor_SUBCLASS_NONE, + HIDInterfaceDescriptor_PROTOCOL_NONE, + 0 // No associated string descriptor + }, + // HID descriptor + { + sizeof(HIDDescriptor), + HIDGenericDescriptor_HID, + HIDDescriptor_HID1_11, + 0, // Device is not localized, no country code + 1, // One HID-specific descriptor (apart from this one) + HIDGenericDescriptor_REPORT, + sizeof(hiddReportDescriptor), + }, + // Interrupt IN endpoint descriptor + { + sizeof(USBEndpointDescriptor), + USBGenericDescriptor_ENDPOINT, // 5 + USBEndpointDescriptor_ADDRESS( + USBEndpointDescriptor_IN, + HIDDJoystickDriverDescriptors_INTERRUPTIN), + USBEndpointDescriptor_INTERRUPT, + sizeof(HIDDJoystickInputReport), + HIDDJoystickDriverDescriptors_INTERRUPTIN_POLLING + } +}; + +/* + Variables: String descriptors + languageIdDescriptor - Language ID string descriptor. + manufacturerDescriptor - Manufacturer name. + productDescriptor - Product name. + serialNumberDescriptor - Product serial number. + stringDescriptors - Array of pointers to string descriptors. +*/ +static const unsigned char languageIdDescriptor[] = { + + USBStringDescriptor_LENGTH(1), + USBGenericDescriptor_STRING, + USBStringDescriptor_ENGLISH_US +}; + +static const unsigned char manufacturerDescriptor[] = { + + USBStringDescriptor_LENGTH(5), + USBGenericDescriptor_STRING, + USBStringDescriptor_UNICODE('A'), + USBStringDescriptor_UNICODE('T'), + USBStringDescriptor_UNICODE('M'), + USBStringDescriptor_UNICODE('E'), + USBStringDescriptor_UNICODE('L') +}; + +static const unsigned char productDescriptor[] = { + + USBStringDescriptor_LENGTH(14), + USBGenericDescriptor_STRING, + USBStringDescriptor_UNICODE('S'), + USBStringDescriptor_UNICODE('K'), + USBStringDescriptor_UNICODE('Y'), + USBStringDescriptor_UNICODE('9'), + USBStringDescriptor_UNICODE('X'), + USBStringDescriptor_UNICODE(' '), + USBStringDescriptor_UNICODE('J'), + USBStringDescriptor_UNICODE('o'), + USBStringDescriptor_UNICODE('y'), + USBStringDescriptor_UNICODE('s'), + USBStringDescriptor_UNICODE('t'), + USBStringDescriptor_UNICODE('i'), + USBStringDescriptor_UNICODE('c'), + USBStringDescriptor_UNICODE('k'), +}; + +static const unsigned char serialNumberDescriptor[] = { + + USBStringDescriptor_LENGTH(12), + USBGenericDescriptor_STRING, + USBStringDescriptor_UNICODE('0'), + USBStringDescriptor_UNICODE('1'), + USBStringDescriptor_UNICODE('2'), + USBStringDescriptor_UNICODE('3'), + USBStringDescriptor_UNICODE('4'), + USBStringDescriptor_UNICODE('5'), + USBStringDescriptor_UNICODE('6'), + USBStringDescriptor_UNICODE('7'), + USBStringDescriptor_UNICODE('8'), + USBStringDescriptor_UNICODE('9'), + USBStringDescriptor_UNICODE('A'), + USBStringDescriptor_UNICODE('F') +}; + +static const unsigned char *stringDescriptors[] = { + + languageIdDescriptor, + manufacturerDescriptor, + productDescriptor, + serialNumberDescriptor +}; + +//------------------------------------------------------------------------------ +// Exported variables +//------------------------------------------------------------------------------ + +/// List of descriptors used by the HID joystick driver. +USBDDriverDescriptors hiddJoystickDriverDescriptors = { + + &deviceDescriptor, + (USBConfigurationDescriptor *) &configurationDescriptors, + 0, // No full-speed device qualifier descriptor + 0, // No full-speed other speed configuration + 0, // No high-speed device descriptor + 0, // No high-speed configuration descriptor + 0, // No high-speed device qualifier descriptor + 0, // No high-speed other speed configuration descriptor + stringDescriptors, + 4 // Four string descriptors in list +}; diff --git a/radio/src/targets/sky9x/usb/device/hid-joystick/HIDDJoystickDriverDescriptors.h b/radio/src/targets/sky9x/usb/device/hid-joystick/HIDDJoystickDriverDescriptors.h new file mode 100644 index 000000000..b9c774016 --- /dev/null +++ b/radio/src/targets/sky9x/usb/device/hid-joystick/HIDDJoystickDriverDescriptors.h @@ -0,0 +1,79 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +/** + \unit + + !!!Purpose + + Definitions of the descriptors required by the HID device joystick + driver. + + !!!Usage + -# Use the hiddJoystickDriverDescriptors variable to initialize a + USBDDriver instance. + -# Send hiddReportDescriptor to the host when a GET_DESCRIPTOR request + for the report descriptor is received. +*/ + +#ifndef HIDDJOYSTICKDRIVERDESCRIPTORS_H +#define HIDDJOYSTICKDRIVERDESCRIPTORS_H + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include + +//------------------------------------------------------------------------------ +// Definitions +//------------------------------------------------------------------------------ +/* + Constants: Endpoints + HIDDJoystickDriverDescriptors_INTERRUPTIN - Interrupt IN endpoint number. + HIDDJoystickDriverDescriptors_INTERRUPTIN_POLLING - Interrupt IN endpoint + polling rate (in milliseconds). +*/ +#define HIDDJoystickDriverDescriptors_INTERRUPTIN 1 +#define HIDDJoystickDriverDescriptors_INTERRUPTIN_POLLING 10 + +//------------------------------------------------------------------------------ +// Exported variables +//------------------------------------------------------------------------------ +/* + Variables: HID joystick driver descriptors + hiddJoystickDriverDescriptors - List of descriptors used by the HID + joystick driver. + hiddReportDescriptor - Report descriptor used by the driver. +*/ +extern USBDDriverDescriptors hiddJoystickDriverDescriptors; +extern const unsigned char hiddReportDescriptor[]; + +#endif //#ifndef HIDDJOYSTICKDRIVERDESCRIPTORS_H + diff --git a/radio/src/targets/sky9x/usb/device/hid-joystick/HIDDJoystickInputReport.c b/radio/src/targets/sky9x/usb/device/hid-joystick/HIDDJoystickInputReport.c new file mode 100644 index 000000000..3fafe5cca --- /dev/null +++ b/radio/src/targets/sky9x/usb/device/hid-joystick/HIDDJoystickInputReport.c @@ -0,0 +1,64 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +/* + Title: HIDDJoystickInputReport implementation + + About: Purpose + Implementation of the HIDDJoystickInputReport class. +*/ + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include "HIDDJoystickInputReport.h" + +//------------------------------------------------------------------------------ +// Exported functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Initializes a joystick input report instance. +/// \param report Pointer to a HIDDJoystickInputReport instance. +//------------------------------------------------------------------------------ +void HIDDJoystickInputReport_Initialize(HIDDJoystickInputReport *report) +{ + report->buttons1 = 0; + report->buttons2 = 0; + report->buttons3 = 0; + report->X = 0; + report->Y = 0; + report->Z = 0; + report->Rx = 0; + report->Ry = 0; + report->Rz = 0; + report->S1 = 0; + report->S2 = 0; +} diff --git a/radio/src/targets/sky9x/usb/device/hid-joystick/HIDDJoystickInputReport.h b/radio/src/targets/sky9x/usb/device/hid-joystick/HIDDJoystickInputReport.h new file mode 100644 index 000000000..42af51e3f --- /dev/null +++ b/radio/src/targets/sky9x/usb/device/hid-joystick/HIDDJoystickInputReport.h @@ -0,0 +1,86 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +/** + \unit + + !!!Purpose + + Class for manipulating HID Joystick input reports. + + !!!Usage + + -# Initialize a newly created input report with + HIDDJoystickInputReport_Initialize +*/ + +#ifndef HIDDJOYSTICKINPUTREPORT_H +#define HIDDJOYSTICKINPUTREPORT_H + +//------------------------------------------------------------------------------ +// Types +//------------------------------------------------------------------------------ + +#ifdef __ICCARM__ // IAR +#pragma pack(1) // IAR +#define __attribute__(...) // IAR +#endif // IAR + +//------------------------------------------------------------------------------ +/// HID input report structure used by the Joystick driver to notify the +/// host of pressed keys. +//------------------------------------------------------------------------------ +typedef struct { + + unsigned char buttons1; // bit 0 - button 1, bit 1 - button 2, ..., mapped to channels 9-16, on if channel > 0 + unsigned char buttons2; // mapped to channels 17-24, on if channel > 0 + unsigned char buttons3; // mapped to channels 25-32, on if channel > 0 + unsigned char X; // analog value, mapped to channel 1 + unsigned char Y; // analog value, mapped to channel 2 + unsigned char Z; // analog value, mapped to channel 3 + unsigned char Rx; // analog value, mapped to channel 4 + unsigned char Ry; // analog value, mapped to channel 5 + unsigned char Rz; // analog value, mapped to channel 6 + unsigned char S1; // analog value, mapped to channel 7 + unsigned char S2; // analog value, mapped to channel 8 + +} __attribute__ ((packed)) HIDDJoystickInputReport; // GCC + +#ifdef __ICCARM__ // IAR +#pragma pack() // IAR +#endif // IAR + +//------------------------------------------------------------------------------ +// Exported functions +//------------------------------------------------------------------------------ + +extern void HIDDJoystickInputReport_Initialize(HIDDJoystickInputReport *report); + +#endif //#ifndef HIDDJOYSTICKINPUTREPORT_H + diff --git a/radio/src/targets/sky9x/usb/device/massstorage/MSDDriver.c b/radio/src/targets/sky9x/usb/device/massstorage/MSDDriver.c index b05c43c2a..c5439a27b 100644 --- a/radio/src/targets/sky9x/usb/device/massstorage/MSDDriver.c +++ b/radio/src/targets/sky9x/usb/device/massstorage/MSDDriver.c @@ -76,23 +76,23 @@ static void MSDDriver_Reset(void) /// request to the Mass Storage device driver handler function. /// \param request Pointer to a USBGenericRequest instance. //----------------------------------------------------------------------------- -void USBDCallbacks_RequestReceived(const USBGenericRequest *request) -{ - MSDDriver_RequestHandler(request); -} +//void USBDCallbacks_RequestReceived(const USBGenericRequest *request) +//{ +// MSDDriver_RequestHandler(request); +//} //----------------------------------------------------------------------------- /// Invoked when the configuration of the device changes. Resets the mass /// storage driver. /// \param cfgnum New configuration number. //----------------------------------------------------------------------------- -void USBDDriverCallbacks_ConfigurationChanged(unsigned char cfgnum) -{ - if (cfgnum > 0) { +//void USBDDriverCallbacks_ConfigurationChanged(unsigned char cfgnum) +//{ +// if (cfgnum > 0) { - MSDDriver_Reset(); - } -} +// MSDDriver_Reset(); +// } +//} //----------------------------------------------------------------------------- // Driver functions diff --git a/radio/src/targets/sky9x/usb_driver.cpp b/radio/src/targets/sky9x/usb_driver.cpp new file mode 100644 index 000000000..babb17c2f --- /dev/null +++ b/radio/src/targets/sky9x/usb_driver.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +// TODO: enable masstorage & implement choice between masstorage and joystick + +extern "C" { +#include "usb/device/hid-joystick/HIDDJoystickDriver.h" +#include "usb/device/massstorage/MSDDriver.h" +} + +extern "C" void USBDDriverCallbacks_ConfigurationChanged(unsigned char cfgnum) +{ +// if (selectedUsbMode == USB_JOYSTICK_MODE) { + (void)cfgnum; +// } else if (selectedUsbMode == USB_MASS_STORAGE_MODE){ +// MSDDriver_Reset(); +// } +} + +extern "C" void USBDCallbacks_RequestReceived(const USBGenericRequest *request) +{ +// if (selectedUsbMode == USB_JOYSTICK_MODE) { + HIDDJoystickDriver_RequestHandler(request); +// } else if (selectedUsbMode == USB_MASS_STORAGE_MODE){ +// MSDDriver_RequestHandler(request); +// } +} diff --git a/radio/src/targets/taranis/CMakeLists.txt b/radio/src/targets/taranis/CMakeLists.txt index d04a4e634..b4bd44e53 100644 --- a/radio/src/targets/taranis/CMakeLists.txt +++ b/radio/src/targets/taranis/CMakeLists.txt @@ -258,7 +258,6 @@ set(GUI_SRC view_telemetry.cpp view_about.cpp bmp.cpp - ../screenshot.cpp ) if(STATUS_LEDS) diff --git a/radio/src/targets/taranis/board.h b/radio/src/targets/taranis/board.h index f50030bca..a899d3551 100644 --- a/radio/src/targets/taranis/board.h +++ b/radio/src/targets/taranis/board.h @@ -625,11 +625,13 @@ void backlightInit(); void backlightDisable(); #define BACKLIGHT_DISABLE() backlightDisable() uint8_t isBacklightEnabled(); -#if defined(PCBX9E) || defined(PCBX9DP) - void backlightEnable(uint8_t level, uint8_t color); +#if !defined(__cplusplus) + #define backlightEnable(...) +#elif defined(PCBX9E) || defined(PCBX9DP) + void backlightEnable(uint8_t level = 0, uint8_t color = 0); #define BACKLIGHT_ENABLE() backlightEnable(g_eeGeneral.backlightBright, g_eeGeneral.backlightColor) #else - void backlightEnable(uint8_t level); + void backlightEnable(uint8_t level = 0); #define BACKLIGHT_ENABLE() backlightEnable(g_eeGeneral.backlightBright) #endif @@ -848,7 +850,8 @@ void setTopBatteryValue(uint32_t volts); #endif extern Fifo telemetryFifo; -extern DMAFifo<32> auxSerialRxFifo; +typedef DMAFifo<32> AuxSerialRxFifo; +extern AuxSerialRxFifo auxSerialRxFifo; #endif // Gyro driver diff --git a/radio/src/targets/taranis/hal.h b/radio/src/targets/taranis/hal.h index a4cba3fda..ea0d08f95 100644 --- a/radio/src/targets/taranis/hal.h +++ b/radio/src/targets/taranis/hal.h @@ -912,7 +912,6 @@ #else #define INTERNAL_MODULE_PXX1 #endif -#define INTMODULE_FLASH_BAUDRATE 57600 #if defined(PCBXLITE) || defined(PCBX9LITE) #define INTMODULE_RCC_APB1Periph 0 #define INTMODULE_RCC_APB2Periph RCC_APB2Periph_USART1 diff --git a/radio/src/tasks.cpp b/radio/src/tasks.cpp index 449d61db5..17446d3a2 100644 --- a/radio/src/tasks.cpp +++ b/radio/src/tasks.cpp @@ -107,7 +107,7 @@ TASK_FUNCTION(mixerTask) static uint32_t lastRunTime; s_pulses_paused = true; - while (1) { + while (true) { #if defined(PCBTARANIS) && defined(SBUS) // SBUS trainer processSbusInput(); @@ -180,11 +180,13 @@ TASK_FUNCTION(mixerTask) } #endif -#if defined(TELEMETRY_FRSKY) +#if defined(PCBSKY9X) && !defined(SIMU) + usbJoystickUpdate(); +#endif + DEBUG_TIMER_START(debugTimerTelemetryWakeup); telemetryWakeup(); DEBUG_TIMER_STOP(debugTimerTelemetryWakeup); -#endif if (heartbeat == HEART_WDT_CHECK) { wdt_reset(); diff --git a/radio/src/telemetry/crossfire.cpp b/radio/src/telemetry/crossfire.cpp index f6bf04f21..ebe2bb869 100644 --- a/radio/src/telemetry/crossfire.cpp +++ b/radio/src/telemetry/crossfire.cpp @@ -129,7 +129,7 @@ void processCrossfireTelemetryFrame() for (unsigned int i=0; i<=TX_SNR_INDEX; i++) { if (getCrossfireTelemetryValue<1>(3+i, value)) { if (i == TX_POWER_INDEX) { - static const int32_t power_values[] = { 0, 10, 25, 100, 500, 1000, 2000 }; + static const int32_t power_values[] = { 0, 10, 25, 100, 500, 1000, 2000, 250 }; value = ((unsigned)value < DIM(power_values) ? power_values[value] : 0); } processCrossfireTelemetryValue(i, value); diff --git a/radio/src/telemetry/frsky.cpp b/radio/src/telemetry/frsky.cpp index 6ae34863a..0bf13e407 100644 --- a/radio/src/telemetry/frsky.cpp +++ b/radio/src/telemetry/frsky.cpp @@ -100,13 +100,11 @@ bool pushFrskyTelemetryData(uint8_t data) } // switch -#if defined(TELEMETRY_FRSKY_SPORT) if (IS_FRSKY_SPORT_PROTOCOL() && telemetryRxBufferCount >= FRSKY_SPORT_PACKET_SIZE) { // end of frame detected dataState = STATE_DATA_IDLE; return true; } -#endif return false; } diff --git a/radio/src/telemetry/frsky_pxx2.cpp b/radio/src/telemetry/frsky_pxx2.cpp index 52a5e86e6..e9db1fd88 100644 --- a/radio/src/telemetry/frsky_pxx2.cpp +++ b/radio/src/telemetry/frsky_pxx2.cpp @@ -18,7 +18,6 @@ * GNU General Public License for more details. */ -#include #include "opentx.h" class Pxx2Telemetry diff --git a/radio/src/telemetry/telemetry.cpp b/radio/src/telemetry/telemetry.cpp index 6d7a1ea6d..ac3a38a5b 100644 --- a/radio/src/telemetry/telemetry.cpp +++ b/radio/src/telemetry/telemetry.cpp @@ -18,7 +18,7 @@ * GNU General Public License for more details. */ -#include +#include "opentx.h" uint8_t telemetryStreaming = 0; uint8_t R9ModuleStreaming = 0; @@ -200,7 +200,9 @@ void telemetryWakeup() } else if (telemetryState == TELEMETRY_OK) { telemetryState = TELEMETRY_KO; - AUDIO_TELEMETRY_LOST(); + if (!isModuleInBeepMode()) { + AUDIO_TELEMETRY_LOST(); + } } } } diff --git a/radio/src/telemetry/telemetry.h b/radio/src/telemetry/telemetry.h index 2c9a8f692..d2f6dadc7 100644 --- a/radio/src/telemetry/telemetry.h +++ b/radio/src/telemetry/telemetry.h @@ -21,11 +21,7 @@ #ifndef _TELEMETRY_H_ #define _TELEMETRY_H_ -#if defined(TELEMETRY_FRSKY) - // FrSky Telemetry - #include "frsky.h" -#endif - +#include "frsky.h" #include "crossfire.h" #if defined(MULTIMODULE) #include "spektrum.h" diff --git a/radio/src/telemetry/telemetry_sensors.cpp b/radio/src/telemetry/telemetry_sensors.cpp index 8e4e72829..779e072c6 100644 --- a/radio/src/telemetry/telemetry_sensors.cpp +++ b/radio/src/telemetry/telemetry_sensors.cpp @@ -34,7 +34,6 @@ bool isFaiForbidden(source_t idx) TelemetrySensor * sensor = &g_model.telemetrySensors[(idx-MIXSRC_FIRST_TELEM)/3]; switch (telemetryProtocol) { - case PROTOCOL_TELEMETRY_FRSKY_SPORT: if (sensor->id == RSSI_ID) { return false; @@ -355,11 +354,20 @@ void TelemetryItem::eval(const TelemetrySensor & sensor) } } uint32_t angle = abs(gpsItem.gps.latitude - gpsItem.pilotLatitude); +#if defined(STM32) uint32_t dist = uint64_t(EARTH_RADIUS * M_PI / 180) * angle / 1000000; +#else + // TODO search later why it breaks Sky9x + uint32_t dist = EARTH_RADIUS * angle / 1000000; +#endif uint32_t result = dist * dist; angle = abs(gpsItem.gps.longitude - gpsItem.pilotLongitude); +#if defined(STM32) dist = uint64_t(gpsItem.distFromEarthAxis) * angle / 1000000; +#else + dist = gpsItem.distFromEarthAxis * angle / 1000000; +#endif result += dist * dist; // Length on ground (ignoring curvature of the earth) @@ -501,16 +509,12 @@ int setTelemetryValue(TelemetryProtocol protocol, uint16_t id, uint8_t subId, ui int index = availableTelemetryIndex(); if (index >= 0) { switch (protocol) { -#if defined(TELEMETRY_FRSKY_SPORT) case TELEM_PROTO_FRSKY_SPORT: frskySportSetDefault(index, id, subId, instance); break; -#endif -#if defined(TELEMETRY_FRSKY) case TELEM_PROTO_FRSKY_D: frskyDSetDefault(index, id); break; -#endif #if defined(CROSSFIRE) case TELEM_PROTO_CROSSFIRE: crossfireSetDefault(index, id, instance); diff --git a/radio/src/tests/CMakeLists.txt b/radio/src/tests/CMakeLists.txt index bef6b072e..73e1b34b0 100644 --- a/radio/src/tests/CMakeLists.txt +++ b/radio/src/tests/CMakeLists.txt @@ -4,23 +4,35 @@ find_path(GTEST_INCDIR gtest/gtest.h HINTS "${GTEST_ROOT}/include" DOC "Path to find_path(GTEST_SRCDIR src/gtest-all.cc HINTS "${GTEST_ROOT}" "${GTEST_ROOT}/src/gtest" DOC "Path of Google Test 'src' folder.") if(GTEST_INCDIR AND GTEST_SRCDIR AND Qt5Widgets_FOUND) - add_library(gtests-lib STATIC EXCLUDE_FROM_ALL ${GTEST_SRCDIR}/src/gtest-all.cc ) - target_include_directories(gtests-lib PUBLIC ${GTEST_INCDIR} ${GTEST_INCDIR}/gtest ${GTEST_SRCDIR}) + add_library(gtests-radio-lib STATIC EXCLUDE_FROM_ALL ${GTEST_SRCDIR}/src/gtest-all.cc ) + target_include_directories(gtests-radio-lib PUBLIC ${GTEST_INCDIR} ${GTEST_INCDIR}/gtest ${GTEST_SRCDIR}) add_definitions(-DSIMU) add_definitions(-DGTESTS) remove_definitions(-DCLI) - set(TESTS_PATH ${RADIO_SRC_DIRECTORY}) + set(TESTS_PATH ${RADIO_SRC_DIRECTORY}/tests) configure_file(${RADIO_SRC_DIRECTORY}/tests/location.h.in ${CMAKE_CURRENT_BINARY_DIR}/location.h @ONLY) include_directories(${CMAKE_CURRENT_BINARY_DIR}) + if(PCB STREQUAL X12S OR PCB STREQUAL X10) + add_custom_command( + MAIN_DEPENDENCY ${TESTS_PATH}/model_22_x10.otx + OUTPUT ${TESTS_PATH}/model_22_x10/RADIO/radio.bin ${TESTS_PATH}/model_22_x10/RADIO/models.txt ${TESTS_PATH}/model_22_x10/MODELS/model1.bin + COMMAND mkdir -p model_22_x10 && cd model_22_x10 && unzip -o -DD ../model_22_x10.otx + WORKING_DIRECTORY ${TESTS_PATH} + ) + add_custom_target(x10-model-test-files + DEPENDS ${TESTS_PATH}/model_22_x10/RADIO/radio.bin ${TESTS_PATH}/model_22_x10/RADIO/models.txt ${TESTS_PATH}/model_22_x10/MODELS/model1.bin + ) + endif() + if(WIN32) - target_include_directories(gtests-lib PUBLIC ${WIN_INCLUDE_DIRS}) - target_link_libraries(gtests-lib PRIVATE ${WIN_LINK_LIBRARIES}) + target_include_directories(gtests-radio-lib PUBLIC ${WIN_INCLUDE_DIRS}) + target_link_libraries(gtests-radio-lib PRIVATE ${WIN_LINK_LIBRARIES}) endif(WIN32) if(SDL_FOUND AND SIMU_AUDIO) - target_include_directories(gtests-lib PUBLIC ${SDL_INCLUDE_DIR}) - target_link_libraries(gtests-lib PRIVATE ${SDL_LIBRARY}) + target_include_directories(gtests-radio-lib PUBLIC ${SDL_INCLUDE_DIR}) + target_link_libraries(gtests-radio-lib PRIVATE ${SDL_LIBRARY}) endif() foreach(FILE ${SRC}) @@ -38,9 +50,12 @@ if(GTEST_INCDIR AND GTEST_SRCDIR AND Qt5Widgets_FOUND) use_cxx11() # ensure gnu++11 in CXX_FLAGS with CMake < 3.1 - add_executable(gtests EXCLUDE_FROM_ALL ${TEST_SRC_FILES} ${CMAKE_CURRENT_SOURCE_DIR}/location.h ${RADIO_SRC} ../targets/simu/simpgmspace.cpp ../targets/simu/simueeprom.cpp ../targets/simu/simufatfs.cpp) - add_dependencies(gtests ${FIRMWARE_DEPENDENCIES} gtests-lib) - target_link_libraries(gtests gtests-lib pthread Qt5::Core Qt5::Widgets) + add_executable(gtests-radio EXCLUDE_FROM_ALL ${TEST_SRC_FILES} ${CMAKE_CURRENT_SOURCE_DIR}/location.h ${RADIO_SRC} ../targets/simu/simpgmspace.cpp ../targets/simu/simueeprom.cpp ../targets/simu/simufatfs.cpp) + add_dependencies(gtests-radio ${FIRMWARE_DEPENDENCIES} gtests-radio-lib) + if(PCB STREQUAL X12S OR PCB STREQUAL X10) + add_dependencies(gtests-radio x10-model-test-files) + endif() + target_link_libraries(gtests-radio gtests-radio-lib pthread Qt5::Core Qt5::Widgets) message(STATUS "Added optional gtests target") else() message(WARNING "WARNING: gtests target will not be available (check that GTEST_INCDIR, GTEST_SRCDIR, and Qt5Widgets are configured).") diff --git a/radio/src/tests/MODELS/model_22_horus.bin b/radio/src/tests/MODELS/model_22_horus.bin deleted file mode 100644 index 2ecad1c2f..000000000 Binary files a/radio/src/tests/MODELS/model_22_horus.bin and /dev/null differ diff --git a/radio/src/tests/conversions.cpp b/radio/src/tests/conversions.cpp index 0726e29ee..be5c3d96e 100644 --- a/radio/src/tests/conversions.cpp +++ b/radio/src/tests/conversions.cpp @@ -33,12 +33,26 @@ void loadEEPROMFile(const char * filename) #if defined(PCBX9DP) TEST(Conversions, ConversionX9DPFrom22) { - loadEEPROMFile(TESTS_PATH "/tests/eeprom_22_x9d+.bin"); + loadEEPROMFile(TESTS_PATH "/eeprom_22_x9d+.bin"); eepromOpen(); + eeLoadGeneralSettingsData(); + convertRadioData_218_to_219(g_eeGeneral); eeConvertModel(0, 218); eeLoadModel(0); + EXPECT_EQ(-30, g_eeGeneral.vBatMin); + EXPECT_EQ(8, g_eeGeneral.speakerVolume); + EXPECT_EQ('e', g_eeGeneral.ttsLanguage[0]); + EXPECT_EQ('n', g_eeGeneral.ttsLanguage[1]); + + EXPECT_EQ(SWSRC_TELEMETRY_STREAMING, g_eeGeneral.customFn[0].swtch); + EXPECT_EQ(FUNC_LOGS, g_eeGeneral.customFn[0].func); + EXPECT_EQ(20, g_eeGeneral.customFn[0].all.val); + + EXPECT_ZSTREQ("Tes", g_eeGeneral.switchNames[0]); + EXPECT_EQ(SWITCH_3POS, SWITCH_CONFIG(0)); + EXPECT_ZSTREQ("Test", g_model.header.name); EXPECT_EQ(TMRMODE_COUNT - 1 + SWSRC_SA0, g_model.timers[0].mode); EXPECT_EQ(80, g_model.mixData[0].weight); @@ -53,18 +67,33 @@ TEST(Conversions, ConversionX9DPFrom22) EXPECT_ZSTREQ("Tes", g_model.telemetrySensors[0].label); EXPECT_EQ(10, g_model.telemetrySensors[0].id); EXPECT_EQ(9, g_model.telemetrySensors[0].frskyInstance.physID); + EXPECT_EQ(MIXSRC_FIRST_TELEM, g_model.logicalSw[0].v1); } #endif #if defined(PCBX7) TEST(Conversions, ConversionX7From22) { - loadEEPROMFile(TESTS_PATH "/tests/eeprom_22_x7.bin"); + loadEEPROMFile(TESTS_PATH "/eeprom_22_x7.bin"); eepromOpen(); + eeLoadGeneralSettingsData(); + convertRadioData_218_to_219(g_eeGeneral); eeConvertModel(0, 218); eeLoadModel(0); + EXPECT_EQ(-30, g_eeGeneral.vBatMin); + EXPECT_EQ(8, g_eeGeneral.speakerVolume); + EXPECT_EQ('e', g_eeGeneral.ttsLanguage[0]); + EXPECT_EQ('n', g_eeGeneral.ttsLanguage[1]); + + EXPECT_EQ(SWSRC_TELEMETRY_STREAMING, g_eeGeneral.customFn[0].swtch); + EXPECT_EQ(FUNC_LOGS, g_eeGeneral.customFn[0].func); + EXPECT_EQ(20, g_eeGeneral.customFn[0].all.val); + + EXPECT_ZSTREQ("Tes", g_eeGeneral.switchNames[0]); + EXPECT_EQ(SWITCH_3POS, SWITCH_CONFIG(0)); + EXPECT_ZSTREQ("Test", g_model.header.name); EXPECT_EQ(MODULE_TYPE_R9M_PXX1, g_model.moduleData[EXTERNAL_MODULE].type); EXPECT_EQ(MODULE_SUBTYPE_R9M_EU, g_model.moduleData[EXTERNAL_MODULE].subType); @@ -96,20 +125,61 @@ TEST(Conversions, ConversionX7From22) #endif #if defined(PCBX10) -TEST(Conversions, ConversionHorusFrom22) +TEST(Conversions, ConversionX10From22) { - simuFatfsSetPaths(TESTS_PATH "/tests/", TESTS_PATH "/tests/"); - loadModel("model_22_horus.bin"); + simuFatfsSetPaths(TESTS_PATH "/model_22_x10/", TESTS_PATH "/model_22_x10/"); + + loadRadioSettings("/RADIO/radio.bin"); + loadModel("model1.bin"); + + EXPECT_EQ(219, g_eeGeneral.version); + + EXPECT_EQ(100, g_eeGeneral.calib[9].spanNeg); + EXPECT_EQ(500, g_eeGeneral.calib[9].mid); + EXPECT_EQ(900, g_eeGeneral.calib[9].spanPos); + + EXPECT_EQ(200, g_eeGeneral.calib[10].spanNeg); + EXPECT_EQ(400, g_eeGeneral.calib[10].mid); + EXPECT_EQ(600, g_eeGeneral.calib[10].spanPos); + + EXPECT_EQ(-23, g_eeGeneral.vBatMin); + EXPECT_EQ(8, g_eeGeneral.speakerVolume); + EXPECT_STRNEQ("en", g_eeGeneral.ttsLanguage); + EXPECT_STRNEQ("model1.bin", g_eeGeneral.currModelFilename); + + EXPECT_EQ(SWSRC_TELEMETRY_STREAMING, g_eeGeneral.customFn[0].swtch); + EXPECT_EQ(FUNC_LOGS, g_eeGeneral.customFn[0].func); + EXPECT_EQ(20, g_eeGeneral.customFn[0].all.val); + + EXPECT_EQ(SWSRC_ON, g_eeGeneral.customFn[1].swtch); + EXPECT_EQ(FUNC_VOLUME, g_eeGeneral.customFn[1].func); + EXPECT_EQ(MIXSRC_RS, g_eeGeneral.customFn[1].all.val); + + EXPECT_ZSTREQ("Tes", g_eeGeneral.switchNames[0]); + EXPECT_EQ(SWITCH_3POS, SWITCH_CONFIG(0)); + + EXPECT_ZSTREQ("BT_X10", g_eeGeneral.bluetoothName); + EXPECT_STREQ("Default", g_eeGeneral.themeName); + + EXPECT_EQ(WHITE, g_eeGeneral.themeData.options[0].unsignedValue); + EXPECT_EQ(RED, g_eeGeneral.themeData.options[1].unsignedValue); EXPECT_ZSTREQ("Test", g_model.header.name); + EXPECT_EQ(0, g_model.noGlobalFunctions); + EXPECT_EQ(0, g_model.beepANACenter); EXPECT_EQ(80, g_model.mixData[0].weight); - EXPECT_EQ(MIXSRC_FIRST_TRAINER, g_model.mixData[4].srcRaw); - EXPECT_EQ(SWSRC_TELEMETRY_STREAMING, g_model.mixData[4].swtch); + EXPECT_EQ(MIXSRC_MAX, g_model.mixData[2].srcRaw); // MAX + EXPECT_EQ(MIXSRC_LS, g_model.mixData[3].srcRaw); // LS + EXPECT_EQ(MIXSRC_FIRST_TRAINER, g_model.mixData[5].srcRaw); + EXPECT_EQ(SWSRC_TELEMETRY_STREAMING, g_model.mixData[5].swtch); EXPECT_EQ(-100, g_model.limitData[0].max); EXPECT_EQ(80, g_model.expoData[0].weight); EXPECT_EQ(LS_FUNC_VPOS, g_model.logicalSw[0].func); EXPECT_EQ(MIXSRC_FIRST_TRAINER, g_model.logicalSw[0].v1); EXPECT_EQ(0, g_model.logicalSw[0].v2); + EXPECT_EQ(MIXSRC_FIRST_TELEM+19*3, g_model.logicalSw[1].v1); // TELE:20 + EXPECT_EQ(20, g_model.logicalSw[1].v2); + EXPECT_EQ(SWSRC_FIRST_LOGICAL_SWITCH, g_model.logicalSw[1].andsw); EXPECT_EQ(SWASH_TYPE_120X, g_model.swashR.type); EXPECT_ZSTREQ("Tes", g_model.flightModeData[0].name); EXPECT_EQ(10, g_model.flightModeData[0].gvars[0]); @@ -120,6 +190,13 @@ TEST(Conversions, ConversionHorusFrom22) EXPECT_ZSTREQ("Tes", g_model.telemetrySensors[0].label); EXPECT_EQ(10, g_model.telemetrySensors[0].id); EXPECT_EQ(9, g_model.telemetrySensors[0].frskyInstance.physID); + EXPECT_EQ((NUM_POTS + NUM_SLIDERS + 3), g_model.thrTraceSrc); // CH3 + + EXPECT_STREQ("Layout2P1", g_model.screenData[0].layoutName); + EXPECT_STREQ("ModelBmp", g_model.screenData[0].layoutData.zones[0].widgetName); + EXPECT_STREQ("Value", g_model.topbarData.zones[0].widgetName); + EXPECT_EQ(MIXSRC_FIRST_TELEM, g_model.topbarData.zones[0].widgetData.options[0].unsignedValue); + EXPECT_EQ(MIXSRC_RS, g_model.screenData[0].layoutData.zones[2].widgetData.options[0].unsignedValue); } #endif diff --git a/radio/src/tests/eeprom_22_x7.bin b/radio/src/tests/eeprom_22_x7.bin index 50fe2108b..5f9381631 100644 Binary files a/radio/src/tests/eeprom_22_x7.bin and b/radio/src/tests/eeprom_22_x7.bin differ diff --git a/radio/src/tests/eeprom_22_x9d+.bin b/radio/src/tests/eeprom_22_x9d+.bin index 66b09a0df..8145e55dc 100644 Binary files a/radio/src/tests/eeprom_22_x9d+.bin and b/radio/src/tests/eeprom_22_x9d+.bin differ diff --git a/radio/src/tests/frsky.cpp b/radio/src/tests/frsky.cpp index 27c4cb0f9..e33668265 100644 --- a/radio/src/tests/frsky.cpp +++ b/radio/src/tests/frsky.cpp @@ -21,17 +21,10 @@ #include "gtests.h" void frskyDProcessPacket(const uint8_t *packet); - -#if defined(TELEMETRY_FRSKY_SPORT) bool checkSportPacket(const uint8_t *packet); void sportProcessTelemetryPacket(const uint8_t * packet); bool checkSportPacket(const uint8_t *packet); -void frskyCalculateCellStats(void); -void displayVoltagesScreen(); -#endif - -#if defined(TELEMETRY_FRSKY) TEST(FrSky, TelemetryValueWithMinAveraging) { /* @@ -147,9 +140,6 @@ TEST(FrSky, Gps) EXPECT_EQ(telemetryItems[0].gps.longitude, 45341666); } -#endif // defined(TELEMETRY_FRSKY) - -#if defined(TELEMETRY_FRSKY_SPORT) TEST(FrSkySPORT, checkCrc) { // Packet downstream @@ -487,4 +477,3 @@ TEST(FrSkySPORT, frskyCurrent) EXPECT_EQ(telemetryItems[0].valueMax, 505); } -#endif //#if defined(TELEMETRY_FRSKY_SPORT) diff --git a/radio/src/tests/gtests.cpp b/radio/src/tests/gtests.cpp index d7b5a0a7c..77fa35317 100644 --- a/radio/src/tests/gtests.cpp +++ b/radio/src/tests/gtests.cpp @@ -134,16 +134,27 @@ uint16_t getAnalogValue(uint8_t index) return anaIn(index); } -static char _zchar2stringResult[200]; +static char _stringResult[200]; const char * zchar2string(const char * zstring, int size) { - if (size > (int)sizeof(_zchar2stringResult) ) { - return 0; + if (size > (int)sizeof(_stringResult) ) { + return nullptr; } - zchar2str(_zchar2stringResult, zstring, size); - return _zchar2stringResult; + zchar2str(_stringResult, zstring, size); + return _stringResult; } +const char * nchar2string(const char * string, int size) +{ + if (size > (int)sizeof(_stringResult) ) { + return nullptr; + } + strncpy(_stringResult, string, size); + _stringResult[size] = '\0'; + return _stringResult; +} + + int main(int argc, char **argv) { QCoreApplication app(argc, argv); diff --git a/radio/src/tests/gtests.h b/radio/src/tests/gtests.h index 5be8b49be..ab5c35abd 100644 --- a/radio/src/tests/gtests.h +++ b/radio/src/tests/gtests.h @@ -36,7 +36,9 @@ extern uint16_t anaInValues[NUM_STICKS+NUM_POTS+NUM_SLIDERS]; void doMixerCalculations(); extern const char * zchar2string(const char * zstring, int size); +extern const char * nchar2string(const char * string, int size); #define EXPECT_ZSTREQ(c_string, z_string) EXPECT_STREQ(c_string, zchar2string(z_string, sizeof(z_string))) +#define EXPECT_STRNEQ(c_string, n_string) EXPECT_STREQ(c_string, nchar2string(n_string, sizeof(n_string))) #if defined(PCBTARANIS) || defined(PCBHORUS) #define RADIO_RESET() \ @@ -80,13 +82,11 @@ inline void MIXER_RESET() inline void TELEMETRY_RESET() { -#if defined(TELEMETRY_FRSKY) telemetryData.clear(); telemetryData.rssi.set(100); for (int i=0; i bitmap(BITMAP_BUFFER_SIZE(7, 32)); - EXPECT_TRUE(lcdLoadBitmap(bitmap.buffer(), TESTS_PATH "/tests/4b_7x32.bmp", 7, 32) != NULL); + EXPECT_TRUE(lcdLoadBitmap(bitmap.buffer(), TESTS_PATH "/4b_7x32.bmp", 7, 32) != NULL); bitmap.leakCheck(); lcdDrawBitmap(10, 2, bitmap.buffer()); } { TestBuffer<1000> bitmap(BITMAP_BUFFER_SIZE(6, 32)); - EXPECT_TRUE(lcdLoadBitmap(bitmap.buffer(), TESTS_PATH "/tests/1b_6x32.bmp", 6, 32) != NULL); + EXPECT_TRUE(lcdLoadBitmap(bitmap.buffer(), TESTS_PATH "/1b_6x32.bmp", 6, 32) != NULL); bitmap.leakCheck(); lcdDrawBitmap(20, 2, bitmap.buffer()); } { TestBuffer<1000> bitmap(BITMAP_BUFFER_SIZE(31, 31)); - EXPECT_TRUE(lcdLoadBitmap(bitmap.buffer(), TESTS_PATH "/tests/4b_31x31.bmp", 31, 31) != NULL); + EXPECT_TRUE(lcdLoadBitmap(bitmap.buffer(), TESTS_PATH "/4b_31x31.bmp", 31, 31) != NULL); bitmap.leakCheck(); lcdDrawBitmap(30, 2, bitmap.buffer()); } { TestBuffer<1000> bitmap(BITMAP_BUFFER_SIZE(39, 32)); - EXPECT_TRUE(lcdLoadBitmap(bitmap.buffer(), TESTS_PATH "/tests/1b_39x32.bmp", 39, 32) != NULL); + EXPECT_TRUE(lcdLoadBitmap(bitmap.buffer(), TESTS_PATH "/1b_39x32.bmp", 39, 32) != NULL); bitmap.leakCheck(); lcdDrawBitmap(70, 2, bitmap.buffer()); } { TestBuffer<1000> bitmap(BITMAP_BUFFER_SIZE(20, 20)); - EXPECT_TRUE(lcdLoadBitmap(bitmap.buffer(), TESTS_PATH "/tests/4b_20x20.bmp", 20, 20) != NULL); + EXPECT_TRUE(lcdLoadBitmap(bitmap.buffer(), TESTS_PATH "/4b_20x20.bmp", 20, 20) != NULL); bitmap.leakCheck(); lcdDrawBitmap(120, 2, bitmap.buffer()); } @@ -379,7 +379,7 @@ TEST(Lcd, lcdDrawBitmapLoadAndDisplay) } { TestBuffer<1000> bitmap(BITMAP_BUFFER_SIZE(10, 10)); - EXPECT_TRUE(lcdLoadBitmap(bitmap.buffer(), TESTS_PATH "/tests/1b_39x32.bmp", 10, 10) == NULL) << "to small buffer"; + EXPECT_TRUE(lcdLoadBitmap(bitmap.buffer(), TESTS_PATH "/1b_39x32.bmp", 10, 10) == NULL) << "to small buffer"; bitmap.leakCheck(); } } diff --git a/radio/src/tests/lcd_480x272.cpp b/radio/src/tests/lcd_480x272.cpp index 486b601f2..769fccc5f 100644 --- a/radio/src/tests/lcd_480x272.cpp +++ b/radio/src/tests/lcd_480x272.cpp @@ -67,7 +67,7 @@ bool checkScreenshot_480x272(const QString & test) QPainter p(&buffer); doPaint_480x272(p); QString filename(QString("%1_%2x%3.png").arg(test).arg(LCD_W).arg(LCD_H)); - QImage reference(TESTS_PATH "/tests/" + filename); + QImage reference(TESTS_PATH "/" + filename); if (buffer == reference) { return true; diff --git a/radio/src/tests/model_22_x10.otx b/radio/src/tests/model_22_x10.otx new file mode 100644 index 000000000..e81996c2b Binary files /dev/null and b/radio/src/tests/model_22_x10.otx differ diff --git a/radio/src/translations.cpp b/radio/src/translations.cpp index 5cccd7764..1763cc4da 100644 --- a/radio/src/translations.cpp +++ b/radio/src/translations.cpp @@ -24,7 +24,6 @@ ISTR(OFFON); ISTR(MMMINV); -ISTR(NCHANNELS); ISTR(VBEEPMODE); ISTR(TRNMODE); ISTR(TRNCHN); @@ -32,7 +31,6 @@ ISTR(VTRIMINC); ISTR(VDISPLAYTRIMS); ISTR(RETA123); ISTR(VPROTOS); -ISTR(POSNEG); ISTR(VBLMODE); ISTR(VCURVEFUNC); ISTR(VMLTPX); @@ -43,18 +41,12 @@ ISTR(VFSWFUNC); ISTR(VFSWRESET); ISTR(FUNCSOUNDS); ISTR(VTELEMUNIT); -ISTR(VALARM); -ISTR(VALARMFN); -ISTR(VTELPROTO); ISTR(GPSFORMAT); -ISTR(AMPSRC); -ISTR(VARIOSRC); ISTR(VTELEMSCREENTYPE); ISTR(VKEYS); ISTR(VSWITCHES); ISTR(VSRCRAW); ISTR(VTMRMODES); -ISTR(DATETIME); ISTR(VPERSISTENT); ISTR(VLCD); ISTR(VUNITSSYSTEM); @@ -77,18 +69,12 @@ ISTR(XJT_ACCST_RF_PROTOCOLS); ISTR(ISRM_RF_PROTOCOLS); ISTR(R9M_PXX2_RF_PROTOCOLS); ISTR(DSM_PROTOCOLS); -ISTR(VOLTSRC); ISTR(CURVE_TYPES); ISTR(VSENSORTYPES); ISTR(VFORMULAS); ISTR(VPREC); ISTR(VCELLINDEX); ISTR(VANTENNATYPES); - -#if !defined(GRAPHICS) -ISTR(VBEEPLEN); -#endif - ISTR(AUX_SERIAL_MODES); ISTR(SWTYPES); ISTR(POTTYPES); @@ -630,7 +616,6 @@ const char STR_BLONBRIGHTNESS[] = TR_BLONBRIGHTNESS; const char STR_BLOFFBRIGHTNESS[] = TR_BLOFFBRIGHTNESS; #endif -#if defined(TELEMETRY_FRSKY) const char STR_TIMEZONE[] = TR_TIMEZONE; const char STR_ADJUST_RTC[] = TR_ADJUST_RTC; const char STR_GPS[] = TR_GPS; @@ -639,7 +624,6 @@ const char STR_VARIO[] = TR_VARIO; const char STR_PITCH_AT_ZERO[] = TR_PITCH_AT_ZERO; const char STR_PITCH_AT_MAX[] = TR_PITCH_AT_MAX; const char STR_REPEAT_AT_ZERO[] = TR_REPEAT_AT_ZERO; -#endif #if defined(EEPROM) const char STR_BAD_RADIO_DATA[] = TR_BADEEPROMDATA; @@ -658,9 +642,7 @@ const char STR_STORAGE_FORMAT[] = TR_STORAGE_FORMAT; const char STR_MENUCUSTOMSCRIPTS[] = TR_MENUCUSTOMSCRIPTS; #endif -#if defined(TELEMETRY_FRSKY) const char STR_MENUTELEMETRY[] = TR_MENUTELEMETRY; -#endif #if defined(DSM2) || defined(PXX) const char STR_RECEIVER_NUM[] = TR_RECEIVER_NUM; diff --git a/radio/src/translations/cz.h.txt b/radio/src/translations/cz.h.txt index 1b2828a36..c6e0fcd32 100644 --- a/radio/src/translations/cz.h.txt +++ b/radio/src/translations/cz.h.txt @@ -48,15 +48,9 @@ #define LEN_MMMINV "\003" #define TR_MMMINV "---""INV" -#define LEN_NCHANNELS "\004" -#define TR_NCHANNELS "\0014CH\0016CH\0018CH10CH12CH14CH16CH" - #define LEN_VBEEPMODE TR("\005","\012") #define TR_VBEEPMODE TR("Tichý""Alarm""BezKl""Vše\0", "Tichý\0 ""Jen alarm\0""Bez kláves""Vše\0 ") -#define LEN_VBEEPLEN "\005" -#define TR_VBEEPLEN "O====""=O===""==O==""===O=""====O" - #define LEN_VRENAVIG "\003" #define TR_VRENAVIG "Ne REaREb" @@ -85,9 +79,6 @@ #define LEN_SLIDERTYPES "\006" #define TR_SLIDERTYPES "Žádný\0""Slider" -#define LEN_DATETIME "\006" -#define TR_DATETIME "DATUM:""ČAS: " - #define LEN_VLCD "\006" #define TR_VLCD "NormalOptrex" @@ -155,9 +146,6 @@ #define TR_VPROTOS "PPM\0 " TR_PXX TR_DSM2 -#define LEN_POSNEG "\003" -#define TR_POSNEG "POZ""NEG" - #if defined(PCBSKY9X) && defined(REVX) #define LEN_VOUTPUT_TYPE "\011" #define TR_VOUTPUT_TYPE "OpenDrain""PushPull\0" @@ -263,23 +251,14 @@ #define TR_SF_SAFETY "---\0 " #endif -#if defined(PCBTARANIS) - #define TR_SF_SCREENSHOT "Snímek LCD\0" -#else - #define TR_SF_SCREENSHOT -#endif - +#define TR_SF_SCREENSHOT "Snímek LCD\0" #define TR_SF_RESERVE "[rezerva]\0 " - #define TR_VFSWFUNC TR_SF_SAFETY "Trenér \0 ""Insta-Trim\0""Reset\0 ""Změna \0 " TR_ADJUST_GVAR "Hlasitost\0 " "SetFailsafe" "RangeCheck\0" "ModuleBind\0" TR_SOUND TR_PLAY_TRACK TR_PLAY_VALUE TR_SF_RESERVE TR_SF_PLAY_SCRIPT TR_SF_RESERVE TR_SF_BG_MUSIC TR_VVARIO TR_HAPTIC TR_SDCLOGS "Podsvětlení" TR_SF_SCREENSHOT TR_SF_TEST +#define TR_VFSWFUNC TR_SF_SAFETY "Trenér \0 ""Insta-Trim\0""Reset\0 ""Změna \0 " TR_ADJUST_GVAR "Hlasitost\0 " "SetFailsafe" "RangeCheck\0" "ModuleBind\0" TR_SOUND TR_PLAY_TRACK TR_PLAY_VALUE TR_SF_RESERVE TR_SF_PLAY_SCRIPT TR_SF_RESERVE TR_SF_BG_MUSIC TR_VVARIO TR_HAPTIC TR_SDCLOGS "Podsvětlení" TR_SF_SCREENSHOT TR_SF_TEST #define LEN_VFSWRESET TR("\004", "\012") -#if defined(TELEMETRY_FRSKY) - #define TR_FSW_RESET_TELEM TR("Telm", "Telemetrie") -#else - #define TR_FSW_RESET_TELEM -#endif +#define TR_FSW_RESET_TELEM TR("Telm", "Telemetrie") #if LCD_W >= 212 #define TR_FSW_RESET_TIMERS "Stopky1\0 ""Stopky2\0 ""Stopky3\0 " @@ -299,37 +278,16 @@ #define LENGTH_UNIT_METR "m\0 " #define SPEED_UNIT_METR "kmh" - #define LEN_VUNITSSYSTEM TR("\006", "\010") - #define TR_VUNITSSYSTEM TR("Metr.\0""Imper.", "Metrické""Imperial") - #define LEN_VTELEMUNIT "\003" - #define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz" +#define LEN_VUNITSSYSTEM TR("\006", "\010") +#define TR_VUNITSSYSTEM TR("Metr.\0""Imper.", "Metrické""Imperial") +#define LEN_VTELEMUNIT "\003" +#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz" #define STR_V (STR_VTELEMUNIT+1) #define STR_A (STR_VTELEMUNIT+4) -#define LEN_VALARM "\004" -#define TR_VALARM "----""žlut""oran""červ" - -#define LEN_VALARMFN "\001" -#define TR_VALARMFN "<>" - -#define LEN_VTELPROTO "\007" -#define TR_VTELPROTO "---\0 ""Hub\0 ""WSHHigh" - - #define LEN_AMPSRC TR("\003", "\005") - #define TR_AMPSRC TR("---""A1\0""A2\0""A3\0""A4\0""FAS""Cel", "---\0 ""A1\0 ""A2\0 ""A3\0 ""A4\0 ""FAS\0 ""Cells") - #define LEN_VOLTSRC TR("\003", "\005") - #define TR_VOLTSRC TR("A1\0""A2\0""A3\0""A4\0""FAS""Cel", "A1\0 ""A2\0 ""A3\0 ""A4\0 ""FAS\0 ""Cells") - -#define LEN_VARIOSRC "\004" -#if defined(TELEMETRY_FRSKY_SPORT) - #define TR_VARIOSRC "VSpd""A1\0 ""A2\0 ""dTE\0" -#else - #define TR_VARIOSRC "Alt\0""Alt+""VSpd""A1\0 ""A2\0" -#endif - - #define LEN_VTELEMSCREENTYPE "\010" - #define TR_VTELEMSCREENTYPE "Nic\0 ""Hodnota ""Ukazatel""Skript\0" +#define LEN_VTELEMSCREENTYPE "\010" +#define TR_VTELEMSCREENTYPE "Nic\0 ""Hodnota ""Ukazatel""Skript\0" #define LEN_GPSFORMAT "\004" #define TR_GPSFORMAT "DMS\0""NMEA" @@ -1174,9 +1132,9 @@ //TODO: translation #define TR_INVERTED_SERIAL INDENT "Invert" #define TR_IGNORE_INSTANCE TR(INDENT "Chybné ID", INDENT "Ignoruj chyby ID") -#define TR_DISCOVER_SENSORS INDENT "Detekovat nové senzory" -#define TR_STOP_DISCOVER_SENSORS INDENT "Zastavit autodetekci" -#define TR_DELETE_ALL_SENSORS INDENT "Odebrat všechny senzory" +#define TR_DISCOVER_SENSORS "Detekovat nové senzory" +#define TR_STOP_DISCOVER_SENSORS "Zastavit autodetekci" +#define TR_DELETE_ALL_SENSORS "Odebrat všechny senzory" #define TR_CONFIRMDELETE "Opravdu " LCDW_128_480_LINEBREAK "odstranit vše ?" #define TR_SELECT_WIDGET "Zvolit widget" #define TR_REMOVE_WIDGET "Odstranit widget" diff --git a/radio/src/translations/de.h.txt b/radio/src/translations/de.h.txt index fc3b27d38..85314265a 100644 --- a/radio/src/translations/de.h.txt +++ b/radio/src/translations/de.h.txt @@ -49,15 +49,9 @@ #define LEN_MMMINV "\003" #define TR_MMMINV "---""INV" -#define LEN_NCHANNELS "\004" -#define TR_NCHANNELS "\0014CH\0016CH\0018CH10CH12CH14CH16CH" - #define LEN_VBEEPMODE "\005" #define TR_VBEEPMODE "Stumm""Alarm""NoKey""Alle\0" -#define LEN_VBEEPLEN "\005" -#define TR_VBEEPLEN "0====""=0===""==0==""===0=""====0" - #define LEN_VRENAVIG "\003" #define TR_VRENAVIG "AUSDGaDGb" @@ -86,9 +80,6 @@ #define LEN_SLIDERTYPES "\006" #define TR_SLIDERTYPES "Keine\0""Slider" -#define LEN_DATETIME "\005" -#define TR_DATETIME "DATE:""ZEIT:" - #define LEN_VLCD "\006" #define TR_VLCD "NormalOptrex" @@ -156,9 +147,6 @@ #define TR_VPROTOS "PPM\0 " TR_DSM2 -#define LEN_POSNEG "\003" -#define TR_POSNEG "POS""NEG" - #if defined(PCBSKY9X) && defined(REVX) #define LEN_VOUTPUT_TYPE "\011" #define TR_VOUTPUT_TYPE "OpenDrain""PushPull\0" @@ -266,23 +254,14 @@ #define TR_SF_SAFETY "---\0 " #endif -#if defined(PCBTARANIS) - #define TR_SF_SCREENSHOT "Screenshot" -#else - #define TR_SF_SCREENSHOT -#endif - +#define TR_SF_SCREENSHOT "Screenshot" #define TR_SF_RESERVE "[Reserve]\0" - #define TR_VFSWFUNC TR_SF_SAFETY "Lehrer \0 ""Inst. Trim""Rücksetz.\0""Setze \0 " TR_ADJUST_GVAR "Lautstr.\0 " "SetFailsfe" "RangeCheck" "ModuleBind" TR_SOUND TR_PLAY_TRACK TR_PLAY_VALUE TR_SF_RESERVE TR_SF_PLAY_SCRIPT TR_SF_RESERVE TR_SF_BG_MUSIC TR_VVARIO TR_HAPTIC TR_SDCLOGS "LCD Licht\0" TR_SF_SCREENSHOT TR_SF_TEST +#define TR_VFSWFUNC TR_SF_SAFETY "Lehrer \0 ""Inst. Trim""Rücksetz.\0""Setze \0 " TR_ADJUST_GVAR "Lautstr.\0 " "SetFailsfe" "RangeCheck" "ModuleBind" TR_SOUND TR_PLAY_TRACK TR_PLAY_VALUE TR_SF_RESERVE TR_SF_PLAY_SCRIPT TR_SF_RESERVE TR_SF_BG_MUSIC TR_VVARIO TR_HAPTIC TR_SDCLOGS "LCD Licht\0" TR_SF_SCREENSHOT TR_SF_TEST #define LEN_VFSWRESET TR("\004", "\011") -#if defined(TELEMETRY_FRSKY) - #define TR_FSW_RESET_TELEM TR("Telm", "Telemetrie") -#else - #define TR_FSW_RESET_TELEM -#endif +#define TR_FSW_RESET_TELEM TR("Telm", "Telemetrie") #if LCD_W >= 212 #define TR_FSW_RESET_TIMERS "Timer 1\0 ""Timer 2\0 ""Timer 3\0 " @@ -327,29 +306,8 @@ #define STR_V (STR_VTELEMUNIT+1) #define STR_A (STR_VTELEMUNIT+4) -#define LEN_VALARM "\003" -#define TR_VALARM "---""Glb""Org""Rot" - -#define LEN_VALARMFN "\001" -#define TR_VALARMFN "<>" - -#define LEN_VTELPROTO "\007" -#define TR_VTELPROTO "Kein\0 ""Hub\0 ""WSHHigh" - - #define LEN_AMPSRC TR("\003", "\005") - #define TR_AMPSRC TR("---""A1\0""A2\0""A3\0""A4\0""FAS""Cel", "---\0 ""A1\0 ""A2\0 ""A3\0 ""A4\0 ""FAS\0 ""Cells") - #define LEN_VOLTSRC TR("\003", "\005") - #define TR_VOLTSRC TR("A1\0""A2\0""A3\0""A4\0""FAS""Cel", "A1\0 ""A2\0 ""A3\0 ""A4\0 ""FAS\0 ""Cells") - -#define LEN_VARIOSRC "\004" -#if defined(TELEMETRY_FRSKY_SPORT) - #define TR_VARIOSRC "Vspd""A1\0 ""A2\0 ""dTE\0" -#else - #define TR_VARIOSRC "Alt\0""Alt+""Vspd""A1\0 ""A2\0 " -#endif - - #define LEN_VTELEMSCREENTYPE "\007" - #define TR_VTELEMSCREENTYPE " None "" Werte "" Balken"" Script" +#define LEN_VTELEMSCREENTYPE "\007" +#define TR_VTELEMSCREENTYPE " None "" Werte "" Balken"" Script" #define LEN_GPSFORMAT "\004" #define TR_GPSFORMAT "GMS\0""NMEA" //Koordinatenanzeige @@ -1185,9 +1143,9 @@ #define TR_SERVOS_KO "Servos KO" #define TR_INVERTED_SERIAL INDENT "Invert." #define TR_IGNORE_INSTANCE TR(INDENT "Ignr. Inst.", INDENT "Ignor. Instanzen") -#define TR_DISCOVER_SENSORS INDENT "Start Sensorsuche" -#define TR_STOP_DISCOVER_SENSORS INDENT "Stop Sensorsuche" -#define TR_DELETE_ALL_SENSORS INDENT "Lösche alle Sensoren" +#define TR_DISCOVER_SENSORS "Start Sensorsuche" +#define TR_STOP_DISCOVER_SENSORS "Stop Sensorsuche" +#define TR_DELETE_ALL_SENSORS "Lösche alle Sensoren" #define TR_CONFIRMDELETE "Wirklich alle " LCDW_128_480_LINEBREAK "löschen ?" #define TR_SELECT_WIDGET "Widget auswählen" // grafisches Element #define TR_REMOVE_WIDGET "Widget löschen" diff --git a/radio/src/translations/en.h.txt b/radio/src/translations/en.h.txt index 594165722..5ae8263a6 100644 --- a/radio/src/translations/en.h.txt +++ b/radio/src/translations/en.h.txt @@ -49,15 +49,9 @@ #define LEN_MMMINV "\003" #define TR_MMMINV "---""INV" -#define LEN_NCHANNELS "\004" -#define TR_NCHANNELS "\0014CH\0016CH\0018CH10CH12CH14CH16CH" - #define LEN_VBEEPMODE "\005" #define TR_VBEEPMODE "Quiet""Alarm""NoKey""All\0 " -#define LEN_VBEEPLEN "\005" -#define TR_VBEEPLEN "0====""=0===""==0==""===0=""====0" - #define LEN_VRENAVIG "\003" #define TR_VRENAVIG "No REaREb" @@ -86,9 +80,6 @@ #define LEN_SLIDERTYPES "\006" #define TR_SLIDERTYPES "None\0 ""Slider" -#define LEN_DATETIME "\005" -#define TR_DATETIME "DATE:""TIME:" - #define LEN_VLCD "\006" #define TR_VLCD "NormalOptrex" @@ -156,9 +147,6 @@ #define TR_VPROTOS "PPM\0 " TR_PXX TR_DSM2 -#define LEN_POSNEG "\003" -#define TR_POSNEG "POS""NEG" - #if defined(PCBSKY9X) && defined(REVX) #define LEN_VOUTPUT_TYPE "\011" #define TR_VOUTPUT_TYPE "OpenDrain""PushPull\0" @@ -266,23 +254,14 @@ #define TR_SF_SAFETY "---\0 " #endif -#if defined(PCBTARANIS) - #define TR_SF_SCREENSHOT "Screenshot" -#else - #define TR_SF_SCREENSHOT -#endif +#define TR_SF_SCREENSHOT "Screenshot" +#define TR_SF_RESERVE "[reserve]\0" -#define TR_SF_RESERVE "[reserve]\0" - - #define TR_VFSWFUNC TR_SF_SAFETY "Trainer\0 ""Inst. Trim""Reset\0 ""Set \0 " TR_ADJUST_GVAR "Volume\0 " "SetFailsfe" "RangeCheck" "ModuleBind" TR_SOUND TR_PLAY_TRACK TR_PLAY_VALUE TR_SF_RESERVE TR_SF_PLAY_SCRIPT TR_SF_RESERVE TR_SF_BG_MUSIC TR_VVARIO TR_HAPTIC TR_SDCLOGS "Backlight\0" TR_SF_SCREENSHOT TR_SF_TEST +#define TR_VFSWFUNC TR_SF_SAFETY "Trainer\0 ""Inst. Trim""Reset\0 ""Set \0 " TR_ADJUST_GVAR "Volume\0 " "SetFailsfe" "RangeCheck" "ModuleBind" TR_SOUND TR_PLAY_TRACK TR_PLAY_VALUE TR_SF_RESERVE TR_SF_PLAY_SCRIPT TR_SF_RESERVE TR_SF_BG_MUSIC TR_VVARIO TR_HAPTIC TR_SDCLOGS "Backlight\0" TR_SF_SCREENSHOT TR_SF_TEST #define LEN_VFSWRESET TR("\004", "\011") -#if defined(TELEMETRY_FRSKY) - #define TR_FSW_RESET_TELEM TR("Telm", "Telemetry") -#else - #define TR_FSW_RESET_TELEM -#endif +#define TR_FSW_RESET_TELEM TR("Telm", "Telemetry") #if LCD_W >= 212 #define TR_FSW_RESET_TIMERS "Timer 1\0 ""Timer 2\0 ""Timer 3\0 " @@ -310,29 +289,8 @@ #define STR_V (STR_VTELEMUNIT+1) #define STR_A (STR_VTELEMUNIT+4) -#define LEN_VALARM "\003" -#define TR_VALARM "---""Yel""Org""Red" - -#define LEN_VALARMFN "\001" -#define TR_VALARMFN "<>" - -#define LEN_VTELPROTO "\007" -#define TR_VTELPROTO "None\0 ""Hub\0 ""WSHHigh" - -#define LEN_AMPSRC TR("\003", "\005") -#define TR_AMPSRC TR("---""A1\0""A2\0""A3\0""A4\0""FAS""Cel", "---\0 ""A1\0 ""A2\0 ""A3\0 ""A4\0 ""FAS\0 ""Cells") -#define LEN_VOLTSRC TR("\003", "\005") -#define TR_VOLTSRC TR("A1\0""A2\0""A3\0""A4\0""FAS""Cel", "A1\0 ""A2\0 ""A3\0 ""A4\0 ""FAS\0 ""Cells") - -#define LEN_VARIOSRC "\004" -#if defined(TELEMETRY_FRSKY_SPORT) - #define TR_VARIOSRC "VSpd""A1\0 ""A2\0 ""dTE\0" -#else - #define TR_VARIOSRC "Alt\0""Alt+""VSpd""A1\0 ""A2\0" -#endif - - #define LEN_VTELEMSCREENTYPE "\006" - #define TR_VTELEMSCREENTYPE "None\0 ""Nums\0 ""Bars\0 ""Script" +#define LEN_VTELEMSCREENTYPE "\006" +#define TR_VTELEMSCREENTYPE "None\0 ""Nums\0 ""Bars\0 ""Script" #define LEN_GPSFORMAT "\004" #define TR_GPSFORMAT "DMS\0""NMEA" @@ -1179,9 +1137,9 @@ #define TR_SERVOS_KO "Servos KO" #define TR_INVERTED_SERIAL INDENT "Invert" #define TR_IGNORE_INSTANCE TR(INDENT "No inst.", INDENT "Ignore instances") -#define TR_DISCOVER_SENSORS INDENT "Discover new sensors" -#define TR_STOP_DISCOVER_SENSORS INDENT "Stop discovery" -#define TR_DELETE_ALL_SENSORS INDENT "Delete all sensors" +#define TR_DISCOVER_SENSORS "Discover new sensors" +#define TR_STOP_DISCOVER_SENSORS "Stop discovery" +#define TR_DELETE_ALL_SENSORS "Delete all sensors" #define TR_CONFIRMDELETE "Really " LCDW_128_480_LINEBREAK "delete all ?" #define TR_SELECT_WIDGET "Select widget" #define TR_REMOVE_WIDGET "Remove widget" diff --git a/radio/src/translations/es.h.txt b/radio/src/translations/es.h.txt index 74924c4f1..2abbce9f1 100644 --- a/radio/src/translations/es.h.txt +++ b/radio/src/translations/es.h.txt @@ -49,15 +49,9 @@ #define LEN_MMMINV "\003" #define TR_MMMINV "---""INV" -#define LEN_NCHANNELS "\004" -#define TR_NCHANNELS "\0014CH\0016CH\0018CH10CH12CH14CH16CH" - #define LEN_VBEEPMODE "\005" #define TR_VBEEPMODE "Mudo ""Alarm""NoKey""Todo " -#define LEN_VBEEPLEN "\005" -#define TR_VBEEPLEN "0====""=0===""==0==""===0=""====0" - #define LEN_VRENAVIG "\003" #define TR_VRENAVIG "No REaREb" @@ -86,9 +80,6 @@ #define LEN_SLIDERTYPES "\006" #define TR_SLIDERTYPES "Rien\0 ""Slider" -#define LEN_DATETIME "\005" -#define TR_DATETIME "DATA:""HORA:" - #define LEN_VLCD "\006" #define TR_VLCD "NormalOptrex" @@ -156,9 +147,6 @@ #define TR_VPROTOS "PPM\0 " TR_PXX TR_DSM2 -#define LEN_POSNEG "\003" -#define TR_POSNEG "POS""NEG" - #if defined(PCBSKY9X) && defined(REVX) #define LEN_VOUTPUT_TYPE "\011" #define TR_VOUTPUT_TYPE "OpenDrain""PushPull\0" @@ -264,23 +252,14 @@ #define TR_SF_SAFETY "---\0 " #endif -#if defined(PCBTARANIS) - #define TR_SF_SCREENSHOT "Screenshot" -#else - #define TR_SF_SCREENSHOT -#endif - +#define TR_SF_SCREENSHOT "Screenshot" #define TR_SF_RESERVE "[reserve]\0" - #define TR_VFSWFUNC TR_SF_SAFETY "Aprendiz\0 ""Inst. Trim""Reset\0 ""Set \0 " TR_ADJUST_GVAR "Volumen\0 " "SetFailsfe" "RangeCheck" "ModuleBind" TR_SOUND TR_PLAY_TRACK TR_PLAY_VALUE TR_SF_RESERVE TR_SF_PLAY_SCRIPT TR_SF_RESERVE TR_SF_BG_MUSIC TR_VVARIO TR_HAPTIC TR_SDCLOGS "Luz fondo\0" TR_SF_SCREENSHOT TR_SF_TEST +#define TR_VFSWFUNC TR_SF_SAFETY "Aprendiz\0 ""Inst. Trim""Reset\0 ""Set \0 " TR_ADJUST_GVAR "Volumen\0 " "SetFailsfe" "RangeCheck" "ModuleBind" TR_SOUND TR_PLAY_TRACK TR_PLAY_VALUE TR_SF_RESERVE TR_SF_PLAY_SCRIPT TR_SF_RESERVE TR_SF_BG_MUSIC TR_VVARIO TR_HAPTIC TR_SDCLOGS "Luz fondo\0" TR_SF_SCREENSHOT TR_SF_TEST #define LEN_VFSWRESET TR("\004", "\011") -#if defined(TELEMETRY_FRSKY) - #define TR_FSW_RESET_TELEM TR("Telm", "Telemetry") -#else - #define TR_FSW_RESET_TELEM -#endif +#define TR_FSW_RESET_TELEM TR("Telm", "Telemetry") #if defined(PCBTARANIS) #define TR_FSW_RESET_TIMERS "Timer 1\0 ""Timer 2\0 ""Timer 3\0 " @@ -325,27 +304,6 @@ #define STR_V (STR_VTELEMUNIT+1) #define STR_A (STR_VTELEMUNIT+4) -#define LEN_VALARM "\003" -#define TR_VALARM "---""Ama""Nar""Roj" - -#define LEN_VALARMFN "\001" -#define TR_VALARMFN "<>" - -#define LEN_VTELPROTO "\007" -#define TR_VTELPROTO "Nada\0 ""Hub\0 ""WSHHigh" - - #define LEN_AMPSRC TR("\003", "\007") - #define TR_AMPSRC TR("---""A1\0""A2\0""A3\0""A4\0""FAS""Cel", "---\0 ""A1\0 ""A2\0 ""A3\0 ""A4\0 ""FAS\0 ""Cells\0 ") - #define LEN_VOLTSRC TR("\003", "\007") - #define TR_VOLTSRC TR("A1\0""A2\0""A3\0""A4\0""FAS""Cel", "A1\0 ""A2\0 ""A3\0 ""A4\0 ""FAS\0 ""Cells\0 ") - -#define LEN_VARIOSRC "\005" -#if defined(TELEMETRY_FRSKY_SPORT) - #define TR_VARIOSRC "Vario""A1\0 ""A2\0" -#else - #define TR_VARIOSRC "Alti\0""Alti+""Vario""A1\0 ""A2\0" -#endif - #define LEN_VTELEMSCREENTYPE "\004" #define TR_VTELEMSCREENTYPE "Nums""Bars" @@ -1200,9 +1158,9 @@ #define TR_SERVOS_KO "Servos KO" #define TR_INVERTED_SERIAL INDENT "Invert" #define TR_IGNORE_INSTANCE INDENT "Ignore instance" -#define TR_DISCOVER_SENSORS INDENT "Discover new sensors" -#define TR_STOP_DISCOVER_SENSORS INDENT "Stop discovery" -#define TR_DELETE_ALL_SENSORS INDENT "Delete all sensors" +#define TR_DISCOVER_SENSORS "Discover new sensors" +#define TR_STOP_DISCOVER_SENSORS "Stop discovery" +#define TR_DELETE_ALL_SENSORS "Delete all sensors" #define TR_CONFIRMDELETE "Really " LCDW_128_480_LINEBREAK "delete all ?" #define TR_SELECT_WIDGET "Select widget" #define TR_REMOVE_WIDGET "Remove widget" diff --git a/radio/src/translations/fi.h.txt b/radio/src/translations/fi.h.txt index f085532d8..cbdff6b41 100644 --- a/radio/src/translations/fi.h.txt +++ b/radio/src/translations/fi.h.txt @@ -49,15 +49,9 @@ #define LEN_MMMINV "\003" #define TR_MMMINV "---""KÄÄ" -#define LEN_NCHANNELS "\004" -#define TR_NCHANNELS "\0014CH\0016CH\0018CH10CH12CH14CH16CH" - #define LEN_VBEEPMODE "\005" #define TR_VBEEPMODE "Äänet""Hälyt""EiNap""Kaikk" -#define LEN_VBEEPLEN "\005" -#define TR_VBEEPLEN "0====""=0===""==0==""===0=""====0" - #define LEN_VRENAVIG "\003" #define TR_VRENAVIG "No REaREb" @@ -86,9 +80,6 @@ #define LEN_SLIDERTYPES "\006" #define TR_SLIDERTYPES "Rien\0 ""Slider" -#define LEN_DATETIME "\005" -#define TR_DATETIME "PÄIV:""AIKA:" - #define LEN_VLCD "\006" #define TR_VLCD "NormalOptrex" @@ -156,9 +147,6 @@ #define TR_VPROTOS "PPM\0 " TR_PXX TR_DSM2 -#define LEN_POSNEG "\003" -#define TR_POSNEG "POS""NEG" - #if defined(PCBSKY9X) && defined(REVX) #define LEN_VOUTPUT_TYPE "\011" #define TR_VOUTPUT_TYPE "OpenDrain""PushPull\0" @@ -264,23 +252,14 @@ #define TR_SF_SAFETY "---\0 " #endif -#if defined(PCBTARANIS) - #define TR_SF_SCREENSHOT "Screenshot" -#else - #define TR_SF_SCREENSHOT -#endif - +#define TR_SF_SCREENSHOT "Screenshot" #define TR_SF_RESERVE "[reserve]\0" - #define TR_VFSWFUNC TR_SF_SAFETY "Trainer\0 ""Inst. Trim""Reset\0 ""Set \0 " TR_ADJUST_GVAR "Volume\0 " "SetFailsfe" "RangeCheck" "ModuleBind" TR_SOUND TR_PLAY_TRACK TR_PLAY_VALUE TR_SF_RESERVE TR_SF_PLAY_SCRIPT TR_SF_RESERVE TR_SF_BG_MUSIC TR_VVARIO TR_HAPTIC TR_SDCLOGS "Backlight\0" TR_SF_SCREENSHOT TR_SF_TEST +#define TR_VFSWFUNC TR_SF_SAFETY "Trainer\0 ""Inst. Trim""Reset\0 ""Set \0 " TR_ADJUST_GVAR "Volume\0 " "SetFailsfe" "RangeCheck" "ModuleBind" TR_SOUND TR_PLAY_TRACK TR_PLAY_VALUE TR_SF_RESERVE TR_SF_PLAY_SCRIPT TR_SF_RESERVE TR_SF_BG_MUSIC TR_VVARIO TR_HAPTIC TR_SDCLOGS "Backlight\0" TR_SF_SCREENSHOT TR_SF_TEST #define LEN_VFSWRESET TR("\004", "\011") -#if defined(TELEMETRY_FRSKY) - #define TR_FSW_RESET_TELEM TR("Telm", "Telemetry") -#else - #define TR_FSW_RESET_TELEM -#endif +#define TR_FSW_RESET_TELEM TR("Telm", "Telemetry") #if defined(PCBTARANIS) #define TR_FSW_RESET_TIMERS "Timer 1\0 ""Timer 2\0 ""Timer 3\0 " @@ -317,35 +296,14 @@ #define LENGTH_UNIT_METR "m\0 " #define SPEED_UNIT_METR "kmh" - #define LEN_VUNITSSYSTEM TR("\006", "\010") - #define TR_VUNITSSYSTEM TR("Metric""Imper.", "Metric\0 ""Imperial") - #define LEN_VTELEMUNIT "\003" - #define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz" +#define LEN_VUNITSSYSTEM TR("\006", "\010") +#define TR_VUNITSSYSTEM TR("Metric""Imper.", "Metric\0 ""Imperial") +#define LEN_VTELEMUNIT "\003" +#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz" #define STR_V (STR_VTELEMUNIT+1) #define STR_A (STR_VTELEMUNIT+4) -#define LEN_VALARM "\003" -#define TR_VALARM "---""Yel""Org""Red" - -#define LEN_VALARMFN "\001" -#define TR_VALARMFN "<>" - -#define LEN_VTELPROTO "\007" -#define TR_VTELPROTO "None\0 ""Hub\0 ""WSHHigh" - - #define LEN_AMPSRC TR("\003", "\007") - #define TR_AMPSRC TR("---""A1\0""A2\0""A3\0""A4\0""FAS""Cel", "---\0 ""A1\0 ""A2\0 ""A3\0 ""A4\0 ""FAS\0 ""Cells\0 ") - #define LEN_VOLTSRC TR("\003", "\007") - #define TR_VOLTSRC TR("A1\0""A2\0""A3\0""A4\0""FAS""Cel", "A1\0 ""A2\0 ""A3\0 ""A4\0 ""FAS\0 ""Cells\0 ") - -#define LEN_VARIOSRC "\005" -#if defined(TELEMETRY_FRSKY_SPORT) - #define TR_VARIOSRC "Vario""A1\0 ""A2\0" -#else - #define TR_VARIOSRC "Alti\0""Alti+""Vario""A1\0 ""A2\0" -#endif - #define LEN_VTELEMSCREENTYPE "\004" #define TR_VTELEMSCREENTYPE "Nums""Bars" @@ -1193,9 +1151,9 @@ #define TR_SERVOS_KO "Servos KO" #define TR_INVERTED_SERIAL INDENT "Invert" #define TR_IGNORE_INSTANCE INDENT "Ignore instance" -#define TR_DISCOVER_SENSORS INDENT "Discover new sensors" -#define TR_STOP_DISCOVER_SENSORS INDENT "Stop discovery" -#define TR_DELETE_ALL_SENSORS INDENT "Delete all sensors" +#define TR_DISCOVER_SENSORS "Discover new sensors" +#define TR_STOP_DISCOVER_SENSORS "Stop discovery" +#define TR_DELETE_ALL_SENSORS "Delete all sensors" #define TR_CONFIRMDELETE "Really " LCDW_128_480_LINEBREAK "delete all ?" #define TR_SELECT_WIDGET "Select widget" #define TR_REMOVE_WIDGET "Remove widget" diff --git a/radio/src/translations/fr.h.txt b/radio/src/translations/fr.h.txt index 72e7606a2..ddfae01bd 100644 --- a/radio/src/translations/fr.h.txt +++ b/radio/src/translations/fr.h.txt @@ -49,15 +49,9 @@ #define LEN_MMMINV "\003" #define TR_MMMINV "---""INV" -#define LEN_NCHANNELS "\004" -#define TR_NCHANNELS "\0014CH\0016CH\0018CH10CH12CH14CH16CH" - #define LEN_VBEEPMODE "\005" #define TR_VBEEPMODE "Aucun""Alarm""NoKey""Tout\0" -#define LEN_VBEEPLEN "\005" -#define TR_VBEEPLEN "0====""=0===""==0==""===0=""====0" - #define LEN_VRENAVIG "\003" #define TR_VRENAVIG "NonREaREb" @@ -86,9 +80,6 @@ #define LEN_SLIDERTYPES "\006" #define TR_SLIDERTYPES "Rien\0 ""Slider" -#define LEN_DATETIME "\005" -#define TR_DATETIME "DATE:""HEURE" - #define LEN_VLCD "\006" #define TR_VLCD "NormalOptrex" @@ -156,9 +147,6 @@ #define TR_VPROTOS "PPM\0 " TR_PXX TR_DSM2 -#define LEN_POSNEG "\003" -#define TR_POSNEG "POS""NEG" - #if defined(PCBSKY9X) && defined(REVX) #define LEN_VOUTPUT_TYPE "\011" #define TR_VOUTPUT_TYPE "OpenDrain""PushPull\0" @@ -266,23 +254,14 @@ #define TR_SF_SAFETY "---\0 " #endif -#if defined(PCBTARANIS) - #define TR_SF_SCREENSHOT "Photo Ecran\0 " -#else - #define TR_SF_SCREENSHOT -#endif - +#define TR_SF_SCREENSHOT "Photo Ecran\0 " #define TR_SF_RESERVE "[reserve]\0 " #define TR_VFSWFUNC TR_SF_SAFETY "Ecolage\0 ""Trim instant.""Remise à 0\0 ""Déf.\0 " TR_ADJUST_GVAR "Volume\0 " "DéfFailsafe\0 " "Test Port.\0 " "Bind\0 " TR_SOUND TR_PLAY_TRACK TR_PLAY_VALUE TR_SF_RESERVE TR_SF_PLAY_SCRIPT TR_SF_RESERVE TR_SF_BG_MUSIC TR_VVARIO TR_HAPTIC TR_SDCLOGS "Rétroécl.\0 " TR_SF_SCREENSHOT TR_SF_TEST #define LEN_VFSWRESET TR("\004", "\012") -#if defined(TELEMETRY_FRSKY) - #define TR_FSW_RESET_TELEM TR("Télm", "Télémétrie") -#else - #define TR_FSW_RESET_TELEM -#endif +#define TR_FSW_RESET_TELEM TR("Télm", "Télémétrie") #if LCD_W >= 212 #define TR_FSW_RESET_TIMERS "Chrono 1\0 ""Chrono 2\0 ""Chrono 3\0 " @@ -319,35 +298,14 @@ #define LENGTH_UNIT_METR "m\0 " #define SPEED_UNIT_METR "kmh" - #define LEN_VUNITSSYSTEM TR("\006", "\012") - #define TR_VUNITSSYSTEM TR("Métr.\0""Impér.", "Métriques\0""Impériales") - #define LEN_VTELEMUNIT "\003" - #define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz" +#define LEN_VUNITSSYSTEM TR("\006", "\012") +#define TR_VUNITSSYSTEM TR("Métr.\0""Impér.", "Métriques\0""Impériales") +#define LEN_VTELEMUNIT "\003" +#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz" #define STR_V (STR_VTELEMUNIT+1) #define STR_A (STR_VTELEMUNIT+4) -#define LEN_VALARM "\004" -#define TR_VALARM "----""Jaun""Oran""Roug" - -#define LEN_VALARMFN "\001" -#define TR_VALARMFN "<>" - -#define LEN_VTELPROTO "\007" -#define TR_VTELPROTO "Aucun ""Hub\0 ""WSHHigh" - - #define LEN_AMPSRC TR("\003", "\005") - #define TR_AMPSRC TR("---""A1\0""A2\0""A3\0""A4\0""FAS""Cel", "---\0 ""A1\0 ""A2\0 ""A3\0 ""A4\0 ""FAS\0 ""Elem.") - #define LEN_VOLTSRC TR("\003", "\005") - #define TR_VOLTSRC TR("A1\0""A2\0""A3\0""A4\0""FAS""Cel", "A1\0 ""A2\0 ""A3\0 ""A4\0 ""FAS\0 ""Elem.") - -#define LEN_VARIOSRC "\005" -#if defined(TELEMETRY_FRSKY_SPORT) - #define TR_VARIOSRC "Vario""A1\0 ""A2\0 ""dTE\0 " -#else - #define TR_VARIOSRC "Alti\0""Alti+""Vario""A1\0 ""A2\0" -#endif - #define LEN_VTELEMSCREENTYPE "\007" #define TR_VTELEMSCREENTYPE "Rien\0 ""Valeurs""Barres\0""Script\0" @@ -1202,9 +1160,9 @@ #define TR_SERVOS_KO "Servos KO" #define TR_INVERTED_SERIAL INDENT "Inversé" #define TR_IGNORE_INSTANCE TR(INDENT "Ign. inst", INDENT "Ignorer instance") -#define TR_DISCOVER_SENSORS INDENT "Découvrir capteurs" -#define TR_STOP_DISCOVER_SENSORS INDENT "Terminer découverte" -#define TR_DELETE_ALL_SENSORS TR(INDENT "Suppr. tous capteurs", INDENT "Supprimer tous capteurs") +#define TR_DISCOVER_SENSORS "Découvrir capteurs" +#define TR_STOP_DISCOVER_SENSORS "Terminer découverte" +#define TR_DELETE_ALL_SENSORS TR("Suppr. tous capteurs", "Supprimer tous capteurs") #define TR_CONFIRMDELETE TR("Tout effacer?", "Vraiment tout " LCDW_128_480_LINEBREAK "effacer ?") #define TR_SELECT_WIDGET "Sélect. widget" #define TR_REMOVE_WIDGET "Supprimer widget" diff --git a/radio/src/translations/it.h.txt b/radio/src/translations/it.h.txt index 422d3e43a..c2a83e0a2 100644 --- a/radio/src/translations/it.h.txt +++ b/radio/src/translations/it.h.txt @@ -49,15 +49,9 @@ #define LEN_MMMINV "\003" #define TR_MMMINV "---""INV" -#define LEN_NCHANNELS "\004" -#define TR_NCHANNELS "\0014CH\0016CH\0018CH10CH12CH14CH16CH" - #define LEN_VBEEPMODE TR("\005", "\010") #define TR_VBEEPMODE TR("Silen""Avvis""Notst""Tutti","Silente ""Avvisi\0 ""No Tasti""Tutti\0 ") -#define LEN_VBEEPLEN "\005" -#define TR_VBEEPLEN "+Cort""Corta""Media""Lunga""+Lung" - #define LEN_VRENAVIG "\003" #define TR_VRENAVIG "No REaREb" @@ -86,9 +80,6 @@ #define LEN_SLIDERTYPES "\006" #define TR_SLIDERTYPES "Niente""Slider" -#define LEN_DATETIME "\005" -#define TR_DATETIME "DATA:""ORA :" - #define LEN_VLCD "\006" #define TR_VLCD "NormalOptrex" @@ -156,9 +147,6 @@ #define TR_VPROTOS "PPM\0 " TR_PXX TR_DSM2 -#define LEN_POSNEG "\003" -#define TR_POSNEG "POS""NEG" - #if defined(PCBSKY9X) && defined(REVX) #define LEN_VOUTPUT_TYPE "\011" #define TR_VOUTPUT_TYPE "OpenDrain""PushPull\0" @@ -266,23 +254,14 @@ #define TR_SF_SAFETY "---\0 " #endif -#if defined(PCBTARANIS) - #define TR_SF_SCREENSHOT "Screenshot\0 " -#else - #define TR_SF_SCREENSHOT -#endif +#define TR_SF_SCREENSHOT "Screenshot\0 " +#define TR_SF_RESERVE "[riserva] \0" -#define TR_SF_RESERVE "[riserva] \0" - - #define TR_VFSWFUNC TR_SF_SAFETY "Maestro \0 ""Trim Instant.""Azzera\0 ""Set \0 " TR_ADJUST_GVAR "Volume\0 " "SetFailsafe\0 " "RangeCheck\0 " "ModuleBind\0 " TR_SOUND TR_PLAY_TRACK TR_PLAY_VALUE TR_SF_RESERVE TR_SF_PLAY_SCRIPT TR_SF_RESERVE TR_SF_BG_MUSIC TR_VVARIO TR_HAPTIC TR_SDCLOGS "Retroillum.\0 " TR_SF_SCREENSHOT TR_SF_TEST +#define TR_VFSWFUNC TR_SF_SAFETY "Maestro \0 ""Trim Instant.""Azzera\0 ""Set \0 " TR_ADJUST_GVAR "Volume\0 " "SetFailsafe\0 " "RangeCheck\0 " "ModuleBind\0 " TR_SOUND TR_PLAY_TRACK TR_PLAY_VALUE TR_SF_RESERVE TR_SF_PLAY_SCRIPT TR_SF_RESERVE TR_SF_BG_MUSIC TR_VVARIO TR_HAPTIC TR_SDCLOGS "Retroillum.\0 " TR_SF_SCREENSHOT TR_SF_TEST #define LEN_VFSWRESET TR("\004", "\011") -#if defined(TELEMETRY_FRSKY) - #define TR_FSW_RESET_TELEM TR("Telm", "Telemetr.") -#else - #define TR_FSW_RESET_TELEM -#endif +#define TR_FSW_RESET_TELEM TR("Telm", "Telemetr.") #if LCD_W >= 212 #define TR_FSW_RESET_TIMERS "Timer 1\0 ""Timer 2\0 ""Timer 3\0 " @@ -319,37 +298,16 @@ #define LENGTH_UNIT_METR "m\0 " #define SPEED_UNIT_METR "kmh" - #define LEN_VUNITSSYSTEM TR("\006", "\011") - #define TR_VUNITSSYSTEM TR("Metric""Imper.", "Metriche\0""Imperiali") - #define LEN_VTELEMUNIT "\003" - #define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz" +#define LEN_VUNITSSYSTEM TR("\006", "\011") +#define TR_VUNITSSYSTEM TR("Metric""Imper.", "Metriche\0""Imperiali") +#define LEN_VTELEMUNIT "\003" +#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz" #define STR_V (STR_VTELEMUNIT+1) #define STR_A (STR_VTELEMUNIT+4) -#define LEN_VALARM "\003" -#define TR_VALARM "---""Gia""Ara""Ros" - -#define LEN_VALARMFN "\001" -#define TR_VALARMFN "<>" - -#define LEN_VTELPROTO "\007" -#define TR_VTELPROTO "---\0 ""Hub\0 ""WSHHigh" - - #define LEN_AMPSRC TR("\003", "\007") - #define TR_AMPSRC TR("---""A1\0""A2\0""A3\0""A4\0""FAS""Cel", "---\0 ""A1\0 ""A2\0 ""A3\0 ""A4\0 ""FAS\0 ""Celle\0 ") - #define LEN_VOLTSRC TR("\003", "\007") - #define TR_VOLTSRC TR("A1\0""A2\0""A3\0""A4\0""FAS""Cel", "A1\0 ""A2\0 ""A3\0 ""A4\0 ""FAS\0 ""Celle\0 ") - -#define LEN_VARIOSRC "\005" -#if defined(TELEMETRY_FRSKY_SPORT) - #define TR_VARIOSRC "Vario""A1\0 ""A2\0" -#else - #define TR_VARIOSRC "Alti\0""Alti+""Vario""A1\0 ""A2\0" -#endif - - #define LEN_VTELEMSCREENTYPE "\006" - #define TR_VTELEMSCREENTYPE "Niente""Valori""Barre\0""Script" +#define LEN_VTELEMSCREENTYPE "\006" +#define TR_VTELEMSCREENTYPE "Niente""Valori""Barre\0""Script" #define LEN_GPSFORMAT "\004" #define TR_GPSFORMAT "HMS NMEA" @@ -1195,9 +1153,9 @@ //TODO: translation #define TR_INVERTED_SERIAL INDENT "Invert" #define TR_IGNORE_INSTANCE TR(INDENT "No inst.","Ignora instanza") -#define TR_DISCOVER_SENSORS INDENT "Cerca nuovi sensori" -#define TR_STOP_DISCOVER_SENSORS INDENT "Ferma ricerca.." -#define TR_DELETE_ALL_SENSORS INDENT "Elimina tutti i sensori" +#define TR_DISCOVER_SENSORS "Cerca nuovi sensori" +#define TR_STOP_DISCOVER_SENSORS "Ferma ricerca.." +#define TR_DELETE_ALL_SENSORS "Elimina tutti i sensori" #define TR_CONFIRMDELETE "Confermi " LCDW_128_480_LINEBREAK "eliminazione ?" #define TR_SELECT_WIDGET "Select widget" #define TR_REMOVE_WIDGET "Remove widget" diff --git a/radio/src/translations/nl.h.txt b/radio/src/translations/nl.h.txt index 4c1067616..1f9986383 100644 --- a/radio/src/translations/nl.h.txt +++ b/radio/src/translations/nl.h.txt @@ -49,15 +49,9 @@ #define LEN_MMMINV "\003" #define TR_MMMINV "---""INV" -#define LEN_NCHANNELS "\004" -#define TR_NCHANNELS "\0014CH\0016CH\0018CH10CH12CH14CH16CH" - #define LEN_VBEEPMODE "\005" #define TR_VBEEPMODE "Stil\0""Alarm""NoKey""Alles" -#define LEN_VBEEPLEN "\005" -#define TR_VBEEPLEN "0====""=0===""==0==""===0=""====0" - #define LEN_VRENAVIG "\003" #define TR_VRENAVIG "UITREaREb" @@ -84,13 +78,9 @@ #define LEN_POTTYPES TR("\013","\021") #define TR_POTTYPES TR("None\0 ""Pot w. det\0""Multipos\0 ""Pot\0 ", "Geen\0 ""Pot met Klik\0 ""Standenschakelaar""Pot zonder Klik\0 ") - #define LEN_SLIDERTYPES "\006" #define TR_SLIDERTYPES "Geen\0 ""Schuif" -#define LEN_DATETIME "\006" -#define TR_DATETIME "DATUM:""TIJD: " - #define LEN_VLCD "\006" #define TR_VLCD "NormalOptrex" @@ -158,9 +148,6 @@ #define TR_VPROTOS "PPM\0 " TR_PXX TR_DSM2 -#define LEN_POSNEG "\003" -#define TR_POSNEG "POS""NEG" - #if defined(PCBSKY9X) && defined(REVX) #define LEN_VOUTPUT_TYPE "\011" #define TR_VOUTPUT_TYPE "OpenDrain""PushPull\0" @@ -268,23 +255,14 @@ #define TR_SF_SAFETY "---\0 " #endif -#if defined(PCBTARANIS) - #define TR_SF_SCREENSHOT "Schermafdruk" -#else - #define TR_SF_SCREENSHOT -#endif - +#define TR_SF_SCREENSHOT "Schermafdruk" #define TR_SF_RESERVE "[reserve]\0" - #define TR_VFSWFUNC TR_SF_SAFETY "Trainer\0 ""Inst. Trim""Reset\0 ""Set \0 " TR_ADJUST_GVAR "Volume\0 " "SetFailsfe" "RangeCheck" "ModuleBind" TR_SOUND TR_PLAY_TRACK TR_PLAY_VALUE TR_SF_RESERVE TR_SF_PLAY_SCRIPT TR_SF_RESERVE TR_SF_BG_MUSIC TR_VVARIO TR_HAPTIC TR_SDCLOGS "Backlight\0" TR_SF_SCREENSHOT TR_SF_TEST +#define TR_VFSWFUNC TR_SF_SAFETY "Trainer\0 ""Inst. Trim""Reset\0 ""Set \0 " TR_ADJUST_GVAR "Volume\0 " "SetFailsfe" "RangeCheck" "ModuleBind" TR_SOUND TR_PLAY_TRACK TR_PLAY_VALUE TR_SF_RESERVE TR_SF_PLAY_SCRIPT TR_SF_RESERVE TR_SF_BG_MUSIC TR_VVARIO TR_HAPTIC TR_SDCLOGS "Backlight\0" TR_SF_SCREENSHOT TR_SF_TEST #define LEN_VFSWRESET TR("\004", "\012") -#if defined(TELEMETRY_FRSKY) - #define TR_FSW_RESET_TELEM TR("Telm", "Telemetrie") -#else - #define TR_FSW_RESET_TELEM -#endif +#define TR_FSW_RESET_TELEM TR("Telm", "Telemetrie") #if LCD_W >= 212 #define TR_FSW_RESET_TIMERS "Timer 1\0 ""Timer 2\0 ""Timer 3\0 " @@ -304,37 +282,16 @@ #define LENGTH_UNIT_METR "m\0 " #define SPEED_UNIT_METR "kmh" - #define LEN_VUNITSSYSTEM TR("\006", "\010") - #define TR_VUNITSSYSTEM TR("Mtrsch""Engels", "Metrisch\0 ""Engels\0 ") - #define LEN_VTELEMUNIT "\003" +#define LEN_VUNITSSYSTEM TR("\006", "\010") +#define TR_VUNITSSYSTEM TR("Mtrsch""Engels", "Metrisch\0 ""Engels\0 ") +#define LEN_VTELEMUNIT "\003" #define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz" #define STR_V (STR_VTELEMUNIT+1) #define STR_A (STR_VTELEMUNIT+4) -#define LEN_VALARM "\003" -#define TR_VALARM "---""Gel""Ora""Rod" - -#define LEN_VALARMFN "\001" -#define TR_VALARMFN "<>" - -#define LEN_VTELPROTO "\007" -#define TR_VTELPROTO "Geen\0 ""Hub\0 ""WSHHigh" - - #define LEN_AMPSRC TR("\003", "\005") - #define TR_AMPSRC TR("---""A1\0""A2\0""A3\0""A4\0""FAS""Cel", "---\0 ""A1\0 ""A2\0 ""A3\0 ""A4\0 ""FAS\0 ""Cells") - #define LEN_VOLTSRC TR("\003", "\005") - #define TR_VOLTSRC TR("A1\0""A2\0""A3\0""A4\0""FAS""Cel", "A1\0 ""A2\0 ""A3\0 ""A4\0 ""FAS\0 ""Cells") - -#define LEN_VARIOSRC "\004" -#if defined(TELEMETRY_FRSKY_SPORT) - #define TR_VARIOSRC "VSpd""A1\0 ""A2\0 ""dTE\0" -#else - #define TR_VARIOSRC "Alt\0""Alt+""VSpd""A1\0 ""A2\0" -#endif - - #define LEN_VTELEMSCREENTYPE "\006" - #define TR_VTELEMSCREENTYPE "Geen\0 ""Nums\0 ""Balken""Script" +#define LEN_VTELEMSCREENTYPE "\006" +#define TR_VTELEMSCREENTYPE "Geen\0 ""Nums\0 ""Balken""Script" #define LEN_GPSFORMAT "\004" #define TR_GPSFORMAT "DMS\0""NMEA" @@ -1189,9 +1146,9 @@ TR_GYR_VSRCRAW //TODO: translation #define TR_INVERTED_SERIAL INDENT "Invert" #define TR_IGNORE_INSTANCE TR(INDENT "Neg. ID ","Negeer ID's") -#define TR_DISCOVER_SENSORS INDENT "Ontdek nieuwe sensors" -#define TR_STOP_DISCOVER_SENSORS INDENT "Stop ontdekking" -#define TR_DELETE_ALL_SENSORS INDENT "Wis alle sensors" +#define TR_DISCOVER_SENSORS "Ontdek nieuwe sensors" +#define TR_STOP_DISCOVER_SENSORS "Stop ontdekking" +#define TR_DELETE_ALL_SENSORS "Wis alle sensors" #define TR_CONFIRMDELETE "Echt alles wissen?" #define TR_SELECT_WIDGET "Widget kiezen" #define TR_REMOVE_WIDGET "Widget wissen" diff --git a/radio/src/translations/pl.h.txt b/radio/src/translations/pl.h.txt index 6282dbf5b..ad74a2dc0 100644 --- a/radio/src/translations/pl.h.txt +++ b/radio/src/translations/pl.h.txt @@ -49,15 +49,9 @@ #define LEN_MMMINV "\003" #define TR_MMMINV "---""REV" -#define LEN_NCHANNELS "\004" -#define TR_NCHANNELS "\0014KN\0016KN\0018KN10KN12KN14KN16KN" - #define LEN_VBEEPMODE "\005" #define TR_VBEEPMODE "Cichy""Alarm""BezPr""Wsz.\0" -#define LEN_VBEEPLEN "\005" -#define TR_VBEEPLEN "0====""=0===""==0==""===0=""====0" - #define LEN_VRENAVIG "\003" #define TR_VRENAVIG "No REaREb" @@ -86,9 +80,6 @@ #define LEN_SLIDERTYPES "\006" #define TR_SLIDERTYPES "Brak\0 ""Suwak " -#define LEN_DATETIME "\005" -#define TR_DATETIME "DATA:""CZAS:" - #define LEN_VLCD "\006" #define TR_VLCD "NormalOptrex" @@ -157,9 +148,6 @@ #define TR_VPROTOS "PPM\0 " TR_PXX TR_DSM2 -#define LEN_POSNEG "\003" -#define TR_POSNEG "POZ""NEG" - #if defined(PCBSKY9X) && defined(REVX) #define LEN_VOUTPUT_TYPE "\011" #define TR_VOUTPUT_TYPE "OpenDrain""PushPull\0" @@ -267,23 +255,14 @@ #define TR_SF_SAFETY "---\0 " #endif -#if defined(PCBTARANIS) - #define TR_SF_SCREENSHOT "Zrzut Ekra" -#else - #define TR_SF_SCREENSHOT -#endif - +#define TR_SF_SCREENSHOT "Zrzut Ekra" #define TR_SF_RESERVE "[rezerwa]\0" - #define TR_VFSWFUNC TR_SF_SAFETY "Trener \0 ""Inst-Trim ""Resetuj\0 ""Ustaw\0 " TR_ADJUST_GVAR "Głośność\0 " "SetFailsfe" "RangeCheck" "ModuleBind" TR_SOUND TR_PLAY_TRACK TR_PLAY_VALUE TR_SF_RESERVE TR_SF_PLAY_SCRIPT TR_SF_RESERVE TR_SF_BG_MUSIC TR_VVARIO TR_HAPTIC TR_SDCLOGS "Podświetl\0" TR_SF_SCREENSHOT TR_SF_TEST +#define TR_VFSWFUNC TR_SF_SAFETY "Trener \0 ""Inst-Trim ""Resetuj\0 ""Ustaw\0 " TR_ADJUST_GVAR "Głośność\0 " "SetFailsfe" "RangeCheck" "ModuleBind" TR_SOUND TR_PLAY_TRACK TR_PLAY_VALUE TR_SF_RESERVE TR_SF_PLAY_SCRIPT TR_SF_RESERVE TR_SF_BG_MUSIC TR_VVARIO TR_HAPTIC TR_SDCLOGS "Podświetl\0" TR_SF_SCREENSHOT TR_SF_TEST #define LEN_VFSWRESET TR("\004", "\011") /*9 decimal*/ -#if defined(TELEMETRY_FRSKY) - #define TR_FSW_RESET_TELEM TR("Telm", "Telemetra") -#else - #define TR_FSW_RESET_TELEM -#endif +#define TR_FSW_RESET_TELEM TR("Telm", "Telemetra") #if LCD_W >= 212 #define TR_FSW_RESET_TIMERS "Timer 1\0 ""Timer 2\0 ""Timer 3\0 " @@ -320,37 +299,16 @@ #define LENGTH_UNIT_METR "m\0 " #define SPEED_UNIT_METR "kmh" - #define LEN_VUNITSSYSTEM TR("\006", "\010") /*8 decimal*/ - #define TR_VUNITSSYSTEM TR("Metr. ""Imper.", "Metryczn""Imperial") - #define LEN_VTELEMUNIT "\003" - #define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz" +#define LEN_VUNITSSYSTEM TR("\006", "\010") /*8 decimal*/ +#define TR_VUNITSSYSTEM TR("Metr. ""Imper.", "Metryczn""Imperial") +#define LEN_VTELEMUNIT "\003" +#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz" #define STR_V (STR_VTELEMUNIT+1) #define STR_A (STR_VTELEMUNIT+4) -#define LEN_VALARM "\003" -#define TR_VALARM "---""Żół""Pom""Cze" - -#define LEN_VALARMFN "\001" -#define TR_VALARMFN "<>" - -#define LEN_VTELPROTO "\007" -#define TR_VTELPROTO "None\0 ""Hub\0 ""WSHHigh" - - #define LEN_AMPSRC TR("\003", "\005") - #define TR_AMPSRC TR("---""A1\0""A2\0""A3\0""A4\0""FAS""Cel", "---\0 ""A1\0 ""A2\0 ""A3\0 ""A4\0 ""FAS\0 ""Cells") - #define LEN_VOLTSRC TR("\003", "\005") - #define TR_VOLTSRC TR("A1\0""A2\0""A3\0""A4\0""FAS""Cel", "A1\0 ""A2\0 ""A3\0 ""A4\0 ""FAS\0 ""Cells") - -#define LEN_VARIOSRC "\004" -#if defined(TELEMETRY_FRSKY_SPORT) - #define TR_VARIOSRC "VSpd""A1\0 ""A2\0 ""dTE\0" -#else - #define TR_VARIOSRC "Wys\0""Wys+""VSpd""A1\0 ""A2\0" -#endif - - #define LEN_VTELEMSCREENTYPE "\006" - #define TR_VTELEMSCREENTYPE "Brak\0 ""Liczb\0""Paski\0""Skrypt" +#define LEN_VTELEMSCREENTYPE "\006" +#define TR_VTELEMSCREENTYPE "Brak\0 ""Liczb\0""Paski\0""Skrypt" #define LEN_GPSFORMAT "\004" #define TR_GPSFORMAT "DMS\0""NMEA" @@ -1195,9 +1153,9 @@ //TODO: translation #define TR_INVERTED_SERIAL INDENT "Invert" #define TR_IGNORE_INSTANCE INDENT "Ignoruj przypadek" -#define TR_DISCOVER_SENSORS INDENT "Znajdź nowe czujniki" -#define TR_STOP_DISCOVER_SENSORS INDENT "Szukanie STOP " -#define TR_DELETE_ALL_SENSORS INDENT "Usuń czujniki " +#define TR_DISCOVER_SENSORS "Znajdź nowe czujniki" +#define TR_STOP_DISCOVER_SENSORS "Szukanie STOP " +#define TR_DELETE_ALL_SENSORS "Usuń czujniki " #define TR_CONFIRMDELETE "Usunąć wszystkie?" #define TR_SELECT_WIDGET "Select widget" #define TR_REMOVE_WIDGET "Remove widget" diff --git a/radio/src/translations/pt.h.txt b/radio/src/translations/pt.h.txt index c7eb014ce..4517c9c5e 100644 --- a/radio/src/translations/pt.h.txt +++ b/radio/src/translations/pt.h.txt @@ -49,15 +49,9 @@ #define LEN_MMMINV "\003" #define TR_MMMINV "---""INV" -#define LEN_NCHANNELS "\004" -#define TR_NCHANNELS "\0014CH\0016CH\0018CH10CH12CH14CH16CH" - #define LEN_VBEEPMODE "\005" #define TR_VBEEPMODE "Mudo ""Alarm""NoKey""Todo " -#define LEN_VBEEPLEN "\005" -#define TR_VBEEPLEN "0====""=0===""==0==""===0=""====0" - #define LEN_VRENAVIG "\003" #define TR_VRENAVIG "No REaREb" @@ -86,9 +80,6 @@ #define LEN_SLIDERTYPES "\006" #define TR_SLIDERTYPES "Rien\0 ""Slider" -#define LEN_DATETIME "\005" -#define TR_DATETIME "DATA:""HORA:" - #define LEN_VLCD "\006" #define TR_VLCD "NormalOptrex" @@ -155,9 +146,6 @@ #define TR_VPROTOS "PPM\0 " TR_PXX TR_DSM2 -#define LEN_POSNEG "\003" -#define TR_POSNEG "POS""NEG" - #if defined(PCBSKY9X) && defined(REVX) #define LEN_VOUTPUT_TYPE "\011" #define TR_VOUTPUT_TYPE "OpenDrain""PushPull\0" @@ -263,23 +251,14 @@ #define TR_SF_SAFETY "---\0 " #endif -#if defined(PCBTARANIS) - #define TR_SF_SCREENSHOT "Screenshot" -#else - #define TR_SF_SCREENSHOT -#endif - +#define TR_SF_SCREENSHOT "Screenshot" #define TR_SF_RESERVE "[reserve]\0 " - #define TR_VFSWFUNC TR_SF_SAFETY "Aprendiz\0 ""Ajuste Rapido""Reset\0 ""Set \0 " TR_ADJUST_GVAR "Volume\0 " "SetFailsafe\0 " "RangeCheck\0 " "ModuleBind\0 " TR_SOUND TR_PLAY_TRACK TR_PLAY_VALUE TR_SF_RESERVE TR_SF_PLAY_SCRIPT TR_SF_RESERVE TR_SF_BG_MUSIC TR_VVARIO TR_HAPTIC TR_SDCLOGS "Backlight\0 " TR_SF_SCREENSHOT TR_SF_TEST +#define TR_VFSWFUNC TR_SF_SAFETY "Aprendiz\0 ""Ajuste Rapido""Reset\0 ""Set \0 " TR_ADJUST_GVAR "Volume\0 " "SetFailsafe\0 " "RangeCheck\0 " "ModuleBind\0 " TR_SOUND TR_PLAY_TRACK TR_PLAY_VALUE TR_SF_RESERVE TR_SF_PLAY_SCRIPT TR_SF_RESERVE TR_SF_BG_MUSIC TR_VVARIO TR_HAPTIC TR_SDCLOGS "Backlight\0 " TR_SF_SCREENSHOT TR_SF_TEST #define LEN_VFSWRESET TR("\004", "\011") -#if defined(TELEMETRY_FRSKY) - #define TR_FSW_RESET_TELEM TR("Telm", "Telemetry") -#else - #define TR_FSW_RESET_TELEM -#endif +#define TR_FSW_RESET_TELEM TR("Telm", "Telemetry") #if defined(PCBTARANIS) #define TR_FSW_RESET_TIMERS "Timer 1\0 ""Timer 2\0 ""Timer 3\0 " @@ -324,27 +303,6 @@ #define STR_V (STR_VTELEMUNIT+1) #define STR_A (STR_VTELEMUNIT+4) -#define LEN_VALARM "\003" -#define TR_VALARM "---""Ama""Lar""Ver" - -#define LEN_VALARMFN "\001" -#define TR_VALARMFN "<>" - -#define LEN_VTELPROTO "\007" -#define TR_VTELPROTO "Nada\0 ""Hub\0 ""WSHHigh" - - #define LEN_AMPSRC TR("\003", "\007") - #define TR_AMPSRC TR("---""A1\0""A2\0""A3\0""A4\0""FAS""Cel", "---\0 ""A1\0 ""A2\0 ""A3\0 ""A4\0 ""FAS\0 ""Cells\0 ") - #define LEN_VOLTSRC TR("\003", "\007") - #define TR_VOLTSRC TR("A1\0""A2\0""A3\0""A4\0""FAS""Cel", "A1\0 ""A2\0 ""A3\0 ""A4\0 ""FAS\0 ""Cells\0 ") - -#define LEN_VARIOSRC "\005" -#if defined(TELEMETRY_FRSKY_SPORT) - #define TR_VARIOSRC "Vario""A1\0 ""A2\0" -#else - #define TR_VARIOSRC "Alti\0""Alti+""Vario""A1\0 ""A2\0" -#endif - #define LEN_VTELEMSCREENTYPE "\004" #define TR_VTELEMSCREENTYPE "Nums""Bars" @@ -1184,9 +1142,9 @@ #define TR_SERVOS_KO "Servos KO" #define TR_INVERTED_SERIAL INDENT "Invert" #define TR_IGNORE_INSTANCE INDENT "Ignore instance" -#define TR_DISCOVER_SENSORS INDENT "Discover new sensors" -#define TR_STOP_DISCOVER_SENSORS INDENT "Stop discovery" -#define TR_DELETE_ALL_SENSORS INDENT "Delete all sensors" +#define TR_DISCOVER_SENSORS "Discover new sensors" +#define TR_STOP_DISCOVER_SENSORS "Stop discovery" +#define TR_DELETE_ALL_SENSORS "Delete all sensors" #define TR_CONFIRMDELETE "Really " LCDW_128_480_LINEBREAK "delete all ?" #define TR_SELECT_WIDGET "Select widget" #define TR_REMOVE_WIDGET "Remove widget" diff --git a/radio/src/translations/se.h.txt b/radio/src/translations/se.h.txt index e3d34e7ec..1e1f61a5b 100644 --- a/radio/src/translations/se.h.txt +++ b/radio/src/translations/se.h.txt @@ -49,15 +49,9 @@ #define LEN_MMMINV "\003" #define TR_MMMINV "---""INV" -#define LEN_NCHANNELS "\004" -#define TR_NCHANNELS "\0014KN\0016KN\0018KN10KN12KN14KN16KN" - #define LEN_VBEEPMODE "\005" #define TR_VBEEPMODE "Tyst\0""Alarm""EjKnp""Alla\0" -#define LEN_VBEEPLEN "\005" -#define TR_VBEEPLEN "0====""=0===""==0==""===0=""====0" - #define LEN_VRENAVIG "\003" #define TR_VRENAVIG "IngREaREb" @@ -86,9 +80,6 @@ #define LEN_SLIDERTYPES "\010" #define TR_SLIDERTYPES "Ingen\0 ""Skjutpot" -#define LEN_DATETIME "\005" -#define TR_DATETIME "DAG: ""TID: " - #define LEN_VLCD "\006" #define TR_VLCD "NormalOptrex" @@ -154,9 +145,6 @@ #define TR_VPROTOS "PPM\0 " TR_PXX TR_DSM2 -#define LEN_POSNEG "\003" -#define TR_POSNEG "Pos""Neg" - #if defined(PCBSKY9X) && defined(REVX) #define LEN_VOUTPUT_TYPE "\011" #define TR_VOUTPUT_TYPE "OpenDrain""PushPull\0" @@ -264,23 +252,14 @@ #define TR_SF_SAFETY "---\0 " #endif -#if defined(PCBTARANIS) - #define TR_SF_SCREENSHOT "Skärmbild" -#else - #define TR_SF_SCREENSHOT -#endif - +#define TR_SF_SCREENSHOT "Skärmbild" #define TR_SF_RESERVE "[reserve]\0" - #define TR_VFSWFUNC TR_SF_SAFETY "Trainer\0 ""Sätt Trim\0""Nollställ\0""Sätt\0 " TR_ADJUST_GVAR "Volym\0 " "SetFailsfe" "RangeCheck" "ModuleBind" TR_SOUND TR_PLAY_TRACK TR_PLAY_VALUE TR_SF_RESERVE TR_SF_PLAY_SCRIPT TR_SF_RESERVE TR_SF_BG_MUSIC TR_VVARIO TR_HAPTIC TR_SDCLOGS "Belysning\0" TR_SF_SCREENSHOT TR_SF_TEST +#define TR_VFSWFUNC TR_SF_SAFETY "Trainer\0 ""Sätt Trim\0""Nollställ\0""Sätt\0 " TR_ADJUST_GVAR "Volym\0 " "SetFailsfe" "RangeCheck" "ModuleBind" TR_SOUND TR_PLAY_TRACK TR_PLAY_VALUE TR_SF_RESERVE TR_SF_PLAY_SCRIPT TR_SF_RESERVE TR_SF_BG_MUSIC TR_VVARIO TR_HAPTIC TR_SDCLOGS "Belysning\0" TR_SF_SCREENSHOT TR_SF_TEST #define LEN_VFSWRESET TR("\004", "\011") -#if defined(TELEMETRY_FRSKY) - #define TR_FSW_RESET_TELEM TR("Telm", "Telemetry") -#else - #define TR_FSW_RESET_TELEM -#endif +#define TR_FSW_RESET_TELEM TR("Telm", "Telemetry") #if defined(PCBTARANIS) #define TR_FSW_RESET_TIMERS "Timer 1\0 ""Timer 2\0 ""Timer 3\0 " @@ -317,37 +296,16 @@ #define LENGTH_UNIT_METR "m\0 " #define SPEED_UNIT_METR "kmh" - #define LEN_VUNITSSYSTEM TR("\006", "\010") - #define TR_VUNITSSYSTEM TR("Metri.""Imper.", "Metriska""Imperial") - #define LEN_VTELEMUNIT "\003" - #define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz" +#define LEN_VUNITSSYSTEM TR("\006", "\010") +#define TR_VUNITSSYSTEM TR("Metri.""Imper.", "Metriska""Imperial") +#define LEN_VTELEMUNIT "\003" +#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz" #define STR_V (STR_VTELEMUNIT+1) #define STR_A (STR_VTELEMUNIT+4) -#define LEN_VALARM "\003" -#define TR_VALARM "---""Gul""Ora""Röd" - -#define LEN_VALARMFN "\001" -#define TR_VALARMFN "<>" - -#define LEN_VTELPROTO "\007" -#define TR_VTELPROTO "---\0 ""Hub\0 ""WSHHög." - - #define LEN_AMPSRC TR("\003", "\007") - #define TR_AMPSRC TR("---""A1\0""A2\0""A3\0""A4\0""FAS""Cel", "---\0 ""A1\0 ""A2\0 ""A3\0 ""A4\0 ""FAS\0 ""Cells\0 ") - #define LEN_VOLTSRC TR("\003", "\007") - #define TR_VOLTSRC TR("A1\0""A2\0""A3\0""A4\0""FAS""Cel", "A1\0 ""A2\0 ""A3\0 ""A4\0 ""FAS\0 ""Cells\0 ") - -#define LEN_VARIOSRC "\005" -#if defined(TELEMETRY_FRSKY_SPORT) - #define TR_VARIOSRC "Vario""A1\0 ""A2\0" -#else - #define TR_VARIOSRC "Alti\0""Alti+""Vario""A1\0 ""A2\0" -#endif - - #define LEN_VTELEMSCREENTYPE "\007" - #define TR_VTELEMSCREENTYPE "Inget\0 ""Siffror""Staplar""Script\0" +#define LEN_VTELEMSCREENTYPE "\007" +#define TR_VTELEMSCREENTYPE "Inget\0 ""Siffror""Staplar""Script\0" #define LEN_GPSFORMAT "\004" #define TR_GPSFORMAT "HMS NMEA" @@ -1195,9 +1153,9 @@ //TODO: translation #define TR_INVERTED_SERIAL INDENT "Invert" #define TR_IGNORE_INSTANCE TR(INDENT "Inst.fel", INDENT "Hantera Instansfel") -#define TR_DISCOVER_SENSORS INDENT "Sök nya sensorer" -#define TR_STOP_DISCOVER_SENSORS INDENT "Avbryt sökning" -#define TR_DELETE_ALL_SENSORS INDENT "Ta bort alla sensorer" +#define TR_DISCOVER_SENSORS "Sök nya sensorer" +#define TR_STOP_DISCOVER_SENSORS "Avbryt sökning" +#define TR_DELETE_ALL_SENSORS "Ta bort alla sensorer" #define TR_CONFIRMDELETE "Ta bort alla?" #define TR_SELECT_WIDGET "Select widget" #define TR_REMOVE_WIDGET "Remove widget" diff --git a/radio/util/Dockerfile b/radio/util/Dockerfile index 315acb3bd..7648b0302 100644 --- a/radio/util/Dockerfile +++ b/radio/util/Dockerfile @@ -23,3 +23,5 @@ ENV PATH $PATH:/opt/gcc-arm-none-eabi/bin:/opentx/code/radio/util ARG OPENTX_VERSION_SUFFIX= ENV OPENTX_VERSION_SUFFIX ${OPENTX_VERSION_SUFFIX} + +WORKDIR /build diff --git a/radio/util/build-firmware.py b/radio/util/build-firmware.py index eaa548055..6c74ef532 100755 --- a/radio/util/build-firmware.py +++ b/radio/util/build-firmware.py @@ -16,245 +16,221 @@ INVALID_FIRMWARE = 5 INVALID_BOARD = 6 INVALID_LANGUAGE = 7 -# Board types -BOARD_SKY9X = 2 -BOARD_TARANIS = 3 -BOARD_HORUS = 4 -# Board families -BOARD_FAMILY_ARM = 1 - -if len(sys.argv) != 3: - exit(INVALID_FIRMWARE) - -what = sys.argv[1] -directory, filename = os.path.split(sys.argv[2]) -root, ext = os.path.splitext(filename) -options = root.split("-") - -if len(options) < 2 or options[0] != "opentx": - exit(INVALID_FIRMWARE) - -optcount = 1 -command_options = {} - - -if options[optcount] == "sky9x": - command_options["PCB"] = "SKY9X" - firmware_options = options_sky9x - maxsize = 65536 * 4 - board = BOARD_SKY9X - board_family = BOARD_FAMILY_ARM -elif options[optcount] == "9xrpro": - command_options["PCB"] = "9XRPRO" - command_options["SDCARD"] = "YES" - firmware_options = options_sky9x - maxsize = 65536 * 4 - board = BOARD_SKY9X - board_family = BOARD_FAMILY_ARM -elif options[optcount] == "ar9x": - command_options["PCB"] = "AR9X" - command_options["SDCARD"] = "YES" - firmware_options = options_ar9x - maxsize = 65536 * 4 - board = BOARD_SKY9X - board_family = BOARD_FAMILY_ARM -elif options[optcount] == "x9lite": - command_options["PCB"] = "X9LITE" - command_options["MULTI_SPORT"] = "ON" - firmware_options = options_taranis_x9lite - maxsize = 65536 * 8 - board = BOARD_TARANIS - board_family = BOARD_FAMILY_ARM -elif options[optcount] == "x7": - command_options["PCB"] = "X7" - command_options["MULTI_SPORT"] = "ON" - firmware_options = options_taranis_x9dp - maxsize = 65536 * 8 - board = BOARD_TARANIS - board_family = BOARD_FAMILY_ARM -elif options[optcount] == "xlite": - command_options["PCB"] = "XLITE" - command_options["MULTI_SPORT"] = "ON" - firmware_options = options_taranis_xlite - maxsize = 65536 * 8 - board = BOARD_TARANIS - board_family = BOARD_FAMILY_ARM -elif options[optcount] == "xlites": - command_options["PCB"] = "XLITES" - command_options["MULTI_SPORT"] = "ON" - firmware_options = options_taranis_xlites - maxsize = 65536 * 8 - board = BOARD_TARANIS - board_family = BOARD_FAMILY_ARM -elif options[optcount] == "x9d": - command_options["PCB"] = "X9D" - command_options["MULTI_SPORT"] = "ON" - firmware_options = options_taranis_x9d - maxsize = 65536 * 8 - board = BOARD_TARANIS - board_family = BOARD_FAMILY_ARM -elif options[optcount] == "x9d+": - command_options["PCB"] = "X9D+" - command_options["MULTI_SPORT"] = "ON" - firmware_options = options_taranis_x9dp - maxsize = 65536 * 8 - board = BOARD_TARANIS - board_family = BOARD_FAMILY_ARM -elif options[optcount] == "x9d+2019": - command_options["PCB"] = "X9D+" - command_options["PCBREV"] = "2019" - command_options["MULTI_SPORT"] = "ON" - firmware_options = options_taranis_x9dp - maxsize = 65536 * 8 - board = BOARD_TARANIS - board_family = BOARD_FAMILY_ARM -elif options[optcount] == "x9e": - command_options["PCB"] = "X9E" - command_options["MULTI_SPORT"] = "ON" - firmware_options = options_taranis_x9e - maxsize = 65536 * 8 - board = BOARD_TARANIS - board_family = BOARD_FAMILY_ARM -elif options[optcount] == "x10": - command_options["PCB"] = "X10" - command_options["MULTI_SPORT"] = "ON" - firmware_options = options_horus_x10 - maxsize = 2 * 1024 * 1024 - board = BOARD_HORUS - board_family = BOARD_FAMILY_ARM -elif options[optcount] == "x12s": - command_options["PCB"] = "X12S" - command_options["MULTI_SPORT"] = "ON" - firmware_options = options_horus_x12s - maxsize = 2 * 1024 * 1024 - board = BOARD_HORUS - board_family = BOARD_FAMILY_ARM -elif options[optcount] == "t12": - command_options["PCB"] = "X7" - command_options["PCBREV"] = "T12" - command_options["MULTI_SPORT"] = "ON" - firmware_options = options_taranis_x9dp - maxsize = 65536 * 8 - board = BOARD_TARANIS - board_family = BOARD_FAMILY_ARM -else: - exit(INVALID_BOARD) - -if what == "firmware": - if board_family == BOARD_FAMILY_ARM: - ext = ".bin" - else: - ext = ".hex" - target = "firmware" + ext - filename = "opentx" -elif what == "libsimulator": - ext = ".so" - target = "libopentx-" + options[optcount] + "-simulator.so" - filename = "libopentx" -else: - exit(INVALID_BOARD) - -filename += "-" + options[optcount] -optcount += 1 - -# The firmware options -for opt, value in firmware_options.items(): - found = False - for i in range(optcount, len(options)): - if options[i] == opt: - found = True - break - - if found: - optvalue = value[1] - filename += "-" + opt - else: - optvalue = value[2] - - if optvalue is not None: - command_options[value[0]] = optvalue - -# The firmware display language -language = "" -for key in languages: - if key == options[-1]: - language = key -if not language: - exit(INVALID_LANGUAGE) -command_options["TRANSLATIONS"] = language.upper() - -filename += "-" + language + ext -path = os.path.join(directory, filename) -errpath = path + ".err" - - -def build_firmware(path): +def build_target(target, path, cmake_options): srcdir = os.path.dirname(os.path.realpath(__file__)) + "/../.." outpath = path + ".out" - - # cmake 3.7.2 cannot work from / so we need to go into a subdir - os.mkdir("/build") - os.chdir("/build") + errpath = path + ".err" # Launch CMake cmd = ["cmake"] - for opt, value in command_options.items(): - cmd.append("-D%s=%s" % (opt, value)) + for option, value in cmake_options.items(): + cmd.append("-D%s=%s" % (option, value)) if "OPENTX_VERSION_SUFFIX" in os.environ: suffix = os.environ["OPENTX_VERSION_SUFFIX"] cmd.append('-DVERSION_SUFFIX="%s"' % suffix) if suffix.startswith("N"): cmd.append('-DNIGHTLY_BUILD_WARNING=YES') cmd.append(srcdir) + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) output, error = proc.communicate() if proc.returncode == 0: - file(outpath, "a").write("\n".join(cmd) + output + error) + open(outpath, "a").write("\n".join(cmd) + output.decode("utf-8") + error.decode("utf-8")) else: - file(errpath, "w").write(output + error) - print(filename) - exit(COMPILATION_ERROR) + open(errpath, "w").write(output.decode("utf-8") + error.decode("utf-8")) + return COMPILATION_ERROR # Launch make - cmd = ["make", "-j2", what] + cmd = ["make", "-j2", target] proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) output, error = proc.communicate() if proc.returncode == 0: - open(outpath, "a").write(output + error) + open(outpath, "a").write(output.decode("utf-8") + error.decode("utf-8")) else: - open(errpath, "w").write(output + error) + open(errpath, "w").write(output.decode("utf-8") + error.decode("utf-8")) + return COMPILATION_ERROR + + return 0 + + +def main(): + if len(sys.argv) != 3: + exit(INVALID_FIRMWARE) + + target = sys.argv[1] + directory, filename = os.path.split(sys.argv[2]) + root, ext = os.path.splitext(filename) + options = root.split("-") + + if len(options) < 2 or options[0] != "opentx": + exit(INVALID_FIRMWARE) + + optcount = 1 + cmake_options = {} + board_name = options[optcount] + + if board_name == "sky9x": + cmake_options["PCB"] = "SKY9X" + firmware_options = options_sky9x + maxsize = 65536 * 4 + elif board_name == "9xrpro": + cmake_options["PCB"] = "9XRPRO" + cmake_options["SDCARD"] = "YES" + firmware_options = options_sky9x + maxsize = 65536 * 4 + elif board_name == "ar9x": + cmake_options["PCB"] = "AR9X" + cmake_options["SDCARD"] = "YES" + firmware_options = options_ar9x + maxsize = 65536 * 4 + elif board_name == "x9lite": + cmake_options["PCB"] = "X9LITE" + cmake_options["MULTI_SPORT"] = "ON" + firmware_options = options_taranis_x9lite + maxsize = 65536 * 8 + elif board_name == "x7": + cmake_options["PCB"] = "X7" + cmake_options["MULTI_SPORT"] = "ON" + firmware_options = options_taranis_x9dp + maxsize = 65536 * 8 + elif board_name == "xlite": + cmake_options["PCB"] = "XLITE" + cmake_options["MULTI_SPORT"] = "ON" + firmware_options = options_taranis_xlite + maxsize = 65536 * 8 + elif board_name == "xlites": + cmake_options["PCB"] = "XLITES" + cmake_options["MULTI_SPORT"] = "ON" + firmware_options = options_taranis_xlites + maxsize = 65536 * 8 + elif board_name == "x9d": + cmake_options["PCB"] = "X9D" + cmake_options["MULTI_SPORT"] = "ON" + firmware_options = options_taranis_x9d + maxsize = 65536 * 8 + elif board_name == "x9d+": + cmake_options["PCB"] = "X9D+" + cmake_options["MULTI_SPORT"] = "ON" + firmware_options = options_taranis_x9dp + maxsize = 65536 * 8 + elif board_name == "x9d+2019": + cmake_options["PCB"] = "X9D+" + cmake_options["PCBREV"] = "2019" + cmake_options["MULTI_SPORT"] = "ON" + firmware_options = options_taranis_x9dp + maxsize = 65536 * 8 + elif board_name == "x9e": + cmake_options["PCB"] = "X9E" + cmake_options["MULTI_SPORT"] = "ON" + firmware_options = options_taranis_x9e + maxsize = 65536 * 8 + elif board_name == "x10": + cmake_options["PCB"] = "X10" + cmake_options["MULTI_SPORT"] = "ON" + firmware_options = options_horus_x10 + maxsize = 2 * 1024 * 1024 + elif board_name == "x10express": + cmake_options["PCB"] = "X10" + cmake_options["PCBREV"] = "EXPRESS" + cmake_options["MULTI_SPORT"] = "ON" + firmware_options = options_horus_x10 + maxsize = 2 * 1024 * 1024 + elif board_name == "x12s": + cmake_options["PCB"] = "X12S" + cmake_options["MULTI_SPORT"] = "ON" + firmware_options = options_horus_x12s + maxsize = 2 * 1024 * 1024 + elif board_name == "t12": + cmake_options["PCB"] = "X7" + cmake_options["PCBREV"] = "T12" + cmake_options["MULTI_SPORT"] = "ON" + firmware_options = options_taranis_x9dp + maxsize = 65536 * 8 + else: + exit(INVALID_BOARD) + + if target == "firmware": + binary = "firmware.bin" + ext = ".bin" + filename = "opentx" + elif target == "libsimulator": + binary = "libopentx-" + board_name + "-simulator.so" + ext = ".so" + filename = "libopentx" + else: + exit(INVALID_BOARD) + + filename += "-" + board_name + optcount += 1 + + # The firmware options + for opt, values in firmware_options.items(): + found = False + for i in range(optcount, len(options)): + if options[i] == opt: + found = True + break + + if not isinstance(values, list): + values = [values] + + for name, value1, value2 in values: + if found: + value = value1 + filename += "-" + opt + else: + value = value2 + + if value is not None: + cmake_options[name] = value + + # The firmware display language + language = "" + for key in languages: + if key == options[-1]: + language = key + if not language: + exit(INVALID_LANGUAGE) + cmake_options["TRANSLATIONS"] = language.upper() + + filename += "-" + language + ext + path = os.path.join(directory, filename) + errpath = path + ".err" + + if os.path.isfile(errpath): print(filename) exit(COMPILATION_ERROR) - if what == "firmware": + if os.path.isfile(path): + print(filename) + exit(0) + + lockpath = path + ".lock" + lock = filelock.FileLock(lockpath) + try: + with lock.acquire(timeout=60 * 60): + if not os.path.isfile(path): + result = build_target(target, path, cmake_options) + if result != 0: + print(filename) + return result + except filelock.Timeout: + print(filename) + exit(COMPILATION_ERROR) + + if target == "firmware": # Check binary size - if board_family == BOARD_FAMILY_ARM: - size = os.stat(target).st_size + size = os.stat(binary).st_size if size > maxsize: - exit(FIRMWARE_SIZE_TOO_BIG) + return FIRMWARE_SIZE_TOO_BIG # Copy binary to the binaries directory - shutil.move(target, path) + shutil.move(binary, path) - -if os.path.isfile(errpath): - print(filename) - exit(COMPILATION_ERROR) - -if os.path.isfile(path): print(filename) exit(0) -lockpath = path + ".lock" -lock = filelock.FileLock(lockpath) -try: - with lock.acquire(timeout = 60*60): - if not os.path.isfile(path): - build_firmware(path) -except filelock.Timeout: - print(filename) - exit(COMPILATION_ERROR) -print(filename) -exit(0) +if __name__ == "__main__": + main() diff --git a/radio/util/fwoptions.py b/radio/util/fwoptions.py index 75ae7dcf7..da8041bc7 100755 --- a/radio/util/fwoptions.py +++ b/radio/util/fwoptions.py @@ -40,7 +40,6 @@ options_sky9x = { "faimode": ("FAI", "YES", None), "faichoice": ("FAI", "CHOICE", None), "nooverridech": ("OVERRIDE_CHANNEL_FUNCTION", "NO", "YES"), - "multimodule": ("MULTIMODULE", "YES", "NO"), "flexr9m": ("R9M_PROTO_FLEX", "YES", None) } @@ -62,7 +61,6 @@ options_ar9x = { "faichoice": ("FAI", "CHOICE", None), "nooverridech": ("OVERRIDE_CHANNEL_FUNCTION", "NO", "YES"), # "rtc": ("RTCLOCK", "YES", "NO"), - "multimodule": ("MULTIMODULE", "YES", "NO"), "flexr9m": ("R9M_PROTO_FLEX", "YES", None) } @@ -70,7 +68,6 @@ options_taranis_x9d = { "noheli": ("HELI", "NO", "YES"), "ppmus": ("PPM_UNIT", "US", "PERCENT_PREC1"), "lua": ("LUA", "YES", "NO_MODEL_SCRIPTS"), - "luac": ("LUA_COMPILER", "YES", "NO"), "haptic": ("HAPTIC", "YES", "NO"), "nogvars": ("GVARS", "NO", "YES"), "sqt5font": ("FONT", "SQT5", None), @@ -80,8 +77,6 @@ options_taranis_x9d = { "internalppm": ("INTERNAL_MODULE_PPM", "YES", "NO"), "shutdownconfirm": ("SHUTDOWN_CONFIRMATION", "YES", "NO"), "eu": ("SUPPORT_D16_EU_ONLY", "YES", "NO"), - "multimodule": ("MULTIMODULE", "YES", "NO"), - "crossfire": ("CROSSFIRE", "YES", "NO"), "flexr9m": ("R9M_PROTO_FLEX", "YES", None) } @@ -89,7 +84,6 @@ options_taranis_x9dp = { "noheli": ("HELI", "NO", "YES"), "ppmus": ("PPM_UNIT", "US", "PERCENT_PREC1"), "lua": ("LUA", "YES", "NO_MODEL_SCRIPTS"), - "luac": ("LUA_COMPILER", "YES", "NO"), "nogvars": ("GVARS", "NO", "YES"), "sqt5font": ("FONT", "SQT5", None), "noras": ("RAS", "NO", "YES"), @@ -99,8 +93,6 @@ options_taranis_x9dp = { "internalppm": ("INTERNAL_MODULE_PPM", "YES", "NO"), "shutdownconfirm": ("SHUTDOWN_CONFIRMATION", "YES", "NO"), "eu": ("SUPPORT_D16_EU_ONLY", "YES", "NO"), - "multimodule": ("MULTIMODULE", "YES", "NO"), - "crossfire": ("CROSSFIRE", "YES", "NO"), "flexr9m": ("R9M_PROTO_FLEX", "YES", None) } @@ -108,7 +100,6 @@ options_taranis_x9lite = { "noheli": ("HELI", "NO", "YES"), "ppmus": ("PPM_UNIT", "US", "PERCENT_PREC1"), "lua": ("LUA", "YES", "NO_MODEL_SCRIPTS"), - "luac": ("LUA_COMPILER", "YES", "NO"), "nogvars": ("GVARS", "NO", "YES"), "autoupdate": ("AUTOUPDATE", "YES", None), "sqt5font": ("FONT", "SQT5", None), @@ -118,9 +109,7 @@ options_taranis_x9lite = { "nooverridech": ("OVERRIDE_CHANNEL_FUNCTION", "NO", "YES"), "shutdownconfirm": ("SHUTDOWN_CONFIRMATION", "YES", "NO"), "eu": ("SUPPORT_D16_EU_ONLY", "YES", "NO"), - "multimodule": ("MULTIMODULE", "YES", "NO"), "internalpxx1": ("INTERNAL_MODULE_PXX1", "YES", "NO"), - "crossfire": ("CROSSFIRE", "YES", "NO"), "flexr9m": ("R9M_PROTO_FLEX", "YES", None) } @@ -128,7 +117,6 @@ options_taranis_xlite = { "noheli": ("HELI", "NO", "YES"), "ppmus": ("PPM_UNIT", "US", "PERCENT_PREC1"), "lua": ("LUA", "YES", "NO_MODEL_SCRIPTS"), - "luac": ("LUA_COMPILER", "YES", "NO"), "nogvars": ("GVARS", "NO", "YES"), "sqt5font": ("FONT", "SQT5", None), "faimode": ("FAI", "YES", None), @@ -136,8 +124,6 @@ options_taranis_xlite = { "nooverridech": ("OVERRIDE_CHANNEL_FUNCTION", "NO", "YES"), "shutdownconfirm": ("SHUTDOWN_CONFIRMATION", "YES", "NO"), "eu": ("SUPPORT_D16_EU_ONLY", "YES", "NO"), - "multimodule": ("MULTIMODULE", "YES", "NO"), - "crossfire": ("CROSSFIRE", "YES", "NO"), "flexr9m": ("R9M_PROTO_FLEX", "YES", None) } @@ -145,7 +131,6 @@ options_taranis_xlites = { "noheli": ("HELI", "NO", "YES"), "ppmus": ("PPM_UNIT", "US", "PERCENT_PREC1"), "lua": ("LUA", "YES", "NO_MODEL_SCRIPTS"), - "luac": ("LUA_COMPILER", "YES", "NO"), "nogvars": ("GVARS", "NO", "YES"), "autoupdate": ("AUTOUPDATE", "YES", None), "sqt5font": ("FONT", "SQT5", None), @@ -154,9 +139,7 @@ options_taranis_xlites = { "nooverridech": ("OVERRIDE_CHANNEL_FUNCTION", "NO", "YES"), "shutdownconfirm": ("SHUTDOWN_CONFIRMATION", "YES", "NO"), "eu": ("SUPPORT_D16_EU_ONLY", "YES", "NO"), - "multimodule": ("MULTIMODULE", "YES", "NO"), "internalpxx1": ("INTERNAL_MODULE_PXX1", "YES", "NO"), - "crossfire": ("CROSSFIRE", "YES", "NO"), "flexr9m": ("R9M_PROTO_FLEX", "YES", None) } @@ -164,7 +147,6 @@ options_taranis_x9e = { "noheli": ("HELI", "NO", "YES"), "ppmus": ("PPM_UNIT", "US", "PERCENT_PREC1"), "lua": ("LUA", "YES", "NO_MODEL_SCRIPTS"), - "luac": ("LUA_COMPILER", "YES", "NO"), "nogvars": ("GVARS", "NO", "YES"), "sqt5font": ("FONT", "SQT5", None), "faimode": ("FAI", "YES", None), @@ -174,8 +156,6 @@ options_taranis_x9e = { "shutdownconfirm": ("SHUTDOWN_CONFIRMATION", "YES", "NO"), "eu": ("SUPPORT_D16_EU_ONLY", "YES", "NO"), "horussticks": ("STICKS", "HORUS", "STANDARD"), - "multimodule": ("MULTIMODULE", "YES", "NO"), - "crossfire": ("CROSSFIRE", "YES", "NO"), "flexr9m": ("R9M_PROTO_FLEX", "YES", None) } @@ -183,19 +163,30 @@ options_horus_x12s = { "noheli": ("HELI", "NO", "YES"), "ppmus": ("PPM_UNIT", "US", "PERCENT_PREC1"), "lua": ("LUA", "YES", "NO_MODEL_SCRIPTS"), - "luac": ("LUA_COMPILER", "YES", "NO"), "nogvars": ("GVARS", "NO", "YES"), "faimode": ("FAI", "YES", None), "faichoice": ("FAI", "CHOICE", None), "nooverridech": ("OVERRIDE_CHANNEL_FUNCTION", "NO", "YES"), "eu": ("SUPPORT_D16_EU_ONLY", "YES", "NO"), - "multimodule": ("MULTIMODULE", "YES", "NO"), "pcbdev": ("PCBREV", "10", None), - "crossfire": ("CROSSFIRE", "YES", "NO"), - "flexr9m": ("R9M_PROTO_FLEX", "YES", None) + "flexr9m": ("R9M_PROTO_FLEX", "YES", None), + "internalaccess": [("INTERNAL_MODULE_PXX1", "NO", None), ("INTERNAL_MODULE_PXX2", "YES", None)] } options_horus_x10 = { + "noheli": ("HELI", "NO", "YES"), + "ppmus": ("PPM_UNIT", "US", "PERCENT_PREC1"), + "lua": ("LUA", "YES", "NO_MODEL_SCRIPTS"), + "nogvars": ("GVARS", "NO", "YES"), + "faimode": ("FAI", "YES", None), + "faichoice": ("FAI", "CHOICE", None), + "nooverridech": ("OVERRIDE_CHANNEL_FUNCTION", "NO", "YES"), + "eu": ("SUPPORT_D16_EU_ONLY", "YES", "NO"), + "flexr9m": ("R9M_PROTO_FLEX", "YES", None), + "internalaccess": [("INTERNAL_MODULE_PXX1", "NO", None), ("INTERNAL_MODULE_PXX2", "YES", None)] +} + +options_horus_x10express = { "noheli": ("HELI", "NO", "YES"), "ppmus": ("PPM_UNIT", "US", "PERCENT_PREC1"), "lua": ("LUA", "YES", "NO_MODEL_SCRIPTS"), @@ -205,7 +196,5 @@ options_horus_x10 = { "faichoice": ("FAI", "CHOICE", None), "nooverridech": ("OVERRIDE_CHANNEL_FUNCTION", "NO", "YES"), "eu": ("SUPPORT_D16_EU_ONLY", "YES", "NO"), - "multimodule": ("MULTIMODULE", "YES", "NO"), - "crossfire": ("CROSSFIRE", "YES", "NO"), "flexr9m": ("R9M_PROTO_FLEX", "YES", None) } diff --git a/tools/build-companion-nightly.sh b/tools/build-companion-nightly.sh index 6a9ffca5e..c0cf47bd1 100755 --- a/tools/build-companion-nightly.sh +++ b/tools/build-companion-nightly.sh @@ -59,10 +59,10 @@ make -j${JOBS} libsimulator cmake ${COMMON_OPTIONS} -DPCB=X9D ${SRCDIR} make -j${JOBS} libsimulator -cmake ${COMMON_OPTIONS} -DPCB=X9D+ -DPCBREV=2019 ${SRCDIR} +cmake ${COMMON_OPTIONS} -DPCB=X9D+ ${SRCDIR} make -j${JOBS} libsimulator -cmake ${COMMON_OPTIONS} -DPCB=X9D+ ${SRCDIR} +cmake ${COMMON_OPTIONS} -DPCB=X9D+ -DPCBREV=2019 ${SRCDIR} make -j${JOBS} libsimulator cmake ${COMMON_OPTIONS} -DPCB=XLITE ${SRCDIR} @@ -77,6 +77,9 @@ make -j${JOBS} libsimulator cmake ${COMMON_OPTIONS} -DPCB=X10 ${SRCDIR} make -j${JOBS} libsimulator +cmake ${COMMON_OPTIONS} -DPCB=X10 -DPCBREV=EXPRESS ${SRCDIR} +make -j${JOBS} libsimulator + cmake ${COMMON_OPTIONS} -DPCB=X12S ${SRCDIR} make -j${JOBS} libsimulator diff --git a/tools/build-companion-release.sh b/tools/build-companion-release.sh index 33400ae65..14bda21bf 100755 --- a/tools/build-companion-release.sh +++ b/tools/build-companion-release.sh @@ -59,6 +59,9 @@ make -j${JOBS} libsimulator cmake ${COMMON_OPTIONS} -DPCB=X9D+ ${SRCDIR} make -j${JOBS} libsimulator +cmake ${COMMON_OPTIONS} -DPCB=X9D+ -DPCBREV=2019 ${SRCDIR} +make -j${JOBS} libsimulator + cmake ${COMMON_OPTIONS} -DPCB=XLITE ${SRCDIR} make -j${JOBS} libsimulator @@ -71,6 +74,9 @@ make -j${JOBS} libsimulator cmake ${COMMON_OPTIONS} -DPCB=X10 ${SRCDIR} make -j${JOBS} libsimulator +cmake ${COMMON_OPTIONS} -DPCB=X10 -DPCBREV=EXPRESS ${SRCDIR} +make -j${JOBS} libsimulator + cmake ${COMMON_OPTIONS} -DPCB=X12S ${SRCDIR} make -j${JOBS} libsimulator diff --git a/tools/build-frsky.py b/tools/build-frsky.py index f30d68cf5..f08ee39d3 100755 --- a/tools/build-frsky.py +++ b/tools/build-frsky.py @@ -9,6 +9,16 @@ import tempfile options = { + "XLITE": { + "LUA": "NO_MODEL_SCRIPTS", + "GVARS": "YES", + "MODULE_SIZE_STD": "NO", + "PPM": "NO", + "DSM2": "NO", + "MULTIMODULE": "NO", + "CROSSFIRE": "NO", + "SBUS": "NO", + }, "XLITES": { "LUA": "NO_MODEL_SCRIPTS", "GVARS": "YES", @@ -18,6 +28,7 @@ options = { "MODULE_SIZE_STD": "NO", "PPM": "NO", "DSM2": "NO", + "MULTIMODULE": "NO", "CROSSFIRE": "NO", "SBUS": "NO", }, @@ -30,6 +41,7 @@ options = { "MODULE_SIZE_STD": "NO", "PPM": "NO", "DSM2": "NO", + "MULTIMODULE": "NO", "CROSSFIRE": "NO", "SBUS": "NO", "DEFAULT_MODE": "2", @@ -40,6 +52,7 @@ options = { "GVARS": "YES", "AUTOUPDATE": "YES", "PXX1": "YES", + "MULTIMODULE": "NO", "CROSSFIRE": "NO", "DEFAULT_MODE": "2", } diff --git a/tools/commit-tests.sh b/tools/commit-tests.sh index b4bd0f589..83b35fc70 100755 --- a/tools/commit-tests.sh +++ b/tools/commit-tests.sh @@ -66,7 +66,7 @@ if [[ " SKY9X ARM9X ALL " =~ " ${FLAVOR} " ]] ; then cmake ${COMMON_OPTIONS} -DPCB=SKY9X -DHELI=YES DLUA=YES -DTELEMETRY=FRSKY -DPPM_LIMITS_SYMETRICAL=YES -DVARIO=YES -DAUTOSWITCH=YES -DAUTOSOURCE=YES -DAUDIO=YES -DGPS=YES -DPPM_CENTER_ADJUSTABLE=YES -DFLIGHT_MODES=YES -DOVERRIDE_CHANNEL_FUNCTION=YES -DFRSKY_STICKS=YES -DGVARS=YES ${SRCDIR} make -j${CORES} ${FIRMARE_TARGET} make -j${CORES} libsimulator - make -j${CORES} gtests ; ./gtests ${TEST_OPTIONS} + make -j${CORES} gtests && ./gtests-radio ${TEST_OPTIONS} && ./gtests-companion ${TEST_OPTIONS} fi if [[ " AR9X ARM9X ALL " =~ " ${FLAVOR} " ]] ; then @@ -75,7 +75,7 @@ if [[ " AR9X ARM9X ALL " =~ " ${FLAVOR} " ]] ; then cmake ${COMMON_OPTIONS} -DPCB=AR9X -DHELI=YES -DGVARS=YES ${SRCDIR} make -j${CORES} ${FIRMARE_TARGET} make -j${CORES} libsimulator - make -j${CORES} gtests ; ./gtests ${TEST_OPTIONS} + make -j${CORES} gtests && ./gtests-radio ${TEST_OPTIONS} && ./gtests-companion ${TEST_OPTIONS} fi if [[ " 9XRPRO ARM9X ALL " =~ " ${FLAVOR} " ]] ; then @@ -84,7 +84,7 @@ if [[ " 9XRPRO ARM9X ALL " =~ " ${FLAVOR} " ]] ; then cmake ${COMMON_OPTIONS} -DPCB=9XRPRO -DHELI=YES -DGVARS=YES ${SRCDIR} make -j${CORES} ${FIRMARE_TARGET} make -j${CORES} libsimulator - make -j${CORES} gtests ; ./gtests ${TEST_OPTIONS} + make -j${CORES} gtests && ./gtests-radio ${TEST_OPTIONS} && ./gtests-companion ${TEST_OPTIONS} fi if [[ " X9LITE ALL " =~ " ${FLAVOR} " ]] ; then @@ -93,7 +93,7 @@ if [[ " X9LITE ALL " =~ " ${FLAVOR} " ]] ; then cmake ${COMMON_OPTIONS} -DPCB=X9LITE -DHELI=YES -DGVARS=YES ${SRCDIR} make -j${CORES} ${FIRMARE_TARGET} make -j${CORES} libsimulator - make -j${CORES} gtests ; ./gtests ${TEST_OPTIONS} + make -j${CORES} gtests && ./gtests-radio ${TEST_OPTIONS} && ./gtests-companion ${TEST_OPTIONS} fi if [[ " X7 ALL " =~ " ${FLAVOR} " ]] ; then @@ -102,7 +102,7 @@ if [[ " X7 ALL " =~ " ${FLAVOR} " ]] ; then cmake ${COMMON_OPTIONS} -DPCB=X7 -DHELI=YES -DGVARS=YES ${SRCDIR} make -j${CORES} ${FIRMARE_TARGET} make -j${CORES} libsimulator - make -j${CORES} gtests ; ./gtests ${TEST_OPTIONS} + make -j${CORES} gtests && ./gtests-radio ${TEST_OPTIONS} && ./gtests-companion ${TEST_OPTIONS} fi if [[ " XLITE ALL " =~ " ${FLAVOR} " ]] ; then @@ -111,7 +111,7 @@ if [[ " XLITE ALL " =~ " ${FLAVOR} " ]] ; then cmake ${COMMON_OPTIONS} -DPCB=XLITE -DHELI=YES -DGVARS=YES ${SRCDIR} make -j${CORES} ${FIRMARE_TARGET} make -j${CORES} libsimulator - make -j${CORES} gtests ; ./gtests ${TEST_OPTIONS} + make -j${CORES} gtests && ./gtests-radio ${TEST_OPTIONS} && ./gtests-companion ${TEST_OPTIONS} fi if [[ " XLITES ALL " =~ " ${FLAVOR} " ]] ; then @@ -120,7 +120,7 @@ if [[ " XLITES ALL " =~ " ${FLAVOR} " ]] ; then cmake ${COMMON_OPTIONS} -DPCB=XLITES -DHELI=YES -DGVARS=YES ${SRCDIR} make -j${CORES} ${FIRMARE_TARGET} make -j${CORES} libsimulator - make -j${CORES} gtests ; ./gtests ${TEST_OPTIONS} + make -j${CORES} gtests && ./gtests-radio ${TEST_OPTIONS} && ./gtests-companion ${TEST_OPTIONS} fi if [[ " X9D X9 ALL " =~ " ${FLAVOR} " ]] ; then @@ -129,7 +129,7 @@ if [[ " X9D X9 ALL " =~ " ${FLAVOR} " ]] ; then cmake ${COMMON_OPTIONS} -DPCB=X9D -DHELI=YES -DLUA=YES -DGVARS=YES ${SRCDIR} make -j${CORES} ${FIRMARE_TARGET} make -j${CORES} libsimulator - make -j${CORES} gtests ; ./gtests ${TEST_OPTIONS} + make -j${CORES} gtests && ./gtests-radio ${TEST_OPTIONS} && ./gtests-companion ${TEST_OPTIONS} fi if [[ " X9D+ X9 ALL " =~ " ${FLAVOR} " ]] ; then @@ -138,7 +138,7 @@ if [[ " X9D+ X9 ALL " =~ " ${FLAVOR} " ]] ; then cmake ${COMMON_OPTIONS} -DPCB=X9D+ -DHELI=YES -DLUA=YES -DGVARS=YES ${SRCDIR} make -j${CORES} ${FIRMARE_TARGET} make -j${CORES} libsimulator - make -j${CORES} gtests ; ./gtests ${TEST_OPTIONS} + make -j${CORES} gtests && ./gtests-radio ${TEST_OPTIONS} && ./gtests-companion ${TEST_OPTIONS} fi if [[ " X9D+2019 X9 ALL " =~ " ${FLAVOR} " ]] ; then @@ -147,7 +147,7 @@ if [[ " X9D+2019 X9 ALL " =~ " ${FLAVOR} " ]] ; then cmake ${COMMON_OPTIONS} -DPCB=X9D+ -DPCBREV=2019 -DHELI=YES -DLUA=YES -DGVARS=YES ${SRCDIR} make -j${CORES} ${FIRMARE_TARGET} make -j${CORES} libsimulator - make -j${CORES} gtests ; ./gtests ${TEST_OPTIONS} + make -j${CORES} gtests && ./gtests-radio ${TEST_OPTIONS} && ./gtests-companion ${TEST_OPTIONS} fi if [[ " X9E X9 ALL " =~ " ${FLAVOR} " ]] ; then @@ -156,7 +156,7 @@ if [[ " X9E X9 ALL " =~ " ${FLAVOR} " ]] ; then cmake ${COMMON_OPTIONS} -DPCB=X9E -DHELI=YES -DLUA=YES -DGVARS=YES -DPPM_UNIT=PERCENT_PREC1 ${SRCDIR} make -j${CORES} ${FIRMARE_TARGET} make -j${CORES} libsimulator - make -j${CORES} gtests ; ./gtests ${TEST_OPTIONS} + make -j${CORES} gtests && ./gtests-radio ${TEST_OPTIONS} && ./gtests-companion ${TEST_OPTIONS} fi if [[ " X10 HORUS ALL " =~ " ${FLAVOR} " ]] ; then @@ -165,7 +165,7 @@ if [[ " X10 HORUS ALL " =~ " ${FLAVOR} " ]] ; then cmake ${COMMON_OPTIONS} -DPCB=X10 -DHELI=YES -DLUA=YES -DGVARS=YES ${SRCDIR} make -j${CORES} ${FIRMARE_TARGET} make -j${CORES} libsimulator - make -j${CORES} gtests ; ./gtests ${TEST_OPTIONS} + make -j${CORES} gtests && ./gtests-radio ${TEST_OPTIONS} && ./gtests-companion ${TEST_OPTIONS} fi if [[ " X12S HORUS ALL " =~ " ${FLAVOR} " ]] ; then @@ -174,7 +174,7 @@ if [[ " X12S HORUS ALL " =~ " ${FLAVOR} " ]] ; then cmake ${COMMON_OPTIONS} -DPCB=X12S -DHELI=YES -DLUA=YES -DGVARS=YES ${SRCDIR} make -j${CORES} ${FIRMARE_TARGET} make -j${CORES} libsimulator - make -j${CORES} gtests ; ./gtests ${TEST_OPTIONS} + make -j${CORES} gtests && ./gtests-radio ${TEST_OPTIONS} && ./gtests-companion ${TEST_OPTIONS} fi if [[ " T12 ALL " =~ " ${FLAVOR} " ]] ; then @@ -183,7 +183,7 @@ if [[ " T12 ALL " =~ " ${FLAVOR} " ]] ; then cmake ${COMMON_OPTIONS} -DPCB=X7 -DPCBREV=T12 -DHELI=YES -DGVARS=YES ${SRCDIR} make -j${CORES} ${FIRMARE_TARGET} make -j${CORES} libsimulator - make -j${CORES} gtests ; ./gtests ${TEST_OPTIONS} + make -j${CORES} gtests && ./gtests-radio ${TEST_OPTIONS} && ./gtests-companion ${TEST_OPTIONS} fi if [[ " DEFAULT ALL " =~ " ${FLAVOR} " ]] ; then diff --git a/tools/nightly23/build-nightly.sh b/tools/nightly23/build-nightly.sh index 71c1c920a..e452eb1fe 100755 --- a/tools/nightly23/build-nightly.sh +++ b/tools/nightly23/build-nightly.sh @@ -35,7 +35,7 @@ docker run -dit --name companion -v /home/opentx/${docker}:/opentx ${docker} docker exec companion sh -c "mkdir -p build && cd build && cmake /opentx/code && cp radio/src/stamp.h /opentx/binaries/stamp-opentx.txt" cp -f ${workdir}/binaries/stamp-opentx.txt ${output}/firmware # These radios are currently not enabled -echo "#define BLOCK \"x10,x12s\"" >> ${output}/firmware/stamp-opentx.txt +# echo "#define BLOCK \"x10,x12s\"" >> ${output}/firmware/stamp-opentx.txt docker exec companion rm -rf build echo "Check if Linux companion is needed" diff --git a/tools/nightly23/build-sdcard.sh b/tools/nightly23/build-sdcard.sh index 6f915608e..81b4c209f 100755 --- a/tools/nightly23/build-sdcard.sh +++ b/tools/nightly23/build-sdcard.sh @@ -1,6 +1,7 @@ #!/bin/bash set -e +set -x branch=2.3 workdir=/home/opentx/nightly23 @@ -26,10 +27,6 @@ else mkdir -p ${workdir}/sdcard/horus/IMAGES cp /home/opentx/horus-bitmaps/* ${workdir}/sdcard/horus/IMAGES/ - # Get FrSky utilities - cp -r ${workdir}/code/radio/sdcard/FrSky-utilities ${workdir}/sdcard/horus/ - cp -r ${workdir}/code/radio/sdcard/FrSky-utilities ${workdir}/sdcard/taranis-x7/ - cp -r ${workdir}/code/radio/sdcard/FrSky-utilities ${workdir}/sdcard/taranis-x9/ # Request sound pack generation if [[ ! -d /tmp/SOUNDS/fr ]];then