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

Bsongis/r9 m fixes (#5406)

R9M support
This commit is contained in:
Bertrand Songis 2017-12-08 11:26:46 +01:00 committed by GitHub
parent 9c27947345
commit a6044a684d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 771 additions and 495 deletions

View file

@ -3523,8 +3523,8 @@ void OpenTxModelData::afterImport()
modelData.moduleData[module].pxx.power = pxxByte & 0x03;
modelData.moduleData[module].pxx.receiver_telem_off = static_cast<bool>(pxxByte & (1 << 4));
modelData.moduleData[module].pxx.receiver_channel_9_16 = static_cast<bool>(pxxByte & (1 << 5));
modelData.moduleData[module].pxx.external_antenna = modelData.moduleData[module].ppm.outputType;
modelData.moduleData[module].pxx.sport_out = modelData.moduleData[module].ppm.pulsePol;
modelData.moduleData[module].pxx.sport_out = modelData.moduleData[module].ppm.outputType;
modelData.moduleData[module].pxx.external_antenna = modelData.moduleData[module].ppm.pulsePol;
}
}

View file

@ -172,6 +172,7 @@ void TimerPanel::on_name_editingFinished()
#define MASK_MULTIOPTION 512
#define MASK_R9M 1024
#define MASK_SBUSPPM_FIELDS 2048
#define MASK_SUBTYPES 4096
quint8 ModulePanel::failsafesValueDisplayType = ModulePanel::FAILSAFE_DISPLAY_PERCENT;
@ -369,7 +370,7 @@ void ModulePanel::update()
mask |= MASK_PROTOCOL;
switch (protocol) {
case PULSES_PXX_R9M:
mask |= MASK_R9M;
mask |= MASK_R9M | MASK_SUBTYPES;
case PULSES_PXX_XJT_X16:
case PULSES_PXX_XJT_D8:
case PULSES_PXX_XJT_LR12:
@ -402,7 +403,7 @@ void ModulePanel::update()
mask |= MASK_SBUSPPM_FIELDS| MASK_CHANNELS_RANGE;
break;
case PULSES_MULTIMODULE:
mask |= MASK_CHANNELS_RANGE | MASK_RX_NUMBER | MASK_MULTIMODULE;
mask |= MASK_CHANNELS_RANGE | MASK_RX_NUMBER | MASK_MULTIMODULE | MASK_SUBTYPES;
max_rx_num = 15;
if (module.multi.rfProtocol == MM_RF_PROTO_DSM2)
mask |= MASK_CHANNELS_COUNT;
@ -468,37 +469,49 @@ void ModulePanel::update()
ui->antennaMode->setVisible(mask & MASK_ANTENNA);
ui->antennaMode->setCurrentIndex(module.pxx.external_antenna);
// R9M S.port output
// R9M options
ui->sportOut->setVisible(mask & MASK_R9M);
ui->label_sportOut->setVisible(mask & MASK_R9M);
ui->sportOut->setCurrentIndex(module.pxx.sport_out);
ui->r9mPower->setVisible(mask & MASK_R9M);
ui->label_r9mPower->setVisible(mask & MASK_R9M);
ui->r9mPower->setVisible((mask & MASK_R9M) && module.subType == 0);
ui->label_r9mPower->setVisible((mask & MASK_R9M) && module.subType == 0);
if (mask & MASK_R9M) {
if (model->moduleData[0].protocol >= PULSES_PXX_XJT_X16 && model->moduleData[0].protocol <= PULSES_PXX_XJT_LR12) {
module.pxx.sport_out = false;
ui->sportOut->setDisabled(true);
}
else {
ui->sportOut->setEnabled(true);
}
ui->sportOut->setChecked(module.pxx.sport_out);
ui->r9mPower->setCurrentIndex(module.pxx.power);
}
// module subtype
ui->label_multiSubType->setVisible(mask & MASK_SUBTYPES);
ui->multiSubType->setVisible(mask & MASK_SUBTYPES);
if (mask & MASK_SUBTYPES) {
unsigned numEntries = 2; // R9M FCC/EU
if (mask & MASK_MULTIMODULE)
numEntries = (module.multi.customProto ? 8 : multiProtocols.getProtocol(module.multi.rfProtocol).numSubytes());
const QSignalBlocker blocker(ui->multiSubType);
ui->multiSubType->clear();
for (unsigned i=0; i < numEntries; i++)
ui->multiSubType->addItem(ModelPrinter::printModuleSubType(protocol, i, module.multi.rfProtocol, module.multi.customProto), i);
ui->multiSubType->setCurrentIndex(module.subType);
}
// Multi settings fields
ui->label_multiProtocol->setVisible(mask & MASK_MULTIMODULE);
ui->multiProtocol->setVisible(mask & MASK_MULTIMODULE);
ui->multiProtocol->setCurrentIndex(module.multi.rfProtocol);
ui->label_multiSubType->setVisible(mask & MASK_MULTIMODULE);
ui->multiSubType->setVisible(mask & MASK_MULTIMODULE);
ui->label_option->setVisible(mask & MASK_MULTIOPTION);
ui->optionValue->setVisible(mask & MASK_MULTIOPTION);
ui->autoBind->setVisible(mask & MASK_MULTIMODULE);
ui->lowPower->setVisible(mask & MASK_MULTIMODULE);
if (mask & MASK_MULTIMODULE) {
int numEntries = multiProtocols.getProtocol(module.multi.rfProtocol).numSubytes();
if (module.multi.customProto)
numEntries=8;
// Removes extra items
ui->multiSubType->setMaxCount(numEntries);
for (int i=0; i < numEntries; i++) {
if (i < ui->multiSubType->count())
ui->multiSubType->setItemText(i, ModelPrinter::printMultiSubType(module.multi.rfProtocol, module.multi.customProto, i));
else
ui->multiSubType->addItem(ModelPrinter::printMultiSubType(module.multi.rfProtocol, module.multi.customProto, i), (QVariant) i);
}
ui->multiProtocol->setCurrentIndex(module.multi.rfProtocol);
ui->autoBind->setChecked(module.multi.autoBindMode ? Qt::Checked : Qt::Unchecked);
ui->lowPower->setChecked(module.multi.lowPowerMode ? Qt::Checked : Qt::Unchecked);
}
if (mask & MASK_MULTIOPTION) {
@ -508,14 +521,8 @@ void ModulePanel::update()
ui->optionValue->setValue(module.multi.optionValue);
ui->label_option->setText(qApp->translate("Multiprotocols", qPrintable(pdef.optionsstr)));
}
ui->multiSubType->setCurrentIndex(module.subType);
ui->autoBind->setVisible(mask & MASK_MULTIMODULE);
ui->autoBind->setChecked(module.multi.autoBindMode ? Qt::Checked : Qt::Unchecked);
ui->lowPower->setVisible(mask & MASK_MULTIMODULE);
ui->lowPower->setChecked(module.multi.lowPowerMode ? Qt::Checked : Qt::Unchecked);
// Failsafes
ui->label_failsafeMode->setVisible(mask & MASK_FAILSAFES);
ui->failsafeMode->setVisible(mask & MASK_FAILSAFES);
@ -584,11 +591,13 @@ void ModulePanel::on_antennaMode_currentIndexChanged(int index)
emit modified();
}
void ModulePanel::on_sportOut_currentIndexChanged(int index)
void ModulePanel::on_sportOut_toggled(bool checked)
{
module.pxx.sport_out = index;
if (module.pxx.sport_out != checked) {
module.pxx.sport_out = checked;
emit modified();
}
}
void ModulePanel::on_r9mPower_currentIndexChanged(int index)
{

View file

@ -88,7 +88,7 @@ class ModulePanel : public ModelPanel
void on_multiSubType_currentIndexChanged(int index);
void on_autoBind_stateChanged(int state);
void on_lowPower_stateChanged(int state);
void on_sportOut_currentIndexChanged(int index);
void on_sportOut_toggled(bool checked);
void on_r9mPower_currentIndexChanged(int index);
void setChannelFailsafeValue(const int channel, const int value, quint8 updtSb = 0);
void onFailsafeComboIndexChanged(int index);

View file

@ -6,13 +6,16 @@
<rect>
<x>0</x>
<y>0</y>
<width>674</width>
<height>229</height>
<width>708</width>
<height>259</height>
</rect>
</property>
<property name="windowTitle">
<string/>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>6</number>
@ -147,22 +150,43 @@
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_multiSubType">
<widget class="QLabel" name="label_rxNumber">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>SubType</string>
<string>Receiver No.</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="multiSubType">
<widget class="QSpinBox" name="rxNumber">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
<property name="suffix">
<string/>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>63</number>
</property>
<property name="singleStep">
<number>1</number>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
@ -206,88 +230,54 @@
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_antenna">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<widget class="QLabel" name="label_r9mPower">
<property name="text">
<string>Antenna</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
<string>RF Output Power</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="antennaMode">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
<widget class="QComboBox" name="r9mPower">
<item>
<property name="text">
<string>Internal</string>
<string>10 mW</string>
</property>
</item>
<item>
<property name="text">
<string>Ext. + Int.</string>
</property>
</item>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_ppmOutputType">
<property name="text">
<string>Output type</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="ppmOutputType">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
<item>
<property name="text">
<string>Open Drain</string>
<string>100 mW</string>
</property>
</item>
<item>
<property name="text">
<string>Push Pull</string>
<string>500 mW</string>
</property>
</item>
</widget>
</item>
<item row="5" column="1">
<widget class="QSpinBox" name="optionValue">
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_option">
<item>
<property name="text">
<string>Option value</string>
<string>1000 mW</string>
</property>
</item>
</widget>
</item>
<item row="4" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QCheckBox" name="autoBind">
<property name="text">
<string>Bind on startup</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="lowPower">
<property name="text">
<string>Low Power</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item row="0" column="2">
@ -352,61 +342,6 @@
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_rxNumber">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Receiver No.</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="rxNumber">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="suffix">
<string/>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>63</number>
</property>
<property name="singleStep">
<number>1</number>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="autoBind">
<property name="text">
<string>Bind on startup</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="lowPower">
<property name="text">
<string>Low Power</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_ppmDelay">
<property name="maximumSize">
<size>
@ -422,7 +357,7 @@
</property>
</widget>
</item>
<item row="3" column="1">
<item row="1" column="1">
<widget class="QSpinBox" name="ppmDelay">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
@ -450,7 +385,7 @@
</property>
</widget>
</item>
<item row="4" column="0">
<item row="2" column="0">
<widget class="QLabel" name="label_ppmFrameLength">
<property name="maximumSize">
<size>
@ -466,7 +401,7 @@
</property>
</widget>
</item>
<item row="4" column="1">
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="ppmFrameLength">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
@ -494,6 +429,89 @@
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_antenna">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Antenna</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="antennaMode">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
<item>
<property name="text">
<string>Internal</string>
</property>
</item>
<item>
<property name="text">
<string>Ext. + Int.</string>
</property>
</item>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_ppmOutputType">
<property name="text">
<string>Output type</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QComboBox" name="ppmOutputType">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
<item>
<property name="text">
<string>Open Drain</string>
</property>
</item>
<item>
<property name="text">
<string>Push Pull</string>
</property>
</item>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_option">
<property name="text">
<string>Option value</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QSpinBox" name="optionValue">
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0">
@ -560,6 +578,26 @@
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_multiSubType">
<property name="text">
<string>Sub Type</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="multiSubType">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_failsafeMode">
<property name="maximumSize">
<size>
@ -575,7 +613,7 @@
</property>
</widget>
</item>
<item row="2" column="1">
<item row="4" column="1">
<widget class="QComboBox" name="failsafeMode">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
@ -613,7 +651,7 @@
</item>
</widget>
</item>
<item row="3" column="0">
<item row="5" column="0">
<widget class="QLabel" name="label_trainerMode">
<property name="maximumSize">
<size>
@ -629,7 +667,7 @@
</property>
</widget>
</item>
<item row="3" column="1">
<item row="5" column="1">
<widget class="QComboBox" name="trainerMode">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
@ -667,64 +705,19 @@
</item>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_sportOut">
<item row="3" column="1">
<widget class="QCheckBox" name="sportOut">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>S.port output</string>
<string>Module Telemetry</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="sportOut">
<property name="currentText">
<string>Disable</string>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
<item>
<property name="text">
<string>Disable</string>
</property>
</item>
<item>
<property name="text">
<string>Enable</string>
</property>
</item>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_r9mPower">
<property name="text">
<string>RF Output Power</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QComboBox" name="r9mPower">
<item>
<property name="text">
<string>10 mW</string>
</property>
</item>
<item>
<property name="text">
<string>100 mW</string>
</property>
</item>
<item>
<property name="text">
<string>500 mW</string>
</property>
</item>
<item>
<property name="text">
<string>1000 mW</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item row="1" column="0" colspan="3">

View file

@ -45,6 +45,14 @@ ModelPrinter::~ModelPrinter()
{
}
QString ModelPrinter::printBoolean(bool val)
{
if (val)
return tr("Y");
else
return tr("N");
}
void debugHtml(const QString & html)
{
QFile file("foo.html");
@ -140,7 +148,7 @@ QString ModelPrinter::printMultiRfProtocol(int rfProtocol, bool custom)
return CHECK_IN_ARRAY(strings, rfProtocol);
}
QString ModelPrinter::printMultiSubType(int rfProtocol, bool custom, unsigned int subType) {
QString ModelPrinter::printMultiSubType(unsigned rfProtocol, bool custom, unsigned int subType) {
/* custom protocols */
if (custom)
@ -154,6 +162,39 @@ QString ModelPrinter::printMultiSubType(int rfProtocol, bool custom, unsigned in
return "???";
}
QString ModelPrinter::printR9MPowerValue(unsigned subType, unsigned val, bool telem)
{
static const QStringList strFTC = QStringList() << tr("10mW") << tr("100mW") << tr("500mW") << tr("1W");
static const QStringList strLBT = QStringList() << tr("25mW") << tr("500mW");
if (subType == 0 && (int)val < strFTC.size())
return strFTC.at(val);
else if (subType == 1)
return (telem ? strLBT.at(0) : strLBT.at(1));
else
return "???";
}
QString ModelPrinter::printModuleSubType(unsigned protocol, unsigned subType, unsigned rfProtocol, bool custom)
{
static const char * strings[] = {
"FCC",
"LBT(EU)"
};
switch (protocol) {
case PULSES_MULTIMODULE:
return printMultiSubType(rfProtocol, custom, subType);
case PULSES_PXX_R9M:
return CHECK_IN_ARRAY(strings, subType);
default:
return "???";
}
}
QString ModelPrinter::printModule(int idx) {
const ModuleData &module = model.moduleData[idx];
if (module.protocol == PULSES_OFF)
@ -167,6 +208,8 @@ QString ModelPrinter::printModule(int idx) {
}
if (module.protocol == PULSES_MULTIMODULE)
result += " " + tr("radio Protocol %1, subType %2, option value %3").arg(printMultiRfProtocol(module.multi.rfProtocol, module.multi.customProto)).arg(printMultiSubType(module.multi.rfProtocol, module.multi.customProto, module.subType)).arg(module.multi.optionValue);
else if (module.protocol == PULSES_PXX_R9M)
result += " " + tr("Module Type: %1, Power: %2, Telemetry Enabled: %3").arg(printModuleSubType(module.protocol, module.subType)).arg(printR9MPowerValue(module.subType, module.pxx.power, module.pxx.sport_out)).arg(printBoolean(module.pxx.sport_out));
return result;
}
}
@ -709,7 +752,7 @@ QString ModelPrinter::printGlobalVarMax(int idx)
QString ModelPrinter::printGlobalVarPopup(int idx)
{
return (model.gvarData[idx].popup ? "Y" : "N" );
return printBoolean(model.gvarData[idx].popup);
}
QString ModelPrinter::printOutputValueGVar(int val)
@ -760,6 +803,6 @@ QString ModelPrinter::printOutputCurve(int idx)
QString ModelPrinter::printOutputSymetrical(int idx)
{
return (model.limitData[idx].symetrical ? "Y": "N");
return printBoolean(model.limitData[idx].symetrical);
}

View file

@ -54,12 +54,15 @@ class ModelPrinter: public QObject
ModelPrinter(Firmware * firmware, const GeneralSettings & generalSettings, const ModelData & model);
virtual ~ModelPrinter();
QString printBoolean(bool val);
QString printEEpromSize();
QString printTrimIncrementMode();
QString printThrottleTrimMode();
static QString printModuleProtocol(unsigned int protocol);
static QString printMultiRfProtocol(int rfProtocol, bool custom);
static QString printMultiSubType(int rfProtocol, bool custom, unsigned int subType);
static QString printR9MPowerValue(unsigned subType, unsigned val, bool telem);
static QString printMultiSubType(unsigned rfProtocol, bool custom, unsigned int subType);
static QString printModuleSubType(unsigned protocol, unsigned subType, unsigned rfProtocol = 0, bool custom = false);
QString printFlightModeSwitch(const RawSwitch & swtch);
QString printFlightModeName(int index);
QString printFlightModes(unsigned int flightModes);

View file

@ -41,7 +41,7 @@ option(FAS_PROTOTYPE "Support of old FAS prototypes (different resistors)" OFF)
option(TEMPLATES "Model templates menu" OFF)
option(TRACE_SIMPGMSPACE "Turn on traces in simpgmspace.cpp" ON)
option(TRACE_LUA_INTERNALS "Turn on traces for Lua internals" OFF)
option(BINDING_OPTIONS "Allow advanced frsky bindings" OFF)
option(BINDING_OPTIONS "Allow advanced FrSky bindings" OFF)
option(FRSKY_STICKS "Reverse sticks for FrSky sticks" OFF)
option(NANO "Use nano newlib and binalloc")
option(NIGHTLY_BUILD_WARNING "Warn this is a nightly build" OFF)

View file

@ -667,23 +667,23 @@ PACK(struct ModuleData {
} ppm;
NOBACKUP(struct {
uint8_t rfProtocolExtra:2;
uint8_t spare:3;
uint8_t spare1:3;
uint8_t customProto:1;
uint8_t autoBindMode:1;
uint8_t lowPowerMode:1;
int8_t optionValue;
} multi);
NOBACKUP(struct {
uint8_t power:2; // 0 10 mW, 1 100 mW, 2 500 mW, 3 1W
uint8_t spare:2;
uint8_t power:2; // 0=10 mW, 1=100 mW, 2=500 mW, 3=1W
uint8_t spare1:2;
uint8_t receiver_telem_off:1; // false = receiver telem enabled
uint8_t receiver_channel_9_16:1; // false = pwm out 1-8, true 9-16
uint8_t external_antenna:1; // false = internal antenna, true = external antenna
uint8_t sport_out:1;
uint8_t spare3;
uint8_t spare2;
} pxx);
NOBACKUP(struct {
uint8_t spare:6;
uint8_t spare1:6;
uint8_t noninverted:1;
uint8_t spare2:1;
int8_t refreshRate; // definition as framelength for ppm (* 5 + 225 = time in 1/10 ms)

View file

@ -143,7 +143,7 @@ enum MenuModelSetupItems {
#endif
#define PORT_CHANNELS_ROWS(x) (x==EXTERNAL_MODULE ? EXTERNAL_MODULE_CHANNELS_ROWS : 0)
#define EXTERNAL_MODULE_MODE_ROWS (IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0
#define EXTERNAL_MODULE_MODE_ROWS (IS_MODULE_PXX(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE) || IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0
#define CURSOR_ON_CELL (true)
#define MODEL_SETUP_MAX_LINES (HEADER_LINE+ITEM_MODEL_SETUP_MAX)
@ -181,27 +181,49 @@ enum MenuModelSetupItems {
#if defined(BINDING_OPTIONS)
void onBindMenu(const char * result)
{
if (result == STR_BINDING_1_8_TELEM_ON) {
g_model.moduleData[INTERNAL_MODULE].pxx.receiver_telem_off = false;
g_model.moduleData[INTERNAL_MODULE].pxx.receiver_channel_9_16 = false;
uint8_t moduleIdx = CURRENT_MODULE_EDITED(menuVerticalPosition);
if (result == STR_BINDING_25MW_CH1_8_TELEM_OFF) {
g_model.moduleData[moduleIdx].pxx.power = R9M_LBT_POWER_25;
g_model.moduleData[moduleIdx].pxx.receiver_telem_off = true;
g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = false;
}
else if (result == STR_BINDING_25MW_CH1_8_TELEM_ON) {
g_model.moduleData[moduleIdx].pxx.power = R9M_LBT_POWER_25;
g_model.moduleData[moduleIdx].pxx.receiver_telem_off = false;
g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = false;
}
else if (result == STR_BINDING_500MW_CH1_8_TELEM_OFF) {
g_model.moduleData[moduleIdx].pxx.power = R9M_LBT_POWER_500;
g_model.moduleData[moduleIdx].pxx.receiver_telem_off = true;
g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = false;
}
else if (result == STR_BINDING_500MW_CH9_16_TELEM_OFF) {
g_model.moduleData[moduleIdx].pxx.power = R9M_LBT_POWER_500;
g_model.moduleData[moduleIdx].pxx.receiver_telem_off = true;
g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = true;
}
else if (result == STR_BINDING_1_8_TELEM_ON) {
g_model.moduleData[moduleIdx].pxx.receiver_telem_off = false;
g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = false;
}
else if (result == STR_BINDING_1_8_TELEM_OFF) {
g_model.moduleData[INTERNAL_MODULE].pxx.receiver_telem_off = true;
g_model.moduleData[INTERNAL_MODULE].pxx.receiver_channel_9_16 = false;
g_model.moduleData[moduleIdx].pxx.receiver_telem_off = true;
g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = false;
}
else if (result == STR_BINDING_9_16_TELEM_ON) {
g_model.moduleData[INTERNAL_MODULE].pxx.receiver_telem_off = false;
g_model.moduleData[INTERNAL_MODULE].pxx.receiver_channel_9_16 = true;
g_model.moduleData[moduleIdx].pxx.receiver_telem_off = false;
g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = true;
}
else if (result == STR_BINDING_9_16_TELEM_OFF) {
g_model.moduleData[INTERNAL_MODULE].pxx.receiver_telem_off = true;
g_model.moduleData[INTERNAL_MODULE].pxx.receiver_channel_9_16 = true;
g_model.moduleData[moduleIdx].pxx.receiver_telem_off = true;
g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = true;
}
else {
return;
}
moduleFlag[INTERNAL_MODULE] = MODULE_BIND;
moduleFlag[moduleIdx] = MODULE_BIND;
}
#endif
@ -711,6 +733,8 @@ void menuModelSetup(event_t event)
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+5*FW, y, STR_XJT_PROTOCOLS, 1+g_model.moduleData[EXTERNAL_MODULE].rfProtocol, menuHorizontalPosition==1 ? attr : 0);
else if (IS_MODULE_DSM2(EXTERNAL_MODULE))
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+5*FW, y, STR_DSM_PROTOCOLS, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, menuHorizontalPosition==1 ? attr : 0);
else if (IS_MODULE_R9M(EXTERNAL_MODULE))
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+5*FW, y, STR_R9M_MODES, g_model.moduleData[EXTERNAL_MODULE].subType, (menuHorizontalPosition==1 ? attr : 0));
#if defined(MULTIMODULE)
else if (IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) {
int multi_rfProto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false);
@ -735,6 +759,8 @@ void menuModelSetup(event_t event)
case 1:
if (IS_MODULE_DSM2(EXTERNAL_MODULE))
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, DSM2_PROTO_LP45, DSM2_PROTO_DSMX);
else if (IS_MODULE_R9M(EXTERNAL_MODULE))
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, MODULE_SUBTYPE_R9M_FCC, MODULE_SUBTYPE_R9M_LBT);
#if defined(MULTIMODULE)
else if (IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) {
int multiRfProto = g_model.moduleData[EXTERNAL_MODULE].multi.customProto == 1 ? MM_RF_PROTO_CUSTOM : g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false);
@ -747,7 +773,8 @@ void menuModelSetup(event_t event)
// Sensible default for DSM2 (same as for ppm): 7ch@22ms + Autodetect settings enabled
if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) == MM_RF_PROTO_DSM2) {
g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode = 1;
} else {
}
else {
g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode = 0;
}
g_model.moduleData[EXTERNAL_MODULE].multi.optionValue = 0;
@ -776,8 +803,8 @@ void menuModelSetup(event_t event)
if (multi_rfProto == MM_RF_CUSTOM_SELECTED) {
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN + 3 * FW, y, g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false), RIGHT | (menuHorizontalPosition == 0 ? attr : 0), 2);
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN + 5 * FW, y, g_model.moduleData[EXTERNAL_MODULE].subType, RIGHT | (menuHorizontalPosition == 1 ? attr : 0), 2);
} else
{
}
else {
if (pdef->subTypeString != nullptr)
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, pdef->subTypeString, g_model.moduleData[EXTERNAL_MODULE].subType, attr);
}
@ -991,17 +1018,28 @@ void menuModelSetup(event_t event)
if (attr && l_posHorz > 0) {
if (s_editMode > 0) {
if (l_posHorz == 1) {
if (IS_MODULE_XJT(moduleIdx) && g_model.moduleData[moduleIdx].rfProtocol== RF_PROTO_X16 && s_current_protocol[INTERNAL_MODULE] == PROTO_PXX) {
if (IS_MODULE_R9M(moduleIdx) || (IS_MODULE_XJT(moduleIdx) && g_model.moduleData[moduleIdx].rfProtocol== RF_PROTO_X16)) {
if (event == EVT_KEY_BREAK(KEY_ENTER)) {
uint8_t default_selection;
if (IS_MODULE_R9M_LBT(moduleIdx)) {
POPUP_MENU_ADD_ITEM(STR_BINDING_25MW_CH1_8_TELEM_OFF);
POPUP_MENU_ADD_ITEM(STR_BINDING_25MW_CH1_8_TELEM_ON);
POPUP_MENU_ADD_ITEM(STR_BINDING_500MW_CH1_8_TELEM_OFF);
POPUP_MENU_ADD_ITEM(STR_BINDING_500MW_CH9_16_TELEM_OFF);
default_selection = 2;
}
else {
POPUP_MENU_ADD_ITEM(STR_BINDING_1_8_TELEM_ON);
POPUP_MENU_ADD_ITEM(STR_BINDING_1_8_TELEM_OFF);
POPUP_MENU_ADD_ITEM(STR_BINDING_9_16_TELEM_ON);
POPUP_MENU_ADD_ITEM(STR_BINDING_9_16_TELEM_OFF);
POPUP_MENU_SELECT_ITEM(g_model.moduleData[INTERNAL_MODULE].pxx.receiver_telem_off + (g_model.moduleData[INTERNAL_MODULE].pxx.receiver_channel_9_16 << 1));
default_selection = g_model.moduleData[INTERNAL_MODULE].pxx.receiver_telem_off + (g_model.moduleData[INTERNAL_MODULE].pxx.receiver_channel_9_16 << 1);
}
POPUP_MENU_SELECT_ITEM(default_selection);
POPUP_MENU_START(onBindMenu);
continue;
}
if (moduleFlag[INTERNAL_MODULE] == MODULE_BIND) {
if (moduleFlag[moduleIdx] == MODULE_BIND) {
newFlag = MODULE_BIND;
}
else {
@ -1083,7 +1121,9 @@ void menuModelSetup(event_t event)
}
}
break;
case ITEM_MODEL_EXTERNAL_MODULE_OPTIONS: {
case ITEM_MODEL_EXTERNAL_MODULE_OPTIONS:
{
uint8_t moduleIdx = CURRENT_MODULE_EDITED(k);
#if defined(MULTIMODULE)
if (IS_MODULE_MULTIMODULE(moduleIdx)) {
@ -1101,21 +1141,23 @@ void menuModelSetup(event_t event)
if (attr) {
if (multi_proto == MM_RF_PROTO_FS_AFHDS2A) {
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].multi.optionValue, 0, 70);
} else if (multi_proto == MM_RF_PROTO_OLRS) {
}
else if (multi_proto == MM_RF_PROTO_OLRS) {
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].multi.optionValue, -1, 7);
} else {
}
else {
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].multi.optionValue, -128, 127);
}
}
}
#endif
if (IS_MODULE_R9M(moduleIdx)) {
if (IS_TELEMETRY_INTERNAL_MODULE) {
lcdDrawTextAlignedLeft(y, STR_SPORT_OUT);
if (IS_TELEMETRY_INTERNAL_MODULE()) {
lcdDrawTextAlignedLeft(y, STR_MODULE_TELEMETRY);
lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_DISABLE_INTERNAL);
}
else {
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);
g_model.moduleData[moduleIdx].pxx.sport_out = editCheckBox(g_model.moduleData[EXTERNAL_MODULE].pxx.sport_out, MODEL_SETUP_2ND_COLUMN, y, STR_MODULE_TELEMETRY, attr, event);
}
}
else if (IS_MODULE_SBUS(moduleIdx)) {
@ -1124,21 +1166,26 @@ void menuModelSetup(event_t event)
}
break;
}
case ITEM_MODEL_EXTERNAL_MODULE_POWER: {
case ITEM_MODEL_EXTERNAL_MODULE_POWER:
{
uint8_t moduleIdx = CURRENT_MODULE_EDITED(k);
if (IS_MODULE_R9M_FCC(moduleIdx)) {
// Power selection is only available on R9M FCC
lcdDrawTextAlignedLeft(y, TR_MULTI_RFPOWER);
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_R9M_FCC_POWER_VALUES, g_model.moduleData[moduleIdx].pxx.power, LEFT | attr);
if (attr)
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].pxx.power, 0, R9M_FCC_POWER_MAX);
}
#if defined(MULTIMODULE)
if (IS_MODULE_MULTIMODULE(moduleIdx)) {
else if (IS_MODULE_MULTIMODULE(moduleIdx)) {
g_model.moduleData[EXTERNAL_MODULE].multi.lowPowerMode = editCheckBox(g_model.moduleData[EXTERNAL_MODULE].multi.lowPowerMode, MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_LOWPOWER, attr, event);
}
#endif
if (IS_MODULE_R9M(moduleIdx)) {
lcdDrawTextAlignedLeft(y, TR_MULTI_RFPOWER);
lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, getR9MPowerString(g_model.moduleData[moduleIdx].pxx.power), attr);
if (attr)
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].pxx.power, 0, 3);
}
}
break;
#if defined(MULTIMODULE)
case ITEM_MODEL_EXTERNAL_MODULE_AUTOBIND:
if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) == MM_RF_PROTO_DSM2)
@ -1146,6 +1193,7 @@ void menuModelSetup(event_t event)
else
g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode = editCheckBox(g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode, MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_AUTOBIND, attr, event);
break;
case ITEM_MODEL_EXTERNAL_MODULE_STATUS: {
lcdDrawTextAlignedLeft(y, STR_MODULE_STATUS);
@ -1154,6 +1202,7 @@ void menuModelSetup(event_t event)
lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, statusText);
break;
}
case ITEM_MODEL_EXTERNAL_MODULE_SYNCSTATUS: {
lcdDrawTextAlignedLeft(y, STR_MODULE_SYNC);

View file

@ -103,30 +103,54 @@ enum MenuModelSetupItems {
#define MODEL_SETUP_RANGE_OFS 7*FW
#define MODEL_SETUP_SET_FAILSAFE_OFS 10*FW-2
#define CURRENT_MODULE_EDITED(k) (k>=ITEM_MODEL_TRAINER_LABEL ? TRAINER_MODULE : (k>=ITEM_MODEL_EXTERNAL_MODULE_LABEL ? EXTERNAL_MODULE : INTERNAL_MODULE))
#if defined(BINDING_OPTIONS)
void onBindMenu(const char * result)
{
if (result == STR_BINDING_1_8_TELEM_ON) {
g_model.moduleData[INTERNAL_MODULE].pxx.receiver_telem_off = false;
g_model.moduleData[INTERNAL_MODULE].pxx.receiver_channel_9_16 = false;
uint8_t moduleIdx = CURRENT_MODULE_EDITED(menuVerticalPosition);
if (result == STR_BINDING_25MW_CH1_8_TELEM_OFF) {
g_model.moduleData[moduleIdx].pxx.power = R9M_LBT_POWER_25;
g_model.moduleData[moduleIdx].pxx.receiver_telem_off = true;
g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = false;
}
else if (result == STR_BINDING_25MW_CH1_8_TELEM_ON) {
g_model.moduleData[moduleIdx].pxx.power = R9M_LBT_POWER_25;
g_model.moduleData[moduleIdx].pxx.receiver_telem_off = false;
g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = false;
}
else if (result == STR_BINDING_500MW_CH1_8_TELEM_OFF) {
g_model.moduleData[moduleIdx].pxx.power = R9M_LBT_POWER_500;
g_model.moduleData[moduleIdx].pxx.receiver_telem_off = true;
g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = false;
}
else if (result == STR_BINDING_500MW_CH9_16_TELEM_OFF) {
g_model.moduleData[moduleIdx].pxx.power = R9M_LBT_POWER_500;
g_model.moduleData[moduleIdx].pxx.receiver_telem_off = true;
g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = true;
}
else if (result == STR_BINDING_1_8_TELEM_ON) {
g_model.moduleData[moduleIdx].pxx.receiver_telem_off = false;
g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = false;
}
else if (result == STR_BINDING_1_8_TELEM_OFF) {
g_model.moduleData[INTERNAL_MODULE].pxx.receiver_telem_off = true;
g_model.moduleData[INTERNAL_MODULE].pxx.receiver_channel_9_16 = false;
g_model.moduleData[moduleIdx].pxx.receiver_telem_off = true;
g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = false;
}
else if (result == STR_BINDING_9_16_TELEM_ON) {
g_model.moduleData[INTERNAL_MODULE].pxx.receiver_telem_off = false;
g_model.moduleData[INTERNAL_MODULE].pxx.receiver_channel_9_16 = true;
g_model.moduleData[moduleIdx].pxx.receiver_telem_off = false;
g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = true;
}
else if (result == STR_BINDING_9_16_TELEM_OFF) {
g_model.moduleData[INTERNAL_MODULE].pxx.receiver_telem_off = true;
g_model.moduleData[INTERNAL_MODULE].pxx.receiver_channel_9_16 = true;
g_model.moduleData[moduleIdx].pxx.receiver_telem_off = true;
g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = true;
}
else {
return;
}
moduleFlag[INTERNAL_MODULE] = MODULE_BIND;
moduleFlag[moduleIdx] = MODULE_BIND;
}
#endif
@ -219,8 +243,6 @@ void editTimerCountdown(int timerIdx, coord_t y, LcdFlags attr, event_t event)
}
}
#define CURRENT_MODULE_EDITED(k) (k>=ITEM_MODEL_TRAINER_LABEL ? TRAINER_MODULE : (k>=ITEM_MODEL_EXTERNAL_MODULE_LABEL ? EXTERNAL_MODULE : INTERNAL_MODULE))
int getSwitchWarningsCount()
{
int count = 0;
@ -253,7 +275,7 @@ int getSwitchWarningsCount()
#define TIMER_ROWS(x) 2|NAVIGATION_LINE_BY_LINE, 0, 0, 0, g_model.timers[x].countdownBeep != COUNTDOWN_SILENT ? (uint8_t) 1 : (uint8_t)0
#define EXTERNAL_MODULE_MODE_ROWS (IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : IS_MODULE_MULTIMODULE(EXTERNAL_MODULE) ? MULTIMODULE_MODE_ROWS(EXTERNAL_MODULE) : (uint8_t)0
#define EXTERNAL_MODULE_MODE_ROWS (IS_MODULE_PXX(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : IS_MODULE_MULTIMODULE(EXTERNAL_MODULE) ? MULTIMODULE_MODE_ROWS(EXTERNAL_MODULE) : (uint8_t)0
#if TIMERS == 1
#define TIMERS_ROWS TIMER_ROWS(0)
@ -307,7 +329,10 @@ void menuModelSetup(event_t event)
MULTIMODULE_STATUS_ROWS
EXTERNAL_MODULE_CHANNELS_ROWS,
((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,
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
MENU_CHECK(STR_MENUSETUP, menuTabModel, MENU_MODEL_SETUP, ITEM_MODEL_SETUP_MAX);
@ -741,6 +766,8 @@ void menuModelSetup(event_t event)
lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_XJT_PROTOCOLS, 1+g_model.moduleData[EXTERNAL_MODULE].rfProtocol, menuHorizontalPosition==1 ? attr : 0);
else if (IS_MODULE_DSM2(EXTERNAL_MODULE))
lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_DSM_PROTOCOLS, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, menuHorizontalPosition==1 ? attr : 0);
else if (IS_MODULE_R9M(EXTERNAL_MODULE))
lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_R9M_MODES, g_model.moduleData[EXTERNAL_MODULE].subType, (menuHorizontalPosition==1 ? attr : 0));
#if defined(MULTIMODULE)
else if (IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) {
uint8_t multi_rfProto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false);
@ -775,6 +802,8 @@ void menuModelSetup(event_t event)
case 1:
if (IS_MODULE_DSM2(EXTERNAL_MODULE))
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, DSM2_PROTO_LP45, DSM2_PROTO_DSMX);
else if (IS_MODULE_R9M(EXTERNAL_MODULE))
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, MODULE_SUBTYPE_R9M_FCC, MODULE_SUBTYPE_R9M_LBT);
#if defined(MULTIMODULE)
else if (IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) {
int multiRfProto = g_model.moduleData[EXTERNAL_MODULE].multi.customProto == 1 ? MM_RF_PROTO_CUSTOM : g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false);
@ -787,7 +816,8 @@ void menuModelSetup(event_t event)
// Sensible default for DSM2 (same as for ppm): 7ch@22ms + Autodetect settings enabled
if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) == MM_RF_PROTO_DSM2) {
g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode = 1;
} else {
}
else {
g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode = 0;
}
g_model.moduleData[EXTERNAL_MODULE].multi.optionValue = 0;
@ -807,7 +837,8 @@ void menuModelSetup(event_t event)
if (g_model.moduleData[EXTERNAL_MODULE].multi.customProto) {
g_model.moduleData[EXTERNAL_MODULE].setMultiProtocol(checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false), 0, 63, EE_MODEL));
break;
} else {
}
else {
const mm_protocol_definition * pdef = getMultiProtocolDefinition(g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false));
if (pdef->maxSubtype > 0)
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, pdef->maxSubtype);
@ -967,11 +998,11 @@ void menuModelSetup(event_t event)
lcdDrawTextAlignedLeft(y, STR_RECEIVER_NUM);
}
if (IS_MODULE_PXX(moduleIdx) || IS_MODULE_DSM2(moduleIdx) || IS_MODULE_MULTIMODULE(moduleIdx)) {
if (xOffsetBind) lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, g_model.header.modelId[moduleIdx], (l_posHorz==0 ? attr : 0) | LEADING0|LEFT, 2);
if (xOffsetBind)
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, g_model.header.modelId[moduleIdx], (l_posHorz==0 ? attr : 0) | LEADING0|LEFT, 2);
if (attr && l_posHorz==0) {
if (s_editMode>0) {
CHECK_INCDEC_MODELVAR_ZERO(event, g_model.header.modelId[moduleIdx], MAX_RX_NUM(moduleIdx));
if (checkIncDec_Ret) {
modelHeaders[g_eeGeneral.currModel].modelId[moduleIdx] = g_model.header.modelId[moduleIdx];
}
@ -993,17 +1024,28 @@ void menuModelSetup(event_t event)
if (attr && l_posHorz>0) {
if (s_editMode>0) {
if (l_posHorz == 1) {
if (IS_MODULE_XJT(moduleIdx) && g_model.moduleData[moduleIdx].rfProtocol== RF_PROTO_X16 && s_current_protocol[INTERNAL_MODULE] == PROTO_PXX) {
if (IS_MODULE_R9M(moduleIdx) || (IS_MODULE_XJT(moduleIdx) && g_model.moduleData[moduleIdx].rfProtocol== RF_PROTO_X16)) {
if (event == EVT_KEY_BREAK(KEY_ENTER)) {
uint8_t default_selection;
if (IS_MODULE_R9M_LBT(moduleIdx)) {
POPUP_MENU_ADD_ITEM(STR_BINDING_25MW_CH1_8_TELEM_OFF);
POPUP_MENU_ADD_ITEM(STR_BINDING_25MW_CH1_8_TELEM_ON);
POPUP_MENU_ADD_ITEM(STR_BINDING_500MW_CH1_8_TELEM_OFF);
POPUP_MENU_ADD_ITEM(STR_BINDING_500MW_CH9_16_TELEM_OFF);
default_selection = 2;
}
else {
POPUP_MENU_ADD_ITEM(STR_BINDING_1_8_TELEM_ON);
POPUP_MENU_ADD_ITEM(STR_BINDING_1_8_TELEM_OFF);
POPUP_MENU_ADD_ITEM(STR_BINDING_9_16_TELEM_ON);
POPUP_MENU_ADD_ITEM(STR_BINDING_9_16_TELEM_OFF);
POPUP_MENU_SELECT_ITEM(g_model.moduleData[INTERNAL_MODULE].pxx.receiver_telem_off + (g_model.moduleData[INTERNAL_MODULE].pxx.receiver_channel_9_16 << 1));
default_selection = g_model.moduleData[moduleIdx].pxx.receiver_telem_off + (g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 << 1);
}
POPUP_MENU_SELECT_ITEM(default_selection);
POPUP_MENU_START(onBindMenu);
continue;
}
if (moduleFlag[INTERNAL_MODULE] == MODULE_BIND) {
if (moduleFlag[moduleIdx] == MODULE_BIND) {
newFlag = MODULE_BIND;
}
else {
@ -1070,7 +1112,9 @@ void menuModelSetup(event_t event)
break;
}
break;
case ITEM_MODEL_EXTERNAL_MODULE_OPTIONS: {
case ITEM_MODEL_EXTERNAL_MODULE_OPTIONS:
{
uint8_t moduleIdx = CURRENT_MODULE_EDITED(k);
#if defined(MULTIMODULE)
@ -1100,12 +1144,12 @@ void menuModelSetup(event_t event)
}
#endif
if (IS_MODULE_R9M(moduleIdx)) {
if (IS_TELEMETRY_INTERNAL_MODULE) {
lcdDrawTextAlignedLeft(y, STR_SPORT_OUT);
if (IS_TELEMETRY_INTERNAL_MODULE()) {
lcdDrawTextAlignedLeft(y, STR_MODULE_TELEMETRY);
lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_DISABLE_INTERNAL);
}
else {
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);
g_model.moduleData[moduleIdx].pxx.sport_out = editCheckBox(g_model.moduleData[EXTERNAL_MODULE].pxx.sport_out, MODEL_SETUP_2ND_COLUMN, y, STR_MODULE_TELEMETRY, attr, event);
}
}
else if (IS_MODULE_SBUS(moduleIdx)) {
@ -1114,18 +1158,22 @@ void menuModelSetup(event_t event)
}
}
break;
case ITEM_MODEL_EXTERNAL_MODULE_POWER: {
case ITEM_MODEL_EXTERNAL_MODULE_POWER:
{
uint8_t moduleIdx = CURRENT_MODULE_EDITED(k);
#if defined (MULTIMODULE)
if (IS_MODULE_MULTIMODULE(moduleIdx))
g_model.moduleData[EXTERNAL_MODULE].multi.lowPowerMode = editCheckBox(g_model.moduleData[EXTERNAL_MODULE].multi.lowPowerMode, MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_LOWPOWER, attr, event);
#endif
if (IS_MODULE_R9M(moduleIdx)) {
if (IS_MODULE_R9M_FCC(moduleIdx)) {
// Power selection is only available on R9M FCC
lcdDrawTextAlignedLeft(y, TR_MULTI_RFPOWER);
lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, getR9MPowerString(g_model.moduleData[moduleIdx].pxx.power), attr);
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_R9M_FCC_POWER_VALUES, g_model.moduleData[moduleIdx].pxx.power, LEFT | attr);
if (attr)
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].pxx.power, 0, 3);
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].pxx.power, 0, R9M_FCC_POWER_MAX);
}
#if defined (MULTIMODULE)
else if (IS_MODULE_MULTIMODULE(moduleIdx)) {
g_model.moduleData[EXTERNAL_MODULE].multi.lowPowerMode = editCheckBox(g_model.moduleData[EXTERNAL_MODULE].multi.lowPowerMode, MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_LOWPOWER, attr, event);
}
#endif
break;
}
@ -1136,7 +1184,8 @@ void menuModelSetup(event_t event)
else
g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode = editCheckBox(g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode, MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_AUTOBIND, attr, event);
break;
case ITEM_MODEL_EXTERNAL_MODULE_STATUS: {
case ITEM_MODEL_EXTERNAL_MODULE_STATUS:
{
lcdDrawTextAlignedLeft(y, STR_MODULE_STATUS);
char statusText[64];

View file

@ -96,30 +96,54 @@ enum MenuModelSetupItems {
#define MODEL_SETUP_SET_FAILSAFE_OFS 100
#define MODEL_SETUP_SLIDPOT_SPACING 45
#define CURRENT_MODULE_EDITED(k) (k>=ITEM_MODEL_TRAINER_LABEL ? TRAINER_MODULE : (k>=ITEM_MODEL_EXTERNAL_MODULE_LABEL ? EXTERNAL_MODULE : INTERNAL_MODULE))
#if defined(BINDING_OPTIONS)
void onBindMenu(const char * result)
{
if (result == STR_BINDING_1_8_TELEM_ON) {
g_model.moduleData[INTERNAL_MODULE].pxx.receiver_telem_off = false;
g_model.moduleData[INTERNAL_MODULE].pxx.receiver_channel_9_16 = false;
uint8_t moduleIdx = CURRENT_MODULE_EDITED(menuVerticalPosition);
if (result == STR_BINDING_25MW_CH1_8_TELEM_OFF) {
g_model.moduleData[moduleIdx].pxx.power = R9M_LBT_POWER_25;
g_model.moduleData[moduleIdx].pxx.receiver_telem_off = true;
g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = false;
}
else if (result == STR_BINDING_25MW_CH1_8_TELEM_ON) {
g_model.moduleData[moduleIdx].pxx.power = R9M_LBT_POWER_25;
g_model.moduleData[moduleIdx].pxx.receiver_telem_off = false;
g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = false;
}
else if (result == STR_BINDING_500MW_CH1_8_TELEM_OFF) {
g_model.moduleData[moduleIdx].pxx.power = R9M_LBT_POWER_500;
g_model.moduleData[moduleIdx].pxx.receiver_telem_off = true;
g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = false;
}
else if (result == STR_BINDING_500MW_CH9_16_TELEM_OFF) {
g_model.moduleData[moduleIdx].pxx.power = R9M_LBT_POWER_500;
g_model.moduleData[moduleIdx].pxx.receiver_telem_off = true;
g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = true;
}
else if (result == STR_BINDING_1_8_TELEM_ON) {
g_model.moduleData[moduleIdx].pxx.receiver_telem_off = false;
g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = false;
}
else if (result == STR_BINDING_1_8_TELEM_OFF) {
g_model.moduleData[INTERNAL_MODULE].pxx.receiver_telem_off = true;
g_model.moduleData[INTERNAL_MODULE].pxx.receiver_channel_9_16 = false;
g_model.moduleData[moduleIdx].pxx.receiver_telem_off = true;
g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = false;
}
else if (result == STR_BINDING_9_16_TELEM_ON) {
g_model.moduleData[INTERNAL_MODULE].pxx.receiver_telem_off = false;
g_model.moduleData[INTERNAL_MODULE].pxx.receiver_channel_9_16 = true;
g_model.moduleData[moduleIdx].pxx.receiver_telem_off = false;
g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = true;
}
else if (result == STR_BINDING_9_16_TELEM_OFF) {
g_model.moduleData[INTERNAL_MODULE].pxx.receiver_telem_off = true;
g_model.moduleData[INTERNAL_MODULE].pxx.receiver_channel_9_16 = true;
g_model.moduleData[moduleIdx].pxx.receiver_telem_off = true;
g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 = true;
}
else {
return;
}
moduleFlag[INTERNAL_MODULE] = MODULE_BIND;
moduleFlag[moduleIdx] = MODULE_BIND;
}
#endif
@ -197,8 +221,6 @@ void editTimerCountdown(int timerIdx, coord_t y, LcdFlags attr, event_t event)
}
}
#define CURRENT_MODULE_EDITED(k) (k>=ITEM_MODEL_TRAINER_LABEL ? TRAINER_MODULE : (k>=ITEM_MODEL_EXTERNAL_MODULE_LABEL ? EXTERNAL_MODULE : INTERNAL_MODULE))
int getSwitchWarningsCount()
{
int count = 0;
@ -219,7 +241,7 @@ int getSwitchWarningsCount()
#define TIMER_ROWS(x) NAVIGATION_LINE_BY_LINE|1, 0, 0, 0, g_model.timers[x].countdownBeep != COUNTDOWN_SILENT ? (uint8_t)1 : (uint8_t)0
#define EXTERNAL_MODULE_MODE_ROWS (IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : IS_MODULE_MULTIMODULE(EXTERNAL_MODULE) ? MULTIMODULE_MODE_ROWS(EXTERNAL_MODULE) : (uint8_t)0
#define EXTERNAL_MODULE_MODE_ROWS (IS_MODULE_PXX(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : IS_MODULE_MULTIMODULE(EXTERNAL_MODULE) ? MULTIMODULE_MODE_ROWS(EXTERNAL_MODULE) : (uint8_t)0
#if TIMERS == 1
#define TIMERS_ROWS TIMER_ROWS(0)
@ -263,9 +285,15 @@ bool menuModelSetup(event_t event)
EXTERNAL_MODULE_MODE_ROWS,
MULTIMODULE_STATUS_ROWS
EXTERNAL_MODULE_CHANNELS_ROWS,
((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 });
((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_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 });
if (menuEvent) {
moduleFlag[0] = 0;
@ -665,6 +693,8 @@ bool menuModelSetup(event_t event)
lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_XJT_PROTOCOLS, 1+g_model.moduleData[EXTERNAL_MODULE].rfProtocol, (menuHorizontalPosition==1 ? attr : 0));
else if (IS_MODULE_DSM2(EXTERNAL_MODULE))
lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_DSM_PROTOCOLS, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, (menuHorizontalPosition==1 ? attr : 0));
else if (IS_MODULE_R9M(EXTERNAL_MODULE))
lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_R9M_MODES, g_model.moduleData[EXTERNAL_MODULE].subType, (menuHorizontalPosition==1 ? attr : 0));
#if defined(MULTIMODULE)
else if (IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) {
int multi_rfProto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false);
@ -672,9 +702,9 @@ bool menuModelSetup(event_t event)
lcdDrawText(MODEL_SETUP_3RD_COLUMN, y, STR_MULTI_CUSTOM, menuHorizontalPosition == 1 ? attr : 0);
lcdDrawNumber(MODEL_SETUP_4TH_COLUMN, y, multi_rfProto, menuHorizontalPosition==2 ? attr : 0, 2);
lcdDrawNumber(MODEL_SETUP_4TH_COLUMN + MODEL_SETUP_BIND_OFS, y, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==3 ? attr : 0, 2);
} else {
}
else {
const mm_protocol_definition * pdef = getMultiProtocolDefinition(multi_rfProto);
lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_MULTI_PROTOCOLS, multi_rfProto, menuHorizontalPosition == 1 ? attr : 0);
if (pdef->subTypeString != nullptr)
lcdDrawTextAtIndex(MODEL_SETUP_4TH_COLUMN, y, pdef->subTypeString, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0);
@ -696,6 +726,8 @@ bool menuModelSetup(event_t event)
case 1:
if (IS_MODULE_DSM2(EXTERNAL_MODULE))
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, DSM2_PROTO_LP45, DSM2_PROTO_DSMX);
else if (IS_MODULE_R9M(EXTERNAL_MODULE))
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, MODULE_SUBTYPE_R9M_FCC, MODULE_SUBTYPE_R9M_LBT);
#if defined(MULTIMODULE)
else if (IS_MODULE_MULTIMODULE(EXTERNAL_MODULE)) {
int multiRfProto = g_model.moduleData[EXTERNAL_MODULE].multi.customProto == 1 ? MM_RF_PROTO_CUSTOM : g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false);
@ -708,7 +740,8 @@ bool menuModelSetup(event_t event)
// Sensible default for DSM2 (same as for ppm): 7ch@22ms + Autodetect settings enabled
if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) == MM_RF_PROTO_DSM2) {
g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode = 1;
} else {
}
else {
g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode = 0;
}
g_model.moduleData[EXTERNAL_MODULE].multi.optionValue = 0;
@ -876,10 +909,10 @@ bool menuModelSetup(event_t event)
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_RECEIVER_NUM);
}
if (IS_MODULE_PXX(moduleIdx) || IS_MODULE_DSM2(moduleIdx) || IS_MODULE_MULTIMODULE(moduleIdx)) {
if (xOffsetBind) lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, g_model.header.modelId[moduleIdx], (l_posHorz==0 ? attr : 0) | LEADING0 | LEFT, 2);
if (attr && l_posHorz==0 && s_editMode>0) {
if (xOffsetBind)
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, g_model.header.modelId[moduleIdx], (l_posHorz==0 ? attr : 0) | LEADING0 | LEFT, 2);
if (attr && l_posHorz==0 && s_editMode>0)
CHECK_INCDEC_MODELVAR_ZERO(event, g_model.header.modelId[moduleIdx], MAX_RX_NUM(moduleIdx));
}
drawButton(MODEL_SETUP_2ND_COLUMN+xOffsetBind, y, STR_MODULE_BIND, (moduleFlag[moduleIdx] == MODULE_BIND ? BUTTON_ON : BUTTON_OFF) | (l_posHorz==1 ? attr : 0));
drawButton(MODEL_SETUP_2ND_COLUMN+MODEL_SETUP_RANGE_OFS+xOffsetBind, y, STR_MODULE_RANGE, (moduleFlag[moduleIdx] == MODULE_RANGECHECK ? BUTTON_ON : BUTTON_OFF) | (l_posHorz==2 ? attr : 0));
uint8_t newFlag = 0;
@ -893,17 +926,28 @@ bool menuModelSetup(event_t event)
if (attr && l_posHorz>0) {
if (s_editMode>0) {
if (l_posHorz == 1) {
if (IS_MODULE_XJT(moduleIdx) && g_model.moduleData[moduleIdx].rfProtocol== RF_PROTO_X16 && s_current_protocol[INTERNAL_MODULE] == PROTO_PXX) {
if (IS_MODULE_R9M(moduleIdx) || (IS_MODULE_XJT(moduleIdx) && g_model.moduleData[moduleIdx].rfProtocol == RF_PROTO_X16)) {
if (event == EVT_KEY_BREAK(KEY_ENTER)) {
uint8_t default_selection;
if (IS_MODULE_R9M_LBT(moduleIdx)) {
POPUP_MENU_ADD_ITEM(STR_BINDING_25MW_CH1_8_TELEM_OFF);
POPUP_MENU_ADD_ITEM(STR_BINDING_25MW_CH1_8_TELEM_ON);
POPUP_MENU_ADD_ITEM(STR_BINDING_500MW_CH1_8_TELEM_OFF);
POPUP_MENU_ADD_ITEM(STR_BINDING_500MW_CH9_16_TELEM_OFF);
default_selection = 2;
}
else {
POPUP_MENU_ADD_ITEM(STR_BINDING_1_8_TELEM_ON);
POPUP_MENU_ADD_ITEM(STR_BINDING_1_8_TELEM_OFF);
POPUP_MENU_ADD_ITEM(STR_BINDING_9_16_TELEM_ON);
POPUP_MENU_ADD_ITEM(STR_BINDING_9_16_TELEM_OFF);
POPUP_MENU_SELECT_ITEM(g_model.moduleData[INTERNAL_MODULE].pxx.receiver_telem_off + (g_model.moduleData[INTERNAL_MODULE].pxx.receiver_channel_9_16 << 1));
default_selection = g_model.moduleData[moduleIdx].pxx.receiver_telem_off + (g_model.moduleData[moduleIdx].pxx.receiver_channel_9_16 << 1);
}
POPUP_MENU_SELECT_ITEM(default_selection);
POPUP_MENU_START(onBindMenu);
continue;
}
if (moduleFlag[INTERNAL_MODULE] == MODULE_BIND) {
if (moduleFlag[moduleIdx] == MODULE_BIND) {
newFlag = MODULE_BIND;
}
else {
@ -970,7 +1014,9 @@ bool menuModelSetup(event_t event)
}
break;
}
case ITEM_MODEL_EXTERNAL_MODULE_OPTIONS: {
case ITEM_MODEL_EXTERNAL_MODULE_OPTIONS:
{
uint8_t moduleIdx = CURRENT_MODULE_EDITED(k);
#if defined(MULTIMODULE)
if (IS_MODULE_MULTIMODULE(moduleIdx)) {
@ -988,17 +1034,19 @@ bool menuModelSetup(event_t event)
if (attr) {
if (multi_proto == MM_RF_PROTO_FS_AFHDS2A) {
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].multi.optionValue, 0, 70);
} else if (multi_proto == MM_RF_PROTO_OLRS) {
}
else if (multi_proto == MM_RF_PROTO_OLRS) {
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].multi.optionValue, -1, 7);
} else {
}
else {
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].multi.optionValue, -128, 127);
}
}
}
#endif
if (IS_MODULE_R9M(moduleIdx)) {
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_SPORT_OUT);
if (IS_TELEMETRY_INTERNAL_MODULE) {
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MODULE_TELEMETRY);
if (IS_TELEMETRY_INTERNAL_MODULE()) {
lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_DISABLE_INTERNAL);
}
else {
@ -1011,13 +1059,16 @@ bool menuModelSetup(event_t event)
}
}
break;
case ITEM_MODEL_EXTERNAL_MODULE_POWER: {
case ITEM_MODEL_EXTERNAL_MODULE_POWER:
{
uint8_t moduleIdx = CURRENT_MODULE_EDITED(k);
if (IS_MODULE_R9M(moduleIdx)) {
lcdDrawText(MENUS_MARGIN_LEFT, y, TR_MULTI_RFPOWER);
lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, getR9MPowerString(g_model.moduleData[moduleIdx].pxx.power), LEFT | attr);
if (IS_MODULE_R9M_FCC(moduleIdx)) {
// Power selection is only available on R9M FCC
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MULTI_RFPOWER);
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_R9M_FCC_POWER_VALUES, g_model.moduleData[moduleIdx].pxx.power, LEFT | attr);
if (attr)
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].pxx.power, 0, 3);
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].pxx.power, 0, R9M_FCC_POWER_MAX);
}
#if defined(MULTIMODULE)
else if (IS_MODULE_MULTIMODULE(moduleIdx)) {
@ -1027,6 +1078,7 @@ bool menuModelSetup(event_t event)
#endif
}
break;
#if defined(MULTIMODULE)
case ITEM_MODEL_EXTERNAL_MODULE_AUTOBIND:
if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) == MM_RF_PROTO_DSM2)

