diff --git a/radio/src/datastructs.h b/radio/src/datastructs.h index b74bdb318..06c6e8a68 100644 --- a/radio/src/datastructs.h +++ b/radio/src/datastructs.h @@ -644,6 +644,8 @@ PACK(struct TelemetrySensor { * Module structure */ +// Only used in case switch and if statements as "virtual" protocol +#define MM_RF_CUSTOM_SELECTED 0xff PACK(struct ModuleData { uint8_t type:4; int8_t rfProtocol:4; @@ -677,8 +679,10 @@ PACK(struct ModuleData { }; // Helper functions to set both of the rfProto protocol at the same time - inline uint8_t getMultiProtocol() + inline uint8_t getMultiProtocol(bool returnCustom) { + if (returnCustom && multi.customProto) + return MM_RF_CUSTOM_SELECTED; return ((uint8_t) (rfProtocol & 0x0f)) + (multi.rfProtocolExtra << 4); } diff --git a/radio/src/gui/212x64/model_setup.cpp b/radio/src/gui/212x64/model_setup.cpp index 783197e8f..a16fd1e95 100644 --- a/radio/src/gui/212x64/model_setup.cpp +++ b/radio/src/gui/212x64/model_setup.cpp @@ -695,11 +695,14 @@ 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)) { - uint8_t multi_rfProto = g_model.moduleData[EXTERNAL_MODULE].multi.customProto ? MM_RF_PROTO_CUSTOM : g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(); + int multi_rfProto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false); + if (g_model.moduleData[EXTERNAL_MODULE].multi.customProto) + multi_rfProto = MM_RF_PROTO_LAST + 1; // Custom proto has its string after all other valid protocols + // 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 lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+5*FW, y, STR_MULTI_PROTOCOLS, multi_rfProto, menuHorizontalPosition==1 ? attr : 0); - switch(multi_rfProto) { + 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; @@ -736,8 +739,8 @@ void menuModelSetup(event_t event) 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_CUSTOM: - lcdDrawNumber(MODEL_SETUP_2ND_COLUMN+14*FW, y, g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(), menuHorizontalPosition==2 ? attr : 0, 2); + 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; } @@ -758,15 +761,15 @@ void menuModelSetup(event_t event) CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, DSM2_PROTO_LP45, DSM2_PROTO_DSMX); #if defined(MULTIMODULE) else if (IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) { - uint8_t multiRfProto = g_model.moduleData[EXTERNAL_MODULE].multi.customProto == 1 ? MM_RF_PROTO_CUSTOM : g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(); + int multiRfProto = g_model.moduleData[EXTERNAL_MODULE].multi.customProto == 1 ? MM_RF_PROTO_CUSTOM : g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false); CHECK_INCDEC_MODELVAR(event, multiRfProto, MM_RF_PROTO_FIRST, MM_RF_PROTO_LAST); if (checkIncDec_Ret) { g_model.moduleData[EXTERNAL_MODULE].multi.customProto = (multiRfProto == MM_RF_PROTO_CUSTOM); if (!g_model.moduleData[EXTERNAL_MODULE].multi.customProto) g_model.moduleData[EXTERNAL_MODULE].setMultiProtocol(multiRfProto); g_model.moduleData[EXTERNAL_MODULE].subType = 0; - // Sensible default for DSM2 (same as for ppm): 6ch@22ms - if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol() == MM_RF_PROTO_DSM2) { + // Sensible default for DSM2 (same as for ppm): 7ch@22ms + Autodetect settings enabled + if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) == MM_RF_PROTO_DSM2) { g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode = 1; } else { g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode = 0; @@ -786,10 +789,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, 63, EE_MODEL)); + 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()) { + switch (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true)) { case MM_RF_PROTO_HISKY: case MM_RF_PROTO_SYMAX: case MM_RF_PROTO_KN: @@ -972,7 +975,7 @@ void menuModelSetup(event_t event) } #if defined(MULTIMODULE) else if (IS_MODULE_MULTIMODULE(moduleIdx)) { - switch (g_model.moduleData[moduleIdx].getMultiProtocol()) + switch ( g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true)) { case MM_RF_PROTO_FRSKY: case MM_RF_PROTO_SFHSS: @@ -988,7 +991,7 @@ void menuModelSetup(event_t event) lcdDrawTextAlignedLeft(y, STR_MULTI_OPTION); break; } - if (g_model.moduleData[moduleIdx].getMultiProtocol() != MM_RF_PROTO_DSM2) { + if (g_model.moduleData[moduleIdx].getMultiProtocol(true) != MM_RF_PROTO_DSM2) { lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, g_model.moduleData[moduleIdx].multi.optionValue, LEFT | attr); if (attr) { CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].multi.optionValue, -128, 127); @@ -1000,7 +1003,7 @@ void menuModelSetup(event_t event) } #if defined(MULTIMODULE) case ITEM_MODEL_EXTERNAL_MODULE_AUTOBIND: - if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol() == MM_RF_PROTO_DSM2) + if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) == MM_RF_PROTO_DSM2) g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode = editCheckBox(g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode, MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_DSM_AUTODTECT, attr, event); else g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode = editCheckBox(g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode, MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_AUTOBIND, attr, event); diff --git a/radio/src/gui/gui_common.h b/radio/src/gui/gui_common.h index f0f227261..95a583ae7 100644 --- a/radio/src/gui/gui_common.h +++ b/radio/src/gui/gui_common.h @@ -110,17 +110,17 @@ 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() != MM_RF_PROTO_DSM2)) ? (uint8_t)0 : (uint8_t)1) +#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_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()) ? (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()) ? (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) -#define MULTIMODULE_HASOPTIONS(x) (x == MM_RF_PROTO_HUBSAN || x == MM_RF_PROTO_FRSKY || x == MM_RF_PROTO_DSM2 ) -#define MULTIMODULE_FAILSAFEROWS(x) (IS_MODULE_MULTIMODULE(x) && (g_model.moduleData[x].multi.customProto || MULTIMODULE_HASOPTIONS(g_model.moduleData[x].getMultiProtocol()))) ? (uint8_t) 0: 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_CUSTOM_SELECTED) +#define MULTIMODULE_HASOPTIONS(x) (x == MM_RF_PROTO_HUBSAN || x == MM_RF_PROTO_FRSKY || x == MM_RF_PROTO_DSM2 || x == MM_RF_CUSTOM_SELECTED) +#define MULTIMODULE_FAILSAFEROWS(x) (IS_MODULE_MULTIMODULE(x) && (MULTIMODULE_HASOPTIONS(g_model.moduleData[x].getMultiProtocol(true)))) ? (uint8_t) 0: HIDDEN_ROW #else #define MULTIMODULE_MODULE_ROWS diff --git a/radio/src/myeeprom.h b/radio/src/myeeprom.h index 2ef219222..efd4fd9a0 100644 --- a/radio/src/myeeprom.h +++ b/radio/src/myeeprom.h @@ -498,8 +498,9 @@ enum RFProtocols { }; enum MultiModuleRFProtocols { + MM_RF_PROTO_CUSTOM = -1, + MM_RF_PROTO_FIRST = MM_RF_PROTO_CUSTOM, MM_RF_PROTO_FLYSKY=0, - MM_RF_PROTO_FIRST=MM_RF_PROTO_FLYSKY, MM_RF_PROTO_HUBSAN, MM_RF_PROTO_FRSKY, MM_RF_PROTO_HISKY, @@ -524,8 +525,7 @@ enum MultiModuleRFProtocols { MM_RF_PROTO_ASSAN, MM_RF_PROTO_HONTAI, MM_RF_PROTO_OLRS, - MM_RF_PROTO_CUSTOM, - MM_RF_PROTO_LAST= MM_RF_PROTO_CUSTOM + MM_RF_PROTO_LAST= MM_RF_PROTO_OLRS }; #define MM_RF_DSM2_SUBTYPE_DSM2_22 0 diff --git a/radio/src/opentx.h b/radio/src/opentx.h index 73f0deb91..4261d4ad7 100644 --- a/radio/src/opentx.h +++ b/radio/src/opentx.h @@ -387,17 +387,15 @@ void memswap(void * a, void * b, uint8_t size); #if defined(CPUARM) // Order is the same as in enum Protocols in myeeprom.h (none, ppm, xjt, dsm, crossfire, multi) - static const int8_t maxChannelsModules[] = { 0, 8, 8, -2, 8, 8 }; // relative to 8! + static const int8_t maxChannelsModules[] = { 0, 8, 8, -2, 8, 4 }; // relative to 8! static const int8_t maxChannelsXJT[] = { 0, 8, 0, 4 }; // relative to 8! #define MAX_TRAINER_CHANNELS_M8() (MAX_TRAINER_CHANNELS-8) #endif #if defined(MULTIMODULE) #define IS_MODULE_MULTIMODULE(idx) (idx==EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type==MODULE_TYPE_MULTIMODULE) - #define IS_MODULE_MULTIMODULE_DSM(idx) (IS_MODULE_MULTIMODULE(idx) && g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol() == MM_RF_PROTO_DSM2) #else #define IS_MODULE_MULTIMODULE(idx) (false) - #define IS_MODULE_MULTIMODULE_DSM(idx) (false) #endif #if defined(PCBTARANIS) || defined(PCBHORUS) @@ -425,7 +423,7 @@ void memswap(void * a, void * b, uint8_t size); #endif #define MAX_EXTERNAL_MODULE_CHANNELS() ((g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_XJT) ? maxChannelsXJT[1+g_model.moduleData[1].rfProtocol] : maxChannelsModules[g_model.moduleData[EXTERNAL_MODULE].type]) #define MAX_CHANNELS(idx) (idx==INTERNAL_MODULE ? MAX_INTERNAL_MODULE_CHANNELS() : (idx==EXTERNAL_MODULE ? MAX_EXTERNAL_MODULE_CHANNELS() : MAX_TRAINER_CHANNELS_M8())) - #define NUM_CHANNELS(idx) ((IS_MODULE_CROSSFIRE(idx) || (IS_MODULE_MULTIMODULE(idx) && !IS_MODULE_MULTIMODULE_DSM(idx))) ? CROSSFIRE_CHANNELS_COUNT : (8+g_model.moduleData[idx].channelsCount)) + #define NUM_CHANNELS(idx) ((IS_MODULE_CROSSFIRE(idx) || (IS_MODULE_MULTIMODULE(idx) && (g_model.moduleData[idx].getMultiProtocol(true) != MM_RF_PROTO_DSM2))) ? CROSSFIRE_CHANNELS_COUNT : (8+g_model.moduleData[idx].channelsCount)) #elif defined(PCBSKY9X) && !defined(REVA) #define IS_MODULE_PPM(idx) (idx==TRAINER_MODULE || idx==EXTRA_MODULE || (idx==EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type==MODULE_TYPE_PPM)) #define IS_MODULE_XJT(idx) (idx==EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type==MODULE_TYPE_XJT) @@ -442,7 +440,13 @@ void memswap(void * a, void * b, uint8_t size); #define MAX_CHANNELS(idx) (idx==EXTERNAL_MODULE ? MAX_EXTERNAL_MODULE_CHANNELS() : MAX_TRAINER_CHANNELS_M8()) #define NUM_CHANNELS(idx) (8+g_model.moduleData[idx].channelsCount) #endif + +#if defined(MULTIMODULE) +#define IS_MULTIMODULE_DSM(idx) (IS_MODULE_MULTIMODULE(idx) && g_model.moduleData[idx].getMultiProtocol(true) == MM_RF_PROTO_DSM2) +#define DEFAULT_CHANNELS(idx) (IS_MODULE_PPM(idx) ? 0 : IS_MULTIMODULE_DSM(idx) ? -1 : MAX_CHANNELS(idx)) +#else #define DEFAULT_CHANNELS(idx) (IS_MODULE_PPM(idx) ? 0 : MAX_CHANNELS(idx)) +#endif #if defined(CPUARM) #define MASK_CFN_TYPE uint64_t // current max = 64 function switches diff --git a/radio/src/pulses/multi_arm.cpp b/radio/src/pulses/multi_arm.cpp index 0ccaea301..020ef683a 100644 --- a/radio/src/pulses/multi_arm.cpp +++ b/radio/src/pulses/multi_arm.cpp @@ -115,7 +115,7 @@ void setupPulsesMultimodule(uint8_t port) // byte 1+2, protocol information // Our enumeration starts at 0 - int type = g_model.moduleData[port].getMultiProtocol() + 1; + int type = g_model.moduleData[port].getMultiProtocol(false) + 1; int subtype = g_model.moduleData[port].subType; int8_t optionValue = g_model.moduleData[port].multi.optionValue; @@ -126,11 +126,11 @@ void setupPulsesMultimodule(uint8_t port) protoByte |= MULTI_SEND_RANGECHECK; // rfProtocol - if (g_model.moduleData[port].getMultiProtocol() && g_model.moduleData[port].multi.autoBindMode && moduleFlag[port] == MODULE_BIND) { + if (g_model.moduleData[port].getMultiProtocol(true) == MM_RF_PROTO_DSM2 && g_model.moduleData[port].multi.autoBindMode && moduleFlag[port] == MODULE_BIND) { // Autobinding should always be done in DSMX 11ms subtype = MM_RF_DSM2_SUBTYPE_AUTO; - // The multi module wants the number of channels as options value and negative amout if the + // The multi module wants the number of channels as options value and negative amount if the // broken PRNG table is to be used. if (optionValue==0) optionValue = NUM_CHANNELS(EXTERNAL_MODULE); @@ -148,7 +148,7 @@ void setupPulsesMultimodule(uint8_t port) if (type >= 23) type = type + 1; - if (g_model.moduleData[port].getMultiProtocol() == MM_RF_PROTO_FRSKY) { + if (g_model.moduleData[port].getMultiProtocol(true) == MM_RF_PROTO_FRSKY) { if(subtype == MM_RF_FRSKY_SUBTYPE_D8) { //D8 type = 3; @@ -172,8 +172,13 @@ void setupPulsesMultimodule(uint8_t port) else sendByteMulti(0x54); - // (g_model.moduleData[port].multi.autoBindMode << 6) + + + protoByte |= (type & 0x1f); + if(g_model.moduleData[port].getMultiProtocol(true) != MM_RF_PROTO_DSM2) + protoByte |= (g_model.moduleData[port].multi.autoBindMode << 6); + sendByteMulti(protoByte); diff --git a/radio/src/telemetry/spektrum.cpp b/radio/src/telemetry/spektrum.cpp index dff161a16..00bf0c80c 100644 --- a/radio/src/telemetry/spektrum.cpp +++ b/radio/src/telemetry/spektrum.cpp @@ -347,7 +347,7 @@ void processSpektrumPacket(const uint8_t *packet) void processDSMBindPacket(const uint8_t *packet) { uint32_t debugval; - if (g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_MULTIMODULE && g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol() == MM_RF_PROTO_DSM2 + 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]; diff --git a/radio/src/telemetry/telemetry.h b/radio/src/telemetry/telemetry.h index eb66603f8..c426ed975 100644 --- a/radio/src/telemetry/telemetry.h +++ b/radio/src/telemetry/telemetry.h @@ -147,9 +147,9 @@ 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() == MM_RF_PROTO_DSM2) + if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false) == MM_RF_PROTO_DSM2) return PROTOCOL_SPEKTRUM; - else if ((g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol() == MM_RF_PROTO_FRSKY) && + 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