Module settings

This commit is contained in:
Raphael Coeffic
2021-12-31 10:53:09 +01:00
parent e679af9351
commit 80c62bb1f0
4 changed files with 430 additions and 3 deletions
+1
View File
@@ -41,6 +41,7 @@ set(firmwares_SRCS
edgetx/yaml_mixdata.cpp
edgetx/yaml_expodata.cpp
edgetx/yaml_curvedata.cpp
edgetx/yaml_moduledata.cpp
datahelpers.cpp
customisation_data.cpp
)
@@ -24,6 +24,7 @@
#include "yaml_rawsource.h"
#include "yaml_expodata.h"
#include "yaml_curvedata.h"
#include "yaml_moduledata.h"
#include "modeldata.h"
#include "output_data.h"
@@ -338,7 +339,12 @@ Node convert<ModelData>::encode(const ModelData& rhs)
node["trainerMode"] = trainerModeLut << rhs.trainerMode;
// moduleData[]
for (int i=0; i<CPN_MAX_MODULES; i++) {
if (rhs.moduleData[i].protocol != PULSES_OFF) {
node["moduleData"][std::to_string(i)] = rhs.moduleData[i];
}
}
// scriptData[]
// sensorData[]
@@ -416,8 +422,7 @@ bool convert<ModelData>::decode(const Node& node, ModelData& rhs)
// rssiAlarms
node["trainerMode"] >> trainerModeLut >> rhs.trainerMode;
// moduleData[]
node["moduleData"] >> rhs.moduleData;
// scriptData[]
// sensorData[]
@@ -0,0 +1,390 @@
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "yaml_moduledata.h"
#include "moduledata.h"
#include "rawsource.h"
// type: TYPE_MULTIMODULE
// subType: 15,2
// channelsStart: 0
// channelsCount: 12
// failsafeMode: NOT_SET
// mod:
// multi:
// disableTelemetry: 0
// disableMapping: 0
// autoBindMode: 0
// lowPowerMode: 0
// optionValue: 0
// receiverTelemetryOff: 0
// receiverHigherChannels: 0
static const YamlLookupTable protocolLut = {
{ PULSES_OFF, "TYPE_NONE" },
{ PULSES_PPM, "TYPE_PPM" },
{ PULSES_PXX_XJT_X16, "TYPE_XJT_PXX1" },
{ PULSES_ACCESS_ISRM, "TYPE_ISRM_PXX2" },
{ PULSES_LP45, "TYPE_DSM2" },
{ PULSES_CROSSFIRE, "TYPE_CROSSFIRE" },
{ PULSES_MULTIMODULE, "TYPE_MULTIMODULE" },
{ PULSES_PXX_R9M, "TYPE_R9M_PXX1" },
{ PULSES_ACCESS_R9M, "TYPE_R9M_PXX2" },
{ PULSES_PXX_R9M_LITE, "TYPE_R9M_LITE_PXX1" },
{ PULSES_ACCESS_R9M_LITE, "TYPE_R9M_LITE_PXX2" },
{ PULSES_GHOST, "TYPE_GHOST" },
{ PULSES_ACCESS_R9M_LITE_PRO, "TYPE_R9M_LITE_PRO_PXX2" },
{ PULSES_SBUS, "TYPE_SBUS" },
{ PULSES_XJT_LITE_X16, "TYPE_XJT_LITE_PXX2" },
{ PULSES_AFHDS3, "TYPE_FLYSKY" },
};
static const YamlLookupTable xjtLut = {
{ 0, "D16" },
{ 1, "D8" },
{ 2, "LR12" },
};
static const YamlLookupTable isrmLut = {
{ 0, "ACCESS" },
{ 1, "D16" },
};
static const YamlLookupTable r9mLut = {
{ MODULE_SUBTYPE_R9M_FCC, "FCC" },
{ MODULE_SUBTYPE_R9M_EU, "EU" },
{ MODULE_SUBTYPE_R9M_EUPLUS, "EUPLUS" },
{ MODULE_SUBTYPE_R9M_AUPLUS, "AUPLUS" },
};
static const YamlLookupTable dsmLut = {
{ 0, "LP45" },
{ 1, "DSM2" },
{ 3, "DSMX" },
};
static const YamlLookupTable failsafeLut = {
{ FAILSAFE_NOT_SET, "NOT_SET" },
{ FAILSAFE_HOLD, "HOLD" },
{ FAILSAFE_CUSTOM, "CUSTOM" },
{ FAILSAFE_NOPULSES, "NOPULSES" },
{ FAILSAFE_RECEIVER, "RECEIVER" },
};
enum MMRFrskySubtypes {
MM_RF_FRSKY_SUBTYPE_D16,
MM_RF_FRSKY_SUBTYPE_D8,
MM_RF_FRSKY_SUBTYPE_D16_8CH,
MM_RF_FRSKY_SUBTYPE_V8,
MM_RF_FRSKY_SUBTYPE_D16_LBT,
MM_RF_FRSKY_SUBTYPE_D16_LBT_8CH,
MM_RF_FRSKY_SUBTYPE_D8_CLONED,
MM_RF_FRSKY_SUBTYPE_D16_CLONED
};
// from radio/src/pulses/multi.cpp
static void convertMultiProtocolToEtx(int *protocol, int *subprotocol)
{
if (*protocol == 3 && *subprotocol == 0) {
*protocol = MODULE_SUBTYPE_MULTI_FRSKY + 1;
*subprotocol = MM_RF_FRSKY_SUBTYPE_D8;
return;
}
if (*protocol == 3 && *subprotocol == 1) {
*protocol = MODULE_SUBTYPE_MULTI_FRSKY + 1;
*subprotocol = MM_RF_FRSKY_SUBTYPE_D8_CLONED;
return;
}
if (*protocol == 25) {
*protocol = MODULE_SUBTYPE_MULTI_FRSKY + 1;
*subprotocol = MM_RF_FRSKY_SUBTYPE_V8;
return;
}
if (*protocol == 15) {
*protocol = MODULE_SUBTYPE_MULTI_FRSKY + 1;
if (*subprotocol == 0)
*subprotocol = MM_RF_FRSKY_SUBTYPE_D16;
else if (*subprotocol == 1)
*subprotocol = MM_RF_FRSKY_SUBTYPE_D16_8CH;
else if (*subprotocol == 2)
*subprotocol = MM_RF_FRSKY_SUBTYPE_D16_LBT;
else if (*subprotocol == 3)
*subprotocol = MM_RF_FRSKY_SUBTYPE_D16_LBT_8CH;
else if (*subprotocol == 4)
*subprotocol = MM_RF_FRSKY_SUBTYPE_D16_CLONED;
return;
}
if (*protocol >= 25)
*protocol -= 1;
if (*protocol >= 16)
*protocol -= 1;
}
void convertEtxProtocolToMulti(int *protocol, int *subprotocol)
{
// Special treatment for the FrSky entry...
if (*protocol == MODULE_SUBTYPE_MULTI_FRSKY + 1) {
if (*subprotocol == MM_RF_FRSKY_SUBTYPE_D8) {
//D8
*protocol = 3;
*subprotocol = 0;
}
else if (*subprotocol == MM_RF_FRSKY_SUBTYPE_D8_CLONED) {
//D8
*protocol = 3;
*subprotocol = 1;
}
else if (*subprotocol == MM_RF_FRSKY_SUBTYPE_V8) {
//V8
*protocol = 25;
*subprotocol = 0;
}
else {
*protocol = 15;
if (*subprotocol == MM_RF_FRSKY_SUBTYPE_D16_8CH)
*subprotocol = 1;
else if (*subprotocol == MM_RF_FRSKY_SUBTYPE_D16)
*subprotocol = 0; // D16
else if (*subprotocol == MM_RF_FRSKY_SUBTYPE_D16_LBT)
*subprotocol = 2;
else if (*subprotocol == MM_RF_FRSKY_SUBTYPE_D16_LBT_8CH)
*subprotocol = 3;
else
*subprotocol = 4; // D16_CLONED
}
}
else {
// 15 for Multimodule is FrskyX or D16 which we map as a protocol of 3 (FrSky)
// all protos > frskyx are therefore also off by one
if (*protocol >= 15)
*protocol += 1;
// 25 is again a FrSky *protocol (FrskyV) so shift again
if (*protocol >= 25)
*protocol += 1;
}
}
namespace YAML
{
Node convert<ModuleData>::encode(const ModuleData& rhs)
{
Node node;
int protocol = rhs.protocol;
int subtype = rhs.subType;
if (rhs.protocol >= PULSES_LP45 && rhs.protocol <= PULSES_DSMX) {
protocol = PULSES_LP45;
subtype = rhs.protocol - PULSES_LP45;
} else if (rhs.protocol == PULSES_ACCST_ISRM_D16 || rhs.protocol == PULSES_ACCESS_ISRM) {
protocol = PULSES_ACCESS_ISRM;
subtype = rhs.protocol - PULSES_ACCESS_ISRM;
} else if (rhs.protocol >= PULSES_PXX_XJT_X16 && rhs.protocol <= PULSES_PXX_XJT_LR12) {
protocol = PULSES_PXX_XJT_X16;
subtype = rhs.protocol - PULSES_PXX_XJT_X16;
} else if (rhs.protocol >= PULSES_XJT_LITE_X16 && rhs.protocol <= PULSES_XJT_LITE_LR12) {
protocol = PULSES_XJT_LITE_X16;
subtype = rhs.protocol - PULSES_XJT_LITE_X16;
}
node["type"] = LookupValue(protocolLut, protocol);
switch (protocol) {
case PULSES_PXX_XJT_X16:
case PULSES_XJT_LITE_X16:
node["subType"] = LookupValue(xjtLut, subtype);
break;
case PULSES_ACCESS_ISRM:
node["subType"] = LookupValue(isrmLut, subtype);
break;
case PULSES_PXX_R9M:
case PULSES_PXX_R9M_LITE:
node["subType"] = LookupValue(r9mLut, subtype);
break;
case PULSES_LP45:
node["subType"] = LookupValue(dsmLut, subtype);
break;
case PULSES_MULTIMODULE: {
int rfProtocol = rhs.multi.rfProtocol + 1;
int subType = rhs.subType;
convertEtxProtocolToMulti(&rfProtocol, &subType);
std::string st_str = std::to_string(rfProtocol);
st_str += ",";
st_str += std::to_string(subType);
node["subType"] = st_str;
} break;
}
node["channelsStart"] = rhs.channelsStart;
node["channelsCount"] = rhs.channelsCount;
node["failsafeMode"] = LookupValue(failsafeLut, rhs.failsafeMode);
Node mod;
switch (protocol) {
case PULSES_PXX_XJT_X16:
case PULSES_PXX_R9M:
case PULSES_PXX_R9M_LITE: {
Node pxx;
pxx["power"] = rhs.pxx.power;
// pxx["receiverTelemetryOff"] = rhs.pxx.receiverTelemetryOff;
// pxx["receiverHigherChannels"] = rhs.pxx.receiverHigherChannels;
pxx["antennaMode"] = rhs.pxx.antennaMode;
mod["pxx"] = pxx;
} break;
case PULSES_ACCESS_ISRM:
case PULSES_ACCESS_R9M:
case PULSES_ACCESS_R9M_LITE:
case PULSES_ACCESS_R9M_LITE_PRO:
case PULSES_XJT_LITE_X16: {
Node pxx2;
pxx2["receivers"] = rhs.access.receivers;
pxx2["racingMode"] = rhs.access.racingMode;
for (int i=0; i<rhs.access.receivers; i++) {
pxx2["receiverName"][std::to_string(i)] = rhs.access.receiverName[i];
}
mod["pxx2"] = pxx2;
} break;
case PULSES_MULTIMODULE: {
Node multi;;
multi["disableTelemetry"] = (int)rhs.multi.disableTelemetry;
multi["disableMapping"] = (int)rhs.multi.disableMapping;
multi["autoBindMode"] = (int)rhs.multi.autoBindMode;
multi["lowPowerMode"] = (int)rhs.multi.lowPowerMode;
multi["optionValue"] = rhs.multi.optionValue;
// multi["receiverTelemetryOff"] = (int)rhs.pxx.receiverTelemetryOff;
// multi["receiverHigherChannels"] = (int)rhs.pxx.receiverHigherChannels;
mod["multi"] = multi;
} break;
case PULSES_SBUS: {
Node sbus;
sbus["refreshRate"] = rhs.ppm.frameLength;
mod["sbus"] = sbus;
} break;
// TODO: afhds3, flysky
default: {
Node ppm;
ppm["delay"] = rhs.ppm.delay;
ppm["pulsePol"] = rhs.ppm.pulsePol;
ppm["outputType"] = rhs.ppm.outputType;
ppm["frameLength"] = rhs.ppm.frameLength;
mod["ppm"] = ppm;
} break;
}
if (mod && mod.IsMap())
node["mod"] = mod;
return node;
}
bool convert<ModuleData>::decode(const Node& node, ModuleData& rhs)
{
node["type"] >> protocolLut >> rhs.protocol;
Node subType;
node["subType"] >> subType;
switch (rhs.protocol) {
case PULSES_PXX_XJT_X16:
case PULSES_XJT_LITE_X16: {
int subProto = 0;
subType >> xjtLut >> subProto;
rhs.protocol += subProto;
} break;
case PULSES_ACCESS_ISRM: {
int subProto = 0;
subType >> isrmLut >> subProto;
rhs.protocol += subProto;
} break;
case PULSES_PXX_R9M:
case PULSES_PXX_R9M_LITE: {
subType >> r9mLut >> rhs.subType;
} break;
case PULSES_LP45: {
int subProto = 0;
subType >> dsmLut >> subProto;
rhs.protocol += subProto;
} break;
case PULSES_MULTIMODULE: {
std::string st_str;
subType >> st_str;
if (!st_str.empty()) {
size_t pos = 0;
int rfProtocol = std::stoi(st_str, &pos);
st_str = st_str.substr(pos + 1);
int rfSubType = std::stoi(st_str);
convertMultiProtocolToEtx(&rfProtocol, &rfSubType);
if (rfProtocol > 0) {
rhs.multi.rfProtocol = rfProtocol - 1;
rhs.subType = rfSubType;
}
}
} break;
}
node["channelsStart"] >> rhs.channelsStart;
node["channelsCount"] >> rhs.channelsCount;
node["failsafeMode"] >> failsafeLut >> rhs.failsafeMode;
if (node["mod"]) {
Node mod = node["mod"];
if (mod["ppm"]) {
Node ppm = mod["ppm"];
ppm["delay"] >> rhs.ppm.delay;
ppm["pulsePol"] >> rhs.ppm.pulsePol;
ppm["outputType"] >> rhs.ppm.outputType;
ppm["frameLength"] >> rhs.ppm.frameLength;
} else if (mod["multi"]) {
Node multi = mod["multi"];
multi["disableTelemetry"] >> rhs.multi.disableTelemetry;
multi["disableMapping"] >> rhs.multi.disableMapping;
multi["autoBindMode"] >> rhs.multi.autoBindMode;
multi["lowPowerMode"] >> rhs.multi.lowPowerMode;
multi["optionValue"] >> rhs.multi.optionValue;
// multi["receiverTelemetryOff"] >> rhs.pxx.receiverTelemetryOff;
// multi["receiverHigherChannels"] >> rhs.pxx.receiverHigherChannels;
} else if (mod["pxx"]) {
Node pxx = mod["pxx"];
pxx["power"] >> rhs.pxx.power;
// pxx["receiverTelemetryOff"] >> rhs.pxx.receiverTelemetryOff;
// pxx["receiverHigherChannels"] >> rhs.pxx.receiverHigherChannels;
pxx["antennaMode"] >> rhs.pxx.antennaMode;
} else if (mod["sbus"]) {
mod["sbus"]["refreshRate"] >> rhs.ppm.frameLength;
} else if (mod["pxx2"]) {
Node pxx2 = mod["pxx2"];
pxx2["receivers"] >> rhs.access.receivers;
pxx2["racingMode"] >> rhs.access.racingMode;
for (const auto& rx : pxx2["receiverName"]) {
rx >> rhs.access.receiverName;
}
} else if (mod["flysky"]) {
//TODO
} else if (mod["afhds3"]) {
//TODO
}
}
return true;
}
}
@@ -0,0 +1,31 @@
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "yaml_ops.h"
#include "moduledata.h"
namespace YAML
{
template <>
struct convert<ModuleData> {
static Node encode(const ModuleData& rhs);
static bool decode(const Node& node, ModuleData& rhs);
};
} // namespace YAML