1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-25 01:05:10 +03:00

Schwabe/multi telemetry (#4151)

* 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
This commit is contained in:
Arne Schwabe 2016-12-24 00:04:11 +01:00 committed by Bertrand Songis
parent d1ef22ee47
commit 06b0694f03
37 changed files with 888 additions and 423 deletions

View file

@ -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;

View file

@ -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:

View file

@ -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()
@ -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
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));
break;
}
break;
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);
@ -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;
@ -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);
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;
break;
default:
lcdDrawTextAlignedLeft(y, STR_MULTI_OPTION);
break;
}
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

View file

@ -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

View file

@ -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)
if (g_model.moduleData[EXTERNAL_MODULE].multi.customProto) {
lcdDrawText(MODEL_SETUP_2ND_COLUMN + 5 * FW, y, STR_MULTI_CUSTOM, menuHorizontalPosition == 1 ? attr : 0);
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;
}
else {
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+5*FW, y, STR_MULTI_PROTOCOLS, multi_rfProto, menuHorizontalPosition==1 ? attr : 0);
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);
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;
break;
default:
lcdDrawTextAlignedLeft(y, STR_MULTI_OPTION);
break;
}
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
}
}

View file

@ -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)
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);
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, 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);
break;
} else {
const mm_protocol_definition *pdef = getMultiProtocolDefinition(multi_rfProto);
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);
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;
break;
default:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MULTI_OPTION);
break;
}
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
}
}

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -189,24 +189,27 @@ void setupPulsesMultimodule(uint8_t port)
sendByteMulti(protoByte);
// byte 2, subtype, powermode, model id
sendByteMulti((g_model.header.modelId[port] & 0x0f)
sendByteMulti((uint8_t) ((g_model.header.modelId[port] & 0x0f)
| ((subtype & 0x7) << 4)
| (g_model.moduleData[port].multi.lowPowerMode << 7)
| (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<MULTI_CHANS; i++) {
int channel = g_model.moduleData[port].channelsStart+i;
int value = channelOutputs[channel] + 2*PPM_CH_CENTER(channel) - 2*PPM_CENTER;
bits |= limit(0, 1024 + value, 2047) << bitsavailable;
// Scale to 80%
value = value*800/1000 + 1024;
bits |= limit(0, value, 2047) << bitsavailable;
bitsavailable += MULTI_CHAN_BITS;
while (bitsavailable >= 8) {
sendByteMulti((uint8_t) (bits & 0xff));

View file

@ -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)

View file

@ -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;
}
}

View file

@ -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

View file

@ -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();

View file

@ -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])

View file

@ -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])

View file

@ -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<FRSKY_SPORT_PACKET_SIZE; ++i) {
@ -122,7 +122,7 @@ void sportProcessTelemetryPacket(uint16_t id, uint8_t subId, uint8_t instance, u
}
}
void sportProcessTelemetryPacket(uint8_t * packet)
void sportProcessTelemetryPacket(const uint8_t * packet)
{
uint8_t physicalId = packet[0] & 0x1F;
uint8_t primId = packet[1];

View file

@ -0,0 +1,274 @@
/*
* 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.
*/
#include "opentx.h"
MultiModuleStatus multiModuleStatus;
uint8_t multiBindStatus = MULTI_NORMAL_OPERATION;
enum MultiPacketTypes : uint8_t {
MultiStatus = 1,
FrSkySportTelemtry,
FrSkyHubTelemetry,
SpektrumTelemetry,
DSMBindPacket,
FlyskyIBusTelemetry,
};
enum MultiBufferState : uint8_t {
NoProtocolDetected,
MultiFirstByteReceived,
ReceivingMultiProtocol,
SpektrumTelemetryFallback,
FrskyTelemetryFallbackFirstByte,
FrskyTelemetryFallbackNextBytes,
FlyskyTelemetryFallback
};
MultiBufferState guessProtocol()
{
if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false) == MM_RF_PROTO_DSM2)
return SpektrumTelemetryFallback;
else if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false) == MM_RF_PROTO_FS_AFHDS2A)
return FlyskyTelemetryFallback;
else
return FrskyTelemetryFallbackFirstByte;
}
static void processMultiStatusPacket(const uint8_t *data)
{
// At least two status packets without bind flag
bool wasBinding = (multiModuleStatus.isBinding());
multiModuleStatus.flags = data[0];
multiModuleStatus.major = data[1];
multiModuleStatus.minor = data[2];
multiModuleStatus.revision = data[3];
multiModuleStatus.patch = data[4];
multiModuleStatus.lastUpdate = get_tmr10ms();
if (wasBinding && !multiModuleStatus.isBinding() && multiBindStatus == MULTI_BIND_INITIATED)
multiBindStatus = MULTI_BIND_FINISHED;
// set moduleFlag to bind status
/*
if (moduleFlag[EXTERNAL_MODULE] != MODULE_RANGECHECK)
// Two times the same status in a row to avoid race conditions
if (multiModuleStatus.isBinding() == wasBinding) {
multiModuleStatus.isBinding() ? moduleFlag[EXTERNAL_MODULE] = MODULE_BIND : MODULE_NORMAL_MODE;
}
*/
}
static void processMultiTelemetryPaket(const uint8_t *packet)
{
uint8_t type = packet[0];
uint8_t len = packet[1];
const uint8_t *data = packet + 2;
// Switch type
switch (type) {
case MultiStatus:
if (len >= 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;
}
}

118
radio/src/telemetry/multi.h Normal file
View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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) {

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -228,7 +228,10 @@ extern const pm_char STR_OPEN9X[];
#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_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
@ -365,6 +368,9 @@ extern const pm_char STR_OPEN9X[];
#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_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)
@ -609,6 +615,13 @@ 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[];

View file

@ -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"

View file

@ -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"

View file

@ -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"

View file

@ -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"

View file

@ -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"

View file

@ -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"

View file

@ -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"

View file

@ -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"

View file

@ -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"

View file

@ -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"

View file

@ -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"