diff --git a/companion/src/firmwares/CMakeLists.txt b/companion/src/firmwares/CMakeLists.txt index e298b2a82..c2b258537 100644 --- a/companion/src/firmwares/CMakeLists.txt +++ b/companion/src/firmwares/CMakeLists.txt @@ -42,6 +42,7 @@ set(firmwares_SRCS edgetx/yaml_expodata.cpp edgetx/yaml_curvedata.cpp edgetx/yaml_moduledata.cpp + edgetx/yaml_logicalswitchdata.cpp datahelpers.cpp customisation_data.cpp ) diff --git a/companion/src/firmwares/edgetx/yaml_logicalswitchdata.cpp b/companion/src/firmwares/edgetx/yaml_logicalswitchdata.cpp new file mode 100644 index 000000000..10b3b133e --- /dev/null +++ b/companion/src/firmwares/edgetx/yaml_logicalswitchdata.cpp @@ -0,0 +1,186 @@ +/* + * 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_logicalswitchdata.h" +#include "yaml_rawswitch.h" +#include "yaml_rawsource.h" + +static const YamlLookupTable funcLut = { + {LS_FN_OFF, "FUNC_NONE"}, + {LS_FN_VEQUAL, "FUNC_VEQUAL"}, + {LS_FN_VALMOSTEQUAL, "FUNC_VALMOSTEQUAL"}, + {LS_FN_VPOS, "FUNC_VPOS"}, + {LS_FN_VNEG, "FUNC_VNEG"}, + {LS_FN_APOS, "FUNC_APOS"}, + {LS_FN_ANEG, "FUNC_ANEG"}, + {LS_FN_AND, "FUNC_AND"}, + {LS_FN_OR, "FUNC_OR"}, + {LS_FN_XOR, "FUNC_XOR"}, + {LS_FN_EDGE, "FUNC_EDGE"}, + {LS_FN_EQUAL, "FUNC_EQUAL"}, + {LS_FN_GREATER, "FUNC_GREATER"}, + {LS_FN_LESS, "FUNC_LESS"}, + {LS_FN_DPOS, "FUNC_DIFFEGREATER"}, + {LS_FN_DAPOS, "FUNC_ADIFFEGREATER"}, + {LS_FN_TIMER, "FUNC_TIMER"}, + {LS_FN_STICKY, "FUNC_STICKY"}, +}; + +static int timerValue2lsw(uint32_t t) +{ + if (t < 20) { + return t - 129; + } else if (600) { + return t / 5 - 113; + } else { + return t / 10 - 53; + } +} +// val = [-129,-110] => [0,19] (step 1) +// val = [-109,6] => [20,595] (step 5) +// val = [7,122] => [600,1750] (step 10) +// +static int lswTimerValue(int val) +{ + return (val < -109 ? 129+val : (val < 7 ? (113+val)*5 : (53+val)*10)); +} + +namespace YAML +{ +Node convert::encode(const LogicalSwitchData& rhs) +{ + Node node; + node["func"] = funcLut << rhs.func; + + std::string def; + + switch (rhs.getFunctionFamily()) { + case LS_FAMILY_VBOOL: + case LS_FAMILY_STICKY: { + def += YamlRawSwitchEncode(RawSwitch(rhs.val1)); + def += ","; + def += YamlRawSwitchEncode(RawSwitch(rhs.val2)); + } break; + + case LS_FAMILY_EDGE: { + def += YamlRawSwitchEncode(RawSwitch(rhs.val1)); + def += ","; + def += std::to_string(lswTimerValue(rhs.val2)); + def += ","; + def += std::to_string(lswTimerValue(rhs.val3)); + } break; + + case LS_FAMILY_VCOMP: { + def += YamlRawSourceEncode(RawSource(rhs.val1)); + def += ","; + def += YamlRawSourceEncode(RawSource(rhs.val2)); + } break; + + case LS_FAMILY_TIMER: { + def += std::to_string(lswTimerValue(rhs.val1)); + def += ","; + def += std::to_string(lswTimerValue(rhs.val2)); + } break; + + default: { + def += YamlRawSourceEncode(RawSource(rhs.val1)); + def += ","; + def += std::to_string(rhs.val2); + } break; + } + + node["def"] = def; + node["delay"] = rhs.delay; + node["duration"] = rhs.duration; + node["andsw"] = YamlRawSwitchEncode(RawSwitch(rhs.andsw)); + + return node; +} + +bool convert::decode(const Node& node, + LogicalSwitchData& rhs) +{ + node["func"] >> funcLut >> rhs.func; + + std::string def_str; + node["def"] >> def_str; + std::stringstream def(def_str); + + switch (rhs.getFunctionFamily()) { + case LS_FAMILY_VBOOL: + case LS_FAMILY_STICKY: { + std::string sw_str; + getline(def, sw_str, ','); + rhs.val1 = YamlRawSwitchDecode(sw_str).toValue(); + rhs.val2 = YamlRawSwitchDecode(def.str()).toValue(); + } break; + + case LS_FAMILY_EDGE: { + std::string sw_str; + getline(def, sw_str, ','); + rhs.val1 = YamlRawSwitchDecode(sw_str).toValue(); + int v2=0, v3=0; + def >> v2; + rhs.val2 = timerValue2lsw(v2); + def.ignore(); + if (def.peek() == '<') { + rhs.val3 = -1; + } else if (def.peek() == '-') { + rhs.val3 = 0; + } else { + def >> v3; + rhs.val3 = timerValue2lsw(v3); + } + } break; + + case LS_FAMILY_VCOMP: { + std::string src_str; + getline(def, src_str, ','); + rhs.val1 = YamlRawSourceDecode(src_str).toValue(); + rhs.val2 = YamlRawSourceDecode(def.str()).toValue(); + } break; + + case LS_FAMILY_TIMER: { + int v1=0, v2=0; + def >> v1; + rhs.val1 = timerValue2lsw(v1); + def.ignore(); + def >> v2; + rhs.val2 = timerValue2lsw(v2); + } break; + + default: { + std::string src_str; + getline(def, src_str, ','); + rhs.val1 = YamlRawSourceDecode(src_str).toValue(); + def >> rhs.val2; + } break; + } + + node["delay"] >> rhs.delay; + node["duration"] >> rhs.duration; + + RawSwitch andsw; + node["andsw"] >> andsw; + rhs.andsw = andsw.toValue(); + + return true; +} +} // namespace YAML diff --git a/companion/src/firmwares/edgetx/yaml_logicalswitchdata.h b/companion/src/firmwares/edgetx/yaml_logicalswitchdata.h new file mode 100644 index 000000000..738a6fc8a --- /dev/null +++ b/companion/src/firmwares/edgetx/yaml_logicalswitchdata.h @@ -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 "logicalswitchdata.h" + +namespace YAML +{ +template <> +struct convert { + static Node encode(const LogicalSwitchData& rhs); + static bool decode(const Node& node, LogicalSwitchData& rhs); +}; +} // namespace YAML diff --git a/companion/src/firmwares/edgetx/yaml_modeldata.cpp b/companion/src/firmwares/edgetx/yaml_modeldata.cpp index ffca31292..242e95f1c 100644 --- a/companion/src/firmwares/edgetx/yaml_modeldata.cpp +++ b/companion/src/firmwares/edgetx/yaml_modeldata.cpp @@ -25,6 +25,7 @@ #include "yaml_expodata.h" #include "yaml_curvedata.h" #include "yaml_moduledata.h" +#include "yaml_logicalswitchdata.h" #include "modeldata.h" #include "output_data.h" @@ -315,7 +316,13 @@ Node convert::encode(const ModelData& rhs) node["points"] = points; } - // logicalSw[] + for (int i = 0; i < CPN_MAX_LOGICAL_SWITCHES; i++) { + const LogicalSwitchData& ls = rhs.logicalSw[i]; + if (!ls.isEmpty()) { + node["logicalSw"][std::to_string(i)] = ls; + } + } + // customFn[] // swashRingData @@ -397,8 +404,8 @@ bool convert::decode(const Node& node, ModelData& rhs) node["curves"] >> rhs.curves; YamlReadCurvePoints(node["points"], rhs.curves); - // logicalSw[] - // customFn[] + node["logicalSw"] >> rhs.logicalSw; + node["customFn"] >> rhs.customFn; // swashRingData diff --git a/companion/src/firmwares/edgetx/yaml_rawsource.cpp b/companion/src/firmwares/edgetx/yaml_rawsource.cpp index e05c10dd2..fc6f41103 100644 --- a/companion/src/firmwares/edgetx/yaml_rawsource.cpp +++ b/companion/src/firmwares/edgetx/yaml_rawsource.cpp @@ -51,8 +51,7 @@ const YamlLookupTable specialSourceLut = { // TODO: { ???, "TX_GPS" }, }; -namespace YAML { -Node convert::encode(const RawSource& rhs) +std::string YamlRawSourceEncode(const RawSource& rhs) { std::string src_str; switch (rhs.type) { @@ -123,13 +122,12 @@ Node convert::encode(const RawSource& rhs) src_str = "NONE"; break; } - - return Node(src_str); + return src_str; } -bool convert::decode(const Node& node, RawSource& rhs) +RawSource YamlRawSourceDecode(const std::string& src_str) { - std::string src_str = node.Scalar(); + RawSource rhs; const char* val = src_str.data(); size_t val_len = src_str.size(); @@ -252,8 +250,20 @@ bool convert::decode(const Node& node, RawSource& rhs) rhs.index = 0; } } - // TODO: raw analogs + + return rhs; +} +namespace YAML { +Node convert::encode(const RawSource& rhs) +{ + return Node(YamlRawSourceEncode(rhs)); +} + +bool convert::decode(const Node& node, RawSource& rhs) +{ + std::string src_str = node.Scalar(); + rhs = YamlRawSourceDecode(src_str); return true; } } // namespace YAML diff --git a/companion/src/firmwares/edgetx/yaml_rawsource.h b/companion/src/firmwares/edgetx/yaml_rawsource.h index 6cf25ba82..9775793b5 100644 --- a/companion/src/firmwares/edgetx/yaml_rawsource.h +++ b/companion/src/firmwares/edgetx/yaml_rawsource.h @@ -21,12 +21,13 @@ #include "yaml_ops.h" #include "rawsource.h" -namespace YAML { +std::string YamlRawSourceEncode(const RawSource& rhs); +RawSource YamlRawSourceDecode(const std::string& src_str); +namespace YAML { template <> struct convert { static Node encode(const RawSource& rhs); static bool decode(const Node& node, RawSource& rhs); }; - } diff --git a/companion/src/firmwares/edgetx/yaml_rawswitch.cpp b/companion/src/firmwares/edgetx/yaml_rawswitch.cpp index b43fea0db..59727c179 100644 --- a/companion/src/firmwares/edgetx/yaml_rawswitch.cpp +++ b/companion/src/firmwares/edgetx/yaml_rawswitch.cpp @@ -46,14 +46,9 @@ const YamlLookupTable switchTypeLut = { { SWITCH_TYPE_OFF, "OFF" }, }; -namespace YAML { - -ENUM_CONVERTER(RawSwitchType, switchTypeLut); - -Node convert::encode(const RawSwitch& rhs) +std::string YamlRawSwitchEncode(const RawSwitch& rhs) { std::string sw_str; - int32_t sval = rhs.index; if (rhs.index < 0) { sval = -sval; @@ -96,13 +91,12 @@ Node convert::encode(const RawSwitch& rhs) sw_str += LookupValue(switchTypeLut, rhs.type); break; } - - return Node(sw_str); + return sw_str; } -bool convert::decode(const Node& node, RawSwitch& rhs) +RawSwitch YamlRawSwitchDecode(const std::string& sw_str) { - const std::string& sw_str = node.Scalar(); + RawSwitch rhs; const char* val = sw_str.data(); size_t val_len = sw_str.size(); @@ -147,7 +141,21 @@ bool convert::decode(const Node& node, RawSwitch& rhs) if (neg) { rhs.index = -rhs.index; } + return rhs; +} +namespace YAML { + +ENUM_CONVERTER(RawSwitchType, switchTypeLut); + +Node convert::encode(const RawSwitch& rhs) +{ + return Node(YamlRawSwitchEncode(rhs)); +} + +bool convert::decode(const Node& node, RawSwitch& rhs) +{ + rhs = YamlRawSwitchDecode(node.Scalar()); return true; } } // namespace YAML diff --git a/companion/src/firmwares/edgetx/yaml_rawswitch.h b/companion/src/firmwares/edgetx/yaml_rawswitch.h index 95128aac2..fa0a824a1 100644 --- a/companion/src/firmwares/edgetx/yaml_rawswitch.h +++ b/companion/src/firmwares/edgetx/yaml_rawswitch.h @@ -21,6 +21,9 @@ #include "yaml_ops.h" #include "rawswitch.h" +std::string YamlRawSwitchEncode(const RawSwitch& rhs); +RawSwitch YamlRawSwitchDecode(const std::string& sw_str); + namespace YAML { template <>