Rework DSM2/X support, auto protocol selection for DSM2

Support more than 31 protocols for the multi module. Breaks existing multi eeproms, need to reselect protocols
This commit is contained in:
Arne Schwabe
2016-10-16 22:17:38 +02:00
parent c592fed9f1
commit c055e93247
23 changed files with 198 additions and 182 deletions
+49 -63
View File
@@ -211,33 +211,14 @@ int getSwitchWarningsCount()
#define IF_INTERNAL_MODULE_ON(x) (g_model.moduleData[INTERNAL_MODULE].rfProtocol == RF_PROTO_OFF ? HIDDEN_ROW : (uint8_t)(x))
#endif
#define IF_EXTERNAL_MODULE_ON(x) (g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_NONE ? HIDDEN_ROW : (uint8_t)(x))
#define IF_TRAINER_ON(x) (g_model.trainerMode == TRAINER_MODE_SLAVE ? (uint8_t)(x) : HIDDEN_ROW)
#define IS_D8_RX(x) (g_model.moduleData[x].rfProtocol == RF_PROTO_D8)
#define IF_EXTERNAL_MODULE_XJT(x) (IS_MODULE_XJT(EXTERNAL_MODULE) ? (uint8_t)x : HIDDEN_ROW)
#define INTERNAL_MODULE_CHANNELS_ROWS IF_INTERNAL_MODULE_ON(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)) ? (uint8_t)0 : (uint8_t)1)
#define TRAINER_CHANNELS_ROWS() IF_TRAINER_ON(1)
#define PORT_CHANNELS_ROWS(x) (x==INTERNAL_MODULE ? INTERNAL_MODULE_CHANNELS_ROWS : (x==EXTERNAL_MODULE ? EXTERNAL_MODULE_CHANNELS_ROWS : TRAINER_CHANNELS_ROWS()))
#if defined MULTIMODULE
#define MULTIMODULE_HASOPTIONS(x) (x == MM_RF_PROTO_HUBSAN || x == MM_RF_PROTO_FRSKY || x == MM_RF_PROTO_DSM2 || x == MM_RF_PROTO_SFHSS || x >= MM_RF_PROTO_CUSTOM)
#define MULTIMODULE_FAILSAFEROWS(x) (IS_MODULE_MULTIMODULE(x) && (MULTIMODULE_HASOPTIONS(g_model.moduleData[x].multi.rfProtocol))) ? (uint8_t) 0: HIDDEN_ROW
#else
#define MULTIMODULE_FAILSAFEROWS(x) HIDDEN_ROW
#endif
#define FAILSAFE_ROWS(x) (IS_MODULE_XJT(x) && HAS_RF_PROTOCOL_FAILSAFE(g_model.moduleData[x].rfProtocol) ? (g_model.moduleData[x].failsafeMode==FAILSAFE_CUSTOM ? (uint8_t)1 : (uint8_t)0) : MULTIMODULE_FAILSAFEROWS(x))
#define TIMER_ROWS(x) 2|NAVIGATION_LINE_BY_LINE, 0, 0, 0, g_model.timers[x].countdownBeep != COUNTDOWN_SILENT ? (uint8_t) 1 : (uint8_t)0
#if defined(MULTIMODULE)
#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)
#define MULTIMODULE_MODE_ROWS(x) (g_model.moduleData[x].multi.rfProtocol >= MM_RF_PROTO_CUSTOM ) ? (uint8_t) 3 :MULTIMODULE_HAS_SUBTYPE(g_model.moduleData[x].multi.rfProtocol) ? (uint8_t)2 : (uint8_t)1
#define MULTIMODULE_MODULE_ROWS IS_MODULE_MULTIMODULE(EXTERNAL_MODULE) ? (uint8_t) 0 : HIDDEN_ROW, IS_MODULE_MULTIMODULE(EXTERNAL_MODULE) ? (uint8_t) 0 : HIDDEN_ROW,
#else
#define MULTIMODULE_MODE_ROWS(x) (uint8_t)0
#define MULTIMODULE_MODULE_ROWS
#endif
#define EXTERNAL_MODULE_MODE_ROWS (IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : IS_MODULE_MULTIMODULE(EXTERNAL_MODULE) ? MULTIMODULE_MODE_ROWS(EXTERNAL_MODULE) : (uint8_t)0
#if TIMERS == 1
@@ -714,7 +695,7 @@ 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 = min(g_model.moduleData[EXTERNAL_MODULE].multi.rfProtocol, (uint8_t) MM_RF_PROTO_CUSTOM);
uint8_t multi_rfProto = g_model.moduleData[EXTERNAL_MODULE].multi.customProto ? MM_RF_PROTO_CUSTOM : g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol();
// 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);
@@ -729,7 +710,7 @@ void menuModelSetup(event_t event)
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+11*FW, y, STR_DSM_PROTOCOLS, g_model.moduleData[EXTERNAL_MODULE].subType+1, menuHorizontalPosition==2 ? attr : 0);
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);
@@ -756,7 +737,7 @@ void menuModelSetup(event_t event)
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].multi.rfProtocol & 0x1f, menuHorizontalPosition==2 ? attr : 0, 2);
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN+14*FW, y, g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(), 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;
}
@@ -777,19 +758,20 @@ 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)) {
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].multi.rfProtocol, MM_RF_PROTO_FIRST, MM_RF_PROTO_LAST);
uint8_t multiRfProto = g_model.moduleData[EXTERNAL_MODULE].multi.customProto == 1 ? MM_RF_PROTO_CUSTOM : g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol();
CHECK_INCDEC_MODELVAR(event, multiRfProto, MM_RF_PROTO_FIRST, MM_RF_PROTO_LAST);
if (checkIncDec_Ret) {
// When in custom protocol mode the highest bit (0x20) is set to indicate the protocl we might be way above MM_RF_PROTO_LAST.
// Reset to MM_RF_PROTO_LAST-1 in that case
if (checkIncDec_Ret == -1 && g_model.moduleData[EXTERNAL_MODULE].multi.rfProtocol >= MM_RF_PROTO_LAST) {
g_model.moduleData[EXTERNAL_MODULE].multi.rfProtocol = MM_RF_PROTO_LAST-1;
}
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].multi.rfProtocol == MM_RF_PROTO_DSM2)
g_model.moduleData[EXTERNAL_MODULE].multi.optionValue = MM_RF_DSM2_22MS_6CH_OPTION;
else
g_model.moduleData[EXTERNAL_MODULE].multi.optionValue = 0;
if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol() == MM_RF_PROTO_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;
}
}
#endif
@@ -803,33 +785,34 @@ void menuModelSetup(event_t event)
break;
#if defined(MULTIMODULE)
case 2:
switch (min(g_model.moduleData[EXTERNAL_MODULE].multi.rfProtocol, (uint8_t) MM_RF_PROTO_CUSTOM)) {
case MM_RF_PROTO_HISKY:
case MM_RF_PROTO_DSM2:
case MM_RF_PROTO_SYMAX:
case MM_RF_PROTO_KN:
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_FLYSKY:
case MM_RF_PROTO_MT99XX:
case MM_RF_PROTO_FRSKY:
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, 3);
break;
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;
case MM_RF_PROTO_CUSTOM:
//custom protocol using the highest bit 0x20 to indicate that the protocol and the lower bits as the rfProtocol
g_model.moduleData[EXTERNAL_MODULE].multi.rfProtocol = 0x20 | checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].multi.rfProtocol & 0x1f, 1, 31, EE_MODEL);
break;
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));
break;
} else {
switch (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol()) {
case MM_RF_PROTO_HISKY:
case MM_RF_PROTO_SYMAX:
case MM_RF_PROTO_KN:
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_FLYSKY:
case MM_RF_PROTO_MT99XX:
case MM_RF_PROTO_FRSKY:
case MM_RF_PROTO_DSM2:
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, 3);
break;
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;
}
}
break;
case 3:
@@ -989,7 +972,7 @@ void menuModelSetup(event_t event)
}
#if defined(MULTIMODULE)
else if (IS_MODULE_MULTIMODULE(moduleIdx)) {
switch (g_model.moduleData[moduleIdx].multi.rfProtocol)
switch (g_model.moduleData[moduleIdx].getMultiProtocol())
{
case MM_RF_PROTO_FRSKY:
case MM_RF_PROTO_SFHSS:
@@ -999,13 +982,13 @@ void menuModelSetup(event_t event)
lcdDrawTextAlignedLeft(y, STR_MULTI_VIDFREQ);
break;
case MM_RF_PROTO_DSM2:
g_model.moduleData[moduleIdx].multi.optionValue = editChoice(MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_DSMFRAME, STR_OPTIONS_DSM, g_model.moduleData[moduleIdx].multi.optionValue, 0, 12, attr, event);
g_model.moduleData[EXTERNAL_MODULE].multi.optionValue = editCheckBox(g_model.moduleData[EXTERNAL_MODULE].multi.optionValue, MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_DSMPRNG, attr, event);
break;
default:
lcdDrawTextAlignedLeft(y, STR_MULTI_OPTION);
break;
}
if (g_model.moduleData[moduleIdx].multi.rfProtocol != MM_RF_PROTO_DSM2) {
if (g_model.moduleData[moduleIdx].getMultiProtocol() != 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);
@@ -1017,7 +1000,10 @@ void menuModelSetup(event_t event)
}
#if defined(MULTIMODULE)
case ITEM_MODEL_EXTERNAL_MODULE_AUTOBIND:
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);
if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol() == 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);
break;
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);