From 06b0694f034ff503bc47fc8788a7dd03405662d3 Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Sat, 24 Dec 2016 00:04:11 +0100 Subject: [PATCH] Schwabe/multi telemetry (#4151) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add FY805 protocol * Fix stray space * Fix multi sending 120% instead of 100%. * Implement a custom telemetry for the multi module The custom telemetry allows the module to tell the telemetry protocol to OpenTX and also allows signaling the status of the Module (e.g. invalid protocol) to OpenTX This should also close #3979. * Cosmetics and a few small bugfixes * remove empty if * Move status line directly below the mode to be always visible when selecting a protocol * warn if internal RF module is on * Replace sprint with small helper function to build on AVR ARM (AR9X, 9XPRO, …) * TR in wrong order, RF_PROTO_OFF inverted * Refactor definition of Multimodule protocols to have one central place to define all multi protocol properties * Also update protocols in companion * Update multi version number to display as a.b.c.d --- companion/src/eeprominterface.cpp | 6 +- companion/src/modelprinter.cpp | 12 +- radio/src/gui/128x64/model_setup.cpp | 154 ++++------- radio/src/gui/128x64/model_telemetry.cpp | 3 +- radio/src/gui/212x64/model_setup.cpp | 148 +++-------- radio/src/gui/480x272/model_setup.cpp | 140 +++------- radio/src/gui/gui_common.h | 21 +- radio/src/gui/gui_common_arm.cpp | 44 +++- radio/src/myeeprom.h | 3 +- radio/src/pulses/multi_arm.cpp | 15 +- radio/src/targets/common/arm/CMakeLists.txt | 2 +- radio/src/telemetry/flysky_ibus.cpp | 8 +- radio/src/telemetry/flysky_ibus.h | 4 + radio/src/telemetry/frsky.h | 4 +- radio/src/telemetry/frsky_d.cpp | 2 +- radio/src/telemetry/frsky_d_arm.cpp | 2 +- radio/src/telemetry/frsky_sport.cpp | 4 +- radio/src/telemetry/multi.cpp | 274 ++++++++++++++++++++ radio/src/telemetry/multi.h | 118 +++++++++ radio/src/telemetry/spektrum.cpp | 33 +-- radio/src/telemetry/spektrum.h | 4 +- radio/src/telemetry/telemetry.cpp | 13 +- radio/src/telemetry/telemetry.h | 16 +- radio/src/tests/frsky.cpp | 8 +- radio/src/translations.cpp | 10 + radio/src/translations.h | 31 ++- radio/src/translations/cz.h.txt | 20 +- radio/src/translations/de.h.txt | 23 +- radio/src/translations/en.h.txt | 22 +- radio/src/translations/es.h.txt | 22 +- radio/src/translations/fi.h.txt | 22 +- radio/src/translations/fr.h.txt | 22 +- radio/src/translations/it.h.txt | 22 +- radio/src/translations/nl.h.txt | 22 +- radio/src/translations/pl.h.txt | 22 +- radio/src/translations/pt.h.txt | 22 +- radio/src/translations/se.h.txt | 13 +- 37 files changed, 888 insertions(+), 423 deletions(-) create mode 100644 radio/src/telemetry/multi.cpp create mode 100644 radio/src/telemetry/multi.h diff --git a/companion/src/eeprominterface.cpp b/companion/src/eeprominterface.cpp index 0877a2162..7165baa57 100644 --- a/companion/src/eeprominterface.cpp +++ b/companion/src/eeprominterface.cpp @@ -1831,14 +1831,18 @@ unsigned int getNumSubtypes(MultiModuleRFProtocols type) { case MM_RF_PROTO_KN: case MM_RF_PROTO_SLT: case MM_RF_PROTO_Q2X2: + case MM_RF_PROTO_FY326: + case MM_RF_PROTO_BAYANG: + case MM_RF_PROTO_V2X2: return 2; case MM_RF_PROTO_CG023: - case MM_RF_PROTO_MT99XX: return 3; case MM_RF_PROTO_FRSKY: case MM_RF_PROTO_DSM2: + case MM_RF_PROTO_MT99XX: + case MM_RF_PROTO_HONTAI: case MM_RF_PROTO_AFHDS2A: return 4; diff --git a/companion/src/modelprinter.cpp b/companion/src/modelprinter.cpp index 2d9f25856..220e09ae1 100644 --- a/companion/src/modelprinter.cpp +++ b/companion/src/modelprinter.cpp @@ -129,7 +129,8 @@ QString ModelPrinter::printMultiRfProtocol(int rfProtocol, bool custom) { static const char *strings[] = { "FlySky", "Hubsan", "FrSky", "Hisky", "V2x2", "DSM", "Devo", "YD717", "KN", "SymaX", "SLT", "CX10", "CG023", - "Bayang", "ESky", "MT99XX", "MJXQ", "Shenqi", "FY326", "SFHSS", "J6 PRO","FQ777","Assan","Hontai","OLRS","FlySky AFHDS2A" + "Bayang", "ESky", "MT99XX", "MJXQ", "Shenqi", "FY326", "SFHSS", "J6 PRO","FQ777","Assan","Hontai","OLRS", + "FlySky AFHDS2A", "Q2x2" }; if (custom) return "Custom - proto " + QString::number(rfProtocol); @@ -143,15 +144,18 @@ QString ModelPrinter::printMultiSubType(int rfProtocol, bool custom, int subType static const char *flysky_strings[] = {"Standard", "V9x9", "V6x6", "V912", "CX20"}; static const char *frsky_strings[] = {"D16", "D8", "D16 8ch", "V8"}; static const char *hisky_strings[] = {"HiSky", "HK310"}; + static const char *v2x2_strings[] = {"V2x2", "JXD506"}; static const char *dsm2_strings[] = {"DSM2 22ms", "DSM2 11ms", "DSMX 22ms", "DSMX 11ms"}; static const char *yd717_strings[] = {"YD717", "Skywalker", "Syma X2", "XINXUN", "NIHUI"}; static const char *symax_strings[] = {"Standard", "Syma X5C"}; static const char *slt_strings[] = {"SLT", "Vista"}; static const char *cx10_strings[] = {"Green", "Blue", "DM007", "-", "JC3015a", "JC3015b", "MK33041", "Q242"}; static const char *cg023_strings[] = {"CG023", "YD829", "H3 3D"}; + static const char *bayang_strings[] = {"Bayang", "H8S3D"}; static const char *kn_strings[] = {"WLtoys", "FeiLun"}; static const char *mt99_strings[] = {"MT99", "H7", "YZ"}; static const char *mjxq_strings[] = {"WLH08", "X600", "X800", "H26D", "E010"}; + static const char *fy326_strings[] = {"FY326", "FY319"}; static const char *hontai_strings[] = {"Standard", "JJRC X1", "X5C1 Clone"}; static const char *afhds2a_strings[] = {"PWM and IBUS", "PPM and IBUS", "PWM and SBUS", "PPM and SBUS"}; static const char *q2x2_strings[] = {"Q242", "Q282"}; @@ -168,6 +172,8 @@ QString ModelPrinter::printMultiSubType(int rfProtocol, bool custom, int subType return CHECK_IN_ARRAY(hisky_strings, subType); case MM_RF_PROTO_DSM2: return CHECK_IN_ARRAY(dsm2_strings, subType); + case MM_RF_PROTO_V2X2: + return CHECK_IN_ARRAY(v2x2_strings, subType); case MM_RF_PROTO_YD717: return CHECK_IN_ARRAY(yd717_strings, subType); case MM_RF_PROTO_SYMAX: @@ -178,12 +184,16 @@ QString ModelPrinter::printMultiSubType(int rfProtocol, bool custom, int subType return CHECK_IN_ARRAY(cx10_strings, subType); case MM_RF_PROTO_CG023: return CHECK_IN_ARRAY(cg023_strings, subType); + case MM_RF_PROTO_BAYANG: + return CHECK_IN_ARRAY(bayang_strings, subType); case MM_RF_PROTO_KN: return CHECK_IN_ARRAY(kn_strings, subType); case MM_RF_PROTO_MT99XX: return CHECK_IN_ARRAY(mt99_strings, subType); case MM_RF_PROTO_MJXQ: return CHECK_IN_ARRAY(mjxq_strings, subType); + case MM_RF_PROTO_FY326: + return CHECK_IN_ARRAY(fy326_strings, subType); case MM_RF_PROTO_HONTAI: return CHECK_IN_ARRAY(hontai_strings, subType); case MM_RF_PROTO_AFHDS2A: diff --git a/radio/src/gui/128x64/model_setup.cpp b/radio/src/gui/128x64/model_setup.cpp index 84089d078..119937351 100644 --- a/radio/src/gui/128x64/model_setup.cpp +++ b/radio/src/gui/128x64/model_setup.cpp @@ -67,6 +67,7 @@ enum MenuModelSetupItems { ITEM_MODEL_EXTERNAL_MODULE_MODE, #if defined(MULTIMODULE) ITEM_MODEL_EXTERNAL_MODULE_SUBTYPE, + ITEM_MODEL_EXTERNAL_MODULE_STATUS, #endif ITEM_MODEL_EXTERNAL_MODULE_CHANNELS, ITEM_MODEL_EXTERNAL_MODULE_BIND, @@ -179,6 +180,7 @@ void menuModelSetup(event_t event) LABEL(ExternalModule), EXTERNAL_MODULE_MODE_ROWS, MULTIMODULE_SUBTYPE_ROWS(EXTERNAL_MODULE) + MULTIMODULE_STATUS_ROW EXTERNAL_MODULE_CHANNELS_ROWS, EXTERNAL_MODULE_BIND_ROWS(), OUTPUT_TYPE_ROWS() @@ -191,6 +193,7 @@ void menuModelSetup(event_t event) LABEL(ExternalModule), EXTERNAL_MODULE_MODE_ROWS, MULTIMODULE_SUBTYPE_ROWS(EXTERNAL_MODULE) + MULTIMODULE_STATUS_ROW EXTERNAL_MODULE_CHANNELS_ROWS, EXTERNAL_MODULE_BIND_ROWS(), OUTPUT_TYPE_ROWS() @@ -549,7 +552,7 @@ void menuModelSetup(event_t event) if (attr) g_model.noGlobalFunctions = !checkIncDecModel(event, !g_model.noGlobalFunctions, 0, 1); break; #endif - + #if defined(PCBX7) case ITEM_MODEL_INTERNAL_MODULE_LABEL: lcdDrawTextAlignedLeft(y, TR_INTERNALRF); @@ -568,7 +571,7 @@ void menuModelSetup(event_t event) } break; #endif - + #if defined(PCBSKY9X) case ITEM_MODEL_EXTRA_MODULE_LABEL: lcdDrawTextAlignedLeft(y, "RF Port 2 (PPM)"); @@ -644,91 +647,25 @@ void menuModelSetup(event_t event) case ITEM_MODEL_EXTERNAL_MODULE_SUBTYPE: { lcdDrawTextAlignedLeft(y, STR_SUBTYPE); - switch (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true)) { - case MM_RF_PROTO_FLYSKY: - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_SUBTYPE_FLYSKY, g_model.moduleData[EXTERNAL_MODULE].subType, attr); - break; - case MM_RF_PROTO_FRSKY: - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_SUBTYPE_FRSKY, g_model.moduleData[EXTERNAL_MODULE].subType, attr); - break; - case MM_RF_PROTO_HISKY: - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_SUBTYPE_HISKY, g_model.moduleData[EXTERNAL_MODULE].subType, attr); - break; - case MM_RF_PROTO_DSM2: - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_SUBTYPE_DSM, g_model.moduleData[EXTERNAL_MODULE].subType, attr); - break; - case MM_RF_PROTO_YD717: - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_SUBTYPE_YD717, g_model.moduleData[EXTERNAL_MODULE].subType, attr); - break; - case MM_RF_PROTO_KN: - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_SUBTYPE_KN, g_model.moduleData[EXTERNAL_MODULE].subType, attr); - break; - case MM_RF_PROTO_SYMAX: - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_SUBTYPE_SYMAX, g_model.moduleData[EXTERNAL_MODULE].subType, attr); - break; - case MM_RF_PROTO_SLT: - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_SUBTYPE_SLT, g_model.moduleData[EXTERNAL_MODULE].subType, attr); - break; - case MM_RF_PROTO_CX10: - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_SUBTYPE_CX10, g_model.moduleData[EXTERNAL_MODULE].subType, attr); - break; - case MM_RF_PROTO_CG023: - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_SUBTYPE_CG023, g_model.moduleData[EXTERNAL_MODULE].subType, attr); - break; - case MM_RF_PROTO_MT99XX: - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_SUBTYPE_MT99, g_model.moduleData[EXTERNAL_MODULE].subType, attr); - break; - case MM_RF_PROTO_MJXQ: - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_SUBTYPE_MJXQ, g_model.moduleData[EXTERNAL_MODULE].subType, attr); - break; - case MM_RF_PROTO_HONTAI: - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_SUBTYPE_HONTAI, g_model.moduleData[EXTERNAL_MODULE].subType, attr); - break; - case MM_RF_PROTO_FS_AFHDS2A: - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_SUBTYPE_AFHDS2A, g_model.moduleData[EXTERNAL_MODULE].subType, attr); - break; - case MM_RF_PROTO_Q2X2: - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_SUBTYPE_Q2X2, g_model.moduleData[EXTERNAL_MODULE].subType, attr); - break; - case MM_RF_CUSTOM_SELECTED: + uint8_t multi_rfProto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true); + const mm_protocol_definition *pdef = getMultiProtocolDefinition(multi_rfProto); + + if (multi_rfProto == MM_RF_CUSTOM_SELECTED) { lcdDrawNumber(MODEL_SETUP_2ND_COLUMN + 3 * FW, y, g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false), RIGHT | (menuHorizontalPosition == 0 ? attr : 0), 2); lcdDrawNumber(MODEL_SETUP_2ND_COLUMN + 5 * FW, y, g_model.moduleData[EXTERNAL_MODULE].subType, RIGHT | (menuHorizontalPosition == 1 ? attr : 0), 2); - break; + } else + { + if (pdef->subTypeString != nullptr) + lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, pdef->subTypeString, g_model.moduleData[EXTERNAL_MODULE].subType, attr); } if (attr && (editMode > 0 || p1valdiff)) { switch (menuHorizontalPosition) { case 0: - switch (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true)) { - case MM_RF_PROTO_HISKY: - case MM_RF_PROTO_SYMAX: - case MM_RF_PROTO_KN: - case MM_RF_PROTO_SLT: - case MM_RF_PROTO_Q2X2: - CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, 1); - break; - case MM_RF_PROTO_CG023: - CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, 2); - break; - case MM_RF_PROTO_FRSKY: - case MM_RF_PROTO_DSM2: - case MM_RF_PROTO_MT99XX: - case MM_RF_PROTO_FS_AFHDS2A: - CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, 3); - break; - case MM_RF_PROTO_MJXQ: - case MM_RF_PROTO_YD717: - case MM_RF_PROTO_FLYSKY: - CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, 4); - break; - case MM_RF_PROTO_CX10: - CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, 7); - break; - case MM_RF_CUSTOM_SELECTED: - //custom protocol using the highest bit 0x20 to indicate that the protocol and the lower bits as the rfProtocol - g_model.moduleData[EXTERNAL_MODULE].setMultiProtocol(checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false), 0, 63, EE_MODEL)); - break; - } - break; + if (multi_rfProto == MM_RF_CUSTOM_SELECTED) + g_model.moduleData[EXTERNAL_MODULE].setMultiProtocol(checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false), 0, 63, EE_MODEL)); + else if (pdef->maxSubtype > 0) + CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, pdef->maxSubtype); + case 1: // Custom protocol, third column is subtype CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, 7); @@ -738,7 +675,7 @@ void menuModelSetup(event_t event) } break; #endif - + #if defined(PCBX7) case ITEM_MODEL_TRAINER_LABEL: lcdDrawTextAlignedLeft(y, STR_TRAINER); @@ -786,7 +723,7 @@ void menuModelSetup(event_t event) break; } #endif - + #if defined(PCBX7) case ITEM_MODEL_TRAINER_SETTINGS: case ITEM_MODEL_INTERNAL_MODULE_BIND: @@ -848,8 +785,8 @@ void menuModelSetup(event_t event) lcdDrawText(MODEL_SETUP_2ND_COLUMN+MODEL_SETUP_RANGE_OFS+xOffsetBind, y, STR_MODULE_RANGE, l_posHorz==2 ? attr : 0); uint8_t newFlag = 0; #if defined(MULTIMODULE) - if (spektrumBindFinished) { - spektrumBindFinished = false; + if (multiBindStatus == MULTI_BIND_FINISHED) { + multiBindStatus = MULTI_NORMAL_OPERATION; s_editMode=0; } #endif @@ -861,6 +798,10 @@ void menuModelSetup(event_t event) } } moduleFlag[moduleIdx] = newFlag; +#if defined(MULTIMODULE) + if (newFlag == MODULE_BIND) + multiBindStatus = MULTI_BIND_INITIATED; +#endif } } break; @@ -876,7 +817,7 @@ void menuModelSetup(event_t event) break; } #endif - + #if defined(PCBX7) case ITEM_MODEL_INTERNAL_MODULE_FAILSAFE: #endif @@ -918,31 +859,19 @@ void menuModelSetup(event_t event) else if (IS_MODULE_MULTIMODULE(moduleIdx)) { int optionValue = g_model.moduleData[moduleIdx].multi.optionValue; - switch (g_model.moduleData[moduleIdx].getMultiProtocol(true)) - { - case MM_RF_PROTO_FRSKY: - case MM_RF_PROTO_SFHSS: - lcdDrawTextAlignedLeft(y, STR_MULTI_RFTUNE); - break; - case MM_RF_PROTO_HUBSAN: - lcdDrawTextAlignedLeft(y, STR_MULTI_VIDFREQ); - break; - case MM_RF_PROTO_OLRS: - lcdDrawTextAlignedLeft(y, STR_MULTI_RFPOWER); - break; - case MM_RF_PROTO_FS_AFHDS2A: - lcdDrawTextAlignedLeft(y, TR_MULTI_SERVOFREQ); - optionValue = 50 + 5 * optionValue; - break; - default: - lcdDrawTextAlignedLeft(y, STR_MULTI_OPTION); - break; - } + const uint8_t multi_proto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false); + const mm_protocol_definition* pdef = getMultiProtocolDefinition(multi_proto); + if (pdef->optionsstr) + lcdDrawTextAlignedLeft(y, pdef->optionsstr); + + if (multi_proto == MM_RF_PROTO_FS_AFHDS2A) + optionValue = 50 + 5 * optionValue; + lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, optionValue, LEFT | attr); if (attr) { - if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) == MM_RF_PROTO_FS_AFHDS2A) { + if (multi_proto == MM_RF_PROTO_FS_AFHDS2A) { CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].multi.optionValue, 0, 70); - } else if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) == MM_RF_PROTO_OLRS) { + } else if (multi_proto == MM_RF_PROTO_OLRS) { CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].multi.optionValue, -1, 7); } else { CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].multi.optionValue, -128, 127); @@ -963,6 +892,15 @@ void menuModelSetup(event_t event) case ITEM_MODEL_EXTERNAL_MODULE_LOWPOWER: g_model.moduleData[EXTERNAL_MODULE].multi.lowPowerMode = editCheckBox(g_model.moduleData[EXTERNAL_MODULE].multi.lowPowerMode, MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_LOWPOWER, attr, event); break; + case ITEM_MODEL_EXTERNAL_MODULE_STATUS: { + lcdDrawTextAlignedLeft(y, STR_MODULE_STATUS); + + char statusText[64]; + multiModuleStatus.getStatusString(statusText); + lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, statusText); + break; + } + #endif #endif diff --git a/radio/src/gui/128x64/model_telemetry.cpp b/radio/src/gui/128x64/model_telemetry.cpp index 802c71db9..2b578fc4f 100644 --- a/radio/src/gui/128x64/model_telemetry.cpp +++ b/radio/src/gui/128x64/model_telemetry.cpp @@ -679,8 +679,7 @@ void menuModelTelemetryFrsky(event_t event) case ITEM_TELEMETRY_RSSI_LABEL: #if defined(MULTIMODULE) - if (g_model.moduleData[INTERNAL_MODULE].rfProtocol == RF_PROTO_OFF && - g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_MULTIMODULE && + if (telemetryProtocol == PROTOCOL_MULTIMODULE && g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false) == MM_RF_PROTO_FS_AFHDS2A) lcdDrawTextAlignedLeft(y, PSTR("RSNR")); else diff --git a/radio/src/gui/212x64/model_setup.cpp b/radio/src/gui/212x64/model_setup.cpp index 0880a31e4..389eb4bc3 100644 --- a/radio/src/gui/212x64/model_setup.cpp +++ b/radio/src/gui/212x64/model_setup.cpp @@ -76,6 +76,9 @@ enum MenuModelSetupItems { ITEM_MODEL_INTERNAL_MODULE_FAILSAFE, ITEM_MODEL_EXTERNAL_MODULE_LABEL, ITEM_MODEL_EXTERNAL_MODULE_MODE, +#if defined (MULTIMODULE) + ITEM_MODEL_EXTERNAL_MODULE_STATUS, +#endif ITEM_MODEL_EXTERNAL_MODULE_CHANNELS, ITEM_MODEL_EXTERNAL_MODULE_BIND, ITEM_MODEL_EXTERNAL_MODULE_FAILSAFE, @@ -254,6 +257,7 @@ void menuModelSetup(event_t event) IF_INTERNAL_MODULE_ON((IS_MODULE_XJT(INTERNAL_MODULE)) ? FAILSAFE_ROWS(INTERNAL_MODULE) : HIDDEN_ROW), LABEL(ExternalModule), (IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0, + MULTIMODULE_STATUS_ROW EXTERNAL_MODULE_CHANNELS_ROWS, (IS_MODULE_XJT(EXTERNAL_MODULE) && !HAS_RF_PROTOCOL_MODELINDEX(g_model.moduleData[EXTERNAL_MODULE].rfProtocol)) ? (uint8_t)1 : (IS_MODULE_PPM(EXTERNAL_MODULE) || IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW, IF_EXTERNAL_MODULE_XJT(FAILSAFE_ROWS(EXTERNAL_MODULE)), @@ -268,6 +272,7 @@ void menuModelSetup(event_t event) IF_INTERNAL_MODULE_ON(FAILSAFE_ROWS(INTERNAL_MODULE)), LABEL(ExternalModule), EXTERNAL_MODULE_MODE_ROWS, + MULTIMODULE_STATUS_ROW EXTERNAL_MODULE_CHANNELS_ROWS, (IS_MODULE_XJT(EXTERNAL_MODULE) && !HAS_RF_PROTOCOL_FAILSAFE(g_model.moduleData[EXTERNAL_MODULE].rfProtocol)) ? (uint8_t)1 : (IS_MODULE_PPM(EXTERNAL_MODULE) || IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW, FAILSAFE_ROWS(EXTERNAL_MODULE), MULTIMODULE_MODULE_ROWS @@ -695,64 +700,20 @@ void menuModelSetup(event_t event) lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_DSM_PROTOCOLS, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, menuHorizontalPosition==1 ? attr : 0); #if defined(MULTIMODULE) else if (IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) { - int multi_rfProto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false); + uint8_t multi_rfProto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false); // 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(MODEL_SETUP_2ND_COLUMN+5*FW, y, STR_MULTI_CUSTOM, menuHorizontalPosition==1 ? attr : 0); - else + if (g_model.moduleData[EXTERNAL_MODULE].multi.customProto) { + lcdDrawText(MODEL_SETUP_2ND_COLUMN + 5 * FW, y, STR_MULTI_CUSTOM, menuHorizontalPosition == 1 ? attr : 0); + lcdDrawNumber(MODEL_SETUP_2ND_COLUMN + 14 * FW, y, g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false), menuHorizontalPosition == 2 ? attr : 0, 2); + lcdDrawNumber(MODEL_SETUP_2ND_COLUMN + 16 * FW, y, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition == 3 ? attr : 0, 2); + } + else { lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+5*FW, y, STR_MULTI_PROTOCOLS, multi_rfProto, menuHorizontalPosition==1 ? attr : 0); - switch(g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true)) { - case MM_RF_PROTO_FLYSKY: - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+11*FW, y, STR_SUBTYPE_FLYSKY, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); - break; - case MM_RF_PROTO_FRSKY: - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+11*FW, y, STR_SUBTYPE_FRSKY, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); - break; - case MM_RF_PROTO_HISKY: - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+10*FW, y, STR_SUBTYPE_HISKY, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); - break; - case MM_RF_PROTO_DSM2: - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+10*FW, y, STR_SUBTYPE_DSM, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); - break; - case MM_RF_PROTO_YD717: - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+10*FW, y, STR_SUBTYPE_YD717, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); - break; - case MM_RF_PROTO_KN: - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+11*FW, y, STR_SUBTYPE_KN, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); - break; - case MM_RF_PROTO_SYMAX: - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+11*FW, y, STR_SUBTYPE_SYMAX, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); - break; - case MM_RF_PROTO_SLT: - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+11*FW, y, STR_SUBTYPE_SLT, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); - break; - case MM_RF_PROTO_CX10: - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+10*FW, y, STR_SUBTYPE_CX10, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); - break; - case MM_RF_PROTO_CG023: - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+10*FW, y, STR_SUBTYPE_CG023, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); - break; - case MM_RF_PROTO_MT99XX: - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+11*FW, y, STR_SUBTYPE_MT99, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); - break; - case MM_RF_PROTO_MJXQ: - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+11*FW, y, STR_SUBTYPE_MJXQ, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); - break; - case MM_RF_PROTO_HONTAI: - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+11*FW, y, STR_SUBTYPE_HONTAI, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); - break; - case MM_RF_PROTO_FS_AFHDS2A: - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+10*FW, y, STR_SUBTYPE_AFHDS2A , g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); - break; - case MM_RF_PROTO_Q2X2: - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+10*FW, y, STR_SUBTYPE_Q2X2 , g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); - break; - case MM_RF_CUSTOM_SELECTED: - lcdDrawNumber(MODEL_SETUP_2ND_COLUMN+14*FW, y, g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false), menuHorizontalPosition==2 ? attr : 0, 2); - lcdDrawNumber(MODEL_SETUP_2ND_COLUMN+16*FW, y, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==3 ? attr : 0, 2); - break; + const mm_protocol_definition *pdef = getMultiProtocolDefinition(multi_rfProto); + if (pdef->subTypeString != nullptr) + lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+11*FW, y, pdef->subTypeString, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); } } #endif @@ -802,33 +763,9 @@ void menuModelSetup(event_t event) g_model.moduleData[EXTERNAL_MODULE].setMultiProtocol(checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false), 0, 63, EE_MODEL)); break; } else { - switch (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true)) { - case MM_RF_PROTO_HISKY: - case MM_RF_PROTO_SYMAX: - case MM_RF_PROTO_KN: - case MM_RF_PROTO_SLT: - case MM_RF_PROTO_Q2X2: - CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, 1); - break; - case MM_RF_PROTO_CG023: - CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, 2); - break; - case MM_RF_PROTO_MT99XX: - case MM_RF_PROTO_FRSKY: - case MM_RF_PROTO_DSM2: - case MM_RF_PROTO_FS_AFHDS2A: - CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, 3); - break; - case MM_RF_PROTO_FLYSKY: - case MM_RF_PROTO_MJXQ: - case MM_RF_PROTO_YD717: - CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, 4); - break; - case MM_RF_PROTO_CX10: - case MM_RF_PROTO_HONTAI: - CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, 7); - break; - } + const mm_protocol_definition* pdef = getMultiProtocolDefinition(g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false)); + if (pdef->maxSubtype > 0) + CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, pdef->maxSubtype); } break; case 3: @@ -942,8 +879,8 @@ void menuModelSetup(event_t event) lcdDrawText(MODEL_SETUP_2ND_COLUMN+MODEL_SETUP_RANGE_OFS+xOffsetBind, y, STR_MODULE_RANGE, l_posHorz==2 ? attr : 0); uint8_t newFlag = 0; #if defined(MULTIMODULE) - if (spektrumBindFinished) { - spektrumBindFinished = false; + if (multiBindStatus == MULTI_BIND_FINISHED) { + multiBindStatus = MULTI_NORMAL_OPERATION; s_editMode=0; } #endif @@ -955,7 +892,10 @@ void menuModelSetup(event_t event) } } moduleFlag[moduleIdx] = newFlag; - +#if defined(MULTIMODULE) + if (newFlag == MODULE_BIND) + multiBindStatus = MULTI_BIND_INITIATED; +#endif } } break; @@ -996,31 +936,19 @@ void menuModelSetup(event_t event) else if (IS_MODULE_MULTIMODULE(moduleIdx)) { int optionValue = g_model.moduleData[moduleIdx].multi.optionValue; - switch (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true)) - { - case MM_RF_PROTO_FRSKY: - case MM_RF_PROTO_SFHSS: - lcdDrawTextAlignedLeft(y, STR_MULTI_RFTUNE); - break; - case MM_RF_PROTO_HUBSAN: - lcdDrawTextAlignedLeft(y, STR_MULTI_VIDFREQ); - break; - case MM_RF_PROTO_OLRS: - lcdDrawTextAlignedLeft(y, STR_MULTI_RFPOWER); - break; - case MM_RF_PROTO_FS_AFHDS2A: - lcdDrawTextAlignedLeft(y, TR_MULTI_SERVOFREQ); - optionValue = 50 + 5 * optionValue; - break; - default: - lcdDrawTextAlignedLeft(y, STR_MULTI_OPTION); - break; - } + const uint8_t multi_proto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false); + const mm_protocol_definition* pdef = getMultiProtocolDefinition(multi_proto); + if (pdef->optionsstr) + lcdDrawTextAlignedLeft(y, pdef->optionsstr); + + if (multi_proto == MM_RF_PROTO_FS_AFHDS2A) + optionValue = 50 + 5 * optionValue; + lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, optionValue, LEFT | attr); if (attr) { - if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) == MM_RF_PROTO_FS_AFHDS2A) { + if (multi_proto == MM_RF_PROTO_FS_AFHDS2A) { CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].multi.optionValue, 0, 70); - } else if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) == MM_RF_PROTO_OLRS) { + } else if (multi_proto == MM_RF_PROTO_OLRS) { CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].multi.optionValue, -1, 7); } else { CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].multi.optionValue, -128, 127); @@ -1040,6 +968,14 @@ void menuModelSetup(event_t event) case ITEM_MODEL_EXTERNAL_MODULE_LOWPOWER: g_model.moduleData[EXTERNAL_MODULE].multi.lowPowerMode = editCheckBox(g_model.moduleData[EXTERNAL_MODULE].multi.lowPowerMode, MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_LOWPOWER, attr, event); break; + case ITEM_MODEL_EXTERNAL_MODULE_STATUS: { + lcdDrawTextAlignedLeft(y, STR_MODULE_STATUS); + + char statusText[64]; + multiModuleStatus.getStatusString(statusText); + lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, statusText); + break; + } #endif } } diff --git a/radio/src/gui/480x272/model_setup.cpp b/radio/src/gui/480x272/model_setup.cpp index 84027aa74..19de0ca64 100644 --- a/radio/src/gui/480x272/model_setup.cpp +++ b/radio/src/gui/480x272/model_setup.cpp @@ -69,6 +69,9 @@ enum MenuModelSetupItems { ITEM_MODEL_INTERNAL_MODULE_ANTENNA, ITEM_MODEL_EXTERNAL_MODULE_LABEL, ITEM_MODEL_EXTERNAL_MODULE_MODE, +#if defined(MULTIMODULE) + ITEM_MODEL_EXTERNAL_MODULE_STATUS, +#endif ITEM_MODEL_EXTERNAL_MODULE_CHANNELS, ITEM_MODEL_EXTERNAL_MODULE_BIND, ITEM_MODEL_EXTERNAL_MODULE_FAILSAFE, @@ -229,6 +232,7 @@ bool menuModelSetup(event_t event) IF_INTERNAL_MODULE_ON(0), LABEL(ExternalModule), EXTERNAL_MODULE_MODE_ROWS, + MULTIMODULE_STATUS_ROW EXTERNAL_MODULE_CHANNELS_ROWS, (IS_MODULE_XJT(EXTERNAL_MODULE) && !HAS_RF_PROTOCOL_MODELINDEX(g_model.moduleData[EXTERNAL_MODULE].rfProtocol)) ? (uint8_t)1 : (IS_MODULE_PPM(EXTERNAL_MODULE) || IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW, FAILSAFE_ROWS(EXTERNAL_MODULE), MULTIMODULE_MODULE_ROWS @@ -629,61 +633,16 @@ bool menuModelSetup(event_t event) #if defined(MULTIMODULE) else if (IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) { int multi_rfProto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false); - if (g_model.moduleData[EXTERNAL_MODULE].multi.customProto) - lcdDrawText(MODEL_SETUP_3RD_COLUMN, y, STR_MULTI_CUSTOM, menuHorizontalPosition==1 ? attr : 0); - else - lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_MULTI_PROTOCOLS, multi_rfProto, menuHorizontalPosition==1 ? attr : 0); + if (g_model.moduleData[EXTERNAL_MODULE].multi.customProto) { + lcdDrawText(MODEL_SETUP_3RD_COLUMN, y, STR_MULTI_CUSTOM, menuHorizontalPosition == 1 ? attr : 0); + lcdDrawNumber(MODEL_SETUP_4TH_COLUMN, y, multi_rfProto, menuHorizontalPosition==2 ? attr : 0, 2); + lcdDrawNumber(MODEL_SETUP_4TH_COLUMN + MODEL_SETUP_BIND_OFS, y, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==3 ? attr : 0, 2); + } else { + const mm_protocol_definition *pdef = getMultiProtocolDefinition(multi_rfProto); - switch(g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true)) { - case MM_RF_PROTO_FLYSKY: - lcdDrawTextAtIndex(MODEL_SETUP_4TH_COLUMN, y, STR_SUBTYPE_FLYSKY, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); - break; - case MM_RF_PROTO_FRSKY: - lcdDrawTextAtIndex(MODEL_SETUP_4TH_COLUMN, y, STR_XJT_PROTOCOLS, g_model.moduleData[EXTERNAL_MODULE].subType+1, menuHorizontalPosition==2 ? attr : 0); - break; - case MM_RF_PROTO_HISKY: - lcdDrawTextAtIndex(MODEL_SETUP_4TH_COLUMN, y, STR_SUBTYPE_HISKY, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); - break; - case MM_RF_PROTO_DSM2: - lcdDrawTextAtIndex(MODEL_SETUP_4TH_COLUMN, y, STR_SUBTYPE_DSM, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); - break; - case MM_RF_PROTO_YD717: - lcdDrawTextAtIndex(MODEL_SETUP_4TH_COLUMN, y, STR_SUBTYPE_YD717, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); - break; - case MM_RF_PROTO_KN: - lcdDrawTextAtIndex(MODEL_SETUP_4TH_COLUMN, y, STR_SUBTYPE_KN, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); - break; - case MM_RF_PROTO_SYMAX: - lcdDrawTextAtIndex(MODEL_SETUP_4TH_COLUMN, y, STR_SUBTYPE_SYMAX, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); - break; - case MM_RF_PROTO_SLT: - lcdDrawTextAtIndex(MODEL_SETUP_4TH_COLUMN, y, STR_SUBTYPE_SLT, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); - break; - case MM_RF_PROTO_CX10: - lcdDrawTextAtIndex(MODEL_SETUP_4TH_COLUMN, y, STR_SUBTYPE_CX10, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); - break; - case MM_RF_PROTO_CG023: - lcdDrawTextAtIndex(MODEL_SETUP_4TH_COLUMN, y, STR_SUBTYPE_CG023, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); - break; - case MM_RF_PROTO_MT99XX: - lcdDrawTextAtIndex(MODEL_SETUP_4TH_COLUMN, y, STR_SUBTYPE_MT99, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); - break; - case MM_RF_PROTO_MJXQ: - lcdDrawTextAtIndex(MODEL_SETUP_4TH_COLUMN, y, STR_SUBTYPE_MJXQ, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); - break; - case MM_RF_PROTO_HONTAI: - lcdDrawTextAtIndex(MODEL_SETUP_4TH_COLUMN, y, STR_SUBTYPE_HONTAI, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); - break; - case MM_RF_PROTO_FS_AFHDS2A: - lcdDrawTextAtIndex(MODEL_SETUP_4TH_COLUMN, y, STR_SUBTYPE_AFHDS2A , g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); - break; - case MM_RF_PROTO_Q2X2: - lcdDrawTextAtIndex(MODEL_SETUP_4TH_COLUMN, y, STR_SUBTYPE_Q2X2, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); - break; - case MM_RF_CUSTOM_SELECTED: - lcdDrawNumber(MODEL_SETUP_4TH_COLUMN, y, g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false), menuHorizontalPosition==2 ? attr : 0, 2); - lcdDrawNumber(MODEL_SETUP_4TH_COLUMN + MODEL_SETUP_BIND_OFS, y, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==3 ? attr : 0, 2); - break; + lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_MULTI_PROTOCOLS, multi_rfProto, menuHorizontalPosition == 1 ? attr : 0); + if (pdef->subTypeString != nullptr) + lcdDrawTextAtIndex(MODEL_SETUP_4TH_COLUMN, y, pdef->subTypeString, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0); } } #endif @@ -734,32 +693,9 @@ bool menuModelSetup(event_t event) g_model.moduleData[EXTERNAL_MODULE].setMultiProtocol(checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false), 0, 63, EE_MODEL)); break; } else { - switch (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true)) { - case MM_RF_PROTO_HISKY: - case MM_RF_PROTO_SYMAX: - case MM_RF_PROTO_KN: - case MM_RF_PROTO_SLT: - CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, 1); - break; - case MM_RF_PROTO_CG023: - CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, 2); - break; - case MM_RF_PROTO_MT99XX: - case MM_RF_PROTO_FRSKY: - case MM_RF_PROTO_DSM2: - case MM_RF_PROTO_FS_AFHDS2A: - CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, 3); - break; - case MM_RF_PROTO_MJXQ: - case MM_RF_PROTO_YD717: - case MM_RF_PROTO_FLYSKY: - CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, 4); - break; - case MM_RF_PROTO_CX10: - case MM_RF_PROTO_HONTAI: - CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, 7); - break; - } + const mm_protocol_definition *pdef = getMultiProtocolDefinition(g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false)); + if (pdef->maxSubtype > 0) + CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, pdef->maxSubtype); } break; case 3: @@ -855,8 +791,8 @@ bool menuModelSetup(event_t event) drawButton(MODEL_SETUP_2ND_COLUMN+MODEL_SETUP_RANGE_OFS+xOffsetBind, y, STR_MODULE_RANGE, (moduleFlag[moduleIdx] == MODULE_RANGECHECK ? BUTTON_ON : BUTTON_OFF) | (l_posHorz==2 ? attr : 0)); uint8_t newFlag = 0; #if defined(MULTIMODULE) - if (spektrumBindFinished) { - spektrumBindFinished = false; + if (multiBindStatus == MULTI_BIND_FINISHED) { + multiBindStatus = MULTI_NORMAL_OPERATION; s_editMode=0; } #endif @@ -868,6 +804,10 @@ bool menuModelSetup(event_t event) } } moduleFlag[moduleIdx] = newFlag; +#if defined(MULTIMODULE) + if (newFlag == MODULE_BIND) + multiBindStatus = MULTI_BIND_INITIATED; +#endif } } break; @@ -909,26 +849,14 @@ bool menuModelSetup(event_t event) else if (IS_MODULE_MULTIMODULE(moduleIdx)) { int optionValue = g_model.moduleData[moduleIdx].multi.optionValue; - switch (g_model.moduleData[moduleIdx].getMultiProtocol(true)) - { - case MM_RF_PROTO_FRSKY: - case MM_RF_PROTO_SFHSS: - lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MULTI_RFTUNE); - break; - case MM_RF_PROTO_HUBSAN: - lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MULTI_VIDFREQ); - break; - case MM_RF_PROTO_OLRS: - lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MULTI_RFPOWER); - break; - case MM_RF_PROTO_FS_AFHDS2A: - lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MULTI_SERVOFREQ); - optionValue = 50 + 5 * optionValue; - break; - default: - lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MULTI_OPTION); - break; - } + const uint8_t multi_proto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false); + const mm_protocol_definition* pdef = getMultiProtocolDefinition(multi_proto); + if (pdef->optionsstr) + lcdDrawText(MENUS_MARGIN_LEFT, y, pdef->optionsstr); + + if (multi_proto == MM_RF_PROTO_FS_AFHDS2A) + optionValue = 50 + 5 * optionValue; + lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, optionValue, LEFT | attr); if (attr) { if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) == MM_RF_PROTO_FS_AFHDS2A) { @@ -955,6 +883,14 @@ bool menuModelSetup(event_t event) lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MULTI_LOWPOWER); g_model.moduleData[EXTERNAL_MODULE].multi.lowPowerMode = editCheckBox(g_model.moduleData[EXTERNAL_MODULE].multi.lowPowerMode, MODEL_SETUP_2ND_COLUMN, y, attr, event); break; + case ITEM_MODEL_EXTERNAL_MODULE_STATUS: { + lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MODULE_STATUS); + + char statusText[64]; + multiModuleStatus.getStatusString(statusText); + lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, statusText); + break; + } #endif } } diff --git a/radio/src/gui/gui_common.h b/radio/src/gui/gui_common.h index a673f9cdf..034e9f970 100644 --- a/radio/src/gui/gui_common.h +++ b/radio/src/gui/gui_common.h @@ -111,24 +111,33 @@ void drawFatalErrorScreen(const char * message); void runFatalErrorScreen(const char * message); #endif + // model_setup Defines that are used in all uis in the same way #define EXTERNAL_MODULE_CHANNELS_ROWS IF_EXTERNAL_MODULE_ON((IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_CROSSFIRE(EXTERNAL_MODULE) || (IS_MODULE_MULTIMODULE(EXTERNAL_MODULE) && g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) != MM_RF_PROTO_DSM2)) ? (uint8_t)0 : (uint8_t)1) #if defined(MULTIMODULE) +#define MULTIMODULE_STATUS_ROW IS_MODULE_MULTIMODULE(EXTERNAL_MODULE) ? TITLE_ROW : HIDDEN_ROW, #define MULTIMODULE_MODULE_ROWS IS_MODULE_MULTIMODULE(EXTERNAL_MODULE) ? (uint8_t) 0 : HIDDEN_ROW, IS_MODULE_MULTIMODULE(EXTERNAL_MODULE) ? (uint8_t) 0 : HIDDEN_ROW, #define MULTIMODULE_MODE_ROWS(x) (g_model.moduleData[x].multi.customProto) ? (uint8_t) 3 :MULTIMODULE_HAS_SUBTYPE(g_model.moduleData[x].getMultiProtocol(true)) ? (uint8_t)2 : (uint8_t)1 #define MULTIMODULE_RFPROTO_ROWS(x) (g_model.moduleData[x].multi.customProto) ? (uint8_t) 1 :MULTIMODULE_HAS_SUBTYPE(g_model.moduleData[x].getMultiProtocol(true)) ? (uint8_t) 0 : HIDDEN_ROW #define MULTIMODULE_SUBTYPE_ROWS(x) IS_MODULE_MULTIMODULE(x) ? MULTIMODULE_RFPROTO_ROWS(x) : HIDDEN_ROW, -#define MULTIMODULE_HAS_SUBTYPE(x) (x == MM_RF_PROTO_FLYSKY || x == MM_RF_PROTO_FRSKY || x == MM_RF_PROTO_HISKY || x == MM_RF_PROTO_DSM2 || x == MM_RF_PROTO_YD717 \ - || x == MM_RF_PROTO_KN || x == MM_RF_PROTO_SYMAX || x == MM_RF_PROTO_CX10 || x == MM_RF_PROTO_CG023 || x == MM_RF_PROTO_MT99XX \ - || x == MM_RF_PROTO_MJXQ || x == MM_RF_PROTO_HONTAI || x == MM_RF_PROTO_FS_AFHDS2A || x == MM_RF_PROTO_SLT || x == MM_RF_PROTO_Q2X2 \ - || x == MM_RF_CUSTOM_SELECTED) -#define MULTIMODULE_HASOPTIONS(x) (x == MM_RF_PROTO_HUBSAN || x == MM_RF_PROTO_FRSKY || x == MM_RF_PROTO_SFHSS || x == MM_RF_PROTO_FS_AFHDS2A \ - || x == MM_RF_PROTO_OLRS || x == MM_RF_CUSTOM_SELECTED) +#define MULTIMODULE_HAS_SUBTYPE(x) (getMultiProtocolDefinition(x)->maxSubtype > 0) +#define MULTIMODULE_HASOPTIONS(x) (getMultiProtocolDefinition(x)->optionsstr != nullptr) #define MULTIMODULE_FAILSAFEROWS(x) (IS_MODULE_MULTIMODULE(x) && (MULTIMODULE_HASOPTIONS(g_model.moduleData[x].getMultiProtocol(true)))) ? (uint8_t) 0: HIDDEN_ROW #define MULTI_MAX_RX_NUM(x) (g_model.moduleData[x].getMultiProtocol(true) == MM_RF_PROTO_OLRS ? 4 : 15) +// only packed to save flash +PACK( + struct mm_protocol_definition { + uint8_t protocol; + const pm_char *subTypeString; + uint8_t maxSubtype; + const pm_char *optionsstr; + } ); + +const mm_protocol_definition *getMultiProtocolDefinition (uint8_t protocol); #else +#define MULTIMODULE_STATUS_ROW #define MULTIMODULE_MODULE_ROWS #define MULTIMODULE_FAILSAFEROWS(x) HIDDEN_ROW #define MULTIMODULE_SUBTYPE_ROWS(x) diff --git a/radio/src/gui/gui_common_arm.cpp b/radio/src/gui/gui_common_arm.cpp index a16f11263..1e4f5654d 100644 --- a/radio/src/gui/gui_common_arm.cpp +++ b/radio/src/gui/gui_common_arm.cpp @@ -533,7 +533,7 @@ bool isTelemetryProtocolAvailable(int protocol) } #if !defined(MULTIMODULE) - if (protocol == PROTOCOL_SPEKTRUM || protocol == PROTOCOL_FLYSKY_IBUS) { + if (protocol == PROTOCOL_SPEKTRUM || protocol == PROTOCOL_FLYSKY_IBUS || protocol == PROTOCOL_MULTIMODULE) { return false; } #endif @@ -582,4 +582,46 @@ int getFirstAvailable(int min, int max, IsValueAvailable isValueAvailable) } return retval; } +#if defined(MULTIMODULE) +const mm_protocol_definition multi_protocols[] = { + { MM_RF_PROTO_FLYSKY, STR_SUBTYPE_FLYSKY, 4, nullptr }, + { MM_RF_PROTO_HUBSAN, nullptr, 0, STR_MULTI_VIDFREQ }, + { MM_RF_PROTO_FRSKY, STR_SUBTYPE_FRSKY, 3, STR_MULTI_RFTUNE }, + { MM_RF_PROTO_HISKY, STR_SUBTYPE_HISKY, 1, nullptr }, + { MM_RF_PROTO_V2X2, STR_SUBTYPE_V2X2, 1, nullptr }, + { MM_RF_PROTO_DSM2, STR_SUBTYPE_DSM, 3, nullptr }, + { MM_RF_PROTO_YD717, STR_SUBTYPE_YD717, 4, nullptr }, + { MM_RF_PROTO_KN, STR_SUBTYPE_KN, 1, nullptr }, + { MM_RF_PROTO_SYMAX, STR_SUBTYPE_SYMAX, 1, nullptr }, + { MM_RF_PROTO_SLT, STR_SUBTYPE_SLT, 1, nullptr }, + { MM_RF_PROTO_CX10, STR_SUBTYPE_CX10, 7, nullptr }, + { MM_RF_PROTO_CG023, STR_SUBTYPE_CG023, 2, nullptr }, + { MM_RF_PROTO_BAYANG, STR_SUBTYPE_BAYANG, 1, nullptr }, + { MM_RF_PROTO_MT99XX, STR_SUBTYPE_MT99, 4, nullptr }, + { MM_RF_PROTO_MJXQ, STR_SUBTYPE_MJXQ, 4, nullptr }, + { MM_RF_PROTO_FY326, STR_SUBTYPE_FY326, 1, nullptr }, + { MM_RF_PROTO_SFHSS, nullptr, 0, STR_MULTI_RFTUNE }, + { MM_RF_PROTO_HONTAI, STR_SUBTYPE_HONTAI, 3, nullptr }, + { MM_RF_PROTO_OLRS, nullptr, 0, STR_MULTI_RFPOWER }, + { MM_RF_PROTO_FS_AFHDS2A, STR_SUBTYPE_AFHDS2A, 3, STR_MULTI_SERVOFREQ }, + { MM_RF_PROTO_Q2X2, STR_SUBTYPE_Q2X2, 1, nullptr }, + { MM_RF_CUSTOM_SELECTED, nullptr, 7, STR_MULTI_OPTION }, + + //Sential and default for protocols not listed above (MM_RF_CUSTOM is 0xff() + { 0xfe, nullptr, 0, nullptr } +}; + +const mm_protocol_definition *getMultiProtocolDefinition (uint8_t protocol) +{ + const mm_protocol_definition *pdef; + for (pdef = multi_protocols; pdef->protocol != 0xfe; pdef++) { + if (pdef->protocol == protocol) + return pdef; + } + // Return the empty last protocol + return pdef; +} + +#endif + #endif diff --git a/radio/src/myeeprom.h b/radio/src/myeeprom.h index aea5c611b..59a623cc3 100644 --- a/radio/src/myeeprom.h +++ b/radio/src/myeeprom.h @@ -621,7 +621,8 @@ enum TelemetryType PROTOCOL_PULSES_CROSSFIRE, PROTOCOL_SPEKTRUM, PROTOCOL_FLYSKY_IBUS, - PROTOCOL_TELEMETRY_LAST=PROTOCOL_FLYSKY_IBUS + PROTOCOL_MULTIMODULE, + PROTOCOL_TELEMETRY_LAST=PROTOCOL_MULTIMODULE }; enum DisplayTrims diff --git a/radio/src/pulses/multi_arm.cpp b/radio/src/pulses/multi_arm.cpp index 6c936472c..0c1321249 100644 --- a/radio/src/pulses/multi_arm.cpp +++ b/radio/src/pulses/multi_arm.cpp @@ -189,24 +189,27 @@ void setupPulsesMultimodule(uint8_t port) sendByteMulti(protoByte); // byte 2, subtype, powermode, model id - sendByteMulti((g_model.header.modelId[port] & 0x0f) - | ((subtype & 0x7) << 4) - | (g_model.moduleData[port].multi.lowPowerMode << 7) + sendByteMulti((uint8_t) ((g_model.header.modelId[port] & 0x0f) + | ((subtype & 0x7) << 4) + | (g_model.moduleData[port].multi.lowPowerMode << 7)) ); // byte 3 - sendByteMulti(optionValue); + sendByteMulti((uint8_t) optionValue); uint32_t bits = 0; uint8_t bitsavailable = 0; // byte 4-25, channels 0..2047 - // ?? Range for pulses (channelsOutputs) is [-1024:+1024] + // Range for pulses (channelsOutputs) is [-1024:+1024] for [-100%;100%] + // Multi uses [204;1843] as [-100%;100%] for (int i=0; i= 8) { sendByteMulti((uint8_t) (bits & 0xff)); diff --git a/radio/src/targets/common/arm/CMakeLists.txt b/radio/src/targets/common/arm/CMakeLists.txt index a74978a01..7d2e25061 100644 --- a/radio/src/targets/common/arm/CMakeLists.txt +++ b/radio/src/targets/common/arm/CMakeLists.txt @@ -74,7 +74,7 @@ if(HAPTIC) endif() if(MULTIMODULE) add_definitions(-DMULTIMODULE) - set(SRC ${SRC} pulses/multi_arm.cpp telemetry/spektrum.cpp telemetry/flysky_ibus.cpp) + set(SRC ${SRC} pulses/multi_arm.cpp telemetry/spektrum.cpp telemetry/flysky_ibus.cpp telemetry/multi.cpp) endif() add_definitions(-DCPUARM -DVIRTUAL_INPUTS) add_definitions(-DTELEMETRY_FRSKY -DTELEMETRY_FRSKY_SPORT -DFRSKY_HUB -DGPS -DPXX -DDSM2) diff --git a/radio/src/telemetry/flysky_ibus.cpp b/radio/src/telemetry/flysky_ibus.cpp index ac479a186..d690458ea 100644 --- a/radio/src/telemetry/flysky_ibus.cpp +++ b/radio/src/telemetry/flysky_ibus.cpp @@ -110,13 +110,13 @@ static void processFlySkySensor(const uint8_t *packet) setTelemetryValue(TELEM_PROTO_FLYSKY_IBUS, id, 0, instance, value, UNIT_RAW, 0); } -static void processFlySkyPacket(const uint8_t *packet) +void processFlySkyPacket(const uint8_t *packet) { // Set TX RSSI Value, reverse MULTIs scaling - setTelemetryValue(TELEM_PROTO_FLYSKY_IBUS, TX_RSSI_ID, 0, 0, packet[1], UNIT_RAW, 0); + setTelemetryValue(TELEM_PROTO_FLYSKY_IBUS, TX_RSSI_ID, 0, 0, packet[0], UNIT_RAW, 0); for (int sensor = 0; sensor < 7; sensor++) { - int index = 2 + (4 * sensor); + int index = 1 + (4 * sensor); processFlySkySensor(packet+index); } telemetryStreaming = TELEMETRY_TIMEOUT10ms; @@ -149,7 +149,7 @@ void processFlySkyTelemetryData(uint8_t data) } debugPrintf("\r\n"); #endif - processFlySkyPacket(telemetryRxBuffer); + processFlySkyPacket(telemetryRxBuffer+1); telemetryRxBufferCount = 0; } } diff --git a/radio/src/telemetry/flysky_ibus.h b/radio/src/telemetry/flysky_ibus.h index 15eb59fc2..71726d64c 100644 --- a/radio/src/telemetry/flysky_ibus.h +++ b/radio/src/telemetry/flysky_ibus.h @@ -24,4 +24,8 @@ void processFlySkyTelemetryData(uint8_t data); void flySkySetDefault(int index, uint16_t id, uint8_t subId, uint8_t instance); +// Used by multi protocol +void processFlySkyPacket(const uint8_t *packet); + + #endif diff --git a/radio/src/telemetry/frsky.h b/radio/src/telemetry/frsky.h index cbb0b11c6..86b957157 100644 --- a/radio/src/telemetry/frsky.h +++ b/radio/src/telemetry/frsky.h @@ -409,10 +409,10 @@ typedef enum { // FrSky D Telemetry Protocol void processHubPacket(uint8_t id, int16_t value); void frskyDSendNextAlarm(); -void frskyDProcessPacket(uint8_t *packet); +void frskyDProcessPacket(const uint8_t *packet); // FrSky S.PORT Telemetry Protocol -void sportProcessTelemetryPacket(uint8_t * packet); +void sportProcessTelemetryPacket(const uint8_t * packet); void telemetryWakeup(); void telemetryReset(); diff --git a/radio/src/telemetry/frsky_d.cpp b/radio/src/telemetry/frsky_d.cpp index f9b68f60a..80a32fe69 100644 --- a/radio/src/telemetry/frsky_d.cpp +++ b/radio/src/telemetry/frsky_d.cpp @@ -229,7 +229,7 @@ void parseTelemWSHowHighByte(uint8_t byte) } #endif -void frskyDProcessPacket(uint8_t *packet) +void frskyDProcessPacket(const uint8_t *packet) { // What type of packet? switch (packet[0]) diff --git a/radio/src/telemetry/frsky_d_arm.cpp b/radio/src/telemetry/frsky_d_arm.cpp index 6399c81fd..f6e4454cf 100644 --- a/radio/src/telemetry/frsky_d_arm.cpp +++ b/radio/src/telemetry/frsky_d_arm.cpp @@ -63,7 +63,7 @@ void parseTelemHubByte(uint8_t byte) } #endif // #if defined(FRSKY_HUB) -void frskyDProcessPacket(uint8_t *packet) +void frskyDProcessPacket(const uint8_t *packet) { // What type of packet? switch (packet[0]) diff --git a/radio/src/telemetry/frsky_sport.cpp b/radio/src/telemetry/frsky_sport.cpp index d2de4205a..152705274 100644 --- a/radio/src/telemetry/frsky_sport.cpp +++ b/radio/src/telemetry/frsky_sport.cpp @@ -78,7 +78,7 @@ const FrSkySportSensor * getFrSkySportSensor(uint16_t id, uint8_t subId=0) return result; } -bool checkSportPacket(uint8_t *packet) +bool checkSportPacket(const uint8_t *packet) { short crc = 0; for (int i=1; i= 5) + processMultiStatusPacket(data); + break; + case DSMBindPacket: + if (len >= 10) + processDSMBindPacket(data); + break; + case SpektrumTelemetry: + // processSpektrumPacket expects data[0] to be the telemetry indicator 0xAA but does not check it, + // just send one byte of our header instead + if (len >= 17) + processSpektrumPacket(data - 1); + else + TRACE("[MP] Received spektrum telemetry len %d < 17", len); + break; + case FlyskyIBusTelemetry: + if (len >= 28) + processFlySkyPacket(data); + else + TRACE("[MP] Received IBUS telemetry len %d < 28", len); + break; + case FrSkyHubTelemetry: + if (len >= 4) + frskyDProcessPacket(data); + else + TRACE("[MP] Received Frsky HUB telemetry len %d < 4", len); + break; + case FrSkySportTelemtry: + if (len >= 4) + sportProcessTelemetryPacket(data); + else + TRACE("[MP] Received sm telemetry len %d < 4", len); + break; + default: + TRACE("[MP] Unkown multi packet type 0x%02X, len %d", type, len); + break; + } +} + +// sprintf does not work AVR ARM +// use a small helper function +static void appendInt(char* buf, uint32_t val) +{ + while(*buf) + buf++; + + int len=1; + int32_t tmp = val / 10; + while (tmp) { + len++; + tmp /= 10; + } + + buf[len]='\0'; + for (uint8_t i=1;i<=len; i++) { + div_t qr = div(val, 10); + char c = qr.rem + '0'; + buf[len - i] = c; + val = qr.quot; + } +} + + +void MultiModuleStatus::getStatusString(char *statusText) +{ + if (get_tmr10ms() - lastUpdate > 200) { +#if defined(PCBTARANIS) || defined(PCBHORUS) + if (g_model.moduleData[INTERNAL_MODULE].rfProtocol != RF_PROTO_OFF) + strcpy(statusText, STR_DISABLE_INTERNAL); + else +#endif + strcpy(statusText, STR_MODULE_NO_TELEMETRY); + return; + } + if (!protocolValid()) { + strcpy(statusText, STR_PROTOCOL_INVALID); + return; + } else if (!serialMode()) { + strcpy(statusText, STR_MODULE_NO_SERIAL_MODE); + return; + } else if (!inputDetected()) { + strcpy(statusText, STR_MODULE_NO_INPUT); + return; + } + + strcpy(statusText, "V"); + appendInt(statusText, major); + strcat(statusText, "."); + appendInt(statusText, minor); + strcat(statusText, "."); + appendInt(statusText, revision); + strcat(statusText, "."); + appendInt(statusText, patch); + strcat(statusText, " "); + + if (isBinding()) + strcat(statusText, STR_MODULE_BINDING); +} + + +static MultiBufferState multiTelemetryBufferState; + +static void processMultiTelemetryByte(const uint8_t data) +{ + if (telemetryRxBufferCount < TELEMETRY_RX_PACKET_SIZE) { + telemetryRxBuffer[telemetryRxBufferCount++] = data; + } else { + TRACE("[MP] array size %d error", telemetryRxBufferCount); + multiTelemetryBufferState = NoProtocolDetected; + } + + // Length field does not count the header + if (telemetryRxBufferCount >= 2 && telemetryRxBuffer[1] == telemetryRxBufferCount - 2) { + // debug print the content of the packet +#if 0 + debugPrintf("[MP] Packet type %02X len 0x%02X: ", + telemetryRxBuffer[0], telemetryRxBuffer[1]); + for (int i=0; i<(telemetryRxBufferCount+3)/4; i++) { + debugPrintf("[%02X%02X %02X%02X] ", telemetryRxBuffer[i*4+2], telemetryRxBuffer[i*4 + 3], + telemetryRxBuffer[i*4 + 4], telemetryRxBuffer[i*4 + 5]); + } + debugPrintf("\r\n"); +#endif + // Packet is complete, process it + processMultiTelemetryPaket(telemetryRxBuffer); + multiTelemetryBufferState = NoProtocolDetected; + } +} + +void processMultiTelemetryData(const uint8_t data) +{ + switch (multiTelemetryBufferState) { + case NoProtocolDetected: + if (data == 'M') { + multiTelemetryBufferState = MultiFirstByteReceived; + } else if (data == 0x55 || data == 0x7e) { + multiTelemetryBufferState = guessProtocol(); + if (multiTelemetryBufferState == FrskyTelemetryFallbackFirstByte) + processFrskyTelemetryData(data); + } else { + TRACE("[MP] invalid start byte 0x%02X", data); + } + break; + + case FrskyTelemetryFallbackFirstByte: + multiTelemetryBufferState = FrskyTelemetryFallbackNextBytes; + + case FrskyTelemetryFallbackNextBytes: + processFrskyTelemetryData(data); + if (data == 0x7e) + // might start a new packet + multiTelemetryBufferState = FrskyTelemetryFallbackFirstByte; + else if (telemetryRxBufferCount == 0 && data != 0x7d) + // Should be in a frame (no bytestuff), but the Frsky parser has discarded the byte + multiTelemetryBufferState = NoProtocolDetected; + break; + + case FlyskyTelemetryFallback: + processFlySkyTelemetryData(data); + if (telemetryRxBufferCount == 0) + multiTelemetryBufferState = NoProtocolDetected; + break; + + case SpektrumTelemetryFallback: + processSpektrumTelemetryData(data); + if (telemetryRxBufferCount == 0) + multiTelemetryBufferState = NoProtocolDetected; + break; + + case MultiFirstByteReceived: + if (data == 'P') { + telemetryRxBufferCount = 0; + multiTelemetryBufferState = ReceivingMultiProtocol; + } else { + TRACE("[MP] invalid second byte 0x%02X", data); + multiTelemetryBufferState = NoProtocolDetected; + } + break; + + case ReceivingMultiProtocol: + processMultiTelemetryByte(data); + break; + } + +} diff --git a/radio/src/telemetry/multi.h b/radio/src/telemetry/multi.h new file mode 100644 index 000000000..5a07de852 --- /dev/null +++ b/radio/src/telemetry/multi.h @@ -0,0 +1,118 @@ +/* + * 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 OPENTX_MULTI_H +#define OPENTX_MULTI_H + +/* + Multiprotocol telemetry definition + + Serial: 100000 Baud 8e2 (same as input) + + TLV Protocol (type, length, value), allows a TX to ignore unknown messages + + Format: header (4 byte) + data (variable) + + [0] = 'M' (0x4d) + [1] = 'P' (0x50) + + + The first byte is deliberatly chosen to be different from other telemetry protocols + (e.g. 0xAA for DSM/Multi, 0xAA for FlySky and 0x7e for Frsky) to allow a TX to detect + the telemetry format of older versions + + [2] Type (see below) + [3] Length (excluding the 4 header bytes) + + [4-xx] data + + +Type = 0x01 Multimodule Status: + [4] Flags + 0x01 = Input signal detected + 0x02 = Serial mode enabled + 0x04 = protocol is valid + 0x08 = module is in binding mode + [5] major + [6] minor + [7] revision + [8] patchlevel, + version of multi code, should be displayed as major.minor.revision.patchlevel + + more information can be added by specifying a longer length of the type, the TX will just ignore these bytes + + +Type 0x02 Frksy S.port telemetry +Type 0x03 Frsky Hub telemetry + + *No* usual frsky byte stuffing and without start/stop byte (0x7e) + + +Type 0x04 Spektrum telemetry data + data[0] RSSI + data[1-15] telemetry data + +Type 0x05 DSM bind data + data[0-16] DSM bind data + + technically DSM bind data is only 10 bytes but multi send 16 + like with telemtry, check length field) + +Type 0x06 Flysky AFHDS2 telemetry data + length: 29 + data[0] = RSSI value + data[1-28] telemetry data + +*/ + + + +void processMultiTelemetryData(uint8_t data); + +#define MULTISTATUS_FLAG + +struct MultiModuleStatus { + + uint8_t major; + uint8_t minor; + uint8_t revision; + uint8_t patch; + + uint8_t flags; + tmr10ms_t lastUpdate; + + void getStatusString(char* statusText); + + inline bool isBinding() { return flags & 0x08; } + inline bool protocolValid() { return flags & 0x04; } + inline bool serialMode() { return flags & 0x02; } + inline bool inputDetected() { return flags & 0x01; } +}; + +extern MultiModuleStatus multiModuleStatus; +enum MultiBindStatus : uint8_t { + MULTI_NORMAL_OPERATION, + MULTI_BIND_INITIATED, + MULTI_BIND_FINISHED, +}; + +extern uint8_t multiBindStatus; + +#endif //OPENTX_MULTI_H \ No newline at end of file diff --git a/radio/src/telemetry/spektrum.cpp b/radio/src/telemetry/spektrum.cpp index 568564759..a336c300a 100644 --- a/radio/src/telemetry/spektrum.cpp +++ b/radio/src/telemetry/spektrum.cpp @@ -269,7 +269,6 @@ bool isSpektrumValidValue(int32_t value, const SpektrumDataType type) } } -bool spektrumBindFinished = 0; void processSpektrumPacket(const uint8_t *packet) { setTelemetryValue(TELEM_PROTO_SPEKTRUM, (I2C_PSEUDO_TX << 8) + 0, 0, 0, packet[1], UNIT_RAW, 0); @@ -350,23 +349,21 @@ void processSpektrumPacket(const uint8_t *packet) } } -// Parse the DSM2 bind reponse, Fields are as per http://www.rcgroups.com/forums/showpost.php?p=35692146&postcount=5191 +// Parse the DSM2 bind response, Fields are as per http://www.rcgroups.com/forums/showpost.php?p=35692146&postcount=5191 // "I" here means the multi module /* -0 0xAA -> telemetry start -1 0x80 -> bind packet -2-5 4 bytes -> Cyrf ID of the TX xor 0xFF but you don't care as I've checked it already... -6 1 byte -> RX version but you don't care... -7 1 byte -> number of channels, example 0x06=6 channels -8 1 byte -> max DSM type allowed: +0-3 4 bytes -> Cyrf ID of the TX xor 0xFF but you don't care as I've checked it already... +4 1 byte -> RX version but you don't care... +5 1 byte -> number of channels, example 0x06=6 channels +6 1 byte -> max DSM type allowed: 0x01 => 22ms 1024 DSM2 1 packet => number of channels is <8 and no telemetry 0x02 => 22ms 1024 DSM2 2 packets => either a number of channel >7 or telemetry enable RX 0x12 => 11ms 2048 DSM2 2 packets => can be any number of channels with/without telemetry -> this mode might be supported following Mike's trials, note the channels should be duplicated between the packets which is not the case today 0xa2 => 22ms 2048 DSMX 1 packet => number of channels is <8 and no telemetry 0xb2 => 11ms 2048 DSMX => can be any number of channels with/without telemetry -> this mode is only half supported since the channels should be duplicated between the packets which is not the case but might be supported following Mike's trials -9 0x00: not sure of the use of this byte since I've always seen it at 0... -10 2 bytes CRC but you don't care as I've checked it already... +7 0x00: not sure of the use of this byte since I've always seen it at 0... +8-9 2 bytes CRC but you don't care as I've checked it already... Examples: DSM #Chan RXver Inductrix 0xa2 07 1 @@ -379,16 +376,16 @@ void processDSMBindPacket(const uint8_t *packet) if (g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_MULTIMODULE && g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) == MM_RF_PROTO_DSM2 && g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode) { - int channels = packet[7]; + int channels = packet[5]; // Only sets channel etc when in DSM multi mode g_model.moduleData[EXTERNAL_MODULE].channelsCount = channels - 8; // bool use11ms = (packet[8] & 0x10) ; - if (packet[8] >= 0xb2) + if (packet[6] >= 0xb2) g_model.moduleData[EXTERNAL_MODULE].subType = MM_RF_DSM2_SUBTYPE_DSMX_11; - else if (packet[8] >= 0xa2) + else if (packet[6] >= 0xa2) g_model.moduleData[EXTERNAL_MODULE].subType = MM_RF_DSM2_SUBTYPE_DSMX_22; - else if (packet[8] >= 0x12) + else if (packet[6] >= 0x12) g_model.moduleData[EXTERNAL_MODULE].subType = MM_RF_DSM2_SUBTYPE_DSM2_11; else g_model.moduleData[EXTERNAL_MODULE].subType = MM_RF_DSM2_SUBTYPE_DSM2_22; @@ -397,7 +394,7 @@ void processDSMBindPacket(const uint8_t *packet) } - debugval = packet[9] << 24 | packet[8] << 16 | packet[7] << 8 | packet[6]; + debugval = packet[7] << 24 | packet[6] << 16 | packet[5] << 8 | packet[4]; /* log the bind packet as telemetry for quick debugging */ setTelemetryValue(TELEM_PROTO_SPEKTRUM, (I2C_PSEUDO_TX << 8) + 4, 0, 0, debugval, UNIT_RAW, 0); @@ -405,7 +402,7 @@ void processDSMBindPacket(const uint8_t *packet) /* Finally stop binding as the rx just told us that it is bound */ if (g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_MULTIMODULE && g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) == MM_RF_PROTO_DSM2 && moduleFlag[EXTERNAL_MODULE] == MODULE_BIND) { - spektrumBindFinished=true; + multiBindStatus=MULTI_BIND_FINISHED; } } @@ -425,13 +422,11 @@ void processSpektrumTelemetryData(uint8_t data) } if (telemetryRxBuffer[1] == 0x80 && telemetryRxBufferCount >= DSM_BIND_PACKET_LENGTH) { - processDSMBindPacket(telemetryRxBuffer); + processDSMBindPacket(telemetryRxBuffer+2); telemetryRxBufferCount = 0; return; } - - if (telemetryRxBufferCount >= SPEKTRUM_TELEMETRY_LENGTH) { // Debug print content of Telemetry to console #if 0 diff --git a/radio/src/telemetry/spektrum.h b/radio/src/telemetry/spektrum.h index 5585cf277..d9b6d5b7b 100644 --- a/radio/src/telemetry/spektrum.h +++ b/radio/src/telemetry/spektrum.h @@ -24,5 +24,7 @@ void processSpektrumTelemetryData(uint8_t data); void spektrumSetDefault(int index, uint16_t id, uint8_t subId, uint8_t instance); -extern bool spektrumBindFinished; +// Used directly by multi telemetry protocol +void processSpektrumPacket(const uint8_t *packet); +void processDSMBindPacket(const uint8_t *packet); #endif diff --git a/radio/src/telemetry/telemetry.cpp b/radio/src/telemetry/telemetry.cpp index 05eb464e3..cd11dacbe 100644 --- a/radio/src/telemetry/telemetry.cpp +++ b/radio/src/telemetry/telemetry.cpp @@ -74,10 +74,12 @@ void processTelemetryData(uint8_t data) if (telemetryProtocol == PROTOCOL_SPEKTRUM) { processSpektrumTelemetryData(data); return; - } - else if (telemetryProtocol == PROTOCOL_FLYSKY_IBUS) { + } else if (telemetryProtocol == PROTOCOL_FLYSKY_IBUS) { processFlySkyTelemetryData(data); return; + } else if (telemetryProtocol == PROTOCOL_MULTIMODULE) { + processMultiTelemetryData(data); + return; } #endif processFrskyTelemetryData(data); @@ -411,10 +413,13 @@ void telemetryReset() // we don't reset the telemetry here as we would also reset the consumption after model load void telemetryInit(uint8_t protocol) { #if defined(MULTIMODULE) - // TODO: Is there a better way to communicate this to this function? - if (!IS_TELEMETRY_INTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_MULTIMODULE) { + if (protocol == PROTOCOL_MULTIMODULE || protocol == PROTOCOL_FLYSKY_IBUS) { // The DIY Multi module always speaks 100000 baud regardless of the telemetry protocol in use telemetryPortInit(MULTIMODULE_BAUDRATE, TELEMETRY_SERIAL_8E2); + } else if (protocol == PROTOCOL_SPEKTRUM) + { + // Spektrum's own small race RX (SPM4648) uses 125000 8N1, use the same since there is no real standard + telemetryPortInit(125000, TELEMETRY_SERIAL_8N1); } else #endif if (protocol == PROTOCOL_FRSKY_D) { diff --git a/radio/src/telemetry/telemetry.h b/radio/src/telemetry/telemetry.h index 9a409eebb..595b02af8 100644 --- a/radio/src/telemetry/telemetry.h +++ b/radio/src/telemetry/telemetry.h @@ -44,6 +44,7 @@ #if defined(MULTIMODULE) #include "spektrum.h" #include "flysky_ibus.h" + #include "multi.h" #endif extern uint8_t telemetryStreaming; // >0 (true) == data is streaming in. 0 = no data detected for some time @@ -127,7 +128,12 @@ void frskyDSetDefault(int index, uint16_t id); #if defined(CPUARM) extern uint8_t telemetryProtocol; #define IS_FRSKY_D_PROTOCOL() (telemetryProtocol == PROTOCOL_FRSKY_D) +#if defined (MULTIMODULE) +#define IS_D16_MULTI() ((g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false) == MM_RF_PROTO_FRSKY) && (g_model.moduleData[EXTERNAL_MODULE].subType == MM_RF_FRSKY_SUBTYPE_D16 || g_model.moduleData[EXTERNAL_MODULE].subType == MM_RF_FRSKY_SUBTYPE_D16_8CH)) +#define IS_FRSKY_SPORT_PROTOCOL() (telemetryProtocol == PROTOCOL_FRSKY_SPORT || (telemetryProtocol == PROTOCOL_MULTIMODULE && IS_D16_MULTI())) +#else #define IS_FRSKY_SPORT_PROTOCOL() (telemetryProtocol == PROTOCOL_FRSKY_SPORT) +#endif #define IS_SPEKTRUM_PROTOCOL() (telemetryProtocol == PROTOCOL_SPEKTRUM) #else #define IS_FRSKY_D_PROTOCOL() (true) @@ -149,15 +155,7 @@ inline uint8_t modelTelemetryProtocol() #if defined(MULTIMODULE) if (g_model.moduleData[INTERNAL_MODULE].rfProtocol == RF_PROTO_OFF && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_MULTIMODULE) { - if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false) == MM_RF_PROTO_DSM2) - return PROTOCOL_SPEKTRUM; - else if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false) == MM_RF_PROTO_FS_AFHDS2A) - return PROTOCOL_FLYSKY_IBUS; - else if ((g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false) == MM_RF_PROTO_FRSKY) && - (g_model.moduleData[EXTERNAL_MODULE].subType == MM_RF_FRSKY_SUBTYPE_D16 || g_model.moduleData[EXTERNAL_MODULE].subType == MM_RF_FRSKY_SUBTYPE_D16_8CH)) - return PROTOCOL_FRSKY_SPORT; - else - return PROTOCOL_FRSKY_D; + return PROTOCOL_MULTIMODULE; } #endif diff --git a/radio/src/tests/frsky.cpp b/radio/src/tests/frsky.cpp index 38111434e..f9d828fd3 100644 --- a/radio/src/tests/frsky.cpp +++ b/radio/src/tests/frsky.cpp @@ -20,12 +20,12 @@ #include "gtests.h" -void frskyDProcessPacket(uint8_t *packet); +void frskyDProcessPacket(const uint8_t *packet); #if defined(TELEMETRY_FRSKY_SPORT) -bool checkSportPacket(uint8_t *packet); -void sportProcessTelemetryPacket(uint8_t * packet); -bool checkSportPacket(uint8_t *packet); +bool checkSportPacket(const uint8_t *packet); +void sportProcessTelemetryPacket(const uint8_t * packet); +bool checkSportPacket(const uint8_t *packet); void frskyCalculateCellStats(void); void displayVoltagesScreen(); #endif diff --git a/radio/src/translations.cpp b/radio/src/translations.cpp index 1da67c9ea..de8409a29 100644 --- a/radio/src/translations.cpp +++ b/radio/src/translations.cpp @@ -127,6 +127,9 @@ const pm_char STR_OPEN9X[] PROGMEM = ISTR(SUBTYPE_HONTAI) ISTR(SUBTYPE_AFHDS2A) ISTR(SUBTYPE_Q2X2) + ISTR(SUBTYPE_V2X2) + ISTR(SUBTYPE_BAYANG) + ISTR(SUBTYPE_FY326) #endif ISTR(VOLTSRC) ISTR(CURVE_TYPES) @@ -475,6 +478,13 @@ const pm_char STR_MULTI_OPTION[] PROGMEM = TR_MULTI_OPTION; const pm_char STR_MULTI_AUTOBIND[] PROGMEM = TR_MULTI_AUTOBIND; const pm_char STR_MULTI_DSM_AUTODTECT[] PROGMEM = TR_MULTI_DSM_AUTODTECT; const pm_char STR_MULTI_LOWPOWER[] PROGMEM = TR_MULTI_LOWPOWER; +const pm_char STR_DISABLE_INTERNAL[] PROGMEM = TR_DISABLE_INTERNAL; +const pm_char STR_MODULE_NO_SERIAL_MODE[] PROGMEM = TR_MODULE_NO_SERIAL_MODE; +const pm_char STR_MODULE_NO_INPUT[] PROGMEM = TR_MODULE_NO_INPUT; +const pm_char STR_MODULE_NO_TELEMETRY[] PROGMEM = TR_MODULE_NO_TELEMETRY; +const pm_char STR_MODULE_BINDING[] PROGMEM = TR_MODULE_BINDING; +const pm_char STR_PROTOCOL_INVALID[] PROGMEM = TR_PROTOCOL_INVALID; +const pm_char STR_MODULE_STATUS[] PROGMEM = TR_MODULE_STATUS; const pm_char STR_MULTI_SERVOFREQ[] PROGMEM = TR_MULTI_SERVOFREQ; #if LCD_W < 212 const pm_char STR_SUBTYPE[] PROGMEM = TR_SUBTYPE; diff --git a/radio/src/translations.h b/radio/src/translations.h index 112825ad7..c35cef357 100644 --- a/radio/src/translations.h +++ b/radio/src/translations.h @@ -219,16 +219,19 @@ extern const pm_char STR_OPEN9X[]; #define OFS_SUBTYPE_DSM (OFS_SUBTYPE_HISKY + sizeof(TR_SUBTYPE_HISKY)) #define OFS_SUBTYPE_YD717 (OFS_SUBTYPE_DSM + sizeof(TR_SUBTYPE_DSM)) #define OFS_SUBTYPE_SYMAX (OFS_SUBTYPE_YD717 + sizeof(TR_SUBTYPE_YD717)) - #define OFS_SUBTYPE_SLT (OFS_SUBTYPE_SYMAX + sizeof(TR_SUBTYPE_SYMAX)) - #define OFS_SUBTYPE_CX10 (OFS_SUBTYPE_SLT + sizeof(TR_SUBTYPE_SLT)) + #define OFS_SUBTYPE_SLT (OFS_SUBTYPE_SYMAX + sizeof(TR_SUBTYPE_SYMAX)) + #define OFS_SUBTYPE_CX10 (OFS_SUBTYPE_SLT + sizeof(TR_SUBTYPE_SLT)) #define OFS_SUBTYPE_CG023 (OFS_SUBTYPE_CX10 + sizeof(TR_SUBTYPE_CX10)) #define OFS_SUBTYPE_KN (OFS_SUBTYPE_CG023 + sizeof(TR_SUBTYPE_CG023)) #define OFS_SUBTYPE_MT99 (OFS_SUBTYPE_KN + sizeof(TR_SUBTYPE_KN)) #define OFS_SUBTYPE_MJXQ (OFS_SUBTYPE_MT99 + sizeof(TR_SUBTYPE_MT99)) #define OFS_SUBTYPE_HONTAI (OFS_SUBTYPE_MJXQ + sizeof(TR_SUBTYPE_MJXQ)) #define OFS_SUBTYPE_AFHDS2A (OFS_SUBTYPE_HONTAI + sizeof(TR_SUBTYPE_HONTAI)) - #define OFS_SUBTYPE_Q2X2 (OFS_SUBTYPE_AFHDS2A + sizeof(TR_SUBTYPE_AFHDS2A)) - #define OFS_VOLTSRC (OFS_SUBTYPE_Q2X2 + sizeof(TR_SUBTYPE_Q2X2)) + #define OFS_SUBTYPE_Q2X2 (OFS_SUBTYPE_AFHDS2A + sizeof(TR_SUBTYPE_AFHDS2A)) + #define OFS_SUBTYPE_V2X2 (OFS_SUBTYPE_Q2X2 + sizeof(TR_SUBTYPE_Q2X2)) + #define OFS_SUBTYPE_BAYANG (OFS_SUBTYPE_V2X2 + sizeof(TR_SUBTYPE_V2X2)) + #define OFS_SUBTYPE_FY326 (OFS_SUBTYPE_BAYANG + sizeof(TR_SUBTYPE_BAYANG)) + #define OFS_VOLTSRC (OFS_SUBTYPE_FY326 + sizeof(TR_SUBTYPE_FY326)) #else #define OFS_VOLTSRC (OFS_DSM_PROTOCOLS + sizeof(TR_DSM_PROTOCOLS)) #endif @@ -356,7 +359,7 @@ extern const pm_char STR_OPEN9X[]; #define STR_SUBTYPE_DSM (STR_OPEN9X + OFS_SUBTYPE_DSM) #define STR_SUBTYPE_YD717 (STR_OPEN9X + OFS_SUBTYPE_YD717) #define STR_SUBTYPE_SYMAX (STR_OPEN9X + OFS_SUBTYPE_SYMAX) - #define STR_SUBTYPE_SLT (STR_OPEN9X + OFS_SUBTYPE_SLT) + #define STR_SUBTYPE_SLT (STR_OPEN9X + OFS_SUBTYPE_SLT) #define STR_SUBTYPE_CX10 (STR_OPEN9X + OFS_SUBTYPE_CX10) #define STR_SUBTYPE_CG023 (STR_OPEN9X + OFS_SUBTYPE_CG023) #define STR_SUBTYPE_KN (STR_OPEN9X + OFS_SUBTYPE_KN) @@ -364,7 +367,10 @@ extern const pm_char STR_OPEN9X[]; #define STR_SUBTYPE_MJXQ (STR_OPEN9X + OFS_SUBTYPE_MJXQ) #define STR_SUBTYPE_HONTAI (STR_OPEN9X + OFS_SUBTYPE_HONTAI) #define STR_SUBTYPE_AFHDS2A (STR_OPEN9X + OFS_SUBTYPE_AFHDS2A) - #define STR_SUBTYPE_Q2X2 (STR_OPEN9X + OFS_SUBTYPE_Q2X2) + #define STR_SUBTYPE_Q2X2 (STR_OPEN9X + OFS_SUBTYPE_Q2X2) + #define STR_SUBTYPE_V2X2 (STR_OPEN9X + OFS_SUBTYPE_V2X2) + #define STR_SUBTYPE_BAYANG (STR_OPEN9X + OFS_SUBTYPE_BAYANG) + #define STR_SUBTYPE_FY326 (STR_OPEN9X + OFS_SUBTYPE_FY326) #endif #define STR_CURVE_TYPES (STR_OPEN9X + OFS_CURVE_TYPES) #define STR_VSENSORTYPES (STR_OPEN9X + OFS_VSENSORTYPES) @@ -604,11 +610,18 @@ extern const pm_char STR_FAS_OFFSET[]; extern const pm_char STR_MULTI_CUSTOM[]; extern const pm_char STR_MULTI_OPTION[]; extern const pm_char STR_MULTI_VIDFREQ[]; -extern const pm_char STR_MULTI_RFPOWER[]; +extern const pm_char STR_MULTI_RFPOWER[]; extern const pm_char STR_MULTI_RFTUNE[]; extern const pm_char STR_MULTI_AUTOBIND[]; extern const pm_char STR_MULTI_DSM_AUTODTECT[]; extern const pm_char STR_MULTI_LOWPOWER[]; +extern const pm_char STR_DISABLE_INTERNAL[]; +extern const pm_char STR_MODULE_NO_SERIAL_MODE[]; +extern const pm_char STR_MODULE_NO_INPUT[]; +extern const pm_char STR_MODULE_NO_TELEMETRY[]; +extern const pm_char STR_MODULE_BINDING[]; +extern const pm_char STR_PROTOCOL_INVALID[]; +extern const pm_char STR_MODULE_STATUS[]; extern const pm_char STR_MULTI_SERVOFREQ[]; #if LCD_W < 212 extern const pm_char STR_SUBTYPE[]; @@ -712,7 +725,7 @@ extern const pm_char STR_RESET_BTN[]; extern const pm_char STR_DELETE_ERROR[]; extern const pm_char STR_NO_SDCARD[]; extern const pm_char STR_SDCARD_FULL[]; -extern const pm_char STR_SDCARD_NOWIZ[]; +extern const pm_char STR_SDCARD_NOWIZ[]; extern const pm_char STR_INCOMPATIBLE[]; extern const pm_char STR_LOGS_PATH[]; extern const pm_char STR_LOGS_EXT[]; @@ -796,7 +809,7 @@ extern const pm_char STR_VIEW_TEXT[]; extern const pm_char STR_FLASH_BOOTLOADER[]; extern const pm_char STR_FLASH_EXTERNAL_DEVICE[]; extern const pm_char STR_FLASH_INTERNAL_MODULE[]; -extern const pm_char STR_FIRMWARE_UPDATE_ERROR[]; +extern const pm_char STR_FIRMWARE_UPDATE_ERROR[]; extern const pm_char STR_WRITING[]; extern const pm_char STR_CONFIRM_FORMAT[]; extern const pm_char STR_EEBACKUP[]; diff --git a/radio/src/translations/cz.h.txt b/radio/src/translations/cz.h.txt index 2cae73df1..437aea48d 100644 --- a/radio/src/translations/cz.h.txt +++ b/radio/src/translations/cz.h.txt @@ -144,8 +144,8 @@ #define LEN_SUBTYPE_KN "\006" #define TR_SUBTYPE_KN "WLtoys""FeiLun" -#define LEN_SUBTYPE_MT99 "\004" -#define TR_SUBTYPE_MT99 "MT99""H7\0 ""YZ\0 ""LS\0 " +#define LEN_SUBTYPE_MT99 "\005" +#define TR_SUBTYPE_MT99 "MT99\0""H7\0 ""YZ\0 ""LS\0 ""FY805" #define LEN_SUBTYPE_MJXQ "\005" #define TR_SUBTYPE_MJXQ "WLH08""X600\0""X800\0""H26D\0""E010\0" @@ -156,6 +156,15 @@ #define LEN_SUBTYPE_Q2X2 "\004" #define TR_SUBTYPE_Q2X2 "Q242""Q282" +#define LEN_SUBTYPE_V2X2 "\006" +#define TR_SUBTYPE_V2X2 "V2x2\0 ""JXD506" + +#define LEN_SUBTYPE_BAYANG "\006" +#define TR_SUBTYPE_BAYANG "Bayang""H8S3D" + +#define LEN_SUBTYPE_FY326 "\005" +#define TR_SUBTYPE_FY326 "FY326""FY319" + #define LEN_VTRIMINC "\007" #define TR_VTRIMINC "Expo\0 ""ExJemný""Jemný\0 ""Střední""Hrubý\0 " @@ -904,6 +913,13 @@ #define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on powerup") #define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodetect", INDENT "Autodetect format") #define TR_MULTI_LOWPOWER TR(INDENT "Low power", INDENT "Low power mode") +#define TR_DISABLE_INTERNAL TR("Disable int. RF", "Disable internal RF") +#define TR_MODULE_NO_SERIAL_MODE TR("!serial mode", "Not in serial mode") +#define TR_MODULE_NO_INPUT TR("No input", "No serial input") +#define TR_MODULE_NO_TELEMETRY TR3( "No telmetry", "No MULTI_TELEMETRY", "No telemetry (enable MULTI_TELEMETRY)") +#define TR_MODULE_BINDING "Binding" +#define TR_PROTOCOL_INVALID TR("Prot. invalid", "Protocol invalid") +#define TR_MODULE_STATUS TR(INDENT "Status", INDENT "Module Status") #define TR_MULTI_SERVOFREQ TR(INDENT "Servo rate", INDENT "Servo update rate") #define TR_SYNCMENU "[Sync]" #define TR_LIMIT INDENT"Limit" diff --git a/radio/src/translations/de.h.txt b/radio/src/translations/de.h.txt index 6655f906a..97888a93b 100644 --- a/radio/src/translations/de.h.txt +++ b/radio/src/translations/de.h.txt @@ -102,7 +102,8 @@ #define TR_TARANIS_PROTOCOLS "AUS\0""PPM\0""XJT\0""DSM?""CRSF""MULT" #define LEN_TELEMETRY_PROTOCOLS "\017" -#define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 FrSky D\0 FrSky D (cable)Spektrum\0 " +#define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 ""FrSky D\0 ""FrSky D (Kabel)""TBS Crossfire\0 ""Spektrum\0 ""AFHDS2A IBUS\0 ""Multi Telemetry" + #define LEN_XJT_PROTOCOLS "\004" #define TR_XJT_PROTOCOLS "AUS\0""D16\0""D8\0 ""LR12" @@ -148,8 +149,8 @@ #define LEN_SUBTYPE_KN "\006" #define TR_SUBTYPE_KN "WLtoys""FeiLun" -#define LEN_SUBTYPE_MT99 "\004" -#define TR_SUBTYPE_MT99 "MT99""H7\0 ""YZ\0 ""LS\0 " +#define LEN_SUBTYPE_MT99 "\005" +#define TR_SUBTYPE_MT99 "MT99\0""H7\0 ""YZ\0 ""LS\0 ""FY805" #define LEN_SUBTYPE_MJXQ "\005" #define TR_SUBTYPE_MJXQ "WLH08""X600\0""X800\0""H26D\0""E010\0" @@ -160,6 +161,15 @@ #define LEN_SUBTYPE_Q2X2 "\004" #define TR_SUBTYPE_Q2X2 "Q242""Q282" +#define LEN_SUBTYPE_V2X2 "\006" +#define TR_SUBTYPE_V2X2 "V2x2\0 ""JXD506" + +#define LEN_SUBTYPE_BAYANG "\006" +#define TR_SUBTYPE_BAYANG "Bayang""H8S3D" + +#define LEN_SUBTYPE_FY326 "\005" +#define TR_SUBTYPE_FY326 "FY326""FY319" + #define LEN_VTRIMINC TR("\007", "\014") // ursprüglich "\006", "\013" #define TR_VTRIMINC TR("Expo ""ExFein ""Fein ""Mittel ""Grob ", "Exponentiell""Extrafein ""Fein ""Mittel ""Grob ") @@ -907,6 +917,13 @@ #define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on powerup") #define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodetect", INDENT "Autodetect format") #define TR_MULTI_LOWPOWER TR(INDENT "Low power", INDENT "Low power mode") +#define TR_DISABLE_INTERNAL TR("Disable int. RF", "Disable internal RF") +#define TR_MODULE_NO_SERIAL_MODE TR("!serial mode", "Not in serial mode") +#define TR_MODULE_NO_INPUT TR("No input", "No serial input") +#define TR_MODULE_NO_TELEMETRY TR3( "No telmetry", "No MULTI_TELEMETRY", "No telemetry (enable MULTI_TELEMETRY)") +#define TR_MODULE_BINDING "Binding" +#define TR_PROTOCOL_INVALID TR("Prot. invalid", "Protocol invalid") +#define TR_MODULE_STATUS TR(INDENT "Status", INDENT "Module Status") #define TR_MULTI_SERVOFREQ TR(INDENT "Servo rate", INDENT "Servo update rate") #define TR_SYNCMENU "Sync [MENU]" #define TR_LIMIT INDENT "Grenzen" diff --git a/radio/src/translations/en.h.txt b/radio/src/translations/en.h.txt index d5dfd650f..f615c26f8 100644 --- a/radio/src/translations/en.h.txt +++ b/radio/src/translations/en.h.txt @@ -102,7 +102,7 @@ #define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT" #define LEN_TELEMETRY_PROTOCOLS "\017" -#define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 FrSky D\0 FrSky D (cable)Spektrum\0 " +#define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 ""FrSky D\0 ""FrSky D (cable)""TBS Crossfire\0 ""Spektrum\0 ""AFHDS2A IBUS\0 ""Multi Telemetry" #define LEN_XJT_PROTOCOLS "\004" #define TR_XJT_PROTOCOLS "OFF\0""D16\0""D8\0 ""LR12" @@ -148,8 +148,8 @@ #define LEN_SUBTYPE_KN "\006" #define TR_SUBTYPE_KN "WLtoys""FeiLun" -#define LEN_SUBTYPE_MT99 "\004" -#define TR_SUBTYPE_MT99 "MT99""H7\0 ""YZ\0 ""LS\0 " +#define LEN_SUBTYPE_MT99 "\005" +#define TR_SUBTYPE_MT99 "MT99\0""H7\0 ""YZ\0 ""LS\0 ""FY805" #define LEN_SUBTYPE_MJXQ "\005" #define TR_SUBTYPE_MJXQ "WLH08""X600\0""X800\0""H26D\0""E010\0" @@ -160,6 +160,15 @@ #define LEN_SUBTYPE_Q2X2 "\004" #define TR_SUBTYPE_Q2X2 "Q242""Q282" +#define LEN_SUBTYPE_V2X2 "\006" +#define TR_SUBTYPE_V2X2 "V2x2\0 ""JXD506" + +#define LEN_SUBTYPE_BAYANG "\006" +#define TR_SUBTYPE_BAYANG "Bayang""H8S3D" + +#define LEN_SUBTYPE_FY326 "\005" +#define TR_SUBTYPE_FY326 "FY326""FY319" + #define LEN_VTRIMINC TR("\006", "\013") #define TR_VTRIMINC TR("Expo\0 ""ExFine""Fine\0 ""Medium""Coarse", "Exponential""Extra Fine\0""Fine\0 ""Medium\0 ""Coarse\0 ") @@ -879,6 +888,13 @@ #define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on powerup") #define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodetect", INDENT "Autodetect format") #define TR_MULTI_LOWPOWER TR(INDENT "Low power", INDENT "Low power mode") +#define TR_DISABLE_INTERNAL TR("Disable int. RF", "Disable internal RF") +#define TR_MODULE_NO_SERIAL_MODE TR("!serial mode", "Not in serial mode") +#define TR_MODULE_NO_INPUT TR("No input", "No serial input") +#define TR_MODULE_NO_TELEMETRY TR3( "No telmetry", "No MULTI_TELEMETRY", "No MULTI_TELEMETRY detected") +#define TR_MODULE_BINDING "Binding" +#define TR_PROTOCOL_INVALID TR("Prot. invalid", "Protocol invalid") +#define TR_MODULE_STATUS TR(INDENT "Status", INDENT "Module Status") #define TR_MULTI_SERVOFREQ TR(INDENT "Servo rate", INDENT "Servo update rate") #define TR_SYNCMENU "[Sync]" #define TR_LIMIT INDENT "Limit" diff --git a/radio/src/translations/es.h.txt b/radio/src/translations/es.h.txt index 869cf41b7..78678d163 100644 --- a/radio/src/translations/es.h.txt +++ b/radio/src/translations/es.h.txt @@ -98,7 +98,7 @@ #define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT" #define LEN_TELEMETRY_PROTOCOLS "\017" -#define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 FrSky D\0 FrSky D (cable)Spektrum\0 " +#define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 ""FrSky D\0 ""FrSky D (cable)""TBS Crossfire\0 ""Spektrum\0 ""AFHDS2A IBUS\0 ""Multi Telemetry" #define LEN_XJT_PROTOCOLS "\004" #define TR_XJT_PROTOCOLS "OFF\0""D16\0""D8\0 ""LR12" @@ -144,8 +144,8 @@ #define LEN_SUBTYPE_KN "\006" #define TR_SUBTYPE_KN "WLtoys""FeiLun" -#define LEN_SUBTYPE_MT99 "\004" -#define TR_SUBTYPE_MT99 "MT99""H7\0 ""YZ\0 ""LS\0 " +#define LEN_SUBTYPE_MT99 "\005" +#define TR_SUBTYPE_MT99 "MT99\0""H7\0 ""YZ\0 ""LS\0 ""FY805" #define LEN_SUBTYPE_MJXQ "\005" #define TR_SUBTYPE_MJXQ "WLH08""X600\0""X800\0""H26D\0""E010\0" @@ -156,6 +156,15 @@ #define LEN_SUBTYPE_Q2X2 "\004" #define TR_SUBTYPE_Q2X2 "Q242""Q282" +#define LEN_SUBTYPE_V2X2 "\006" +#define TR_SUBTYPE_V2X2 "V2x2\0 ""JXD506" + +#define LEN_SUBTYPE_BAYANG "\006" +#define TR_SUBTYPE_BAYANG "Bayang""H8S3D" + +#define LEN_SUBTYPE_FY326 "\005" +#define TR_SUBTYPE_FY326 "FY326""FY319" + #define LEN_VTRIMINC TR("\006", "\013") #define TR_VTRIMINC TR("Expo ""ExFino""Fino ""Medio ""Grueso", "Exponencial""Extra Fino ""Fino ""Medio ""Grueso ") @@ -852,6 +861,13 @@ #define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on powerup") #define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodetect", INDENT "Autodetect format") #define TR_MULTI_LOWPOWER TR(INDENT "Low power", INDENT "Low power mode") +#define TR_DISABLE_INTERNAL TR("Disable int. RF", "Disable internal RF") +#define TR_MODULE_NO_SERIAL_MODE TR("!serial mode", "Not in serial mode") +#define TR_MODULE_NO_INPUT TR("No input", "No serial input") +#define TR_MODULE_NO_TELEMETRY TR3( "No telmetry", "No MULTI_TELEMETRY", "No telemetry (enable MULTI_TELEMETRY)") +#define TR_MODULE_BINDING "Binding" +#define TR_PROTOCOL_INVALID TR("Prot. invalid", "Protocol invalid") +#define TR_MODULE_STATUS TR(INDENT "Status", INDENT "Module Status") #define TR_MULTI_SERVOFREQ TR(INDENT "Servo rate", INDENT "Servo update rate") #define TR_SYNCMENU "Sync " TR_ENTER #define TR_LIMIT INDENT"Limite" diff --git a/radio/src/translations/fi.h.txt b/radio/src/translations/fi.h.txt index 65f75cd9a..d19c1bf7f 100644 --- a/radio/src/translations/fi.h.txt +++ b/radio/src/translations/fi.h.txt @@ -98,7 +98,7 @@ #define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT" #define LEN_TELEMETRY_PROTOCOLS "\017" -#define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 FrSky D\0 FrSky D (cable)Spektrum\0 " +#define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 ""FrSky D\0 ""FrSky D (cable)""TBS Crossfire\0 ""Spektrum\0 ""AFHDS2A IBUS\0 ""Multi Telemetry" #define LEN_XJT_PROTOCOLS "\004" #define TR_XJT_PROTOCOLS "OFF\0""D16\0""D8\0 ""LR12" @@ -144,8 +144,8 @@ #define LEN_SUBTYPE_KN "\006" #define TR_SUBTYPE_KN "WLtoys""FeiLun" -#define LEN_SUBTYPE_MT99 "\004" -#define TR_SUBTYPE_MT99 "MT99""H7\0 ""YZ\0 ""LS\0 " +#define LEN_SUBTYPE_MT99 "\005" +#define TR_SUBTYPE_MT99 "MT99\0""H7\0 ""YZ\0 ""LS\0 ""FY805" #define LEN_SUBTYPE_MJXQ "\005" #define TR_SUBTYPE_MJXQ "WLH08""X600\0""X800\0""H26D\0""E010\0" @@ -156,6 +156,15 @@ #define LEN_SUBTYPE_Q2X2 "\004" #define TR_SUBTYPE_Q2X2 "Q242""Q282" +#define LEN_SUBTYPE_V2X2 "\006" +#define TR_SUBTYPE_V2X2 "V2x2\0 ""JXD506" + +#define LEN_SUBTYPE_BAYANG "\006" +#define TR_SUBTYPE_BAYANG "Bayang""H8S3D" + +#define LEN_SUBTYPE_FY326 "\005" +#define TR_SUBTYPE_FY326 "FY326""FY319" + #define LEN_VTRIMINC TR("\006", "\013") #define TR_VTRIMINC TR("Expo\0 ""EriHie""Hieno\0""Keski\0""Karkea", "Exponential""Eri Hieno\0 ""Hieno\0 ""Keski\0 ""Karkea\0 ") @@ -852,6 +861,13 @@ #define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on powerup") #define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodetect", INDENT "Autodetect format") #define TR_MULTI_LOWPOWER TR(INDENT "Low power", INDENT "Low power mode") +#define TR_DISABLE_INTERNAL TR("Disable int. RF", "Disable internal RF") +#define TR_MODULE_NO_SERIAL_MODE TR("!serial mode", "Not in serial mode") +#define TR_MODULE_NO_INPUT TR("No input", "No serial input") +#define TR_MODULE_NO_TELEMETRY TR3( "No telmetry", "No MULTI_TELEMETRY", "No telemetry (enable MULTI_TELEMETRY)") +#define TR_MODULE_BINDING "Binding" +#define TR_PROTOCOL_INVALID TR("Prot. invalid", "Protocol invalid") +#define TR_MODULE_STATUS TR(INDENT "Status", INDENT "Module Status") #define TR_MULTI_SERVOFREQ TR(INDENT "Servo rate", INDENT "Servo update rate") #define TR_SYNCMENU "[Sync]" #define TR_LIMIT INDENT"Limit" diff --git a/radio/src/translations/fr.h.txt b/radio/src/translations/fr.h.txt index 86a55ba6a..3b8e304da 100644 --- a/radio/src/translations/fr.h.txt +++ b/radio/src/translations/fr.h.txt @@ -98,7 +98,7 @@ #define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT" #define LEN_TELEMETRY_PROTOCOLS "\017" -#define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 FrSky D\0 FrSky D (cable)Spektrum\0 " +#define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 ""FrSky D\0 ""FrSky D (cable)""TBS Crossfire\0 ""Spektrum\0 ""AFHDS2A IBUS\0 ""Multi Telemetry" #define LEN_XJT_PROTOCOLS "\004" #define TR_XJT_PROTOCOLS "OFF\0""D16\0""D8\0 ""LR12" @@ -144,8 +144,8 @@ #define LEN_SUBTYPE_KN "\006" #define TR_SUBTYPE_KN "WLtoys""FeiLun" -#define LEN_SUBTYPE_MT99 "\004" -#define TR_SUBTYPE_MT99 "MT99""H7\0 ""YZ\0 ""LS\0 " +#define LEN_SUBTYPE_MT99 "\005" +#define TR_SUBTYPE_MT99 "MT99\0""H7\0 ""YZ\0 ""LS\0 ""FY805" #define LEN_SUBTYPE_MJXQ "\005" #define TR_SUBTYPE_MJXQ "WLH08""X600\0""X800\0""H26D\0""E010\0" @@ -156,6 +156,15 @@ #define LEN_SUBTYPE_Q2X2 "\004" #define TR_SUBTYPE_Q2X2 "Q242""Q282" +#define LEN_SUBTYPE_V2X2 "\006" +#define TR_SUBTYPE_V2X2 "V2x2\0 ""JXD506" + +#define LEN_SUBTYPE_BAYANG "\006" +#define TR_SUBTYPE_BAYANG "Bayang""H8S3D" + +#define LEN_SUBTYPE_FY326 "\005" +#define TR_SUBTYPE_FY326 "FY326""FY319" + #define LEN_VTRIMINC TR("\006", "\013") #define TR_VTRIMINC TR("Expo\0 ""ExFin\0""Fin\0 ""Moyen\0""Gros\0 ","Exponentiel""Extra Fin\0 ""Fin\0 ""Moyen\0 ""Grossier\0 ") @@ -886,6 +895,13 @@ #define TR_MULTI_AUTOBIND TR(INDENT "Bind auto", INDENT "Bind automatique") #define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodét.", INDENT "Autodétection") #define TR_MULTI_LOWPOWER TR(INDENT "Basse puis.", INDENT "Mode basse puiss.") +#define TR_DISABLE_INTERNAL TR("Disable int. RF", "Disable internal RF") +#define TR_MODULE_NO_SERIAL_MODE TR("!serial mode", "Not in serial mode") +#define TR_MODULE_NO_INPUT TR("No input", "No serial input") +#define TR_MODULE_NO_TELEMETRY TR3( "No telmetry", "No MULTI_TELEMETRY", "No telemetry (enable MULTI_TELEMETRY)") +#define TR_MODULE_BINDING "Binding" +#define TR_PROTOCOL_INVALID TR("Prot. invalid", "Protocol invalid") +#define TR_MODULE_STATUS TR(INDENT "Status", INDENT "Module Status") #define TR_MULTI_SERVOFREQ TR(INDENT "Fréq.servo", INDENT "Fréquence servos") #define TR_SYNCMENU "Sync [MENU]" #define TR_LIMIT INDENT "Limite" diff --git a/radio/src/translations/it.h.txt b/radio/src/translations/it.h.txt index 598b4587e..0fb8cde24 100644 --- a/radio/src/translations/it.h.txt +++ b/radio/src/translations/it.h.txt @@ -98,7 +98,7 @@ #define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT" #define LEN_TELEMETRY_PROTOCOLS "\017" -#define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 FrSky D\0 FrSky D (cable)Spektrum\0 " +#define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 ""FrSky D\0 ""FrSky D (cable)""TBS Crossfire\0 ""Spektrum\0 ""AFHDS2A IBUS\0 ""Multi Telemetry" #define LEN_XJT_PROTOCOLS "\004" #define TR_XJT_PROTOCOLS "OFF\0""D16\0""D8\0 ""LR12" @@ -144,8 +144,8 @@ #define LEN_SUBTYPE_KN "\006" #define TR_SUBTYPE_KN "WLtoys""FeiLun" -#define LEN_SUBTYPE_MT99 "\004" -#define TR_SUBTYPE_MT99 "MT99""H7\0 ""YZ\0 ""LS\0 " +#define LEN_SUBTYPE_MT99 "\005" +#define TR_SUBTYPE_MT99 "MT99\0""H7\0 ""YZ\0 ""LS\0 ""FY805" #define LEN_SUBTYPE_MJXQ "\005" #define TR_SUBTYPE_MJXQ "WLH08""X600\0""X800\0""H26D\0""E010\0" @@ -156,6 +156,15 @@ #define LEN_SUBTYPE_Q2X2 "\004" #define TR_SUBTYPE_Q2X2 "Q242""Q282" +#define LEN_SUBTYPE_V2X2 "\006" +#define TR_SUBTYPE_V2X2 "V2x2\0 ""JXD506" + +#define LEN_SUBTYPE_BAYANG "\006" +#define TR_SUBTYPE_BAYANG "Bayang""H8S3D" + +#define LEN_SUBTYPE_FY326 "\005" +#define TR_SUBTYPE_FY326 "FY326""FY319" + #define LEN_VTRIMINC "\006" #define TR_VTRIMINC "Exp ""ExFine""Fine ""Medio ""Ampio " @@ -887,6 +896,13 @@ #define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on powerup") #define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodetect", INDENT "Autodetect format") #define TR_MULTI_LOWPOWER TR(INDENT "Low power", INDENT "Low power mode") +#define TR_DISABLE_INTERNAL TR("Disable int. RF", "Disable internal RF") +#define TR_MODULE_NO_SERIAL_MODE TR("!serial mode", "Not in serial mode") +#define TR_MODULE_NO_INPUT TR("No input", "No serial input") +#define TR_MODULE_NO_TELEMETRY TR3( "No telmetry", "No MULTI_TELEMETRY", "No telemetry (enable MULTI_TELEMETRY)") +#define TR_MODULE_BINDING "Binding" +#define TR_PROTOCOL_INVALID TR("Prot. invalid", "Protocol invalid") +#define TR_MODULE_STATUS TR(INDENT "Status", INDENT "Module Status") #define TR_MULTI_SERVOFREQ TR(INDENT "Servo rate", INDENT "Servo update rate") #define TR_SYNCMENU "[Sync]" #define TR_LIMIT INDENT "Limiti" diff --git a/radio/src/translations/nl.h.txt b/radio/src/translations/nl.h.txt index 8130532b0..b889586bc 100644 --- a/radio/src/translations/nl.h.txt +++ b/radio/src/translations/nl.h.txt @@ -103,7 +103,7 @@ #define TR_TARANIS_PROTOCOLS "UIT\0""PPM\0""XJT\0""DSM2""CRSF""MULT" #define LEN_TELEMETRY_PROTOCOLS "\017" -#define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 FrSky D\0 FrSky D (cable)Spektrum\0 " +#define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 ""FrSky D\0 ""FrSky D (cable)""TBS Crossfire\0 ""Spektrum\0 ""AFHDS2A IBUS\0 ""Multi Telemetry" #define LEN_XJT_PROTOCOLS "\004" #define TR_XJT_PROTOCOLS "OFF\0""D16\0""D8\0 ""LR12" @@ -149,8 +149,8 @@ #define LEN_SUBTYPE_KN "\006" #define TR_SUBTYPE_KN "WLtoys""FeiLun" -#define LEN_SUBTYPE_MT99 "\004" -#define TR_SUBTYPE_MT99 "MT99""H7\0 ""YZ\0 ""LS\0 " +#define LEN_SUBTYPE_MT99 "\005" +#define TR_SUBTYPE_MT99 "MT99\0""H7\0 ""YZ\0 ""LS\0 ""FY805" #define LEN_SUBTYPE_MJXQ "\005" #define TR_SUBTYPE_MJXQ "WLH08""X600\0""X800\0""H26D\0""E010\0" @@ -161,6 +161,15 @@ #define LEN_SUBTYPE_Q2X2 "\004" #define TR_SUBTYPE_Q2X2 "Q242""Q282" +#define LEN_SUBTYPE_V2X2 "\006" +#define TR_SUBTYPE_V2X2 "V2x2\0 ""JXD506" + +#define LEN_SUBTYPE_BAYANG "\006" +#define TR_SUBTYPE_BAYANG "Bayang""H8S3D" + +#define LEN_SUBTYPE_FY326 "\005" +#define TR_SUBTYPE_FY326 "FY326""FY319" + #define LEN_VTRIMINC TR("\006", "\014") #define TR_VTRIMINC TR("Expo\0 ""ExFijn""Fijn\0 ""Medium""Grof\0 ", "Exponentieel""Extra Fijn\0 ""Fijn\0 ""Medium\0 ""Grof\0 ") @@ -881,6 +890,13 @@ #define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on powerup") #define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodetect", INDENT "Autodetect format") #define TR_MULTI_LOWPOWER TR(INDENT "Low power", INDENT "Low power mode") +#define TR_DISABLE_INTERNAL TR("Disable int. RF", "Disable internal RF") +#define TR_MODULE_NO_SERIAL_MODE TR("!serial mode", "Not in serial mode") +#define TR_MODULE_NO_INPUT TR("No input", "No serial input") +#define TR_MODULE_NO_TELEMETRY TR3( "No telmetry", "No MULTI_TELEMETRY", "No telemetry (enable MULTI_TELEMETRY)") +#define TR_MODULE_BINDING "Binding" +#define TR_PROTOCOL_INVALID TR("Prot. invalid", "Protocol invalid") +#define TR_MODULE_STATUS TR(INDENT "Status", INDENT "Module Status") #define TR_MULTI_SERVOFREQ TR(INDENT "Servo rate", INDENT "Servo update rate") #define TR_SYNCMENU "Sync [MENU]" #define TR_LIMIT INDENT "Grenzen" diff --git a/radio/src/translations/pl.h.txt b/radio/src/translations/pl.h.txt index ded71ccd0..12ad48ffc 100644 --- a/radio/src/translations/pl.h.txt +++ b/radio/src/translations/pl.h.txt @@ -99,7 +99,7 @@ #define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT" #define LEN_TELEMETRY_PROTOCOLS "\017" -#define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 FrSky D\0 FrSky D (cable)Spektrum\0 " +#define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 ""FrSky D\0 ""FrSky D (cable)""TBS Crossfire\0 ""Spektrum\0 ""AFHDS2A IBUS\0 ""Multi Telemetry" #define LEN_XJT_PROTOCOLS "\004" #define TR_XJT_PROTOCOLS "OFF\0""D16\0""D8\0 ""LR12" @@ -145,8 +145,8 @@ #define LEN_SUBTYPE_KN "\006" #define TR_SUBTYPE_KN "WLtoys""FeiLun" -#define LEN_SUBTYPE_MT99 "\004" -#define TR_SUBTYPE_MT99 "MT99""H7\0 ""YZ\0 ""LS\0 " +#define LEN_SUBTYPE_MT99 "\005" +#define TR_SUBTYPE_MT99 "MT99\0""H7\0 ""YZ\0 ""LS\0 ""FY805" #define LEN_SUBTYPE_MJXQ "\005" #define TR_SUBTYPE_MJXQ "WLH08""X600\0""X800\0""H26D\0""E010\0" @@ -157,6 +157,15 @@ #define LEN_SUBTYPE_Q2X2 "\004" #define TR_SUBTYPE_Q2X2 "Q242""Q282" +#define LEN_SUBTYPE_V2X2 "\006" +#define TR_SUBTYPE_V2X2 "V2x2\0 ""JXD506" + +#define LEN_SUBTYPE_BAYANG "\006" +#define TR_SUBTYPE_BAYANG "Bayang""H8S3D" + +#define LEN_SUBTYPE_FY326 "\005" +#define TR_SUBTYPE_FY326 "FY326""FY319" + #define LEN_VTRIMINC TR("\006", "\013") /*11 decimal*/ #define TR_VTRIMINC TR("Expo\0 ""B.Dokł""Dokł.\0""Średni""Zgrubn", "Expotencja ""B.Dokładny\0""Dokładny\0 ""Średni\0 ""Zgrubny\0 ") @@ -889,6 +898,13 @@ #define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on powerup") #define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodetect", INDENT "Autodetect format") #define TR_MULTI_LOWPOWER TR(INDENT "Low power", INDENT "Low power mode") +#define TR_DISABLE_INTERNAL TR("Disable int. RF", "Disable internal RF") +#define TR_MODULE_NO_SERIAL_MODE TR("!serial mode", "Not in serial mode") +#define TR_MODULE_NO_INPUT TR("No input", "No serial input") +#define TR_MODULE_NO_TELEMETRY TR3( "No telmetry", "No MULTI_TELEMETRY", "No telemetry (enable MULTI_TELEMETRY)") +#define TR_MODULE_BINDING "Binding" +#define TR_PROTOCOL_INVALID TR("Prot. invalid", "Protocol invalid") +#define TR_MODULE_STATUS TR(INDENT "Status", INDENT "Module Status") #define TR_MULTI_SERVOFREQ TR(INDENT "Servo rate", INDENT "Servo update rate") #define TR_SYNCMENU "[Synch]" #define TR_LIMIT INDENT "Limit" diff --git a/radio/src/translations/pt.h.txt b/radio/src/translations/pt.h.txt index 80960e5a0..189a02700 100644 --- a/radio/src/translations/pt.h.txt +++ b/radio/src/translations/pt.h.txt @@ -98,7 +98,7 @@ #define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT" #define LEN_TELEMETRY_PROTOCOLS "\017" -#define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 FrSky D\0 FrSky D (cable)Spektrum\0 " +#define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 ""FrSky D\0 ""FrSky D (cable)""TBS Crossfire\0 ""Spektrum\0 ""AFHDS2A IBUS\0 ""Multi Telemetry" #define LEN_XJT_PROTOCOLS "\004" #define TR_XJT_PROTOCOLS "OFF\0""D16\0""D8\0 ""LR12" @@ -145,8 +145,8 @@ #define LEN_SUBTYPE_KN "\006" #define TR_SUBTYPE_KN "WLtoys""FeiLun" -#define LEN_SUBTYPE_MT99 "\004" -#define TR_SUBTYPE_MT99 "MT99""H7\0 ""YZ\0 ""LS\0 " +#define LEN_SUBTYPE_MT99 "\005" +#define TR_SUBTYPE_MT99 "MT99\0""H7\0 ""YZ\0 ""LS\0 ""FY805" #define LEN_SUBTYPE_MJXQ "\005" #define TR_SUBTYPE_MJXQ "WLH08""X600\0""X800\0""H26D\0""E010\0" @@ -157,6 +157,15 @@ #define LEN_SUBTYPE_Q2X2 "\004" #define TR_SUBTYPE_Q2X2 "Q242""Q282" +#define LEN_SUBTYPE_V2X2 "\006" +#define TR_SUBTYPE_V2X2 "V2x2\0 ""JXD506" + +#define LEN_SUBTYPE_BAYANG "\006" +#define TR_SUBTYPE_BAYANG "Bayang""H8S3D" + +#define LEN_SUBTYPE_FY326 "\005" +#define TR_SUBTYPE_FY326 "FY326""FY319" + #define LEN_VTRIMINC "\006" #define TR_VTRIMINC "Expo ""ExFino""Fino ""Medio ""Largo " @@ -848,6 +857,13 @@ #define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on powerup") #define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodetect", INDENT "Autodetect format") #define TR_MULTI_LOWPOWER TR(INDENT "Low power", INDENT "Low power mode") +#define TR_DISABLE_INTERNAL TR("Disable int. RF", "Disable internal RF") +#define TR_MODULE_NO_SERIAL_MODE TR("!serial mode", "Not in serial mode") +#define TR_MODULE_NO_INPUT TR("No input", "No serial input") +#define TR_MODULE_NO_TELEMETRY TR3( "No telmetry", "No MULTI_TELEMETRY", "No telemetry (enable MULTI_TELEMETRY)") +#define TR_MODULE_BINDING "Binding" +#define TR_PROTOCOL_INVALID TR("Prot. invalid", "Protocol invalid") +#define TR_MODULE_STATUS TR(INDENT "Status", INDENT "Module Status") #define TR_MULTI_SERVOFREQ TR(INDENT "Servo rate", INDENT "Servo update rate") #define TR_LIMIT INDENT"Limite" #define TR_MINRSSI "Min Rssi" diff --git a/radio/src/translations/se.h.txt b/radio/src/translations/se.h.txt index 41f3c5def..94dc1cc67 100644 --- a/radio/src/translations/se.h.txt +++ b/radio/src/translations/se.h.txt @@ -98,7 +98,7 @@ #define TR_TARANIS_PROTOCOLS "Av\0 ""PPM\0""XJT\0""DSM2""CRSF""MULT" #define LEN_TELEMETRY_PROTOCOLS "\017" -#define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 FrSky D\0 FrSky D (cable)Spektrum\0 " +#define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 ""FrSky D\0 ""FrSky D (cable)""TBS Crossfire\0 ""Spektrum\0 ""AFHDS2A IBUS\0 ""Multi Telemetry" #define LEN_XJT_PROTOCOLS "\004" #define TR_XJT_PROTOCOLS "Av\0 ""D16\0""D8\0 ""LR12" @@ -144,8 +144,8 @@ #define LEN_SUBTYPE_KN "\006" #define TR_SUBTYPE_KN "WLtoys""FeiLun" -#define LEN_SUBTYPE_MT99 "\004" -#define TR_SUBTYPE_MT99 "MT99""H7\0 ""YZ\0 ""LS\0 " +#define LEN_SUBTYPE_MT99 "\005" +#define TR_SUBTYPE_MT99 "MT99\0""H7\0 ""YZ\0 ""LS\0 ""FY805" #define LEN_SUBTYPE_MJXQ "\005" #define TR_SUBTYPE_MJXQ "WLH08""X600\0""X800\0""H26D\0""E010\0" @@ -901,6 +901,13 @@ #define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on powerup") #define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodetect", INDENT "Autodetect format") #define TR_MULTI_LOWPOWER TR(INDENT "Low power", INDENT "Low power mode") +#define TR_DISABLE_INTERNAL TR("Disable int. RF", "Disable internal RF") +#define TR_MODULE_NO_SERIAL_MODE TR("!serial mode", "Not in serial mode") +#define TR_MODULE_NO_INPUT TR("No input", "No serial input") +#define TR_MODULE_NO_TELEMETRY TR3( "No telmetry", "No MULTI_TELEMETRY", "No telemetry (enable MULTI_TELEMETRY)") +#define TR_MODULE_BINDING "Binding" +#define TR_PROTOCOL_INVALID TR("Prot. invalid", "Protocol invalid") +#define TR_MODULE_STATUS TR(INDENT "Status", INDENT "Module Status") #define TR_MULTI_SERVOFREQ TR(INDENT "Servo rate", INDENT "Servo update rate") #define TR_LIMIT INDENT "Nivå" #define TR_MINRSSI "Min Rssi"