View file

@ -68,7 +68,6 @@ bool isCurrentSensor(int sensor);
bool isTelemetryFieldAvailable(int index);
bool isTelemetryFieldComparisonAvailable(int index);
bool isSensorAvailable(int sensor);
const char* getR9MPowerString(int power);
bool modelHasNotes();
#endif
@ -158,9 +157,9 @@ const mm_protocol_definition *getMultiProtocolDefinition (uint8_t protocol);
#define IS_R9M_OR_XJTD16(x) ((IS_MODULE_XJT(x) && g_model.moduleData[x].rfProtocol== RF_PROTO_X16) || IS_MODULE_R9M(x))
#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 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 : 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
#define EXTERNAL_MODULE_POWER_ROW (IS_MODULE_MULTIMODULE(EXTERNAL_MODULE) || IS_MODULE_R9M_FCC(EXTERNAL_MODULE)) ? (uint8_t) 0 : HIDDEN_ROW
void editStickHardwareSettings(coord_t x, coord_t y, int idx, event_t event, LcdFlags flags);

View file

@ -738,18 +738,3 @@ void editStickHardwareSettings(coord_t x, coord_t y, int idx, event_t event, Lcd
else
lcdDrawMMM(x, y, flags);
}
const char* getR9MPowerString(int power)
{
switch (power) {
case 0:
return " 10 mW";
case 1:
return "100 mW";
case 2:
return "500 mW";
case 3:
default:
return " 1 W";
}
}

