1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-24 00:35:18 +03:00

Schwabe/multimodule 9x (#3676)

* Fix Multimodule showing up as Crossfire when only multimode and not crossfire is enabled.

* Don't hardcode telemetry to be Frysky on non STM32 arm targets

* Port multi module code to 9X platforms

* Allow Spektrum telemetry protocol to be selected as protocol for the telemetry selection

* Fix infinite loop in spektrum code

* Fix cosmetics

Changes also done for Horus and Taranis UI where appropriate
This commit is contained in:
Arne Schwabe 2016-08-02 18:21:18 +02:00 committed by Bertrand Songis
parent d0527be2c4
commit 0b67d412a0
26 changed files with 392 additions and 115 deletions

View file

@ -58,12 +58,19 @@ enum menuModelSetupItems {
#if defined(CPUARM)
ITEM_MODEL_EXTERNAL_MODULE_LABEL,
ITEM_MODEL_EXTERNAL_MODULE_MODE,
#if defined(MULTIMODULE)
ITEM_MODEL_EXTERNAL_MODULE_SUBTYPE,
#endif
ITEM_MODEL_EXTERNAL_MODULE_CHANNELS,
ITEM_MODEL_EXTERNAL_MODULE_BIND,
#if defined(PCBSKY9X) && defined(REVX)
ITEM_MODEL_EXTERNAL_MODULE_OUTPUT_TYPE,
#endif
ITEM_MODEL_EXTERNAL_MODULE_FAILSAFE,
#if defined(MULTIMODULE)
ITEM_MODEL_EXTERNAL_MODULE_AUTOBIND,
ITEM_MODEL_EXTERNAL_MODULE_LOWPOWER,
#endif
#if defined(PCBSKY9X) && !defined(REVA)
ITEM_MODEL_EXTRA_MODULE_LABEL,
ITEM_MODEL_EXTRA_MODULE_CHANNELS,
@ -99,16 +106,39 @@ void menuModelSetup(uint8_t event)
#define IF_EXTERNAL_MODULE_XJT(x) (IS_MODULE_XJT(EXTERNAL_MODULE) ? (uint8_t)(x) : HIDDEN_ROW)
#define IF_EXTERNAL_MODULE_ON(x) (g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_NONE ? HIDDEN_ROW : (uint8_t)(x))
#define IS_D8_RX(x) (g_model.moduleData[x].rfProtocol == RF_PROTO_D8)
#define EXTERNAL_MODULE_CHANNELS_ROWS() IF_EXTERNAL_MODULE_ON(IS_MODULE_DSM2(EXTERNAL_MODULE) ? (uint8_t)0 : (uint8_t)1)
#define EXTERNAL_MODULE_SETTINGS_ROWS() (IS_MODULE_XJT(EXTERNAL_MODULE) && IS_D8_RX(EXTERNAL_MODULE)) ? (uint8_t)1 : (IS_MODULE_PPM(EXTERNAL_MODULE) || IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW
#define EXTERNAL_MODULE_CHANNELS_ROWS IF_EXTERNAL_MODULE_ON((IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) ? (uint8_t)0 : (uint8_t)1)
#define EXTERNAL_MODULE_BIND_ROWS() (IS_MODULE_XJT(EXTERNAL_MODULE) && IS_D8_RX(EXTERNAL_MODULE)) ? (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 defined(PCBSKY9X) && defined(REVX)
#define OUTPUT_TYPE_ROWS() (IS_MODULE_PPM(EXTERNAL_MODULE) ? (uint8_t)0 : HIDDEN_ROW) ,
#else
#define OUTPUT_TYPE_ROWS()
#endif
#define TRAINER_CHANNELS_ROWS() (HIDDEN_ROW)
#define PORT_CHANNELS_ROWS(x) (x==EXTERNAL_MODULE ? EXTERNAL_MODULE_CHANNELS_ROWS() : 0)
#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) : HIDDEN_ROW)
#define PORT_CHANNELS_ROWS(x) (x==EXTERNAL_MODULE ? EXTERNAL_MODULE_CHANNELS_ROWS : 0)
#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))
#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,
#define MULTIMODULE_RFPROTO_ROWS(x) (g_model.moduleData[x].multi.rfProtocol >= MM_RF_PROTO_CUSTOM) ? (uint8_t) 1 :MULTIMODULE_HAS_SUBTYPE(g_model.moduleData[x].multi.rfProtocol) ? (uint8_t) 0 : HIDDEN_ROW
#define MULTIMODULE_SUBTYPE_ROWS(x) IS_MODULE_MULTIMODULE(x) ? MULTIMODULE_RFPROTO_ROWS(x) : HIDDEN_ROW,
#else
#define MULTIMODULE_MODE_ROWS(x) (uint8_t)0
#define MULTIMODULE_MODULE_ROWS
#define MULTIMODULE_SUBTYPE_ROWS(x)
#endif
#define EXTERNAL_MODULE_MODE_ROWS (IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0
#define CURSOR_ON_CELL (true)
#define MODEL_SETUP_MAX_LINES (1+ITEM_MODEL_SETUP_MAX)
#define POT_WARN_ITEMS() ((g_model.nPotsToWarn >> 6) ? (uint8_t)NUM_POTS : (uint8_t)0)
@ -121,11 +151,13 @@ void menuModelSetup(uint8_t event)
#define TRAINER_MODULE_ROWS
MENU_TAB({ 0, 0, TIMER_ROWS, TIMER_ROWS, TIMER_ROWS, 0, 1, 0, 0, 0, 0, 0, CASE_CPUARM(LABEL(PreflightCheck)) CASE_CPUARM(0) 0, 6, NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1, 0,
LABEL(ExternalModule),
(IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0,
EXTERNAL_MODULE_CHANNELS_ROWS(),
EXTERNAL_MODULE_SETTINGS_ROWS(),
EXTERNAL_MODULE_MODE_ROWS,
MULTIMODULE_SUBTYPE_ROWS(EXTERNAL_MODULE)
EXTERNAL_MODULE_CHANNELS_ROWS,
EXTERNAL_MODULE_BIND_ROWS(),
OUTPUT_TYPE_ROWS()
FAILSAFE_ROWS(EXTERNAL_MODULE),
MULTIMODULE_MODULE_ROWS
EXTRA_MODULE_ROWS
TRAINER_MODULE_ROWS });
#elif defined(CPUM64)
@ -502,6 +534,12 @@ void menuModelSetup(uint8_t event)
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+5*FW, y, STR_XJT_PROTOCOLS, 1+g_model.moduleData[EXTERNAL_MODULE].rfProtocol, menuHorizontalPosition==1 ? attr : 0);
else if (IS_MODULE_DSM2(EXTERNAL_MODULE))
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+5*FW, 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);
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+5*FW, y, STR_MULTI_PROTOCOLS, multi_rfProto, menuHorizontalPosition==1 ? attr : 0);
}
#endif
if (attr && (editMode>0 || p1valdiff)) {
switch (menuHorizontalPosition) {
case 0:
@ -518,8 +556,27 @@ void menuModelSetup(uint8_t event)
case 1:
if (IS_MODULE_DSM2(EXTERNAL_MODULE))
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, DSM2_PROTO_LP45, DSM2_PROTO_DSMX);
else
#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);
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].subType = 0;
// Sensible default for DSM2 (same as for ppm): 6ch@11ms
if (g_model.moduleData[EXTERNAL_MODULE].multi.rfProtocol == MM_RF_PROTO_DSM2)
g_model.moduleData[EXTERNAL_MODULE].multi.optionValue = MM_RF_DSM2_11MS_6CH_OPTION;
else
g_model.moduleData[EXTERNAL_MODULE].multi.optionValue = 0;
}
}
#endif
else {
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, RF_PROTO_X16, RF_PROTO_LAST);
}
if (checkIncDec_Ret) {
g_model.moduleData[EXTERNAL_MODULE].channelsStart = 0;
g_model.moduleData[EXTERNAL_MODULE].channelsCount = MAX_EXTERNAL_MODULE_CHANNELS();
@ -528,7 +585,90 @@ void menuModelSetup(uint8_t event)
}
break;
#endif
#if defined (MULTIMODULE)
case ITEM_MODEL_EXTERNAL_MODULE_SUBTYPE:
{
lcd_putsLeft(y, STR_SUBTYPE);
int8_t multi_rfProto = min<int8_t>(g_model.moduleData[EXTERNAL_MODULE].multi.rfProtocol, (uint8_t) MM_RF_PROTO_CUSTOM);
switch (multi_rfProto) {
case MM_RF_PROTO_FLYSKY:
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_SUBTYPE_FLYSKY, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition == 0 ? attr : 0);
break;
case MM_RF_PROTO_FRSKY:
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_SUBTYPE_FRSKY, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition == 0 ? attr : 0);
break;
case MM_RF_PROTO_HISKY:
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_SUBTYPE_HISKY, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition == 0 ? attr : 0);
break;
case MM_RF_PROTO_DSM2:
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_DSM_PROTOCOLS, g_model.moduleData[EXTERNAL_MODULE].subType + 1, menuHorizontalPosition == 0 ? attr : 0);
break;
case MM_RF_PROTO_YD717:
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_SUBTYPE_YD717, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition == 0 ? attr : 0);
break;
case MM_RF_PROTO_KN:
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_SUBTYPE_KN, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition == 0 ? attr : 0);
break;
case MM_RF_PROTO_SYMAX:
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_SUBTYPE_SYMAX, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition == 0 ? attr : 0);
break;
case MM_RF_PROTO_CX10:
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_SUBTYPE_CX10, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition == 0 ? attr : 0);
break;
case MM_RF_PROTO_CG023:
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_SUBTYPE_CG023, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition == 0 ? attr : 0);
break;
case MM_RF_PROTO_MT99XX:
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_SUBTYPE_MT99, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition == 0 ? attr : 0);
break;
case MM_RF_PROTO_MJXQ:
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_SUBTYPE_MJXQ, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition == 0 ? attr : 0);
break;
case MM_RF_PROTO_CUSTOM:
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN + 3 * FW, y, g_model.moduleData[EXTERNAL_MODULE].multi.rfProtocol & 0x1f, menuHorizontalPosition == 0 ? attr : 0, 2);
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN + 5 * FW, y, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition == 1 ? attr : 0, 2);
break;
}
if (attr && (editMode > 0 || p1valdiff)) {
switch (menuHorizontalPosition) {
case 0:
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:
case MM_RF_PROTO_MT99XX:
case MM_RF_PROTO_FRSKY:
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, 2);
break;
case MM_RF_PROTO_FLYSKY:
case MM_RF_PROTO_MJXQ:
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, 3);
break;
case MM_RF_PROTO_YD717:
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_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;
}
break;
case 1:
// Custom protocol, third column is subtype
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, 7);
break;
}
}
}
break;
#endif
#if defined(PCBSKY9X)
case ITEM_MODEL_EXTRA_MODULE_CHANNELS:
#endif
@ -602,11 +742,11 @@ void menuModelSetup(uint8_t event)
else {
lcd_putsLeft(y, STR_RECEIVER_NUM);
}
if (IS_MODULE_XJT(moduleIdx) || IS_MODULE_DSM2(moduleIdx)) {
if (IS_MODULE_XJT(moduleIdx) || IS_MODULE_DSM2(moduleIdx) || IS_MODULE_MULTIMODULE(moduleIdx)) {
if (xOffsetBind) lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, g_model.header.modelId[moduleIdx], (l_posHorz==0 ? attr : 0) | LEADING0|LEFT, 2);
if (attr && l_posHorz==0) {
if (editMode>0 || p1valdiff) {
CHECK_INCDEC_MODELVAR_ZERO(event, g_model.header.modelId[moduleIdx], IS_MODULE_DSM2(moduleIdx) ? 20 : 63);
CHECK_INCDEC_MODELVAR_ZERO(event, g_model.header.modelId[moduleIdx], IS_MODULE_DSM2(moduleIdx) ? 20 : IS_MODULE_MULTIMODULE(moduleIdx) ? 15 : 63);
if (checkIncDec_Ret) {
modelHeaders[g_eeGeneral.currModel].modelId[moduleIdx] = g_model.header.modelId[moduleIdx];
}
@ -646,34 +786,72 @@ void menuModelSetup(uint8_t event)
case ITEM_MODEL_EXTERNAL_MODULE_FAILSAFE:
{
uint8_t moduleIdx = CURRENT_MODULE_EDITED(k);
ModuleData & moduleData = g_model.moduleData[moduleIdx];
lcd_putsLeft(y, TR_FAILSAFE);
ModuleData &moduleData = g_model.moduleData[moduleIdx];
if (IS_MODULE_XJT(moduleIdx)) {
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_VFAILSAFE, moduleData.failsafeMode, menuHorizontalPosition==0 ? attr : 0);
if (moduleData.failsafeMode == FAILSAFE_CUSTOM) lcdDrawText(MODEL_SETUP_2ND_COLUMN + MODEL_SETUP_SET_FAILSAFE_OFS, y, STR_SET, menuHorizontalPosition==1 ? attr : 0);
lcd_putsLeft(y, TR_FAILSAFE);
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_VFAILSAFE, moduleData.failsafeMode, menuHorizontalPosition == 0
? attr : 0);
if (moduleData.failsafeMode == FAILSAFE_CUSTOM)
lcdDrawText(MODEL_SETUP_2ND_COLUMN + MODEL_SETUP_SET_FAILSAFE_OFS, y, STR_SET, menuHorizontalPosition == 1
? attr : 0);
if (attr) {
if (moduleData.failsafeMode != FAILSAFE_CUSTOM)
menuHorizontalPosition = 0;
if (menuHorizontalPosition==0) {
if (editMode>0 || p1valdiff) {
if (menuHorizontalPosition == 0) {
if (editMode > 0 || p1valdiff) {
CHECK_INCDEC_MODELVAR_ZERO(event, moduleData.failsafeMode, FAILSAFE_LAST);
if (checkIncDec_Ret) SEND_FAILSAFE_NOW(moduleIdx);
}
}
else if (menuHorizontalPosition==1) {
else if (menuHorizontalPosition == 1) {
s_editMode = 0;
if (moduleData.failsafeMode==FAILSAFE_CUSTOM && event==EVT_KEY_FIRST(KEY_ENTER)) {
if (moduleData.failsafeMode == FAILSAFE_CUSTOM && event == EVT_KEY_FIRST(KEY_ENTER)) {
g_moduleIdx = moduleIdx;
pushMenu(menuModelFailsafe);
}
}
else {
lcdDrawFilledRect(MODEL_SETUP_2ND_COLUMN, y, LCD_W-MODEL_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH, 8);
lcdDrawFilledRect(MODEL_SETUP_2ND_COLUMN, y, LCD_W - MODEL_SETUP_2ND_COLUMN - MENUS_SCROLLBAR_WIDTH, 8);
}
}
}
break;
#if defined(MULTIMODULE)
else if (IS_MODULE_MULTIMODULE(moduleIdx)) {
switch (g_model.moduleData[moduleIdx].multi.rfProtocol)
{
case MM_RF_PROTO_FRSKY:
case MM_RF_PROTO_SFHSS:
lcd_putsLeft(y, STR_MULTI_RFTUNE);
break;
case MM_RF_PROTO_HUBSAN:
lcd_putsLeft(y, STR_MULTI_VIDFREQ);
break;
case MM_RF_PROTO_DSM2:
g_model.moduleData[moduleIdx].multi.optionValue = selectMenuItem(MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_DSMFRAME, STR_OPTIONS_DSM, g_model.moduleData[moduleIdx].multi.optionValue, 0, 12, attr, event);
break;
default:
lcd_putsLeft(y, STR_MULTI_OPTION);
break;
}
if (g_model.moduleData[moduleIdx].multi.rfProtocol != 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);
}
}
}
#endif
}
break;
#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);
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);
break;
#endif
#endif
#if !defined(CPUARM)

View file

@ -553,7 +553,9 @@ void menuModelTelemetry(uint8_t event)
switch (k) {
#if defined(CPUARM)
case ITEM_TELEMETRY_PROTOCOL_TYPE:
g_model.telemetryProtocol = selectMenuItem(TELEM_COL2, y, STR_TELEMETRY_TYPE, "\017FrSky S.PORT\0 FrSky D\0 FrSky D (cable)", g_model.telemetryProtocol, PROTOCOL_TELEMETRY_FIRST, CASE_PCBSKY9X(PROTOCOL_FRSKY_D_SECONDARY) attr, event);
lcd_putsLeft(y, STR_TELEMETRY_TYPE);
lcdDrawTextAtIndex(TELEM_COL2, y, STR_TELEMETRY_PROTOCOLS, g_model.telemetryProtocol, attr);
g_model.telemetryProtocol = checkIncDec(event, g_model.telemetryProtocol, PROTOCOL_TELEMETRY_FIRST, PROTOCOL_TELEMETRY_LAST, EE_MODEL, isTelemetryProtocolAvailable);
break;
#if defined(REVX)
case ITEM_TELEMETRY_INVERTED_SERIAL:

View file

@ -80,7 +80,7 @@ enum menuModelSetupItems {
ITEM_MODEL_EXTERNAL_MODULE_CHANNELS,
ITEM_MODEL_EXTERNAL_MODULE_BIND,
ITEM_MODEL_EXTERNAL_MODULE_FAILSAFE,
#ifdef MULTIMODULE
#if defined (MULTIMODULE)
ITEM_MODEL_EXTERNAL_MODULE_AUTOBIND,
ITEM_MODEL_EXTERNAL_MODULE_LOWPOWER,
#endif
@ -715,7 +715,7 @@ void menuModelSetup(uint8_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)) {
int8_t multi_rfProto = min(g_model.moduleData[EXTERNAL_MODULE].multi.rfProtocol, (uint8_t) MM_RF_PROTO_CUSTOM);
uint8_t multi_rfProto = min(g_model.moduleData[EXTERNAL_MODULE].multi.rfProtocol, (uint8_t) MM_RF_PROTO_CUSTOM);
// 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);
@ -773,25 +773,27 @@ void menuModelSetup(uint8_t event)
case 1:
if (IS_MODULE_DSM2(EXTERNAL_MODULE))
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);
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)
{
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].subType = 0;
// Sensible default for DSM2 (same as for ppm): 6ch@11ms
if (g_model.moduleData[EXTERNAL_MODULE].multi.rfProtocol == MM_RF_PROTO_DSM2)
g_model.moduleData[EXTERNAL_MODULE].multi.optionValue = 6;
g_model.moduleData[EXTERNAL_MODULE].multi.optionValue = MM_RF_DSM2_11MS_6CH_OPTION;
else
g_model.moduleData[EXTERNAL_MODULE].multi.optionValue = 0;
}
}
else
#endif
else {
g_model.moduleData[EXTERNAL_MODULE].rfProtocol = checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, RF_PROTO_X16, RF_PROTO_LAST, EE_MODEL, isRfProtocolAvailable);
}
if (checkIncDec_Ret) {
g_model.moduleData[EXTERNAL_MODULE].channelsStart = 0;
g_model.moduleData[EXTERNAL_MODULE].channelsCount = 0;
@ -978,7 +980,8 @@ void menuModelSetup(uint8_t event)
}
#if defined(MULTIMODULE)
else if (IS_MODULE_MULTIMODULE(moduleIdx)) {
switch (g_model.moduleData[moduleIdx].multi.rfProtocol) {
switch (g_model.moduleData[moduleIdx].multi.rfProtocol)
{
case MM_RF_PROTO_FRSKY:
case MM_RF_PROTO_SFHSS:
lcd_putsLeft(y, STR_MULTI_RFTUNE);

View file

@ -433,7 +433,7 @@ void menuModelTelemetry(uint8_t event)
lcdDrawText(TELEM_COL2, y, "---", 0); // TODO shortcut
}
TelemetrySensor * sensor = & g_model.telemetrySensors[index];
#ifdef MULTIMODULE
#if defined(MULTIMODULE)
if (IS_SPEKTRUM_PROTOCOL()) {
// Spektrum does not (yet?) really support multiple sensor of the same type. But a lot of
// different sensor display the same information (e.g. voltage, capacity). Show the id
@ -463,7 +463,9 @@ void menuModelTelemetry(uint8_t event)
switch (k) {
case ITEM_TELEMETRY_PROTOCOL_TYPE:
g_model.telemetryProtocol = selectMenuItem(TELEM_COL2, y, STR_TELEMETRY_TYPE, "\017FrSky S.PORT\0 FrSky D\0 FrSky D (cable)", g_model.telemetryProtocol, PROTOCOL_TELEMETRY_FIRST, g_eeGeneral.serial2Mode==UART_MODE_TELEMETRY ? PROTOCOL_FRSKY_D_SECONDARY : PROTOCOL_FRSKY_D, attr, event);
lcd_putsLeft(y, STR_TELEMETRY_TYPE);
lcdDrawTextAtIndex(TELEM_COL2, y, STR_TELEMETRY_PROTOCOLS, g_model.telemetryProtocol, attr);
g_model.telemetryProtocol = checkIncDec(event, g_model.telemetryProtocol, PROTOCOL_TELEMETRY_FIRST, PROTOCOL_TELEMETRY_LAST, EE_MODEL, isTelemetryProtocolAvailable);
break;
case ITEM_TELEMETRY_SENSORS_LABEL:

View file

@ -597,7 +597,7 @@ bool menuModelSetup(evt_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)) {
int8_t multi_rfProto = min(g_model.moduleData[EXTERNAL_MODULE].multi.rfProtocol, (uint8_t) MM_RF_PROTO_CUSTOM);
uint8_t multi_rfProto = min(g_model.moduleData[EXTERNAL_MODULE].multi.rfProtocol, (uint8_t) MM_RF_PROTO_CUSTOM);
lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_MULTI_PROTOCOLS, multi_rfProto, menuHorizontalPosition==1 ? attr : 0);
switch(multi_rfProto) {
@ -662,20 +662,20 @@ bool menuModelSetup(evt_t event)
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)
{
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].subType = 0;
// Sensible default for DSM2 (same as for ppm): 6ch@11ms
if (g_model.moduleData[EXTERNAL_MODULE].multi.rfProtocol == MM_RF_PROTO_DSM2)
g_model.moduleData[EXTERNAL_MODULE].multi.optionValue = 6;
g_model.moduleData[EXTERNAL_MODULE].multi.optionValue = MM_RF_DSM2_11MS_6CH_OPTION;
else
g_model.moduleData[EXTERNAL_MODULE].multi.optionValue = 0;
}
}
else
else {
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, RF_PROTO_X16, RF_PROTO_LAST);
}
if (checkIncDec_Ret) {
g_model.moduleData[EXTERNAL_MODULE].channelsStart = 0;
g_model.moduleData[EXTERNAL_MODULE].channelsCount = MAX_EXTERNAL_MODULE_CHANNELS();
@ -846,7 +846,8 @@ bool menuModelSetup(evt_t event)
}
#if defined(MULTIMODULE)
else if (IS_MODULE_MULTIMODULE(moduleIdx)) {
switch (g_model.moduleData[moduleIdx].multi.rfProtocol) {
switch (g_model.moduleData[moduleIdx].multi.rfProtocol)
{
case MM_RF_PROTO_FRSKY:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MULTI_RFTUNE);
break;

View file

@ -436,7 +436,7 @@ bool menuModelTelemetry(evt_t event)
lcdDrawText(TELEM_COL2, y, "---"); // TODO shortcut
}
TelemetrySensor * sensor = & g_model.telemetrySensors[index];
#ifdef MULTIMODULE
#if defined(MULTIMODULE)
if (IS_SPEKTRUM_PROTOCOL()) {
// Spektrum does not (yet?) really support multiple sensor of the same type. But a lot of
// different sensor display the same information (e.g. voltage, capacity). Show the id
@ -467,7 +467,8 @@ bool menuModelTelemetry(evt_t event)
switch (k) {
case ITEM_TELEMETRY_PROTOCOL_TYPE:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_TELEMETRY_TYPE);
g_model.telemetryProtocol = selectMenuItem(TELEM_COL2, y, "\017FrSky S.PORT\0 FrSky D\0 FrSky D (cable)", g_model.telemetryProtocol, PROTOCOL_TELEMETRY_FIRST, PROTOCOL_FRSKY_D, attr, event);
lcdDrawTextAtIndex(TELEM_COL2, y, STR_TELEMETRY_PROTOCOLS, g_model.telemetryProtocol, attr);
g_model.telemetryProtocol = checkIncDec(event, g_model.telemetryProtocol, PROTOCOL_TELEMETRY_FIRST, PROTOCOL_TELEMETRY_LAST, EE_MODEL, isTelemetryProtocolAvailable);
break;
case ITEM_TELEMETRY_SENSORS_LABEL:

View file

@ -47,6 +47,7 @@ bool isSwitchAvailableInMixes(int swtch);
bool isSwitchAvailableInTimers(int swtch);
bool isModuleAvailable(int module);
bool isRfProtocolAvailable(int protocol);
bool isTelemetryProtocolAvailable(int protocol);
bool isTrainerModeAvailable(int mode);
bool isSensorUnit(int sensor, uint8_t unit);

View file

@ -482,22 +482,30 @@ bool isSourceAvailableInResetSpecialFunction(int index)
}
}
#if defined(PCBFLAMENCO)
bool isModuleAvailable(int module)
{
return true;
}
#else
bool isModuleAvailable(int module)
{
#if defined(CROSSFIRE)
if (module == MODULE_TYPE_CROSSFIRE && g_model.moduleData[INTERNAL_MODULE].rfProtocol != RF_PROTO_OFF) {
return false;
}
#else
if (module == MODULE_TYPE_CROSSFIRE) {
return false;
}
#endif
#if !defined(DSM2)
if (module == MODULE_TYPE_DSM2) {
return false;
}
#endif
#if !defined(MULTIMODULE)
if (module == MODULE_TYPE_MULTIMODULE) {
return false;
}
#endif
return true;
}
#endif
bool isRfProtocolAvailable(int protocol)
{
@ -514,6 +522,30 @@ bool isRfProtocolAvailable(int protocol)
return true;
}
#if defined(CPUARM)
bool isTelemetryProtocolAvailable(int protocol)
{
#if defined(PCBTARANIS)
if(protocol == PROTOCOL_FRSKY_D_SECONDARY && g_eeGeneral.serial2Mode != UART_MODE_TELEMETRY)
return false;
#endif
if (protocol== PROTOCOL_PULSES_CROSSFIRE)
return false;
#if !defined(MULTIMODULE)
if (protocol== PROTOCOL_SPEKTRUM)
return false;
#endif
#if defined(PBHORUS)
if (protocol == PROTOCOL_FRSKY_D_SECONDARY)
return false;
#endif
return true;
}
#endif
#if defined(PCBHORUS)
bool isTrainerModeAvailable(int mode)
{