diff --git a/radio/src/gui/128x64/model_setup.cpp b/radio/src/gui/128x64/model_setup.cpp index 9b7b08dc9..cbaa90cf4 100644 --- a/radio/src/gui/128x64/model_setup.cpp +++ b/radio/src/gui/128x64/model_setup.cpp @@ -962,14 +962,7 @@ void menuModelSetup(event_t event) if (checkIncDec_Ret) { g_model.moduleData[moduleIdx].setMultiProtocol(multiRfProto); g_model.moduleData[moduleIdx].subType = 0; - // Sensible default for DSM2 (same as for ppm): 7ch@22ms + Autodetect settings enabled - if (g_model.moduleData[moduleIdx].getMultiProtocol() == MODULE_SUBTYPE_MULTI_DSM2) { - g_model.moduleData[moduleIdx].multi.autoBindMode = 1; - } - else { - g_model.moduleData[moduleIdx].multi.autoBindMode = 0; - } - g_model.moduleData[moduleIdx].multi.optionValue = 0; + resetMultiProtocolsOptions(moduleIdx); } } #endif @@ -1018,6 +1011,9 @@ void menuModelSetup(event_t event) switch (menuHorizontalPosition) { case 0:{ CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].subType, 0, getMaxMultiSubtype(moduleIdx)); + if (checkIncDec_Ret) { + resetMultiProtocolsOptions(moduleIdx); + } break; } } @@ -1458,7 +1454,7 @@ void menuModelSetup(event_t event) case ITEM_MODEL_SETUP_EXTERNAL_MODULE_OPTIONS: { #if defined(MULTIMODULE) - if (isModuleMultimodule(moduleIdx)) { + if (MULTIMODULE_PROTOCOL_KNOWN(moduleIdx)) { int optionValue = g_model.moduleData[moduleIdx].multi.optionValue; const uint8_t multi_proto = g_model.moduleData[moduleIdx].getMultiProtocol(); diff --git a/radio/src/gui/212x64/model_setup.cpp b/radio/src/gui/212x64/model_setup.cpp index ef03b00ba..b8f373ee9 100644 --- a/radio/src/gui/212x64/model_setup.cpp +++ b/radio/src/gui/212x64/model_setup.cpp @@ -855,14 +855,7 @@ void menuModelSetup(event_t event) if (checkIncDec_Ret) { g_model.moduleData[EXTERNAL_MODULE].setMultiProtocol(multiRfProto); g_model.moduleData[EXTERNAL_MODULE].subType = 0; - // Sensible default for DSM2 (same as for ppm): 7ch@22ms + Autodetect settings enabled - if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol() == MODULE_SUBTYPE_MULTI_DSM2) { - g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode = 1; - } - else { - g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode = 0; - } - g_model.moduleData[EXTERNAL_MODULE].multi.optionValue = 0; + resetMultiProtocolsOptions(EXTERNAL_MODULE); } } #endif @@ -884,18 +877,10 @@ void menuModelSetup(event_t event) #if defined(MULTIMODULE) case 2: - if (g_model.moduleData[EXTERNAL_MODULE].multi.customProto) { - g_model.moduleData[EXTERNAL_MODULE].setMultiProtocol(checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(), 0, MULTI_MAX_PROTOCOLS, EE_MODEL)); - break; + CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, getMaxMultiSubtype(EXTERNAL_MODULE)); + if (checkIncDec_Ret) { + resetMultiProtocolsOptions(EXTERNAL_MODULE); } - else { - CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, getMaxMultiSubtype(EXTERNAL_MODULE)); - } - break; - - case 3: - // Custom protocol, third column is subtype - CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, 7); break; #endif } @@ -1228,7 +1213,7 @@ void menuModelSetup(event_t event) uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); #if defined(MULTIMODULE) - if (isModuleMultimodule(moduleIdx)) { + if (MULTIMODULE_PROTOCOL_KNOWN(moduleIdx)) { int optionValue = g_model.moduleData[moduleIdx].multi.optionValue; const uint8_t multi_proto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(); diff --git a/radio/src/gui/480x272/model_setup.cpp b/radio/src/gui/480x272/model_setup.cpp index 15f1b58c6..ef2be344f 100644 --- a/radio/src/gui/480x272/model_setup.cpp +++ b/radio/src/gui/480x272/model_setup.cpp @@ -1117,16 +1117,7 @@ bool menuModelSetup(event_t event) if (checkIncDec_Ret) { g_model.moduleData[moduleIdx].setMultiProtocol(multiRfProto); g_model.moduleData[moduleIdx].subType = 0; - // Sensible default for DSM2 (same as for ppm): 7ch@22ms + Autodetect settings enabled - if (g_model.moduleData[moduleIdx].getMultiProtocol() == MODULE_SUBTYPE_MULTI_DSM2) { - g_model.moduleData[moduleIdx].multi.autoBindMode = 1; - } - else { - g_model.moduleData[moduleIdx].multi.autoBindMode = 0; - } - g_model.moduleData[moduleIdx].multi.optionValue = 0; - g_model.moduleData[moduleIdx].multi.disableTelemetry = 0; - g_model.moduleData[moduleIdx].multi.disableMapping = 0; + resetMultiProtocolsOptions(moduleIdx); } } #endif @@ -1146,6 +1137,9 @@ bool menuModelSetup(event_t event) #if defined(MULTIMODULE) case 2: { CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].subType, 0, getMaxMultiSubtype(moduleIdx)); + if (checkIncDec_Ret) { + resetMultiProtocolsOptions(moduleIdx); + } break; } #endif @@ -1616,7 +1610,7 @@ bool menuModelSetup(event_t event) case ITEM_MODEL_SETUP_EXTERNAL_MODULE_OPTIONS: { #if defined(MULTIMODULE) - if (isModuleMultimodule(moduleIdx)) { + if (MULTIMODULE_PROTOCOL_KNOWN(moduleIdx)) { int optionValue = g_model.moduleData[moduleIdx].multi.optionValue; const uint8_t multi_proto = g_model.moduleData[moduleIdx].getMultiProtocol(); diff --git a/radio/src/gui/gui_common.h b/radio/src/gui/gui_common.h index 297808555..806ceb751 100644 --- a/radio/src/gui/gui_common.h +++ b/radio/src/gui/gui_common.h @@ -161,43 +161,6 @@ inline uint8_t MODULE_CHANNELS_ROWS(int moduleIdx) #if defined(MULTIMODULE) -// When using packed, the pointer in here end up not being aligned, which clang and gcc complain about -// Keep the order of the fields that the so that the size stays small -struct mm_options_strings { - static const char* options[]; -}; - -struct mm_protocol_definition { - uint8_t protocol; - uint8_t maxSubtype; - bool failsafe; - bool disable_ch_mapping; - const char *subTypeString; - const char *optionsstr; -}; - -const mm_protocol_definition *getMultiProtocolDefinition (uint8_t protocol); - -inline uint8_t getMaxMultiSubtype(uint8_t moduleIdx) -{ - MultiModuleStatus &status = getMultiModuleStatus(moduleIdx); - const mm_protocol_definition *pdef = getMultiProtocolDefinition(g_model.moduleData[moduleIdx].getMultiProtocol()); - - if (g_model.moduleData[moduleIdx].getMultiProtocol() == MODULE_SUBTYPE_MULTI_FRSKY) { - return 5; - } - - if (g_model.moduleData[moduleIdx].getMultiProtocol() > MODULE_SUBTYPE_MULTI_LAST) { - if (status.isValid()) - return (status.protocolSubNbr == 0 ? 0 : status.protocolSubNbr - 1); - else - return 7; - } - else { - return max((uint8_t )(status.protocolSubNbr == 0 ? 0 : status.protocolSubNbr - 1), pdef->maxSubtype); - } -} - inline uint8_t MULTI_DISABLE_CHAN_MAP_ROW(uint8_t moduleIdx) { if (!isModuleMultimodule(moduleIdx)) @@ -223,6 +186,24 @@ inline bool isMultiProtocolSelectable(int protocol) return protocol != MODULE_SUBTYPE_MULTI_SCANNER; } +inline bool MULTIMODULE_PROTOCOL_KNOWN(uint8_t moduleIdx) +{ + if (!isModuleMultimodule(moduleIdx)) { + return false; + } + + if (g_model.moduleData[moduleIdx].getMultiProtocol() < MODULE_SUBTYPE_MULTI_LAST) { + return true; + } + + MultiModuleStatus &status = getMultiModuleStatus(moduleIdx); + if (status.isValid()) { + return status.protocolValid(); + } + + return false; +} + inline bool MULTIMODULE_HAS_SUBTYPE(uint8_t moduleIdx) { MultiModuleStatus &status = getMultiModuleStatus(moduleIdx); @@ -266,7 +247,7 @@ inline uint8_t MULTIMODULE_HASOPTIONS(uint8_t moduleIdx) return status.optionDisp; } -#define MULTIMODULE_MODULE_ROWS(moduleIdx) isModuleMultimodule(moduleIdx) ? (uint8_t) 0 : HIDDEN_ROW, isModuleMultimodule(moduleIdx) ? (uint8_t) 0 : HIDDEN_ROW, MULTI_DISABLE_CHAN_MAP_ROW(moduleIdx), // AUTOBIND, DISABLE TELEM, DISABLE CN.MAP +#define MULTIMODULE_MODULE_ROWS(moduleIdx) MULTIMODULE_PROTOCOL_KNOWN(moduleIdx) ? (uint8_t) 0 : HIDDEN_ROW, MULTIMODULE_PROTOCOL_KNOWN(moduleIdx) ? (uint8_t) 0 : HIDDEN_ROW, MULTI_DISABLE_CHAN_MAP_ROW(moduleIdx), // AUTOBIND, DISABLE TELEM, DISABLE CN.MAP #define MULTIMODULE_STATUS_ROWS(moduleIdx) isModuleMultimodule(moduleIdx) ? TITLE_ROW : HIDDEN_ROW, (isModuleMultimodule(moduleIdx) && getMultiSyncStatus(moduleIdx).isValid()) ? TITLE_ROW : HIDDEN_ROW, #define MULTIMODULE_MODE_ROWS(moduleIdx) (g_model.moduleData[moduleIdx].multi.customProto) ? (uint8_t) 3 : MULTIMODULE_HAS_SUBTYPE(moduleIdx) ? (uint8_t)2 : (uint8_t)1 #define MULTIMODULE_SUBTYPE_ROWS(moduleIdx) isModuleMultimodule(moduleIdx) ? MULTIMODULE_RFPROTO_COLUMNS(moduleIdx) : HIDDEN_ROW, @@ -282,7 +263,7 @@ inline uint8_t MULTIMODULE_HASOPTIONS(uint8_t moduleIdx) #define FAILSAFE_ROWS(moduleIdx) isModuleFailsafeAvailable(moduleIdx) ? (g_model.moduleData[moduleIdx].failsafeMode==FAILSAFE_CUSTOM ? (uint8_t)1 : (uint8_t)0) : HIDDEN_ROW #define MODULE_OPTION_ROW(moduleIdx) (isModuleR9MNonAccess(moduleIdx) || isModuleSBUS(moduleIdx) ? TITLE_ROW : MULTIMODULE_OPTIONS_ROW(moduleIdx)) -#define MODULE_POWER_ROW(moduleIdx) (isModuleMultimodule(moduleIdx) || isModuleR9MNonAccess(moduleIdx)) ? (isModuleR9MLiteNonPro(moduleIdx) ? (isModuleR9M_FCC_VARIANT(moduleIdx) ? READONLY_ROW : (uint8_t)0) : (uint8_t)0) : HIDDEN_ROW +#define MODULE_POWER_ROW(moduleIdx) (MULTIMODULE_PROTOCOL_KNOWN(moduleIdx) || isModuleR9MNonAccess(moduleIdx)) ? (isModuleR9MLiteNonPro(moduleIdx) ? (isModuleR9M_FCC_VARIANT(moduleIdx) ? READONLY_ROW : (uint8_t)0) : (uint8_t)0) : HIDDEN_ROW void editStickHardwareSettings(coord_t x, coord_t y, int idx, event_t event, LcdFlags flags); diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index 65e682496..3425802d6 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -890,7 +890,12 @@ void checkFailsafe() void checkRSSIAlarmsDisabled() { if (g_model.rssiAlarms.disabled) { - ALERT(STR_RSSIALARM_WARN, STR_NO_RSSIALARM, AU_ERROR); +#if !defined(INTERNAL_MODULE) + if (!isModuleMultimoduleDSM2(EXTERNAL_MODULE)) +#else + if (!isModuleMultimoduleDSM2(INTERNAL_MODULE) && !isModuleMultimoduleDSM2(EXTERNAL_MODULE)) +#endif + ALERT(STR_RSSIALARM_WARN, STR_NO_RSSIALARM, AU_ERROR); } } diff --git a/radio/src/pulses/modules_helpers.h b/radio/src/pulses/modules_helpers.h index f7cdaee71..ecc3226d7 100644 --- a/radio/src/pulses/modules_helpers.h +++ b/radio/src/pulses/modules_helpers.h @@ -32,6 +32,43 @@ #define CROSSFIRE_CHANNELS_COUNT 16 #if defined(MULTIMODULE) +// When using packed, the pointer in here end up not being aligned, which clang and gcc complain about +// Keep the order of the fields that the so that the size stays small +struct mm_options_strings { + static const char* options[]; +}; + +struct mm_protocol_definition { + uint8_t protocol; + uint8_t maxSubtype; + bool failsafe; + bool disable_ch_mapping; + const char *subTypeString; + const char *optionsstr; +}; + +const mm_protocol_definition *getMultiProtocolDefinition (uint8_t protocol); + +inline uint8_t getMaxMultiSubtype(uint8_t moduleIdx) +{ + MultiModuleStatus &status = getMultiModuleStatus(moduleIdx); + const mm_protocol_definition *pdef = getMultiProtocolDefinition(g_model.moduleData[moduleIdx].getMultiProtocol()); + + if (g_model.moduleData[moduleIdx].getMultiProtocol() == MODULE_SUBTYPE_MULTI_FRSKY) { + return 5; + } + + if (g_model.moduleData[moduleIdx].getMultiProtocol() > MODULE_SUBTYPE_MULTI_LAST) { + if (status.isValid()) + return (status.protocolSubNbr == 0 ? 0 : status.protocolSubNbr - 1); + else + return 7; + } + else { + return max((uint8_t )(status.protocolSubNbr == 0 ? 0 : status.protocolSubNbr - 1), pdef->maxSubtype); + } +} + inline bool isModuleMultimodule(uint8_t idx) { return g_model.moduleData[idx].type == MODULE_TYPE_MULTIMODULE; @@ -357,8 +394,14 @@ inline bool isModuleFailsafeAvailable(uint8_t moduleIdx) #if defined(MULTIMODULE) if (isModuleMultimodule(moduleIdx)){ - MultiModuleStatus& status = getMultiModuleStatus(moduleIdx); - return status.isValid() && status.supportsFailsafe(); + MultiModuleStatus &status = getMultiModuleStatus(moduleIdx); + if (status.isValid()) { + return status.supportsFailsafe(); + } + else { + const mm_protocol_definition * pdef = getMultiProtocolDefinition(g_model.moduleData[moduleIdx].getMultiProtocol()); + return pdef->failsafe; + } } #endif @@ -497,4 +540,24 @@ inline void setModuleType(uint8_t moduleIdx, uint8_t moduleType) extern bool isExternalAntennaEnabled(); +#if defined(MULTIMODULE) +inline void resetMultiProtocolsOptions(uint8_t moduleIdx) +{ + if (!isModuleMultimodule(moduleIdx)) + return; + + // Sensible default for DSM2 (same as for ppm): 7ch@22ms + Autodetect settings enabled + if (g_model.moduleData[moduleIdx].getMultiProtocol() == MODULE_SUBTYPE_MULTI_DSM2) { + g_model.moduleData[moduleIdx].multi.autoBindMode = 1; + } + else { + g_model.moduleData[moduleIdx].multi.autoBindMode = 0; + } + g_model.moduleData[moduleIdx].multi.optionValue = 0; + g_model.moduleData[moduleIdx].multi.disableTelemetry = 0; + g_model.moduleData[moduleIdx].multi.disableMapping = 0; + g_model.moduleData[moduleIdx].multi.lowPowerMode = 0; +} +#endif + #endif // _MODULES_HELPERS_H_