View file

@ -503,6 +503,12 @@ enum XJTRFProtocols {
RF_PROTO_LAST = RF_PROTO_LR12
};
enum R9MSubTypes
{
MODULE_SUBTYPE_R9M_FCC,
MODULE_SUBTYPE_R9M_LBT,
};
enum MultiModuleRFProtocols {
MM_RF_PROTO_CUSTOM = -1,
MM_RF_PROTO_FIRST = MM_RF_PROTO_CUSTOM,

View file

@ -455,6 +455,8 @@ void memswap(void * a, void * b, uint8_t size);
#define NUM_CHANNELS(idx) (8+g_model.moduleData[idx].channelsCount)
#endif
#define IS_MODULE_R9M(idx) (g_model.moduleData[idx].type == MODULE_TYPE_R9M)
#define IS_MODULE_R9M_FCC(idx) (IS_MODULE_R9M(idx) && g_model.moduleData[idx].subType == MODULE_SUBTYPE_R9M_FCC)
#define IS_MODULE_R9M_LBT(idx) (IS_MODULE_R9M(idx) && g_model.moduleData[idx].subType == MODULE_SUBTYPE_R9M_LBT)
#define IS_MODULE_PXX(idx) (IS_MODULE_XJT(idx) || IS_MODULE_R9M(idx))
#if defined(DSM2)

View file

@ -180,4 +180,28 @@ inline void SEND_FAILSAFE_1S()
}
}
#define LEN_R9M_MODES "\007"
#define TR_R9M_MODES "FCC\0 ""LBT(EU)"
#define LEN_R9M_FCC_POWER_VALUES "\006"
#define LEN_R9M_LBT_POWER_VALUES "\006"
#define TR_R9M_FCC_POWER_VALUES "10 mW\0" "100 mW" "500 mW" "1 W\0"
#define TR_R9M_LBT_POWER_VALUES "25 mW\0" "500 mW"
enum R9MFCCPowerValues {
R9M_FCC_POWER_10 = 0,
R9M_FCC_POWER_100,
R9M_FCC_POWER_500,
R9M_FCC_POWER_1000,
R9M_FCC_POWER_MAX = R9M_FCC_POWER_1000
};
enum R9MLBTPowerValues {
R9M_LBT_POWER_25 = 0,
R9M_LBT_POWER_500,
R9M_LBT_POWER_MAX = R9M_LBT_POWER_500
};
#define BIND_TELEM_ALLOWED(idx) (!IS_MODULE_R9M_LBT(idx) || g_model.moduleData[idx].pxx.power == R9M_LBT_POWER_25)
#define BIND_CH9TO16_ALLOWED(idx) (!IS_MODULE_R9M_LBT(idx) || g_model.moduleData[idx].pxx.power != R9M_LBT_POWER_25)
#endif // _PULSES_ARM_H_

