Files
edgetx-gx12/companion/src/firmwares/edgetx/yaml_switchconfig.cpp
T

423 lines
12 KiB
C++

/*
* Copyright (C) EdgeTX
*
* Based on code named
* opentx - https://github.com/opentx/opentx
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "yaml_switchconfig.h"
#include "boards.h"
#include "eeprominterface.h"
#include "generalsettings.h"
#include "boardjson.h"
const YamlLookupTable switchConfigLut = {
{Board::SWITCH_NOT_AVAILABLE, "none"},
{Board::SWITCH_TOGGLE, "toggle"},
{Board::SWITCH_2POS, "2pos"},
{Board::SWITCH_3POS, "3pos"},
};
const YamlLookupTable potConfigLut = {
{Board::FLEX_NONE, "none"},
{Board::FLEX_POT, "without_detent"},
{Board::FLEX_POT_CENTER, "with_detent"},
{Board::FLEX_SLIDER, "slider"},
{Board::FLEX_MULTIPOS, "multipos_switch"},
{Board::FLEX_AXIS_X, "axis_x"},
{Board::FLEX_AXIS_Y, "axis_y"},
{Board::FLEX_SWITCH, "switch"},
};
// pre v2.10
const YamlLookupTable sliderConfigLut = {
{Board::SLIDER_NONE, "none"},
{Board::SLIDER_WITH_DETENT, "with_detent"},
};
// pre v2.10
const YamlLookupTable sticksLut = {
{0, "Rud"},
{1, "Ele"},
{2, "Thr"},
{3, "Ali"},
};
YamlPotConfig::YamlPotConfig(const GeneralSettings::InputConfig* rhs)
{
for (int i = 0; i < Boards::getCapability(getCurrentBoard(), Board::Inputs); i++) {
if (Boards::isInputConfigurable(i)) {
config[i].tag = Boards::getInputYamlName(i, BoardJson::YLT_CONFIG).toStdString();
config[i].type = rhs[i].type;
memcpy(config[i].name, rhs[i].name, sizeof(HARDWARE_NAME_LEN));
config[i].flexType = rhs[i].flexType;
config[i].inverted = rhs[i].inverted;
}
}
}
void YamlPotConfig::copy(GeneralSettings::InputConfig* rhs) const
{
for (int i = 0; i < Boards::getCapability(getCurrentBoard(), Board::Inputs); i++) {
if (config[i].type == (unsigned int)Board::AIT_FLEX) {
memcpy(rhs[i].name, config[i].name, sizeof(HARDWARE_NAME_LEN));
rhs[i].flexType = (Board::FlexType)config[i].flexType;
rhs[i].inverted = config[i].inverted;
}
}
}
void YamlSliderConfig::copy(GeneralSettings::InputConfig* rhs) const
{
for (int i = 0; i < Boards::getCapability(getCurrentBoard(), Board::Inputs); i++) {
if (config[i].type == (unsigned int)Board::AIT_FLEX) {
memcpy(rhs[i].name, config[i].name, sizeof(HARDWARE_NAME_LEN));
rhs[i].flexType = (Board::FlexType)config[i].flexType;
rhs[i].inverted = config[i].inverted;
}
}
}
YamlStickConfig::YamlStickConfig(const GeneralSettings::InputConfig* rhs)
{
for (int i = 0; i < Boards::getCapability(getCurrentBoard(), Board::Inputs); i++) {
config[i].tag = std::to_string(i);
config[i].type = rhs[i].type;
memcpy(config[i].name, rhs[i].name, sizeof(HARDWARE_NAME_LEN));
}
}
void YamlStickConfig::copy(GeneralSettings::InputConfig* rhs) const
{
for (int i = 0; i < Boards::getCapability(getCurrentBoard(), Board::Inputs); i++) {
if (config[i].type == (unsigned int)Board::AIT_STICK) {
memcpy(rhs[i].name, config[i].name, sizeof(HARDWARE_NAME_LEN));
}
}
}
YamlSwitchConfig::YamlSwitchConfig(const GeneralSettings::SwitchConfig* rhs)
{
for (int i = 0; i < Boards::getCapability(getCurrentBoard(), Board::Switches); i++) {
config[i].tag = Boards::getSwitchYamlName(i, BoardJson::YLT_CONFIG).toStdString();
config[i].type = rhs[i].type;
memcpy(config[i].name, rhs[i].name, sizeof(HARDWARE_NAME_LEN));
// config[i].inverted = rhs[i].inverted;
}
}
void YamlSwitchConfig::copy(GeneralSettings::SwitchConfig* rhs) const
{
for (int i = 0; i < Boards::getCapability(getCurrentBoard(), Board::Switches); i++) {
if (config[i].type != (unsigned int)Board::SWITCH_NOT_AVAILABLE) {
memcpy(rhs[i].name, config[i].name, sizeof(HARDWARE_NAME_LEN));
rhs[i].type = (Board::SwitchType)config[i].type;
// rhs[i].inverted = config[i].inverted;
}
}
}
YamlSwitchesFlex::YamlSwitchesFlex(const GeneralSettings::SwitchConfig* rhs)
{
for (int i = 0; i < Boards::getCapability(getCurrentBoard(), Board::Switches); i++) {
if (Boards::isSwitchFlex(i) && rhs[i].inputIdx != SWITCH_INPUTINDEX_NONE) {
int idx = Boards::getSwitchTagNum(i) - 1;
if (idx >= 0 && idx < CPN_MAX_SWITCHES_FLEX) {
config[idx].tag = Boards::getSwitchYamlName(i, BoardJson::YLT_CONFIG).toStdString();
config[idx].channel = Boards::getInputYamlName(rhs[i].inputIdx, BoardJson::YLT_CONFIG).toStdString();
}
}
}
}
void YamlSwitchesFlex::copy(GeneralSettings::SwitchConfig* rhs) const
{
for (int i = 0; i < Boards::getCapability(getCurrentBoard(), Board::FlexSwitches); i++) {
int idx = Boards::getSwitchYamlIndex(config[i].tag.c_str(), BoardJson::YLT_CONFIG);
rhs[idx].inputIdx = config[i].inputIndx;
}
}
namespace YAML
{
Node convert<InputConfig>::encode(const InputConfig& rhs)
{
Node node;
node["name"] = rhs.name;
if (rhs.type != Board::AIT_STICK) {
node["type"] = potConfigLut << rhs.flexType;
node["inv"] = (int)rhs.inverted;
}
return node;
}
bool convert<InputConfig>::decode(const Node& node, InputConfig& rhs)
{
if (!node.IsMap()) return false;
node["name"] >> rhs.name;
node["type"] >> potConfigLut >> rhs.flexType;
node["inv"] >> rhs.inverted;
if (radioSettingsVersion < SemanticVersion(QString(CPN_ADC_REFACTOR_VERSION))) {
int idx = Boards::getInputYamlIndex(rhs.tag.c_str(), BoardJson::YLT_CONFIG);
if (idx >= 0) {
Board::InputInfo info = Boards::getInputInfo(idx);
rhs.inverted = info.inverted;
}
else
rhs.inverted = false;
}
return true;
}
Node convert<SwitchConfig>::encode(const SwitchConfig& rhs)
{
Node node;
node["type"] = switchConfigLut << rhs.type;
node["name"] = rhs.name;
// node["inv"] = (int)rhs.inverted; in hwdef json but not implemented in radio yaml
return node;
}
bool convert<SwitchConfig>::decode(const Node& node, SwitchConfig& rhs)
{
if (!node.IsMap()) return false;
node["type"] >> switchConfigLut >> rhs.type;
node["name"] >> rhs.name;
// node["inv"] >> rhs.inverted; in hwdef json but not implemented in radio yaml
if (radioSettingsVersion < SemanticVersion(QString(CPN_ADC_REFACTOR_VERSION))) {
int idx = Boards::getSwitchYamlIndex(rhs.tag.c_str(), BoardJson::YLT_CONFIG);
if (idx >= 0) {
Board::SwitchInfo info = Boards::getSwitchInfo(idx);
rhs.inverted = info.inverted;
}
}
return true;
}
Node convert<SwitchFlex>::encode(const SwitchFlex& rhs)
{
Node node;
node["channel"] = rhs.channel;
return node;
}
bool convert<SwitchFlex>::decode(const Node& node, SwitchFlex& rhs)
{
if (!node.IsMap()) return false;
node["channel"] >> rhs.channel;
rhs.inputIndx = Boards::getInputYamlIndex(rhs.channel.c_str(), BoardJson::YLT_CONFIG);
return true;
}
Node convert<YamlPotConfig>::encode(const YamlPotConfig& rhs)
{
Node node;
const int maxcnt = Boards::getCapability(getCurrentBoard(), Board::Inputs);
for (int i = 0; i < maxcnt; i++) {
if (rhs.config[i].type == (unsigned int)Board::AIT_FLEX && rhs.config[i].flexType != (unsigned int)Board::FLEX_NONE) {
std::string tag = rhs.config[i].tag;
node[tag] = rhs.config[i];
}
}
return node;
}
bool convert<YamlPotConfig>::decode(const Node& node, YamlPotConfig& rhs)
{
if (!node.IsMap()) return false;
const int maxcnt = Boards::getCapability(getCurrentBoard(), Board::Inputs);
for (const auto& kv : node) {
std::string tag;
kv.first >> tag;
if (radioSettingsVersion < SemanticVersion(QString(CPN_ADC_REFACTOR_VERSION)))
tag = Boards::getLegacyAnalogMappedInputTag(tag.c_str());
int idx = Boards::getInputYamlIndex(tag.c_str(), BoardJson::YLT_CONFIG);
if (idx >= 0 && idx < maxcnt) {
kv.second >> rhs.config[idx];
rhs.config[idx].tag = tag;
rhs.config[idx].type = Board::AIT_FLEX;
}
}
return true;
}
//
bool convert<YamlSliderConfig>::decode(const Node& node, YamlSliderConfig& rhs)
{
if (!node.IsMap()) return false;
const int maxcnt = Boards::getCapability(getCurrentBoard(), Board::Inputs);
if (Boards::getCapability(getCurrentBoard(), Board::Sliders) < 1)
return true;
int i = 1;
for (const auto& kv : node) {
std::string tag;
kv.first >> tag;
int idx = Boards::getInputSliderIndex(i);
if (idx >= 0 && idx < maxcnt) {
kv.second >> rhs.config[idx];
rhs.config[idx].tag = Boards::getInputTag(idx).toStdString();
rhs.config[idx].type = Board::AIT_FLEX;
}
i++;
}
return true;
}
Node convert<YamlStickConfig>::encode(const YamlStickConfig& rhs)
{
Node node;
const int maxcnt = Boards::getCapability(getCurrentBoard(), Board::Inputs);
for (int i = 0; i < maxcnt; i++) {
if (rhs.config[i].type == (unsigned int)Board::AIT_STICK) {
std::string tag = rhs.config[i].tag;
node[tag] = rhs.config[i];
}
}
return node;
}
bool convert<YamlStickConfig>::decode(const Node& node, YamlStickConfig& rhs)
{
if (!node.IsMap()) return false;
const int maxcnt = Boards::getCapability(getCurrentBoard(), Board::Inputs);
for (const auto& kv : node) {
std::string tag;
kv.first >> tag;
if (!tag.empty()) {
int idx = std::stoi(tag);
if (idx >= 0 && idx < maxcnt) {
kv.second >> rhs.config[idx];
rhs.config[idx].tag = tag;
rhs.config[idx].type = Board::AIT_STICK;
}
}
}
return true;
}
Node convert<YamlSwitchConfig>::encode(const YamlSwitchConfig& rhs)
{
Node node;
const int maxcnt = Boards::getCapability(getCurrentBoard(), Board::Switches);
for (int i = 0; i < maxcnt; i++) {
if (rhs.config[i].type != Board::SWITCH_NOT_AVAILABLE) {
std::string tag = Boards::getSwitchYamlName(i, BoardJson::YLT_CONFIG).toStdString();
node[tag] = rhs.config[i];
}
}
return node;
}
bool convert<YamlSwitchConfig>::decode(const Node& node, YamlSwitchConfig& rhs)
{
if (!node.IsMap()) return false;
Board::Type board = getCurrentBoard();
const int maxcnt = Boards::getCapability(board, Board::Switches);
for (const auto& kv : node) {
std::string tag;
kv.first >> tag;
int idx = Boards::getSwitchYamlIndex(tag.c_str(), BoardJson::YLT_CONFIG);
if (idx >= 0 && idx < maxcnt) {
kv.second >> rhs.config[idx];
rhs.config[idx].tag = tag;
}
}
return true;
}
Node convert<YamlSwitchesFlex>::encode(const YamlSwitchesFlex& rhs)
{
Node node;
const int maxcnt = Boards::getCapability(getCurrentBoard(), Board::FlexSwitches);
for (int i = 0; i < maxcnt; i++) {
if (!rhs.config[i].tag.empty())
node[rhs.config[i].tag] = rhs.config[i];
}
return node;
}
bool convert<YamlSwitchesFlex>::decode(const Node& node, YamlSwitchesFlex& rhs)
{
if (!node.IsMap()) return false;
const int maxcnt = Boards::getCapability(getCurrentBoard(), Board::FlexSwitches);
for (const auto& kv : node) {
std::string tag;
kv.first >> tag;
const char* val = tag.data();
size_t len = tag.size();
if (len > 2 && val[0] == 'F' && val[1] == 'L' && val[2] > '0' && val[2] <= '9') {
int idx = std::stoi(tag.substr(2, len - 2)) - 1;
if (idx >= 0 && idx < maxcnt) {
kv.second >> rhs.config[idx];
rhs.config[idx].tag = tag;
}
}
}
return true;
}
} // namespace YAML