From fd782538d87a8ac41aa3ed499c1f165c13f2f061 Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Fri, 29 Sep 2017 18:29:39 +0200 Subject: [PATCH] Implement SBUS output for external module bay. (#5225) * Implement SBUS output for external module bay. * Bugfixes and Companion support --- companion/src/firmwares/opentx/opentxeeprom.h | 8 +- .../src/firmwares/opentx/opentxinterface.cpp | 2 + companion/src/modeledit/setup.cpp | 15 +- companion/src/modelprinter.cpp | 3 +- companion/src/radiodata.h | 1 + radio/src/datastructs.h | 6 + radio/src/gui/128x64/model_setup.cpp | 25 ++- radio/src/gui/212x64/model_setup.cpp | 25 ++- radio/src/gui/480x272/model_setup.cpp | 24 ++- radio/src/gui/gui_common.h | 4 +- radio/src/myeeprom.h | 7 +- radio/src/opentx.h | 21 ++- radio/src/pulses/multi_arm.cpp | 78 +-------- radio/src/pulses/pulses.h | 6 + radio/src/pulses/pulses_arm.cpp | 18 +- radio/src/pulses/pulses_arm.h | 8 +- radio/src/pulses/sbus_arm.cpp | 157 ++++++++++++++++++ radio/src/targets/common/arm/CMakeLists.txt | 3 +- radio/src/targets/horus/board.h | 7 +- radio/src/targets/horus/extmodule_driver.cpp | 6 +- radio/src/targets/horus/pulses_driver.cpp | 6 +- radio/src/targets/sky9x/board.h | 6 +- radio/src/targets/sky9x/pulses_driver.cpp | 10 +- radio/src/targets/taranis/board.h | 7 +- .../src/targets/taranis/extmodule_driver.cpp | 6 +- radio/src/targets/taranis/pulses_driver.cpp | 6 +- radio/src/translations.cpp | 4 + radio/src/translations.h | 4 + radio/src/translations/cz.h.txt | 4 +- radio/src/translations/de.h.txt | 4 +- radio/src/translations/en.h.txt | 4 +- radio/src/translations/es.h.txt | 4 +- radio/src/translations/fi.h.txt | 4 +- radio/src/translations/fr.h.txt | 4 +- radio/src/translations/it.h.txt | 4 +- radio/src/translations/nl.h.txt | 4 +- radio/src/translations/pl.h.txt | 4 +- radio/src/translations/pt.h.txt | 4 +- radio/src/translations/se.h.txt | 4 +- 39 files changed, 367 insertions(+), 150 deletions(-) create mode 100644 radio/src/pulses/sbus_arm.cpp diff --git a/companion/src/firmwares/opentx/opentxeeprom.h b/companion/src/firmwares/opentx/opentxeeprom.h index 0c610896e..c91e70869 100644 --- a/companion/src/firmwares/opentx/opentxeeprom.h +++ b/companion/src/firmwares/opentx/opentxeeprom.h @@ -98,15 +98,11 @@ class ProtocolsConversionTable: public ConversionTable addConversion(PULSES_DSM2, val++); addConversion(PULSES_DSMX, val++); } - if (IS_HORUS_OR_TARANIS(board)) { + if (IS_ARM(board)) { addConversion(PULSES_CROSSFIRE, val++); addConversion(PULSES_MULTIMODULE, val++); addConversion(PULSES_PXX_R9M, val++); - } - else if (IS_ARM(board)) { - val++; - addConversion(PULSES_MULTIMODULE, val++); - addConversion(PULSES_PXX_R9M, val++); + addConversion(PULSES_SBUS, val++); } } }; diff --git a/companion/src/firmwares/opentx/opentxinterface.cpp b/companion/src/firmwares/opentx/opentxinterface.cpp index 6cc42869c..e96922fb5 100644 --- a/companion/src/firmwares/opentx/opentxinterface.cpp +++ b/companion/src/firmwares/opentx/opentxinterface.cpp @@ -806,6 +806,7 @@ int OpenTxFirmware::isAvailable(PulsesProtocol proto, int port) case PULSES_DSM2: case PULSES_DSMX: case PULSES_CROSSFIRE: + case PULSES_SBUS: return 1; case PULSES_MULTIMODULE: return id.contains("multimodule") ? 1 : 0; @@ -837,6 +838,7 @@ int OpenTxFirmware::isAvailable(PulsesProtocol proto, int port) case PULSES_LP45: case PULSES_DSM2: case PULSES_DSMX: + case PULSES_SBUS: return 1; case PULSES_MULTIMODULE: return id.contains("multimodule") ? 1 : 0; diff --git a/companion/src/modeledit/setup.cpp b/companion/src/modeledit/setup.cpp index 6168574f6..6848ca704 100644 --- a/companion/src/modeledit/setup.cpp +++ b/companion/src/modeledit/setup.cpp @@ -171,6 +171,7 @@ void TimerPanel::on_name_editingFinished() #define MASK_ANTENNA 256 #define MASK_MULTIOPTION 512 #define MASK_R9M 1024 +#define MASK_SBUSPPM_FIELDS 2048 quint8 ModulePanel::failsafesValueDisplayType = ModulePanel::FAILSAFE_DISPLAY_PERCENT; @@ -391,11 +392,15 @@ void ModulePanel::update() module.channelsCount = 16; break; case PULSES_PPM: - mask |= MASK_PPM_FIELDS | MASK_CHANNELS_RANGE| MASK_CHANNELS_COUNT; + mask |= MASK_PPM_FIELDS | MASK_SBUSPPM_FIELDS| MASK_CHANNELS_RANGE| MASK_CHANNELS_COUNT; if (IS_9XRPRO(firmware->getBoard())) { mask |= MASK_OPEN_DRAIN; } break; + case PULSES_SBUS: + module.channelsCount = 16; + mask |= MASK_SBUSPPM_FIELDS| MASK_CHANNELS_RANGE; + break; case PULSES_MULTIMODULE: mask |= MASK_CHANNELS_RANGE | MASK_RX_NUMBER | MASK_MULTIMODULE; max_rx_num = 15; @@ -441,8 +446,8 @@ void ModulePanel::update() ui->channelsCount->setSingleStep(firmware->getCapability(HasPPMStart) ? 1 : 2); // PPM settings fields - ui->label_ppmPolarity->setVisible(mask & MASK_PPM_FIELDS); - ui->ppmPolarity->setVisible(mask & MASK_PPM_FIELDS); + ui->label_ppmPolarity->setVisible(mask & MASK_SBUSPPM_FIELDS); + ui->ppmPolarity->setVisible(mask & MASK_SBUSPPM_FIELDS); ui->ppmPolarity->setCurrentIndex(module.ppm.pulsePol); ui->label_ppmOutputType->setVisible(mask & MASK_OPEN_DRAIN); ui->ppmOutputType->setVisible(mask & MASK_OPEN_DRAIN); @@ -450,8 +455,8 @@ void ModulePanel::update() ui->label_ppmDelay->setVisible(mask & MASK_PPM_FIELDS); ui->ppmDelay->setVisible(mask & MASK_PPM_FIELDS); ui->ppmDelay->setValue(module.ppm.delay); - ui->label_ppmFrameLength->setVisible(mask & MASK_PPM_FIELDS); - ui->ppmFrameLength->setVisible(mask & MASK_PPM_FIELDS); + ui->label_ppmFrameLength->setVisible(mask & MASK_SBUSPPM_FIELDS); + ui->ppmFrameLength->setVisible(mask & MASK_SBUSPPM_FIELDS); ui->ppmFrameLength->setMinimum(module.channelsCount*(model->extendedLimits ? 2.250 : 2)+3.5); ui->ppmFrameLength->setMaximum(firmware->getCapability(PPMFrameLength)); ui->ppmFrameLength->setValue(22.5+((double)module.ppm.frameLength)*0.5); diff --git a/companion/src/modelprinter.cpp b/companion/src/modelprinter.cpp index 7375375f5..9d820dccd 100644 --- a/companion/src/modelprinter.cpp +++ b/companion/src/modelprinter.cpp @@ -120,7 +120,8 @@ QString ModelPrinter::printModuleProtocol(unsigned int protocol) "FrSky XJT (D16)", "FrSky XJT (D8)", "FrSky XJT (LR12)", "FrSky DJT", "Crossfire", "DIY Multiprotocol Module", - "FrSky R9M Module" + "FrSky R9M Module", + "SBUS output at VBat" }; return CHECK_IN_ARRAY(strings, protocol); diff --git a/companion/src/radiodata.h b/companion/src/radiodata.h index 578e55a8b..c83838923 100644 --- a/companion/src/radiodata.h +++ b/companion/src/radiodata.h @@ -775,6 +775,7 @@ enum PulsesProtocol { PULSES_CROSSFIRE, PULSES_MULTIMODULE, PULSES_PXX_R9M, + PULSES_SBUS, PULSES_PROTOCOL_LAST }; diff --git a/radio/src/datastructs.h b/radio/src/datastructs.h index 6e377bc57..55aa3dbbd 100644 --- a/radio/src/datastructs.h +++ b/radio/src/datastructs.h @@ -682,6 +682,12 @@ PACK(struct ModuleData { uint8_t sport_out:1; uint8_t spare3; } pxx); + NOBACKUP(struct { + uint8_t spare:6; + uint8_t noninverted:1; + uint8_t spare2:1; + int8_t refreshRate; // definition as framelength for ppm (* 5 + 225 = time in 1/10 ms) + } sbus); }; // Helper functions to set both of the rfProto protocol at the same time diff --git a/radio/src/gui/128x64/model_setup.cpp b/radio/src/gui/128x64/model_setup.cpp index d09e87d05..12b9f8e97 100644 --- a/radio/src/gui/128x64/model_setup.cpp +++ b/radio/src/gui/128x64/model_setup.cpp @@ -133,7 +133,7 @@ enum MenuModelSetupItems { #define IF_INTERNAL_MODULE_ON(x) (IS_INTERNAL_MODULE_ENABLED()? (uint8_t)(x) : HIDDEN_ROW ) #define IF_EXTERNAL_MODULE_ON(x) (IS_EXTERNAL_MODULE_ENABLED()? (uint8_t)(x) : HIDDEN_ROW) #define INTERNAL_MODULE_CHANNELS_ROWS IF_INTERNAL_MODULE_ON(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_PXX(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW + #define EXTERNAL_MODULE_BIND_ROWS() ((IS_MODULE_XJT(EXTERNAL_MODULE) && IS_D8_RX(EXTERNAL_MODULE)) || IS_MODULE_SBUS(EXTERNAL_MODULE)) ? (uint8_t)1 : (IS_MODULE_PPM(EXTERNAL_MODULE) || IS_MODULE_PXX(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) , @@ -727,6 +727,8 @@ void menuModelSetup(event_t event) g_model.moduleData[EXTERNAL_MODULE].rfProtocol = 0; g_model.moduleData[EXTERNAL_MODULE].channelsStart = 0; g_model.moduleData[EXTERNAL_MODULE].channelsCount = DEFAULT_CHANNELS(EXTERNAL_MODULE); + if (IS_MODULE_SBUS(EXTERNAL_MODULE)) + g_model.moduleData[EXTERNAL_MODULE].sbus.refreshRate = -31; } break; case 1: @@ -934,6 +936,23 @@ void menuModelSetup(event_t event) } } } + else if (IS_MODULE_SBUS(moduleIdx)) { + lcdDrawTextAlignedLeft(y, STR_REFRESHRATE); + lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, (int16_t)moduleData.ppm.frameLength*5 + 225, (menuHorizontalPosition<=0 ? attr : 0) | PREC1|LEFT); + lcdDrawText(lcdLastRightPos, y, STR_MS); + lcdDrawText(MODEL_SETUP_2ND_COLUMN+5*FW+2, y, moduleData.sbus.noninverted ? "no inv" : "normal", (CURSOR_ON_LINE() || menuHorizontalPosition==1) ? attr : 0); + + if (attr && s_editMode>0) { + switch (menuHorizontalPosition) { + case 0: + CHECK_INCDEC_MODELVAR(event, moduleData.ppm.frameLength, -33, 35); + break; + case 1: + CHECK_INCDEC_MODELVAR_ZERO(event, moduleData.sbus.noninverted, 1); + break; + } + } + } else { horzpos_t l_posHorz = menuHorizontalPosition; coord_t xOffsetBind = MODEL_SETUP_BIND_OFS; @@ -1100,6 +1119,10 @@ void menuModelSetup(event_t event) g_model.moduleData[moduleIdx].pxx.sport_out = editCheckBox(g_model.moduleData[EXTERNAL_MODULE].pxx.sport_out, MODEL_SETUP_2ND_COLUMN, y, STR_SPORT_OUT, attr, event); } } + else if (IS_MODULE_SBUS(moduleIdx)) { + lcdDrawTextAlignedLeft(y, STR_WARN_BATTVOLTAGE); + putsVolts(lcdLastRightPos, y, getBatteryVoltage(), attr | PREC2 | LEFT); + } break; } case ITEM_MODEL_EXTERNAL_MODULE_POWER: { diff --git a/radio/src/gui/212x64/model_setup.cpp b/radio/src/gui/212x64/model_setup.cpp index ffdd70ae4..9575bd071 100644 --- a/radio/src/gui/212x64/model_setup.cpp +++ b/radio/src/gui/212x64/model_setup.cpp @@ -305,7 +305,7 @@ void menuModelSetup(event_t event) 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_PXX(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW, + ((IS_MODULE_XJT(EXTERNAL_MODULE) && !HAS_RF_PROTOCOL_FAILSAFE(g_model.moduleData[EXTERNAL_MODULE].rfProtocol))|| IS_MODULE_SBUS(EXTERNAL_MODULE)) ? (uint8_t)1 : (IS_MODULE_PPM(EXTERNAL_MODULE) || IS_MODULE_PXX(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW, FAILSAFE_ROWS(EXTERNAL_MODULE), EXTERNAL_MODULE_OPTION_ROW, MULTIMODULE_MODULE_ROWS EXTERNAL_MODULE_POWER_ROW, LABEL(Trainer), 0, TRAINER_LINE1_ROWS, TRAINER_LINE2_ROWS}); #endif @@ -767,6 +767,8 @@ void menuModelSetup(event_t event) g_model.moduleData[EXTERNAL_MODULE].rfProtocol = 0; g_model.moduleData[EXTERNAL_MODULE].channelsStart = 0; g_model.moduleData[EXTERNAL_MODULE].channelsCount = DEFAULT_CHANNELS(EXTERNAL_MODULE); + if (IS_MODULE_SBUS(EXTERNAL_MODULE)) + g_model.moduleData[EXTERNAL_MODULE].sbus.refreshRate = -31; } break; case 1: @@ -935,6 +937,23 @@ void menuModelSetup(event_t event) } } } + else if (IS_MODULE_SBUS(moduleIdx)) { + lcdDrawTextAlignedLeft(y, STR_REFRESHRATE); + lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, (int16_t)moduleData.ppm.frameLength*5 + 225, (menuHorizontalPosition<=0 ? attr : 0) | PREC1|LEFT); + lcdDrawText(lcdLastRightPos, y, STR_MS); + lcdDrawText(MODEL_SETUP_3RD_COLUMN, y, moduleData.sbus.noninverted ? "not inverted" : "normal", (CURSOR_ON_LINE() || menuHorizontalPosition==1) ? attr : 0); + + if (attr && s_editMode>0) { + switch (menuHorizontalPosition) { + case 0: + CHECK_INCDEC_MODELVAR(event, moduleData.ppm.frameLength, -33, 35); + break; + case 1: + CHECK_INCDEC_MODELVAR_ZERO(event, moduleData.sbus.noninverted, 1); + break; + } + } + } else { horzpos_t l_posHorz = menuHorizontalPosition; coord_t xOffsetBind = MODEL_SETUP_BIND_OFS; @@ -1089,6 +1108,10 @@ void menuModelSetup(event_t event) g_model.moduleData[moduleIdx].pxx.sport_out = editCheckBox(g_model.moduleData[EXTERNAL_MODULE].pxx.sport_out, MODEL_SETUP_2ND_COLUMN, y, STR_SPORT_OUT, attr, event); } } + else if (IS_MODULE_SBUS(moduleIdx)) { + lcdDrawTextAlignedLeft(y, STR_WARN_BATTVOLTAGE); + putsVolts(lcdLastRightPos, y, getBatteryVoltage(), attr | PREC2 | LEFT); + } } break; case ITEM_MODEL_EXTERNAL_MODULE_POWER: { diff --git a/radio/src/gui/480x272/model_setup.cpp b/radio/src/gui/480x272/model_setup.cpp index c594374e2..c00a17376 100644 --- a/radio/src/gui/480x272/model_setup.cpp +++ b/radio/src/gui/480x272/model_setup.cpp @@ -262,7 +262,7 @@ bool menuModelSetup(event_t event) 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, + ((IS_MODULE_XJT(EXTERNAL_MODULE) && !HAS_RF_PROTOCOL_MODELINDEX(g_model.moduleData[EXTERNAL_MODULE].rfProtocol)) || IS_MODULE_SBUS(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, FAILSAFE_ROWS(EXTERNAL_MODULE), EXTERNAL_MODULE_OPTION_ROW, MULTIMODULE_MODULE_ROWS EXTERNAL_MODULE_POWER_ROW, LABEL(Trainer), 0, TRAINER_LINE1_ROWS, TRAINER_LINE2_ROWS }); @@ -688,6 +688,8 @@ bool menuModelSetup(event_t event) g_model.moduleData[EXTERNAL_MODULE].rfProtocol = 0; g_model.moduleData[EXTERNAL_MODULE].channelsStart = 0; g_model.moduleData[EXTERNAL_MODULE].channelsCount = DEFAULT_CHANNELS(EXTERNAL_MODULE); + if (IS_MODULE_SBUS(EXTERNAL_MODULE)) + g_model.moduleData[EXTERNAL_MODULE].sbus.refreshRate = -31; } break; case 1: @@ -845,6 +847,22 @@ bool menuModelSetup(event_t event) } } } + else if (IS_MODULE_SBUS(moduleIdx)) { + lcdDrawText(MENUS_MARGIN_LEFT, y, STR_REFRESHRATE); + lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, (int16_t)moduleData.ppm.frameLength*5 + 225, (menuHorizontalPosition<=0 ? attr : 0) | PREC1|LEFT, 0, NULL, STR_MS); + lcdDrawText(MODEL_SETUP_3RD_COLUMN, y, moduleData.sbus.noninverted ? "not inverted" : "normal", (CURSOR_ON_LINE() || menuHorizontalPosition==1) ? attr : 0); + + if (attr && s_editMode>0) { + switch (menuHorizontalPosition) { + case 0: + CHECK_INCDEC_MODELVAR(event, moduleData.ppm.frameLength, -33, 35); + break; + case 1: + CHECK_INCDEC_MODELVAR_ZERO(event, moduleData.sbus.noninverted, 1); + break; + } + } + } else { int l_posHorz = menuHorizontalPosition; coord_t xOffsetBind = MODEL_SETUP_BIND_OFS; @@ -988,6 +1006,10 @@ bool menuModelSetup(event_t event) g_model.moduleData[moduleIdx].pxx.sport_out = editCheckBox(g_model.moduleData[EXTERNAL_MODULE].pxx.sport_out, MODEL_SETUP_2ND_COLUMN, y, attr, event); } } + else if (IS_MODULE_SBUS(moduleIdx)) { + lcdDrawText(MENUS_MARGIN_LEFT, y, STR_WARN_BATTVOLTAGE); + drawValueWithUnit(MODEL_SETUP_4TH_COLUMN, y, getBatteryVoltage(), UNIT_VOLTS, attr|PREC2|LEFT); + } } break; case ITEM_MODEL_EXTERNAL_MODULE_POWER: { diff --git a/radio/src/gui/gui_common.h b/radio/src/gui/gui_common.h index e8aada2b1..a1afc7f56 100644 --- a/radio/src/gui/gui_common.h +++ b/radio/src/gui/gui_common.h @@ -115,7 +115,7 @@ void runFatalErrorScreen(const char * message); void lcdDrawMMM(coord_t x, coord_t y, LcdFlags flags=0); // 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) +#define EXTERNAL_MODULE_CHANNELS_ROWS IF_EXTERNAL_MODULE_ON((IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_CROSSFIRE(EXTERNAL_MODULE) || IS_MODULE_SBUS(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) @@ -159,7 +159,7 @@ const mm_protocol_definition *getMultiProtocolDefinition (uint8_t protocol); #define FAILSAFE_ROWS(x) ((IS_MODULE_XJT(x) && HAS_RF_PROTOCOL_FAILSAFE(g_model.moduleData[x].rfProtocol)) || MULTIMODULE_HASFAILSAFE(x) || IS_MODULE_R9M(x)) ? (g_model.moduleData[x].failsafeMode==FAILSAFE_CUSTOM ? (uint8_t)1 : (uint8_t)0) : HIDDEN_ROW #define R9M_OPTION_ROW (IS_TELEMETRY_INTERNAL_MODULE ? TITLE_ROW : (uint8_t) 0) -#define EXTERNAL_MODULE_OPTION_ROW (IS_MODULE_R9M(EXTERNAL_MODULE) ? R9M_OPTION_ROW : MULTIMODULE_OPTIONS_ROW) +#define EXTERNAL_MODULE_OPTION_ROW (IS_MODULE_R9M(EXTERNAL_MODULE) ? R9M_OPTION_ROW : IS_MODULE_SBUS(EXTERNAL_MODULE) ? TITLE_ROW : MULTIMODULE_OPTIONS_ROW) #define EXTERNAL_MODULE_POWER_ROW (IS_MODULE_MULTIMODULE(EXTERNAL_MODULE) || IS_MODULE_R9M(EXTERNAL_MODULE)) ? (uint8_t) 0 : HIDDEN_ROW void editStickHardwareSettings(coord_t x, coord_t y, int idx, event_t event, LcdFlags flags); diff --git a/radio/src/myeeprom.h b/radio/src/myeeprom.h index 6f98e285c..4c5b7ed6e 100644 --- a/radio/src/myeeprom.h +++ b/radio/src/myeeprom.h @@ -48,6 +48,7 @@ #endif #define GET_PPM_POLARITY(idx) g_model.moduleData[idx].ppm.pulsePol +#define GET_SBUS_POLARITY(idx) g_model.moduleData[idx].sbus.noninverted #define GET_PPM_DELAY(idx) (g_model.moduleData[idx].ppm.delay * 50 + 300) #define SET_DEFAULT_PPM_FRAME_LENGTH(idx) g_model.moduleData[idx].ppm.frameLength = 4 * max((int8_t)0, g_model.moduleData[idx].channelsCount) @@ -473,7 +474,7 @@ enum Protocols { PROTO_DSM2_DSM2, PROTO_DSM2_DSMX, #endif -#if defined(CROSSFIRE) || defined(MULTIMODULE) +#if defined(CPUARM) PROTO_CROSSFIRE, #endif #if defined(IRPROTOS) @@ -484,8 +485,9 @@ enum Protocols { PROTO_PICZ, PROTO_SWIFT, #endif -#if defined(MULTIMODULE) +#if defined(CPUARM) PROTO_MULTIMODULE, + PROTO_SBUS, #endif PROTO_MAX, PROTO_NONE @@ -570,6 +572,7 @@ enum ModuleTypes { MODULE_TYPE_CROSSFIRE, MODULE_TYPE_MULTIMODULE, MODULE_TYPE_R9M, + MODULE_TYPE_SBUS, MODULE_TYPE_COUNT }; diff --git a/radio/src/opentx.h b/radio/src/opentx.h index 38c209df7..d18fc9975 100644 --- a/radio/src/opentx.h +++ b/radio/src/opentx.h @@ -398,12 +398,14 @@ void memswap(void * a, void * b, uint8_t size); #include "pulses/pulses.h" #if defined(CPUARM) -// Order is the same as in enum Protocols in myeeprom.h (none, ppm, xjt, dsm, crossfire, multi, r9m) - static const int8_t maxChannelsModules[] = { 0, 8, 8, -2, 8, 4, 8}; // relative to 8! +// Order is the same as in enum Protocols in myeeprom.h (none, ppm, xjt, dsm, crossfire, multi, r9m, sbus) + static const int8_t maxChannelsModules[] = { 0, 8, 8, -2, 8, 4, 8, 8}; // relative to 8! static const int8_t maxChannelsXJT[] = { 0, 8, 0, 4 }; // relative to 8! #define MAX_TRAINER_CHANNELS_M8() (MAX_TRAINER_CHANNELS-8) #endif + + #if defined(MULTIMODULE) #define IS_MODULE_MULTIMODULE(idx) (idx==EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type==MODULE_TYPE_MULTIMODULE) #else @@ -417,11 +419,7 @@ void memswap(void * a, void * b, uint8_t size); #define IS_MODULE_PPM(idx) (idx==TRAINER_MODULE || (idx==EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type==MODULE_TYPE_PPM)) #endif #define IS_MODULE_XJT(idx) (g_model.moduleData[idx].type==MODULE_TYPE_XJT) - #if defined(DSM2) - #define IS_MODULE_DSM2(idx) (idx==EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type==MODULE_TYPE_DSM2) - #else - #define IS_MODULE_DSM2(idx) (false) - #endif + #if defined(CROSSFIRE) #define IS_MODULE_CROSSFIRE(idx) (idx==EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type==MODULE_TYPE_CROSSFIRE) #else @@ -438,7 +436,6 @@ void memswap(void * a, void * b, uint8_t size); #elif defined(PCBSKY9X) && !defined(REVA) #define IS_MODULE_PPM(idx) (idx==TRAINER_MODULE || idx==EXTRA_MODULE || (idx==EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type==MODULE_TYPE_PPM)) #define IS_MODULE_XJT(idx) (idx==EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type==MODULE_TYPE_XJT) - #define IS_MODULE_DSM2(idx) (idx==EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type==MODULE_TYPE_DSM2) #define MAX_EXTERNAL_MODULE_CHANNELS() ((g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_XJT) ? maxChannelsXJT[1+g_model.moduleData[0].rfProtocol] : maxChannelsModules[g_model.moduleData[EXTERNAL_MODULE].type]) #define MAX_EXTRA_MODULE_CHANNELS() (8) // Only PPM (16ch PPM) #define MAX_CHANNELS(idx) (idx==EXTERNAL_MODULE ? MAX_EXTERNAL_MODULE_CHANNELS() : (idx==EXTRA_MODULE ? MAX_EXTRA_MODULE_CHANNELS() : MAX_TRAINER_CHANNELS_M8())) @@ -447,7 +444,6 @@ void memswap(void * a, void * b, uint8_t size); #else #define IS_MODULE_PPM(idx) (idx==TRAINER_MODULE || (idx==EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type==MODULE_TYPE_PPM)) #define IS_MODULE_XJT(idx) (idx==EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type==MODULE_TYPE_XJT) - #define IS_MODULE_DSM2(idx) (idx==EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type==MODULE_TYPE_DSM2) #define MAX_EXTERNAL_MODULE_CHANNELS() ((g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_XJT) ? maxChannelsXJT[1+g_model.moduleData[EXTERNAL_MODULE].rfProtocol] : maxChannelsModules[g_model.moduleData[EXTERNAL_MODULE].type]) #define MAX_CHANNELS(idx) (idx==EXTERNAL_MODULE ? MAX_EXTERNAL_MODULE_CHANNELS() : MAX_TRAINER_CHANNELS_M8()) #define NUM_CHANNELS(idx) (8+g_model.moduleData[idx].channelsCount) @@ -455,6 +451,13 @@ void memswap(void * a, void * b, uint8_t size); #define IS_MODULE_R9M(idx) (g_model.moduleData[idx].type==MODULE_TYPE_R9M) #define IS_MODULE_PXX(idx) (IS_MODULE_XJT(idx) || IS_MODULE_R9M(idx)) +#if defined(DSM2) + #define IS_MODULE_DSM2(idx) (idx==EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type==MODULE_TYPE_DSM2) + #define IS_MODULE_SBUS(idx) (idx==EXTERNAL_MODULE && g_model.moduleData[EXTERNAL_MODULE].type==MODULE_TYPE_SBUS) +#else + #define IS_MODULE_DSM2(idx) (false) +#endif + #if defined(MULTIMODULE) #define IS_MULTIMODULE_DSM(idx) (IS_MODULE_MULTIMODULE(idx) && g_model.moduleData[idx].getMultiProtocol(true) == MM_RF_PROTO_DSM2) diff --git a/radio/src/pulses/multi_arm.cpp b/radio/src/pulses/multi_arm.cpp index a3d4045a0..c443890a9 100644 --- a/radio/src/pulses/multi_arm.cpp +++ b/radio/src/pulses/multi_arm.cpp @@ -26,77 +26,11 @@ -/* The protocol is heavily inspired by the DSM2 protocol, so reuse some the definitions where they are identical */ - #define MULTI_SEND_BIND (1 << 7) #define MULTI_SEND_RANGECHECK (1 << 5) #define MULTI_SEND_AUTOBIND (1 << 6) -#define BITLEN_MULTI (10*2) //100000 Baud => 10uS per bit - -#if defined(PPM_PIN_SERIAL) -static void sendByteMulti(uint8_t b) -{ - uint8_t parity = 1; - - putDsm2SerialBit(0); // Start bit - for (uint8_t i=0; i<8; i++) { // 8 data Bits - putDsm2SerialBit(b & 1); - parity = parity ^ (b & 1); - b >>= 1; - } - putDsm2SerialBit(!parity); // Even Parity bit - - putDsm2SerialBit(1); // Stop bit - putDsm2SerialBit(1); // Stop bit -} -#else -static void _send_level(uint8_t v) -{ - /* Copied over from DSM, this looks doubious and in my logic analyzer - output the low->high is about 2 ns late */ - if (modulePulsesData[EXTERNAL_MODULE].dsm2.index & 1) - v += 2; - else - v -= 2; - - *modulePulsesData[EXTERNAL_MODULE].dsm2.ptr++ = v - 1; - modulePulsesData[EXTERNAL_MODULE].dsm2.index+=1; - modulePulsesData[EXTERNAL_MODULE].dsm2.rest -=v; -} - -static void sendByteMulti(uint8_t b) //max 11 changes 0 10 10 10 10 P 1 -{ - bool lev = 0; - uint8_t parity = 1; - - uint8_t len = BITLEN_MULTI; //max val: 10*20 < 256 - for (uint8_t i=0; i<=9; i++) { //8Bits + 1Parity + Stop=1 - bool nlev = b & 1; //lsb first - parity = parity ^ (uint8_t)nlev; - if (lev == nlev) { - len += BITLEN_MULTI; - } - else { - _send_level(len); - len = BITLEN_MULTI; - lev = nlev; - } - b = (b>>1) | 0x80; //shift in ones for stop bit and parity - if (i==7) - b = b ^ parity; // lowest bit is one from previous line - } - _send_level(len+ BITLEN_MULTI); // enlarge the last bit to be two stop bits long -} -#endif - -// This is the data stream to send, prepare after 19.5 mS -// Send after 22.5 mS - -//static uint8_t *Dsm2_pulsePtr = pulses2MHz.pbyte ; - - #define MULTI_CHANS 16 #define MULTI_CHAN_BITS 11 void setupPulsesMultimodule(uint8_t port) @@ -180,9 +114,9 @@ void setupPulsesMultimodule(uint8_t port) // header, byte 0, 0x55 for proto 0-31 0x54 for 32-63 if (type <= 31) - sendByteMulti(0x55); + sendByteSbus(0x55); else - sendByteMulti(0x54); + sendByteSbus(0x54); // protocol byte @@ -190,16 +124,16 @@ void setupPulsesMultimodule(uint8_t port) if(g_model.moduleData[port].getMultiProtocol(true) != MM_RF_PROTO_DSM2) protoByte |= (g_model.moduleData[port].multi.autoBindMode << 6); - sendByteMulti(protoByte); + sendByteSbus(protoByte); // byte 2, subtype, powermode, model id - sendByteMulti((uint8_t) ((g_model.header.modelId[port] & 0x0f) + sendByteSbus((uint8_t) ((g_model.header.modelId[port] & 0x0f) | ((subtype & 0x7) << 4) | (g_model.moduleData[port].multi.lowPowerMode << 7)) ); // byte 3 - sendByteMulti((uint8_t) optionValue); + sendByteSbus((uint8_t) optionValue); uint32_t bits = 0; uint8_t bitsavailable = 0; @@ -216,7 +150,7 @@ void setupPulsesMultimodule(uint8_t port) bits |= limit(0, value, 2047) << bitsavailable; bitsavailable += MULTI_CHAN_BITS; while (bitsavailable >= 8) { - sendByteMulti((uint8_t) (bits & 0xff)); + sendByteSbus((uint8_t) (bits & 0xff)); bits >>= 8; bitsavailable -= 8; } diff --git a/radio/src/pulses/pulses.h b/radio/src/pulses/pulses.h index 04b466157..d5f145033 100644 --- a/radio/src/pulses/pulses.h +++ b/radio/src/pulses/pulses.h @@ -77,6 +77,12 @@ enum ModuleFlag #define IS_MULTIMODULE_PROTOCOL(protocol) (0) #endif +#if defined(CPUARM) + #define IS_SBUS_PROTOCOL(protocol) (protocol == PROTO_SBUS) +#else + #define IS_SBUS_PROTOCOL(protocol) (0) +#endif + #if defined(CPUARM) #include "pulses_arm.h" diff --git a/radio/src/pulses/pulses_arm.cpp b/radio/src/pulses/pulses_arm.cpp index 1c139fdbf..138270d94 100644 --- a/radio/src/pulses/pulses_arm.cpp +++ b/radio/src/pulses/pulses_arm.cpp @@ -65,6 +65,9 @@ uint8_t getRequiredProtocol(uint8_t port) case MODULE_TYPE_R9M: required_protocol = PROTO_PXX; break; + case MODULE_TYPE_SBUS: + required_protocol = PROTO_SBUS; + break; #if defined(MULTIMODULE) case MODULE_TYPE_MULTIMODULE: required_protocol = PROTO_MULTIMODULE; @@ -145,9 +148,10 @@ void setupPulses(uint8_t port) #if defined(MULTIMODULE) case PROTO_MULTIMODULE: - disable_multimodule(port); - break; #endif + case PROTO_SBUS: + disable_sbusOut(port); + break; case PROTO_PPM: disable_ppm(port); @@ -166,6 +170,10 @@ void setupPulses(uint8_t port) setupPulsesPXX(port); scheduleNextMixerCalculation(port, 9); break; + case PROTO_SBUS: + setupPulsesSbus(port); + scheduleNextMixerCalculation(port, (45+g_model.moduleData[port].sbus.refreshRate)/2); + break; #if defined(DSM2) case PROTO_DSM2_LP45: @@ -240,9 +248,11 @@ void setupPulses(uint8_t port) #if defined(MULTIMODULE) case PROTO_MULTIMODULE: - init_multimodule(port); - break; #endif + case PROTO_SBUS: + init_sbusOut(port); + break; + case PROTO_PPM: init_ppm(port); diff --git a/radio/src/pulses/pulses_arm.h b/radio/src/pulses/pulses_arm.h index c09177872..7bdef6dde 100644 --- a/radio/src/pulses/pulses_arm.h +++ b/radio/src/pulses/pulses_arm.h @@ -79,6 +79,7 @@ PACK(struct PxxUartPulsesData { /* DSM2 uses 2 header + 12 channel bytes, with max 10 changes (8n2) per byte + 16 bits trailer ~= 156 max pulses */ /* Multimodule uses 3 bytes header + 22 channel bytes with max 11 changes per byte (8e2) + 16 bits trailer ~= 291 max pulses */ /* Multimodule reuses some of the DSM2 function and structs since the protocols are similar enough */ +/* sbus is 1 byte header, 22 channel bytes (11bit * 16ch) + 1 byte flags */ PACK(struct PxxTimerPulsesData { pulse_duration_t pulses[200]; pulse_duration_t * ptr; @@ -87,11 +88,7 @@ PACK(struct PxxTimerPulsesData { uint32_t pcmOnesCount; }); -#if defined(MULTIMODULE) #define MAX_PULSES_TRANSITIONS 300 -#else -#define MAX_PULSES_TRANSITIONS 200 -#endif PACK(struct Dsm2TimerPulsesData { pulse_duration_t pulses[MAX_PULSES_TRANSITIONS]; @@ -128,6 +125,7 @@ union ModulePulsesData { * sizeof(ModulePulsesData). __ALIGNED is required for sizeof(ModulePulsesData) to be a multiple of the alignment. */ +/* TODO: internal pulsedata only needs 200 bytes vs 300 bytes for external, both use 300 byte since we have a common struct */ extern ModulePulsesData modulePulsesData[NUM_MODULES]; union TrainerPulsesData { @@ -140,12 +138,14 @@ extern const uint16_t CRCTable[]; void setupPulses(uint8_t port); void setupPulsesDSM2(uint8_t port); void setupPulsesMultimodule(uint8_t port); +void setupPulsesSbus(uint8_t port); void setupPulsesPXX(uint8_t port); void setupPulsesPPMModule(uint8_t port); void setupPulsesPPMTrainer(); void sendByteDsm2(uint8_t b); void putDsm2Flush(); void putDsm2SerialBit(uint8_t bit); +void sendByteSbus(uint8_t byte); #if defined(HUBSAN) void Hubsan_Init(); diff --git a/radio/src/pulses/sbus_arm.cpp b/radio/src/pulses/sbus_arm.cpp new file mode 100644 index 000000000..e3f841d2e --- /dev/null +++ b/radio/src/pulses/sbus_arm.cpp @@ -0,0 +1,157 @@ +/* + * 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" + + +#define BITLEN_SBUS (10*2) //100000 Baud => 10uS per bit + + +/* The protocol reuse some the DSM2 definitions where they are identical */ + + +#if defined(PPM_PIN_SERIAL) +void sendByteSbus(uint8_t b) +{ + uint8_t parity = 1; + + putDsm2SerialBit(0); // Start bit + for (uint8_t i=0; i<8; i++) { // 8 data Bits + putDsm2SerialBit(b & 1); + parity = parity ^ (b & 1); + b >>= 1; + } + putDsm2SerialBit(!parity); // Even Parity bit + + putDsm2SerialBit(1); // Stop bit + putDsm2SerialBit(1); // Stop bit +} +#else +static void _send_level(uint8_t v) +{ + /* Copied over from DSM, this looks doubious and in my logic analyzer + output the low->high is about 2 ns late */ + if (modulePulsesData[EXTERNAL_MODULE].dsm2.index & 1) + v += 2; + else + v -= 2; + + *modulePulsesData[EXTERNAL_MODULE].dsm2.ptr++ = v - 1; + modulePulsesData[EXTERNAL_MODULE].dsm2.index+=1; + modulePulsesData[EXTERNAL_MODULE].dsm2.rest -=v; +} + +void sendByteSbus(uint8_t b) //max 11 changes 0 10 10 10 10 P 1 +{ + bool lev = 0; + uint8_t parity = 1; + + uint8_t len = BITLEN_SBUS; //max val: 10*20 < 256 + for (uint8_t i=0; i<=9; i++) { //8Bits + 1Parity + Stop=1 + bool nlev = b & 1; //lsb first + parity = parity ^ (uint8_t)nlev; + if (lev == nlev) { + len += BITLEN_SBUS; + } + else { + _send_level(len); + len = BITLEN_SBUS; + lev = nlev; + } + b = (b>>1) | 0x80; //shift in ones for stop bit and parity + if (i==7) + b = b ^ parity; // lowest bit is one from previous line + } + _send_level(len+ BITLEN_SBUS); // enlarge the last bit to be two stop bits long +} +#endif + + + + +#define SBUS_NORMAL_CHANS 16 +#define SBUS_CHAN_BITS 11 + + +/* Definitions from CleanFlight/BetaFlight */ + +#define SBUS_FLAG_CHANNEL_17 (1 << 0) +#define SBUS_FLAG_CHANNEL_18 (1 << 1) +#define SBUS_FLAG_SIGNAL_LOSS (1 << 2) +#define SBUS_FLAG_FAILSAFE_ACTIVE (1 << 3) +#define SBUS_FRAME_BEGIN_BYTE 0x0F + +#define SBUS_CHAN_CENTER 992 + +inline int getChannelValue(uint8_t port, int channel) { + int ch = g_model.moduleData[port].channelsStart+channel; + // We will ignore 17 and 18th if that brings us over the limit + if (ch > 31) + return 0; + return channelOutputs[ch] + 2*PPM_CH_CENTER(ch) - 2*PPM_CENTER; +} + +void setupPulsesSbus(uint8_t port) +{ +#if defined(PPM_PIN_SERIAL) + modulePulsesData[EXTERNAL_MODULE].dsm2.serialByte = 0 ; + modulePulsesData[EXTERNAL_MODULE].dsm2.serialBitCount = 0 ; +#else + modulePulsesData[EXTERNAL_MODULE].dsm2.rest = (g_model.moduleData[EXTERNAL_MODULE].sbus.refreshRate * 5 + 225)*200 ; + modulePulsesData[EXTERNAL_MODULE].dsm2.index = 0; +#endif + + modulePulsesData[EXTERNAL_MODULE].dsm2.ptr = modulePulsesData[EXTERNAL_MODULE].dsm2.pulses; + + + // Sync Byte + sendByteSbus(SBUS_FRAME_BEGIN_BYTE); + + uint32_t bits = 0; + uint8_t bitsavailable = 0; + + // byte 1-22, channels 0..2047, limits not really clear (B + for (int i=0; i= 8) { + sendByteSbus((uint8_t) (bits & 0xff)); + bits >>= 8; + bitsavailable -= 8; + } + } + // Flags + uint8_t flags=0; + if (getChannelValue(port, 16) > 0) + flags |=SBUS_FLAG_CHANNEL_17; + if (getChannelValue(port, 17) > 0) + flags |=SBUS_FLAG_CHANNEL_18; + + sendByteSbus(flags); + + // Last byte, always 0x0 + sendByteSbus(0x0); + + putDsm2Flush(); + +} diff --git a/radio/src/targets/common/arm/CMakeLists.txt b/radio/src/targets/common/arm/CMakeLists.txt index 9fc747fe3..06961f905 100644 --- a/radio/src/targets/common/arm/CMakeLists.txt +++ b/radio/src/targets/common/arm/CMakeLists.txt @@ -132,4 +132,5 @@ set(PULSES_SRC ppm_arm.cpp pxx_arm.cpp dsm2_arm.cpp - ) + sbus_arm.cpp + ) \ No newline at end of file diff --git a/radio/src/targets/horus/board.h b/radio/src/targets/horus/board.h index e36e25fe7..99d629c9d 100644 --- a/radio/src/targets/horus/board.h +++ b/radio/src/targets/horus/board.h @@ -194,11 +194,8 @@ void init_dsm2(uint32_t module_index); void disable_dsm2(uint32_t module_index); void init_crossfire(uint32_t module_index); void disable_crossfire(uint32_t module_index); - -#if defined(MULTIMODULE) -void init_multimodule(uint32_t module_index); -void disable_multimodule(uint32_t module_index); -#endif +void init_sbusOut(uint32_t module_index); +void disable_sbusOut(uint32_t module_index); // Trainer driver void init_trainer_ppm(void); diff --git a/radio/src/targets/horus/extmodule_driver.cpp b/radio/src/targets/horus/extmodule_driver.cpp index 557e126d0..16a68c49e 100644 --- a/radio/src/targets/horus/extmodule_driver.cpp +++ b/radio/src/targets/horus/extmodule_driver.cpp @@ -271,13 +271,17 @@ void extmoduleSendNextFrame() EXTMODULE_DMA_STREAM->NDTR = modulePulsesData[EXTERNAL_MODULE].pxx.ptr - modulePulsesData[EXTERNAL_MODULE].pxx.pulses; EXTMODULE_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA } - else if (IS_DSM2_PROTOCOL(s_current_protocol[EXTERNAL_MODULE]) || IS_MULTIMODULE_PROTOCOL(s_current_protocol[EXTERNAL_MODULE])) { + else if (IS_DSM2_PROTOCOL(s_current_protocol[EXTERNAL_MODULE]) || IS_MULTIMODULE_PROTOCOL(s_current_protocol[EXTERNAL_MODULE]) || IS_SBUS_PROTOCOL(s_current_protocol[EXTERNAL_MODULE])) { EXTMODULE_TIMER->CCR2 = *(modulePulsesData[EXTERNAL_MODULE].dsm2.ptr - 1) - 4000; // 2mS in advance EXTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA #if defined(PCBX10) || PCBREV >= 13 EXTMODULE_DMA_STREAM->CR |= EXTMODULE_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1; + if (IS_SBUS_PROTOCOL(s_current_protocol[EXTERNAL_MODULE])) + EXTMODULE_TIMER->CCER = TIM_CCER_CC3E | (GET_SBUS_POLARITY(EXTERNAL_MODULE) ? TIM_CCER_CC3P : 0); // reverse polarity for Sbus if needed #else EXTMODULE_DMA_STREAM->CR |= EXTMODULE_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_1 | DMA_SxCR_MSIZE_1 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1; + if (IS_SBUS_PROTOCOL(s_current_protocol[EXTERNAL_MODULE])) + EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | (GET_SBUS_POLARITY(EXTERNAL_MODULE) ? TIM_CCER_CC1P : 0); // reverse polarity for Sbus if needed #endif EXTMODULE_DMA_STREAM->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->ARR); EXTMODULE_DMA_STREAM->M0AR = CONVERT_PTR_UINT(modulePulsesData[EXTERNAL_MODULE].dsm2.pulses); diff --git a/radio/src/targets/horus/pulses_driver.cpp b/radio/src/targets/horus/pulses_driver.cpp index 784e060ce..356b3b2c7 100644 --- a/radio/src/targets/horus/pulses_driver.cpp +++ b/radio/src/targets/horus/pulses_driver.cpp @@ -96,17 +96,15 @@ void disable_dsm2(uint32_t port) } #endif -#if defined(MULTIMODULE) -void init_multimodule(uint32_t port) +void init_sbusOut(uint32_t port) { init_dsm2(port); } -void disable_multimodule(uint32_t port) +void disable_sbusOut(uint32_t port) { disable_dsm2(port); } -#endif void init_crossfire(uint32_t port) { diff --git a/radio/src/targets/sky9x/board.h b/radio/src/targets/sky9x/board.h index c5b42359e..32500ff69 100644 --- a/radio/src/targets/sky9x/board.h +++ b/radio/src/targets/sky9x/board.h @@ -260,10 +260,8 @@ void disable_pxx(uint32_t port); void init_dsm2(uint32_t port); void disable_dsm2(uint32_t port); -#if defined(MULTIMODULE) -void init_multimodule(uint32_t module_index); -void disable_multimodule(uint32_t module_index); -#endif +void init_sbusOut(uint32_t module_index); +void disable_sbusOut(uint32_t module_index); // SD driver #if defined(SIMU) diff --git a/radio/src/targets/sky9x/pulses_driver.cpp b/radio/src/targets/sky9x/pulses_driver.cpp index 3557ab906..be6156f12 100644 --- a/radio/src/targets/sky9x/pulses_driver.cpp +++ b/radio/src/targets/sky9x/pulses_driver.cpp @@ -244,8 +244,7 @@ void disable_dsm2(uint32_t port) } } -#if defined(MULTIMODULE) -void init_multimodule(uint32_t port) +void init_sbusOut(uint32_t port) { if (port == EXTERNAL_MODULE) { init_main_ppm(3500 * 2, 0); @@ -256,11 +255,10 @@ void init_multimodule(uint32_t port) } } -void disable_multimodule(uint32_t port) +void disable_sbusOut(uint32_t port) { disable_dsm2(port); } -#endif #if !defined(SIMU) extern "C" void PWM_IRQHandler(void) @@ -321,6 +319,9 @@ extern "C" void PWM_IRQHandler(void) #if defined(MULTIMODULE) case PROTO_MULTIMODULE: +#endif + case PROTO_SBUS: + // Todo: how to do inverted polarity on this platform? // Alternate periods of 5.5mS and 3.5 mS period = pwmptr->PWM_CH_NUM[3].PWM_CPDR; if (period == 3500 * 2) { @@ -341,7 +342,6 @@ extern "C" void PWM_IRQHandler(void) sscptr->SSC_PTCR = SSC_PTCR_TXTEN; // Start transfers } break; -#endif default: pwmptr->PWM_CH_NUM[3].PWM_CPDRUPD = *modulePulsesData[EXTERNAL_MODULE].ppm.ptr++; diff --git a/radio/src/targets/taranis/board.h b/radio/src/targets/taranis/board.h index 87d593c48..83ad2095a 100644 --- a/radio/src/targets/taranis/board.h +++ b/radio/src/targets/taranis/board.h @@ -194,11 +194,8 @@ void init_dsm2( uint32_t module_index ); void disable_dsm2( uint32_t module_index ); void init_crossfire( uint32_t module_index ); void disable_crossfire( uint32_t module_index ); - -#if defined(MULTIMODULE) -void init_multimodule(uint32_t module_index); -void disable_multimodule(uint32_t module_index); -#endif +void init_sbusOut(uint32_t module_index); +void disable_sbusOut(uint32_t module_index); // Trainer driver void init_trainer_ppm(void); diff --git a/radio/src/targets/taranis/extmodule_driver.cpp b/radio/src/targets/taranis/extmodule_driver.cpp index 2667e4297..431004060 100644 --- a/radio/src/targets/taranis/extmodule_driver.cpp +++ b/radio/src/targets/taranis/extmodule_driver.cpp @@ -117,7 +117,7 @@ void extmodulePxxStart() EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz) EXTMODULE_TIMER->ARR = 18000; - EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | TIM_CCER_CC1NE; + EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | TIM_CCER_CC1NE; //polarity, default low EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs EXTMODULE_TIMER->CCR1 = 18; EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0; // Force O/P high @@ -220,7 +220,9 @@ void extmoduleSendNextFrame() EXTMODULE_DMA_STREAM->NDTR = modulePulsesData[EXTERNAL_MODULE].pxx.ptr - modulePulsesData[EXTERNAL_MODULE].pxx.pulses; EXTMODULE_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA } - else if (IS_DSM2_PROTOCOL(s_current_protocol[EXTERNAL_MODULE]) || IS_MULTIMODULE_PROTOCOL(s_current_protocol[EXTERNAL_MODULE])) { + else if (IS_DSM2_PROTOCOL(s_current_protocol[EXTERNAL_MODULE]) || IS_MULTIMODULE_PROTOCOL(s_current_protocol[EXTERNAL_MODULE]) || IS_SBUS_PROTOCOL(s_current_protocol[EXTERNAL_MODULE])) { + if (IS_SBUS_PROTOCOL(s_current_protocol[EXTERNAL_MODULE])) + EXTMODULE_TIMER->CCER = TIM_CCER_CC1NE | (GET_SBUS_POLARITY(EXTERNAL_MODULE) ? TIM_CCER_CC1NP : 0); // reverse polarity for Sbus if needed EXTMODULE_TIMER->CCR2 = *(modulePulsesData[EXTERNAL_MODULE].dsm2.ptr - 1) - 4000; // 2mS in advance EXTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA EXTMODULE_DMA_STREAM->CR |= EXTMODULE_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1; diff --git a/radio/src/targets/taranis/pulses_driver.cpp b/radio/src/targets/taranis/pulses_driver.cpp index fcbc04909..750a41a72 100644 --- a/radio/src/targets/taranis/pulses_driver.cpp +++ b/radio/src/targets/taranis/pulses_driver.cpp @@ -71,17 +71,15 @@ void disable_dsm2(uint32_t port) } #endif -#if defined(MULTIMODULE) -void init_multimodule(uint32_t port) +void init_sbusOut(uint32_t port) { init_dsm2(port); } -void disable_multimodule(uint32_t port) +void disable_sbusOut(uint32_t port) { disable_dsm2(port); } -#endif void init_ppm(uint32_t port) diff --git a/radio/src/translations.cpp b/radio/src/translations.cpp index 0f7bb3098..946d5d821 100644 --- a/radio/src/translations.cpp +++ b/radio/src/translations.cpp @@ -161,6 +161,10 @@ const pm_char STR_USE_GLOBAL_FUNCS[] PROGMEM = TR_USE_GLOBAL_FUNCS; #endif const pm_char STR_PROTO[] PROGMEM = TR_PROTO; const pm_char STR_PPMFRAME[] PROGMEM = TR_PPMFRAME; +#if defined(CPUARM) +const pm_char STR_REFRESHRATE[] PROGMEM = TR_REFRESHRATE; +const pm_char SSTR_WARN_BATTVOLTAGE[] PROGMEM = STR_WARN_BATTVOLTAGE; +#endif const pm_char STR_MS[] PROGMEM = TR_MS; const pm_char STR_SWITCH[] PROGMEM = TR_SWITCH; const pm_char STR_TRIMS[] PROGMEM = TR_TRIMS; diff --git a/radio/src/translations.h b/radio/src/translations.h index c3ad87885..08b514550 100644 --- a/radio/src/translations.h +++ b/radio/src/translations.h @@ -410,6 +410,10 @@ extern const pm_char STR_USE_GLOBAL_FUNCS[]; #endif extern const pm_char STR_PROTO[]; extern const pm_char STR_PPMFRAME[]; +#if defined(CPUARM) +extern const pm_char STR_REFRESHRATE[]; +extern const pm_char SSTR_WARN_BATTVOLTAGE[]; +#endif extern const pm_char STR_MS[]; extern const pm_char STR_SWITCH[]; extern const pm_char STR_TRIMS[]; diff --git a/radio/src/translations/cz.h.txt b/radio/src/translations/cz.h.txt index efc0a1889..83ea90643 100644 --- a/radio/src/translations/cz.h.txt +++ b/radio/src/translations/cz.h.txt @@ -96,7 +96,7 @@ #define TR_USBMODES TR("Ask\0 ""Joyst\0""SDCard""Serial", "Ask\0 ""Joystick""Storage\0""Serial\0 ") #define LEN_TARANIS_PROTOCOLS "\004" -#define TR_TARANIS_PROTOCOLS "Vyp\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0" +#define TR_TARANIS_PROTOCOLS "Vyp\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0""SBUS" #define LEN_TELEMETRY_PROTOCOLS "\017" #define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 FrSky D\0 FrSky D (kabel)Spektrum\0 " @@ -650,6 +650,8 @@ #define TR_PROTO INDENT "Protokol" #if defined(CPUARM) #define TR_PPMFRAME INDENT "PPM frame" +#define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate") +#define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ") #else #define TR_PPMFRAME "PPM frame" #endif diff --git a/radio/src/translations/de.h.txt b/radio/src/translations/de.h.txt index 53e6820ea..13956dd90 100644 --- a/radio/src/translations/de.h.txt +++ b/radio/src/translations/de.h.txt @@ -102,7 +102,7 @@ #define TR_USBMODES TR("Fragen""Joyst\0""SDCard""Serial", "Fragen\0 ""Joystick""Speicher""Seriell\0") #define LEN_TARANIS_PROTOCOLS "\004" -#define TR_TARANIS_PROTOCOLS "AUS\0""PPM\0""XJT\0""DSM?""CRSF""MULT""R9M\0" +#define TR_TARANIS_PROTOCOLS "AUS\0""PPM\0""XJT\0""DSM?""CRSF""MULT""R9M\0""SBUS" #define LEN_TELEMETRY_PROTOCOLS "\017" #define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 ""FrSky D\0 ""FrSky D (Kabel)""TBS Crossfire\0 ""Spektrum\0 ""AFHDS2A IBUS\0 ""Multi Telemetry" @@ -670,6 +670,8 @@ #define TR_PROTO TR(INDENT "Protok.", INDENT "Protokoll") #if defined(CPUARM) #define TR_PPMFRAME INDENT "PPM frame" +#define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate") +#define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ") #else #define TR_PPMFRAME "PPM frame" #endif diff --git a/radio/src/translations/en.h.txt b/radio/src/translations/en.h.txt index 0b72d96cb..d16083c21 100644 --- a/radio/src/translations/en.h.txt +++ b/radio/src/translations/en.h.txt @@ -102,7 +102,7 @@ #define TR_USBMODES TR("Ask\0 ""Joyst\0""SDCard""Serial", "Ask\0 ""Joystick""Storage\0""Serial\0 ") #define LEN_TARANIS_PROTOCOLS "\004" -#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0" +#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0""SBUS" #define LEN_TELEMETRY_PROTOCOLS "\017" #define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 ""FrSky D\0 ""FrSky D (cable)""TBS Crossfire\0 ""Spektrum\0 ""AFHDS2A IBUS\0 ""Multi Telemetry" @@ -653,6 +653,8 @@ #define TR_PROTO TR(INDENT "Proto", INDENT "Protocol") #if defined(CPUARM) #define TR_PPMFRAME INDENT "PPM frame" + #define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate") + #define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ") #else #define TR_PPMFRAME "PPM frame" #endif diff --git a/radio/src/translations/es.h.txt b/radio/src/translations/es.h.txt index 9b17e0f5b..8c01ef78b 100644 --- a/radio/src/translations/es.h.txt +++ b/radio/src/translations/es.h.txt @@ -98,7 +98,7 @@ #define TR_USBMODES TR("Ask\0 ""Joyst\0""SDCard""Serial", "Ask\0 ""Joystick""Storage\0""Serial\0 ") #define LEN_TARANIS_PROTOCOLS "\004" -#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0" +#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0""SBUS" #define LEN_TELEMETRY_PROTOCOLS "\017" #define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 ""FrSky D\0 ""FrSky D (cable)""TBS Crossfire\0 ""Spektrum\0 ""AFHDS2A IBUS\0 ""Multi Telemetry" @@ -643,6 +643,8 @@ #endif #define TR_PROTO TR(INDENT"Proto",INDENT"Protocol") #define TR_PPMFRAME "Trama PPM" +#define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate") +#define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ") #define TR_MS "ms" #define TR_SWITCH "Interr" #define TR_TRIMS "Trims" diff --git a/radio/src/translations/fi.h.txt b/radio/src/translations/fi.h.txt index 038ef1599..0655993bd 100644 --- a/radio/src/translations/fi.h.txt +++ b/radio/src/translations/fi.h.txt @@ -98,7 +98,7 @@ #define TR_USBMODES TR("Ask\0 ""Joyst\0""SDCard""Serial", "Ask\0 ""Joystick""Storage\0""Serial\0 ") #define LEN_TARANIS_PROTOCOLS "\004" -#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0" +#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0""SBUS" #define LEN_TELEMETRY_PROTOCOLS "\017" #define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 ""FrSky D\0 ""FrSky D (cable)""TBS Crossfire\0 ""Spektrum\0 ""AFHDS2A IBUS\0 ""Multi Telemetry" @@ -639,6 +639,8 @@ #endif #define TR_PROTO TR(INDENT "Proto", INDENT "Protocol") #define TR_PPMFRAME TR("PPM frame", INDENT "PPM frame") +#define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate") +#define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ") #define TR_MS "ms" #define TR_SWITCH "Switch" #define TR_TRIMS "Trims" diff --git a/radio/src/translations/fr.h.txt b/radio/src/translations/fr.h.txt index c31ce2e05..edd9a0ba0 100644 --- a/radio/src/translations/fr.h.txt +++ b/radio/src/translations/fr.h.txt @@ -98,7 +98,7 @@ #define TR_USBMODES TR("Popup\0""Joyst\0""SDCard""Série\0", "Demander""Joystick""Stockage""Série\0 ") #define LEN_TARANIS_PROTOCOLS "\004" -#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0" +#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0""SBUS" #define LEN_TELEMETRY_PROTOCOLS "\017" #define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 ""FrSky D\0 ""FrSky D (cable)""TBS Crossfire\0 ""Spektrum\0 ""AFHDS2A IBUS\0 ""Multi Telemetry" @@ -657,6 +657,8 @@ #define TR_PROTO TR(INDENT "Proto.", INDENT "Protocole") #if defined(CPUARM) #define TR_PPMFRAME INDENT "Trame PPM" +#define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate") +#define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ") #else #define TR_PPMFRAME "Trame PPM" #endif diff --git a/radio/src/translations/it.h.txt b/radio/src/translations/it.h.txt index 81cdbb80c..c1d76c576 100644 --- a/radio/src/translations/it.h.txt +++ b/radio/src/translations/it.h.txt @@ -98,7 +98,7 @@ #define TR_USBMODES TR("Ask\0 ""Joyst\0""SDCard""Serial", "Ask\0 ""Joystick""Storage\0""Serial\0 ") #define LEN_TARANIS_PROTOCOLS "\004" -#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0" +#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0""SBUS" #define LEN_TELEMETRY_PROTOCOLS "\017" #define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 ""FrSky D\0 ""FrSky D (cable)""TBS Crossfire\0 ""Spektrum\0 ""AFHDS2A IBUS\0 ""Multi Telemetry" @@ -655,6 +655,8 @@ #define TR_PROTO TR(INDENT "Proto", INDENT "Protocollo") #if defined(CPUARM) #define TR_PPMFRAME INDENT "PPM frame" +#define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate") +#define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ") #else #define TR_PPMFRAME "PPM frame" #endif diff --git a/radio/src/translations/nl.h.txt b/radio/src/translations/nl.h.txt index b2b1b684c..6130bdbeb 100644 --- a/radio/src/translations/nl.h.txt +++ b/radio/src/translations/nl.h.txt @@ -103,7 +103,7 @@ #define TR_USBMODES TR("Ask\0 ""Joyst\0""SDCard""Serial", "Ask\0 ""Joystick""Storage\0""Serial\0 ") #define LEN_TARANIS_PROTOCOLS "\004" -#define TR_TARANIS_PROTOCOLS "UIT\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0" +#define TR_TARANIS_PROTOCOLS "UIT\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0""SBUS" #define LEN_TELEMETRY_PROTOCOLS "\017" #define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 ""FrSky D\0 ""FrSky D (cable)""TBS Crossfire\0 ""Spektrum\0 ""AFHDS2A IBUS\0 ""Multi Telemetry" @@ -643,6 +643,8 @@ #define TR_PROTO TR(INDENT "Proto", INDENT "Protocol") #if defined(CPUARM) #define TR_PPMFRAME INDENT "PPM frame" +#define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate") +#define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ") #else #define TR_PPMFRAME "PPM frame" #endif diff --git a/radio/src/translations/pl.h.txt b/radio/src/translations/pl.h.txt index ff186a8cd..1dfc4b9d7 100644 --- a/radio/src/translations/pl.h.txt +++ b/radio/src/translations/pl.h.txt @@ -99,7 +99,7 @@ #define TR_USBMODES TR("Ask\0 ""Joyst\0""SDCard""Serial", "Ask\0 ""Joystick""Storage\0""Serial\0 ") #define LEN_TARANIS_PROTOCOLS "\004" -#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0" +#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0""SBUS" #define LEN_TELEMETRY_PROTOCOLS "\017" #define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 ""FrSky D\0 ""FrSky D (cable)""TBS Crossfire\0 ""Spektrum\0 ""AFHDS2A IBUS\0 ""Multi Telemetry" @@ -657,6 +657,8 @@ #define TR_PROTO TR(INDENT "Proto", INDENT "Protokół") #if defined(CPUARM) #define TR_PPMFRAME INDENT "Ramka PPM" +#define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate") +#define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ") #else #define TR_PPMFRAME INDENT "Ramka PPM" #endif diff --git a/radio/src/translations/pt.h.txt b/radio/src/translations/pt.h.txt index 27f1bca65..46a87a705 100644 --- a/radio/src/translations/pt.h.txt +++ b/radio/src/translations/pt.h.txt @@ -98,7 +98,7 @@ #define TR_USBMODES TR("Ask\0 ""Joyst\0""SDCard""Serial", "Ask\0 ""Joystick""Storage\0""Serial\0 ") #define LEN_TARANIS_PROTOCOLS "\004" -#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0" +#define TR_TARANIS_PROTOCOLS "OFF\0""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0""SBUS" #define LEN_TELEMETRY_PROTOCOLS "\017" #define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 ""FrSky D\0 ""FrSky D (cable)""TBS Crossfire\0 ""Spektrum\0 ""AFHDS2A IBUS\0 ""Multi Telemetry" @@ -644,6 +644,8 @@ #endif #define TR_PROTO INDENT"Proto" #define TR_PPMFRAME "PPM frame" +#define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate") +#define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ") #define TR_MS "ms" #define TR_SWITCH "Chave" #define TR_TRIMS "Trims" diff --git a/radio/src/translations/se.h.txt b/radio/src/translations/se.h.txt index 1916e6176..b6233f8e6 100644 --- a/radio/src/translations/se.h.txt +++ b/radio/src/translations/se.h.txt @@ -98,7 +98,7 @@ #define TR_USBMODES TR("Ask\0 ""Joyst\0""SDCard""Serial", "Ask\0 ""Joystick""Storage\0""Serial\0 ") #define LEN_TARANIS_PROTOCOLS "\004" -#define TR_TARANIS_PROTOCOLS "Av\0 ""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0" +#define TR_TARANIS_PROTOCOLS "Av\0 ""PPM\0""XJT\0""DSM2""CRSF""MULT""R9M\0""SBUS" #define LEN_TELEMETRY_PROTOCOLS "\017" #define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 ""FrSky D\0 ""FrSky D (cable)""TBS Crossfire\0 ""Spektrum\0 ""AFHDS2A IBUS\0 ""Multi Telemetry" @@ -668,6 +668,8 @@ #define TR_PROTO TR(INDENT "Proto", INDENT "Protokoll") #if defined(CPUARM) #define TR_PPMFRAME INDENT "PPM-paket" +#define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate") +#define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ") #else #define TR_PPMFRAME "PPM-paket" #endif