View file

@ -378,19 +378,20 @@ void setupPulsesPXX(uint8_t port)
/* Ext. flag (holds antenna selection on Horus internal module, 0x00 otherwise) */
#if defined(PCBHORUS)
if (port == INTERNAL_MODULE) {
extra_flags |= g_model.moduleData[port].pxx.external_antenna;
extra_flags |= (g_model.moduleData[port].pxx.external_antenna << 0);
}
#endif
#if defined(BINDING_OPTIONS)
extra_flags |= g_model.moduleData[port].pxx.receiver_telem_off << 1;
extra_flags |= g_model.moduleData[port].pxx.receiver_channel_9_16 << 2;
extra_flags |= (g_model.moduleData[port].pxx.receiver_telem_off << 1);
extra_flags |= (g_model.moduleData[port].pxx.receiver_channel_9_16 << 2);
#endif
if (IS_MODULE_R9M(port)) {
extra_flags |= g_model.moduleData[port].pxx.power << 3;
// Disable s.port if internal module is active
if (IS_TELEMETRY_INTERNAL_MODULE || !g_model.moduleData[port].pxx.sport_out)
extra_flags |= (max(g_model.moduleData[port].pxx.power, IS_MODULE_R9M_FCC(port) ? (uint8_t)R9M_FCC_POWER_MAX : (uint8_t)R9M_LBT_POWER_MAX) << 3);
// Disable S.PORT if internal module is active
if (IS_TELEMETRY_INTERNAL_MODULE() || !g_model.moduleData[port].pxx.sport_out) {
extra_flags |= (1 << 5);
}
}
putPcmByte(port, extra_flags);

