Support new Multi 1.3 features (#7077)
This commit is contained in:
@@ -86,7 +86,7 @@ QString ModuleData::rfProtocolToString() const
|
||||
{
|
||||
switch (protocol) {
|
||||
case PULSES_MULTIMODULE:
|
||||
return Multiprotocols::protocolToString((int)multi.rfProtocol, multi.customProto);
|
||||
return Multiprotocols::protocolToString((int)multi.rfProtocol);
|
||||
|
||||
default:
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
@@ -107,7 +107,7 @@ QString ModuleData::subTypeToString(int type) const
|
||||
|
||||
switch (protocol) {
|
||||
case PULSES_MULTIMODULE:
|
||||
return Multiprotocols::subTypeToString(multi.customProto ? MM_RF_CUSTOM_SELECTED : (int)multi.rfProtocol, (unsigned)type);
|
||||
return Multiprotocols::subTypeToString((int)multi.rfProtocol, (unsigned)type);
|
||||
|
||||
case PULSES_PXX_R9M:
|
||||
return CHECK_IN_ARRAY(strings, type);
|
||||
|
||||
@@ -164,9 +164,10 @@ class ModuleData {
|
||||
|
||||
struct Multi {
|
||||
unsigned int rfProtocol;
|
||||
bool disableTelemetry;
|
||||
bool disableMapping;
|
||||
bool autoBindMode;
|
||||
bool lowPowerMode;
|
||||
bool customProto;
|
||||
int optionValue;
|
||||
} multi;
|
||||
|
||||
|
||||
@@ -172,5 +172,8 @@ QString Multiprotocols::protocolToString(int protocol, bool custom)
|
||||
// static
|
||||
QString Multiprotocols::subTypeToString(int protocol, unsigned subType)
|
||||
{
|
||||
return tr(qPrintable(multiProtocols.getProtocol(protocol).subTypeStrings.value(subType, CPN_STR_UNKNOWN_ITEM)));
|
||||
if (protocol > MODULE_SUBTYPE_MULTI_LAST)
|
||||
return tr(qPrintable(QString::number(subType)));
|
||||
else
|
||||
return tr(qPrintable(multiProtocols.getProtocol(protocol).subTypeStrings.value(subType, CPN_STR_UNKNOWN_ITEM)));
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include <vector>
|
||||
#include <QtCore>
|
||||
#include "moduledata.h"
|
||||
|
||||
#define MM_RF_CUSTOM_SELECTED 0xff
|
||||
|
||||
@@ -48,7 +49,7 @@ class Multiprotocols
|
||||
|
||||
unsigned int numSubTypes() const
|
||||
{
|
||||
return (unsigned int) subTypeStrings.length();
|
||||
return protocol > MODULE_SUBTYPE_MULTI_LAST ? 8 : (unsigned int) subTypeStrings.length();
|
||||
}
|
||||
|
||||
int getOptionMin() const;
|
||||
|
||||
@@ -2037,9 +2037,10 @@ class ModuleUnionField: public UnionField<unsigned int> {
|
||||
rfProtExtra(0)
|
||||
{
|
||||
ModuleData::Multi& multi = module.multi;
|
||||
internalField.Append(new UnsignedField<2>(this, rfProtExtra));
|
||||
internalField.Append(new SpareBitsField<3>(this));
|
||||
internalField.Append(new BoolField<1>(this, multi.customProto));
|
||||
internalField.Append(new UnsignedField<3>(this, rfProtExtra));
|
||||
internalField.Append(new BoolField<1>(this, multi.disableTelemetry));
|
||||
internalField.Append(new BoolField<1>(this, multi.disableMapping));
|
||||
internalField.Append(new SpareBitsField<1>(this));
|
||||
internalField.Append(new BoolField<1>(this, multi.autoBindMode));
|
||||
internalField.Append(new BoolField<1>(this, multi.lowPowerMode));
|
||||
internalField.Append(new SignedField<8>(this, multi.optionValue));
|
||||
@@ -2052,12 +2053,17 @@ class ModuleUnionField: public UnionField<unsigned int> {
|
||||
|
||||
void beforeExport() override
|
||||
{
|
||||
rfProtExtra = (module.multi.rfProtocol >> 4) & 0x03;
|
||||
if (module.multi.rfProtocol > MODULE_SUBTYPE_MULTI_LAST)
|
||||
module.multi.rfProtocol += 3;
|
||||
rfProtExtra = (module.multi.rfProtocol & 0x70) >> 4;
|
||||
module.multi.rfProtocol &= 0x0f;
|
||||
}
|
||||
|
||||
void afterImport() override
|
||||
{
|
||||
module.multi.rfProtocol = (rfProtExtra & 0x3) << 4 | (module.rfProtocol & 0xf);
|
||||
module.multi.rfProtocol = (rfProtExtra << 4) + (module.rfProtocol & 0xf);
|
||||
if (module.multi.rfProtocol > MODULE_SUBTYPE_MULTI_LAST)
|
||||
module.multi.rfProtocol -= 3;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -227,6 +227,9 @@ ModulePanel::ModulePanel(QWidget * parent, ModelData & model, ModuleData & modul
|
||||
continue;
|
||||
ui->multiProtocol->addItem(Multiprotocols::protocolToString(i), i);
|
||||
}
|
||||
for (int i=MODULE_SUBTYPE_MULTI_LAST + 1; i <= 124; i++) {
|
||||
ui->multiProtocol->addItem(QString::number(i + 3), i);
|
||||
}
|
||||
|
||||
ui->btnGrpValueType->setId(ui->optPercent, FAILSAFE_DISPLAY_PERCENT);
|
||||
ui->btnGrpValueType->setId(ui->optUs, FAILSAFE_DISPLAY_USEC);
|
||||
@@ -469,14 +472,14 @@ void ModulePanel::update()
|
||||
break;
|
||||
case PULSES_MULTIMODULE:
|
||||
mask |= MASK_CHANNELS_RANGE | MASK_RX_NUMBER | MASK_MULTIMODULE | MASK_SUBTYPES;
|
||||
max_rx_num = 15;
|
||||
max_rx_num = 63;
|
||||
if (module.multi.rfProtocol == MODULE_SUBTYPE_MULTI_DSM2)
|
||||
mask |= MASK_CHANNELS_COUNT;
|
||||
else
|
||||
module.channelsCount = 16;
|
||||
if (pdef.optionsstr != nullptr)
|
||||
mask |= MASK_MULTIOPTION;
|
||||
if (pdef.hasFailsafe)
|
||||
if (pdef.hasFailsafe || (module.multi.rfProtocol == MODULE_SUBTYPE_MULTI_FRSKY && (module.subType == 0 || module.subType == 2 || module.subType > 3 )))
|
||||
mask |= MASK_FAILSAFES;
|
||||
break;
|
||||
case PULSES_OFF:
|
||||
@@ -565,7 +568,7 @@ void ModulePanel::update()
|
||||
unsigned i = 0;
|
||||
switch(protocol){
|
||||
case PULSES_MULTIMODULE:
|
||||
numEntries = (module.multi.customProto ? 8 : pdef.numSubTypes());
|
||||
numEntries = (module.multi.rfProtocol > MODULE_SUBTYPE_MULTI_LAST ? 8 : pdef.numSubTypes());
|
||||
break;
|
||||
case PULSES_PXX_R9M:
|
||||
if (firmware->getCapability(HasModuleR9MFlex))
|
||||
@@ -587,11 +590,15 @@ void ModulePanel::update()
|
||||
ui->multiProtocol->setVisible(mask & MASK_MULTIMODULE);
|
||||
ui->label_option->setVisible(mask & MASK_MULTIOPTION);
|
||||
ui->optionValue->setVisible(mask & MASK_MULTIOPTION);
|
||||
ui->disableTelem->setVisible(mask & MASK_MULTIMODULE);
|
||||
ui->disableChMap->setVisible(mask & MASK_MULTIMODULE);
|
||||
ui->autoBind->setVisible(mask & MASK_MULTIMODULE);
|
||||
ui->lowPower->setVisible(mask & MASK_MULTIMODULE);
|
||||
|
||||
if (mask & MASK_MULTIMODULE) {
|
||||
ui->multiProtocol->setCurrentIndex(ui->multiProtocol->findData(module.multi.rfProtocol));
|
||||
ui->disableTelem->setChecked(module.multi.disableTelemetry);
|
||||
ui->disableChMap->setChecked(module.multi.disableMapping);
|
||||
ui->autoBind->setChecked(module.multi.autoBindMode);
|
||||
ui->lowPower->setChecked(module.multi.lowPowerMode);
|
||||
}
|
||||
@@ -763,7 +770,7 @@ void ModulePanel::onMultiProtocolChanged(int index)
|
||||
lock=true;
|
||||
module.multi.rfProtocol = (unsigned int)rfProtocol;
|
||||
unsigned int maxSubTypes = multiProtocols.getProtocol(index).numSubTypes();
|
||||
if (module.multi.customProto)
|
||||
if (rfProtocol > MODULE_SUBTYPE_MULTI_LAST)
|
||||
maxSubTypes=8;
|
||||
module.subType = std::min(module.subType, maxSubTypes -1);
|
||||
module.channelsCount = getMaxChannelCount();
|
||||
@@ -793,10 +800,21 @@ void ModulePanel::onSubTypeChanged()
|
||||
}
|
||||
}
|
||||
|
||||
void ModulePanel::on_disableTelem_stateChanged(int state)
|
||||
{
|
||||
module.multi.disableTelemetry = (state == Qt::Checked);
|
||||
}
|
||||
|
||||
void ModulePanel::on_disableChMap_stateChanged(int state)
|
||||
{
|
||||
module.multi.disableMapping = (state == Qt::Checked);
|
||||
}
|
||||
|
||||
void ModulePanel::on_autoBind_stateChanged(int state)
|
||||
{
|
||||
module.multi.autoBindMode = (state == Qt::Checked);
|
||||
}
|
||||
|
||||
void ModulePanel::on_lowPower_stateChanged(int state)
|
||||
{
|
||||
module.multi.lowPowerMode = (state == Qt::Checked);
|
||||
|
||||
@@ -86,6 +86,8 @@ class ModulePanel : public ModelPanel
|
||||
void onMultiProtocolChanged(int index);
|
||||
void onSubTypeChanged();
|
||||
void on_autoBind_stateChanged(int state);
|
||||
void on_disableChMap_stateChanged(int state);
|
||||
void on_disableTelem_stateChanged(int state);
|
||||
void on_lowPower_stateChanged(int state);
|
||||
void on_r9mPower_currentIndexChanged(int index);
|
||||
void setChannelFailsafeValue(const int channel, const int value, quint8 updtSb = 0);
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1075</width>
|
||||
<height>434</height>
|
||||
<height>438</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -937,7 +937,7 @@
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0" colspan="2">
|
||||
<item row="11" column="0" colspan="2">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
@@ -950,6 +950,20 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QCheckBox" name="disableTelem">
|
||||
<property name="text">
|
||||
<string>Disable Telemetry</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<widget class="QCheckBox" name="disableChMap">
|
||||
<property name="text">
|
||||
<string>Disable Ch. Map</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="3">
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
---- #########################################################################
|
||||
---- # #
|
||||
---- # Copyright (C) OpenTX #
|
||||
-----# #
|
||||
---- # 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. #
|
||||
---- # #
|
||||
---- #########################################################################
|
||||
|
||||
|
||||
--###############################################################################
|
||||
-- Multi buffer for HoTT description
|
||||
-- To start operation:
|
||||
-- Write "HoTT" at address 0..3
|
||||
-- Write 0xFF at address 4 will request the buffer to be cleared
|
||||
-- Write 0xDF at address 5
|
||||
-- Read buffer from address 6 access the RX text for 168 bytes, 21 caracters
|
||||
-- by 8 lines
|
||||
-- Write at address 5 sends an order to the RX: 0xDF=start, 0xD7=prev page,
|
||||
-- 0xDE=next page, 0xD9=enter, 0xDD=next or 0xDB=prev
|
||||
-- Write at address 4 the value 0xFF will request the buffer to be cleared
|
||||
-- !! Before exiting the script must write 0 at address 0 for normal operation !!
|
||||
--###############################################################################
|
||||
|
||||
local function HoTT_Release()
|
||||
multiBuffer( 0, 0 )
|
||||
end
|
||||
|
||||
local function HoTT_Draw_LCD()
|
||||
local i
|
||||
local value
|
||||
local line
|
||||
local result
|
||||
local offset=0
|
||||
|
||||
lcd.clear()
|
||||
|
||||
if LCD_W == 480 then
|
||||
--Draw title
|
||||
lcd.drawFilledRectangle(0, 0, LCD_W, 30, TITLE_BGCOLOR)
|
||||
lcd.drawText(1, 5, "Graupner HoTT RX configuration", MENU_TITLE_COLOR)
|
||||
--Draw RX Menu
|
||||
if multiBuffer( 4 ) == 0xFF then
|
||||
lcd.drawText(10,50,"No HoTT telemetry...", BLINK)
|
||||
else
|
||||
for line = 0, 7, 1 do
|
||||
for i = 0, 21-1, 1 do
|
||||
value=multiBuffer( line*21+6+i )
|
||||
if value > 0x80 then
|
||||
value = value - 0x80
|
||||
lcd.drawText(10+i*16,32+16*line,string.char(value).." ",INVERS)
|
||||
else
|
||||
lcd.drawText(10+i*16,32+16*line,string.char(value))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
--Draw RX Menu on LCD_W=128
|
||||
if multiBuffer( 4 ) == 0xFF then
|
||||
lcd.drawText(2,17,"No HoTT telemetry...",SMLSIZE)
|
||||
else
|
||||
for line = 0, 7, 1 do
|
||||
for i = 0, 21-1, 1 do
|
||||
value=multiBuffer( line*21+6+i )
|
||||
if value > 0x80 then
|
||||
value = value - 0x80
|
||||
lcd.drawText(2+i*6,1+8*line,string.char(value).." ",SMLSIZE+INVERS)
|
||||
else
|
||||
lcd.drawText(2+i*6,1+8*line,string.char(value),SMLSIZE)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Init
|
||||
local function HoTT_Init()
|
||||
--Set protocol to talk to
|
||||
multiBuffer( 0, string.byte('H') )
|
||||
--test if value has been written
|
||||
if multiBuffer( 0 ) ~= string.byte('H') then
|
||||
error("Not enough memory!")
|
||||
return 2
|
||||
end
|
||||
multiBuffer( 1, string.byte('o') )
|
||||
multiBuffer( 2, string.byte('T') )
|
||||
multiBuffer( 3, string.byte('T') )
|
||||
--Request init of the RX buffer
|
||||
multiBuffer( 4, 0xFF )
|
||||
--Request RX to send the config menu
|
||||
multiBuffer( 5, 0xDF )
|
||||
end
|
||||
|
||||
-- Main
|
||||
local function HoTT_Run(event)
|
||||
if event == nil then
|
||||
error("Cannot be run as a model script!")
|
||||
return 2
|
||||
elseif event == EVT_VIRTUAL_EXIT then
|
||||
HoTT_Release()
|
||||
return 2
|
||||
else
|
||||
if event == EVT_VIRTUAL_PREV_PAGE then
|
||||
killEvents(event);
|
||||
multiBuffer( 5, 0xD7 )
|
||||
elseif event == EVT_VIRTUAL_NEXT_PAGE then
|
||||
multiBuffer( 5, 0xDE )
|
||||
elseif event == EVT_VIRTUAL_ENTER then
|
||||
multiBuffer( 5, 0xD9 )
|
||||
elseif event == EVT_VIRTUAL_NEXT then
|
||||
multiBuffer( 5, 0xDD )
|
||||
elseif event == EVT_VIRTUAL_PREV then
|
||||
multiBuffer( 5, 0xDB )
|
||||
else
|
||||
multiBuffer( 5, 0xDF )
|
||||
end
|
||||
HoTT_Draw_LCD()
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
return { init=HoTT_Init, run=HoTT_Run }
|
||||
@@ -0,0 +1,132 @@
|
||||
---- #########################################################################
|
||||
---- # #
|
||||
---- # Copyright (C) OpenTX #
|
||||
-----# #
|
||||
---- # 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. #
|
||||
---- # #
|
||||
---- #########################################################################
|
||||
|
||||
|
||||
--###############################################################################
|
||||
-- Multi buffer for HoTT description
|
||||
-- To start operation:
|
||||
-- Write "HoTT" at address 0..3
|
||||
-- Write 0xFF at address 4 will request the buffer to be cleared
|
||||
-- Write 0xDF at address 5
|
||||
-- Read buffer from address 6 access the RX text for 168 bytes, 21 caracters
|
||||
-- by 8 lines
|
||||
-- Write at address 5 sends an order to the RX: 0xDF=start, 0xD7=prev page,
|
||||
-- 0xDE=next page, 0xD9=enter, 0xDD=next or 0xDB=prev
|
||||
-- Write at address 4 the value 0xFF will request the buffer to be cleared
|
||||
-- !! Before exiting the script must write 0 at address 0 for normal operation !!
|
||||
--###############################################################################
|
||||
|
||||
local function HoTT_Release()
|
||||
multiBuffer( 0, 0 )
|
||||
end
|
||||
|
||||
local function HoTT_Draw_LCD()
|
||||
local i
|
||||
local value
|
||||
local line
|
||||
local result
|
||||
local offset=0
|
||||
|
||||
lcd.clear()
|
||||
|
||||
if LCD_W == 480 then
|
||||
--Draw title
|
||||
lcd.drawFilledRectangle(0, 0, LCD_W, 30, TITLE_BGCOLOR)
|
||||
lcd.drawText(1, 5, "Graupner HoTT RX configuration", MENU_TITLE_COLOR)
|
||||
--Draw RX Menu
|
||||
if multiBuffer( 4 ) == 0xFF then
|
||||
lcd.drawText(10,50,"No HoTT telemetry...", BLINK)
|
||||
else
|
||||
for line = 0, 7, 1 do
|
||||
for i = 0, 21-1, 1 do
|
||||
value=multiBuffer( line*21+6+i )
|
||||
if value > 0x80 then
|
||||
value = value - 0x80
|
||||
lcd.drawText(10+i*16,32+16*line,string.char(value).." ",INVERS)
|
||||
else
|
||||
lcd.drawText(10+i*16,32+16*line,string.char(value))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
--Draw RX Menu on LCD_W=128
|
||||
if multiBuffer( 4 ) == 0xFF then
|
||||
lcd.drawText(2,17,"No HoTT telemetry...",SMLSIZE)
|
||||
else
|
||||
for line = 0, 7, 1 do
|
||||
for i = 0, 21-1, 1 do
|
||||
value=multiBuffer( line*21+6+i )
|
||||
if value > 0x80 then
|
||||
value = value - 0x80
|
||||
lcd.drawText(2+i*6,1+8*line,string.char(value).." ",SMLSIZE+INVERS)
|
||||
else
|
||||
lcd.drawText(2+i*6,1+8*line,string.char(value),SMLSIZE)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Init
|
||||
local function HoTT_Init()
|
||||
--Set protocol to talk to
|
||||
multiBuffer( 0, string.byte('H') )
|
||||
--test if value has been written
|
||||
if multiBuffer( 0 ) ~= string.byte('H') then
|
||||
error("Not enough memory!")
|
||||
return 2
|
||||
end
|
||||
multiBuffer( 1, string.byte('o') )
|
||||
multiBuffer( 2, string.byte('T') )
|
||||
multiBuffer( 3, string.byte('T') )
|
||||
--Request init of the RX buffer
|
||||
multiBuffer( 4, 0xFF )
|
||||
--Request RX to send the config menu
|
||||
multiBuffer( 5, 0xDF )
|
||||
end
|
||||
|
||||
-- Main
|
||||
local function HoTT_Run(event)
|
||||
if event == nil then
|
||||
error("Cannot be run as a model script!")
|
||||
return 2
|
||||
elseif event == EVT_VIRTUAL_EXIT then
|
||||
HoTT_Release()
|
||||
return 2
|
||||
else
|
||||
if event == EVT_VIRTUAL_PREV_PAGE then
|
||||
killEvents(event);
|
||||
multiBuffer( 5, 0xD7 )
|
||||
elseif event == EVT_VIRTUAL_NEXT_PAGE then
|
||||
multiBuffer( 5, 0xDE )
|
||||
elseif event == EVT_VIRTUAL_ENTER then
|
||||
multiBuffer( 5, 0xD9 )
|
||||
elseif event == EVT_VIRTUAL_NEXT then
|
||||
multiBuffer( 5, 0xDD )
|
||||
elseif event == EVT_VIRTUAL_PREV then
|
||||
multiBuffer( 5, 0xDB )
|
||||
else
|
||||
multiBuffer( 5, 0xDF )
|
||||
end
|
||||
HoTT_Draw_LCD()
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
return { init=HoTT_Init, run=HoTT_Run }
|
||||
@@ -0,0 +1,132 @@
|
||||
---- #########################################################################
|
||||
---- # #
|
||||
---- # Copyright (C) OpenTX #
|
||||
-----# #
|
||||
---- # 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. #
|
||||
---- # #
|
||||
---- #########################################################################
|
||||
|
||||
|
||||
--###############################################################################
|
||||
-- Multi buffer for HoTT description
|
||||
-- To start operation:
|
||||
-- Write "HoTT" at address 0..3
|
||||
-- Write 0xFF at address 4 will request the buffer to be cleared
|
||||
-- Write 0xDF at address 5
|
||||
-- Read buffer from address 6 access the RX text for 168 bytes, 21 caracters
|
||||
-- by 8 lines
|
||||
-- Write at address 5 sends an order to the RX: 0xDF=start, 0xD7=prev page,
|
||||
-- 0xDE=next page, 0xD9=enter, 0xDD=next or 0xDB=prev
|
||||
-- Write at address 4 the value 0xFF will request the buffer to be cleared
|
||||
-- !! Before exiting the script must write 0 at address 0 for normal operation !!
|
||||
--###############################################################################
|
||||
|
||||
local function HoTT_Release()
|
||||
multiBuffer( 0, 0 )
|
||||
end
|
||||
|
||||
local function HoTT_Draw_LCD()
|
||||
local i
|
||||
local value
|
||||
local line
|
||||
local result
|
||||
local offset=0
|
||||
|
||||
lcd.clear()
|
||||
|
||||
if LCD_W == 480 then
|
||||
--Draw title
|
||||
lcd.drawFilledRectangle(0, 0, LCD_W, 30, TITLE_BGCOLOR)
|
||||
lcd.drawText(1, 5, "Graupner HoTT RX configuration", MENU_TITLE_COLOR)
|
||||
--Draw RX Menu
|
||||
if multiBuffer( 4 ) == 0xFF then
|
||||
lcd.drawText(10,50,"No HoTT telemetry...", BLINK)
|
||||
else
|
||||
for line = 0, 7, 1 do
|
||||
for i = 0, 21-1, 1 do
|
||||
value=multiBuffer( line*21+6+i )
|
||||
if value > 0x80 then
|
||||
value = value - 0x80
|
||||
lcd.drawText(10+i*16,32+16*line,string.char(value).." ",INVERS)
|
||||
else
|
||||
lcd.drawText(10+i*16,32+16*line,string.char(value))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
--Draw RX Menu on LCD_W=128
|
||||
if multiBuffer( 4 ) == 0xFF then
|
||||
lcd.drawText(2,17,"No HoTT telemetry...",SMLSIZE)
|
||||
else
|
||||
for line = 0, 7, 1 do
|
||||
for i = 0, 21-1, 1 do
|
||||
value=multiBuffer( line*21+6+i )
|
||||
if value > 0x80 then
|
||||
value = value - 0x80
|
||||
lcd.drawText(2+i*6,1+8*line,string.char(value).." ",SMLSIZE+INVERS)
|
||||
else
|
||||
lcd.drawText(2+i*6,1+8*line,string.char(value),SMLSIZE)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Init
|
||||
local function HoTT_Init()
|
||||
--Set protocol to talk to
|
||||
multiBuffer( 0, string.byte('H') )
|
||||
--test if value has been written
|
||||
if multiBuffer( 0 ) ~= string.byte('H') then
|
||||
error("Not enough memory!")
|
||||
return 2
|
||||
end
|
||||
multiBuffer( 1, string.byte('o') )
|
||||
multiBuffer( 2, string.byte('T') )
|
||||
multiBuffer( 3, string.byte('T') )
|
||||
--Request init of the RX buffer
|
||||
multiBuffer( 4, 0xFF )
|
||||
--Request RX to send the config menu
|
||||
multiBuffer( 5, 0xDF )
|
||||
end
|
||||
|
||||
-- Main
|
||||
local function HoTT_Run(event)
|
||||
if event == nil then
|
||||
error("Cannot be run as a model script!")
|
||||
return 2
|
||||
elseif event == EVT_VIRTUAL_EXIT then
|
||||
HoTT_Release()
|
||||
return 2
|
||||
else
|
||||
if event == EVT_VIRTUAL_PREV_PAGE then
|
||||
killEvents(event);
|
||||
multiBuffer( 5, 0xD7 )
|
||||
elseif event == EVT_VIRTUAL_NEXT_PAGE then
|
||||
multiBuffer( 5, 0xDE )
|
||||
elseif event == EVT_VIRTUAL_ENTER then
|
||||
multiBuffer( 5, 0xD9 )
|
||||
elseif event == EVT_VIRTUAL_NEXT then
|
||||
multiBuffer( 5, 0xDD )
|
||||
elseif event == EVT_VIRTUAL_PREV then
|
||||
multiBuffer( 5, 0xDB )
|
||||
else
|
||||
multiBuffer( 5, 0xDF )
|
||||
end
|
||||
HoTT_Draw_LCD()
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
return { init=HoTT_Init, run=HoTT_Run }
|
||||
@@ -268,6 +268,7 @@ enum TelemetryProtocol
|
||||
PROTOCOL_TELEMETRY_SPEKTRUM,
|
||||
PROTOCOL_TELEMETRY_FLYSKY_IBUS,
|
||||
PROTOCOL_TELEMETRY_HITEC,
|
||||
PROTOCOL_TELEMETRY_HOTT,
|
||||
PROTOCOL_TELEMETRY_MULTIMODULE,
|
||||
PROTOCOL_TELEMETRY_LAST=PROTOCOL_TELEMETRY_MULTIMODULE,
|
||||
PROTOCOL_TELEMETRY_LUA
|
||||
|
||||
@@ -418,6 +418,7 @@ PACK(struct TrainerModuleData {
|
||||
|
||||
// Only used in case switch and if statements as "virtual" protocol
|
||||
#define MM_RF_CUSTOM_SELECTED 0xff
|
||||
#define MULTI_MAX_PROTOCOLS 127 // rfProtocol:4 + rfProtocolExtra:3
|
||||
PACK(struct ModuleData {
|
||||
uint8_t type:4;
|
||||
// TODO some refactoring is needed, rfProtocol is only used by DSM2 and MULTI, it could be merged with subType
|
||||
@@ -436,8 +437,9 @@ PACK(struct ModuleData {
|
||||
int8_t frameLength;
|
||||
} ppm;
|
||||
NOBACKUP(struct {
|
||||
uint8_t rfProtocolExtra:2;
|
||||
uint8_t spare1:3;
|
||||
uint8_t rfProtocolExtra:3;
|
||||
uint8_t disableTelemetry:1;
|
||||
uint8_t disableMapping:1;
|
||||
uint8_t customProto:1;
|
||||
uint8_t autoBindMode:1;
|
||||
uint8_t lowPowerMode:1;
|
||||
@@ -464,15 +466,13 @@ PACK(struct ModuleData {
|
||||
};
|
||||
|
||||
// Helper functions to set both of the rfProto protocol at the same time
|
||||
NOBACKUP(inline uint8_t getMultiProtocol(bool returnCustom) {
|
||||
if (returnCustom && multi.customProto)
|
||||
return MM_RF_CUSTOM_SELECTED;
|
||||
NOBACKUP(inline uint8_t getMultiProtocol() {
|
||||
return ((uint8_t) (rfProtocol & 0x0f)) + (multi.rfProtocolExtra << 4);
|
||||
})
|
||||
|
||||
NOBACKUP(inline void setMultiProtocol(uint8_t proto) {
|
||||
rfProtocol = (uint8_t) (proto & 0x0f);
|
||||
multi.rfProtocolExtra = (proto & 0x30) >> 4;
|
||||
multi.rfProtocolExtra = (proto & 0x70) >> 4;
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
@@ -183,6 +183,7 @@ uint8_t * lcdLoadBitmap(uint8_t * dest, const char * filename, uint8_t width, ui
|
||||
#define BLINK_ON_PHASE (0)
|
||||
#else
|
||||
#define BLINK_ON_PHASE (g_blinkTmr10ms & (1<<6))
|
||||
#define SLOW_BLINK_ON_PHASE (g_blinkTmr10ms & (1<<7))
|
||||
#endif
|
||||
|
||||
inline display_t getPixel(uint8_t x, uint8_t y)
|
||||
|
||||
@@ -103,7 +103,6 @@ enum MenuModelSetupItems {
|
||||
#if defined(MULTIMODULE)
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_SUBTYPE,
|
||||
#endif
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_POWER,
|
||||
#if defined(MULTIMODULE)
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_STATUS,
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_SYNCSTATUS,
|
||||
@@ -114,9 +113,12 @@ enum MenuModelSetupItems {
|
||||
#if defined(PCBSKY9X) && defined(REVX)
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_OUTPUT_TYPE,
|
||||
#endif
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_POWER,
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_OPTIONS,
|
||||
#if defined(MULTIMODULE)
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_AUTOBIND,
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_DISABLE_TELEM,
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_DISABLE_MAPPING,
|
||||
#endif
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_FAILSAFE,
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_REGISTER_RANGE,
|
||||
@@ -329,11 +331,11 @@ void menuModelSetup(event_t event)
|
||||
LABEL(ExternalModule),
|
||||
EXTERNAL_MODULE_TYPE_ROW(),
|
||||
MULTIMODULE_SUBTYPE_ROWS(EXTERNAL_MODULE)
|
||||
MODULE_POWER_ROW(EXTERNAL_MODULE),
|
||||
MULTIMODULE_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
|
||||
MODULE_POWER_ROW(EXTERNAL_MODULE),
|
||||
IF_NOT_PXX2_MODULE(EXTERNAL_MODULE, MODULE_OPTION_ROW(EXTERNAL_MODULE)),
|
||||
MULTIMODULE_MODULE_ROWS(EXTERNAL_MODULE)
|
||||
FAILSAFE_ROWS(EXTERNAL_MODULE),
|
||||
@@ -867,11 +869,8 @@ void menuModelSetup(event_t event)
|
||||
lcdDrawTextAtIndex(lcdNextPos + 3, y, STR_R9M_REGION, g_model.moduleData[EXTERNAL_MODULE].subType, (menuHorizontalPosition==1 ? attr : 0));
|
||||
#if defined(MULTIMODULE)
|
||||
else if (isModuleMultimodule(EXTERNAL_MODULE)) {
|
||||
int multi_rfProto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false);
|
||||
if (g_model.moduleData[EXTERNAL_MODULE].multi.customProto)
|
||||
lcdDrawText(lcdNextPos + 3, y, STR_MULTI_CUSTOM, menuHorizontalPosition==1 ? attr : 0);
|
||||
else
|
||||
lcdDrawTextAtIndex(lcdNextPos + 3, y, STR_MULTI_PROTOCOLS, multi_rfProto, menuHorizontalPosition==1 ? attr : 0);
|
||||
int multi_rfProto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol();
|
||||
lcdDrawMultiProtocolString(lcdNextPos + 3, y, EXTERNAL_MODULE, multi_rfProto, menuHorizontalPosition == 1 ? attr : 0);
|
||||
}
|
||||
#endif
|
||||
if (attr && menuHorizontalPosition == 0) {
|
||||
@@ -914,15 +913,13 @@ void menuModelSetup(event_t event)
|
||||
|
||||
#if defined(MULTIMODULE)
|
||||
else if (isModuleMultimodule(EXTERNAL_MODULE)) {
|
||||
int multiRfProto = g_model.moduleData[EXTERNAL_MODULE].multi.customProto == 1 ? MODULE_SUBTYPE_MULTI_CUSTOM : g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false);
|
||||
CHECK_INCDEC_MODELVAR_CHECK(event, multiRfProto, MODULE_SUBTYPE_MULTI_FIRST, MODULE_SUBTYPE_MULTI_LAST, isMultiProtocolSelectable);
|
||||
int multiRfProto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol();
|
||||
CHECK_INCDEC_MODELVAR_CHECK(event, multiRfProto, MODULE_SUBTYPE_MULTI_FIRST, MULTI_MAX_PROTOCOLS, isMultiProtocolSelectable);
|
||||
if (checkIncDec_Ret) {
|
||||
g_model.moduleData[EXTERNAL_MODULE].multi.customProto = (multiRfProto == MODULE_SUBTYPE_MULTI_CUSTOM);
|
||||
if (!g_model.moduleData[EXTERNAL_MODULE].multi.customProto)
|
||||
g_model.moduleData[EXTERNAL_MODULE].setMultiProtocol(multiRfProto);
|
||||
g_model.moduleData[EXTERNAL_MODULE].setMultiProtocol(multiRfProto);
|
||||
g_model.moduleData[EXTERNAL_MODULE].subType = 0;
|
||||
// Sensible default for DSM2 (same as for ppm): 7ch@22ms + Autodetect settings enabled
|
||||
if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) == MODULE_SUBTYPE_MULTI_DSM2) {
|
||||
if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol() == MODULE_SUBTYPE_MULTI_DSM2) {
|
||||
g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode = 1;
|
||||
}
|
||||
else {
|
||||
@@ -969,29 +966,13 @@ void menuModelSetup(event_t event)
|
||||
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_SUBTYPE:
|
||||
{
|
||||
lcdDrawTextAlignedLeft(y, STR_SUBTYPE);
|
||||
uint8_t multi_rfProto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true);
|
||||
const mm_protocol_definition * pdef = getMultiProtocolDefinition(multi_rfProto);
|
||||
|
||||
if (multi_rfProto == MM_RF_CUSTOM_SELECTED) {
|
||||
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false), (menuHorizontalPosition == 0 ? attr : 0), 2);
|
||||
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN + 3 * FW, y, g_model.moduleData[EXTERNAL_MODULE].subType, (menuHorizontalPosition == 1 ? attr : 0), 2);
|
||||
}
|
||||
else {
|
||||
if (pdef->subTypeString != nullptr)
|
||||
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, pdef->subTypeString, g_model.moduleData[EXTERNAL_MODULE].subType, attr);
|
||||
}
|
||||
lcdDrawMultiSubProtocolString(MODEL_SETUP_2ND_COLUMN, y, EXTERNAL_MODULE, g_model.moduleData[EXTERNAL_MODULE].subType, attr);
|
||||
if (attr && s_editMode > 0) {
|
||||
switch (menuHorizontalPosition) {
|
||||
case 0:
|
||||
if (multi_rfProto == MM_RF_CUSTOM_SELECTED)
|
||||
g_model.moduleData[EXTERNAL_MODULE].setMultiProtocol(checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false), 0, 63, EE_MODEL));
|
||||
else if (pdef->maxSubtype > 0)
|
||||
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, pdef->maxSubtype);
|
||||
break;
|
||||
case 1:
|
||||
// Custom protocol, third column is subtype
|
||||
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, 7);
|
||||
case 0:{
|
||||
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, getMaxMultiSubtype(EXTERNAL_MODULE));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1438,10 +1419,27 @@ void menuModelSetup(event_t event)
|
||||
if (isModuleMultimodule(moduleIdx)) {
|
||||
int optionValue = g_model.moduleData[moduleIdx].multi.optionValue;
|
||||
|
||||
const uint8_t multi_proto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true);
|
||||
const mm_protocol_definition * pdef = getMultiProtocolDefinition(multi_proto);
|
||||
if (pdef->optionsstr)
|
||||
lcdDrawText(INDENT_WIDTH, y, pdef->optionsstr);
|
||||
const uint8_t multi_proto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol();
|
||||
if (multi_proto < MODULE_SUBTYPE_MULTI_LAST) {
|
||||
const mm_protocol_definition * pdef = getMultiProtocolDefinition(multi_proto);
|
||||
if (pdef->optionsstr) {
|
||||
lcdDrawText(INDENT_WIDTH, y, pdef->optionsstr);
|
||||
if (attr && pdef->optionsstr == STR_MULTI_RFTUNE) {
|
||||
lcdDrawText(MODEL_SETUP_2ND_COLUMN + 23, y, "RSSI(", LEFT);
|
||||
lcdDrawNumber(lcdLastRightPos, y, TELEMETRY_RSSI(), LEFT);
|
||||
lcdDrawText(lcdLastRightPos, y, ")", LEFT);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
MultiModuleStatus &status = getMultiModuleStatus(moduleIdx);
|
||||
lcdDrawText(INDENT_WIDTH, y, mm_options_strings::options[status.optionDisp]);
|
||||
if (attr && status.optionDisp == 2) {
|
||||
lcdDrawText(MODEL_SETUP_2ND_COLUMN + 23, y, "RSSI(", LEFT);
|
||||
lcdDrawNumber(lcdLastRightPos, y, TELEMETRY_RSSI(), LEFT);
|
||||
lcdDrawText(lcdLastRightPos, y, ")", LEFT);
|
||||
}
|
||||
}
|
||||
|
||||
if (multi_proto == MODULE_SUBTYPE_MULTI_FS_AFHDS2A)
|
||||
optionValue = 50 + 5 * optionValue;
|
||||
@@ -1456,11 +1454,6 @@ void menuModelSetup(event_t event)
|
||||
}
|
||||
else {
|
||||
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].multi.optionValue, -128, 127);
|
||||
if (pdef->optionsstr == STR_MULTI_RFTUNE) {
|
||||
lcdDrawText(MODEL_SETUP_2ND_COLUMN + 23, y, "RSSI(", LEFT);
|
||||
lcdDrawNumber(lcdLastRightPos, y, TELEMETRY_RSSI(), LEFT);
|
||||
lcdDrawText(lcdLastRightPos, y, ")", LEFT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1555,12 +1548,20 @@ void menuModelSetup(event_t event)
|
||||
|
||||
#if defined(MULTIMODULE)
|
||||
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_AUTOBIND:
|
||||
if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) == MODULE_SUBTYPE_MULTI_DSM2)
|
||||
if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol() == MODULE_SUBTYPE_MULTI_DSM2)
|
||||
g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode = editCheckBox(g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode, MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_DSM_AUTODTECT, attr, 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_SETUP_EXTERNAL_MODULE_DISABLE_TELEM:
|
||||
g_model.moduleData[EXTERNAL_MODULE].multi.disableTelemetry = editCheckBox(g_model.moduleData[EXTERNAL_MODULE].multi.disableTelemetry, MODEL_SETUP_2ND_COLUMN, y, INDENT TR_DISABLE_TELEM, attr, event);
|
||||
break;
|
||||
|
||||
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_DISABLE_MAPPING:
|
||||
g_model.moduleData[EXTERNAL_MODULE].multi.disableMapping = editCheckBox(g_model.moduleData[EXTERNAL_MODULE].multi.disableMapping, MODEL_SETUP_2ND_COLUMN, y, INDENT TR_DISABLE_CH_MAP, attr, event);
|
||||
break;
|
||||
|
||||
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_STATUS: {
|
||||
lcdDrawTextAlignedLeft(y, STR_MODULE_STATUS);
|
||||
|
||||
|
||||
@@ -237,8 +237,8 @@ void menuModelTelemetry(event_t event)
|
||||
|
||||
case ITEM_TELEMETRY_RSSI_LABEL:
|
||||
#if defined(MULTIMODULE)
|
||||
if (telemetryProtocol == PROTOCOL_TELEMETRY_MULTIMODULE && g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false) == MODULE_SUBTYPE_MULTI_FS_AFHDS2A)
|
||||
lcdDrawTextAlignedLeft(y, "RSNR");
|
||||
if (telemetryProtocol == PROTOCOL_TELEMETRY_MULTIMODULE && (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol() == MODULE_SUBTYPE_MULTI_FS_AFHDS2A || g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol() == MODULE_SUBTYPE_MULTI_HOTT))
|
||||
lcdDrawTextAlignedLeft(y, "RQly");
|
||||
else
|
||||
lcdDrawTextAlignedLeft(y, "RSSI");
|
||||
#else
|
||||
|
||||
@@ -174,6 +174,7 @@ uint8_t * lcdLoadBitmap(uint8_t * dest, const char * filename, uint16_t width, u
|
||||
#define BLINK_ON_PHASE (0)
|
||||
#else
|
||||
#define BLINK_ON_PHASE (g_blinkTmr10ms & (1<<6))
|
||||
#define SLOW_BLINK_ON_PHASE (g_blinkTmr10ms & (1<<7))
|
||||
#endif
|
||||
|
||||
inline display_t getPixel(unsigned int x, unsigned int y)
|
||||
|
||||
@@ -107,6 +107,8 @@ enum MenuModelSetupItems {
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_OPTIONS,
|
||||
#if defined(MULTIMODULE)
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_AUTOBIND,
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_DISABLE_TELEM,
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_DISABLE_MAPPING,
|
||||
#endif
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_POWER,
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_FAILSAFE,
|
||||
@@ -815,21 +817,11 @@ void menuModelSetup(event_t event)
|
||||
lcdDrawTextAtIndex(lcdNextPos + 3, y, STR_R9M_REGION, g_model.moduleData[EXTERNAL_MODULE].subType, (menuHorizontalPosition==1 ? attr : 0));
|
||||
#if defined(MULTIMODULE)
|
||||
else if (isModuleMultimodule(EXTERNAL_MODULE)) {
|
||||
uint8_t multi_rfProto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false);
|
||||
|
||||
uint8_t multi_rfProto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol();
|
||||
// Do not use MODEL_SETUP_3RD_COLUMN here since some the protocol string are so long that we cannot afford the 2 spaces (+6) here
|
||||
if (g_model.moduleData[EXTERNAL_MODULE].multi.customProto) {
|
||||
lcdDrawText(lcdNextPos + 3, y, STR_MULTI_CUSTOM, menuHorizontalPosition == 1 ? attr : 0);
|
||||
lcdDrawNumber(lcdNextPos + 3, y, g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false), menuHorizontalPosition == 2 ? attr : 0, 2);
|
||||
lcdDrawNumber(lcdNextPos + 3, y, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition == 3 ? attr : 0, 2);
|
||||
}
|
||||
else {
|
||||
lcdDrawTextAtIndex(lcdNextPos + 3, y, STR_MULTI_PROTOCOLS, multi_rfProto, menuHorizontalPosition==1 ? attr : 0);
|
||||
const mm_protocol_definition * pdef = getMultiProtocolDefinition(multi_rfProto);
|
||||
if (pdef->subTypeString) {
|
||||
lcdDrawTextAtIndex(lcdNextPos + 3, y, pdef->subTypeString, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0);
|
||||
}
|
||||
}
|
||||
lcdDrawMultiProtocolString(lcdNextPos + 3, y, EXTERNAL_MODULE, multi_rfProto, menuHorizontalPosition == 1 ? attr : 0);
|
||||
if (MULTIMODULE_HAS_SUBTYPE(EXTERNAL_MODULE))
|
||||
lcdDrawMultiSubProtocolString(lcdNextPos + 3, y, EXTERNAL_MODULE, g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==2 ? attr : 0);
|
||||
}
|
||||
#endif
|
||||
if (attr && menuHorizontalPosition == 0) {
|
||||
@@ -858,15 +850,13 @@ void menuModelSetup(event_t event)
|
||||
}
|
||||
#if defined(MULTIMODULE)
|
||||
else if (isModuleMultimodule(EXTERNAL_MODULE)) {
|
||||
int multiRfProto = g_model.moduleData[EXTERNAL_MODULE].multi.customProto == 1 ? MODULE_SUBTYPE_MULTI_CUSTOM : g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false);
|
||||
CHECK_INCDEC_MODELVAR_CHECK(event, multiRfProto, MODULE_SUBTYPE_MULTI_FIRST, MODULE_SUBTYPE_MULTI_LAST, isMultiProtocolSelectable);
|
||||
int multiRfProto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol();
|
||||
CHECK_INCDEC_MODELVAR_CHECK(event, multiRfProto, MODULE_SUBTYPE_MULTI_FIRST, MULTI_MAX_PROTOCOLS, isMultiProtocolSelectable);
|
||||
if (checkIncDec_Ret) {
|
||||
g_model.moduleData[EXTERNAL_MODULE].multi.customProto = (multiRfProto == MODULE_SUBTYPE_MULTI_CUSTOM);
|
||||
if (!g_model.moduleData[EXTERNAL_MODULE].multi.customProto)
|
||||
g_model.moduleData[EXTERNAL_MODULE].setMultiProtocol(multiRfProto);
|
||||
g_model.moduleData[EXTERNAL_MODULE].setMultiProtocol(multiRfProto);
|
||||
g_model.moduleData[EXTERNAL_MODULE].subType = 0;
|
||||
// Sensible default for DSM2 (same as for ppm): 7ch@22ms + Autodetect settings enabled
|
||||
if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) == MODULE_SUBTYPE_MULTI_DSM2) {
|
||||
if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol() == MODULE_SUBTYPE_MULTI_DSM2) {
|
||||
g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode = 1;
|
||||
}
|
||||
else {
|
||||
@@ -895,13 +885,11 @@ void menuModelSetup(event_t event)
|
||||
#if defined(MULTIMODULE)
|
||||
case 2:
|
||||
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));
|
||||
g_model.moduleData[EXTERNAL_MODULE].setMultiProtocol(checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(), 0, MULTI_MAX_PROTOCOLS, EE_MODEL));
|
||||
break;
|
||||
}
|
||||
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);
|
||||
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].subType, 0, getMaxMultiSubtype(EXTERNAL_MODULE));
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1243,7 +1231,7 @@ void menuModelSetup(event_t event)
|
||||
if (isModuleMultimodule(moduleIdx)) {
|
||||
int optionValue = g_model.moduleData[moduleIdx].multi.optionValue;
|
||||
|
||||
const uint8_t multi_proto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true);
|
||||
const uint8_t multi_proto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol();
|
||||
const mm_protocol_definition *pdef = getMultiProtocolDefinition(multi_proto);
|
||||
if (pdef->optionsstr)
|
||||
lcdDrawText(INDENT_WIDTH, y, pdef->optionsstr);
|
||||
@@ -1317,12 +1305,20 @@ void menuModelSetup(event_t event)
|
||||
|
||||
#if defined (MULTIMODULE)
|
||||
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_AUTOBIND:
|
||||
if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) == MODULE_SUBTYPE_MULTI_DSM2)
|
||||
if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol() == MODULE_SUBTYPE_MULTI_DSM2)
|
||||
g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode = editCheckBox(g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode, MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_DSM_AUTODTECT, attr, 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_SETUP_EXTERNAL_MODULE_DISABLE_TELEM:
|
||||
g_model.moduleData[EXTERNAL_MODULE].multi.disableTelemetry = editCheckBox(g_model.moduleData[EXTERNAL_MODULE].multi.disableTelemetry, MODEL_SETUP_2ND_COLUMN, y, INDENT TR_DISABLE_TELEM, attr, event);
|
||||
break;
|
||||
|
||||
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_DISABLE_MAPPING:
|
||||
g_model.moduleData[EXTERNAL_MODULE].multi.disableMapping = editCheckBox(g_model.moduleData[EXTERNAL_MODULE].multi.disableMapping, MODEL_SETUP_2ND_COLUMN, y, INDENT TR_DISABLE_CH_MAP, attr, event);
|
||||
break;
|
||||
|
||||
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_STATUS:
|
||||
{
|
||||
lcdDrawTextAlignedLeft(y, STR_MODULE_STATUS);
|
||||
|
||||
@@ -228,8 +228,8 @@ void menuModelTelemetry(event_t event)
|
||||
|
||||
case ITEM_TELEMETRY_RSSI_LABEL:
|
||||
#if defined(MULTIMODULE)
|
||||
if (telemetryProtocol == PROTOCOL_TELEMETRY_MULTIMODULE && g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false) == MODULE_SUBTYPE_MULTI_FS_AFHDS2A)
|
||||
lcdDrawTextAlignedLeft(y, "RSNR");
|
||||
if (telemetryProtocol == PROTOCOL_TELEMETRY_MULTIMODULE && (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol() == MODULE_SUBTYPE_MULTI_FS_AFHDS2A || g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol() == MODULE_SUBTYPE_MULTI_HOTT))
|
||||
lcdDrawTextAlignedLeft(y, "RQly");
|
||||
else
|
||||
lcdDrawTextAlignedLeft(y, "RSSI");
|
||||
#else
|
||||
|
||||
@@ -432,6 +432,37 @@ void lcdDrawBlackOverlay()
|
||||
lcdDrawFilledRect(0, 0, LCD_W, LCD_H, SOLID, OVERLAY_COLOR | OPACITY(8));
|
||||
}
|
||||
|
||||
#if defined(MULTIMODULE)
|
||||
void lcdDrawMultiProtocolString(coord_t x, coord_t y, uint8_t moduleIdx, uint8_t protocol, LcdFlags flags)
|
||||
{
|
||||
if (protocol <= MODULE_SUBTYPE_MULTI_LAST) {
|
||||
lcdDrawTextAtIndex(x, y, STR_MULTI_PROTOCOLS, protocol, flags);
|
||||
}
|
||||
else {
|
||||
MultiModuleStatus &status = getMultiModuleStatus(moduleIdx);
|
||||
if (status.protocolName[0] && status.isValid())
|
||||
lcdDrawText(x, y, status.protocolName, flags);
|
||||
else
|
||||
lcdDrawNumber(x, y, protocol + 3, flags); // Convert because of OpenTX FrSky fidling (OpenTX protocol tables and Multiprotocol tables don't match)
|
||||
}
|
||||
}
|
||||
|
||||
void lcdDrawMultiSubProtocolString(coord_t x, coord_t y, uint8_t moduleIdx, uint8_t subType, LcdFlags flags)
|
||||
{
|
||||
const mm_protocol_definition *pdef = getMultiProtocolDefinition(g_model.moduleData[moduleIdx].getMultiProtocol());
|
||||
if (subType <= pdef->maxSubtype && pdef->subTypeString != nullptr) {
|
||||
lcdDrawTextAtIndex(x, y, pdef->subTypeString, subType, flags);
|
||||
}
|
||||
else {
|
||||
MultiModuleStatus &status = getMultiModuleStatus(moduleIdx);
|
||||
if (status.protocolName[0] && status.isValid())
|
||||
lcdDrawText(x, y, status.protocolSubName, flags);
|
||||
else
|
||||
lcdDrawNumber(x, y, subType, flags);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SIMU)
|
||||
BitmapBuffer _lcd(BMP_RGB565, LCD_W, LCD_H, displayBuf);
|
||||
BitmapBuffer * lcd = &_lcd;
|
||||
|
||||
@@ -115,8 +115,9 @@ extern display_t displayBuf[DISPLAY_BUFFER_SIZE];
|
||||
extern coord_t lcdNextPos;
|
||||
|
||||
void lcdDrawChar(coord_t x, coord_t y, char c, LcdFlags flags=0);
|
||||
|
||||
void lcdDrawTextAtIndex(coord_t x, coord_t y, const char * s, uint8_t idx, LcdFlags flags=0);
|
||||
void lcdDrawMultiProtocolString(coord_t x, coord_t y, uint8_t moduleIdx, uint8_t protocol, LcdFlags flags=0);
|
||||
void lcdDrawMultiSubProtocolString(coord_t x, coord_t y, uint8_t moduleIdx, uint8_t subType, LcdFlags flags);
|
||||
|
||||
inline void lcdClear()
|
||||
{
|
||||
|
||||
@@ -69,13 +69,19 @@ enum MenuModelSetupItems {
|
||||
#if defined(HARDWARE_INTERNAL_MODULE)
|
||||
ITEM_MODEL_SETUP_INTERNAL_MODULE_LABEL,
|
||||
ITEM_MODEL_SETUP_INTERNAL_MODULE_TYPE,
|
||||
#if defined(MULTIMODULE)
|
||||
ITEM_MODEL_SETUP_INTERNAL_MODULE_STATUS,
|
||||
ITEM_MODEL_SETUP_INTERNAL_MODULE_SYNCSTATUS,
|
||||
#endif
|
||||
ITEM_MODEL_SETUP_INTERNAL_MODULE_CHANNELS,
|
||||
ITEM_MODEL_SETUP_INTERNAL_MODULE_NOT_ACCESS_RXNUM_BIND_RANGE,
|
||||
ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_MODEL_NUM,
|
||||
ITEM_MODEL_SETUP_INTERNAL_MODULE_OPTIONS,
|
||||
#if defined(MULTIMODULE)
|
||||
ITEM_MODEL_SETUP_INTERNAL_MODULE_AUTOBIND,
|
||||
ITEM_MODEL_SETUP_INTERNAL_MODULE_DISABLE_TELEM,
|
||||
ITEM_MODEL_SETUP_INTERNAL_MODULE_DISABLE_MAPPING,
|
||||
#endif
|
||||
#if defined(INTERNAL_MODULE_PXX1) && defined(EXTERNAL_ANTENNA)
|
||||
ITEM_MODEL_SETUP_INTERNAL_MODULE_ANTENNA,
|
||||
#endif
|
||||
@@ -99,6 +105,8 @@ enum MenuModelSetupItems {
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_OPTIONS,
|
||||
#if defined(MULTIMODULE)
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_AUTOBIND,
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_DISABLE_TELEM,
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_DISABLE_MAPPING,
|
||||
#endif
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_POWER,
|
||||
ITEM_MODEL_SETUP_EXTERNAL_MODULE_FAILSAFE,
|
||||
@@ -563,6 +571,8 @@ void onModelAntennaSwitchConfirm(const char * result)
|
||||
IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), /* ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_MODEL_NUM*/ \
|
||||
MODULE_OPTION_ROW(INTERNAL_MODULE), /* ITEM_MODEL_SETUP_INTERNAL_MODULE_OPTIONS */ \
|
||||
MULTIMODULE_MODULE_ROWS(INTERNAL_MODULE) /* ITEM_MODEL_SETUP_INTERNAL_MODULE_AUTOBIND */ \
|
||||
/* ITEM_MODEL_SETUP_INTERNAL_MODULE_DISABLE_TELEM */ \
|
||||
/* ITEM_MODEL_SETUP_INTERNAL_MODULE_DISABLE_MAPPING */ \
|
||||
EXTERNAL_ANTENNA_ROW /* ITEM_MODEL_SETUP_INTERNAL_MODULE_ANTENNA */ \
|
||||
MODULE_POWER_ROW(INTERNAL_MODULE), /* ITEM_MODEL_SETUP_INTERNAL_MODULE_POWER */ \
|
||||
IF_INTERNAL_MODULE_ON(FAILSAFE_ROWS(INTERNAL_MODULE)), /* ITEM_MODEL_SETUP_INTERNAL_MODULE_FAILSAFE */ \
|
||||
@@ -1060,18 +1070,10 @@ bool menuModelSetup(event_t event)
|
||||
lcdDrawTextAtIndex(MODEL_SETUP_3RD_COLUMN, y, STR_R9M_REGION, g_model.moduleData[moduleIdx].subType, (menuHorizontalPosition==1 ? attr : 0));
|
||||
#if defined(MULTIMODULE)
|
||||
else if (isModuleMultimodule(moduleIdx)) {
|
||||
int multi_rfProto = g_model.moduleData[moduleIdx].getMultiProtocol(false);
|
||||
if (g_model.moduleData[moduleIdx].multi.customProto) {
|
||||
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[moduleIdx].subType, menuHorizontalPosition==3 ? attr : 0, 2);
|
||||
}
|
||||
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[moduleIdx].subType, menuHorizontalPosition==2 ? attr : 0);
|
||||
}
|
||||
int multi_rfProto = g_model.moduleData[moduleIdx].getMultiProtocol();
|
||||
lcdDrawMultiProtocolString(MODEL_SETUP_3RD_COLUMN, y, moduleIdx, multi_rfProto, menuHorizontalPosition == 1 ? attr : 0);
|
||||
if (MULTIMODULE_HAS_SUBTYPE(EXTERNAL_MODULE))
|
||||
lcdDrawMultiSubProtocolString(MODEL_SETUP_4TH_COLUMN, y, moduleIdx, g_model.moduleData[moduleIdx].subType, menuHorizontalPosition==2 ? attr : 0);
|
||||
}
|
||||
#endif
|
||||
if (attr && menuHorizontalPosition == 0 && moduleIdx == EXTERNAL_MODULE) {
|
||||
@@ -1110,21 +1112,21 @@ bool menuModelSetup(event_t event)
|
||||
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].rfProtocol, DSM2_PROTO_LP45, DSM2_PROTO_DSMX);
|
||||
#if defined(MULTIMODULE)
|
||||
else if (isModuleMultimodule(moduleIdx)) {
|
||||
int multiRfProto = g_model.moduleData[moduleIdx].multi.customProto == 1 ? MODULE_SUBTYPE_MULTI_CUSTOM : g_model.moduleData[moduleIdx].getMultiProtocol(false);
|
||||
CHECK_INCDEC_MODELVAR_CHECK(event, multiRfProto, MODULE_SUBTYPE_MULTI_FIRST, MODULE_SUBTYPE_MULTI_LAST, isMultiProtocolSelectable);
|
||||
int multiRfProto = g_model.moduleData[moduleIdx].getMultiProtocol();
|
||||
CHECK_INCDEC_MODELVAR_CHECK(event, multiRfProto, MODULE_SUBTYPE_MULTI_FIRST, MULTI_MAX_PROTOCOLS, isMultiProtocolSelectable);
|
||||
if (checkIncDec_Ret) {
|
||||
g_model.moduleData[moduleIdx].multi.customProto = (multiRfProto == MODULE_SUBTYPE_MULTI_CUSTOM);
|
||||
if (!g_model.moduleData[moduleIdx].multi.customProto)
|
||||
g_model.moduleData[moduleIdx].setMultiProtocol(multiRfProto);
|
||||
g_model.moduleData[moduleIdx].setMultiProtocol(multiRfProto);
|
||||
g_model.moduleData[moduleIdx].subType = 0;
|
||||
// Sensible default for DSM2 (same as for ppm): 7ch@22ms + Autodetect settings enabled
|
||||
if (g_model.moduleData[moduleIdx].getMultiProtocol(true) == MODULE_SUBTYPE_MULTI_DSM2) {
|
||||
if (g_model.moduleData[moduleIdx].getMultiProtocol() == MODULE_SUBTYPE_MULTI_DSM2) {
|
||||
g_model.moduleData[moduleIdx].multi.autoBindMode = 1;
|
||||
}
|
||||
else {
|
||||
g_model.moduleData[moduleIdx].multi.autoBindMode = 0;
|
||||
}
|
||||
g_model.moduleData[moduleIdx].multi.optionValue = 0;
|
||||
g_model.moduleData[moduleIdx].multi.disableTelemetry = 0;
|
||||
g_model.moduleData[moduleIdx].multi.disableMapping = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1142,20 +1144,10 @@ bool menuModelSetup(event_t event)
|
||||
break;
|
||||
|
||||
#if defined(MULTIMODULE)
|
||||
case 2:
|
||||
if (g_model.moduleData[moduleIdx].multi.customProto) {
|
||||
g_model.moduleData[moduleIdx].setMultiProtocol(checkIncDec(event, g_model.moduleData[moduleIdx].getMultiProtocol(false), 0, 63, EE_MODEL));
|
||||
break;
|
||||
} else {
|
||||
const mm_protocol_definition *pdef = getMultiProtocolDefinition(g_model.moduleData[moduleIdx].getMultiProtocol(false));
|
||||
if (pdef->maxSubtype > 0)
|
||||
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].subType, 0, pdef->maxSubtype);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
// Custom protocol, third column is subtype
|
||||
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].subType, 0, 7);
|
||||
case 2: {
|
||||
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].subType, 0, getMaxMultiSubtype(moduleIdx));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1627,11 +1619,23 @@ bool menuModelSetup(event_t event)
|
||||
if (isModuleMultimodule(moduleIdx)) {
|
||||
int optionValue = g_model.moduleData[moduleIdx].multi.optionValue;
|
||||
|
||||
const uint8_t multi_proto = g_model.moduleData[moduleIdx].getMultiProtocol(true);
|
||||
const mm_protocol_definition *pdef = getMultiProtocolDefinition(multi_proto);
|
||||
if (pdef->optionsstr)
|
||||
lcdDrawText(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, pdef->optionsstr);
|
||||
|
||||
const uint8_t multi_proto = g_model.moduleData[moduleIdx].getMultiProtocol();
|
||||
if (multi_proto < MODULE_SUBTYPE_MULTI_LAST) {
|
||||
const mm_protocol_definition * pdef = getMultiProtocolDefinition(multi_proto);
|
||||
if (pdef->optionsstr) {
|
||||
lcdDrawText(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, pdef->optionsstr);
|
||||
if (attr && pdef->optionsstr == STR_MULTI_RFTUNE) {
|
||||
lcdDrawNumber(LCD_W - 10, y, TELEMETRY_RSSI(), RIGHT, 0, "RSSI(", ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
MultiModuleStatus &status = getMultiModuleStatus(moduleIdx);
|
||||
lcdDrawText(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, mm_options_strings::options[status.optionDisp]);
|
||||
if (attr && status.optionDisp == 2) {
|
||||
lcdDrawNumber(LCD_W - 10, y, TELEMETRY_RSSI(), RIGHT, 0, "RSSI(", ")");
|
||||
}
|
||||
}
|
||||
if (multi_proto == MODULE_SUBTYPE_MULTI_FS_AFHDS2A)
|
||||
optionValue = 50 + 5 * optionValue;
|
||||
|
||||
@@ -1643,11 +1647,17 @@ bool menuModelSetup(event_t event)
|
||||
else if (multi_proto == MODULE_SUBTYPE_MULTI_OLRS) {
|
||||
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].multi.optionValue, -1, 7);
|
||||
}
|
||||
else if (multi_proto == MODULE_SUBTYPE_MULTI_DSM2) {
|
||||
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].multi.optionValue, 0, 1);
|
||||
}
|
||||
else if (multi_proto == MODULE_SUBTYPE_MULTI_BAYANG) {
|
||||
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].multi.optionValue, 0, 3);
|
||||
}
|
||||
else if (multi_proto == MODULE_SUBTYPE_MULTI_XN297DP) {
|
||||
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].multi.optionValue, -1, 84);
|
||||
}
|
||||
else {
|
||||
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].multi.optionValue, -128, 127);
|
||||
if (pdef->optionsstr == STR_MULTI_RFTUNE) {
|
||||
lcdDrawNumber(LCD_W - 10, y, TELEMETRY_RSSI(), RIGHT, 0, "RSSI(", ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1671,7 +1681,7 @@ bool menuModelSetup(event_t event)
|
||||
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_POWER:
|
||||
{
|
||||
if (isModuleR9MNonAccess(moduleIdx)) {
|
||||
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_RFPOWER);
|
||||
lcdDrawText(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, STR_RFPOWER);
|
||||
if (isModuleR9M_FCC_VARIANT(moduleIdx)) {
|
||||
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_R9M_FCC_POWER_VALUES, g_model.moduleData[moduleIdx].pxx.power, LEFT | attr);
|
||||
if (attr)
|
||||
@@ -1704,13 +1714,29 @@ bool menuModelSetup(event_t event)
|
||||
case ITEM_MODEL_SETUP_INTERNAL_MODULE_AUTOBIND:
|
||||
#endif
|
||||
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_AUTOBIND:
|
||||
if (g_model.moduleData[moduleIdx].getMultiProtocol(true) == MODULE_SUBTYPE_MULTI_DSM2)
|
||||
if (g_model.moduleData[moduleIdx].getMultiProtocol() == MODULE_SUBTYPE_MULTI_DSM2)
|
||||
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MULTI_DSM_AUTODTECT);
|
||||
else
|
||||
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MULTI_AUTOBIND);
|
||||
g_model.moduleData[moduleIdx].multi.autoBindMode = editCheckBox(g_model.moduleData[moduleIdx].multi.autoBindMode, MODEL_SETUP_2ND_COLUMN, y, attr, event);
|
||||
break;
|
||||
|
||||
#if defined(HARDWARE_INTERNAL_MODULE)
|
||||
case ITEM_MODEL_SETUP_INTERNAL_MODULE_DISABLE_TELEM:
|
||||
#endif
|
||||
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_DISABLE_TELEM:
|
||||
lcdDrawText(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, STR_DISABLE_TELEM);
|
||||
g_model.moduleData[moduleIdx].multi.disableTelemetry = editCheckBox(g_model.moduleData[moduleIdx].multi.disableTelemetry, MODEL_SETUP_2ND_COLUMN, y, attr, event);
|
||||
break;
|
||||
|
||||
#if defined(HARDWARE_INTERNAL_MODULE)
|
||||
case ITEM_MODEL_SETUP_INTERNAL_MODULE_DISABLE_MAPPING:
|
||||
#endif
|
||||
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_DISABLE_MAPPING:
|
||||
lcdDrawText(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, STR_DISABLE_CH_MAP);
|
||||
g_model.moduleData[moduleIdx].multi.disableMapping = editCheckBox(g_model.moduleData[moduleIdx].multi.disableMapping, MODEL_SETUP_2ND_COLUMN, y, attr, event);
|
||||
break;
|
||||
|
||||
#if defined(HARDWARE_INTERNAL_MODULE)
|
||||
case ITEM_MODEL_SETUP_INTERNAL_MODULE_STATUS:
|
||||
#endif
|
||||
|
||||
@@ -220,8 +220,8 @@ bool menuModelTelemetry(event_t event)
|
||||
#if defined(MULTIMODULE)
|
||||
if (!IS_INTERNAL_MODULE_ON() &&
|
||||
g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_MULTIMODULE &&
|
||||
g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false) == MODULE_SUBTYPE_MULTI_FS_AFHDS2A)
|
||||
lcdDrawText(MENUS_MARGIN_LEFT, y, "RSNR");
|
||||
(g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol() == MODULE_SUBTYPE_MULTI_FS_AFHDS2A || g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol() == MODULE_SUBTYPE_MULTI_HOTT ))
|
||||
lcdDrawText(MENUS_MARGIN_LEFT, y, "RQly");
|
||||
else
|
||||
#endif
|
||||
lcdDrawText(MENUS_MARGIN_LEFT, y, "RSSI");
|
||||
|
||||
@@ -39,7 +39,11 @@ coord_t getAverage(uint8_t number, const uint8_t * value)
|
||||
return sum / number;
|
||||
}
|
||||
|
||||
#define SPECTRUM_ROW (isModuleMultimodule(g_moduleIdx) ? READONLY_ROW : (uint8_t)0)
|
||||
#if defined(INTERNAL_MODULE_MULTI)
|
||||
#define SPECTRUM_ROW (g_moduleIdx == INTERNAL_MODULE ? READONLY_ROW : isModuleMultimodule(g_moduleIdx) ? READONLY_ROW : (uint8_t)0)
|
||||
#else
|
||||
#define SPECTRUM_ROW (isModuleMultimodule(g_moduleIdx) ? READONLY_ROW : (uint8_t)0)
|
||||
#endif
|
||||
|
||||
bool menuRadioSpectrumAnalyser(event_t event)
|
||||
{
|
||||
@@ -54,8 +58,12 @@ bool menuRadioSpectrumAnalyser(event_t event)
|
||||
lcdRefresh();
|
||||
if (isModulePXX2(g_moduleIdx))
|
||||
moduleState[g_moduleIdx].readModuleInformation(&reusableBuffer.moduleSetup.pxx2.moduleInformation, PXX2_HW_INFO_TX_ID, PXX2_HW_INFO_TX_ID);
|
||||
else if (isModuleMultimodule((g_moduleIdx)))
|
||||
moduleState[g_moduleIdx].mode = MODULE_MODE_NORMAL;
|
||||
else if (isModuleMultimodule(g_moduleIdx)) {
|
||||
if (reusableBuffer.spectrumAnalyser.moduleOFF)
|
||||
setModuleType(INTERNAL_MODULE, MODULE_TYPE_NONE);
|
||||
else
|
||||
moduleState[g_moduleIdx].mode = MODULE_MODE_NORMAL;
|
||||
}
|
||||
/* wait 1s to resume normal operation before leaving */
|
||||
watchdogSuspend(1000);
|
||||
RTOS_WAIT_MS(1000);
|
||||
@@ -71,9 +79,15 @@ bool menuRadioSpectrumAnalyser(event_t event)
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
memclear(&reusableBuffer.spectrumAnalyser, sizeof(reusableBuffer.spectrumAnalyser));
|
||||
|
||||
#if defined(INTERNAL_MODULE_MULTI)
|
||||
if (g_moduleIdx == INTERNAL_MODULE && g_model.moduleData[INTERNAL_MODULE].type == MODULE_TYPE_NONE) {
|
||||
reusableBuffer.spectrumAnalyser.moduleOFF = true;
|
||||
setModuleType(INTERNAL_MODULE, MODULE_TYPE_MULTIMODULE);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (isModuleR9MAccess(g_moduleIdx)) {
|
||||
reusableBuffer.spectrumAnalyser.spanDefault = 20;
|
||||
reusableBuffer.spectrumAnalyser.spanMax = 40;
|
||||
|
||||
@@ -21,6 +21,37 @@
|
||||
#include "opentx.h"
|
||||
#include <math.h>
|
||||
|
||||
void lcdDrawMultiProtocolString(coord_t x, coord_t y, uint8_t moduleIdx, uint8_t protocol, LcdFlags flags)
|
||||
{
|
||||
if (protocol <= MODULE_SUBTYPE_MULTI_LAST) {
|
||||
lcdDrawTextAtIndex(x, y, STR_MULTI_PROTOCOLS, protocol, flags);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
MultiModuleStatus &status = getMultiModuleStatus(moduleIdx);
|
||||
if (status.protocolName[0] && status.isValid())
|
||||
lcdDrawText(x, y, status.protocolName, flags);
|
||||
else
|
||||
lcdDrawNumber(x, y, protocol + 3, flags); // Convert because of OpenTX FrSky fidling (OpenTX protocol tables and Multiprotocol tables don't match)
|
||||
}
|
||||
}
|
||||
|
||||
void lcdDrawMultiSubProtocolString(coord_t x, coord_t y, uint8_t moduleIdx, uint8_t subType, LcdFlags flags)
|
||||
{
|
||||
const mm_protocol_definition *pdef = getMultiProtocolDefinition(g_model.moduleData[moduleIdx].getMultiProtocol());
|
||||
if (subType <= pdef->maxSubtype && pdef->subTypeString != nullptr) {
|
||||
lcdDrawTextAtIndex(x, y, pdef->subTypeString, subType, flags);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
MultiModuleStatus &status = getMultiModuleStatus(moduleIdx);
|
||||
if (status.protocolName[0] && status.isValid())
|
||||
lcdDrawText(x, y, status.protocolSubName, flags);
|
||||
else
|
||||
lcdDrawNumber(x, y, subType, flags);
|
||||
}
|
||||
}
|
||||
|
||||
void drawStringWithIndex(coord_t x, coord_t y, const char * str, uint8_t idx, LcdFlags flags)
|
||||
{
|
||||
if (flags & RIGHT) {
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
#define _STDLCD_DRAW_FUNCTIONS_H_
|
||||
|
||||
#include "lcd.h"
|
||||
|
||||
void lcdDrawMultiProtocolString(coord_t x, coord_t y, uint8_t moduleIdx, uint8_t protocol, LcdFlags flags = 0);
|
||||
void lcdDrawMultiSubProtocolString(coord_t x, coord_t y, uint8_t moduleIdx, uint8_t subType, LcdFlags flags = 0);
|
||||
void drawStringWithIndex(coord_t x, coord_t y, const char * str, uint8_t idx, LcdFlags att=0);
|
||||
void drawValueWithUnit(coord_t x, coord_t y, int val, uint8_t unit, LcdFlags att=0);
|
||||
|
||||
|
||||
@@ -780,6 +780,37 @@ int getFirstAvailable(int min, int max, IsValueAvailable isValueAvailable)
|
||||
return retval;
|
||||
}
|
||||
#if defined(MULTIMODULE)
|
||||
|
||||
// This maps OpenTX multi type with Pascal's Multi type
|
||||
uint8_t convertMultiProtocol(uint8_t moduleIdx, uint8_t type)
|
||||
{
|
||||
|
||||
// 15 for Multimodule is FrskyX or D16 which we map as a subprotocol of 3 (FrSky)
|
||||
// all protos > frskyx are therefore also off by one
|
||||
if (type >= 15)
|
||||
type = type + 1;
|
||||
|
||||
// 25 is again a FrSky protocol (FrskyV) so shift again
|
||||
if (type >= 25)
|
||||
type = type + 1;
|
||||
|
||||
if (type == MODULE_SUBTYPE_MULTI_FRSKY) {
|
||||
int subtype = g_model.moduleData[moduleIdx].subType;
|
||||
if (subtype == MM_RF_FRSKY_SUBTYPE_D8) {
|
||||
//D8
|
||||
type = 3;
|
||||
}
|
||||
else if (subtype == MM_RF_FRSKY_SUBTYPE_V8) {
|
||||
//V8
|
||||
type = 25;
|
||||
}
|
||||
else {
|
||||
type = 15;
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
// Third row is number of subtypes -1 (max valid subtype)
|
||||
#define NO_SUBTYPE nullptr
|
||||
|
||||
@@ -804,7 +835,7 @@ const char STR_SUBTYPE_SYMAX[] = "\003""Std""X5C";
|
||||
const char STR_SUBTYPE_SLT[] = "\006""V1_6ch""V2_8ch""Q100\0 ""Q200\0 ""MR100\0";
|
||||
const char STR_SUBTYPE_CX10[] = "\007""Green\0 ""Blue\0 ""DM007\0 ""-\0 ""JC3015a""JC3015b""MK33041";
|
||||
const char STR_SUBTYPE_CG023[] = "\005""Std\0 ""YD829";
|
||||
const char STR_SUBTYPE_BAYANG[] = "\007""Std\0 ""H8S3D\0 ""X16 AH\0 ""IRDrone""DHD D4";
|
||||
const char STR_SUBTYPE_BAYANG[] = "\007""Std\0 ""H8S3D\0 ""X16 AH\0""IRDrone""DHD D4";
|
||||
const char STR_SUBTYPE_MT99[] = "\006""MT99\0 ""H7\0 ""YZ\0 ""LS\0 ""FY805";
|
||||
const char STR_SUBTYPE_MJXQ[] = "\007""WLH08\0 ""X600\0 ""X800\0 ""H26D\0 ""E010\0 ""H26WH\0 ""Phoenix";
|
||||
const char STR_SUBTYPE_FY326[] = "\005""Std\0 ""FY319";
|
||||
@@ -825,53 +856,66 @@ const char STR_SUBTYPE_REDPINE[] = "\004""Fast""Slow";
|
||||
const char STR_SUBTYPE_POTENSIC[] = "\003""A20";
|
||||
const char STR_SUBTYPE_ZSX[] = "\007""280JJRC";
|
||||
const char STR_SUBTYPE_FLYZONE[] = "\005""FZ410";
|
||||
const char STR_SUBTYPE_FRSKYX_RX[] = "\003""FCC""LBT";
|
||||
|
||||
const char* mm_options_strings::options[] = {
|
||||
nullptr,
|
||||
STR_MULTI_OPTION,
|
||||
STR_MULTI_RFTUNE,
|
||||
STR_MULTI_VIDFREQ,
|
||||
STR_MULTI_FIXEDID,
|
||||
STR_MULTI_TELEMETRY,
|
||||
STR_MULTI_SERVOFREQ,
|
||||
STR_MULTI_MAX_THROW,
|
||||
STR_MULTI_RFCHAN
|
||||
};
|
||||
|
||||
const mm_protocol_definition multi_protocols[] = {
|
||||
|
||||
{MODULE_SUBTYPE_MULTI_FLYSKY, 4, false, STR_SUBTYPE_FLYSKY, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_HUBSAN, 2, false, STR_SUBTYPE_HUBSAN, STR_MULTI_VIDFREQ},
|
||||
{MODULE_SUBTYPE_MULTI_FRSKY, 5, false, STR_SUBTYPE_FRSKY, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_HISKY, 1, false, STR_SUBTYPE_HISKY, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_V2X2, 1, false, STR_SUBTYPE_V2X2, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_DSM2, 3, false, STR_SUBTYPE_DSM, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_DEVO, 4, false, STR_SUBTYPE_DEVO, STR_MULTI_FIXEDID},
|
||||
{MODULE_SUBTYPE_MULTI_YD717, 4, false, STR_SUBTYPE_YD717, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_KN, 1, false, STR_SUBTYPE_KN, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_SYMAX, 1, false, STR_SUBTYPE_SYMAX, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_SLT, 4, false, STR_SUBTYPE_SLT, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_CX10, 6, false, STR_SUBTYPE_CX10, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_CG023, 1, false, STR_SUBTYPE_CG023, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_BAYANG, 4, false, STR_SUBTYPE_BAYANG, STR_MULTI_TELEMETRY},
|
||||
{MODULE_SUBTYPE_MULTI_MT99XX, 4, false, STR_SUBTYPE_MT99, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_MJXQ, 6, false, STR_SUBTYPE_MJXQ, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_FY326, 1, false, STR_SUBTYPE_FY326, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_SFHSS, 0, true, NO_SUBTYPE, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_HONTAI, 3, false, STR_SUBTYPE_HONTAI, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_OLRS, 0, false, NO_SUBTYPE, STR_RFPOWER},
|
||||
{MODULE_SUBTYPE_MULTI_FS_AFHDS2A, 3, true, STR_SUBTYPE_AFHDS2A, STR_MULTI_SERVOFREQ},
|
||||
{MODULE_SUBTYPE_MULTI_Q2X2, 2, false, STR_SUBTYPE_Q2X2, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_WK_2X01, 5, false, STR_SUBTYPE_WK2x01, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_Q303, 3, false, STR_SUBTYPE_Q303, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_CABELL, 7, false, STR_SUBTYPE_CABELL, STR_MULTI_OPTION},
|
||||
{MODULE_SUBTYPE_MULTI_H83D, 3, false, STR_SUBTYPE_H83D, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_CORONA, 2, false, STR_SUBTYPE_CORONA, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_HITEC, 2, false, STR_SUBTYPE_HITEC, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_BUGS_MINI, 1, false, STR_SUBTYPE_BUGS_MINI, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_TRAXXAS, 0, false, STR_SUBTYPE_TRAXXAS, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_E01X, 2, false, STR_SUBTYPE_E01X, STR_MULTI_OPTION},
|
||||
{MODULE_SUBTYPE_MULTI_V911S, 0, false, NO_SUBTYPE, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_GD00X, 1, false, STR_SUBTYPE_GD00X, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_KF606, 0, false, NO_SUBTYPE, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_REDPINE, 1, false, STR_SUBTYPE_REDPINE, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_POTENSIC, 0, false, STR_SUBTYPE_POTENSIC, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_ZSX, 0, false, STR_SUBTYPE_ZSX, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_FLYZONE, 0, false, STR_SUBTYPE_FLYZONE, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_FRSKYX_RX, 1, false, STR_SUBTYPE_FRSKYX_RX, STR_MULTI_RFTUNE},
|
||||
{MM_RF_CUSTOM_SELECTED, 7, true, NO_SUBTYPE, STR_MULTI_OPTION},
|
||||
// Protocol as defined in pulses\modules_constants.h, number of sub_protocols - 1, Failsafe supported, Disable channel mapping supported, Subtype string, Option type
|
||||
{MODULE_SUBTYPE_MULTI_FLYSKY, 4, false, true, STR_SUBTYPE_FLYSKY, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_HUBSAN, 2, false, false, STR_SUBTYPE_HUBSAN, STR_MULTI_VIDFREQ},
|
||||
{MODULE_SUBTYPE_MULTI_FRSKY, 5, false, false, STR_SUBTYPE_FRSKY, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_HISKY, 1, false, true, STR_SUBTYPE_HISKY, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_V2X2, 1, false, false, STR_SUBTYPE_V2X2, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_DSM2, 3, false, true, STR_SUBTYPE_DSM, STR_MULTI_MAX_THROW},
|
||||
{MODULE_SUBTYPE_MULTI_DEVO, 4, false, true, STR_SUBTYPE_DEVO, STR_MULTI_FIXEDID},
|
||||
{MODULE_SUBTYPE_MULTI_YD717, 4, false, false, STR_SUBTYPE_YD717, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_KN, 1, false, false, STR_SUBTYPE_KN, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_SYMAX, 1, false, false, STR_SUBTYPE_SYMAX, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_SLT, 4, false, true, STR_SUBTYPE_SLT, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_CX10, 6, false, false, STR_SUBTYPE_CX10, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_CG023, 1, false, false, STR_SUBTYPE_CG023, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_BAYANG, 4, false, false, STR_SUBTYPE_BAYANG, STR_MULTI_TELEMETRY},
|
||||
{MODULE_SUBTYPE_MULTI_MT99XX, 4, false, false, STR_SUBTYPE_MT99, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_MJXQ, 6, false, false, STR_SUBTYPE_MJXQ, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_FY326, 1, false, false, STR_SUBTYPE_FY326, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_SFHSS, 0, true, true, NO_SUBTYPE, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_HONTAI, 3, false, false, STR_SUBTYPE_HONTAI, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_OLRS, 0, false, false, NO_SUBTYPE, STR_RFPOWER},
|
||||
{MODULE_SUBTYPE_MULTI_FS_AFHDS2A, 3, true, true, STR_SUBTYPE_AFHDS2A, STR_MULTI_SERVOFREQ},
|
||||
{MODULE_SUBTYPE_MULTI_Q2X2, 2, false, false, STR_SUBTYPE_Q2X2, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_WK_2X01, 5, false, true, STR_SUBTYPE_WK2x01, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_Q303, 3, false, false, STR_SUBTYPE_Q303, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_CABELL, 7, false, false, STR_SUBTYPE_CABELL, STR_MULTI_OPTION},
|
||||
{MODULE_SUBTYPE_MULTI_H83D, 3, false, false, STR_SUBTYPE_H83D, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_CORONA, 2, false, false, STR_SUBTYPE_CORONA, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_HITEC, 2, false, false, STR_SUBTYPE_HITEC, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_BUGS_MINI, 1, false, false, STR_SUBTYPE_BUGS_MINI, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_TRAXXAS, 0, false, false, STR_SUBTYPE_TRAXXAS, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_E01X, 2, false, false, STR_SUBTYPE_E01X, STR_MULTI_OPTION},
|
||||
{MODULE_SUBTYPE_MULTI_V911S, 0, false, false, NO_SUBTYPE, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_GD00X, 1, false, false, STR_SUBTYPE_GD00X, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_KF606, 0, false, false, NO_SUBTYPE, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_REDPINE, 1, false, false, STR_SUBTYPE_REDPINE, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_POTENSIC, 0, false, false, STR_SUBTYPE_POTENSIC, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_ZSX, 0, false, false, STR_SUBTYPE_ZSX, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_FLYZONE, 0, false, false, STR_SUBTYPE_FLYZONE, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_FRSKYX_RX, 0, false, false, NO_SUBTYPE, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_ESky, 0, false, true, NO_SUBTYPE, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_J6PRO, 0, false, true, NO_SUBTYPE, nullptr},
|
||||
{MM_RF_CUSTOM_SELECTED, 7, true, true, NO_SUBTYPE, STR_MULTI_OPTION},
|
||||
|
||||
// Sentinel and default for protocols not listed above (MM_RF_CUSTOM is 0xff)
|
||||
{0xfe, 0, false, NO_SUBTYPE, nullptr}
|
||||
{0xfe, 0, false, true, NO_SUBTYPE, nullptr}
|
||||
};
|
||||
|
||||
#undef NO_SUBTYPE
|
||||
|
||||
@@ -153,7 +153,7 @@ inline uint8_t MODULE_CHANNELS_ROWS(int moduleIdx)
|
||||
if (!IS_MODULE_ENABLED(moduleIdx))
|
||||
return HIDDEN_ROW;
|
||||
|
||||
if (isModuleDSM2(moduleIdx) || isModuleCrossfire(moduleIdx) || isModuleSBUS(moduleIdx) || (isModuleMultimodule(moduleIdx) && g_model.moduleData[moduleIdx].getMultiProtocol(true) != MODULE_SUBTYPE_MULTI_DSM2))
|
||||
if (isModuleDSM2(moduleIdx) || isModuleCrossfire(moduleIdx) || isModuleSBUS(moduleIdx) || (isModuleMultimodule(moduleIdx) && g_model.moduleData[moduleIdx].getMultiProtocol() != MODULE_SUBTYPE_MULTI_DSM2))
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
@@ -163,17 +163,60 @@ inline uint8_t MODULE_CHANNELS_ROWS(int moduleIdx)
|
||||
#if defined(MULTIMODULE)
|
||||
// When using packed, the pointer in here end up not being aligned, which clang and gcc complain about
|
||||
// Keep the order of the fields that the so that the size stays small
|
||||
struct mm_options_strings {
|
||||
static const char* options[];
|
||||
};
|
||||
|
||||
struct mm_protocol_definition {
|
||||
uint8_t protocol;
|
||||
uint8_t maxSubtype;
|
||||
bool failsafe;
|
||||
bool disable_ch_mapping;
|
||||
const char *subTypeString;
|
||||
const char *optionsstr;
|
||||
};
|
||||
|
||||
const mm_protocol_definition *getMultiProtocolDefinition (uint8_t protocol);
|
||||
#define MULTIMODULE_STATUS_ROWS(moduleIdx) isModuleMultimodule(moduleIdx) ? TITLE_ROW : HIDDEN_ROW, (isModuleMultimodule(moduleIdx) && getMultiSyncStatus(moduleIdx).isValid()) ? TITLE_ROW : HIDDEN_ROW,
|
||||
#define MULTIMODULE_MODULE_ROWS(moduleIdx) isModuleMultimodule(moduleIdx) ? (uint8_t) 0 : HIDDEN_ROW,
|
||||
#define MULTIMODULE_MODE_ROWS(moduleIdx) (g_model.moduleData[moduleIdx].multi.customProto) ? (uint8_t) 3 :MULTIMODULE_HAS_SUBTYPE(g_model.moduleData[moduleIdx].getMultiProtocol(true)) ? (uint8_t)2 : (uint8_t)1
|
||||
|
||||
inline uint8_t getMaxMultiSubtype(uint8_t moduleIdx)
|
||||
{
|
||||
MultiModuleStatus &status = getMultiModuleStatus(moduleIdx);
|
||||
const mm_protocol_definition *pdef = getMultiProtocolDefinition(g_model.moduleData[moduleIdx].getMultiProtocol());
|
||||
|
||||
if (g_model.moduleData[moduleIdx].getMultiProtocol() == MODULE_SUBTYPE_MULTI_FRSKY) {
|
||||
return 5;
|
||||
}
|
||||
|
||||
if (g_model.moduleData[moduleIdx].getMultiProtocol() > MODULE_SUBTYPE_MULTI_LAST) {
|
||||
if (status.isValid())
|
||||
return (status.protocolSubNbr == 0 ? 0 : status.protocolSubNbr - 1);
|
||||
else
|
||||
return 7;
|
||||
}
|
||||
else {
|
||||
return max((uint8_t )(status.protocolSubNbr == 0 ? 0 : status.protocolSubNbr - 1), pdef->maxSubtype);
|
||||
}
|
||||
}
|
||||
|
||||
inline uint8_t MULTI_DISABLE_CHAN_MAP_ROW(uint8_t moduleIdx)
|
||||
{
|
||||
if (!isModuleMultimodule(moduleIdx))
|
||||
return HIDDEN_ROW;
|
||||
|
||||
uint8_t protocol = g_model.moduleData[moduleIdx].getMultiProtocol();
|
||||
if (protocol < MODULE_SUBTYPE_MULTI_LAST) {
|
||||
const mm_protocol_definition * pdef = getMultiProtocolDefinition(protocol);
|
||||
if (pdef->disable_ch_mapping)
|
||||
return 0;
|
||||
}
|
||||
|
||||
MultiModuleStatus &status = getMultiModuleStatus(moduleIdx);
|
||||
if (status.supportsDisableMapping() && status.isValid()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return HIDDEN_ROW;
|
||||
}
|
||||
|
||||
inline bool isMultiProtocolSelectable(int protocol)
|
||||
{
|
||||
@@ -182,19 +225,52 @@ inline bool isMultiProtocolSelectable(int protocol)
|
||||
|
||||
inline bool MULTIMODULE_HAS_SUBTYPE(uint8_t moduleIdx)
|
||||
{
|
||||
return getMultiProtocolDefinition(moduleIdx)->maxSubtype > 0;
|
||||
MultiModuleStatus &status = getMultiModuleStatus(moduleIdx);
|
||||
|
||||
if (g_model.moduleData[moduleIdx].getMultiProtocol() == MODULE_SUBTYPE_MULTI_FRSKY) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (status.isValid()) {
|
||||
return status.protocolSubNbr > 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (g_model.moduleData[moduleIdx].getMultiProtocol() > MODULE_SUBTYPE_MULTI_LAST)
|
||||
return true;
|
||||
else
|
||||
return getMultiProtocolDefinition(g_model.moduleData[moduleIdx].getMultiProtocol())->maxSubtype > 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline uint8_t MULTIMODULE_RFPROTO_COLUMNS(uint8_t moduleIdx)
|
||||
{
|
||||
#if LCD_W < 212
|
||||
return (g_model.moduleData[moduleIdx].multi.customProto ? (uint8_t) 1 : MULTIMODULE_HAS_SUBTYPE(g_model.moduleData[moduleIdx].getMultiProtocol(true)) ? (uint8_t) 0 : HIDDEN_ROW);
|
||||
return (MULTIMODULE_HAS_SUBTYPE(moduleIdx) ? (uint8_t) 0 : HIDDEN_ROW);
|
||||
#else
|
||||
return (g_model.moduleData[moduleIdx].multi.customProto ? (uint8_t) 2 : MULTIMODULE_HAS_SUBTYPE(g_model.moduleData[moduleIdx].getMultiProtocol(true)) ? (uint8_t) 1 : 0);
|
||||
return (MULTIMODULE_HAS_SUBTYPE(moduleIdx) ? (uint8_t) 1 : 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline uint8_t MULTIMODULE_HASOPTIONS(uint8_t moduleIdx)
|
||||
{
|
||||
if (!isModuleMultimodule(moduleIdx))
|
||||
return false;
|
||||
|
||||
uint8_t protocol = g_model.moduleData[moduleIdx].getMultiProtocol();
|
||||
if (protocol < MODULE_SUBTYPE_MULTI_LAST) {
|
||||
return getMultiProtocolDefinition(protocol)->optionsstr != nullptr;
|
||||
}
|
||||
|
||||
MultiModuleStatus &status = getMultiModuleStatus(moduleIdx);
|
||||
return status.optionDisp;
|
||||
}
|
||||
|
||||
#define MULTIMODULE_MODULE_ROWS(moduleIdx) isModuleMultimodule(moduleIdx) ? (uint8_t) 0 : HIDDEN_ROW, isModuleMultimodule(moduleIdx) ? (uint8_t) 0 : HIDDEN_ROW, MULTI_DISABLE_CHAN_MAP_ROW(moduleIdx), // AUTOBIND, DISABLE TELEM, DISABLE CN.MAP
|
||||
#define MULTIMODULE_STATUS_ROWS(moduleIdx) isModuleMultimodule(moduleIdx) ? TITLE_ROW : HIDDEN_ROW, (isModuleMultimodule(moduleIdx) && getMultiSyncStatus(moduleIdx).isValid()) ? TITLE_ROW : HIDDEN_ROW,
|
||||
#define MULTIMODULE_MODE_ROWS(moduleIdx) (g_model.moduleData[moduleIdx].multi.customProto) ? (uint8_t) 3 : MULTIMODULE_HAS_SUBTYPE(moduleIdx) ? (uint8_t)2 : (uint8_t)1
|
||||
#define MULTIMODULE_SUBTYPE_ROWS(moduleIdx) isModuleMultimodule(moduleIdx) ? MULTIMODULE_RFPROTO_COLUMNS(moduleIdx) : HIDDEN_ROW,
|
||||
#define MULTIMODULE_HASOPTIONS(moduleIdx) (getMultiProtocolDefinition(moduleIdx)->optionsstr != nullptr)
|
||||
#define MULTIMODULE_OPTIONS_ROW(moduleIdx) (isModuleMultimodule(moduleIdx) && MULTIMODULE_HASOPTIONS(g_model.moduleData[moduleIdx].getMultiProtocol(true))) ? (uint8_t) 0: HIDDEN_ROW
|
||||
#define MULTIMODULE_OPTIONS_ROW(moduleIdx) (isModuleMultimodule(moduleIdx) && MULTIMODULE_HASOPTIONS(moduleIdx)) ? (uint8_t) 0: HIDDEN_ROW
|
||||
|
||||
#else
|
||||
#define MULTIMODULE_STATUS_ROWS(moduleIdx)
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "stamp.h"
|
||||
#include "lua_api.h"
|
||||
#include "telemetry/frsky.h"
|
||||
#include "telemetry/multi.h"
|
||||
|
||||
#if defined(PCBX12S)
|
||||
#include "lua/lua_exports_x12s.inc" // this line must be after lua headers
|
||||
@@ -442,7 +443,7 @@ When called without parameters, it will only return the status of the output buf
|
||||
|
||||
static int luaSportTelemetryPush(lua_State * L)
|
||||
{
|
||||
if (telemetryProtocol != PROTOCOL_TELEMETRY_FRSKY_SPORT) {
|
||||
if (!IS_FRSKY_SPORT_PROTOCOL()) {
|
||||
lua_pushboolean(L, false);
|
||||
return 1;
|
||||
}
|
||||
@@ -1506,6 +1507,40 @@ static int luaResetGlobalTimer(lua_State * L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*luadoc
|
||||
@function multiBuffer(address[,value])
|
||||
|
||||
This function reads/writes the Multi protocol buffer to interact with a protocol².
|
||||
|
||||
@param address to read/write in the buffer
|
||||
@param (optional): value to write in the buffer
|
||||
|
||||
@retval buffer value (number)
|
||||
|
||||
@status current Introduced in 2.3.2
|
||||
*/
|
||||
#if defined(MULTIMODULE)
|
||||
uint8_t * Multi_Buffer = nullptr;
|
||||
|
||||
static int luaMultiBuffer(lua_State * L)
|
||||
{
|
||||
uint8_t address = luaL_checkunsigned(L, 1);
|
||||
if (!Multi_Buffer)
|
||||
Multi_Buffer = (uint8_t *) malloc(MULTI_BUFFER_SIZE);
|
||||
|
||||
if (!Multi_Buffer || address >= MULTI_BUFFER_SIZE) {
|
||||
lua_pushinteger(L, 0);
|
||||
return 0;
|
||||
}
|
||||
uint16_t value = luaL_optunsigned(L, 2, 0x100);
|
||||
if (value < 0x100) {
|
||||
Multi_Buffer[address] = value;
|
||||
}
|
||||
lua_pushinteger(L, Multi_Buffer[address]);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*luadoc
|
||||
@function serialWrite(str)
|
||||
@param str (string) String to be written to the serial port.
|
||||
@@ -1586,6 +1621,9 @@ const luaL_Reg opentxLib[] = {
|
||||
#if defined(CROSSFIRE)
|
||||
{ "crossfireTelemetryPop", luaCrossfireTelemetryPop },
|
||||
{ "crossfireTelemetryPush", luaCrossfireTelemetryPush },
|
||||
#endif
|
||||
#if defined(MULTIMODULE)
|
||||
{ "multiBuffer", luaMultiBuffer },
|
||||
#endif
|
||||
{ "serialWrite", luaSerialWrite },
|
||||
{ nullptr, nullptr } /* sentinel */
|
||||
|
||||
@@ -1198,6 +1198,7 @@ union ReusableBuffer
|
||||
uint16_t freqMax;
|
||||
uint16_t freqMin;
|
||||
uint8_t dirty;
|
||||
uint8_t moduleOFF;
|
||||
} spectrumAnalyser;
|
||||
|
||||
struct {
|
||||
|
||||
@@ -100,9 +100,8 @@ enum ModuleSubtypeR9M {
|
||||
/* Multi module */
|
||||
|
||||
enum ModuleSubtypeMulti {
|
||||
MODULE_SUBTYPE_MULTI_CUSTOM = -1,
|
||||
MODULE_SUBTYPE_MULTI_FIRST = MODULE_SUBTYPE_MULTI_CUSTOM,
|
||||
MODULE_SUBTYPE_MULTI_FLYSKY=0,
|
||||
MODULE_SUBTYPE_MULTI_FIRST = 0,
|
||||
MODULE_SUBTYPE_MULTI_FLYSKY = MODULE_SUBTYPE_MULTI_FIRST,
|
||||
MODULE_SUBTYPE_MULTI_HUBSAN,
|
||||
MODULE_SUBTYPE_MULTI_FRSKY,
|
||||
MODULE_SUBTYPE_MULTI_HISKY,
|
||||
@@ -158,6 +157,8 @@ enum ModuleSubtypeMulti {
|
||||
MODULE_SUBTYPE_MULTI_AFHDS2A_RX,
|
||||
MODULE_SUBTYPE_MULTI_LAST = MODULE_SUBTYPE_MULTI_AFHDS2A_RX
|
||||
};
|
||||
#define MODULE_SUBTYPE_MULTI_HOTT 57-3
|
||||
#define MODULE_SUBTYPE_MULTI_XN297DP 63-3
|
||||
|
||||
enum MMDSM2Subtypes {
|
||||
MM_RF_DSM2_SUBTYPE_DSM2_22,
|
||||
|
||||
@@ -39,7 +39,7 @@ inline bool isModuleMultimodule(uint8_t idx)
|
||||
|
||||
inline bool isModuleMultimoduleDSM2(uint8_t idx)
|
||||
{
|
||||
return isModuleMultimodule(idx) && g_model.moduleData[idx].getMultiProtocol(true) == MODULE_SUBTYPE_MULTI_DSM2;
|
||||
return isModuleMultimodule(idx) && g_model.moduleData[idx].getMultiProtocol() == MODULE_SUBTYPE_MULTI_DSM2;
|
||||
}
|
||||
#else
|
||||
inline bool isModuleMultimodule(uint8_t)
|
||||
@@ -378,7 +378,15 @@ inline uint8_t getMaxRxNum(uint8_t idx)
|
||||
|
||||
#if defined(MULTIMODULE)
|
||||
if (isModuleMultimodule(idx))
|
||||
return g_model.moduleData[idx].getMultiProtocol(true) == MODULE_SUBTYPE_MULTI_OLRS ? 4 : 15;
|
||||
{
|
||||
switch (g_model.moduleData[idx].getMultiProtocol()) {
|
||||
case MODULE_SUBTYPE_MULTI_OLRS:
|
||||
return 4;
|
||||
case MODULE_SUBTYPE_MULTI_BUGS:
|
||||
case MODULE_SUBTYPE_MULTI_BUGS_MINI:
|
||||
return 15;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 63;
|
||||
|
||||
+153
-45
@@ -19,6 +19,7 @@
|
||||
*/
|
||||
|
||||
#include "opentx.h"
|
||||
#include "multi.h"
|
||||
|
||||
// for the MULTI protocol definition
|
||||
// see https://github.com/pascallanger/DIY-Multiprotocol-TX-Module
|
||||
@@ -31,9 +32,59 @@
|
||||
#define MULTI_CHANS 16
|
||||
#define MULTI_CHAN_BITS 11
|
||||
|
||||
static void sendFrameProtocolHeader(uint8_t moduleIdx, bool failsafe);
|
||||
#define MULTI_NORMAL 0x00
|
||||
#define MULTI_FAILSAFE 0x01
|
||||
#define MULTI_DATA 0x02
|
||||
|
||||
static void sendFrameProtocolHeader(uint8_t moduleIdx, bool failsafe);
|
||||
void sendChannels(uint8_t moduleIdx);
|
||||
#if defined(LUA)
|
||||
static void sendSport(uint8_t moduleIdx);
|
||||
static void sendHott(uint8_t moduleIdx);
|
||||
#endif
|
||||
|
||||
void multiPatchCustom(uint8_t moduleIdx)
|
||||
{
|
||||
if (g_model.moduleData[moduleIdx].multi.customProto) {
|
||||
uint8_t type = g_model.moduleData[moduleIdx].getMultiProtocol() - 1; // custom where starting at 1, otx list at 0
|
||||
int subtype = g_model.moduleData[moduleIdx].subType;
|
||||
|
||||
g_model.moduleData[moduleIdx].multi.customProto = 0;
|
||||
|
||||
if (type == 2) { // multi PROTO_FRSKYD
|
||||
g_model.moduleData[moduleIdx].subType = 1; // D8
|
||||
return;
|
||||
}
|
||||
else if (type == 14) { // multi PROTO_FRSKYX
|
||||
g_model.moduleData[moduleIdx].setMultiProtocol(2);
|
||||
switch (subtype) {
|
||||
case 0: //D16-16
|
||||
g_model.moduleData[moduleIdx].subType = 0;
|
||||
break;
|
||||
case 1: //D16-8
|
||||
g_model.moduleData[moduleIdx].subType = 2;
|
||||
break;
|
||||
case 2: //EU-16
|
||||
g_model.moduleData[moduleIdx].subType = 4;
|
||||
break;
|
||||
case 3: //EU-8
|
||||
g_model.moduleData[moduleIdx].subType = 5;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (type == 24) { // multi PROTO_FRSKYV
|
||||
g_model.moduleData[moduleIdx].setMultiProtocol(2);
|
||||
g_model.moduleData[moduleIdx].subType = 3;
|
||||
return;
|
||||
}
|
||||
if (type > 14)
|
||||
type -= 1;
|
||||
if (type > 24)
|
||||
type -= 1;
|
||||
g_model.moduleData[moduleIdx].setMultiProtocol(type);
|
||||
}
|
||||
}
|
||||
|
||||
static void sendMulti(uint8_t moduleIdx, uint8_t b)
|
||||
{
|
||||
@@ -46,22 +97,6 @@ static void sendMulti(uint8_t moduleIdx, uint8_t b)
|
||||
sendByteSbus(b);
|
||||
}
|
||||
|
||||
static void sendSetupFrame(uint8_t moduleIdx)
|
||||
{
|
||||
// Old multi firmware will mark config messsages as invalid frame and throw them away
|
||||
sendMulti(moduleIdx, 'M');
|
||||
sendMulti(moduleIdx, 'P');
|
||||
sendMulti(moduleIdx, 0x80); // Module Configuration
|
||||
sendMulti(moduleIdx, 1); // 1 byte data
|
||||
uint8_t config = 0x01 | 0x02; // inversion + multi_telemetry
|
||||
#if !defined(PPM_PIN_SERIAL)
|
||||
// TODO why PPM_PIN_SERIAL would change MULTI protocol?
|
||||
config |= 0x04; // input synchronsisation
|
||||
#endif
|
||||
|
||||
sendMulti(moduleIdx, config);
|
||||
}
|
||||
|
||||
static void sendFailsafeChannels(uint8_t moduleIdx)
|
||||
{
|
||||
uint32_t bits = 0;
|
||||
@@ -95,21 +130,64 @@ static void sendFailsafeChannels(uint8_t moduleIdx)
|
||||
void setupPulsesMulti(uint8_t moduleIdx)
|
||||
{
|
||||
static int counter[2] = {0,0}; //TODO
|
||||
static uint8_t invert[2] = {0x00, //internal
|
||||
#if defined(PCBTARANIS) || defined(PCBHORUS)
|
||||
0x08 //external
|
||||
#else
|
||||
0x00 //external
|
||||
#endif
|
||||
};
|
||||
uint8_t type=MULTI_NORMAL;
|
||||
|
||||
// Failsafe packets
|
||||
if (counter[moduleIdx] % 1000 == 0 && g_model.moduleData[moduleIdx].failsafeMode != FAILSAFE_NOT_SET && g_model.moduleData[moduleIdx].failsafeMode != FAILSAFE_RECEIVER) {
|
||||
type|=MULTI_FAILSAFE;
|
||||
}
|
||||
|
||||
// Invert telemetry if needed
|
||||
if (invert[moduleIdx] & 0x80 && !g_model.moduleData[moduleIdx].multi.disableTelemetry) {
|
||||
if (getMultiModuleStatus(moduleIdx).isValid()) {
|
||||
invert[moduleIdx] &= 0x08; // Telemetry received, stop searching
|
||||
}
|
||||
else if (counter[moduleIdx] % 100 == 0) {
|
||||
invert[moduleIdx] ^= 0x08; // Try inverting telemetry
|
||||
}
|
||||
}
|
||||
|
||||
// Every 1000 cycles (=9s) send a config packet that configures the multimodule (inversion, telemetry type)
|
||||
counter[moduleIdx]++;
|
||||
if (counter[moduleIdx] % 1000 == 500) {
|
||||
sendSetupFrame(moduleIdx);
|
||||
}
|
||||
else if (counter[moduleIdx] % 1000 == 0 && g_model.moduleData[moduleIdx].failsafeMode != FAILSAFE_NOT_SET && g_model.moduleData[moduleIdx].failsafeMode != FAILSAFE_RECEIVER) {
|
||||
sendFrameProtocolHeader(moduleIdx, true);
|
||||
|
||||
// Send header
|
||||
sendFrameProtocolHeader(moduleIdx, type&MULTI_FAILSAFE);
|
||||
|
||||
// Send channels
|
||||
if (type & MULTI_FAILSAFE)
|
||||
sendFailsafeChannels(moduleIdx);
|
||||
}
|
||||
else {
|
||||
// Normal Frame
|
||||
sendFrameProtocolHeader(moduleIdx, false);
|
||||
else
|
||||
sendChannels(moduleIdx);
|
||||
|
||||
// Multi V1.3.X.X -> Send byte 26, Protocol (bits 7 & 6), RX_Num (bits 5 & 4), invert, not used, disable telemetry, disable mapping
|
||||
sendMulti(moduleIdx, (uint8_t) (((g_model.moduleData[moduleIdx].getMultiProtocol()+3)&0xC0)
|
||||
| (g_model.header.modelId[moduleIdx] & 0x30)
|
||||
| (invert[moduleIdx] & 0x08)
|
||||
//| 0x04 // Future use
|
||||
| (g_model.moduleData[moduleIdx].multi.disableTelemetry << 1)
|
||||
| g_model.moduleData[moduleIdx].multi.disableMapping));
|
||||
|
||||
// Multi V1.3.X.X -> Send protocol additional data: max 9 bytes
|
||||
#if defined(LUA)
|
||||
if (getMultiModuleStatus(moduleIdx).isValid()) {
|
||||
MultiModuleStatus &status = getMultiModuleStatus(moduleIdx);
|
||||
if (status.minor >= 3 && !(status.flags & 0x80)) { //Version 1.3.x.x or more and Buffer not full
|
||||
// SPort send
|
||||
if (IS_D16_MULTI(moduleIdx) && outputTelemetryBuffer.destination == TELEMETRY_ENDPOINT_SPORT && outputTelemetryBuffer.size) {
|
||||
sendSport(moduleIdx); //8 bytes of additional data
|
||||
}
|
||||
else if (IS_HOTT_MULTI(moduleIdx)) {
|
||||
sendHott(moduleIdx); //1 byte of additional data
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void setupPulsesMultiExternalModule()
|
||||
@@ -166,7 +244,7 @@ void sendFrameProtocolHeader(uint8_t moduleIdx, bool failsafe)
|
||||
{// byte 1+2, protocol information
|
||||
|
||||
// Our enumeration starts at 0
|
||||
int type = g_model.moduleData[moduleIdx].getMultiProtocol(false) + 1;
|
||||
int type = g_model.moduleData[moduleIdx].getMultiProtocol() + 1;
|
||||
int subtype = g_model.moduleData[moduleIdx].subType;
|
||||
int8_t optionValue = g_model.moduleData[moduleIdx].multi.optionValue;
|
||||
|
||||
@@ -186,16 +264,18 @@ void sendFrameProtocolHeader(uint8_t moduleIdx, bool failsafe)
|
||||
protoByte |= MULTI_SEND_RANGECHECK;
|
||||
|
||||
// rfProtocol
|
||||
if (g_model.moduleData[moduleIdx].getMultiProtocol(true) == MODULE_SUBTYPE_MULTI_DSM2) {
|
||||
if (g_model.moduleData[moduleIdx].getMultiProtocol() == MODULE_SUBTYPE_MULTI_DSM2) {
|
||||
|
||||
// Autobinding should always be done in DSMX 11ms
|
||||
if (g_model.moduleData[moduleIdx].multi.autoBindMode && moduleState[moduleIdx].mode == MODULE_MODE_BIND)
|
||||
subtype = MM_RF_DSM2_SUBTYPE_AUTO;
|
||||
|
||||
// Multi module in DSM mode wants the number of channels to be used as option value
|
||||
optionValue = sentModuleChannels(moduleIdx);
|
||||
|
||||
}
|
||||
if (optionValue)
|
||||
optionValue = 0x80 | sentModuleChannels(moduleIdx); // Max throw
|
||||
else
|
||||
optionValue = sentModuleChannels(moduleIdx);
|
||||
}
|
||||
|
||||
// 15 for Multimodule is FrskyX or D16 which we map as a subprotocol of 3 (FrSky)
|
||||
// all protos > frskyx are therefore also off by one
|
||||
@@ -206,7 +286,7 @@ void sendFrameProtocolHeader(uint8_t moduleIdx, bool failsafe)
|
||||
if (type >= 25)
|
||||
type = type + 1;
|
||||
|
||||
if (g_model.moduleData[moduleIdx].getMultiProtocol(true) == MODULE_SUBTYPE_MULTI_FRSKY) {
|
||||
if (g_model.moduleData[moduleIdx].getMultiProtocol() == MODULE_SUBTYPE_MULTI_FRSKY) {
|
||||
if (subtype == MM_RF_FRSKY_SUBTYPE_D8) {
|
||||
//D8
|
||||
type = 3;
|
||||
@@ -230,28 +310,27 @@ void sendFrameProtocolHeader(uint8_t moduleIdx, bool failsafe)
|
||||
|
||||
// Set the highest bit of option byte in AFHDS2A protocol to instruct MULTI to passthrough telemetry bytes instead
|
||||
// of sending Frsky D telemetry
|
||||
if (g_model.moduleData[moduleIdx].getMultiProtocol(false) == MODULE_SUBTYPE_MULTI_FS_AFHDS2A)
|
||||
if (g_model.moduleData[moduleIdx].getMultiProtocol() == MODULE_SUBTYPE_MULTI_FS_AFHDS2A)
|
||||
optionValue = optionValue | 0x80;
|
||||
|
||||
// For custom protocol send unmodified type byte
|
||||
if (g_model.moduleData[moduleIdx].getMultiProtocol(true) == MM_RF_CUSTOM_SELECTED)
|
||||
type = g_model.moduleData[moduleIdx].getMultiProtocol(false);
|
||||
if (g_model.moduleData[moduleIdx].getMultiProtocol() == MM_RF_CUSTOM_SELECTED)
|
||||
type = g_model.moduleData[moduleIdx].getMultiProtocol();
|
||||
|
||||
|
||||
uint8_t headerByte = 0x54;
|
||||
uint8_t headerByte = 0x55;
|
||||
// header, byte 0, 0x55 for proto 0-31, 0x54 for proto 32-63
|
||||
if (type & 0x20)
|
||||
headerByte &= 0xFE;
|
||||
|
||||
if (failsafe)
|
||||
headerByte = 0x56;
|
||||
|
||||
// header, byte 0, 0x55 for proto 0-31 0x54 for 32-63
|
||||
if (type <= 31)
|
||||
sendMulti(moduleIdx, headerByte+1);
|
||||
else
|
||||
sendMulti(moduleIdx, headerByte);
|
||||
headerByte |= 0x02;
|
||||
|
||||
sendMulti(moduleIdx, headerByte);
|
||||
|
||||
// protocol byte
|
||||
protoByte |= (type & 0x1f);
|
||||
if (g_model.moduleData[moduleIdx].getMultiProtocol(true) != MODULE_SUBTYPE_MULTI_DSM2)
|
||||
if (g_model.moduleData[moduleIdx].getMultiProtocol() != MODULE_SUBTYPE_MULTI_DSM2)
|
||||
protoByte |= (g_model.moduleData[moduleIdx].multi.autoBindMode << 6);
|
||||
|
||||
sendMulti(moduleIdx, protoByte);
|
||||
@@ -265,3 +344,32 @@ void sendFrameProtocolHeader(uint8_t moduleIdx, bool failsafe)
|
||||
// byte 3
|
||||
sendMulti(moduleIdx, (uint8_t) optionValue);
|
||||
}
|
||||
|
||||
#if defined(LUA)
|
||||
void sendSport(uint8_t moduleIdx)
|
||||
{
|
||||
// example: B7 30 30 0C 80 00 00 00 13
|
||||
uint8_t j=0;
|
||||
|
||||
// unstuff and remove crc
|
||||
for (uint8_t i = 0; i < outputTelemetryBuffer.size - 1 && j < 8; i++, j++) {
|
||||
if (outputTelemetryBuffer.data[i] == BYTESTUFF) {
|
||||
i++;
|
||||
sendMulti(moduleIdx, outputTelemetryBuffer.data[i] ^ STUFF_MASK);
|
||||
}
|
||||
else {
|
||||
sendMulti(moduleIdx, outputTelemetryBuffer.data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
outputTelemetryBuffer.reset(); // empty buffer
|
||||
}
|
||||
|
||||
void sendHott(uint8_t moduleIdx)
|
||||
{
|
||||
if (Multi_Buffer && memcmp(Multi_Buffer, "HoTT", 4) == 0 && Multi_Buffer[5] >= 0xD7 && Multi_Buffer[5] <= 0xDF) {
|
||||
// HoTT Lua script is running
|
||||
sendMulti(moduleIdx, Multi_Buffer[5]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
|
||||
#include "pulses_common.h"
|
||||
|
||||
void multiPatchCustom(uint8_t moduleIdx);
|
||||
|
||||
class UartMultiPulses: public DataBuffer<uint8_t, 64>
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -158,7 +158,7 @@ void ModelCell::setRfModuleData(uint8_t moduleIdx, ModuleData* modData)
|
||||
}
|
||||
else {
|
||||
// do we care here about MM_RF_CUSTOM_SELECTED? probably not...
|
||||
moduleData[moduleIdx].rfProtocol = modData->getMultiProtocol(false);
|
||||
moduleData[moduleIdx].rfProtocol = modData->getMultiProtocol();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
*/
|
||||
|
||||
#include "opentx.h"
|
||||
#include "pulses/multi.h"
|
||||
|
||||
uint8_t storageDirtyMsk;
|
||||
tmr10ms_t storageDirtyTime10ms;
|
||||
@@ -125,11 +126,19 @@ void postModelLoad(bool alarms)
|
||||
if (!isInternalModuleAvailable(g_model.moduleData[INTERNAL_MODULE].type)) {
|
||||
memclear(&g_model.moduleData[INTERNAL_MODULE], sizeof(ModuleData));
|
||||
}
|
||||
#if defined(MULTIMODULE)
|
||||
else if (isModuleMultimodule(INTERNAL_MODULE))
|
||||
multiPatchCustom(INTERNAL_MODULE);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (!isExternalModuleAvailable(g_model.moduleData[EXTERNAL_MODULE].type)) {
|
||||
memclear(&g_model.moduleData[EXTERNAL_MODULE], sizeof(ModuleData));
|
||||
}
|
||||
#if defined(MULTIMODULE)
|
||||
else if (isModuleMultimodule(EXTERNAL_MODULE))
|
||||
multiPatchCustom(EXTERNAL_MODULE);
|
||||
#endif
|
||||
|
||||
AUDIO_FLUSH();
|
||||
flightReset(false);
|
||||
|
||||
@@ -143,7 +143,7 @@ endif()
|
||||
|
||||
if(MULTIMODULE)
|
||||
add_definitions(-DMULTIMODULE)
|
||||
set(SRC ${SRC} pulses/multi.cpp telemetry/spektrum.cpp telemetry/flysky_ibus.cpp telemetry/hitec.cpp telemetry/multi.cpp io/multi_firmware_update.cpp)
|
||||
set(SRC ${SRC} pulses/multi.cpp telemetry/spektrum.cpp telemetry/flysky_ibus.cpp telemetry/hitec.cpp telemetry/hott.cpp telemetry/multi.cpp io/multi_firmware_update.cpp)
|
||||
endif()
|
||||
|
||||
if(CROSSFIRE)
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "opentx.h"
|
||||
|
||||
/* Telemetry
|
||||
packet[0] = TX RSSI value
|
||||
packet[1] = TX LQI value
|
||||
packet[2] = frame number
|
||||
packet[3-12] telemetry data
|
||||
|
||||
The frame number takes the following values: 0x00, 0x01, 0x02, 0x03 and 0x04. The frames can be present or not, they also do not have to follow each others.
|
||||
Here is a description of the telemetry data for each frame number:
|
||||
- frame 0x00
|
||||
[3] = [12] = ??
|
||||
[4] = RX_Voltage*10 in V
|
||||
[5] = Temperature-20 in °C
|
||||
[6] = RX_RSSI
|
||||
[7] = RX_LQI ??
|
||||
[8] = RX_STR ??
|
||||
[9,10] = [10]*256+[9]=max lost packet time in ms, max value seems 2s=0x7D0
|
||||
[11] = 0x00 ??
|
||||
- frame 0x01 Unknown
|
||||
- frame 0x02 Unknown
|
||||
- frame 0x03 Unknown
|
||||
- frame 0x04 Unknown
|
||||
*/
|
||||
|
||||
struct HottSensor
|
||||
{
|
||||
const uint16_t id;
|
||||
const char * name;
|
||||
const TelemetryUnit unit;
|
||||
const uint8_t precision;
|
||||
};
|
||||
|
||||
// telemetry frames
|
||||
enum
|
||||
{
|
||||
HOTT_FRAME_00 = 0x00,
|
||||
HOTT_FRAME_01 = 0x01,
|
||||
HOTT_FRAME_02 = 0x02,
|
||||
HOTT_FRAME_03 = 0x03,
|
||||
HOTT_FRAME_04 = 0x04,
|
||||
};
|
||||
|
||||
#define HOTT_TELEM_NORMAL 0x00
|
||||
#define HOTT_TELEM_BIND 0x40
|
||||
#define HOTT_TELEM_MENU 0x80
|
||||
|
||||
// telemetry sensors ID
|
||||
enum
|
||||
{
|
||||
HOTT_ID_RX_VOLTAGE = 0x0004,// RX_Batt Voltage
|
||||
HOTT_ID_TEMP1 = 0x0005, // RX Temperature sensor
|
||||
TX_RSSI_ID = 0xFF00, // Pseudo id outside 1 byte range of Hott sensors
|
||||
TX_LQI_ID = 0xFF01, // Pseudo id outside 1 byte range of Hott sensors
|
||||
RX_RSSI_ID = 0xFF02, // Pseudo id outside 1 byte range of Hott sensors
|
||||
RX_LQI_ID = 0xFF03, // Pseudo id outside 1 byte range of Hott sensors
|
||||
};
|
||||
|
||||
const HottSensor hottSensors[] = {
|
||||
//frame 00
|
||||
{HOTT_ID_RX_VOLTAGE, ZSTR_BATT, UNIT_VOLTS, 1}, // RX_Batt Voltage
|
||||
{HOTT_ID_TEMP1, ZSTR_TEMP1, UNIT_CELSIUS, 0}, // RX Temperature sensor
|
||||
//frame 01
|
||||
//frame 02
|
||||
//frame 03
|
||||
//frame 04
|
||||
{TX_RSSI_ID, ZSTR_TX_RSSI, UNIT_RAW, 0}, // Pseudo id outside 1 byte range of Hott sensors
|
||||
{TX_LQI_ID, ZSTR_TX_QUALITY, UNIT_RAW, 0}, // Pseudo id outside 1 byte range of Hott sensors
|
||||
{RX_RSSI_ID, ZSTR_RSSI, UNIT_DB, 0}, // RX RSSI
|
||||
{RX_LQI_ID, ZSTR_RX_QUALITY, UNIT_RAW, 0}, // RX LQI
|
||||
{0x00, NULL, UNIT_RAW, 0}, // sentinel
|
||||
};
|
||||
|
||||
const HottSensor * getHottSensor(uint16_t id)
|
||||
{
|
||||
for (const HottSensor * sensor = hottSensors; sensor->id; sensor++) {
|
||||
if (id == sensor->id)
|
||||
return sensor;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void processHottPacket(const uint8_t * packet)
|
||||
{
|
||||
// Set TX RSSI Value
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, TX_RSSI_ID, 0, 0, packet[0]>>1, UNIT_RAW, 0);
|
||||
// Set TX LQI Value
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, TX_LQI_ID, 0, 0, packet[1], UNIT_RAW, 0);
|
||||
|
||||
#if defined(LUA)
|
||||
#define HOTT_MENU_NBR_PAGE 0x13
|
||||
// Config menu consists of the different telem pages put all together
|
||||
// [3] = config mennu page 0x00 to 0x12.
|
||||
// Page X [4] = seems like all the telem pages with the same value are going together to make the full config menu text. Seen so far 'a', 'b', 'c', 'd'
|
||||
// Page X [5..13] = 9 ascii chars to be displayed, char is highlighted when ascii|0x80
|
||||
// Screen display is 21 characters large which means that once the first 21 chars are filled go to the begining of the next line
|
||||
// Menu commands are sent through TX packets:
|
||||
// packet[28]= 0xXF=>no key press, 0xXD=>down, 0xXB=>up, 0xX9=>enter, 0xXE=>right, 0xX7=>left with X=0 or D
|
||||
// packet[29]= 0xX1/0xX9 with X=0 or X counting 0,1,1,2,2,..,9,9
|
||||
if (Multi_Buffer && memcmp(Multi_Buffer, "HoTT", 4) == 0) {
|
||||
// HoTT Lua script is running
|
||||
if (Multi_Buffer[4] == 0xFF) {
|
||||
// Init
|
||||
memset(&Multi_Buffer[6], ' ', HOTT_MENU_NBR_PAGE * 9); // Clear text buffer
|
||||
}
|
||||
|
||||
if (packet[3] < HOTT_MENU_NBR_PAGE && Multi_Buffer[5] >= 0xD7 && Multi_Buffer[5] <= 0xDF) {
|
||||
Multi_Buffer[4] = packet[4]; // Store current menu being received
|
||||
memcpy(&Multi_Buffer[6 + packet[3] * 9], &packet[5], 9); // Store the received page in the buffer
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
const HottSensor * sensor;
|
||||
int32_t value;
|
||||
|
||||
if (packet[2] == HOTT_TELEM_NORMAL) {
|
||||
switch (packet[3]) {
|
||||
case HOTT_FRAME_00:
|
||||
// RX_VOLT
|
||||
value = packet[5];
|
||||
sensor = getHottSensor(HOTT_ID_RX_VOLTAGE);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_RX_VOLTAGE, 0, 0, value, sensor->unit, sensor->precision);
|
||||
// RX_TEMP
|
||||
value = packet[6] - 20;
|
||||
sensor = getHottSensor(HOTT_ID_TEMP1);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, HOTT_ID_TEMP1, 0, 0, value, sensor->unit, sensor->precision);
|
||||
// RX_RSSI
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, RX_RSSI_ID, 0, 0, packet[7], UNIT_DB, 0);
|
||||
// RX_LQI
|
||||
telemetryData.rssi.set(packet[8]);
|
||||
if (packet[8] > 0)
|
||||
telemetryStreaming = TELEMETRY_TIMEOUT10ms;
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, RX_LQI_ID, 0, 0, packet[8], UNIT_RAW, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
// unknown
|
||||
value = (packet[7] << 24) | (packet[6] << 16) | (packet[5] << 8) | packet[4];
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_HOTT, 0xFE00 | packet[3], 0, 0, value, UNIT_RAW, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void hottSetDefault(int index, uint16_t id, uint8_t subId, uint8_t instance)
|
||||
{
|
||||
TelemetrySensor &telemetrySensor = g_model.telemetrySensors[index];
|
||||
telemetrySensor.id = id;
|
||||
telemetrySensor.subId = subId;
|
||||
telemetrySensor.instance = instance;
|
||||
|
||||
const HottSensor * sensor = getHottSensor(id);
|
||||
if (sensor) {
|
||||
TelemetryUnit unit = sensor->unit;
|
||||
uint8_t prec = min<uint8_t>(2, sensor->precision);
|
||||
telemetrySensor.init(sensor->name, unit, prec);
|
||||
if (unit == UNIT_RPMS) {
|
||||
telemetrySensor.custom.ratio = 1;
|
||||
telemetrySensor.custom.offset = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
telemetrySensor.init(id);
|
||||
}
|
||||
|
||||
storageDirty(EE_MODEL);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _HOTT_H
|
||||
#define _HOTT_H
|
||||
|
||||
void hottSetDefault(int index, uint16_t id, uint8_t subId, uint8_t instance);
|
||||
|
||||
// Used by multi protocol
|
||||
void processHottPacket(const uint8_t * packet);
|
||||
|
||||
#endif
|
||||
+124
-67
@@ -39,7 +39,8 @@ enum MultiPacketTypes : uint8_t
|
||||
HitecTelemetry,
|
||||
SpectrumScannerPacket,
|
||||
FlyskyIBusTelemetryAC,
|
||||
MultiRxChannels
|
||||
MultiRxChannels,
|
||||
HottTelemetry,
|
||||
};
|
||||
|
||||
enum MultiBufferState : uint8_t
|
||||
@@ -65,6 +66,7 @@ static MultiModuleSyncStatus multiSyncStatus[NUM_MODULES] = {MultiModuleSyncStat
|
||||
static uint8_t multiBindStatus[NUM_MODULES] = {MULTI_NORMAL_OPERATION, MULTI_NORMAL_OPERATION};
|
||||
|
||||
static MultiBufferState multiTelemetryBufferState[NUM_MODULES];
|
||||
static uint16_t multiTelemetryLastRxTS[NUM_MODULES];
|
||||
|
||||
MultiModuleStatus &getMultiModuleStatus(uint8_t module)
|
||||
{
|
||||
@@ -96,6 +98,11 @@ void setMultiTelemetryBufferState(uint8_t module, MultiBufferState state)
|
||||
multiTelemetryBufferState[module] = state;
|
||||
}
|
||||
|
||||
static uint16_t& getMultiTelemetryLastRxTS(uint8_t module)
|
||||
{
|
||||
return multiTelemetryLastRxTS[module];
|
||||
}
|
||||
|
||||
// Use additional telemetry buffer
|
||||
uint8_t intTelemetryRxBuffer[TELEMETRY_RX_PACKET_SIZE];
|
||||
uint8_t intTelemetryRxBufferCount;
|
||||
@@ -107,6 +114,7 @@ static MultiModuleSyncStatus multiSyncStatus;
|
||||
static uint8_t multiBindStatus = MULTI_NORMAL_OPERATION;
|
||||
|
||||
static MultiBufferState multiTelemetryBufferState;
|
||||
static uint16_t multiTelemetryLastRxTS;
|
||||
|
||||
MultiModuleStatus& getMultiModuleStatus(uint8_t)
|
||||
{
|
||||
@@ -138,6 +146,11 @@ void setMultiTelemetryBufferState(uint8_t, MultiBufferState state)
|
||||
multiTelemetryBufferState = state;
|
||||
}
|
||||
|
||||
uint16_t& getMultiTelemetryLastRxTS(uint8_t module)
|
||||
{
|
||||
return multiTelemetryLastRxTS;
|
||||
}
|
||||
|
||||
#endif // INTERNAL_MODULE_MULTI
|
||||
|
||||
|
||||
@@ -150,9 +163,9 @@ static MultiBufferState guessProtocol(uint8_t module)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (g_model.moduleData[moduleIdx].getMultiProtocol(false) == MODULE_SUBTYPE_MULTI_DSM2)
|
||||
if (g_model.moduleData[moduleIdx].getMultiProtocol() == MODULE_SUBTYPE_MULTI_DSM2)
|
||||
return SpektrumTelemetryFallback;
|
||||
else if (g_model.moduleData[module].getMultiProtocol(false) == MODULE_SUBTYPE_MULTI_FS_AFHDS2A)
|
||||
else if (g_model.moduleData[module].getMultiProtocol() == MODULE_SUBTYPE_MULTI_FS_AFHDS2A)
|
||||
return FlyskyTelemetryFallback;
|
||||
else
|
||||
return FrskyTelemetryFallback;
|
||||
@@ -196,20 +209,38 @@ static void processMultiScannerPacket(const uint8_t *data)
|
||||
}
|
||||
}
|
||||
|
||||
static void processMultiStatusPacket(const uint8_t * data, uint8_t module)
|
||||
static void processMultiStatusPacket(const uint8_t * data, uint8_t module, uint8_t len)
|
||||
{
|
||||
MultiModuleStatus &status = getMultiModuleStatus(module);
|
||||
|
||||
// At least two status packets without bind flag
|
||||
bool wasBinding = status.isBinding();
|
||||
|
||||
status.lastUpdate = get_tmr10ms();
|
||||
status.flags = data[0];
|
||||
status.major = data[1];
|
||||
status.minor = data[2];
|
||||
status.revision = data[3];
|
||||
status.patch = data[4];
|
||||
status.lastUpdate = get_tmr10ms();
|
||||
|
||||
if (len < 6) {
|
||||
status.ch_order = 0xFF;
|
||||
}
|
||||
else {
|
||||
status.ch_order = data[5];
|
||||
if (len >= 24) {
|
||||
status.protocolNext = data[6];
|
||||
status.protocolPrev = data[7];
|
||||
memcpy(status.protocolName, &data[8], 7);
|
||||
status.protocolName[7] = 0;
|
||||
status.protocolSubNbr = data[15] & 0x0F;
|
||||
memcpy(status.protocolSubName, &data[16], 8);
|
||||
status.protocolSubName[8] = 0;
|
||||
status.optionDisp = data[15] >> 4;
|
||||
}
|
||||
else {
|
||||
status.protocolName[0] = 0;
|
||||
}
|
||||
}
|
||||
if (getMultiModuleStatus(module).requiresFailsafeCheck) {
|
||||
getMultiModuleStatus(module).requiresFailsafeCheck = false;
|
||||
if (getMultiModuleStatus(module).supportsFailsafe() && g_model.moduleData[module].failsafeMode == FAILSAFE_NOT_SET)
|
||||
@@ -289,7 +320,7 @@ static void processMultiTelemetryPaket(const uint8_t * packet, uint8_t module)
|
||||
switch (type) {
|
||||
case MultiStatus:
|
||||
if (len >= 5)
|
||||
processMultiStatusPacket(data, module);
|
||||
processMultiStatusPacket(data, module, len);
|
||||
break;
|
||||
|
||||
case DSMBindPacket:
|
||||
@@ -327,6 +358,13 @@ static void processMultiTelemetryPaket(const uint8_t * packet, uint8_t module)
|
||||
TRACE("[MP] Received Hitec telemetry len %d < 8", len);
|
||||
break;
|
||||
|
||||
case HottTelemetry:
|
||||
if (len >= 14)
|
||||
processHottPacket(data);
|
||||
else
|
||||
TRACE("[MP] Received HoTT telemetry len %d < 14", len);
|
||||
break;
|
||||
|
||||
case FrSkyHubTelemetry:
|
||||
if (len >= 4)
|
||||
frskyDProcessPacket(data);
|
||||
@@ -382,17 +420,7 @@ static void processMultiTelemetryPaket(const uint8_t * packet, uint8_t module)
|
||||
}
|
||||
}
|
||||
|
||||
// sprintf does not work AVR ARM
|
||||
// use a small helper function
|
||||
static void appendInt(char * buf, uint32_t val)
|
||||
{
|
||||
while (*buf)
|
||||
buf++;
|
||||
|
||||
strAppendUnsigned(buf, val);
|
||||
}
|
||||
|
||||
#define MIN_REFRESH_RATE 7000
|
||||
#define MIN_REFRESH_RATE 5500
|
||||
|
||||
void MultiModuleSyncStatus::calcAdjustedRefreshRate(uint16_t newRefreshRate, uint16_t newInputLag)
|
||||
{
|
||||
@@ -444,8 +472,8 @@ void MultiModuleSyncStatus::calcAdjustedRefreshRate(uint16_t newRefreshRate, uin
|
||||
adjustedRefreshRate = (adjustedRefreshRate + perframeps);
|
||||
|
||||
// Safeguards
|
||||
if (adjustedRefreshRate < 6 * 1000 * 1000)
|
||||
adjustedRefreshRate = 6 * 1000 * 1000;
|
||||
if (adjustedRefreshRate < MIN_REFRESH_RATE * 1000)
|
||||
adjustedRefreshRate = MIN_REFRESH_RATE * 1000;
|
||||
if (adjustedRefreshRate > 30 * 1000 * 1000)
|
||||
adjustedRefreshRate = 30 * 1000 * 1000;
|
||||
|
||||
@@ -454,12 +482,11 @@ void MultiModuleSyncStatus::calcAdjustedRefreshRate(uint16_t newRefreshRate, uin
|
||||
|
||||
static uint8_t counter;
|
||||
|
||||
uint16_t MultiModuleSyncStatus::getAdjustedRefreshRate()
|
||||
const uint16_t MultiModuleSyncStatus::getAdjustedRefreshRate()
|
||||
{
|
||||
if (!isValid() || refreshRate == 0)
|
||||
return 18000;
|
||||
|
||||
|
||||
counter = (uint8_t) (counter + 1 % 10);
|
||||
uint16_t rate = (uint16_t) ((adjustedRefreshRate + counter * 50) / 500);
|
||||
// Check how far off we are from our target, positive means we are too slow, negative we are too fast
|
||||
@@ -471,37 +498,27 @@ uint16_t MultiModuleSyncStatus::getAdjustedRefreshRate()
|
||||
return rate;
|
||||
}
|
||||
|
||||
|
||||
static void prependSpaces(char * buf, int val)
|
||||
{
|
||||
while (*buf)
|
||||
buf++;
|
||||
|
||||
int k = 10000;
|
||||
while (val / k == 0 && k > 0) {
|
||||
*buf = ' ';
|
||||
buf++;
|
||||
k /= 10;
|
||||
}
|
||||
*buf = '\0';
|
||||
}
|
||||
|
||||
void MultiModuleSyncStatus::getRefreshString(char * statusText)
|
||||
{
|
||||
if (!isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy(statusText, "L ");
|
||||
prependSpaces(statusText, inputLag);
|
||||
appendInt(statusText, inputLag);
|
||||
strcat(statusText, "ns R ");
|
||||
prependSpaces(statusText, adjustedRefreshRate / 1000);
|
||||
appendInt(statusText, (uint32_t) (adjustedRefreshRate / 1000));
|
||||
strcat(statusText, "ns");
|
||||
char * tmp = statusText;
|
||||
#if defined(DEBUG)
|
||||
*tmp++ = 'L';
|
||||
tmp = strAppendUnsigned(tmp, inputLag, 5);
|
||||
tmp = strAppend(tmp, "us R ");
|
||||
tmp = strAppendUnsigned(tmp, (uint32_t) (adjustedRefreshRate / 1000), 5);
|
||||
tmp = strAppend(tmp, "us");
|
||||
#else
|
||||
tmp = strAppend(tmp, "Sync at ");
|
||||
tmp = strAppendUnsigned(tmp, (uint32_t) (adjustedRefreshRate / 1000000));
|
||||
tmp = strAppend(tmp, " ms");
|
||||
#endif
|
||||
}
|
||||
|
||||
void MultiModuleStatus::getStatusString(char * statusText)
|
||||
void MultiModuleStatus::getStatusString(char * statusText) const
|
||||
{
|
||||
if (!isValid()) {
|
||||
#if defined(PCBTARANIS) || defined(PCBHORUS)
|
||||
@@ -531,19 +548,46 @@ void MultiModuleStatus::getStatusString(char * statusText)
|
||||
return;
|
||||
}
|
||||
|
||||
if (major == 1 && minor < 3 && SLOW_BLINK_ON_PHASE) {
|
||||
strcpy(statusText, STR_MODULE_UPGRADE);
|
||||
}
|
||||
else {
|
||||
char * tmp = statusText;
|
||||
*tmp++ = 'V';
|
||||
tmp = strAppendUnsigned(tmp, major);
|
||||
*tmp++ = '.';
|
||||
tmp = strAppendUnsigned(tmp, minor);
|
||||
*tmp++ = '.';
|
||||
tmp = strAppendUnsigned(tmp, revision);
|
||||
*tmp++ = '.';
|
||||
tmp = strAppendUnsigned(tmp, patch);
|
||||
|
||||
strcpy(statusText, "V");
|
||||
appendInt(statusText, major);
|
||||
strcat(statusText, ".");
|
||||
appendInt(statusText, minor);
|
||||
strcat(statusText, ".");
|
||||
appendInt(statusText, revision);
|
||||
strcat(statusText, ".");
|
||||
appendInt(statusText, patch);
|
||||
strcat(statusText, " ");
|
||||
|
||||
if (isBinding())
|
||||
strcat(statusText, STR_MODULE_BINDING);
|
||||
if (isBinding()) {
|
||||
strcpy(tmp, " " TR_MODULE_BINDING);
|
||||
}
|
||||
else if (ch_order != 0xFF) {
|
||||
uint8_t temp = ch_order;
|
||||
*tmp++ = ' ';
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
switch (temp & 0x03) {
|
||||
case 0:
|
||||
*tmp++ = 'A';
|
||||
break;
|
||||
case 1:
|
||||
*tmp++ = 'E';
|
||||
break;
|
||||
case 2:
|
||||
*tmp++ = 'T';
|
||||
break;
|
||||
case 3:
|
||||
*tmp++ = 'R';
|
||||
break;
|
||||
}
|
||||
temp >>= 2;
|
||||
}
|
||||
*tmp = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t * getRxBuffer(uint8_t moduleIdx)
|
||||
@@ -600,7 +644,14 @@ void processMultiTelemetryData(uint8_t data, uint8_t module)
|
||||
uint8_t * rxBuffer = getRxBuffer(module);
|
||||
uint8_t &rxBufferCount = getRxBufferCount(module);
|
||||
|
||||
//debugPrintf("State: %d, byte received %02X, buflen: %d\r\n", multiTelemetryBufferState, data, rxBufferCount);
|
||||
uint16_t &lastRxTS = getMultiTelemetryLastRxTS(module);
|
||||
uint16_t nowMs = (uint16_t)RTOS_GET_MS();
|
||||
if (nowMs - lastRxTS > 15)
|
||||
setMultiTelemetryBufferState(module, NoProtocolDetected);
|
||||
lastRxTS = nowMs;
|
||||
|
||||
// debugPrintf("State: %d, byte received %02X, buflen: %d\r\n", getMultiTelemetryBufferState(module), data, rxBufferCount);
|
||||
|
||||
switch (getMultiTelemetryBufferState(module)) {
|
||||
case NoProtocolDetected:
|
||||
if (data == 'M') {
|
||||
@@ -691,16 +742,22 @@ void processMultiTelemetryData(uint8_t data, uint8_t module)
|
||||
break;
|
||||
|
||||
case ReceivingMultiStatus:
|
||||
rxBuffer[rxBufferCount++] = data;
|
||||
if (rxBufferCount > 5 && rxBuffer[0] == rxBufferCount - 1) {
|
||||
processMultiStatusPacket(rxBuffer + 1, module);
|
||||
rxBufferCount = 0;
|
||||
setMultiTelemetryBufferState(module, NoProtocolDetected);
|
||||
if (rxBufferCount < TELEMETRY_RX_PACKET_SIZE) {
|
||||
rxBuffer[rxBufferCount++] = data;
|
||||
if (rxBufferCount > 5 && rxBuffer[0] == rxBufferCount - 1) {
|
||||
processMultiStatusPacket(rxBuffer + 1, module, rxBuffer[0]);
|
||||
rxBufferCount = 0;
|
||||
setMultiTelemetryBufferState(module, NoProtocolDetected);
|
||||
}
|
||||
if (rxBufferCount > 24) {
|
||||
// too long ignore
|
||||
TRACE("Overlong multi status packet detected ignoring, wanted %d", rxBuffer[0]);
|
||||
rxBufferCount = 0;
|
||||
setMultiTelemetryBufferState(module, NoProtocolDetected);
|
||||
}
|
||||
}
|
||||
if (rxBufferCount > 10) {
|
||||
// too long ignore
|
||||
TRACE("Overlong multi status packet detected ignoring, wanted %d", rxBuffer[0]);
|
||||
rxBufferCount = 0;
|
||||
else {
|
||||
TRACE("[MP] array size %d error", rxBufferCount);
|
||||
setMultiTelemetryBufferState(module, NoProtocolDetected);
|
||||
}
|
||||
break;
|
||||
|
||||
+22
-11
@@ -21,6 +21,9 @@
|
||||
#ifndef OPENTX_MULTI_H
|
||||
#define OPENTX_MULTI_H
|
||||
|
||||
#define MULTI_BUFFER_SIZE 177
|
||||
extern uint8_t * Multi_Buffer;
|
||||
|
||||
/*
|
||||
Multiprotocol telemetry definition
|
||||
|
||||
@@ -93,23 +96,21 @@ void processMultiTelemetryData(uint8_t data, uint8_t module);
|
||||
|
||||
// This should be put into the Module definition if other modules gain this functionality
|
||||
struct MultiModuleSyncStatus {
|
||||
uint32_t adjustedRefreshRate; // in ps
|
||||
uint32_t adjustedRefreshRate = 9000 * 1000; // in ps
|
||||
tmr10ms_t lastUpdate;
|
||||
uint16_t refreshRate;
|
||||
uint16_t inputLag;
|
||||
uint8_t interval;
|
||||
uint8_t target;
|
||||
|
||||
inline bool isValid() {return (get_tmr10ms() - lastUpdate < 100);}
|
||||
void getRefreshString(char* refreshText);
|
||||
uint16_t getAdjustedRefreshRate();
|
||||
void calcAdjustedRefreshRate(uint16_t newRefreshRate, uint16_t newInputLag);
|
||||
|
||||
MultiModuleSyncStatus() {
|
||||
// Initialise to a valid value
|
||||
adjustedRefreshRate=9000 * 1000;
|
||||
inline bool isValid() const
|
||||
{
|
||||
return (get_tmr10ms() - lastUpdate < 100);
|
||||
}
|
||||
|
||||
|
||||
void getRefreshString(char * refreshText);
|
||||
const uint16_t getAdjustedRefreshRate();
|
||||
void calcAdjustedRefreshRate(uint16_t newRefreshRate, uint16_t newInputLag);
|
||||
};
|
||||
|
||||
MultiModuleSyncStatus& getMultiSyncStatus(uint8_t module);
|
||||
@@ -121,14 +122,24 @@ struct MultiModuleStatus {
|
||||
uint8_t minor;
|
||||
uint8_t revision;
|
||||
uint8_t patch;
|
||||
uint8_t ch_order;
|
||||
|
||||
uint8_t flags;
|
||||
uint8_t requiresFailsafeCheck;
|
||||
tmr10ms_t lastUpdate;
|
||||
|
||||
void getStatusString(char* statusText);
|
||||
uint8_t protocolPrev = 0;
|
||||
uint8_t protocolNext = 0;
|
||||
char protocolName[8] = {0};
|
||||
uint8_t protocolSubNbr = 0;
|
||||
char protocolSubName[9] = {0};
|
||||
uint8_t optionDisp = 0;
|
||||
|
||||
void getStatusString(char * statusText) const;
|
||||
|
||||
inline bool isValid() const { return (bool)(get_tmr10ms() - lastUpdate < 200); }
|
||||
inline bool isBufferFull() const { return (bool) (flags & 0x80); }
|
||||
inline bool supportsDisableMapping() const { return (bool) (flags & 0x40); }
|
||||
inline bool supportsFailsafe() const { return (bool) (flags & 0x20); }
|
||||
inline bool isWaitingforBind() const { return (bool) (flags & 0x10); }
|
||||
inline bool isBinding() const { return (bool) (flags & 0x08); }
|
||||
|
||||
@@ -373,7 +373,7 @@ void processSpektrumPacket(const uint8_t *packet)
|
||||
void processDSMBindPacket(uint8_t module, const uint8_t *packet)
|
||||
{
|
||||
uint32_t debugval;
|
||||
if (g_model.moduleData[module].type == MODULE_TYPE_MULTIMODULE && g_model.moduleData[module].getMultiProtocol(true) == MODULE_SUBTYPE_MULTI_DSM2
|
||||
if (g_model.moduleData[module].type == MODULE_TYPE_MULTIMODULE && g_model.moduleData[module].getMultiProtocol() == MODULE_SUBTYPE_MULTI_DSM2
|
||||
&& g_model.moduleData[module].multi.autoBindMode) {
|
||||
|
||||
int channels = packet[5];
|
||||
@@ -399,7 +399,7 @@ void processDSMBindPacket(uint8_t module, const uint8_t *packet)
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_SPEKTRUM, (I2C_PSEUDO_TX << 8) + 4, 0, 0, debugval, UNIT_RAW, 0);
|
||||
|
||||
/* Finally stop binding as the rx just told us that it is bound */
|
||||
if (g_model.moduleData[module].type == MODULE_TYPE_MULTIMODULE && g_model.moduleData[module].getMultiProtocol(true) == MODULE_SUBTYPE_MULTI_DSM2 && moduleState[module].mode == MODULE_MODE_BIND) {
|
||||
if (g_model.moduleData[module].type == MODULE_TYPE_MULTIMODULE && g_model.moduleData[module].getMultiProtocol() == MODULE_SUBTYPE_MULTI_DSM2 && moduleState[module].mode == MODULE_MODE_BIND) {
|
||||
setMultiBindStatus(module, MULTI_BIND_FINISHED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "spektrum.h"
|
||||
#include "flysky_ibus.h"
|
||||
#include "hitec.h"
|
||||
#include "hott.h"
|
||||
#include "multi.h"
|
||||
#endif
|
||||
|
||||
@@ -104,8 +105,13 @@ void frskyDSetDefault(int index, uint16_t id);
|
||||
extern uint8_t telemetryProtocol;
|
||||
|
||||
#if defined (MULTIMODULE)
|
||||
#define IS_D16_MULTI() ((g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false) == MODULE_SUBTYPE_MULTI_FRSKY) && (g_model.moduleData[EXTERNAL_MODULE].subType == MM_RF_FRSKY_SUBTYPE_D16 || g_model.moduleData[EXTERNAL_MODULE].subType == MM_RF_FRSKY_SUBTYPE_D16_8CH))
|
||||
#define IS_FRSKY_SPORT_PROTOCOL() (telemetryProtocol == PROTOCOL_TELEMETRY_FRSKY_SPORT || (telemetryProtocol == PROTOCOL_TELEMETRY_MULTIMODULE && IS_D16_MULTI()))
|
||||
#define IS_D16_MULTI(module) ((g_model.moduleData[module].getMultiProtocol() == MODULE_SUBTYPE_MULTI_FRSKY) && (g_model.moduleData[module].subType == MM_RF_FRSKY_SUBTYPE_D16 || g_model.moduleData[module].subType == MM_RF_FRSKY_SUBTYPE_D16_8CH || g_model.moduleData[module].subType == MM_RF_FRSKY_SUBTYPE_D16_LBT || g_model.moduleData[module].subType == MM_RF_FRSKY_SUBTYPE_D16_LBT_8CH))
|
||||
#define IS_HOTT_MULTI(module) (g_model.moduleData[module].getMultiProtocol() == MODULE_SUBTYPE_MULTI_HOTT)
|
||||
#if defined(HARDWARE_INTERNAL_MODULE)
|
||||
#define IS_FRSKY_SPORT_PROTOCOL() (telemetryProtocol == PROTOCOL_TELEMETRY_FRSKY_SPORT || (telemetryProtocol == PROTOCOL_TELEMETRY_MULTIMODULE && (IS_D16_MULTI(INTERNAL_MODULE)||IS_D16_MULTI(EXTERNAL_MODULE))))
|
||||
#else
|
||||
#define IS_FRSKY_SPORT_PROTOCOL() (telemetryProtocol == PROTOCOL_TELEMETRY_FRSKY_SPORT || (telemetryProtocol == PROTOCOL_TELEMETRY_MULTIMODULE && IS_D16_MULTI(EXTERNAL_MODULE)))
|
||||
#endif
|
||||
#else
|
||||
#define IS_FRSKY_SPORT_PROTOCOL() (telemetryProtocol == PROTOCOL_TELEMETRY_FRSKY_SPORT)
|
||||
#endif
|
||||
|
||||
@@ -530,6 +530,9 @@ int setTelemetryValue(TelemetryProtocol protocol, uint16_t id, uint8_t subId, ui
|
||||
case PROTOCOL_TELEMETRY_HITEC:
|
||||
hitecSetDefault(index, id, subId, instance);
|
||||
break;
|
||||
case PROTOCOL_TELEMETRY_HOTT:
|
||||
hottSetDefault(index, id, subId, instance);
|
||||
break;
|
||||
#endif
|
||||
#if defined(LUA)
|
||||
case PROTOCOL_TELEMETRY_LUA:
|
||||
|
||||
@@ -665,6 +665,8 @@ const char STR_MULTI_VIDFREQ[] = TR_MULTI_VIDFREQ;
|
||||
const char STR_MULTI_OPTION[] = TR_MULTI_OPTION;
|
||||
const char STR_MULTI_FIXEDID[] = TR_MULTI_FIXEDID;
|
||||
const char STR_MULTI_AUTOBIND[] = TR_MULTI_AUTOBIND;
|
||||
const char STR_DISABLE_CH_MAP[] = TR_DISABLE_CH_MAP;
|
||||
const char STR_DISABLE_TELEM[] = TR_DISABLE_TELEM;
|
||||
const char STR_MULTI_DSM_AUTODTECT[] = TR_MULTI_DSM_AUTODTECT;
|
||||
const char STR_MULTI_LOWPOWER[] = TR_MULTI_LOWPOWER;
|
||||
const char STR_MODULE_NO_SERIAL_MODE[] = TR_MODULE_NO_SERIAL_MODE;
|
||||
@@ -672,10 +674,13 @@ const char STR_MODULE_NO_INPUT[] = TR_MODULE_NO_INPUT;
|
||||
const char STR_MODULE_WAITFORBIND[] = TR_MODULE_WAITFORBIND;
|
||||
const char STR_MODULE_NO_TELEMETRY[] = TR_MODULE_NO_TELEMETRY;
|
||||
const char STR_MODULE_BINDING[] = TR_MODULE_BINDING;
|
||||
const char STR_MODULE_UPGRADE[] = TR_MODULE_UPGRADE;
|
||||
const char STR_PROTOCOL_INVALID[] = TR_PROTOCOL_INVALID;
|
||||
const char STR_MODULE_STATUS[] = TR_MODULE_STATUS;
|
||||
const char STR_MODULE_SYNC[] = TR_MODULE_SYNC;
|
||||
const char STR_MULTI_SERVOFREQ[] = TR_MULTI_SERVOFREQ;
|
||||
const char STR_MULTI_MAX_THROW[] = TR_MULTI_MAX_THROW;
|
||||
const char STR_MULTI_RFCHAN[] = TR_MULTI_RFCHAN;
|
||||
const char STR_NEEDS_FILE[] = TR_NEEDS_FILE;
|
||||
const char STR_EXT_MULTI_SPEC[] = TR_EXT_MULTI_SPEC;
|
||||
const char STR_INT_MULTI_SPEC[] = TR_INT_MULTI_SPEC;
|
||||
|
||||
@@ -390,6 +390,8 @@ extern const char STR_MULTI_VIDFREQ[];
|
||||
extern const char STR_MULTI_RFTUNE[];
|
||||
extern const char STR_MULTI_TELEMETRY[];
|
||||
extern const char STR_MULTI_AUTOBIND[];
|
||||
extern const char STR_DISABLE_CH_MAP[];
|
||||
extern const char STR_DISABLE_TELEM[];
|
||||
extern const char STR_MULTI_DSM_AUTODTECT[];
|
||||
extern const char STR_MULTI_LOWPOWER[];
|
||||
extern const char STR_MODULE_NO_SERIAL_MODE[];
|
||||
@@ -397,10 +399,13 @@ extern const char STR_MODULE_NO_INPUT[];
|
||||
extern const char STR_MODULE_WAITFORBIND[];
|
||||
extern const char STR_MODULE_NO_TELEMETRY[];
|
||||
extern const char STR_MODULE_BINDING[];
|
||||
extern const char STR_MODULE_UPGRADE[];
|
||||
extern const char STR_PROTOCOL_INVALID[];
|
||||
extern const char STR_MODULE_STATUS[];
|
||||
extern const char STR_MODULE_SYNC[];
|
||||
extern const char STR_MULTI_SERVOFREQ[];
|
||||
extern const char STR_MULTI_MAX_THROW[];
|
||||
extern const char STR_MULTI_RFCHAN[];
|
||||
#if LCD_W < 212
|
||||
extern const char STR_SUBTYPE[];
|
||||
#endif
|
||||
|
||||
@@ -630,7 +630,9 @@
|
||||
#define TR_RFPOWER INDENT "Výkon RF"
|
||||
#define TR_MULTI_FIXEDID TR("FixedID", "Fixed ID")
|
||||
#define TR_MULTI_OPTION TR(INDENT "Možnosti", INDENT "Hodnota")
|
||||
#define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind při zapnutí")
|
||||
#define TR_MULTI_AUTOBIND TR(INDENT "Bind Ch.",INDENT "Bind při zapnutí")
|
||||
#define TR_DISABLE_CH_MAP TR("No Ch. map", "Disable Ch. map")
|
||||
#define TR_DISABLE_TELEM TR("No Telem", "Disable Telemetry")
|
||||
#define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodetekce", INDENT "Formát autodetekce")
|
||||
#define TR_MULTI_LOWPOWER TR(INDENT "Nízký výkon", INDENT "Režim nízkého výkonu")
|
||||
#define TR_MODULE_TELEMETRY TR(INDENT "S.Port", INDENT "S.Port link")
|
||||
@@ -641,6 +643,7 @@
|
||||
#define TR_MODULE_NO_TELEMETRY TR3("Bez telemetrie", "Bez MULTI_TELEMETIE", "Nedetekována MULTI_TELEMETRIE")
|
||||
#define TR_MODULE_WAITFORBIND "Párovat při zavedení protokolu"
|
||||
#define TR_MODULE_BINDING TR("Bind...","Párování")
|
||||
#define TR_MODULE_UPGRADE "Module upgrade required"
|
||||
#define TR_REBIND "Nutno přepárovat"
|
||||
#define TR_REG_OK "Registrace ok"
|
||||
#define TR_BIND_OK "Úspěšné párovaní"
|
||||
@@ -650,8 +653,10 @@
|
||||
#define TR_BINDING_CH9_16_TELEM_OFF "k9-16 telem vyp"
|
||||
#define TR_PROTOCOL_INVALID TR("Špat. protokol", "Špatný protokol")
|
||||
#define TR_MODULE_STATUS TR(INDENT "Stav", INDENT "Stav modulu")
|
||||
#define TR_MODULE_SYNC TR(INDENT "Synchro", INDENT "Synchro modulu")
|
||||
#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Proto Sync Status")
|
||||
#define TR_MULTI_SERVOFREQ TR(INDENT "Frekv. serva", INDENT "Obnovovací frequence serva")
|
||||
#define TR_MULTI_MAX_THROW TR("Max. Throw", "Enable max. throw")
|
||||
#define TR_MULTI_RFCHAN TR("RF Channel", "Select RF channel")
|
||||
#define TR_SYNCMENU "[Sync]"
|
||||
#define TR_LIMIT INDENT"Limit"
|
||||
#define TR_MINRSSI "Min Rssi"
|
||||
|
||||
@@ -632,7 +632,9 @@
|
||||
#define TR_RFPOWER INDENT "RF Power"
|
||||
#define TR_MULTI_FIXEDID TR("FixedID", "Fixed ID")
|
||||
#define TR_MULTI_OPTION TR(INDENT "Option", INDENT "Optionswert")
|
||||
#define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on channel")
|
||||
#define TR_MULTI_AUTOBIND TR(INDENT "Bind Ch.",INDENT "Bind on channel")
|
||||
#define TR_DISABLE_CH_MAP TR("No Ch. map", "Disable Ch. map")
|
||||
#define TR_DISABLE_TELEM TR("No Telem", "Disable Telemetry")
|
||||
#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_MODULE_TELEMETRY TR(INDENT "S.Port", INDENT "S.Port link")
|
||||
@@ -643,6 +645,7 @@
|
||||
#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_MODULE_UPGRADE "Module upgrade required"
|
||||
#define TR_REBIND "Rebinding required"
|
||||
#define TR_REG_OK "Registration ok"
|
||||
#define TR_BIND_OK "Bind successful"
|
||||
@@ -652,8 +655,10 @@
|
||||
#define TR_BINDING_CH9_16_TELEM_OFF "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")
|
||||
#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Proto Sync Status")
|
||||
#define TR_MULTI_SERVOFREQ TR(INDENT "Servo rate", INDENT "Servo update rate")
|
||||
#define TR_MULTI_MAX_THROW TR("Max. Throw", "Enable max. throw")
|
||||
#define TR_MULTI_RFCHAN TR("RF Channel", "Select RF channel")
|
||||
#define TR_SYNCMENU "Sync [MENU]"
|
||||
#define TR_LIMIT INDENT "Grenzen"
|
||||
#define TR_MINRSSI "Min. RSSI"
|
||||
|
||||
@@ -631,7 +631,9 @@
|
||||
#define TR_RFPOWER "RF Power"
|
||||
#define TR_MULTI_FIXEDID TR("FixedID", "Fixed ID")
|
||||
#define TR_MULTI_OPTION TR("Option", "Option value")
|
||||
#define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on channel")
|
||||
#define TR_MULTI_AUTOBIND TR(INDENT "Bind Ch.",INDENT "Bind on channel")
|
||||
#define TR_DISABLE_CH_MAP TR("No Ch. map", "Disable Ch. map")
|
||||
#define TR_DISABLE_TELEM TR("No Telem", "Disable Telemetry")
|
||||
#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_MODULE_TELEMETRY TR(INDENT "S.Port", INDENT "S.Port link")
|
||||
@@ -642,6 +644,7 @@
|
||||
#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_MODULE_UPGRADE "Module upgrade required"
|
||||
#define TR_REBIND "Rebinding required"
|
||||
#define TR_REG_OK "Registration ok"
|
||||
#define TR_BIND_OK "Bind successful"
|
||||
@@ -651,8 +654,10 @@
|
||||
#define TR_BINDING_CH9_16_TELEM_OFF "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")
|
||||
#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Proto Sync Status")
|
||||
#define TR_MULTI_SERVOFREQ TR("Servo rate", "Servo update rate")
|
||||
#define TR_MULTI_MAX_THROW TR("Max. Throw", "Enable max. throw")
|
||||
#define TR_MULTI_RFCHAN TR("RF Channel", "Select RF channel")
|
||||
#define TR_SYNCMENU "[Sync]"
|
||||
#define TR_LIMIT INDENT "Limit"
|
||||
#define TR_MINRSSI "Min Rssi"
|
||||
|
||||
@@ -655,7 +655,9 @@
|
||||
#define TR_RFPOWER "RF Power"
|
||||
#define TR_MULTI_FIXEDID TR("FixedID", "Fixed ID")
|
||||
#define TR_MULTI_OPTION TR("Option", "Option value")
|
||||
#define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on channel")
|
||||
#define TR_MULTI_AUTOBIND TR(INDENT "Bind Ch.",INDENT "Bind on channel")
|
||||
#define TR_DISABLE_CH_MAP TR("No Ch. map", "Disable Ch. map")
|
||||
#define TR_DISABLE_TELEM TR("No Telem", "Disable Telemetry")
|
||||
#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_MODULE_TELEMETRY TR(INDENT "S.Port", INDENT "S.Port link")
|
||||
@@ -666,6 +668,7 @@
|
||||
#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_MODULE_UPGRADE "Module upgrade required"
|
||||
#define TR_REBIND "Rebinding required"
|
||||
#define TR_REG_OK "Registration ok"
|
||||
#define TR_BIND_OK "Bind successful"
|
||||
@@ -675,8 +678,10 @@
|
||||
#define TR_BINDING_CH9_16_TELEM_OFF "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")
|
||||
#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Proto Sync Status")
|
||||
#define TR_MULTI_SERVOFREQ TR("Servo rate", "Servo update rate")
|
||||
#define TR_MULTI_MAX_THROW TR("Max. Throw", "Enable max. throw")
|
||||
#define TR_MULTI_RFCHAN TR("RF Channel", "Select RF channel")
|
||||
#define TR_SYNCMENU "Sync " TR_ENTER
|
||||
#define TR_LIMIT INDENT"Limite"
|
||||
#define TR_MINRSSI "Min Rssi"
|
||||
|
||||
@@ -649,7 +649,9 @@
|
||||
#define TR_RFPOWER "RF Power"
|
||||
#define TR_MULTI_FIXEDID TR("FixedID", "Fixed ID")
|
||||
#define TR_MULTI_OPTION TR("Option", "Option value")
|
||||
#define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on channel")
|
||||
#define TR_MULTI_AUTOBIND TR(INDENT "Bind Ch.",INDENT "Bind on channel")
|
||||
#define TR_DISABLE_CH_MAP TR("No Ch. map", "Disable Ch. map")
|
||||
#define TR_DISABLE_TELEM TR("No Telem", "Disable Telemetry")
|
||||
#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_MODULE_TELEMETRY TR(INDENT "S.Port", INDENT "S.Port link")
|
||||
@@ -660,6 +662,7 @@
|
||||
#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_MODULE_UPGRADE "Module upgrade required"
|
||||
#define TR_REBIND "Rebinding required"
|
||||
#define TR_REG_OK "Registration ok"
|
||||
#define TR_BIND_OK "Bind successful"
|
||||
@@ -669,8 +672,10 @@
|
||||
#define TR_BINDING_CH9_16_TELEM_OFF "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")
|
||||
#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Proto Sync Status")
|
||||
#define TR_MULTI_SERVOFREQ TR("Servo rate", "Servo update rate")
|
||||
#define TR_MULTI_MAX_THROW TR("Max. Throw", "Enable max. throw")
|
||||
#define TR_MULTI_RFCHAN TR("RF Channel", "Select RF channel")
|
||||
#define TR_SYNCMENU "[Sync]"
|
||||
#define TR_LIMIT INDENT"Limit"
|
||||
#define TR_MINRSSI "Min Rssi"
|
||||
|
||||
@@ -652,7 +652,9 @@
|
||||
#define TR_RFPOWER TR(INDENT "Puiss. RF", INDENT "Puissance RF")
|
||||
#define TR_MULTI_FIXEDID "ID fixe"
|
||||
#define TR_MULTI_OPTION TR(INDENT "Option", INDENT "Option perso")
|
||||
#define TR_MULTI_AUTOBIND TR(INDENT "Bind auto", INDENT "Bind automatique")
|
||||
#define TR_MULTI_AUTOBIND TR(INDENT "Bind voie", INDENT "Bind sur voie")
|
||||
#define TR_DISABLE_CH_MAP TR("No Ch. map", "Désact réorg voies")
|
||||
#define TR_DISABLE_TELEM TR("No Telem", "Désact Télémétrie")
|
||||
#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_MODULE_TELEMETRY TR(INDENT "S.Port", INDENT "Lien S.Port")
|
||||
@@ -663,6 +665,7 @@
|
||||
#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 "Binder d'abord"
|
||||
#define TR_MODULE_BINDING "Bind..."
|
||||
#define TR_MODULE_UPGRADE "Mise à jour requise"
|
||||
#define TR_REBIND "Rebind requis"
|
||||
#define TR_REG_OK "Enregistr. ok"
|
||||
#define TR_BIND_OK "Bind ok"
|
||||
@@ -672,8 +675,10 @@
|
||||
#define TR_BINDING_CH9_16_TELEM_OFF "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")
|
||||
#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Proto Sync Status")
|
||||
#define TR_MULTI_SERVOFREQ TR(INDENT "Fréq.servo", INDENT "Fréquence servos")
|
||||
#define TR_MULTI_MAX_THROW TR("Max. Throw", "Enable max. throw")
|
||||
#define TR_MULTI_RFCHAN TR("RF Channel", "Select RF channel")
|
||||
#define TR_SYNCMENU "Sync [MENU]"
|
||||
#define TR_LIMIT INDENT "Limite"
|
||||
#define TR_MINRSSI "RSSI Min."
|
||||
|
||||
@@ -649,9 +649,11 @@
|
||||
#define TR_MULTI_TELEMETRY "Telemetria"
|
||||
#define TR_MULTI_VIDFREQ TR("Freq. video", "Frequenza video")
|
||||
#define TR_RFPOWER "Potenza RF"
|
||||
#define TR_MULTI_FIXEDID TR("FixedID", "Fixed ID")
|
||||
#define TR_MULTI_OPTION TR("Opzione", "Opzione valore")
|
||||
#define TR_MULTI_AUTOBIND TR(INDENT "Autoassoc.",INDENT "Associa automat.")
|
||||
#define TR_MULTI_FIXEDID TR(INDENT"ID fisso", INDENT"ID Fisso")
|
||||
#define TR_MULTI_OPTION TR(INDENT"Opzione", INDENT"Opzione valore")
|
||||
#define TR_MULTI_AUTOBIND TR(INDENT "Ass. Ch.",INDENT "Associa al canale")
|
||||
#define TR_DISABLE_CH_MAP TR("No Ch. map", "Disab. mappa Ch.")
|
||||
#define TR_DISABLE_TELEM TR("No Telem", "Telem. disabil.")
|
||||
#define TR_MULTI_DSM_AUTODTECT TR(INDENT "Trova autom.", INDENT "Autoril. il formato")
|
||||
#define TR_MULTI_LOWPOWER TR(INDENT "Bassa pot.", INDENT "Modo bassa potenza")
|
||||
#define TR_MODULE_TELEMETRY TR(INDENT "S.Port", INDENT "Link S.Port")
|
||||
@@ -662,6 +664,7 @@
|
||||
#define TR_MODULE_NO_TELEMETRY TR3("No telemetria", "MULTI_TELEMETRY disattivato", "Nessuna telem. (abilita MULTI_TELEMETRY)")
|
||||
#define TR_MODULE_WAITFORBIND "Associa per caricare il protocollo"
|
||||
#define TR_MODULE_BINDING "Associa"
|
||||
#define TR_MODULE_UPGRADE "Richiede agg. modulo"
|
||||
#define TR_REBIND "Richiede associazione"
|
||||
#define TR_REG_OK "Registrazione ok"
|
||||
#define TR_BIND_OK "Associazione riuscita"
|
||||
@@ -673,6 +676,8 @@
|
||||
#define TR_MODULE_STATUS TR(INDENT "Stato", INDENT "Stato del modulo")
|
||||
#define TR_MODULE_SYNC TR(INDENT "Sinc.", INDENT "Sinc. del modulo")
|
||||
#define TR_MULTI_SERVOFREQ TR("Servo rate", "Aggiorna servo rate")
|
||||
#define TR_MULTI_MAX_THROW TR("Escurs. mass.", "Abilita escurs. mass.")
|
||||
#define TR_MULTI_RFCHAN TR("Canale RF", "Selez. canale RF")
|
||||
#define TR_SYNCMENU "[Sync]"
|
||||
#define TR_LIMIT INDENT "Limiti"
|
||||
#define TR_MINRSSI "Min. RSSI"
|
||||
|
||||
@@ -637,7 +637,9 @@
|
||||
#define TR_RFPOWER "RF Power"
|
||||
#define TR_MULTI_FIXEDID TR("FixedID", "Fixed ID")
|
||||
#define TR_MULTI_OPTION TR("Option", "Option value")
|
||||
#define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on channel")
|
||||
#define TR_MULTI_AUTOBIND TR(INDENT "Bind Ch.",INDENT "Bind on channel")
|
||||
#define TR_DISABLE_CH_MAP TR("No Ch. map", "Disable Ch. map")
|
||||
#define TR_DISABLE_TELEM TR("No Telem", "Disable Telemetry")
|
||||
#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_MODULE_TELEMETRY TR(INDENT "S.Port", INDENT "S.Port link")
|
||||
@@ -648,6 +650,7 @@
|
||||
#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_MODULE_UPGRADE "Module upgrade required"
|
||||
#define TR_REBIND "Rebinding required"
|
||||
#define TR_REG_OK "Registration ok"
|
||||
#define TR_BIND_OK "Bind successful"
|
||||
@@ -657,8 +660,10 @@
|
||||
#define TR_BINDING_CH9_16_TELEM_OFF "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")
|
||||
#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Proto Sync Status")
|
||||
#define TR_MULTI_SERVOFREQ TR("Servo rate", "Servo update rate")
|
||||
#define TR_MULTI_MAX_THROW TR("Max. Throw", "Enable max. throw")
|
||||
#define TR_MULTI_RFCHAN TR("RF Channel", "Select RF channel")
|
||||
#define TR_SYNCMENU "Sync [MENU]"
|
||||
#define TR_LIMIT INDENT "Grenzen"
|
||||
#define TR_MINRSSI "Min. RSSI"
|
||||
|
||||
@@ -650,7 +650,9 @@
|
||||
#define TR_RFPOWER "RF Power"
|
||||
#define TR_MULTI_FIXEDID TR("FixedID", "Fixed ID")
|
||||
#define TR_MULTI_OPTION TR("Option", "Option value")
|
||||
#define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on channel")
|
||||
#define TR_MULTI_AUTOBIND TR(INDENT "Bind Ch.",INDENT "Bind on channel")
|
||||
#define TR_DISABLE_CH_MAP TR("No Ch. map", "Disable Ch. map")
|
||||
#define TR_DISABLE_TELEM TR("No Telem", "Disable Telemetry")
|
||||
#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_MODULE_TELEMETRY TR(INDENT "S.Port", INDENT "S.Port link")
|
||||
@@ -661,6 +663,7 @@
|
||||
#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_MODULE_UPGRADE "Module upgrade required"
|
||||
#define TR_REBIND "Rebinding required"
|
||||
#define TR_REG_OK "Registration ok"
|
||||
#define TR_BIND_OK "Bind successful"
|
||||
@@ -670,8 +673,10 @@
|
||||
#define TR_BINDING_CH9_16_TELEM_OFF "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")
|
||||
#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Proto Sync Status")
|
||||
#define TR_MULTI_SERVOFREQ TR("Servo rate", "Servo update rate")
|
||||
#define TR_MULTI_MAX_THROW TR("Max. Throw", "Enable max. throw")
|
||||
#define TR_MULTI_RFCHAN TR("RF Channel", "Select RF channel")
|
||||
#define TR_SYNCMENU "[Synch]"
|
||||
#define TR_LIMIT INDENT "Limit"
|
||||
#define TR_MINRSSI "Min Rssi"
|
||||
|
||||
@@ -641,7 +641,9 @@
|
||||
#define TR_RFPOWER "RF Power"
|
||||
#define TR_MULTI_FIXEDID TR("FixedID", "Fixed ID")
|
||||
#define TR_MULTI_OPTION TR("Option", "Option value")
|
||||
#define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on channel")
|
||||
#define TR_MULTI_AUTOBIND TR(INDENT "Bind Ch.",INDENT "Bind on channel")
|
||||
#define TR_DISABLE_CH_MAP TR("No Ch. map", "Disable Ch. map")
|
||||
#define TR_DISABLE_TELEM TR("No Telem", "Disable Telemetry")
|
||||
#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_MODULE_TELEMETRY TR(INDENT "S.Port", INDENT "S.Port link")
|
||||
@@ -652,6 +654,7 @@
|
||||
#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_MODULE_UPGRADE "Module upgrade required"
|
||||
#define TR_REBIND "Rebinding required"
|
||||
#define TR_REG_OK "Registration ok"
|
||||
#define TR_BIND_OK "Bind successful"
|
||||
@@ -661,8 +664,10 @@
|
||||
#define TR_BINDING_CH9_16_TELEM_OFF "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")
|
||||
#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Proto Sync Status")
|
||||
#define TR_MULTI_SERVOFREQ TR("Servo rate", "Servo update rate")
|
||||
#define TR_MULTI_MAX_THROW TR("Max. Throw", "Enable max. throw")
|
||||
#define TR_MULTI_RFCHAN TR("RF Channel", "Select RF channel")
|
||||
#define TR_LIMIT INDENT"Limite"
|
||||
#define TR_MINRSSI "Min Rssi"
|
||||
#define TR_LATITUDE "Latitude"
|
||||
|
||||
@@ -650,7 +650,9 @@
|
||||
#define TR_RFPOWER "RF Power"
|
||||
#define TR_MULTI_FIXEDID TR("FixedID", "Fixed ID")
|
||||
#define TR_MULTI_OPTION TR("Option", "Option value")
|
||||
#define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on channel")
|
||||
#define TR_MULTI_AUTOBIND TR(INDENT "Bind Ch.",INDENT "Bind on channel")
|
||||
#define TR_DISABLE_CH_MAP TR("No Ch. map", "Disable Ch. map")
|
||||
#define TR_DISABLE_TELEM TR("No Telem", "Disable Telemetry")
|
||||
#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_MODULE_TELEMETRY TR(INDENT "S.Port", INDENT "S.Port link")
|
||||
@@ -661,6 +663,7 @@
|
||||
#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_MODULE_UPGRADE "Module upgrade required"
|
||||
#define TR_REBIND "Rebinding required"
|
||||
#define TR_REG_OK "Registration ok"
|
||||
#define TR_BIND_OK "Bind successful"
|
||||
@@ -670,8 +673,10 @@
|
||||
#define TR_BINDING_CH9_16_TELEM_OFF "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")
|
||||
#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Proto Sync Status")
|
||||
#define TR_MULTI_SERVOFREQ TR("Servo rate", "Servo update rate")
|
||||
#define TR_MULTI_MAX_THROW TR("Max. Throw", "Enable max. throw")
|
||||
#define TR_MULTI_RFCHAN TR("RF Channel", "Select RF channel")
|
||||
#define TR_LIMIT INDENT "Nivå"
|
||||
#define TR_MINRSSI "Min Rssi"
|
||||
#define TR_LATITUDE "Breddgrad"
|
||||
|
||||
Reference in New Issue
Block a user