chore(dsmp): separate DSMP and DSM2, cleanup code, add DSMP status display and Enable AETR option (#6932)
Co-authored-by: Peter Feerick <peter.feerick@gmail.com>
This commit is contained in:
@@ -259,6 +259,7 @@ Node convert<ModuleData>::encode(const ModuleData& rhs)
|
||||
case PULSES_LEMON_DSMP: {
|
||||
Node dsmp;
|
||||
dsmp["flags"] = rhs.dsmp.flags;
|
||||
dsmp["enableAETR"] = (int)rhs.dsmp.enableAETR;
|
||||
mod["dsmp"] = dsmp;
|
||||
} break;
|
||||
case PULSES_FLYSKY_AFHDS2A: {
|
||||
@@ -419,6 +420,7 @@ bool convert<ModuleData>::decode(const Node& node, ModuleData& rhs)
|
||||
} else if (mod["dsmp"]) {
|
||||
Node dsmp = mod["dsmp"];
|
||||
dsmp["flags"] >> rhs.dsmp.flags;
|
||||
dsmp["enableAETR"] >> rhs.dsmp.enableAETR;
|
||||
} else if (mod["flysky"]) {
|
||||
Node flysky = mod["flysky"];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
|
||||
@@ -213,6 +213,7 @@ class ModuleData {
|
||||
|
||||
struct DSMP {
|
||||
unsigned int flags;
|
||||
bool enableAETR;
|
||||
} dsmp;
|
||||
|
||||
void clear();
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
#define MASK_AFHDS (1<<22)
|
||||
#define MASK_CSRF_ARMING_MODE (1<<23)
|
||||
#define MASK_CSRF_ARMING_TRIGGER (1<<24)
|
||||
#define MASK_ENABLE_AETR (1<<25)
|
||||
|
||||
quint8 ModulePanel::failsafesValueDisplayType = ModulePanel::FAILSAFE_DISPLAY_PERCENT;
|
||||
|
||||
@@ -409,7 +410,7 @@ void ModulePanel::update()
|
||||
mask |= MASK_CHANNELS_RANGE| MASK_CHANNELS_COUNT | MASK_FAILSAFES | MASK_AFHDS;
|
||||
break;
|
||||
case PULSES_LEMON_DSMP:
|
||||
mask |= MASK_CHANNELS_RANGE;
|
||||
mask |= MASK_CHANNELS_RANGE | MASK_ENABLE_AETR;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -448,6 +449,8 @@ void ModulePanel::update()
|
||||
ui->channelsCount->setMaximum(module.getMaxChannelCount());
|
||||
ui->channelsCount->setValue(module.channelsCount);
|
||||
ui->channelsCount->setSingleStep(firmware->getCapability(HasPPMStart) ? 1 : 2);
|
||||
|
||||
// CRSF
|
||||
ui->label_crsfArmingMode->setVisible(mask & MASK_CSRF_ARMING_MODE);
|
||||
ui->crsfArmingMode->setVisible(mask & MASK_CSRF_ARMING_MODE);
|
||||
ui->crsfArmingTrigger->setVisible(mask & MASK_CSRF_ARMING_TRIGGER);
|
||||
@@ -611,6 +614,12 @@ void ModulePanel::update()
|
||||
ui->raw12bits->setChecked(module.ghost.raw12bits);
|
||||
}
|
||||
|
||||
// DSMP settings fields
|
||||
ui->enableAETR->setVisible(mask & MASK_ENABLE_AETR);
|
||||
if (mask & MASK_ENABLE_AETR) {
|
||||
ui->enableAETR->setChecked(module.dsmp.enableAETR);
|
||||
}
|
||||
|
||||
if (mask & MASK_ACCESS) {
|
||||
ui->rx1->setText(module.access.receiverName[0]);
|
||||
ui->rx2->setText(module.access.receiverName[1]);
|
||||
@@ -632,7 +641,7 @@ void ModulePanel::update()
|
||||
ui->clearRx3->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1 << 2)));
|
||||
ui->rx3->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1 << 2)));
|
||||
|
||||
// AFHFS
|
||||
// AFHDS2A / AFHDS3
|
||||
if (mask & MASK_AFHDS) {
|
||||
if (protocol == PULSES_FLYSKY_AFHDS2A) {
|
||||
ui->label_afhds->setText(tr("Options"));
|
||||
@@ -915,6 +924,11 @@ void ModulePanel::on_raw12bits_stateChanged(int state)
|
||||
module.ghost.raw12bits = (state == Qt::Checked);
|
||||
}
|
||||
|
||||
void ModulePanel::on_enableAETR_stateChanged(int state)
|
||||
{
|
||||
module.dsmp.enableAETR = (state == Qt::Checked);
|
||||
}
|
||||
|
||||
void ModulePanel::on_racingMode_stateChanged(int state)
|
||||
{
|
||||
module.access.racingMode = (state == Qt::Checked);
|
||||
|
||||
@@ -70,6 +70,7 @@ class ModulePanel : public ModelPanel
|
||||
void on_autoBind_stateChanged(int state);
|
||||
void on_disableChMap_stateChanged(int state);
|
||||
void on_raw12bits_stateChanged(int state);
|
||||
void on_enableAETR_stateChanged(int state);
|
||||
void on_racingMode_stateChanged(int state);
|
||||
void on_disableTelem_stateChanged(int state);
|
||||
void on_lowPower_stateChanged(int state);
|
||||
|
||||
@@ -399,7 +399,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="0" colspan="2">
|
||||
<item row="17" column="0" colspan="2">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
@@ -429,14 +429,14 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="15" column="0">
|
||||
<item row="16" column="0">
|
||||
<widget class="QLabel" name="label_crsfArmingMode">
|
||||
<property name="text">
|
||||
<string>Arm using</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="1">
|
||||
<item row="16" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_crsfarm">
|
||||
<item>
|
||||
<widget class="QComboBox" name="crsfArmingMode"/>
|
||||
@@ -446,6 +446,13 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="15" column="1">
|
||||
<widget class="QCheckBox" name="enableAETR">
|
||||
<property name="text">
|
||||
<string>Enable AETR</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
|
||||
@@ -234,6 +234,9 @@ QString ModelPrinter::printModule(int idx)
|
||||
if (module.protocol == PULSES_GHOST) {
|
||||
str << printLabelValue(tr("Raw 12 bits"), printBoolean(module.ghost.raw12bits, BOOLEAN_YN));
|
||||
}
|
||||
if (module.protocol == PULSES_LEMON_DSMP) {
|
||||
str << printLabelValue(tr("Enable AETR"), printBoolean(module.dsmp.enableAETR, BOOLEAN_YN));
|
||||
}
|
||||
if (module.protocol == PULSES_CROSSFIRE) {
|
||||
str << printLabelValue(tr("Arming mode"), module.crsfArmingModeToString());
|
||||
if (module.crsf.crsfArmingMode == ModuleData::CRSF_ARMING_MODE_SWITCH) {
|
||||
|
||||
@@ -575,6 +575,7 @@ PACK(struct ModuleData {
|
||||
}) crsf);
|
||||
NOBACKUP(struct {
|
||||
uint8_t flags;
|
||||
uint8_t enableAETR : 1;
|
||||
} dsmp);
|
||||
} NAME(mod) FUNC(select_mod_type);
|
||||
|
||||
|
||||
@@ -194,6 +194,10 @@ enum MenuModelSetupItems {
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_AFHDS3_MODE,
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_AFHDS3_STATUS,
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_AFHDS3_POWER_STATUS,
|
||||
#endif
|
||||
#if defined(DSMP)
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_DSMP_STATUS,
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_DSMP_ENABLE_AETR,
|
||||
#endif
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_CHANNELS,
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_NOT_ACCESS_RXNUM_BIND_RANGE,
|
||||
@@ -542,6 +546,7 @@ void editTimerCountdown(int timerIdx, coord_t y, LcdFlags attr, event_t event)
|
||||
MULTIMODULE_STATUS_ROWS(EXTERNAL_MODULE) \
|
||||
AFHDS3_PROTOCOL_ROW(EXTERNAL_MODULE) \
|
||||
AFHDS3_MODE_ROWS(EXTERNAL_MODULE) \
|
||||
DSMP_STATUS_ROWS(EXTERNAL_MODULE) \
|
||||
MODULE_CHANNELS_ROWS(EXTERNAL_MODULE), \
|
||||
IF_NOT_ACCESS_MODULE_RF(EXTERNAL_MODULE, MODULE_BIND_ROWS(EXTERNAL_MODULE)), /* line reused for PPM: PPM settings */ \
|
||||
IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), /* RxNum */ \
|
||||
@@ -2125,12 +2130,13 @@ void menuModelSetup(event_t event)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (isModuleDSMP(moduleIdx) &&
|
||||
(oldFlag != newFlag) &&
|
||||
#if defined(DSMP)
|
||||
if (isModuleDSMP(moduleIdx) && (oldFlag != newFlag) &&
|
||||
(oldFlag == MODULE_MODE_BIND)) {
|
||||
// Restart DSMP module when exiting bind mode
|
||||
restartModule(moduleIdx);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -2435,12 +2441,31 @@ void menuModelSetup(event_t event)
|
||||
#if defined(HARDWARE_EXTERNAL_MODULE)
|
||||
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_STATUS:
|
||||
#endif
|
||||
#endif
|
||||
#if defined(AFHDS3) && defined(HARDWARE_EXTERNAL_MODULE)
|
||||
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_AFHDS3_STATUS:
|
||||
#endif
|
||||
#if (defined(MULTIMODULE) | defined(DSMP) | defined(AFHDS3)) && defined(HARDWARE_EXTERNAL_MODULE)
|
||||
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_DSMP_STATUS:
|
||||
{
|
||||
// MultiModule & LemonDSMP & AFHDS3 Status
|
||||
lcdDrawTextIndented(y, STR_MODULE_STATUS);
|
||||
getModuleStatusString(moduleIdx, reusableBuffer.moduleSetup.msg);
|
||||
lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, reusableBuffer.moduleSetup.msg);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if defined(DSMP) && defined(HARDWARE_EXTERNAL_MODULE)
|
||||
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_DSMP_ENABLE_AETR:
|
||||
g_model.moduleData[EXTERNAL_MODULE].dsmp.enableAETR =
|
||||
editCheckBox(g_model.moduleData[EXTERNAL_MODULE].dsmp.enableAETR,
|
||||
MODEL_SETUP_2ND_COLUMN, y, STR_DSMP_ENABLE_AETR, attr,
|
||||
event, INDENT_WIDTH);
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(MULTIMODULE)
|
||||
#if defined(HARDWARE_INTERNAL_MODULE)
|
||||
case ITEM_MODEL_SETUP_INTERNAL_MODULE_SYNCSTATUS:
|
||||
#endif
|
||||
@@ -2456,14 +2481,6 @@ void menuModelSetup(event_t event)
|
||||
#endif
|
||||
|
||||
#if defined(AFHDS3) && defined(HARDWARE_EXTERNAL_MODULE)
|
||||
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_AFHDS3_STATUS: {
|
||||
lcdDrawTextIndented(y, STR_MODULE_STATUS);
|
||||
|
||||
char statusText[64];
|
||||
getModuleStatusString(moduleIdx, statusText);
|
||||
lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, statusText);
|
||||
break;
|
||||
}
|
||||
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_AFHDS3_POWER_STATUS: {
|
||||
lcdDrawTextIndented(y, STR_AFHDS3_POWER_SOURCE);
|
||||
char statusText[64];
|
||||
|
||||
@@ -139,6 +139,10 @@ enum MenuModelSetupItems {
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_AFHDS3_MODE,
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_AFHDS3_STATUS,
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_AFHDS3_POWER_STATUS,
|
||||
#endif
|
||||
#if defined(DSMP)
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_DSMP_STATUS,
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_DSMP_ENABLE_AETR,
|
||||
#endif
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_CHANNELS,
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_NOT_ACCESS_RXNUM_BIND_RANGE,
|
||||
@@ -561,6 +565,7 @@ void menuModelSetup(event_t event)
|
||||
MULTIMODULE_TYPE_ROW(EXTERNAL_MODULE) // ITEM_MODEL_SETUP_EXTERNAL_MODULE_PROTOCOL
|
||||
MULTIMODULE_DSM_CLONED_RAW(EXTERNAL_MODULE), // ITEM_MODEL_SETUP_EXTERNAL_MODULE_DSM_CLONED
|
||||
MULTIMODULE_STATUS_ROWS(EXTERNAL_MODULE) // ITEM_MODEL_SETUP_EXTERNAL_MODULE_STATUS + ITEM_MODEL_SETUP_EXTERNAL_MODULE_SYNCSTATUS
|
||||
DSMP_STATUS_ROWS(EXTERNAL_MODULE) // ITEM_MODEL_SETUP_EXTERNAL_MODULE_DSMP_STATUS
|
||||
AFHDS3_MODE_ROWS(EXTERNAL_MODULE) // ITEM_MODEL_SETUP_EXTERNAL_MODULE_AFHDS3_MODE + ITEM_MODEL_SETUP_EXTERNAL_MODULE_AFHDS3_STATUS + ITEM_MODEL_SETUP_EXTERNAL_MODULE_AFHDS3_POWER_STATUS
|
||||
MODULE_CHANNELS_ROWS(EXTERNAL_MODULE), // ITEM_MODEL_SETUP_EXTERNAL_MODULE_CHANNELS
|
||||
IF_NOT_ACCESS_MODULE_RF(EXTERNAL_MODULE, MODULE_BIND_ROWS(EXTERNAL_MODULE)), // ITEM_MODEL_SETUP_EXTERNAL_MODULE_NOT_ACCESS_RXNUM_BIND_RANGE
|
||||
@@ -1619,12 +1624,13 @@ void menuModelSetup(event_t event)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (isModuleDSMP(moduleIdx) &&
|
||||
(oldFlag != newFlag) &&
|
||||
#if defined(DSMP)
|
||||
if (isModuleDSMP(moduleIdx) && (oldFlag != newFlag) &&
|
||||
(oldFlag == MODULE_MODE_BIND)) {
|
||||
// Restart DSMP module when exiting bind mode
|
||||
restartModule(moduleIdx);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1834,11 +1840,33 @@ void menuModelSetup(event_t event)
|
||||
|
||||
#if defined (MULTIMODULE)
|
||||
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_STATUS:
|
||||
#endif
|
||||
#if defined(AFHDS3)
|
||||
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_AFHDS3_STATUS:
|
||||
#endif
|
||||
#if defined(DSMP)
|
||||
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_DSMP_STATUS:
|
||||
#endif
|
||||
#if (defined(DSMP) || defined(MULTIMODULE) || defined(AFHDS3))
|
||||
{
|
||||
// MultiModule & LemonDSMP & AFHDS Status
|
||||
lcdDrawTextIndented(y, STR_MODULE_STATUS);
|
||||
getModuleStatusString(EXTERNAL_MODULE, reusableBuffer.moduleSetup.msg);
|
||||
lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, reusableBuffer.moduleSetup.msg);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(DSMP)
|
||||
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_DSMP_ENABLE_AETR:
|
||||
g_model.moduleData[EXTERNAL_MODULE].dsmp.enableAETR =
|
||||
editCheckBox(g_model.moduleData[EXTERNAL_MODULE].dsmp.enableAETR,
|
||||
MODEL_SETUP_2ND_COLUMN, y, STR_DSMP_ENABLE_AETR, attr,
|
||||
event, INDENT_WIDTH);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(MULTIMODULE) && defined(HARDWARE_EXTERNAL_MODULE)
|
||||
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_SYNCSTATUS:
|
||||
lcdDrawTextIndented(y, STR_MODULE_SYNC);
|
||||
getModuleSyncStatusString(EXTERNAL_MODULE, reusableBuffer.moduleSetup.msg);
|
||||
@@ -1852,14 +1880,6 @@ void menuModelSetup(event_t event)
|
||||
lcdDrawText(MODEL_SETUP_2ND_COLUMN, y,
|
||||
g_model.moduleData[EXTERNAL_MODULE].afhds3.telemetry ? STR_AFHDS3_ONE_TO_ONE_TELEMETRY : TR_AFHDS3_ONE_TO_MANY);
|
||||
break;
|
||||
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_AFHDS3_STATUS:
|
||||
{
|
||||
lcdDrawTextIndented(y, TR_MODULE_STATUS);
|
||||
char statusText[64];
|
||||
getModuleStatusString(EXTERNAL_MODULE, statusText);
|
||||
lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, statusText);
|
||||
break;
|
||||
}
|
||||
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_AFHDS3_POWER_STATUS:
|
||||
{
|
||||
lcdDrawTextIndented(y, STR_AFHDS3_POWER_SOURCE);
|
||||
|
||||
@@ -109,6 +109,10 @@ macro(add_gui_src src)
|
||||
)
|
||||
endmacro(add_gui_src)
|
||||
|
||||
if(DSMP)
|
||||
add_gui_src(module/dsmp_settings.cpp)
|
||||
endif()
|
||||
|
||||
if(LUA)
|
||||
add_gui_src(standalone_lua.cpp)
|
||||
set(SRC ${SRC}
|
||||
|
||||
@@ -118,6 +118,13 @@ void ModuleChannelRange::update()
|
||||
{
|
||||
ChannelRange::update();
|
||||
|
||||
#if defined(DSMP)
|
||||
if (isModuleDSMP(moduleIdx)) {
|
||||
// Disable Ch start, module asume starting in Ch1
|
||||
chStart->enable(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
auto min_mod_ch = minModuleChannels(moduleIdx);
|
||||
auto max_mod_ch = maxModuleChannels(moduleIdx);
|
||||
chEnd->enable(min_mod_ch < max_mod_ch);
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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 "dsmp_settings.h"
|
||||
|
||||
#include "choice.h"
|
||||
#include "edgetx.h"
|
||||
|
||||
#define SET_DIRTY() storageDirty(EE_MODEL)
|
||||
|
||||
struct DSMPEnableAETR : public FormLine {
|
||||
DSMPEnableAETR(Window* form, FlexGridLayout& layout, uint8_t moduleIdx) :
|
||||
FormLine(form, layout)
|
||||
{
|
||||
new StaticText(this, rect_t{}, STR_DSMP_ENABLE_AETR);
|
||||
|
||||
auto md = &g_model.moduleData[moduleIdx];
|
||||
|
||||
cb = new ToggleSwitch(this, rect_t{}, GET_SET_DEFAULT(md->dsmp.enableAETR));
|
||||
}
|
||||
|
||||
void update()
|
||||
{
|
||||
show();
|
||||
cb->update();
|
||||
}
|
||||
|
||||
private:
|
||||
ToggleSwitch* cb;
|
||||
};
|
||||
|
||||
DSMPSettings::DSMPSettings(Window* parent,
|
||||
const FlexGridLayout& g,
|
||||
uint8_t moduleIdx) :
|
||||
Window(parent, rect_t{}),
|
||||
md(&g_model.moduleData[moduleIdx]),
|
||||
moduleIdx(moduleIdx)
|
||||
{
|
||||
FlexGridLayout grid(g);
|
||||
setFlexLayout();
|
||||
|
||||
// DSMP status
|
||||
auto line = newLine(grid);
|
||||
new StaticText(line, rect_t{}, STR_MODULE_STATUS);
|
||||
new DynamicText(
|
||||
line, rect_t{},
|
||||
[=] {
|
||||
char msg[64] = "";
|
||||
getModuleStatusString(moduleIdx, msg);
|
||||
return std::string(msg);
|
||||
});
|
||||
|
||||
enableAETR_line = new DSMPEnableAETR(this, grid, moduleIdx);
|
||||
|
||||
// Ensure elements properly initalised
|
||||
update();
|
||||
}
|
||||
|
||||
void DSMPSettings::update() {
|
||||
enableAETR_line->update();
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "window.h"
|
||||
#include "module_setup.h"
|
||||
|
||||
class ToggleSwitch;
|
||||
|
||||
struct ModuleData;
|
||||
struct DSMPEnableAETR;
|
||||
|
||||
class DSMPSettings : public Window, public ModuleOptions
|
||||
{
|
||||
ModuleData* md;
|
||||
uint8_t moduleIdx;
|
||||
DSMPEnableAETR *enableAETR_line;
|
||||
|
||||
public:
|
||||
DSMPSettings(Window* parent, const FlexGridLayout& g,
|
||||
uint8_t moduleIdx);
|
||||
void update() override;
|
||||
};
|
||||
@@ -65,6 +65,10 @@
|
||||
#include "multi_rfprotos.h"
|
||||
#endif
|
||||
|
||||
#if defined(DSMP)
|
||||
#include "dsmp_settings.h"
|
||||
#endif
|
||||
|
||||
#define SET_DIRTY() storageDirty(EE_MODEL)
|
||||
|
||||
#define ETX_STATE_UNIQUE_ID_WARN LV_STATE_USER_1
|
||||
@@ -163,6 +167,11 @@ class ModuleWindow : public Window
|
||||
modOpts = new PXX1AntennaSettings(this, grid, moduleIdx);
|
||||
}
|
||||
#endif
|
||||
#if defined(DSMP)
|
||||
else if (isModuleDSMP(moduleIdx)) {
|
||||
modOpts = new DSMPSettings(this, grid, moduleIdx);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Channel Range
|
||||
auto line = newLine(grid);
|
||||
|
||||
@@ -152,10 +152,10 @@ if (event == EVT_ENTRY) {
|
||||
y += FH;
|
||||
continue;
|
||||
}
|
||||
#if defined(MULTIMODULE)
|
||||
if (isModuleMultimodule(module)) {
|
||||
#if defined(MULTIMODULE) || defined(DSMP)
|
||||
if (isModuleMultimodule(module) || isModuleDSMP(module)) {
|
||||
char statusText[64] = "";
|
||||
getMultiModuleStatus(module).getStatusString(statusText);
|
||||
getModuleStatusString(module,statusText);
|
||||
lcdDrawText(COLUMN2_X, y, statusText);
|
||||
y += FH;
|
||||
continue;
|
||||
|
||||
@@ -218,6 +218,12 @@ extern uint8_t MULTIMODULE_HASOPTIONS(uint8_t moduleIdx);
|
||||
#define AFHDS3_MODULE_ROWS(moduleIdx)
|
||||
#endif
|
||||
|
||||
#if defined(DSMP)
|
||||
#define DSMP_STATUS_ROWS(moduleIdx) isModuleDSMP(moduleIdx) ? TITLE_ROW : HIDDEN_ROW, isModuleDSMP(moduleIdx) ? (uint8_t) 0 : HIDDEN_ROW,
|
||||
#else
|
||||
#define DSMP_STATUS_ROWS(moduleIdx)
|
||||
#endif
|
||||
|
||||
#define FAILSAFE_ROW(moduleIdx) isModuleFailsafeAvailable(moduleIdx) ? (g_model.moduleData[moduleIdx].failsafeMode==FAILSAFE_CUSTOM ? (uint8_t)1 : (uint8_t)0) : HIDDEN_ROW
|
||||
|
||||
extern uint8_t MODULE_OPTION_ROW(uint8_t moduleIdx);
|
||||
|
||||
@@ -38,6 +38,10 @@
|
||||
#include "pulses/multi.h"
|
||||
#endif
|
||||
|
||||
#if defined(DSMP)
|
||||
#include "pulses/dsmp.h"
|
||||
#endif
|
||||
|
||||
/*luadoc
|
||||
@function model.getInfo()
|
||||
|
||||
@@ -138,6 +142,9 @@ Get RF module parameters
|
||||
* 12 R9M_LITE_PRO_PXX2
|
||||
* 13 SBUS
|
||||
* 14 XJT_LITE_PXX2
|
||||
* 15 MODULE_TYPE_FLYSKY_AFHDS3,
|
||||
* 16 ??
|
||||
* 17 MODULE_TYPE_LEMON_DSMP
|
||||
|
||||
`subType` values for XJT_PXX1:
|
||||
* -1 OFF
|
||||
@@ -159,6 +166,8 @@ Get RF module parameters
|
||||
* `protocol` (number) protocol number (Multi only)
|
||||
* `subProtocol` (number) sub-protocol number (Multi only)
|
||||
* `channelsOrder` (number) first 4 channels expected order (Multi only)
|
||||
* if the module type is LemonDSMP additional info is available
|
||||
* `channelsOrder` (number) first 4 channels expected order (DSMP only)
|
||||
|
||||
@status current Introduced in 2.2.0
|
||||
*/
|
||||
@@ -189,6 +198,16 @@ static int luaModelGetModule(lua_State *L)
|
||||
lua_pushtableinteger(L, "channelsOrder", -1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(DSMP)
|
||||
if (module.type == MODULE_TYPE_LEMON_DSMP) {
|
||||
auto& status = getDSMPStatus(idx);
|
||||
int ch_order = -1;
|
||||
if (status.isValid() && status.ch_order != 0xFF) {
|
||||
ch_order = status.ch_order;
|
||||
}
|
||||
lua_pushtableinteger(L, "channelsOrder", ch_order);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
|
||||
+46
-183
@@ -24,7 +24,6 @@
|
||||
#include "mixer_scheduler.h"
|
||||
|
||||
#include "edgetx.h"
|
||||
#include "telemetry/spektrum.h"
|
||||
|
||||
#define DSM2_SEND_BIND (1 << 7)
|
||||
#define DSM2_SEND_RANGECHECK (1 << 5)
|
||||
@@ -41,11 +40,48 @@
|
||||
|
||||
static bool _bind_restart = false;
|
||||
|
||||
static inline void sendByte(uint8_t*& p_buf, uint8_t b)
|
||||
const etx_serial_init dsmUartParams = {
|
||||
.baudrate = 0,
|
||||
.encoding = ETX_Encoding_8N1,
|
||||
.direction = ETX_Dir_TX,
|
||||
.polarity = ETX_Pol_Inverted,
|
||||
};
|
||||
|
||||
etx_module_state_t* dsmInit(uint8_t module, uint32_t baudrate,
|
||||
uint16_t period, bool telemetry)
|
||||
{
|
||||
*p_buf++ = b;
|
||||
// only external module supported
|
||||
if (module == INTERNAL_MODULE) return nullptr;
|
||||
|
||||
etx_serial_init params(dsmUartParams);
|
||||
params.baudrate = baudrate;
|
||||
auto mod_st = modulePortInitSerial(module, ETX_MOD_PORT_UART, ¶ms, true);
|
||||
if (!mod_st) return nullptr;
|
||||
|
||||
if (telemetry) {
|
||||
params.direction = ETX_Dir_RX;
|
||||
modulePortInitSerial(module, ETX_MOD_PORT_SPORT, ¶ms, true);
|
||||
}
|
||||
|
||||
mixerSchedulerSetPeriod(module, period);
|
||||
return mod_st;
|
||||
}
|
||||
|
||||
void dsmDeInit(void* ctx)
|
||||
{
|
||||
auto mod_st = (etx_module_state_t*)ctx;
|
||||
modulePortDeInit(mod_st);
|
||||
}
|
||||
|
||||
static void* dsm2Init(uint8_t module)
|
||||
{
|
||||
auto mod_st = dsmInit(module, DSM2_BITRATE, DSM2_PERIOD, false);
|
||||
mod_st->user_data = (void*)(uintptr_t)g_model.moduleData[module].subType;
|
||||
return (void*)mod_st;
|
||||
}
|
||||
|
||||
static inline void sendByte(uint8_t*& p_buf, uint8_t b) { *p_buf++ = b; }
|
||||
|
||||
static void setupPulsesDSM2(uint8_t module, uint8_t type, uint8_t*& p_buf)
|
||||
{
|
||||
uint8_t dsmDat[DSM2_FRAME_SIZE];
|
||||
@@ -99,160 +135,20 @@ static void setupPulsesDSM2(uint8_t module, uint8_t type, uint8_t*& p_buf)
|
||||
}
|
||||
}
|
||||
|
||||
#define DSMP_BITRATE 115200
|
||||
|
||||
static void setupPulsesLemonDSMP(uint8_t module, uint8_t*& p_buf)
|
||||
static void dsm2SendPulses(void* ctx, uint8_t* buffer, int16_t* channels,
|
||||
uint8_t nChannels)
|
||||
{
|
||||
static uint8_t pass = 0;
|
||||
|
||||
const auto& md = g_model.moduleData[module];
|
||||
|
||||
uint8_t start_channel = md.channelsStart;
|
||||
auto channels = md.getChannelsCount();
|
||||
auto flags = md.dsmp.flags & 0x3F;
|
||||
|
||||
// Force setup packet in Bind mode.
|
||||
auto module_mode = getModuleMode(module);
|
||||
|
||||
sendByte(p_buf, 0xAA);
|
||||
sendByte(p_buf, pass);
|
||||
|
||||
// Setup packet
|
||||
if (pass == 0) {
|
||||
|
||||
if (module_mode == MODULE_MODE_BIND) {
|
||||
flags = DSM2_SEND_BIND | (1 << 6 /* AUTO */);
|
||||
channels = 12;
|
||||
}
|
||||
sendByte(p_buf, flags);
|
||||
|
||||
uint8_t pwr = 7;
|
||||
if (module_mode == MODULE_MODE_RANGECHECK) {
|
||||
pwr = 4;
|
||||
}
|
||||
sendByte(p_buf, pwr);
|
||||
sendByte(p_buf, channels );
|
||||
|
||||
// Model number
|
||||
sendByte(p_buf, 1);
|
||||
|
||||
// Send only 1 single Setup packet
|
||||
pass = 1;
|
||||
|
||||
} else {
|
||||
|
||||
uint8_t current_channel = 0;
|
||||
if (pass == 2) {
|
||||
current_channel += 7;
|
||||
}
|
||||
|
||||
// Send channels
|
||||
for (int i=0; i<7; i++) {
|
||||
|
||||
if (current_channel < channels) {
|
||||
|
||||
uint8_t channel = start_channel + current_channel;
|
||||
int value = channelOutputs[channel] + 2*PPM_CH_CENTER(channel) - 2*PPM_CENTER;
|
||||
uint16_t pulse;
|
||||
|
||||
// Use 11-bit ?
|
||||
if (flags & (1 << 2)) {
|
||||
pulse = limit(0, ((value*349)>>9)+1024, 2047) | (current_channel << 11);
|
||||
} else {
|
||||
pulse = limit(0, ((value*13)>>5)+512, 1023) | (current_channel << 10);
|
||||
}
|
||||
|
||||
sendByte(p_buf, pulse >> 8);
|
||||
sendByte(p_buf, pulse & 0xFF);
|
||||
} else {
|
||||
// Outside of announced number of channels:
|
||||
// -> send invalid value
|
||||
sendByte(p_buf, 0xFF);
|
||||
sendByte(p_buf, 0xFF);
|
||||
}
|
||||
current_channel++;
|
||||
}
|
||||
}
|
||||
|
||||
if (++pass > 2) pass = 1;
|
||||
if (channels < 8) pass = 1;
|
||||
|
||||
if (module_mode == MODULE_MODE_BIND) {
|
||||
// bind packet is setup
|
||||
pass = 0;
|
||||
}
|
||||
else if (--moduleState[module].counter == 0) {
|
||||
// every 100th packet is setup
|
||||
pass = 0;
|
||||
moduleState[module].counter = 100;
|
||||
}
|
||||
}
|
||||
|
||||
const etx_serial_init dsmUartParams = {
|
||||
.baudrate = 0,
|
||||
.encoding = ETX_Encoding_8N1,
|
||||
.direction = ETX_Dir_TX,
|
||||
.polarity = ETX_Pol_Inverted,
|
||||
};
|
||||
|
||||
static etx_module_state_t* dsmInit(uint8_t module, uint32_t baudrate,
|
||||
uint16_t period, bool telemetry)
|
||||
{
|
||||
// only external module supported
|
||||
if (module == INTERNAL_MODULE) return nullptr;
|
||||
|
||||
etx_serial_init params(dsmUartParams);
|
||||
params.baudrate = baudrate;
|
||||
auto mod_st = modulePortInitSerial(module, ETX_MOD_PORT_UART, ¶ms, true);
|
||||
if (!mod_st) return nullptr;
|
||||
|
||||
if (telemetry) {
|
||||
params.direction = ETX_Dir_RX;
|
||||
modulePortInitSerial(module, ETX_MOD_PORT_SPORT, ¶ms, true);
|
||||
}
|
||||
|
||||
mixerSchedulerSetPeriod(module, period);
|
||||
return mod_st;
|
||||
}
|
||||
|
||||
static void* dsm2Init(uint8_t module)
|
||||
{
|
||||
auto mod_st = dsmInit(module, DSM2_BITRATE, DSM2_PERIOD, false);
|
||||
mod_st->user_data = (void*)(uintptr_t)g_model.moduleData[module].subType;
|
||||
return (void*)mod_st;
|
||||
}
|
||||
|
||||
static void* dsmpInit(uint8_t module)
|
||||
{
|
||||
return (void*)dsmInit(module, DSMP_BITRATE, 11 * 1000 /* 11ms in us */, true);
|
||||
}
|
||||
|
||||
static void dsmDeInit(void* ctx)
|
||||
{
|
||||
auto mod_st = (etx_module_state_t*)ctx;
|
||||
modulePortDeInit(mod_st);
|
||||
}
|
||||
|
||||
static void _dsm_send(etx_module_state_t* st, uint8_t* buffer, uint32_t len)
|
||||
{
|
||||
auto drv = modulePortGetSerialDrv(st->tx);
|
||||
auto ctx = modulePortGetCtx(st->tx);
|
||||
drv->sendBuffer(ctx, buffer, len);
|
||||
}
|
||||
|
||||
static void dsm2SendPulses(void* ctx, uint8_t* buffer, int16_t* channels, uint8_t nChannels)
|
||||
{
|
||||
// TODO:
|
||||
(void)channels;
|
||||
(void)nChannels;
|
||||
|
||||
auto mod_st = (etx_module_state_t*)ctx;
|
||||
auto module = modulePortGetModule(mod_st);
|
||||
auto drv = modulePortGetSerialDrv(mod_st->tx);
|
||||
auto drvCtx = modulePortGetCtx(mod_st->tx);
|
||||
|
||||
auto type = (uint8_t)(uintptr_t)mod_st->user_data;
|
||||
|
||||
auto p_data = buffer;
|
||||
setupPulsesDSM2(module, type, p_data);
|
||||
_dsm_send(mod_st, buffer, p_data - buffer);
|
||||
drv->sendBuffer(drvCtx, buffer, p_data - buffer);
|
||||
}
|
||||
|
||||
static void dsm2ConfigChange(void* ctx)
|
||||
@@ -267,28 +163,6 @@ static void dsm2ConfigChange(void* ctx)
|
||||
}
|
||||
}
|
||||
|
||||
static void dsmpSendPulses(void* ctx, uint8_t* buffer, int16_t* channels, uint8_t nChannels)
|
||||
{
|
||||
// TODO:
|
||||
(void)channels;
|
||||
(void)nChannels;
|
||||
|
||||
auto mod_st = (etx_module_state_t*)ctx;
|
||||
auto module = modulePortGetModule(mod_st);
|
||||
|
||||
auto p_data = buffer;
|
||||
setupPulsesLemonDSMP(module, p_data);
|
||||
_dsm_send(mod_st, buffer, p_data - buffer);
|
||||
}
|
||||
|
||||
static void dsmpProcessData(void* ctx, uint8_t data, uint8_t* buffer, uint8_t* len)
|
||||
{
|
||||
auto mod_st = (etx_module_state_t*)ctx;
|
||||
auto module = modulePortGetModule(mod_st);
|
||||
|
||||
processSpektrumTelemetryData(module, data, buffer, *len);
|
||||
}
|
||||
|
||||
// No telemetry
|
||||
const etx_proto_driver_t DSM2Driver = {
|
||||
.protocol = PROTOCOL_CHANNELS_DSM2,
|
||||
@@ -299,15 +173,4 @@ const etx_proto_driver_t DSM2Driver = {
|
||||
.processFrame = nullptr,
|
||||
.onConfigChange = dsm2ConfigChange,
|
||||
.txCompleted = modulePortSerialTxCompleted,
|
||||
};
|
||||
|
||||
const etx_proto_driver_t DSMPDriver = {
|
||||
.protocol = PROTOCOL_CHANNELS_DSMP,
|
||||
.init = dsmpInit,
|
||||
.deinit = dsmDeInit,
|
||||
.sendPulses = dsmpSendPulses,
|
||||
.processData = dsmpProcessData,
|
||||
.processFrame = nullptr,
|
||||
.onConfigChange = nullptr,
|
||||
.txCompleted = modulePortSerialTxCompleted,
|
||||
};
|
||||
};
|
||||
@@ -21,10 +21,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hal/module_port.h"
|
||||
#include "hal/module_driver.h"
|
||||
#include "timers_driver.h"
|
||||
|
||||
// DSM2/DSMX
|
||||
extern const etx_proto_driver_t DSM2Driver;
|
||||
|
||||
// Lemon RX DSMP
|
||||
extern const etx_proto_driver_t DSMPDriver;
|
||||
extern etx_module_state_t* dsmInit(uint8_t module, uint32_t baudrate,
|
||||
uint16_t period, bool telemetry);
|
||||
extern void dsmDeInit(void* ctx);
|
||||
extern const etx_proto_driver_t DSM2Driver;
|
||||
@@ -0,0 +1,537 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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 "dsmp.h"
|
||||
#include "hal/module_port.h"
|
||||
#include "mixer_scheduler.h"
|
||||
|
||||
#include "edgetx.h"
|
||||
#include "telemetry/spektrum.h"
|
||||
|
||||
#define DSMP_SEND_X_PLUS 0
|
||||
|
||||
#define DSMP_BITRATE 115200
|
||||
|
||||
#define MAX_REG_CHANNELS 12
|
||||
#define MAX_CHANNELS 20
|
||||
|
||||
// DSMP Flags
|
||||
#define DSMP_FLAGS_DSMX 0x01
|
||||
#define DSMP_FLAGS_DSM2 0x00
|
||||
#define DSMP_FLAGS_11mS 0x02
|
||||
#define DSMP_FLAGS_22mS 0x00
|
||||
#define DSMP_FLAGS_2048 0x04 // 11 bits
|
||||
#define DSMP_FLAGS_1024 0x00 // 10 bits
|
||||
#define DSMP_FLAGS_FUTABA 0x10 // Translate to AETR -> TAER
|
||||
// #define DSMP_FLAGS_DEVO 0x20
|
||||
#define DSMP_FLAGS_AUTO 0x40
|
||||
#define DSMP_FLAGS_BIND 0x80
|
||||
|
||||
#define DSMP_FLAGS_TXMODE (DSMP_FLAGS_DSMX | DSMP_FLAGS_11mS | DSMP_FLAGS_2048)
|
||||
|
||||
// DSMP Power Settings
|
||||
#define DSMP_POWER_NORMAL 7
|
||||
#define DSMP_POWER_RANGE 4
|
||||
|
||||
// Same Encoding as MultiModule (What channel is each of the functions)
|
||||
// R | T | E | A
|
||||
#define DSMP_CH_AETR ((3<<6)|(2<<4)|(1<<2)|0)
|
||||
#define DSMP_CH_TAER ((3<<6)|(0<<4)|(2<<2)|1)
|
||||
|
||||
#define DSMP_NO_CHANNEL 0xFF
|
||||
|
||||
// MAP AETR->TAER:
|
||||
static uint8_t AETR_TAER_MAP[] = {2, 0, 1};
|
||||
|
||||
static DSMPModuleStatus dsmpStatus = DSMPModuleStatus();
|
||||
|
||||
// Power cycle of the DSMP module
|
||||
// The DSMP module code has the channel data initialized to 0 and initial number of bits as 10b (ch resolution 1024)
|
||||
// The Setup message pass the last BIND configuration to the Module via the setup package (for example, 2048 it was bound to DSMX).
|
||||
// Scenario 1: Setup package processed by DSMP before Ch data
|
||||
// When the Setup package is received, will send the existing CH values (0), so servos will move to the side until valid
|
||||
// Ch data is received.
|
||||
// Scenario 2: Channel packed process by DSMP before Setup package
|
||||
// In this case, it will assume that the Ch data is encoded in 10bits instead of 2048 (if DSMX), then the servos move to
|
||||
// to extreme too.
|
||||
//
|
||||
// Both scenarios are not right, so initially send more frequently the Setup package (usualy every 2.2 sec), but will
|
||||
// be sent every 2 messages (66ms). There is still jump, but for an instant.
|
||||
// The only way to properly fix it is at the DSMP firmware level.. (fixed on DSMP V2).
|
||||
|
||||
|
||||
#define FAST_INITIAL_SETUP_COUNT 50 // 3*22*50=3.3 sec of sending fast status after module activation
|
||||
|
||||
// Using 22.06ms instead of 22ms for V1 module.. This is becuase the module try to send 4 RF
|
||||
// packets to the RX with with spacing 4/7/4/7 (22ms cycle) just after receiving
|
||||
// the message from the TX (perfect world). But the timing is not perfect on the
|
||||
// DSMP module, is really 4.025/7.033/4.025/6.x and the last will be cut too short
|
||||
// to 6.88 by the new TX message (needs to be at least 6.92, up to 7.05). That
|
||||
// can create problems in some RXs (Servos not moving smoth). Compensating for
|
||||
// that little extra delay to make the last closer to 7ms spacing.
|
||||
|
||||
#define SCHEDULER_PERIOD_V1 22060
|
||||
#define SCHEDULER_PERIOD_V2 11000
|
||||
|
||||
static uint8_t pass;
|
||||
static uint8_t pass0_counter;
|
||||
static uint8_t pass0_period;
|
||||
|
||||
static uint16_t fastSetup_count;
|
||||
|
||||
#if DSMP_SEND_X_PLUS
|
||||
static uint8_t x_plus_ch = 0;
|
||||
#endif
|
||||
|
||||
DSMPModuleStatus& getDSMPStatus(uint8_t module)
|
||||
{
|
||||
return dsmpStatus;
|
||||
}
|
||||
|
||||
static void* dsmpInit(uint8_t module)
|
||||
{
|
||||
TRACE("[DSMP] dsmpInit()");
|
||||
pass0_counter = 2; // Send Setup every 2 ch data packages
|
||||
pass = 1; // Start Sending channels
|
||||
pass0_period = 100; // Send pass0 every 100 messages
|
||||
fastSetup_count = FAST_INITIAL_SETUP_COUNT;
|
||||
return (void*)dsmInit(module, DSMP_BITRATE, SCHEDULER_PERIOD_V1, true);
|
||||
}
|
||||
|
||||
|
||||
static inline void sendByte(uint8_t*& p_buf, uint8_t b)
|
||||
{
|
||||
*p_buf++ = b;
|
||||
}
|
||||
|
||||
#if defined(LUA)
|
||||
static uint8_t isFPDataReady()
|
||||
{
|
||||
// Check for Forward Programming data
|
||||
// Multi_Buffer[0..2]=="DSM" -> Lua script is running
|
||||
// Multi_Buffer[3]==0x70 + len -> TX to RX data ready to be sent
|
||||
// Multi_Buffer[4..9]=6 bytes of TX to RX data
|
||||
return (Multi_Buffer && (Multi_Buffer[3] & 0xF8) == 0x70 &&
|
||||
memcmp(Multi_Buffer, "DSM", 3) == 0);
|
||||
}
|
||||
|
||||
static void sendFPLemonDSMP(uint8_t*& p_buf)
|
||||
{
|
||||
auto forwardProgLen = Multi_Buffer[3] & 0x0F;
|
||||
TRACE("LemonDSMP: DSMP FwdProg Send data len = [%d]", forwardProgLen);
|
||||
// Send Forward Prog Data (Includes Len + 6 bytes).. 9 bytes totat
|
||||
sendByte(p_buf, 0xAA);
|
||||
sendByte(p_buf, 3); // Pass=3
|
||||
|
||||
for (uint8_t i = 0; i < 7; i++) {
|
||||
sendByte(p_buf, Multi_Buffer[3 + i]);
|
||||
}
|
||||
|
||||
Multi_Buffer[3] = 0x00; // Data sent, clear LUA to send more
|
||||
}
|
||||
#endif
|
||||
|
||||
static void updateModuleStatus(uint8_t flags)
|
||||
{
|
||||
// Update Status
|
||||
dsmpStatus.lastUpdate = get_tmr10ms();
|
||||
dsmpStatus.flags = flags;
|
||||
dsmpStatus.ch_order = (flags & DSMP_FLAGS_FUTABA) ? DSMP_CH_AETR : DSMP_CH_TAER;
|
||||
}
|
||||
|
||||
static uint16_t getDSMPChannelValue(uint8_t module, uint8_t flags, uint8_t channel)
|
||||
{
|
||||
uint8_t txChannel = channel;
|
||||
// Map from AETR->TAER ???
|
||||
if ((flags & DSMP_FLAGS_FUTABA) && (channel < 3)) {
|
||||
txChannel = AETR_TAER_MAP[channel];
|
||||
}
|
||||
|
||||
int value = channelOutputs[txChannel] + 2 * PPM_CH_CENTER(txChannel) - 2 * PPM_CENTER;
|
||||
uint16_t pulse;
|
||||
|
||||
if (flags & DSMP_FLAGS_2048) { // Use 11-bit ?
|
||||
// Scale to 349/512=0.681, MultiModule is about 0.667
|
||||
pulse = limit(0, ((value * 349) >> 9) + 1024, 2047) | (channel << 11);
|
||||
} else {
|
||||
pulse = limit(0, ((value * 13) >> 5) + 512, 1023) | (channel << 10);
|
||||
}
|
||||
|
||||
return pulse;
|
||||
}
|
||||
|
||||
static void setupPulsesLemonDSMP(uint8_t module, uint8_t*& p_buf)
|
||||
{
|
||||
const auto modelId = g_model.header.modelId[module];
|
||||
/* const*/ auto& md = g_model.moduleData[module];
|
||||
|
||||
//uint8_t start_channel = md.channelsStart;
|
||||
auto channels = md.getChannelsCount();
|
||||
auto flags = md.dsmp.flags;
|
||||
auto module_mode = getModuleMode(module);
|
||||
auto version = dsmpStatus.version[0];
|
||||
|
||||
if (md.dsmp.enableAETR) { // Move GUI settings to flags
|
||||
flags |= DSMP_FLAGS_FUTABA;
|
||||
}
|
||||
|
||||
if (pass0_counter == pass0_period/2) {
|
||||
// update status String.. about each second
|
||||
updateModuleStatus(flags);
|
||||
}
|
||||
|
||||
#if defined(LUA)
|
||||
if ((version> 1) && isFPDataReady()) { // Sent any forward prog data??
|
||||
sendFPLemonDSMP(p_buf);
|
||||
Multi_Buffer[3] = 0x00; // Data sent, clear LUA to send more
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Send channel data
|
||||
sendByte(p_buf, 0xAA);
|
||||
sendByte(p_buf, pass);
|
||||
|
||||
// Setup packet
|
||||
if (pass == 0) {
|
||||
flags &= DSMP_FLAGS_TXMODE; // Only the TXMODE part
|
||||
|
||||
if (module_mode == MODULE_MODE_BIND) {
|
||||
flags = DSMP_FLAGS_BIND | DSMP_FLAGS_AUTO;
|
||||
channels = min<uint8_t>(channels, MAX_REG_CHANNELS);
|
||||
md.dsmp.flags = DSMP_FLAGS_DSMX | DSMP_FLAGS_11mS | DSMP_FLAGS_2048;
|
||||
storageDirty(EE_MODEL);
|
||||
}
|
||||
sendByte(p_buf, flags);
|
||||
|
||||
uint8_t pwr = DSMP_POWER_NORMAL;
|
||||
if (module_mode == MODULE_MODE_RANGECHECK) {
|
||||
pwr = DSMP_POWER_RANGE;
|
||||
}
|
||||
sendByte(p_buf, pwr);
|
||||
sendByte(p_buf, channels );
|
||||
sendByte(p_buf, modelId); // V1.0 ignores it, V2.0 use it
|
||||
|
||||
pass = 1; // move to send Ch data
|
||||
return;
|
||||
} else {
|
||||
#if DSMP_SEND_X_PLUS
|
||||
uint8_t xPlusEnabled = (version > 1) && (channels >= MAX_REG_CHANNELS) && (flags & DSMP_FLAGS_DSMX);
|
||||
#endif
|
||||
// Channel DATA messages
|
||||
uint8_t current_channel = 0;
|
||||
if (pass == 2) {
|
||||
current_channel += 7;
|
||||
}
|
||||
|
||||
// Send channels
|
||||
for (int i=0; i<7; i++) {
|
||||
uint16_t pulse = 0xFFFF; // NO-DATA
|
||||
uint8_t ch_to_send = DSMP_NO_CHANNEL;
|
||||
|
||||
if (current_channel < min<uint8_t>(channels,MAX_REG_CHANNELS)) {
|
||||
ch_to_send = current_channel;
|
||||
}
|
||||
|
||||
#if DSMP_SEND_X_PLUS
|
||||
else if (xPlusEnabled && (current_channel >= MAX_REG_CHANNELS)) {
|
||||
// X-plus channel multiplexing (Ch13-20)
|
||||
ch_to_send = MAX_REG_CHANNELS + x_plus_ch;
|
||||
x_plus_ch = (x_plus_ch + 1) % 8; // 8 X-plus channels
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ch_to_send != DSMP_NO_CHANNEL) {
|
||||
pulse = getDSMPChannelValue(module, flags, ch_to_send);
|
||||
}
|
||||
|
||||
sendByte(p_buf, pulse >> 8);
|
||||
sendByte(p_buf, pulse & 0xFF);
|
||||
current_channel++;
|
||||
} // For
|
||||
}
|
||||
|
||||
if (++pass > 2) pass = 1;
|
||||
if (channels < 8) pass = 1;
|
||||
|
||||
if (module_mode == MODULE_MODE_BIND) { // Force setup packet in Bind mode.
|
||||
pass = 0;
|
||||
} else if (--pass0_counter == 0) {
|
||||
pass = 0;
|
||||
updateModuleStatus(flags);
|
||||
if ((version == 1) && (fastSetup_count > 0)) {
|
||||
fastSetup_count--;
|
||||
pass0_counter = 2; // Keep sendint setup every 2 ch messages
|
||||
} else {
|
||||
pass0_counter = pass0_period; // restar counter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void dsmpSendPulses(void* ctx, uint8_t* buffer, int16_t* channels, uint8_t nChannels)
|
||||
{
|
||||
auto mod_st = (etx_module_state_t*)ctx;
|
||||
auto module = modulePortGetModule(mod_st);
|
||||
auto drv = modulePortGetSerialDrv(mod_st->tx);
|
||||
auto drvCtx = modulePortGetCtx(mod_st->tx);
|
||||
|
||||
auto p_data = buffer;
|
||||
setupPulsesLemonDSMP(module, p_data);
|
||||
drv->sendBuffer(drvCtx, buffer, p_data - buffer);
|
||||
}
|
||||
|
||||
/* The DSMP Bind Return Message contains:
|
||||
Byte
|
||||
0 Flags:
|
||||
Protocol: Maxk 0x01 0=DSM2, 1=DSMX
|
||||
RefreshCycle: Mask 0x02 0=22ms, 1=11ms
|
||||
Resolution: Mask 0x04 0=1024, 1=2048
|
||||
Bind: Mask 0x80 1=Enter Bind Mode (Output only)
|
||||
Bind_Auto: Mask 0x40 1=Use AutoBind (Output only)
|
||||
1 ?? Always 0x00; ?? RX type maybe
|
||||
2 Number of Channels (Up to 12)
|
||||
3 TX Mode:
|
||||
0x01 - DSM2 1024/22ms,
|
||||
0x02 - DSM2 1024/22ms >7 channels,
|
||||
0x11 - DSM2 2048/11ms
|
||||
0x12 - DSM2 2048/11ms >7 channels,
|
||||
0xa2 - DSMX 22ms > 7 channels,
|
||||
0xb2 - DSMX 11ms
|
||||
*/
|
||||
|
||||
static void processDSMPBindPacket(uint8_t module, uint8_t* packet)
|
||||
{
|
||||
uint8_t flags = packet[0];
|
||||
uint8_t rxType = packet[1];
|
||||
uint8_t channels = packet[2];
|
||||
uint8_t txMode = packet[3];
|
||||
|
||||
// save flags, only the TXMode Part
|
||||
g_model.moduleData[module].dsmp.flags = flags & DSMP_FLAGS_TXMODE;
|
||||
|
||||
// save number of channels
|
||||
if (channels > MAX_REG_CHANNELS) {
|
||||
channels = MAX_REG_CHANNELS;
|
||||
}
|
||||
g_model.moduleData[module].channelsCount = channels - 8;
|
||||
if (dsmpStatus.version[0] == 1) { // V1.0 always use modelId=0
|
||||
g_model.header.modelId[module] = 0;
|
||||
}
|
||||
|
||||
TRACE("[DSMP] DSMP bind packet: flags:0x%X / Ch: %i / TxMode =0x%X", flags & 0x3F, channels, txMode);
|
||||
|
||||
storageDirty(EE_MODEL);
|
||||
|
||||
/* Finally stop binding as the rx just told us that it is bound */
|
||||
if (getModuleMode(module) == MODULE_MODE_BIND) {
|
||||
setModuleMode(module, MODULE_MODE_NORMAL);
|
||||
}
|
||||
|
||||
// Convert DSMP bind to Spektrum compatible bind and continue with common Spektrum.cpp bind processing
|
||||
uint8_t newPacket[10] = {0, 0, 0, 0, rxType, channels, txMode, 0, 0, 0};
|
||||
processDSMBindPacket(newPacket);
|
||||
|
||||
// FARZU:.. The real problem was using module[moduleID].counter.. is actually used by the restart mechanism
|
||||
restartModuleAsync(module, 10); // ~100ms
|
||||
}
|
||||
|
||||
|
||||
static void processDSMPManufacturerData(uint8_t module, uint8_t* packet)
|
||||
{
|
||||
// Format M,M,M,M, V, V where M is 4 byte manufacturer data, and V is 2 byte
|
||||
dsmpStatus.version[0] = packet[4]; // Major
|
||||
dsmpStatus.version[1] = packet[5]; // Minor
|
||||
|
||||
TRACE("LemonDSMP: Ver [%d.%d]", dsmpStatus.version[0], dsmpStatus.version[1]);
|
||||
|
||||
if (dsmpStatus.version[0] > 1 && mixerSchedulerGetPeriod(module) != SCHEDULER_PERIOD_V2) {
|
||||
// V2 suppors 11ms
|
||||
mixerSchedulerSetPeriod(module, SCHEDULER_PERIOD_V2);
|
||||
pass0_period = 200; // extend period
|
||||
}
|
||||
}
|
||||
|
||||
static void dsmpTelemetryData(uint8_t module, uint8_t data,
|
||||
uint8_t* rxBuffer, uint8_t& rxBufferCount)
|
||||
{
|
||||
dsmpStatus.lastUpdate = get_tmr10ms();
|
||||
|
||||
if (rxBuffer[1] == 0x80 && rxBufferCount >= DSM_BIND_PACKET_LENGTH) {
|
||||
processDSMPBindPacket(module, rxBuffer + 2); // Skip 0xAA 0x80
|
||||
rxBufferCount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (rxBuffer[1] == 0xFF && rxBufferCount >= SPEKTRUM_TELEMETRY_LENGTH) {
|
||||
processDSMPManufacturerData(module, rxBuffer + 2); // Skip 0xAA 0xFF
|
||||
rxBufferCount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (rxBufferCount >= SPEKTRUM_TELEMETRY_LENGTH) {
|
||||
// Debug print content of Telemetry to console
|
||||
#if 0
|
||||
debugPrintf("[DSMP] Packet 0x%02X rssi 0x%02X: ic2 0x%02x, %02x: ",
|
||||
rxBuffer[0], rxBuffer[1], rxBuffer[2], rxBuffer[3]);
|
||||
for (int i=4; i<SPEKTRUM_TELEMETRY_LENGTH; i+=4) {
|
||||
debugPrintf("%02X%02X %02X%02X ", rxBuffer[i], rxBuffer[i + 1],
|
||||
rxBuffer[i + 2], rxBuffer[i + 3]);
|
||||
}
|
||||
debugPrintf(CRLF);
|
||||
#endif
|
||||
|
||||
processSpektrumPacket(rxBuffer);
|
||||
rxBufferCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void dsmpDebugData(uint8_t module, uint8_t data, uint8_t* rxBuffer,
|
||||
uint8_t& rxBufferCount)
|
||||
{
|
||||
// Format is: 0xAB, <len> <type> <data>
|
||||
if (rxBufferCount < 2) return; // Keep buiding
|
||||
|
||||
auto expectedLen = rxBuffer[1];
|
||||
|
||||
// Overflow???
|
||||
if (expectedLen + 2 > TELEMETRY_RX_PACKET_SIZE) {
|
||||
expectedLen = TELEMETRY_RX_PACKET_SIZE - 2;
|
||||
}
|
||||
|
||||
if (rxBufferCount >= expectedLen + 2) {
|
||||
// msg Completed
|
||||
auto dataType = rxBuffer[2];
|
||||
|
||||
if (dataType == 1) { // Debug Msg
|
||||
TRACE_NOCRLF("[DSMP] Debug: ");
|
||||
for (auto i = 0; i < expectedLen - 1; i++) {
|
||||
TRACE_NOCRLF("%c", rxBuffer[3 + i]);
|
||||
}
|
||||
TRACE(CRLF);
|
||||
}
|
||||
|
||||
rxBufferCount = 0; // Build new message
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void dsmpProcessData(void* ctx, uint8_t data, uint8_t* buffer,
|
||||
uint8_t* len)
|
||||
{
|
||||
auto mod_st = (etx_module_state_t*)ctx;
|
||||
auto module = modulePortGetModule(mod_st);
|
||||
|
||||
uint8_t& rxBufferCount = *len;
|
||||
|
||||
if (rxBufferCount == 0 && (data != 0xAA && data != 0xAB)) {
|
||||
TRACE("[DSMP] invalid start byte 0x%02X", data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rxBufferCount < TELEMETRY_RX_PACKET_SIZE) {
|
||||
|
||||
TRACE("[DSMP] Data 0x%02X, len = %d", data, rxBufferCount);
|
||||
buffer[rxBufferCount++] = data; // Keep building message
|
||||
} else {
|
||||
TRACE("[DSMP] array size %d error", rxBufferCount);
|
||||
rxBufferCount = 0;
|
||||
}
|
||||
|
||||
if (buffer[0] == 0xAA) { // Telemetry data or Bind
|
||||
dsmpTelemetryData(module, data, buffer, *len);
|
||||
} else if (buffer[0] == 0xAB) { // Status
|
||||
dsmpDebugData(module, data, buffer, *len);
|
||||
}
|
||||
}
|
||||
|
||||
void DSMPModuleStatus::getStatusString(char* statusText) const
|
||||
{
|
||||
if (!isValid()) {
|
||||
strcpy(statusText, STR_MODULE_NO_TELEMETRY);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& md = g_model.moduleData[EXTERNAL_MODULE];
|
||||
auto channels = md.getChannelsCount();
|
||||
|
||||
char* tmp = statusText;
|
||||
|
||||
// Version
|
||||
*tmp = 0;
|
||||
tmp = strAppend(tmp, "v", 1);
|
||||
tmp = strAppendUnsigned(tmp, dsmpStatus.version[0]);
|
||||
tmp = strAppend(tmp, ".", 1);
|
||||
tmp = strAppendUnsigned(tmp, dsmpStatus.version[1]);
|
||||
|
||||
char b[] = "? ";
|
||||
if (ch_order != 0xFF) { // Same encoding as MultiModule
|
||||
uint8_t temp = ch_order;
|
||||
b[temp & 0x03] = 'A';
|
||||
temp >>= 2;
|
||||
b[temp & 0x03] = 'E';
|
||||
temp >>= 2;
|
||||
b[temp & 0x03] = 'T';
|
||||
temp >>= 2;
|
||||
b[temp & 0x03] = 'R';
|
||||
}
|
||||
|
||||
tmp = strAppend(tmp, " ", 1);
|
||||
tmp = strAppend(tmp, b, strlen(b));
|
||||
|
||||
const char* mode;
|
||||
|
||||
mode = (flags & DSMP_FLAGS_DSMX) ? " X" : " 2"; // DSMX or DSM2
|
||||
tmp = strAppend(tmp, mode, strlen(mode));
|
||||
|
||||
mode = (flags & DSMP_FLAGS_11mS) ? "_2F" : "_1F"; // 1 or 2 Frames (11ms/22ms)
|
||||
tmp = strAppend(tmp, mode, strlen(mode));
|
||||
|
||||
#if 0
|
||||
// Good for Debugging, but not much for regular users
|
||||
|
||||
//mode = (flags & DSMP_FLAGS_2048) ? " 2048" : " 1024";
|
||||
//tmp = strAppend(tmp, mode, strlen(mode));
|
||||
|
||||
tmp = strAppend(tmp, " S:", 4);
|
||||
uint16_t servoRefresh = (mixerSchedulerGetPeriod(EXTERNAL_MODULE) / 1000);
|
||||
if (channels > 7) servoRefresh *= 2;
|
||||
tmp = strAppendUnsigned(tmp, servoRefresh);
|
||||
tmp = strAppend(tmp, "ms", 2);
|
||||
|
||||
servoRefresh = mixerSchedulerGetPeriod(EXTERNAL_MODULE);
|
||||
tmp = strAppend(tmp, " TX:", 5);
|
||||
tmp = strAppendUnsigned(tmp, servoRefresh);
|
||||
tmp = strAppend(tmp, "us", 2);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
const etx_proto_driver_t DSMPDriver = {
|
||||
.protocol = PROTOCOL_CHANNELS_DSMP,
|
||||
.init = dsmpInit,
|
||||
.deinit = dsmDeInit,
|
||||
.sendPulses = dsmpSendPulses,
|
||||
.processData = dsmpProcessData,
|
||||
.processFrame = nullptr,
|
||||
.onConfigChange = nullptr,
|
||||
.txCompleted = modulePortSerialTxCompleted,
|
||||
};
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTx
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "dsm2.h"
|
||||
|
||||
struct DSMPModuleStatus {
|
||||
uint8_t version[2] = {1, 0}; // Default Version 1.0
|
||||
tmr10ms_t lastUpdate;
|
||||
uint8_t ch_order = 0xFF;
|
||||
uint8_t flags = 0;
|
||||
|
||||
inline bool isValid() const { return (bool)(get_tmr10ms() - lastUpdate < 500);}
|
||||
void getStatusString(char *statusText) const;
|
||||
};
|
||||
|
||||
extern DSMPModuleStatus &getDSMPStatus(uint8_t module);
|
||||
|
||||
// Lemon RX DSMP
|
||||
extern const etx_proto_driver_t DSMPDriver;
|
||||
@@ -67,9 +67,8 @@ int8_t maxModuleChannels_M8(uint8_t moduleIdx)
|
||||
}
|
||||
} else if (isModuleMultimoduleDSM2(moduleIdx)) {
|
||||
return 4; // 12 channels
|
||||
} else if (isModuleDSMP(moduleIdx) &&
|
||||
(g_model.moduleData[moduleIdx].dsmp.flags != 0)) {
|
||||
return g_model.moduleData[moduleIdx].channelsCount;
|
||||
} else if (isModuleDSMP(moduleIdx)) {
|
||||
return 4; // 12 channels
|
||||
} else {
|
||||
return maxChannelsModules_M8[g_model.moduleData[moduleIdx].type];
|
||||
}
|
||||
@@ -129,6 +128,9 @@ void setModuleType(uint8_t moduleIdx, uint8_t moduleType)
|
||||
}
|
||||
else if (moduleData.type == MODULE_TYPE_FLYSKY_AFHDS3) {
|
||||
resetAfhds3Options(moduleIdx);
|
||||
}
|
||||
else if (moduleData.type == MODULE_TYPE_LEMON_DSMP) {
|
||||
restartModule(moduleIdx); // Restart DSMP when switching to it (example PPM->DSMP)
|
||||
}
|
||||
else
|
||||
resetAccessAuthenticationCount();
|
||||
|
||||
@@ -487,7 +487,7 @@ inline int8_t minModuleChannels(uint8_t idx)
|
||||
else if (isModuleSBUS(idx))
|
||||
return 16;
|
||||
else if (isModuleDSMP(idx))
|
||||
return maxModuleChannels(idx);
|
||||
return 1; // FARZU: module assume always start with Ch1. Was: maxModuleChannels(idx);
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
@@ -532,6 +532,9 @@ inline bool isModuleRxNumAvailable(uint8_t moduleIdx)
|
||||
if (isModuleCrossfire(moduleIdx))
|
||||
return true;
|
||||
|
||||
if (isModuleDSMP(moduleIdx))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -557,6 +560,9 @@ inline bool isModuleModelIndexAvailable(uint8_t idx)
|
||||
|
||||
if (isModuleAFHDS3(idx))
|
||||
return true;
|
||||
|
||||
if (isModuleDSMP(idx))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,14 @@
|
||||
|
||||
#include "pulses/pxx2.h"
|
||||
#include "pulses/flysky.h"
|
||||
|
||||
#if defined(DSM2)
|
||||
#include "pulses/dsm2.h"
|
||||
#endif
|
||||
|
||||
#if defined(DSMP)
|
||||
#include "pulses/dsmp.h"
|
||||
#endif
|
||||
|
||||
#if defined(PPM)
|
||||
#include "pulses/ppm.h"
|
||||
@@ -228,6 +235,12 @@ void getModuleStatusString(uint8_t moduleIdx, char * statusText)
|
||||
afhds3::getStatusString(moduleIdx, statusText);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(DSMP)
|
||||
if (isModuleDSMP(moduleIdx)) {
|
||||
getDSMPStatus(moduleIdx).getStatusString(statusText);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void getModuleSyncStatusString(uint8_t moduleIdx, char * statusText)
|
||||
|
||||
@@ -633,6 +633,7 @@ static const struct YamlNode struct_anonymous_12[] = {
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_13[] = {
|
||||
YAML_UNSIGNED( "flags", 8 ),
|
||||
YAML_UNSIGNED( "enableAETR", 1 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
@@ -646,7 +647,7 @@ static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
YAML_STRUCT("afhds3", 16, struct_anonymous_10, NULL),
|
||||
YAML_STRUCT("ghost", 8, struct_anonymous_11, NULL),
|
||||
YAML_STRUCT("crsf", 24, struct_anonymous_12, NULL),
|
||||
YAML_STRUCT("dsmp", 8, struct_anonymous_13, NULL),
|
||||
YAML_STRUCT("dsmp", 16, struct_anonymous_13, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModuleData[] = {
|
||||
|
||||
@@ -701,6 +701,7 @@ static const struct YamlNode struct_anonymous_12[] = {
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_13[] = {
|
||||
YAML_UNSIGNED( "flags", 8 ),
|
||||
YAML_UNSIGNED( "enableAETR", 1 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
@@ -714,7 +715,7 @@ static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
YAML_STRUCT("afhds3", 16, struct_anonymous_10, NULL),
|
||||
YAML_STRUCT("ghost", 8, struct_anonymous_11, NULL),
|
||||
YAML_STRUCT("crsf", 24, struct_anonymous_12, NULL),
|
||||
YAML_STRUCT("dsmp", 8, struct_anonymous_13, NULL),
|
||||
YAML_STRUCT("dsmp", 16, struct_anonymous_13, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModuleData[] = {
|
||||
|
||||
@@ -657,6 +657,7 @@ static const struct YamlNode struct_anonymous_12[] = {
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_13[] = {
|
||||
YAML_UNSIGNED( "flags", 8 ),
|
||||
YAML_UNSIGNED( "enableAETR", 1 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
@@ -670,7 +671,7 @@ static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
YAML_STRUCT("afhds3", 16, struct_anonymous_10, NULL),
|
||||
YAML_STRUCT("ghost", 8, struct_anonymous_11, NULL),
|
||||
YAML_STRUCT("crsf", 24, struct_anonymous_12, NULL),
|
||||
YAML_STRUCT("dsmp", 8, struct_anonymous_13, NULL),
|
||||
YAML_STRUCT("dsmp", 16, struct_anonymous_13, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModuleData[] = {
|
||||
|
||||
@@ -692,6 +692,7 @@ static const struct YamlNode struct_anonymous_12[] = {
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_13[] = {
|
||||
YAML_UNSIGNED( "flags", 8 ),
|
||||
YAML_UNSIGNED( "enableAETR", 1 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
@@ -705,7 +706,7 @@ static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
YAML_STRUCT("afhds3", 16, struct_anonymous_10, NULL),
|
||||
YAML_STRUCT("ghost", 8, struct_anonymous_11, NULL),
|
||||
YAML_STRUCT("crsf", 24, struct_anonymous_12, NULL),
|
||||
YAML_STRUCT("dsmp", 8, struct_anonymous_13, NULL),
|
||||
YAML_STRUCT("dsmp", 16, struct_anonymous_13, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModuleData[] = {
|
||||
|
||||
@@ -699,6 +699,7 @@ static const struct YamlNode struct_anonymous_12[] = {
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_13[] = {
|
||||
YAML_UNSIGNED( "flags", 8 ),
|
||||
YAML_UNSIGNED( "enableAETR", 1 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
@@ -712,7 +713,7 @@ static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
YAML_STRUCT("afhds3", 16, struct_anonymous_10, NULL),
|
||||
YAML_STRUCT("ghost", 8, struct_anonymous_11, NULL),
|
||||
YAML_STRUCT("crsf", 24, struct_anonymous_12, NULL),
|
||||
YAML_STRUCT("dsmp", 8, struct_anonymous_13, NULL),
|
||||
YAML_STRUCT("dsmp", 16, struct_anonymous_13, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModuleData[] = {
|
||||
|
||||
@@ -724,6 +724,7 @@ static const struct YamlNode struct_anonymous_12[] = {
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_13[] = {
|
||||
YAML_UNSIGNED( "flags", 8 ),
|
||||
YAML_UNSIGNED( "enableAETR", 1 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
@@ -737,7 +738,7 @@ static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
YAML_STRUCT("afhds3", 16, struct_anonymous_10, NULL),
|
||||
YAML_STRUCT("ghost", 8, struct_anonymous_11, NULL),
|
||||
YAML_STRUCT("crsf", 24, struct_anonymous_12, NULL),
|
||||
YAML_STRUCT("dsmp", 8, struct_anonymous_13, NULL),
|
||||
YAML_STRUCT("dsmp", 16, struct_anonymous_13, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModuleData[] = {
|
||||
|
||||
@@ -699,6 +699,7 @@ static const struct YamlNode struct_anonymous_12[] = {
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_13[] = {
|
||||
YAML_UNSIGNED( "flags", 8 ),
|
||||
YAML_UNSIGNED( "enableAETR", 1 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
@@ -712,7 +713,7 @@ static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
YAML_STRUCT("afhds3", 16, struct_anonymous_10, NULL),
|
||||
YAML_STRUCT("ghost", 8, struct_anonymous_11, NULL),
|
||||
YAML_STRUCT("crsf", 24, struct_anonymous_12, NULL),
|
||||
YAML_STRUCT("dsmp", 8, struct_anonymous_13, NULL),
|
||||
YAML_STRUCT("dsmp", 16, struct_anonymous_13, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModuleData[] = {
|
||||
|
||||
@@ -692,6 +692,7 @@ static const struct YamlNode struct_anonymous_12[] = {
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_13[] = {
|
||||
YAML_UNSIGNED( "flags", 8 ),
|
||||
YAML_UNSIGNED( "enableAETR", 1 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
@@ -705,7 +706,7 @@ static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
YAML_STRUCT("afhds3", 16, struct_anonymous_10, NULL),
|
||||
YAML_STRUCT("ghost", 8, struct_anonymous_11, NULL),
|
||||
YAML_STRUCT("crsf", 24, struct_anonymous_12, NULL),
|
||||
YAML_STRUCT("dsmp", 8, struct_anonymous_13, NULL),
|
||||
YAML_STRUCT("dsmp", 16, struct_anonymous_13, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModuleData[] = {
|
||||
|
||||
@@ -724,6 +724,7 @@ static const struct YamlNode struct_anonymous_12[] = {
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_13[] = {
|
||||
YAML_UNSIGNED( "flags", 8 ),
|
||||
YAML_UNSIGNED( "enableAETR", 1 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
@@ -737,7 +738,7 @@ static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
YAML_STRUCT("afhds3", 16, struct_anonymous_10, NULL),
|
||||
YAML_STRUCT("ghost", 8, struct_anonymous_11, NULL),
|
||||
YAML_STRUCT("crsf", 24, struct_anonymous_12, NULL),
|
||||
YAML_STRUCT("dsmp", 8, struct_anonymous_13, NULL),
|
||||
YAML_STRUCT("dsmp", 16, struct_anonymous_13, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModuleData[] = {
|
||||
|
||||
@@ -709,6 +709,7 @@ static const struct YamlNode struct_anonymous_12[] = {
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_13[] = {
|
||||
YAML_UNSIGNED( "flags", 8 ),
|
||||
YAML_UNSIGNED( "enableAETR", 1 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
@@ -722,7 +723,7 @@ static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
YAML_STRUCT("afhds3", 16, struct_anonymous_10, NULL),
|
||||
YAML_STRUCT("ghost", 8, struct_anonymous_11, NULL),
|
||||
YAML_STRUCT("crsf", 24, struct_anonymous_12, NULL),
|
||||
YAML_STRUCT("dsmp", 8, struct_anonymous_13, NULL),
|
||||
YAML_STRUCT("dsmp", 16, struct_anonymous_13, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModuleData[] = {
|
||||
|
||||
@@ -724,6 +724,7 @@ static const struct YamlNode struct_anonymous_12[] = {
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_13[] = {
|
||||
YAML_UNSIGNED( "flags", 8 ),
|
||||
YAML_UNSIGNED( "enableAETR", 1 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
@@ -737,7 +738,7 @@ static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
YAML_STRUCT("afhds3", 16, struct_anonymous_10, NULL),
|
||||
YAML_STRUCT("ghost", 8, struct_anonymous_11, NULL),
|
||||
YAML_STRUCT("crsf", 24, struct_anonymous_12, NULL),
|
||||
YAML_STRUCT("dsmp", 8, struct_anonymous_13, NULL),
|
||||
YAML_STRUCT("dsmp", 16, struct_anonymous_13, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModuleData[] = {
|
||||
|
||||
@@ -642,6 +642,7 @@ static const struct YamlNode struct_anonymous_12[] = {
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_13[] = {
|
||||
YAML_UNSIGNED( "flags", 8 ),
|
||||
YAML_UNSIGNED( "enableAETR", 1 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
@@ -655,7 +656,7 @@ static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
YAML_STRUCT("afhds3", 16, struct_anonymous_10, NULL),
|
||||
YAML_STRUCT("ghost", 8, struct_anonymous_11, NULL),
|
||||
YAML_STRUCT("crsf", 24, struct_anonymous_12, NULL),
|
||||
YAML_STRUCT("dsmp", 8, struct_anonymous_13, NULL),
|
||||
YAML_STRUCT("dsmp", 16, struct_anonymous_13, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModuleData[] = {
|
||||
|
||||
@@ -642,6 +642,7 @@ static const struct YamlNode struct_anonymous_12[] = {
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_13[] = {
|
||||
YAML_UNSIGNED( "flags", 8 ),
|
||||
YAML_UNSIGNED( "enableAETR", 1 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
@@ -655,7 +656,7 @@ static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
YAML_STRUCT("afhds3", 16, struct_anonymous_10, NULL),
|
||||
YAML_STRUCT("ghost", 8, struct_anonymous_11, NULL),
|
||||
YAML_STRUCT("crsf", 24, struct_anonymous_12, NULL),
|
||||
YAML_STRUCT("dsmp", 8, struct_anonymous_13, NULL),
|
||||
YAML_STRUCT("dsmp", 16, struct_anonymous_13, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModuleData[] = {
|
||||
|
||||
@@ -724,6 +724,7 @@ static const struct YamlNode struct_anonymous_12[] = {
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_13[] = {
|
||||
YAML_UNSIGNED( "flags", 8 ),
|
||||
YAML_UNSIGNED( "enableAETR", 1 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
@@ -737,7 +738,7 @@ static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
YAML_STRUCT("afhds3", 16, struct_anonymous_10, NULL),
|
||||
YAML_STRUCT("ghost", 8, struct_anonymous_11, NULL),
|
||||
YAML_STRUCT("crsf", 24, struct_anonymous_12, NULL),
|
||||
YAML_STRUCT("dsmp", 8, struct_anonymous_13, NULL),
|
||||
YAML_STRUCT("dsmp", 16, struct_anonymous_13, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModuleData[] = {
|
||||
|
||||
@@ -700,6 +700,7 @@ static const struct YamlNode struct_anonymous_12[] = {
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_13[] = {
|
||||
YAML_UNSIGNED( "flags", 8 ),
|
||||
YAML_UNSIGNED( "enableAETR", 1 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
@@ -713,7 +714,7 @@ static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
YAML_STRUCT("afhds3", 16, struct_anonymous_10, NULL),
|
||||
YAML_STRUCT("ghost", 8, struct_anonymous_11, NULL),
|
||||
YAML_STRUCT("crsf", 24, struct_anonymous_12, NULL),
|
||||
YAML_STRUCT("dsmp", 8, struct_anonymous_13, NULL),
|
||||
YAML_STRUCT("dsmp", 16, struct_anonymous_13, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModuleData[] = {
|
||||
|
||||
@@ -633,6 +633,7 @@ static const struct YamlNode struct_anonymous_12[] = {
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_13[] = {
|
||||
YAML_UNSIGNED( "flags", 8 ),
|
||||
YAML_UNSIGNED( "enableAETR", 1 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
@@ -646,7 +647,7 @@ static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
YAML_STRUCT("afhds3", 16, struct_anonymous_10, NULL),
|
||||
YAML_STRUCT("ghost", 8, struct_anonymous_11, NULL),
|
||||
YAML_STRUCT("crsf", 24, struct_anonymous_12, NULL),
|
||||
YAML_STRUCT("dsmp", 8, struct_anonymous_13, NULL),
|
||||
YAML_STRUCT("dsmp", 16, struct_anonymous_13, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModuleData[] = {
|
||||
|
||||
@@ -633,6 +633,7 @@ static const struct YamlNode struct_anonymous_12[] = {
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_13[] = {
|
||||
YAML_UNSIGNED( "flags", 8 ),
|
||||
YAML_UNSIGNED( "enableAETR", 1 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
@@ -646,7 +647,7 @@ static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
YAML_STRUCT("afhds3", 16, struct_anonymous_10, NULL),
|
||||
YAML_STRUCT("ghost", 8, struct_anonymous_11, NULL),
|
||||
YAML_STRUCT("crsf", 24, struct_anonymous_12, NULL),
|
||||
YAML_STRUCT("dsmp", 8, struct_anonymous_13, NULL),
|
||||
YAML_STRUCT("dsmp", 16, struct_anonymous_13, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModuleData[] = {
|
||||
|
||||
@@ -633,6 +633,7 @@ static const struct YamlNode struct_anonymous_12[] = {
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_13[] = {
|
||||
YAML_UNSIGNED( "flags", 8 ),
|
||||
YAML_UNSIGNED( "enableAETR", 1 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
@@ -646,7 +647,7 @@ static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
YAML_STRUCT("afhds3", 16, struct_anonymous_10, NULL),
|
||||
YAML_STRUCT("ghost", 8, struct_anonymous_11, NULL),
|
||||
YAML_STRUCT("crsf", 24, struct_anonymous_12, NULL),
|
||||
YAML_STRUCT("dsmp", 8, struct_anonymous_13, NULL),
|
||||
YAML_STRUCT("dsmp", 16, struct_anonymous_13, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModuleData[] = {
|
||||
|
||||
@@ -633,6 +633,7 @@ static const struct YamlNode struct_anonymous_12[] = {
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_13[] = {
|
||||
YAML_UNSIGNED( "flags", 8 ),
|
||||
YAML_UNSIGNED( "enableAETR", 1 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
@@ -646,7 +647,7 @@ static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
YAML_STRUCT("afhds3", 16, struct_anonymous_10, NULL),
|
||||
YAML_STRUCT("ghost", 8, struct_anonymous_11, NULL),
|
||||
YAML_STRUCT("crsf", 24, struct_anonymous_12, NULL),
|
||||
YAML_STRUCT("dsmp", 8, struct_anonymous_13, NULL),
|
||||
YAML_STRUCT("dsmp", 16, struct_anonymous_13, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModuleData[] = {
|
||||
|
||||
@@ -637,6 +637,7 @@ static const struct YamlNode struct_anonymous_12[] = {
|
||||
};
|
||||
static const struct YamlNode struct_anonymous_13[] = {
|
||||
YAML_UNSIGNED( "flags", 8 ),
|
||||
YAML_UNSIGNED( "enableAETR", 1 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
@@ -650,7 +651,7 @@ static const struct YamlNode union_anonymous_4_elmts[] = {
|
||||
YAML_STRUCT("afhds3", 16, struct_anonymous_10, NULL),
|
||||
YAML_STRUCT("ghost", 8, struct_anonymous_11, NULL),
|
||||
YAML_STRUCT("crsf", 24, struct_anonymous_12, NULL),
|
||||
YAML_STRUCT("dsmp", 8, struct_anonymous_13, NULL),
|
||||
YAML_STRUCT("dsmp", 16, struct_anonymous_13, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModuleData[] = {
|
||||
|
||||
@@ -11,6 +11,7 @@ option(DEBUG_TRACE_BUFFER "Debug Trace Screen" OFF)
|
||||
option(XJT "XJT TX Module" ON)
|
||||
option(PPM "PPM TX Module" ON)
|
||||
option(DSM2 "DSM2 TX Module" ON)
|
||||
option(DSMP "DSMP LemonRX TX Module" ON)
|
||||
option(SBUS "SBUS TX Module" ON)
|
||||
option(CROSSFIRE "Crossfire TX Module" ON)
|
||||
option(AFHDS2 "Support for AFHDS2" OFF)
|
||||
@@ -192,6 +193,12 @@ if(DSM2)
|
||||
add_definitions(-DDSM2)
|
||||
endif()
|
||||
|
||||
if(DSMP)
|
||||
add_definitions(-DDSM2)
|
||||
add_definitions(-DDSMP)
|
||||
endif()
|
||||
|
||||
|
||||
if(SBUS)
|
||||
add_definitions(-DSBUS)
|
||||
endif()
|
||||
@@ -312,6 +319,14 @@ if(DSM2)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(DSMP)
|
||||
set(PULSES_SRC
|
||||
${PULSES_SRC}
|
||||
dsmp.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
if(SBUS)
|
||||
set(PULSES_SRC
|
||||
${PULSES_SRC}
|
||||
|
||||
@@ -357,6 +357,58 @@ static void processMultiProtoDef(uint8_t module, const uint8_t * packet, uint8_t
|
||||
#endif
|
||||
|
||||
|
||||
static void processMultiDSMBindPacket(uint8_t module, const uint8_t *packet)
|
||||
{
|
||||
if (//g_model.moduleData[module].type == MODULE_TYPE_MULTIMODULE &&
|
||||
//g_model.moduleData[module].multi.rfProtocol ==
|
||||
// MODULE_SUBTYPE_MULTI_DSM2 &&
|
||||
g_model.moduleData[module].subType == MM_RF_DSM2_SUBTYPE_AUTO) {
|
||||
// Only sets channel etc when in DSM/AUTO mode
|
||||
int channels = packet[5];
|
||||
if (channels > 12) {
|
||||
channels = 12;
|
||||
} else if (channels < 3) {
|
||||
channels = 3;
|
||||
}
|
||||
|
||||
switch (packet[6]) {
|
||||
case 0xa2:
|
||||
g_model.moduleData[module].subType = MM_RF_DSM2_SUBTYPE_DSMX_22;
|
||||
break;
|
||||
case 0x12:
|
||||
g_model.moduleData[module].subType = MM_RF_DSM2_SUBTYPE_DSM2_11;
|
||||
if (channels == 7) {
|
||||
channels = 12; // change the number of channels if 7
|
||||
}
|
||||
break;
|
||||
case 0x01:
|
||||
case 0x02:
|
||||
g_model.moduleData[module].subType = MM_RF_DSM2_SUBTYPE_DSM2_22;
|
||||
break;
|
||||
default: // 0xb2 or unknown
|
||||
g_model.moduleData[module].subType = MM_RF_DSM2_SUBTYPE_DSMX_11;
|
||||
if (channels == 7) {
|
||||
channels = 12; // change the number of channels if 7
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
g_model.moduleData[module].channelsCount = channels - 8;
|
||||
// clear the 11ms servo refresh rate flag
|
||||
g_model.moduleData[module].multi.optionValue &= 0xFD;
|
||||
|
||||
storageDirty(EE_MODEL);
|
||||
}
|
||||
|
||||
/* Finally stop binding as the rx just told us that it is bound */
|
||||
if (getModuleMode(module) == MODULE_MODE_BIND) {
|
||||
setMultiBindStatus(module, MULTI_BIND_FINISHED);
|
||||
}
|
||||
|
||||
// Continue with the common Spektrum Processing
|
||||
processDSMBindPacket(packet);
|
||||
}
|
||||
|
||||
static void processMultiTelemetryPaket(const uint8_t * packet, uint8_t module)
|
||||
{
|
||||
uint8_t type = packet[0];
|
||||
@@ -372,7 +424,7 @@ static void processMultiTelemetryPaket(const uint8_t * packet, uint8_t module)
|
||||
|
||||
case DSMBindPacket:
|
||||
if (len >= 10)
|
||||
processDSMBindPacket(module, data);
|
||||
processMultiDSMBindPacket(module, data);
|
||||
break;
|
||||
|
||||
case SpektrumTelemetry:
|
||||
|
||||
@@ -849,131 +849,16 @@ void processSpektrumPacket(const uint8_t *packet)
|
||||
LemonRX+Sat+tele 0xb2 07 1
|
||||
|
||||
*/
|
||||
void processDSMBindPacket(uint8_t module, const uint8_t *packet)
|
||||
void processDSMBindPacket(const uint8_t *packet)
|
||||
{
|
||||
uint32_t debugval;
|
||||
|
||||
if (g_model.moduleData[module].type == MODULE_TYPE_LEMON_DSMP) {
|
||||
|
||||
// save flags
|
||||
g_model.moduleData[module].dsmp.flags = packet[0];
|
||||
|
||||
// save number of channels
|
||||
uint8_t channels = packet[2];
|
||||
if (channels > 12) { channels = 12; }
|
||||
g_model.moduleData[module].channelsCount = channels - 8;
|
||||
|
||||
TRACE("[SPK] DSMP bind packet: 0x%X / %i",
|
||||
packet[0] & 0x3F, packet[2]);
|
||||
|
||||
storageDirty(EE_MODEL);
|
||||
|
||||
moduleState[module].mode = MODULE_MODE_NORMAL;
|
||||
restartModuleAsync(module, 50); // ~500ms
|
||||
}
|
||||
#if defined(MULTIMODULE)
|
||||
else if (g_model.moduleData[module].type == MODULE_TYPE_MULTIMODULE &&
|
||||
g_model.moduleData[module].multi.rfProtocol ==
|
||||
MODULE_SUBTYPE_MULTI_DSM2 &&
|
||||
g_model.moduleData[module].subType == MM_RF_DSM2_SUBTYPE_AUTO) {
|
||||
|
||||
// Only sets channel etc when in DSM/AUTO mode
|
||||
int channels = packet[5];
|
||||
if (channels > 12) {
|
||||
channels = 12;
|
||||
}
|
||||
else if (channels < 3) {
|
||||
channels = 3;
|
||||
}
|
||||
|
||||
switch(packet[6]) {
|
||||
case 0xa2:
|
||||
g_model.moduleData[module].subType = MM_RF_DSM2_SUBTYPE_DSMX_22;
|
||||
break;
|
||||
case 0x12:
|
||||
g_model.moduleData[module].subType = MM_RF_DSM2_SUBTYPE_DSM2_11;
|
||||
if (channels == 7) {
|
||||
channels = 12; // change the number of channels if 7
|
||||
}
|
||||
break;
|
||||
case 0x01:
|
||||
case 0x02:
|
||||
g_model.moduleData[module].subType = MM_RF_DSM2_SUBTYPE_DSM2_22;
|
||||
break;
|
||||
default: // 0xb2 or unknown
|
||||
g_model.moduleData[module].subType = MM_RF_DSM2_SUBTYPE_DSMX_11;
|
||||
if (channels == 7) {
|
||||
channels = 12; // change the number of channels if 7
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
g_model.moduleData[module].channelsCount = channels - 8;
|
||||
// clear the 11ms servo refresh rate flag
|
||||
g_model.moduleData[module].multi.optionValue &= 0xFD;
|
||||
|
||||
storageDirty(EE_MODEL);
|
||||
}
|
||||
#endif
|
||||
debugval = packet[7] << 24 | packet[6] << 16 | packet[5] << 8 | packet[4];
|
||||
|
||||
/* log the bind packet as telemetry for quick debugging */
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_SPEKTRUM, I2C_PSEUDO_TX_BIND, 0, 0,
|
||||
debugval, UNIT_RAW, 0);
|
||||
|
||||
/* Finally stop binding as the rx just told us that it is bound */
|
||||
if (getModuleMode(module) == MODULE_MODE_BIND) {
|
||||
auto module_type = g_model.moduleData[module].type;
|
||||
#if defined(MULTIMODULE)
|
||||
if (module_type == MODULE_TYPE_MULTIMODULE &&
|
||||
g_model.moduleData[module].multi.rfProtocol ==
|
||||
MODULE_SUBTYPE_MULTI_DSM2) {
|
||||
setMultiBindStatus(module, MULTI_BIND_FINISHED);
|
||||
} else
|
||||
#endif
|
||||
if (module_type == MODULE_TYPE_LEMON_DSMP) {
|
||||
setModuleMode(module, MODULE_MODE_NORMAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void processSpektrumTelemetryData(uint8_t module, uint8_t data,
|
||||
uint8_t *rxBuffer, uint8_t &rxBufferCount)
|
||||
{
|
||||
if (rxBufferCount == 0 && data != 0xAA) {
|
||||
TRACE("[SPK] invalid start byte 0x%02X", data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rxBufferCount < TELEMETRY_RX_PACKET_SIZE) {
|
||||
rxBuffer[rxBufferCount++] = data;
|
||||
}
|
||||
else {
|
||||
TRACE("[SPK] array size %d error", rxBufferCount);
|
||||
rxBufferCount = 0;
|
||||
}
|
||||
|
||||
if (rxBuffer[1] == 0x80 && rxBufferCount >= DSM_BIND_PACKET_LENGTH) {
|
||||
processDSMBindPacket(module, rxBuffer+2);
|
||||
rxBufferCount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (rxBufferCount >= SPEKTRUM_TELEMETRY_LENGTH) {
|
||||
// Debug print content of Telemetry to console
|
||||
#if 0
|
||||
debugPrintf("[SPK] Packet 0x%02X rssi 0x%02X: ic2 0x%02x, %02x: ",
|
||||
rxBuffer[0], rxBuffer[1], rxBuffer[2], rxBuffer[3]);
|
||||
for (int i=4; i<SPEKTRUM_TELEMETRY_LENGTH; i+=4) {
|
||||
debugPrintf("%02X%02X %02X%02X ", rxBuffer[i], rxBuffer[i + 1],
|
||||
rxBuffer[i + 2], rxBuffer[i + 3]);
|
||||
}
|
||||
debugPrintf(CRLF);
|
||||
#endif
|
||||
processSpektrumPacket(rxBuffer);
|
||||
rxBufferCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
const SpektrumSensor *getSpektrumSensor(uint16_t pseudoId)
|
||||
{
|
||||
|
||||
@@ -21,9 +21,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
void processSpektrumTelemetryData(uint8_t module, uint8_t data, uint8_t* rxBuffer, uint8_t& rxBufferCount);
|
||||
#define SPEKTRUM_TELEMETRY_LENGTH 18
|
||||
#define DSM_BIND_PACKET_LENGTH 12
|
||||
|
||||
void spektrumSetDefault(int index, uint16_t id, uint8_t subId, uint8_t instance);
|
||||
|
||||
// Used directly by multi telemetry protocol
|
||||
// Used directly by multi and DSMP telemetry protocol
|
||||
void processSpektrumPacket(const uint8_t *packet);
|
||||
void processDSMBindPacket(uint8_t module, const uint8_t *packet);
|
||||
void processDSMBindPacket(const uint8_t *packet);
|
||||
|
||||
@@ -672,6 +672,7 @@
|
||||
#define TR_MULTI_OPTION TR("选项值", "选项值")
|
||||
#define TR_MULTI_AUTOBIND TR("对频通道", "通道控制对频")
|
||||
#define TR_DISABLE_CH_MAP TR("禁用通道映射", "禁用通道重映射")
|
||||
#define TR_DSMP_ENABLE_AETR TR("Enb. AETR", "Enable AETR")
|
||||
#define TR_DISABLE_TELEM TR("禁用回传", "禁用回传")
|
||||
#define TR_MULTI_LOWPOWER TR("低功率", "低功率模式")
|
||||
#define TR_MULTI_LNA_DISABLE "禁用接收放大器"
|
||||
|
||||
@@ -677,6 +677,7 @@
|
||||
#define TR_MULTI_OPTION TR("Možnosti", "Hodnota")
|
||||
#define TR_MULTI_AUTOBIND TR("Bind Ch.","Bind při zapnutí")
|
||||
#define TR_DISABLE_CH_MAP TR("No Ch. map", "Vypnout mapování kanálů")
|
||||
#define TR_DSMP_ENABLE_AETR TR("Enb. AETR", "Enable AETR")
|
||||
#define TR_DISABLE_TELEM TR("No Telem", "Vypnout telemetrii")
|
||||
#define TR_MULTI_LOWPOWER TR("Nízký výkon", "Režim nízkého výkonu")
|
||||
#define TR_MULTI_LNA_DISABLE "LNA vypnuto"
|
||||
|
||||
@@ -677,6 +677,7 @@
|
||||
#define TR_MULTI_OPTION TR("Tilvalg", "Tilvalg værdi")
|
||||
#define TR_MULTI_AUTOBIND TR("Tilslut ka.", "Tilslut kanal")
|
||||
#define TR_DISABLE_CH_MAP TR("% ka. kort", "Deaktiver kanal kort")
|
||||
#define TR_DSMP_ENABLE_AETR TR("Enb. AETR", "Enable AETR")
|
||||
#define TR_DISABLE_TELEM TR("% Telem.", "Deaktiver telemetri")
|
||||
#define TR_MULTI_LOWPOWER TR("Lav strøm", "Lav strøm tilstand")
|
||||
#define TR_MULTI_LNA_DISABLE "LNA deaktiver"
|
||||
|
||||
@@ -673,6 +673,7 @@
|
||||
#define TR_MULTI_OPTION TR("Option", "Optionswert")
|
||||
#define TR_MULTI_AUTOBIND TR("Bind Ka.","Bindung an Kanal")
|
||||
#define TR_DISABLE_CH_MAP TR("No Ch. map", "Deaktiviere Ch. map")
|
||||
#define TR_DSMP_ENABLE_AETR TR("Enb. AETR", "Enable AETR")
|
||||
#define TR_DISABLE_TELEM TR("No Telem", "Deaktiviere Telem.")
|
||||
#define TR_MULTI_LOWPOWER TR("Low power", "reduzierte Leistung")
|
||||
#define TR_MULTI_LNA_DISABLE "LNA disable"
|
||||
|
||||
@@ -673,6 +673,7 @@
|
||||
#define TR_MULTI_OPTION TR("Option", "Option value")
|
||||
#define TR_MULTI_AUTOBIND TR("Bind Ch.", "Bind on channel")
|
||||
#define TR_DISABLE_CH_MAP TR("No Ch. map", "Disable Ch. map")
|
||||
#define TR_DSMP_ENABLE_AETR TR("Enb. AETR", "Enable AETR")
|
||||
#define TR_DISABLE_TELEM TR("No Telem", "Disable Telemetry")
|
||||
#define TR_MULTI_LOWPOWER TR("Low power", "Low power mode")
|
||||
#define TR_MULTI_LNA_DISABLE "LNA disable"
|
||||
|
||||
@@ -672,6 +672,7 @@
|
||||
#define TR_MULTI_OPTION TR("Opción", "Valor opción")
|
||||
#define TR_MULTI_AUTOBIND TR("Emp Cnl","Emparejar en canal")
|
||||
#define TR_DISABLE_CH_MAP TR("No ch map", "Desactivar mapa cnl")
|
||||
#define TR_DSMP_ENABLE_AETR TR("Hab. AETR", "Habilitar AETR")
|
||||
#define TR_DISABLE_TELEM TR("No telem", "Desactivar telem.")
|
||||
#define TR_MULTI_LOWPOWER TR("Baja poten.", "Modo de baja poten.")
|
||||
#define TR_MULTI_LNA_DISABLE "LNA desact."
|
||||
|
||||
@@ -672,6 +672,7 @@
|
||||
#define TR_MULTI_OPTION TR("Option", "Option value")
|
||||
#define TR_MULTI_AUTOBIND TR("Bind Ch.","Bind on channel")
|
||||
#define TR_DISABLE_CH_MAP TR("No Ch. map", "Disable Ch. map")
|
||||
#define TR_DSMP_ENABLE_AETR TR("Enb. AETR", "Enable AETR")
|
||||
#define TR_DISABLE_TELEM TR("No Telem", "Disable Telemetry")
|
||||
#define TR_MULTI_LOWPOWER TR("Low power", "Low power mode")
|
||||
#define TR_MULTI_LNA_DISABLE "LNA disable"
|
||||
|
||||
@@ -677,6 +677,7 @@
|
||||
#define TR_MULTI_OPTION TR("Option", "Option perso")
|
||||
#define TR_MULTI_AUTOBIND TR("Bind voie", "Bind sur voie")
|
||||
#define TR_DISABLE_CH_MAP TR("No Ch. map", "Désact. réorg. voies")
|
||||
#define TR_DSMP_ENABLE_AETR TR("Enb. AETR", "Enable AETR")
|
||||
#define TR_DISABLE_TELEM TR("Pas de Télém.", "Désact. Télémétrie")
|
||||
#define TR_MULTI_LOWPOWER TR("Basse puis.", "Mode basse puiss.")
|
||||
#define TR_MULTI_LNA_DISABLE "LNA désactivé"
|
||||
|
||||
@@ -675,6 +675,7 @@
|
||||
#define TR_MULTI_OPTION TR("Option", "Option value")
|
||||
#define TR_MULTI_AUTOBIND TR("Bind Ch.", "צימוד על ערוץ")
|
||||
#define TR_DISABLE_CH_MAP TR("No Ch. map", "השבתת מיפוי ערוצים")
|
||||
#define TR_DSMP_ENABLE_AETR TR("Enb. AETR", "Enable AETR")
|
||||
#define TR_DISABLE_TELEM TR("No Telem", "השבתת טלמטריה")
|
||||
#define TR_MULTI_LOWPOWER TR("Low power", "מצב מתח נמוך")
|
||||
#define TR_MULTI_LNA_DISABLE "LNA disable"
|
||||
|
||||
@@ -672,6 +672,7 @@
|
||||
#define TR_MULTI_OPTION TR("Opzione", "Opzione valore")
|
||||
#define TR_MULTI_AUTOBIND TR("Ass. Ch.","Associa al canale")
|
||||
#define TR_DISABLE_CH_MAP TR("No Ch. map", "Disab. mappa Ch.")
|
||||
#define TR_DSMP_ENABLE_AETR TR("Enb. AETR", "Enable AETR")
|
||||
#define TR_DISABLE_TELEM TR("No Telem", "Telem. disabil.")
|
||||
#define TR_MULTI_LOWPOWER TR("Bassa pot.", "Modo bassa potenza")
|
||||
#define TR_MULTI_LNA_DISABLE "Disabilita LNA"
|
||||
|
||||
@@ -671,6 +671,7 @@
|
||||
#define TR_MULTI_OPTION TR("Option", "オプション値")
|
||||
#define TR_MULTI_AUTOBIND TR("Bind Ch.", "チャンネルバインド")
|
||||
#define TR_DISABLE_CH_MAP TR("No Ch. map", "CHマップ無効")
|
||||
#define TR_DSMP_ENABLE_AETR TR("Enb. AETR", "Enable AETR")
|
||||
#define TR_DISABLE_TELEM TR("No Telem", "テレメトリー無効")
|
||||
#define TR_MULTI_LOWPOWER TR("Low power", "低出力モード")
|
||||
#define TR_MULTI_LNA_DISABLE "LNA無効"
|
||||
|
||||
@@ -696,6 +696,7 @@
|
||||
#define TR_MULTI_OPTION TR("옵션", "옵션 값")
|
||||
#define TR_MULTI_AUTOBIND TR("바인드 채널", "채널에서 자동 바인딩")
|
||||
#define TR_DISABLE_CH_MAP TR("채널 매핑 없음", "채널 매핑 비활성화")
|
||||
#define TR_DSMP_ENABLE_AETR TR("Enb. AETR", "Enable AETR")
|
||||
#define TR_DISABLE_TELEM TR("텔레메트리 없음", "텔레메트리 비활성화")
|
||||
#define TR_MULTI_LOWPOWER TR("저전력", "저전력 모드")
|
||||
#define TR_MULTI_LNA_DISABLE "LNA 비활성화"
|
||||
|
||||
@@ -674,6 +674,7 @@
|
||||
#define TR_MULTI_OPTION TR("Option", "Option value")
|
||||
#define TR_MULTI_AUTOBIND TR("Bind Ch.","Bind on channel")
|
||||
#define TR_DISABLE_CH_MAP TR("No Ch. map", "Disable Ch. map")
|
||||
#define TR_DSMP_ENABLE_AETR TR("Enb. AETR", "Enable AETR")
|
||||
#define TR_DISABLE_TELEM TR("No Telem", "Disable Telemetry")
|
||||
#define TR_MULTI_LOWPOWER TR("Low power", "Low power mode")
|
||||
#define TR_MULTI_LNA_DISABLE "LNA disable"
|
||||
|
||||
@@ -671,6 +671,7 @@
|
||||
#define TR_MULTI_OPTION TR("Opcja", "Wartość opcji")
|
||||
#define TR_MULTI_AUTOBIND TR("Bind Ch.","Bind on channel")
|
||||
#define TR_DISABLE_CH_MAP TR("No Ch. map", "Disable Ch. map")
|
||||
#define TR_DSMP_ENABLE_AETR TR("Enb. AETR", "Enable AETR")
|
||||
#define TR_DISABLE_TELEM TR("No Telem", "Disable Telemetry")
|
||||
#define TR_MULTI_LOWPOWER TR("Low power", "Low power mode")
|
||||
#define TR_MULTI_LNA_DISABLE "LNA disable"
|
||||
|
||||
@@ -672,6 +672,7 @@
|
||||
#define TR_MULTI_OPTION TR("Opção", "Valor opção")
|
||||
#define TR_MULTI_AUTOBIND TR("Bind Ch.", "Bind on channel")
|
||||
#define TR_DISABLE_CH_MAP TR("No Ch. map", "Disable Ch. map")
|
||||
#define TR_DSMP_ENABLE_AETR TR("Enb. AETR", "Enable AETR")
|
||||
#define TR_DISABLE_TELEM TR("No Telem", "Disable Telemetry")
|
||||
#define TR_MULTI_LOWPOWER TR("Low power", "Low power mode")
|
||||
#define TR_MULTI_LNA_DISABLE "LNA disable"
|
||||
|
||||
@@ -674,6 +674,7 @@
|
||||
#define TR_MULTI_OPTION TR("Опция", "Знач опции")
|
||||
#define TR_MULTI_AUTOBIND TR("Прив к кан", "Прив к кан")
|
||||
#define TR_DISABLE_CH_MAP TR("Откл карту кан", "Откл карту кан")
|
||||
#define TR_DSMP_ENABLE_AETR TR("Enb. AETR", "Enable AETR")
|
||||
#define TR_DISABLE_TELEM TR("Без телеметрии", "Откл телем")
|
||||
#define TR_MULTI_LOWPOWER TR("Низк потребл", "Низк потребл")
|
||||
#define TR_MULTI_LNA_DISABLE "Откл LNA"
|
||||
|
||||
@@ -677,6 +677,7 @@
|
||||
#define TR_MULTI_OPTION TR("Alternativ", "Alternativets värde")
|
||||
#define TR_MULTI_AUTOBIND TR("Bind ka.","Parkoppla via kanal")
|
||||
#define TR_DISABLE_CH_MAP TR("Mappa ej KA", "Inaktivera kanalmappning")
|
||||
#define TR_DSMP_ENABLE_AETR TR("Enb. AETR", "Enable AETR")
|
||||
#define TR_DISABLE_TELEM TR("Ej telem.", "Inaktivera telemetri")
|
||||
#define TR_MULTI_LOWPOWER TR("Låg effekt", "Lågeffektläge")
|
||||
#define TR_MULTI_LNA_DISABLE "LNA disable"
|
||||
|
||||
@@ -669,6 +669,7 @@
|
||||
#define TR_MULTI_OPTION TR("選項值", "選項值")
|
||||
#define TR_MULTI_AUTOBIND TR("對頻通道", "通道控制對頻")
|
||||
#define TR_DISABLE_CH_MAP TR("禁用通道映射", "禁用通道重映射")
|
||||
#define TR_DSMP_ENABLE_AETR TR("Enb. AETR", "Enable AETR")
|
||||
#define TR_DISABLE_TELEM TR("禁用回傳", "禁用回傳")
|
||||
#define TR_MULTI_LOWPOWER TR("低功率", "低功率模式")
|
||||
#define TR_MULTI_LNA_DISABLE "禁用接收放大器"
|
||||
|
||||
@@ -673,6 +673,7 @@
|
||||
#define TR_MULTI_OPTION TR("Опція", "Значення опції")
|
||||
#define TR_MULTI_AUTOBIND TR("Прив'язка до кан.", "Прив'язка до каналу")
|
||||
#define TR_DISABLE_CH_MAP TR("Викл. карту каналів", "Виключити карту каналів")
|
||||
#define TR_DSMP_ENABLE_AETR TR("Enb. AETR", "Enable AETR")
|
||||
#define TR_DISABLE_TELEM TR("Викл. телеметрії", "Виключити телеметрію")
|
||||
#define TR_MULTI_LOWPOWER TR("Низька потужн.", "Режим низької потужності")
|
||||
#define TR_MULTI_LNA_DISABLE "Вимкн. LNA"
|
||||
|
||||
@@ -330,7 +330,7 @@
|
||||
#define STR_MENUCUSTOMSCRIPTS currentLangStrings->STR_MENUCUSTOMSCRIPTS
|
||||
#endif
|
||||
|
||||
#if defined(DSM2) || defined(PXX)
|
||||
#if defined(DSM2) || defined(PXX) || defined(DSMP)
|
||||
#define STR_BIND_OK currentLangStrings->STR_BIND_OK
|
||||
#define STR_REBIND currentLangStrings->STR_REBIND
|
||||
#define STR_RECEIVER_NUM currentLangStrings->STR_RECEIVER_NUM
|
||||
@@ -338,6 +338,10 @@
|
||||
#define STR_REG_OK currentLangStrings->STR_REG_OK
|
||||
#endif
|
||||
|
||||
#if defined(DSMP)
|
||||
#define STR_DSMP_ENABLE_AETR currentLangStrings->STR_DSMP_ENABLE_AETR
|
||||
#endif
|
||||
|
||||
#if defined(AFHDS3)
|
||||
#define STR_AFHDS3_ACTUAL_POWER currentLangStrings->STR_AFHDS3_ACTUAL_POWER
|
||||
#define STR_AFHDS3_ONE_TO_MANY currentLangStrings->STR_AFHDS3_ONE_TO_MANY
|
||||
|
||||
@@ -329,7 +329,7 @@ STR(STRENGTH)
|
||||
STR(MENUCUSTOMSCRIPTS)
|
||||
#endif
|
||||
|
||||
#if defined(DSM2) || defined(PXX)
|
||||
#if defined(DSM2) || defined(PXX) || defined(DSMP)
|
||||
STR(BIND_OK)
|
||||
STR(REBIND)
|
||||
STR(RECEIVER_NUM)
|
||||
@@ -337,6 +337,10 @@ STR(RECEIVER)
|
||||
STR(REG_OK)
|
||||
#endif
|
||||
|
||||
#if defined(DSMP)
|
||||
STR(DSMP_ENABLE_AETR)
|
||||
#endif
|
||||
|
||||
#if defined(AFHDS3)
|
||||
STR(AFHDS3_ACTUAL_POWER)
|
||||
STR(AFHDS3_ONE_TO_MANY)
|
||||
|
||||
Reference in New Issue
Block a user