View file

@ -198,9 +198,9 @@ extern Fifo<uint8_t, LUA_TELEMETRY_INPUT_FIFO_SIZE> * luaInputTelemetryFifo;
#endif
#if defined(STM32)
#define IS_TELEMETRY_INTERNAL_MODULE (g_model.moduleData[INTERNAL_MODULE].type == MODULE_TYPE_XJT)
#define IS_TELEMETRY_INTERNAL_MODULE() (g_model.moduleData[INTERNAL_MODULE].type == MODULE_TYPE_XJT)
#else
#define IS_TELEMETRY_INTERNAL_MODULE (false)
#define IS_TELEMETRY_INTERNAL_MODULE() (false)
#endif
#endif // _TELEMETRY_H_

View file

@ -108,6 +108,9 @@ const pm_char STR_OPEN9X[] PROGMEM =
#if defined(CPUARM)
ISTR(VTRAINERMODES)
ISTR(TARANIS_PROTOCOLS)
ISTR(R9M_MODES)
ISTR(R9M_FCC_POWER_VALUES)
ISTR(R9M_LBT_POWER_VALUES)
ISTR(TELEMETRY_PROTOCOLS)
ISTR(XJT_PROTOCOLS)
ISTR(DSM_PROTOCOLS)
@ -388,7 +391,7 @@ const pm_char STR_RECEIVER[] PROGMEM = TR_RECEIVER;
const pm_char STR_SYNCMENU[] PROGMEM = TR_SYNCMENU;
const pm_char STR_INTERNALRF[] PROGMEM = TR_INTERNALRF;
const pm_char STR_EXTERNALRF[] PROGMEM = TR_EXTERNALRF;
const pm_char STR_SPORT_OUT[] PROGMEM = TR_SPORT_OUT;
const pm_char STR_MODULE_TELEMETRY[] PROGMEM = TR_MODULE_TELEMETRY;
const pm_char STR_COUNTRYCODE[] PROGMEM = TR_COUNTRYCODE;
const pm_char STR_USBMODE[] PROGMEM = TR_USBMODE;
const pm_char STR_FAILSAFE[] PROGMEM = TR_FAILSAFE;
@ -475,7 +478,6 @@ const pm_char STR_MULTI_CUSTOM[] PROGMEM = TR_MULTI_CUSTOM;
const pm_char STR_MULTI_RFTUNE[] PROGMEM = TR_MULTI_RFTUNE;
const pm_char STR_MULTI_TELEMETRY[] PROGMEM = TR_MULTI_TELEMETRY;
const pm_char STR_MULTI_VIDFREQ[] PROGMEM = TR_MULTI_VIDFREQ;
const pm_char STR_MULTI_RFPOWER[] PROGMEM = TR_MULTI_RFPOWER;
const pm_char STR_MULTI_OPTION[] PROGMEM = TR_MULTI_OPTION;
const pm_char STR_MULTI_AUTOBIND[] PROGMEM = TR_MULTI_AUTOBIND;
const pm_char STR_MULTI_DSM_AUTODTECT[] PROGMEM = TR_MULTI_DSM_AUTODTECT;
@ -615,10 +617,14 @@ const pm_char STR_BLCOLOR[] PROGMEM = TR_BLCOLOR;
#if defined(CPUARM)
const pm_char STR_TRAINER[] PROGMEM = TR_TRAINER;
const pm_char STR_MODULE_BIND[] PROGMEM = TR_MODULE_BIND;
const pm_char STR_BINDING_1_8_TELEM_ON[] PROGMEM = TR_BINDING_MODE1;
const pm_char STR_BINDING_1_8_TELEM_OFF[] PROGMEM = TR_BINDING_MODE2;
const pm_char STR_BINDING_9_16_TELEM_ON[] PROGMEM = TR_BINDING_MODE3;
const pm_char STR_BINDING_9_16_TELEM_OFF[] PROGMEM = TR_BINDING_MODE4;
const pm_char STR_BINDING_1_8_TELEM_ON[] PROGMEM = TR_BINDING_CH1_8_TELEM_ON;
const pm_char STR_BINDING_1_8_TELEM_OFF[] PROGMEM = TR_BINDING_CH1_8_TELEM_OFF;
const pm_char STR_BINDING_9_16_TELEM_ON[] PROGMEM = TR_BINDING_CH9_16_TELEM_ON;
const pm_char STR_BINDING_9_16_TELEM_OFF[] PROGMEM = TR_BINDING_CH9_16_TELEM_OFF;
const pm_char STR_BINDING_25MW_CH1_8_TELEM_OFF[] PROGMEM = TR_BINDING_25MW_CH1_8_TELEM_OFF;
const pm_char STR_BINDING_25MW_CH1_8_TELEM_ON[] PROGMEM = TR_BINDING_25MW_CH1_8_TELEM_ON;
const pm_char STR_BINDING_500MW_CH1_8_TELEM_OFF[] PROGMEM = TR_BINDING_500MW_CH1_8_TELEM_OFF;
const pm_char STR_BINDING_500MW_CH9_16_TELEM_OFF[] PROGMEM = TR_BINDING_500MW_CH9_16_TELEM_OFF;
const pm_char STR_CHANNELRANGE[] PROGMEM = TR_CHANNELRANGE;
const pm_char STR_ANTENNASELECTION[] PROGMEM = TR_ANTENNASELECTION;
const pm_char STR_ANTENNACONFIRM1[] PROGMEM = TR_ANTENNACONFIRM1;
@ -676,6 +682,7 @@ const pm_char STR_BLCOLOR[] PROGMEM = TR_BLCOLOR;
const pm_char STR_ADDMAINVIEW[] PROGMEM = TR_ADDMAINVIEW;
const pm_char STR_BACKGROUND_COLOR[] PROGMEM = TR_BACKGROUND_COLOR;
const pm_char STR_MAIN_COLOR[] PROGMEM = TR_MAIN_COLOR;
const pm_char STR_MULTI_RFPOWER[] PROGMEM = TR_MULTI_RFPOWER;
#endif
#if defined(CPUARM)

View file

@ -220,7 +220,10 @@ extern const pm_char STR_OPEN9X[];
#endif
#if defined(CPUARM)
#define OFS_TARANIS_PROTOCOLS (OFS_VTRAINERMODES + sizeof(TR_VTRAINERMODES))
#define OFS_TELEMETRY_PROTOCOLS (OFS_TARANIS_PROTOCOLS + sizeof(TR_TARANIS_PROTOCOLS))
#define OFS_R9M_MODES (OFS_TARANIS_PROTOCOLS + sizeof(TR_TARANIS_PROTOCOLS))
#define OFS_R9M_FCC_POWER_VALUES (OFS_R9M_MODES + sizeof(TR_R9M_MODES))
#define OFS_R9M_LBT_POWER_VALUES (OFS_R9M_FCC_POWER_VALUES + sizeof(TR_R9M_FCC_POWER_VALUES))
#define OFS_TELEMETRY_PROTOCOLS (OFS_R9M_LBT_POWER_VALUES + sizeof(TR_R9M_LBT_POWER_VALUES))
#define OFS_XJT_PROTOCOLS (OFS_TELEMETRY_PROTOCOLS + sizeof(TR_TELEMETRY_PROTOCOLS))
#define OFS_DSM_PROTOCOLS (OFS_XJT_PROTOCOLS + sizeof(TR_XJT_PROTOCOLS))
#if defined(MULTIMODULE)
@ -348,6 +351,9 @@ extern const pm_char STR_OPEN9X[];
#if defined(CPUARM)
#define STR_VTRAINERMODES (STR_OPEN9X + OFS_VTRAINERMODES)
#define STR_TARANIS_PROTOCOLS (STR_OPEN9X + OFS_TARANIS_PROTOCOLS)
#define STR_R9M_MODES (STR_OPEN9X + OFS_R9M_MODES)
#define STR_R9M_FCC_POWER_VALUES (STR_OPEN9X + OFS_R9M_FCC_POWER_VALUES)
#define STR_R9M_LBT_POWER_VALUES (STR_OPEN9X + OFS_R9M_LBT_POWER_VALUES)
#define STR_TELEMETRY_PROTOCOLS (STR_OPEN9X + OFS_TELEMETRY_PROTOCOLS)
#define STR_XJT_PROTOCOLS (STR_OPEN9X + OFS_XJT_PROTOCOLS)
#define STR_DSM_PROTOCOLS (STR_OPEN9X + OFS_DSM_PROTOCOLS)
@ -604,7 +610,6 @@ extern const pm_char STR_FAS_OFFSET[];
extern const pm_char STR_MULTI_CUSTOM[];
extern const pm_char STR_MULTI_OPTION[];
extern const pm_char STR_MULTI_VIDFREQ[];
extern const pm_char STR_MULTI_RFPOWER[];
extern const pm_char STR_MULTI_RFTUNE[];
extern const pm_char STR_MULTI_TELEMETRY[];
extern const pm_char STR_MULTI_AUTOBIND[];
@ -632,7 +637,7 @@ extern const pm_char STR_RECEIVER[];
extern const pm_char STR_SYNCMENU[];
extern const pm_char STR_INTERNALRF[];
extern const pm_char STR_EXTERNALRF[];
extern const pm_char STR_SPORT_OUT[];
extern const pm_char STR_MODULE_TELEMETRY[];
extern const pm_char STR_FAILSAFE[];
extern const pm_char STR_FAILSAFESET[];
extern const pm_char STR_HOLD[];
@ -920,6 +925,10 @@ extern const pm_char STR_BLCOLOR[];
extern const pm_char STR_BINDING_1_8_TELEM_OFF[];
extern const pm_char STR_BINDING_9_16_TELEM_ON[];
extern const pm_char STR_BINDING_9_16_TELEM_OFF[];
extern const pm_char STR_BINDING_25MW_CH1_8_TELEM_OFF[];
extern const pm_char STR_BINDING_25MW_CH1_8_TELEM_ON[];
extern const pm_char STR_BINDING_500MW_CH1_8_TELEM_OFF[];
extern const pm_char STR_BINDING_500MW_CH9_16_TELEM_OFF[];
extern const pm_char STR_CHANNELRANGE[];
extern const pm_char STR_ANTENNASELECTION[];
extern const pm_char STR_ANTENNACONFIRM1[];
@ -977,6 +986,7 @@ extern const pm_char STR_DISABLE_ALARM[];
extern const pm_char STR_ADDMAINVIEW[];
extern const pm_char STR_BACKGROUND_COLOR[];
extern const pm_char STR_MAIN_COLOR[];
extern const pm_char STR_MULTI_RFPOWER[];
#endif
#if defined(CPUARM)

View file

@ -860,17 +860,21 @@
#define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on powerup")
#define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodetect", INDENT "Autodetect format")
#define TR_MULTI_LOWPOWER TR(INDENT "Low power", INDENT "Low power mode")
#define TR_SPORT_OUT INDENT "Telemetry"
#define TR_MODULE_TELEMETRY TR(INDENT "Mod telem.", INDENT "Module telemetry")
#define TR_DISABLE_INTERNAL TR("Disable int.", "Disable internal RF")
#define TR_MODULE_NO_SERIAL_MODE TR("!serial mode", "Not in serial mode")
#define TR_MODULE_NO_INPUT TR("No input", "No serial input")
#define TR_MODULE_NO_TELEMETRY TR3( "No telemetry", "No MULTI_TELEMETRY", "No MULTI_TELEMETRY detected")
#define TR_MODULE_WAITFORBIND "Bind to load protocol"
#define TR_MODULE_BINDING TR("Bind...","Binding")
#define TR_BINDING_MODE1 "Ch1-8 Telem ON"
#define TR_BINDING_MODE2 "Ch1-8 Telem OFF"
#define TR_BINDING_MODE3 "Ch9-16 Telem ON"
#define TR_BINDING_MODE4 "Ch9-16 Telem OFF"
#define TR_BINDING_CH1_8_TELEM_ON "Ch1-8 Telem ON"
#define TR_BINDING_CH1_8_TELEM_OFF "Ch1-8 Telem OFF"
#define TR_BINDING_CH9_16_TELEM_ON "Ch9-16 Telem ON"
#define TR_BINDING_CH9_16_TELEM_OFF "Ch9-16 Telem OFF"
#define TR_BINDING_25MW_CH1_8_TELEM_OFF "25mW Ch1-8 Telem OFF"
#define TR_BINDING_25MW_CH1_8_TELEM_ON "25mW Ch1-8 Telem ON"
#define TR_BINDING_500MW_CH1_8_TELEM_OFF "500mW Ch1-8 Telem OFF"
#define TR_BINDING_500MW_CH9_16_TELEM_OFF "500mW Ch9-16 Telem OFF"
#define TR_PROTOCOL_INVALID TR("Prot. invalid", "Protocol invalid")
#define TR_MODULE_STATUS TR(INDENT "Status", INDENT "Module Status")
#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Module Sync")

View file

@ -881,17 +881,21 @@
#define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on powerup")
#define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodetect", INDENT "Autodetect format")
#define TR_MULTI_LOWPOWER TR(INDENT "Low power", INDENT "Low power mode")
#define TR_SPORT_OUT INDENT "Telemetrie"
#define TR_MODULE_TELEMETRY TR(INDENT "Mod telem.", INDENT "Module telemetrie"
#define TR_DISABLE_INTERNAL TR("Disable int. RF", "Disable internal RF")
#define TR_MODULE_NO_SERIAL_MODE TR("!serial mode", "Not in serial mode")
#define TR_MODULE_NO_INPUT TR("No input", "No serial input")
#define TR_MODULE_NO_TELEMETRY TR3( "No telmetry", "No MULTI_TELEMETRY", "No telemetry (enable MULTI_TELEMETRY)")
#define TR_MODULE_WAITFORBIND "Bind to load protocol"
#define TR_MODULE_BINDING "Binding"
#define TR_BINDING_MODE1 "Ch1-8 Telem ON"
#define TR_BINDING_MODE2 "Ch1-8 Telem OFF"
#define TR_BINDING_MODE3 "Ch9-16 Telem ON"
#define TR_BINDING_MODE4 "Ch9-16 Telem OFF"
#define TR_BINDING_CH1_8_TELEM_ON "Ch1-8 Telem ON"
#define TR_BINDING_CH1_8_TELEM_OFF "Ch1-8 Telem OFF"
#define TR_BINDING_CH9_16_TELEM_ON "Ch9-16 Telem ON"
#define TR_BINDING_CH9_16_TELEM_OFF "Ch9-16 Telem OFF"
#define TR_BINDING_25MW_CH1_8_TELEM_OFF "25mW Ch1-8 Telem OFF"
#define TR_BINDING_25MW_CH1_8_TELEM_ON "25mW Ch1-8 Telem ON"
#define TR_BINDING_500MW_CH1_8_TELEM_OFF "500mW Ch1-8 Telem OFF"
#define TR_BINDING_500MW_CH9_16_TELEM_OFF "500mW Ch9-16 Telem OFF"
#define TR_PROTOCOL_INVALID TR("Prot. invalid", "Protocol invalid")
#define TR_MODULE_STATUS TR(INDENT "Status", INDENT "Module Status")
#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Module Sync")

View file

@ -864,17 +864,21 @@
#define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on powerup")
#define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodetect", INDENT "Autodetect format")
#define TR_MULTI_LOWPOWER TR(INDENT "Low power", INDENT "Low power mode")
#define TR_SPORT_OUT INDENT "Telemetry"
#define TR_MODULE_TELEMETRY TR(INDENT "Mod telem.", INDENT "Module telemetry")
#define TR_DISABLE_INTERNAL TR("Disable int.", "Disable internal RF")
#define TR_MODULE_NO_SERIAL_MODE TR("!serial mode", "Not in serial mode")
#define TR_MODULE_NO_INPUT TR("No input", "No serial input")
#define TR_MODULE_NO_TELEMETRY TR3("No telemetry", "No MULTI_TELEMETRY", "No MULTI_TELEMETRY detected")
#define TR_MODULE_WAITFORBIND "Bind to load protocol"
#define TR_MODULE_BINDING TR("Bind...","Binding")
#define TR_BINDING_MODE1 "Ch1-8 Telem ON"
#define TR_BINDING_MODE2 "Ch1-8 Telem OFF"
#define TR_BINDING_MODE3 "Ch9-16 Telem ON"
#define TR_BINDING_MODE4 "Ch9-16 Telem OFF"
#define TR_BINDING_CH1_8_TELEM_ON "Ch1-8 Telem ON"
#define TR_BINDING_CH1_8_TELEM_OFF "Ch1-8 Telem OFF"
#define TR_BINDING_CH9_16_TELEM_ON "Ch9-16 Telem ON"
#define TR_BINDING_CH9_16_TELEM_OFF "Ch9-16 Telem OFF"
#define TR_BINDING_25MW_CH1_8_TELEM_OFF "25mW Ch1-8 Telem OFF"
#define TR_BINDING_25MW_CH1_8_TELEM_ON "25mW Ch1-8 Telem ON"
#define TR_BINDING_500MW_CH1_8_TELEM_OFF "500mW Ch1-8 Telem OFF"
#define TR_BINDING_500MW_CH9_16_TELEM_OFF "500mW Ch9-16 Telem OFF"
#define TR_PROTOCOL_INVALID TR("Prot. invalid", "Protocol invalid")
#define TR_MODULE_STATUS TR(INDENT "Status", INDENT "Module Status")
#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Module Sync")

View file

@ -840,17 +840,21 @@
#define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on powerup")
#define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodetect", INDENT "Autodetect format")
#define TR_MULTI_LOWPOWER TR(INDENT "Low power", INDENT "Low power mode")
#define TR_SPORT_OUT INDENT "Telemetry"
#define TR_MODULE_TELEMETRY TR(INDENT "Mod telem.", INDENT "Module telemetry")
#define TR_DISABLE_INTERNAL TR("Disable int. RF", "Disable internal RF")
#define TR_MODULE_NO_SERIAL_MODE TR("!serial mode", "Not in serial mode")
#define TR_MODULE_NO_INPUT TR("No input", "No serial input")
#define TR_MODULE_NO_TELEMETRY TR3( "No telmetry", "No MULTI_TELEMETRY", "No telemetry (enable MULTI_TELEMETRY)")
#define TR_MODULE_WAITFORBIND "Bind to load protocol"
#define TR_MODULE_BINDING "Binding"
#define TR_BINDING_MODE1 "Ch1-8 Telem ON"
#define TR_BINDING_MODE2 "Ch1-8 Telem OFF"
#define TR_BINDING_MODE3 "Ch9-16 Telem ON"
#define TR_BINDING_MODE4 "Ch9-16 Telem OFF"
#define TR_BINDING_CH1_8_TELEM_ON "Ch1-8 Telem ON"
#define TR_BINDING_CH1_8_TELEM_OFF "Ch1-8 Telem OFF"
#define TR_BINDING_CH9_16_TELEM_ON "Ch9-16 Telem ON"
#define TR_BINDING_CH9_16_TELEM_OFF "Ch9-16 Telem OFF"
#define TR_BINDING_25MW_CH1_8_TELEM_OFF "25mW Ch1-8 Telem OFF"
#define TR_BINDING_25MW_CH1_8_TELEM_ON "25mW Ch1-8 Telem ON"
#define TR_BINDING_500MW_CH1_8_TELEM_OFF "500mW Ch1-8 Telem OFF"
#define TR_BINDING_500MW_CH9_16_TELEM_OFF "500mW Ch9-16 Telem OFF"
#define TR_PROTOCOL_INVALID TR("Prot. invalid", "Protocol invalid")
#define TR_MODULE_STATUS TR(INDENT "Status", INDENT "Module Status")
#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Module Sync")

View file

@ -836,17 +836,21 @@
#define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on powerup")
#define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodetect", INDENT "Autodetect format")
#define TR_MULTI_LOWPOWER TR(INDENT "Low power", INDENT "Low power mode")
#define TR_SPORT_OUT INDENT "Telemetry"
#define TR_MODULE_TELEMETRY TR(INDENT "Mod telem.", INDENT "Module telemetry")
#define TR_DISABLE_INTERNAL TR("Disable int. RF", "Disable internal RF")
#define TR_MODULE_NO_SERIAL_MODE TR("!serial mode", "Not in serial mode")
#define TR_MODULE_NO_INPUT TR("No input", "No serial input")
#define TR_MODULE_NO_TELEMETRY TR3( "No telmetry", "No MULTI_TELEMETRY", "No telemetry (enable MULTI_TELEMETRY)")
#define TR_MODULE_WAITFORBIND "Bind to load protocol"
#define TR_MODULE_BINDING "Binding"
#define TR_BINDING_MODE1 "Ch1-8 Telem ON"
#define TR_BINDING_MODE2 "Ch1-8 Telem OFF"
#define TR_BINDING_MODE3 "Ch9-16 Telem ON"
#define TR_BINDING_MODE4 "Ch9-16 Telem OFF"
#define TR_BINDING_CH1_8_TELEM_ON "Ch1-8 Telem ON"
#define TR_BINDING_CH1_8_TELEM_OFF "Ch1-8 Telem OFF"
#define TR_BINDING_CH9_16_TELEM_ON "Ch9-16 Telem ON"
#define TR_BINDING_CH9_16_TELEM_OFF "Ch9-16 Telem OFF"
#define TR_BINDING_25MW_CH1_8_TELEM_OFF "25mW Ch1-8 Telem OFF"
#define TR_BINDING_25MW_CH1_8_TELEM_ON "25mW Ch1-8 Telem ON"
#define TR_BINDING_500MW_CH1_8_TELEM_OFF "500mW Ch1-8 Telem OFF"
#define TR_BINDING_500MW_CH9_16_TELEM_OFF "500mW Ch9-16 Telem OFF"
#define TR_PROTOCOL_INVALID TR("Prot. invalid", "Protocol invalid")
#define TR_MODULE_STATUS TR(INDENT "Status", INDENT "Module Status")
#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Module Sync")

View file

@ -863,17 +863,21 @@
#define TR_MULTI_AUTOBIND TR(INDENT "Bind auto", INDENT "Bind automatique")
#define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodét.", INDENT "Autodétection")
#define TR_MULTI_LOWPOWER TR(INDENT "Basse puis.", INDENT "Mode basse puiss.")
#define TR_SPORT_OUT INDENT "Telemetry"
#define TR_MODULE_TELEMETRY TR(INDENT "Télem. mod.", INDENT "Télémétrie module")
#define TR_DISABLE_INTERNAL TR("Désact intRF", "Désact. RF interne")
#define TR_MODULE_NO_SERIAL_MODE TR("Mode série?", "Pas en mode série")
#define TR_MODULE_NO_INPUT TR("Pas de sign.", "Aucun signal série")
#define TR_MODULE_NO_TELEMETRY TR3("Pas de télm.", "Télémétrie absente", "Télémétrie absente(act. MULTI_TELEMETRY)")
#define TR_MODULE_WAITFORBIND "Bind to load protocol"
#define TR_MODULE_BINDING "Bind..."
#define TR_BINDING_MODE1 "Ch1-8 Telem ON"
#define TR_BINDING_MODE2 "Ch1-8 Telem OFF"
#define TR_BINDING_MODE3 "Ch9-16 Telem ON"
#define TR_BINDING_MODE4 "Ch9-16 Telem OFF"
#define TR_BINDING_CH1_8_TELEM_ON "Ch1-8 Télem ON"
#define TR_BINDING_CH1_8_TELEM_OFF "Ch1-8 Télem OFF"
#define TR_BINDING_CH9_16_TELEM_ON "Ch9-16 Télem ON"
#define TR_BINDING_CH9_16_TELEM_OFF "Ch9-16 Télem OFF"
#define TR_BINDING_25MW_CH1_8_TELEM_OFF "25mW Ch1-8 Télem OFF"
#define TR_BINDING_25MW_CH1_8_TELEM_ON "25mW Ch1-8 Télem ON"
#define TR_BINDING_500MW_CH1_8_TELEM_OFF "500mW Ch1-8 Télem OFF"
#define TR_BINDING_500MW_CH9_16_TELEM_OFF "500mW Ch9-16 Télem OFF"
#define TR_PROTOCOL_INVALID TR("Sél. invalide", "Protocole invalide")
#define TR_MODULE_STATUS TR(INDENT "Etat", INDENT "Etat module")
#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Module Sync")

View file

@ -865,17 +865,21 @@
#define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on powerup")
#define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodetect", INDENT "Autodetect format")
#define TR_MULTI_LOWPOWER TR(INDENT "Low power", INDENT "Low power mode")
#define TR_SPORT_OUT INDENT "Telemetry"
#define TR_MODULE_TELEMETRY TR(INDENT "Mod telem.", INDENT "Module telemetry")
#define TR_DISABLE_INTERNAL TR("Disable int. RF", "Disable internal RF")
#define TR_MODULE_NO_SERIAL_MODE TR("!serial mode", "Not in serial mode")
#define TR_MODULE_NO_INPUT TR("No input", "No serial input")
#define TR_MODULE_NO_TELEMETRY TR3( "No telmetry", "No MULTI_TELEMETRY", "No telemetry (enable MULTI_TELEMETRY)")
#define TR_MODULE_WAITFORBIND "Bind to load protocol"
#define TR_MODULE_BINDING "Binding"
#define TR_BINDING_MODE1 "Ch1-8 Telem ON"
#define TR_BINDING_MODE2 "Ch1-8 Telem OFF"
#define TR_BINDING_MODE3 "Ch9-16 Telem ON"
#define TR_BINDING_MODE4 "Ch9-16 Telem OFF"
#define TR_BINDING_CH1_8_TELEM_ON "Ch1-8 Telem ON"
#define TR_BINDING_CH1_8_TELEM_OFF "Ch1-8 Telem OFF"
#define TR_BINDING_CH9_16_TELEM_ON "Ch9-16 Telem ON"
#define TR_BINDING_CH9_16_TELEM_OFF "Ch9-16 Telem OFF"
#define TR_BINDING_25MW_CH1_8_TELEM_OFF "25mW Ch1-8 Telem OFF"
#define TR_BINDING_25MW_CH1_8_TELEM_ON "25mW Ch1-8 Telem ON"
#define TR_BINDING_500MW_CH1_8_TELEM_OFF "500mW Ch1-8 Telem OFF"
#define TR_BINDING_500MW_CH9_16_TELEM_OFF "500mW Ch9-16 Telem OFF"
#define TR_PROTOCOL_INVALID TR("Prot. invalid", "Protocol invalid")
#define TR_MODULE_STATUS TR(INDENT "Status", INDENT "Module Status")
#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Module Sync")

View file

@ -863,17 +863,21 @@
#define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on powerup")
#define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodetect", INDENT "Autodetect format")
#define TR_MULTI_LOWPOWER TR(INDENT "Low power", INDENT "Low power mode")
#define TR_SPORT_OUT INDENT "Telemetry"
#define TR_MODULE_TELEMETRY TR(INDENT "Mod telem.", INDENT "Module telemetry")
#define TR_DISABLE_INTERNAL TR("Disable int. RF", "Disable internal RF")
#define TR_MODULE_NO_SERIAL_MODE TR("!serial mode", "Not in serial mode")
#define TR_MODULE_NO_INPUT TR("No input", "No serial input")
#define TR_MODULE_NO_TELEMETRY TR3( "No telmetry", "No MULTI_TELEMETRY", "No telemetry (enable MULTI_TELEMETRY)")
#define TR_MODULE_WAITFORBIND "Bind to load protocol"
#define TR_MODULE_BINDING "Binding"
#define TR_BINDING_MODE1 "Ch1-8 Telem ON"
#define TR_BINDING_MODE2 "Ch1-8 Telem OFF"
#define TR_BINDING_MODE3 "Ch9-16 Telem ON"
#define TR_BINDING_MODE4 "Ch9-16 Telem OFF"
#define TR_BINDING_CH1_8_TELEM_ON "Ch1-8 Telem ON"
#define TR_BINDING_CH1_8_TELEM_OFF "Ch1-8 Telem OFF"
#define TR_BINDING_CH9_16_TELEM_ON "Ch9-16 Telem ON"
#define TR_BINDING_CH9_16_TELEM_OFF "Ch9-16 Telem OFF"
#define TR_BINDING_25MW_CH1_8_TELEM_OFF "25mW Ch1-8 Telem OFF"
#define TR_BINDING_25MW_CH1_8_TELEM_ON "25mW Ch1-8 Telem ON"
#define TR_BINDING_500MW_CH1_8_TELEM_OFF "500mW Ch1-8 Telem OFF"
#define TR_BINDING_500MW_CH9_16_TELEM_OFF "500mW Ch9-16 Telem OFF"
#define TR_PROTOCOL_INVALID TR("Prot. invalid", "Protocol invalid")
#define TR_MODULE_STATUS TR(INDENT "Status", INDENT "Module Status")
#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Module Sync")

View file

@ -867,17 +867,21 @@
#define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on powerup")
#define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodetect", INDENT "Autodetect format")
#define TR_MULTI_LOWPOWER TR(INDENT "Low power", INDENT "Low power mode")
#define TR_SPORT_OUT INDENT "Telemetry"
#define TR_MODULE_TELEMETRY TR(INDENT "Mod telem.", INDENT "Module telemetry")
#define TR_DISABLE_INTERNAL TR("Disable int. RF", "Disable internal RF")
#define TR_MODULE_NO_SERIAL_MODE TR("!serial mode", "Not in serial mode")
#define TR_MODULE_NO_INPUT TR("No input", "No serial input")
#define TR_MODULE_NO_TELEMETRY TR3( "No telmetry", "No MULTI_TELEMETRY", "No telemetry (enable MULTI_TELEMETRY)")
#define TR_MODULE_WAITFORBIND "Bind to load protocol"
#define TR_MODULE_BINDING "Binding"
#define TR_BINDING_MODE1 "Ch1-8 Telem ON"
#define TR_BINDING_MODE2 "Ch1-8 Telem OFF"
#define TR_BINDING_MODE3 "Ch9-16 Telem ON"
#define TR_BINDING_MODE4 "Ch9-16 Telem OFF"
#define TR_BINDING_CH1_8_TELEM_ON "Ch1-8 Telem ON"
#define TR_BINDING_CH1_8_TELEM_OFF "Ch1-8 Telem OFF"
#define TR_BINDING_CH9_16_TELEM_ON "Ch9-16 Telem ON"
#define TR_BINDING_CH9_16_TELEM_OFF "Ch9-16 Telem OFF"
#define TR_BINDING_25MW_CH1_8_TELEM_OFF "25mW Ch1-8 Telem OFF"
#define TR_BINDING_25MW_CH1_8_TELEM_ON "25mW Ch1-8 Telem ON"
#define TR_BINDING_500MW_CH1_8_TELEM_OFF "500mW Ch1-8 Telem OFF"
#define TR_BINDING_500MW_CH9_16_TELEM_OFF "500mW Ch9-16 Telem OFF"
#define TR_PROTOCOL_INVALID TR("Prot. invalid", "Protocol invalid")
#define TR_MODULE_STATUS TR(INDENT "Status", INDENT "Module Status")
#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Module Sync")

View file

@ -842,17 +842,21 @@
#define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on powerup")
#define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodetect", INDENT "Autodetect format")
#define TR_MULTI_LOWPOWER TR(INDENT "Low power", INDENT "Low power mode")
#define TR_SPORT_OUT INDENT "Telemetry"
#define TR_MODULE_TELEMETRY TR(INDENT "Mod telem.", INDENT "Module telemetry")
#define TR_DISABLE_INTERNAL TR("Disable int. RF", "Disable internal RF")
#define TR_MODULE_NO_SERIAL_MODE TR("!serial mode", "Not in serial mode")
#define TR_MODULE_NO_INPUT TR("No input", "No serial input")
#define TR_MODULE_NO_TELEMETRY TR3( "No telmetry", "No MULTI_TELEMETRY", "No telemetry (enable MULTI_TELEMETRY)")
#define TR_MODULE_WAITFORBIND "Bind to load protocol"
#define TR_MODULE_BINDING "Binding"
#define TR_BINDING_MODE1 "Ch1-8 Telem ON"
#define TR_BINDING_MODE2 "Ch1-8 Telem OFF"
#define TR_BINDING_MODE3 "Ch9-16 Telem ON"
#define TR_BINDING_MODE4 "Ch9-16 Telem OFF"
#define TR_BINDING_CH1_8_TELEM_ON "Ch1-8 Telem ON"
#define TR_BINDING_CH1_8_TELEM_OFF "Ch1-8 Telem OFF"
#define TR_BINDING_CH9_16_TELEM_ON "Ch9-16 Telem ON"
#define TR_BINDING_CH9_16_TELEM_OFF "Ch9-16 Telem OFF"
#define TR_BINDING_25MW_CH1_8_TELEM_OFF "25mW Ch1-8 Telem OFF"
#define TR_BINDING_25MW_CH1_8_TELEM_ON "25mW Ch1-8 Telem ON"
#define TR_BINDING_500MW_CH1_8_TELEM_OFF "500mW Ch1-8 Telem OFF"
#define TR_BINDING_500MW_CH9_16_TELEM_OFF "500mW Ch9-16 Telem OFF"
#define TR_PROTOCOL_INVALID TR("Prot. invalid", "Protocol invalid")
#define TR_MODULE_STATUS TR(INDENT "Status", INDENT "Module Status")
#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Module Sync")

View file

@ -879,17 +879,21 @@
#define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on powerup")
#define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodetect", INDENT "Autodetect format")
#define TR_MULTI_LOWPOWER TR(INDENT "Low power", INDENT "Low power mode")
#define TR_SPORT_OUT INDENT "Telemetry"
#define TR_MODULE_TELEMETRY TR(INDENT "Mod telem.", INDENT "Module telemetry")
#define TR_DISABLE_INTERNAL TR("Disable int. RF", "Disable internal RF")
#define TR_MODULE_NO_SERIAL_MODE TR("!serial mode", "Not in serial mode")
#define TR_MODULE_NO_INPUT TR("No input", "No serial input")
#define TR_MODULE_NO_TELEMETRY TR3( "No telmetry", "No MULTI_TELEMETRY", "No telemetry (enable MULTI_TELEMETRY)")
#define TR_MODULE_WAITFORBIND "Bind to load protocol"
#define TR_MODULE_BINDING "Binding"
#define TR_BINDING_MODE1 "Ch1-8 Telem ON"
#define TR_BINDING_MODE2 "Ch1-8 Telem OFF"
#define TR_BINDING_MODE3 "Ch9-16 Telem ON"
#define TR_BINDING_MODE4 "Ch9-16 Telem OFF"
#define TR_BINDING_CH1_8_TELEM_ON "Ch1-8 Telem ON"
#define TR_BINDING_CH1_8_TELEM_OFF "Ch1-8 Telem OFF"
#define TR_BINDING_CH9_16_TELEM_ON "Ch9-16 Telem ON"
#define TR_BINDING_CH9_16_TELEM_OFF "Ch9-16 Telem OFF"
#define TR_BINDING_25MW_CH1_8_TELEM_OFF "25mW Ch1-8 Telem OFF"
#define TR_BINDING_25MW_CH1_8_TELEM_ON "25mW Ch1-8 Telem ON"
#define TR_BINDING_500MW_CH1_8_TELEM_OFF "500mW Ch1-8 Telem OFF"
#define TR_BINDING_500MW_CH9_16_TELEM_OFF "500mW Ch9-16 Telem OFF"
#define TR_PROTOCOL_INVALID TR("Prot. invalid", "Protocol invalid")
#define TR_MODULE_STATUS TR(INDENT "Status", INDENT "Module Status")
#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Module Sync")