From 84db6ffc2e14ce23c5ee22c3118bfc2f925c8b87 Mon Sep 17 00:00:00 2001 From: wimalopaan Date: Sat, 8 Feb 2025 16:03:52 +0100 Subject: [PATCH 01/11] first try to implement virtual inputs ans virtual switches --- radio/src/CMakeLists.txt | 8 ++++ radio/src/dataconstants.h | 14 +++++++ .../gui/colorlcd/controls/sourcechoice.cpp | 4 ++ .../gui/colorlcd/controls/switchchoice.cpp | 2 + radio/src/gui/gui_common.cpp | 14 ++++++- radio/src/lua/api_general.cpp | 39 +++++++++++++++++++ radio/src/mixer.cpp | 12 +++++- .../storage/yaml/yaml_datastructs_funcs.cpp | 32 ++++++++++++++- radio/src/strhelpers.cpp | 5 +++ radio/src/switches.cpp | 12 ++++++ radio/src/translations.cpp | 3 ++ radio/src/translations.h | 3 ++ radio/src/translations/de.h | 3 ++ radio/src/translations/en.h | 3 ++ radio/src/vcontrols.cpp | 6 +++ radio/src/vcontrols.h | 6 +++ 16 files changed, 161 insertions(+), 5 deletions(-) create mode 100644 radio/src/vcontrols.cpp create mode 100644 radio/src/vcontrols.h diff --git a/radio/src/CMakeLists.txt b/radio/src/CMakeLists.txt index 1febe265800..18c39d1286a 100644 --- a/radio/src/CMakeLists.txt +++ b/radio/src/CMakeLists.txt @@ -63,6 +63,7 @@ else() option(USBJ_EX "Enable USB Joystick Extension" ON) endif() option(POWER_LED_BLUE "Override Power LED to be normally Blue" OFF) +option(VCONTROLS "Enable virtual controls support" ON) # since we reset all default CMAKE compiler flags for firmware builds, provide an alternate way for user to specify additional flags. set(FIRMWARE_C_FLAGS "" CACHE STRING "Additional flags for firmware target c compiler (note: all CMAKE_C_FLAGS[_*] are ignored for firmware/bootloader).") @@ -389,6 +390,10 @@ if(DISABLE_MCUCHECK) add_definitions(-DDISABLE_MCUCHECK) endif() +if(VCONTROLS) + add_definitions(-DVCONTROLS) +endif() + set(SRC ${SRC} edgetx.cpp @@ -427,6 +432,9 @@ if(GUI) endforeach() endif() +if(VCONTROLS) + set(SRC ${SRC} vcontrols.cpp) +endif() if(USBJ_EX) add_definitions(-DUSBJ_EX) diff --git a/radio/src/dataconstants.h b/radio/src/dataconstants.h index 5ed0e87d242..a56649f4a05 100644 --- a/radio/src/dataconstants.h +++ b/radio/src/dataconstants.h @@ -55,6 +55,8 @@ #define MAX_TRAINER_CHANNELS 16 #define MAX_TELEMETRY_SENSORS 60 #define MAX_CUSTOM_SCREENS 10 + #define MAX_VIRTUAL_INPUTS 16 + #define MAX_VIRTUAL_SWITCHES 64 #elif defined(PCBX9D) || defined(PCBX9DP) || defined(PCBX9E) #define MAX_MODELS 60 #define MAX_OUTPUT_CHANNELS 32 // number of real output channels CH1-CH32 @@ -441,6 +443,11 @@ enum SwitchSources { SWSRC_FIRST_LOGICAL_SWITCH SKIP, SWSRC_LAST_LOGICAL_SWITCH SKIP = SWSRC_FIRST_LOGICAL_SWITCH + MAX_LOGICAL_SWITCHES - 1, +#if defined(VCONTROLS) + SWSRC_FIRST_VIRTUAL_SWITCH SKIP, + SWSRC_LAST_VIRTUAL_SWITCH SKIP = SWSRC_FIRST_VIRTUAL_SWITCH + MAX_VIRTUAL_SWITCHES - 1, +#endif + SWSRC_ON, SWSRC_ONE, @@ -483,6 +490,7 @@ enum SwitchTypes { SW_FLIGHT_MODE = 1 << 3, SW_TELEM = 1 << 4, SW_OTHER = 1 << 5, + SW_VIRTUAL = 1 << 6, SW_NONE = 1 << 20, }; @@ -547,6 +555,11 @@ enum MixSources { MIXSRC_FIRST_CH SKIP, MIXSRC_LAST_CH SKIP = MIXSRC_FIRST_CH + MAX_OUTPUT_CHANNELS - 1, +#if defined(VCONTROLS) + MIXSRC_FIRST_VCONTROL SKIP, + MIXSRC_LAST_VCONTROL SKIP = MIXSRC_FIRST_VCONTROL + MAX_VIRTUAL_INPUTS - 1, +#endif + MIXSRC_FIRST_GVAR SKIP, MIXSRC_LAST_GVAR SKIP = MIXSRC_FIRST_GVAR + MAX_GVARS - 1, @@ -596,6 +609,7 @@ enum SrcTypes { SRC_TELEM_COMP = 1 << 19, SRC_NONE = 1 << 20, SRC_INVERT = 1 << 21, + SRC_VCONTROL = 1 << 22, }; enum BacklightMode { diff --git a/radio/src/gui/colorlcd/controls/sourcechoice.cpp b/radio/src/gui/colorlcd/controls/sourcechoice.cpp index 6e82e452546..7a5a719d629 100644 --- a/radio/src/gui/colorlcd/controls/sourcechoice.cpp +++ b/radio/src/gui/colorlcd/controls/sourcechoice.cpp @@ -87,6 +87,10 @@ class SourceChoiceMenuToolbar : public MenuToolbar nullptr, STR_MENU_TRAINER); addButton(STR_CHAR_CHANNEL, MIXSRC_FIRST_CH, MIXSRC_LAST_CH, nullptr, STR_MENU_CHANNELS); +#if defined(VCONTROLS) + addButton("VI", MIXSRC_FIRST_VCONTROL, MIXSRC_LAST_VCONTROL, nullptr, + STR_MENU_VCONTROL); +#endif #if defined(GVARS) if (modelGVEnabled()) addButton(STR_CHAR_SLIDER, MIXSRC_FIRST_GVAR, MIXSRC_LAST_GVAR, nullptr, diff --git a/radio/src/gui/colorlcd/controls/switchchoice.cpp b/radio/src/gui/colorlcd/controls/switchchoice.cpp index 33372fd03ae..d90c3387003 100644 --- a/radio/src/gui/colorlcd/controls/switchchoice.cpp +++ b/radio/src/gui/colorlcd/controls/switchchoice.cpp @@ -39,6 +39,8 @@ class SwitchChoiceMenuToolbar : public MenuToolbar STR_MENU_TRIMS); addButton("LS", SWSRC_FIRST_LOGICAL_SWITCH, SWSRC_LAST_LOGICAL_SWITCH, nullptr, STR_MENU_LOGICAL_SWITCHES); + addButton("VS", SWSRC_FIRST_VIRTUAL_SWITCH, SWSRC_LAST_VIRTUAL_SWITCH, + nullptr, STR_MENU_VIRTUAL_SWITCHES); addButton("FM", SWSRC_FIRST_FLIGHT_MODE, SWSRC_LAST_FLIGHT_MODE, nullptr, STR_FLIGHT_MODE); addButton(STR_CHAR_TELEMETRY, SWSRC_FIRST_SENSOR, SWSRC_LAST_SENSOR, diff --git a/radio/src/gui/gui_common.cpp b/radio/src/gui/gui_common.cpp index 25fbcf80d11..8a772586d60 100644 --- a/radio/src/gui/gui_common.cpp +++ b/radio/src/gui/gui_common.cpp @@ -223,6 +223,9 @@ static bool isSourceTrainerAvailable(int source) { return g_model.trainerData.mode > 0; } +static bool isSourceVControlAvailable(int source) { + return true; +} static bool isSourceGvarAvailable(int source) { #if defined(GVARS) return modelGVEnabled(); @@ -282,6 +285,7 @@ static struct sourceAvailableCheck sourceChecks[] = { { MIXSRC_FIRST_TRAINER, MIXSRC_LAST_TRAINER, SRC_TRAINER, isSourceTrainerAvailable }, { MIXSRC_FIRST_CH, MIXSRC_LAST_CH, SRC_CHANNEL, isChannelUsed }, { MIXSRC_FIRST_CH, MIXSRC_LAST_CH, SRC_CHANNEL_ALL, sourceIsAvailable }, + { MIXSRC_FIRST_VCONTROL, MIXSRC_LAST_VCONTROL, SRC_VCONTROL, isSourceVControlAvailable }, { MIXSRC_FIRST_GVAR, MIXSRC_LAST_GVAR, SRC_GVAR, isSourceGvarAvailable }, { MIXSRC_TX_VOLTAGE, MIXSRC_TX_GPS, SRC_TX, sourceIsAvailable }, { MIXSRC_FIRST_TIMER, MIXSRC_LAST_TIMER, SRC_TIMER, isSourceTimerAvailable }, @@ -306,7 +310,7 @@ bool checkSourceAvailable(int source, uint32_t sourceTypes) #define SRC_COMMON \ SRC_STICK | SRC_POT | SRC_TILT | SRC_SPACEMOUSE | SRC_MINMAX | SRC_TRIM | \ - SRC_SWITCH | SRC_FUNC_SWITCH | SRC_LOGICAL_SWITCH | SRC_TRAINER | SRC_GVAR + SRC_SWITCH | SRC_FUNC_SWITCH | SRC_LOGICAL_SWITCH | SRC_TRAINER | SRC_GVAR | SRC_VCONTROL bool isSourceAvailable(int source) { @@ -391,7 +395,13 @@ bool isSwitchAvailable(int swtch, SwitchContext context) int index = (swtch - SWSRC_FIRST_TRIM) / 2; return index < keysGetMaxTrims(); } - + +#if defined(VCONTROLS) + if ((swtch >= SWSRC_FIRST_VIRTUAL_SWITCH) && (swtch <= SWSRC_LAST_VIRTUAL_SWITCH)) { + return true; + } +#endif + if (swtch >= SWSRC_FIRST_LOGICAL_SWITCH && swtch <= SWSRC_LAST_LOGICAL_SWITCH) { if (context == GeneralCustomFunctionsContext) { return false; diff --git a/radio/src/lua/api_general.cpp b/radio/src/lua/api_general.cpp index 161801362a6..9a0e88554b4 100644 --- a/radio/src/lua/api_general.cpp +++ b/radio/src/lua/api_general.cpp @@ -63,6 +63,11 @@ #define RADIO_VERSION FLAVOUR #endif +#if defined(VCONTROLS) +#include +#include "vcontrols.h" +#endif + #define VERSION_OSNAME "EdgeTX" #define FIND_FIELD_DESC 0x01 @@ -2466,6 +2471,36 @@ static int luaSerialSetPower(lua_State* L) } #endif +#if defined(VCONTROLS) +static int luaSetVirtualSwitch(lua_State * L) +{ + const int sw = luaL_checkinteger(L, 1); + const bool on = lua_toboolean(L, 2); + + if (1 <= sw && sw <= 64) { + if (on) { + virtualSwitches |= (1 << (sw - 1)); + } + else { + virtualSwitches &= ~(1 << (sw - 1)); + } +// TRACE("luaSetVirtualSwitch: %d, %b", (sw - 1), on); + } + return 0; +} +static int luaSetVirtualInput(lua_State * L) +{ + int ch = luaL_checkinteger(L, 1); + int value = std::clamp(luaL_checkinteger(L, 2), -1024, 1024); + + if (1 <= ch && ch <= 16) { + virtualInputs[ch - 1] = value; +// TRACE("luaSetVirtualInput: %d, %d", (ch - 1), virtualInputs[ch - 1]); + } + return 0; +} +#endif + #if defined(COLORLCD) static int shmVar[16] = {0}; @@ -2998,6 +3033,10 @@ LROT_BEGIN(etxlib, NULL, 0) #if defined(COLORLCD) LROT_FUNCENTRY( setShmVar, luaSetShmVar ) LROT_FUNCENTRY( getShmVar, luaGetShmVar ) +#endif +#if defined(VCONTROLS) + LROT_FUNCENTRY( setVirtualInput, luaSetVirtualInput) + LROT_FUNCENTRY( setVirtualSwitch, luaSetVirtualSwitch) #endif LROT_FUNCENTRY( setStickySwitch, luaSetStickySwitch ) LROT_FUNCENTRY( getLogicalSwitchValue, luaGetLogicalSwitchValue ) diff --git a/radio/src/mixer.cpp b/radio/src/mixer.cpp index 730eb7b4521..263d44f0064 100644 --- a/radio/src/mixer.cpp +++ b/radio/src/mixer.cpp @@ -25,6 +25,7 @@ #include "switches.h" #include "input_mapping.h" #include "mixes.h" +#include "vcontrols.h" #include "hal/adc_driver.h" #include "hal/trainer_driver.h" @@ -480,7 +481,15 @@ getvalue_t _getValue(mixsrc_t i, bool* valid) } else if (i <= MIXSRC_LAST_CH) { return ex_chans[i - MIXSRC_FIRST_CH]; } - + else if (i <= MIXSRC_LAST_VCONTROL) { +#if defined(VCONTROLS) +// TRACE("mixer: %d %d", (i - MIXSRC_FIRST_VCONTROL), virtualInputs[i - MIXSRC_FIRST_VCONTROL]); + return virtualInputs[i - MIXSRC_FIRST_VCONTROL]; +#else + if (valid != nullptr) *valid = false; + return 0; +#endif + } else if (i <= MIXSRC_LAST_GVAR) { #if defined(GVARS) return GVAR_VALUE(i - MIXSRC_FIRST_GVAR, getGVarFlightMode(mixerCurrentFlightMode, i - MIXSRC_FIRST_GVAR)); @@ -489,7 +498,6 @@ getvalue_t _getValue(mixsrc_t i, bool* valid) return 0; #endif } - else if (i == MIXSRC_TX_VOLTAGE) { return g_vbat100mV; } else if (i < MIXSRC_FIRST_TIMER) { diff --git a/radio/src/storage/yaml/yaml_datastructs_funcs.cpp b/radio/src/storage/yaml/yaml_datastructs_funcs.cpp index eaab984e806..c78359fe25c 100644 --- a/radio/src/storage/yaml/yaml_datastructs_funcs.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_funcs.cpp @@ -156,6 +156,7 @@ uint8_t find_sep(const char* val, uint8_t val_len) // - ls(n): logical switches // - tr(n): trainer input // - ch(n): channels +// - vin(n): virtual inputs // - gv(n): gvars // - tele(n): telemetry // @@ -207,7 +208,17 @@ static uint32_t r_mixSrcRaw(const YamlNode* node, const char* val, uint8_t val_l val += 3; val_len -= 3; // parse int and ignore closing ')' return yaml_str2uint(val, val_len) + MIXSRC_FIRST_CH; - + + } else if (val_len > 4 && + val[0] == 'v' && + val[1] == 'i' && + val[2] == 'n' && + val[3] == '(') { + + val += 4; val_len -= 4; + // parse int and ignore closing ')' + return yaml_str2uint(val, val_len) + MIXSRC_FIRST_VCONTROL; + } else if (val_len > 3 && val[0] == 'g' && val[1] == 'v' && @@ -392,6 +403,14 @@ static bool w_mixSrcRaw(const YamlNode* node, uint32_t val, yaml_writer_func wf, return false; str = closing_parenthesis; } + else if (val >= MIXSRC_FIRST_VCONTROL + && val <= MIXSRC_LAST_VCONTROL) { + + val -= MIXSRC_FIRST_VCONTROL; + if (!output_source_1_param("vin(", 4, val, wf, opaque)) + return false; + str = closing_parenthesis; + } else if (val >= MIXSRC_FIRST_GVAR && val <= MIXSRC_LAST_GVAR) { @@ -1067,6 +1086,12 @@ static uint32_t r_swtchSrc(const YamlNode* node, const char* val, uint8_t val_le ival = SWSRC_FIRST_LOGICAL_SWITCH + yaml_str2int(val+1, val_len-1) - 1; } + else if (val_len >= 2 + && val[0] == 'V' + && (val[1] >= '0' && val[1] <= '9')) { + + ival = SWSRC_FIRST_VIRTUAL_SWITCH + yaml_str2int(val+1, val_len-1) - 1; + } else if (val_len == 3 && val[0] == 'F' && val[1] == 'M' @@ -1133,6 +1158,11 @@ static bool w_swtchSrc_unquoted(const YamlNode* node, uint32_t val, wf(opaque, "L", 1); str = yaml_unsigned2str(sval - SWSRC_FIRST_LOGICAL_SWITCH + 1); return wf(opaque,str, strlen(str)); + } else if (sval <= SWSRC_LAST_VIRTUAL_SWITCH) { + + wf(opaque, "V", 1); + str = yaml_unsigned2str(sval - SWSRC_FIRST_VIRTUAL_SWITCH + 1); + return wf(opaque,str, strlen(str)); } else if (sval <= SWSRC_LAST_FLIGHT_MODE) { diff --git a/radio/src/strhelpers.cpp b/radio/src/strhelpers.cpp index dfb3243f184..ed6896c48f0 100644 --- a/radio/src/strhelpers.cpp +++ b/radio/src/strhelpers.cpp @@ -496,6 +496,9 @@ char *getSwitchPositionName(char *dest, swsrc_t idx) } else if (idx <= SWSRC_LAST_LOGICAL_SWITCH) { *s++ = 'L'; strAppendUnsigned(s, idx - SWSRC_FIRST_LOGICAL_SWITCH + 1, 2); + } else if (idx <= SWSRC_LAST_VIRTUAL_SWITCH) { + *s++ = 'V'; + strAppendUnsigned(s, idx - SWSRC_FIRST_VIRTUAL_SWITCH + 1, 2); } else if (idx <= SWSRC_ONE) { idx -= SWSRC_ON; getStringAtIndex(s, STR_ON_ONE_SWITCHES, idx); @@ -732,6 +735,8 @@ char *getSourceString(char (&destRef)[L], mixsrc_t idx) } else { strAppendStringWithIndex(dest, STR_CH, ch + 1); } + } else if (idx <= MIXSRC_LAST_VCONTROL) { + strAppendStringWithIndex(dest, STR_VC, idx + 1 - MIXSRC_FIRST_VCONTROL); } else if (idx <= MIXSRC_LAST_GVAR) { idx -= MIXSRC_FIRST_GVAR; #if defined(LIBOPENUI) diff --git a/radio/src/switches.cpp b/radio/src/switches.cpp index d3c687f7620..202277b0425 100644 --- a/radio/src/switches.cpp +++ b/radio/src/switches.cpp @@ -30,6 +30,9 @@ #include "input_mapping.h" #include "inactivity_timer.h" #include "tasks/mixer_task.h" +#if defined(VCONTROLS) +#include "vcontrols.h" +#endif #define CS_LAST_VALUE_INIT -32768 @@ -768,6 +771,15 @@ bool getSwitch(swsrc_t swtch, uint8_t flags) result = (idx == mixerCurrentFlightMode); #else result = false; +#endif + } + else if ((cs_idx >= SWSRC_FIRST_VIRTUAL_SWITCH) && (cs_idx <= SWSRC_LAST_VIRTUAL_SWITCH)) { +#if defined(VCONTROLS) + cs_idx -= SWSRC_FIRST_VIRTUAL_SWITCH; + const uint64_t mask = (1 << cs_idx); + result = virtualSwitches & mask; +#else + result = false; #endif } else { diff --git a/radio/src/translations.cpp b/radio/src/translations.cpp index b3ec71b956c..96e98a4fb42 100644 --- a/radio/src/translations.cpp +++ b/radio/src/translations.cpp @@ -241,6 +241,7 @@ const char STR_SLOWDOWN[] = TR_SLOWDOWN; const char STR_SLOWUP[] = TR_SLOWUP; const char STR_MIXES[] = TR_MIXES; const char STR_CV[] = TR_CV; +const char STR_VC[] = TR_VC; const char STR_GV[] = TR_GV; const char STR_RANGE[] = TR_RANGE; const char STR_CENTER[] = TR_CENTER; @@ -744,8 +745,10 @@ const char STR_MENU_HELI[] = TR_MENU_HELI; const char STR_MENU_TRIMS[] = TR_MENU_TRIMS; const char STR_MENU_SWITCHES[] = TR_MENU_SWITCHES; const char STR_MENU_LOGICAL_SWITCHES[] = TR_MENU_LOGICAL_SWITCHES; +const char STR_MENU_VIRTUAL_SWITCHES[] = TR_MENU_VIRTUAL_SWITCHES; const char STR_MENU_TRAINER[] = TR_MENU_TRAINER; const char STR_MENU_CHANNELS[] = TR_MENU_CHANNELS; +const char STR_MENU_VCONTROL[] = TR_MENU_VCONTROL; const char STR_MENU_GVARS[] = TR_MENU_GVARS; const char STR_MENU_TELEMETRY[] = TR_MENU_TELEMETRY; const char STR_MENU_DISPLAY[] = TR_MENU_DISPLAY; diff --git a/radio/src/translations.h b/radio/src/translations.h index d126c949560..8b90b66665a 100644 --- a/radio/src/translations.h +++ b/radio/src/translations.h @@ -373,6 +373,7 @@ extern const char STR_SLOWDOWN[]; extern const char STR_SLOWUP[]; extern const char STR_MIXES[]; extern const char STR_CV[]; +extern const char STR_VC[]; extern const char STR_GV[]; extern const char STR_RANGE[]; extern const char STR_CENTER[]; @@ -1132,8 +1133,10 @@ extern const char STR_MENU_HELI[]; extern const char STR_MENU_TRIMS[]; extern const char STR_MENU_SWITCHES[]; extern const char STR_MENU_LOGICAL_SWITCHES[]; +extern const char STR_MENU_VIRTUAL_SWITCHES[]; extern const char STR_MENU_TRAINER[]; extern const char STR_MENU_CHANNELS[]; +extern const char STR_MENU_VCONTROL[]; extern const char STR_MENU_GVARS[]; extern const char STR_MENU_TELEMETRY[]; extern const char STR_MENU_DISPLAY[]; diff --git a/radio/src/translations/de.h b/radio/src/translations/de.h index 98dd68ee59e..f18c4570bcf 100644 --- a/radio/src/translations/de.h +++ b/radio/src/translations/de.h @@ -346,6 +346,7 @@ #define TR_SLOWUP "Langs.Up" #define TR_MIXES "MISCHER" #define TR_CV "KV" +#define TR_VC "VIn" #if defined(PCBNV14) || defined(PCBPL18) #define TR_GV "GV" #else @@ -1174,8 +1175,10 @@ #define TR_MENU_TRIMS STR_CHAR_TRIM "Trimmung" #define TR_MENU_SWITCHES STR_CHAR_SWITCH "Schalter" #define TR_MENU_LOGICAL_SWITCHES STR_CHAR_SWITCH "Log. Schalter" +#define TR_MENU_VIRTUAL_SWITCHES STR_CHAR_SWITCH "Virt. Schalter" #define TR_MENU_TRAINER STR_CHAR_TRAINER "Trainer" #define TR_MENU_CHANNELS STR_CHAR_CHANNEL "Kanäle" +#define TR_MENU_VCONTROL "Virtuals" #define TR_MENU_GVARS STR_CHAR_SLIDER "Glob. Vars" #define TR_MENU_TELEMETRY STR_CHAR_TELEMETRY "Telemetrie" #define TR_MENU_DISPLAY "TELM-SEITEN" diff --git a/radio/src/translations/en.h b/radio/src/translations/en.h index 6125d4e6ff6..cd6b172d735 100644 --- a/radio/src/translations/en.h +++ b/radio/src/translations/en.h @@ -345,6 +345,7 @@ #define TR_SLOWUP "Slow up" #define TR_MIXES "MIXES" #define TR_CV "CV" +#define TR_VC "VIn" #if defined(PCBNV14) || defined(PCBPL18) #define TR_GV "GV" #else @@ -1171,8 +1172,10 @@ #define TR_MENU_TRIMS STR_CHAR_TRIM "Trims" #define TR_MENU_SWITCHES STR_CHAR_SWITCH "Switches" #define TR_MENU_LOGICAL_SWITCHES STR_CHAR_SWITCH "Logical switches" +#define TR_MENU_VIRTUAL_SWITCHES STR_CHAR_SWITCH "Virtual switches" #define TR_MENU_TRAINER STR_CHAR_TRAINER "Trainer" #define TR_MENU_CHANNELS STR_CHAR_CHANNEL "Channels" +#define TR_MENU_VCONTROL "Virtuals" #define TR_MENU_GVARS STR_CHAR_SLIDER "GVars" #define TR_MENU_TELEMETRY STR_CHAR_TELEMETRY "Telemetry" #define TR_MENU_DISPLAY "DISPLAY" diff --git a/radio/src/vcontrols.cpp b/radio/src/vcontrols.cpp new file mode 100644 index 00000000000..4bffd76df85 --- /dev/null +++ b/radio/src/vcontrols.cpp @@ -0,0 +1,6 @@ +#include "vcontrols.h" + +#include "edgetx.h" + +int16_t virtualInputs[MAX_VIRTUAL_INPUTS] = {}; +uint64_t virtualSwitches = 0; \ No newline at end of file diff --git a/radio/src/vcontrols.h b/radio/src/vcontrols.h new file mode 100644 index 00000000000..d4803a860ce --- /dev/null +++ b/radio/src/vcontrols.h @@ -0,0 +1,6 @@ +#pragma once + +#include "dataconstants.h" + +extern int16_t virtualInputs[MAX_VIRTUAL_INPUTS]; +extern uint64_t virtualSwitches; \ No newline at end of file From 5d6ff3430df1183fdbee38a02103a35082c3e724 Mon Sep 17 00:00:00 2001 From: wimalopaan Date: Sat, 8 Feb 2025 20:27:45 +0100 Subject: [PATCH 02/11] added function getVirtualSwitch --- radio/src/lua/api_general.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/radio/src/lua/api_general.cpp b/radio/src/lua/api_general.cpp index 9a0e88554b4..6ae0b824473 100644 --- a/radio/src/lua/api_general.cpp +++ b/radio/src/lua/api_general.cpp @@ -2472,6 +2472,20 @@ static int luaSerialSetPower(lua_State* L) #endif #if defined(VCONTROLS) +static int luaGetVirtualSwitch(lua_State * L) +{ + const int sw = luaL_checkinteger(L, 1); + + if (1 <= sw && sw <= 64) { + const bool v = virtualSwitches & (1 << (sw - 1)); + lua_pushboolean(L, v); + } + else { + lua_pushnil(L); + } + return 1; +} + static int luaSetVirtualSwitch(lua_State * L) { const int sw = luaL_checkinteger(L, 1); @@ -3037,6 +3051,7 @@ LROT_BEGIN(etxlib, NULL, 0) #if defined(VCONTROLS) LROT_FUNCENTRY( setVirtualInput, luaSetVirtualInput) LROT_FUNCENTRY( setVirtualSwitch, luaSetVirtualSwitch) + LROT_FUNCENTRY( getVirtualSwitch, luaGetVirtualSwitch) #endif LROT_FUNCENTRY( setStickySwitch, luaSetStickySwitch ) LROT_FUNCENTRY( getLogicalSwitchValue, luaGetLogicalSwitchValue ) From 2d0ee5b257e4db49d87b1eb73767ef3d0d62fd1a Mon Sep 17 00:00:00 2001 From: wimalopaan Date: Sat, 8 Feb 2025 21:51:25 +0100 Subject: [PATCH 03/11] disabled on BW --- radio/src/dataconstants.h | 4 ++-- radio/src/gui/gui_common.cpp | 7 +++++-- radio/src/lua/api_general.cpp | 6 +++--- radio/src/mixer.cpp | 8 ++------ radio/src/storage/yaml/yaml_datastructs_funcs.cpp | 12 ++++++++++-- radio/src/strhelpers.cpp | 10 ++++++++-- radio/src/switches.cpp | 6 ++---- radio/src/vcontrols.cpp | 4 +++- radio/src/vcontrols.h | 4 +++- 9 files changed, 38 insertions(+), 23 deletions(-) diff --git a/radio/src/dataconstants.h b/radio/src/dataconstants.h index a56649f4a05..fcabe7d3afa 100644 --- a/radio/src/dataconstants.h +++ b/radio/src/dataconstants.h @@ -443,7 +443,7 @@ enum SwitchSources { SWSRC_FIRST_LOGICAL_SWITCH SKIP, SWSRC_LAST_LOGICAL_SWITCH SKIP = SWSRC_FIRST_LOGICAL_SWITCH + MAX_LOGICAL_SWITCHES - 1, -#if defined(VCONTROLS) +#if defined(VCONTROLS) && defined(COLORLCD) SWSRC_FIRST_VIRTUAL_SWITCH SKIP, SWSRC_LAST_VIRTUAL_SWITCH SKIP = SWSRC_FIRST_VIRTUAL_SWITCH + MAX_VIRTUAL_SWITCHES - 1, #endif @@ -555,7 +555,7 @@ enum MixSources { MIXSRC_FIRST_CH SKIP, MIXSRC_LAST_CH SKIP = MIXSRC_FIRST_CH + MAX_OUTPUT_CHANNELS - 1, -#if defined(VCONTROLS) +#if defined(VCONTROLS) && defined(COLORLCD) MIXSRC_FIRST_VCONTROL SKIP, MIXSRC_LAST_VCONTROL SKIP = MIXSRC_FIRST_VCONTROL + MAX_VIRTUAL_INPUTS - 1, #endif diff --git a/radio/src/gui/gui_common.cpp b/radio/src/gui/gui_common.cpp index 8a772586d60..f084206540e 100644 --- a/radio/src/gui/gui_common.cpp +++ b/radio/src/gui/gui_common.cpp @@ -222,10 +222,11 @@ static bool isSourceLSAvailable(int source) { static bool isSourceTrainerAvailable(int source) { return g_model.trainerData.mode > 0; } - +#if defined(VCONTROLS) && defined(COLORLCD) static bool isSourceVControlAvailable(int source) { return true; } +#endif static bool isSourceGvarAvailable(int source) { #if defined(GVARS) return modelGVEnabled(); @@ -285,7 +286,9 @@ static struct sourceAvailableCheck sourceChecks[] = { { MIXSRC_FIRST_TRAINER, MIXSRC_LAST_TRAINER, SRC_TRAINER, isSourceTrainerAvailable }, { MIXSRC_FIRST_CH, MIXSRC_LAST_CH, SRC_CHANNEL, isChannelUsed }, { MIXSRC_FIRST_CH, MIXSRC_LAST_CH, SRC_CHANNEL_ALL, sourceIsAvailable }, +#if defined(VCONTROLS) && defined(COLORLCD) { MIXSRC_FIRST_VCONTROL, MIXSRC_LAST_VCONTROL, SRC_VCONTROL, isSourceVControlAvailable }, +#endif { MIXSRC_FIRST_GVAR, MIXSRC_LAST_GVAR, SRC_GVAR, isSourceGvarAvailable }, { MIXSRC_TX_VOLTAGE, MIXSRC_TX_GPS, SRC_TX, sourceIsAvailable }, { MIXSRC_FIRST_TIMER, MIXSRC_LAST_TIMER, SRC_TIMER, isSourceTimerAvailable }, @@ -396,7 +399,7 @@ bool isSwitchAvailable(int swtch, SwitchContext context) return index < keysGetMaxTrims(); } -#if defined(VCONTROLS) +#if defined(VCONTROLS) && defined(COLORLCD) if ((swtch >= SWSRC_FIRST_VIRTUAL_SWITCH) && (swtch <= SWSRC_LAST_VIRTUAL_SWITCH)) { return true; } diff --git a/radio/src/lua/api_general.cpp b/radio/src/lua/api_general.cpp index 6ae0b824473..376f74e79b8 100644 --- a/radio/src/lua/api_general.cpp +++ b/radio/src/lua/api_general.cpp @@ -63,7 +63,7 @@ #define RADIO_VERSION FLAVOUR #endif -#if defined(VCONTROLS) +#if defined(VCONTROLS) && defined(COLORLCD) #include #include "vcontrols.h" #endif @@ -2471,7 +2471,7 @@ static int luaSerialSetPower(lua_State* L) } #endif -#if defined(VCONTROLS) +#if defined(VCONTROLS) && defined(COLORLCD) static int luaGetVirtualSwitch(lua_State * L) { const int sw = luaL_checkinteger(L, 1); @@ -3048,7 +3048,7 @@ LROT_BEGIN(etxlib, NULL, 0) LROT_FUNCENTRY( setShmVar, luaSetShmVar ) LROT_FUNCENTRY( getShmVar, luaGetShmVar ) #endif -#if defined(VCONTROLS) +#if defined(VCONTROLS) && defined(COLORLCD) LROT_FUNCENTRY( setVirtualInput, luaSetVirtualInput) LROT_FUNCENTRY( setVirtualSwitch, luaSetVirtualSwitch) LROT_FUNCENTRY( getVirtualSwitch, luaGetVirtualSwitch) diff --git a/radio/src/mixer.cpp b/radio/src/mixer.cpp index 263d44f0064..5eb9c18134a 100644 --- a/radio/src/mixer.cpp +++ b/radio/src/mixer.cpp @@ -481,15 +481,11 @@ getvalue_t _getValue(mixsrc_t i, bool* valid) } else if (i <= MIXSRC_LAST_CH) { return ex_chans[i - MIXSRC_FIRST_CH]; } +#if defined(VCONTROLS) && defined(COLORLCD) else if (i <= MIXSRC_LAST_VCONTROL) { -#if defined(VCONTROLS) -// TRACE("mixer: %d %d", (i - MIXSRC_FIRST_VCONTROL), virtualInputs[i - MIXSRC_FIRST_VCONTROL]); return virtualInputs[i - MIXSRC_FIRST_VCONTROL]; -#else - if (valid != nullptr) *valid = false; - return 0; -#endif } +#endif else if (i <= MIXSRC_LAST_GVAR) { #if defined(GVARS) return GVAR_VALUE(i - MIXSRC_FIRST_GVAR, getGVarFlightMode(mixerCurrentFlightMode, i - MIXSRC_FIRST_GVAR)); diff --git a/radio/src/storage/yaml/yaml_datastructs_funcs.cpp b/radio/src/storage/yaml/yaml_datastructs_funcs.cpp index c78359fe25c..720760e8e1b 100644 --- a/radio/src/storage/yaml/yaml_datastructs_funcs.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_funcs.cpp @@ -209,6 +209,7 @@ static uint32_t r_mixSrcRaw(const YamlNode* node, const char* val, uint8_t val_l // parse int and ignore closing ')' return yaml_str2uint(val, val_len) + MIXSRC_FIRST_CH; +#if defined(VCONTROLS) && defined(COLORLCD) } else if (val_len > 4 && val[0] == 'v' && val[1] == 'i' && @@ -218,7 +219,7 @@ static uint32_t r_mixSrcRaw(const YamlNode* node, const char* val, uint8_t val_l val += 4; val_len -= 4; // parse int and ignore closing ')' return yaml_str2uint(val, val_len) + MIXSRC_FIRST_VCONTROL; - +#endif } else if (val_len > 3 && val[0] == 'g' && val[1] == 'v' && @@ -403,6 +404,7 @@ static bool w_mixSrcRaw(const YamlNode* node, uint32_t val, yaml_writer_func wf, return false; str = closing_parenthesis; } +#if defined(VCONTROLS) && defined(COLORLCD) else if (val >= MIXSRC_FIRST_VCONTROL && val <= MIXSRC_LAST_VCONTROL) { @@ -411,6 +413,7 @@ static bool w_mixSrcRaw(const YamlNode* node, uint32_t val, yaml_writer_func wf, return false; str = closing_parenthesis; } +#endif else if (val >= MIXSRC_FIRST_GVAR && val <= MIXSRC_LAST_GVAR) { @@ -1086,12 +1089,14 @@ static uint32_t r_swtchSrc(const YamlNode* node, const char* val, uint8_t val_le ival = SWSRC_FIRST_LOGICAL_SWITCH + yaml_str2int(val+1, val_len-1) - 1; } +#if defined(VCONTROLS) && defined(COLORLCD) else if (val_len >= 2 && val[0] == 'V' && (val[1] >= '0' && val[1] <= '9')) { ival = SWSRC_FIRST_VIRTUAL_SWITCH + yaml_str2int(val+1, val_len-1) - 1; } +#endif else if (val_len == 3 && val[0] == 'F' && val[1] == 'M' @@ -1158,12 +1163,15 @@ static bool w_swtchSrc_unquoted(const YamlNode* node, uint32_t val, wf(opaque, "L", 1); str = yaml_unsigned2str(sval - SWSRC_FIRST_LOGICAL_SWITCH + 1); return wf(opaque,str, strlen(str)); - } else if (sval <= SWSRC_LAST_VIRTUAL_SWITCH) { + } +#if defined(VCONTROLS) && defined(COLORLCD) + else if (sval <= SWSRC_LAST_VIRTUAL_SWITCH) { wf(opaque, "V", 1); str = yaml_unsigned2str(sval - SWSRC_FIRST_VIRTUAL_SWITCH + 1); return wf(opaque,str, strlen(str)); } +#endif else if (sval <= SWSRC_LAST_FLIGHT_MODE) { wf(opaque, "FM", 2); diff --git a/radio/src/strhelpers.cpp b/radio/src/strhelpers.cpp index ed6896c48f0..e82780d82b8 100644 --- a/radio/src/strhelpers.cpp +++ b/radio/src/strhelpers.cpp @@ -496,9 +496,11 @@ char *getSwitchPositionName(char *dest, swsrc_t idx) } else if (idx <= SWSRC_LAST_LOGICAL_SWITCH) { *s++ = 'L'; strAppendUnsigned(s, idx - SWSRC_FIRST_LOGICAL_SWITCH + 1, 2); +#if defined(VCONTROLS) && defined(COLORLCD) } else if (idx <= SWSRC_LAST_VIRTUAL_SWITCH) { *s++ = 'V'; strAppendUnsigned(s, idx - SWSRC_FIRST_VIRTUAL_SWITCH + 1, 2); +#endif } else if (idx <= SWSRC_ONE) { idx -= SWSRC_ON; getStringAtIndex(s, STR_ON_ONE_SWITCHES, idx); @@ -735,9 +737,13 @@ char *getSourceString(char (&destRef)[L], mixsrc_t idx) } else { strAppendStringWithIndex(dest, STR_CH, ch + 1); } - } else if (idx <= MIXSRC_LAST_VCONTROL) { + } +#if defined(VCONTROLS) && defined(COLORLCD) + else if (idx <= MIXSRC_LAST_VCONTROL) { strAppendStringWithIndex(dest, STR_VC, idx + 1 - MIXSRC_FIRST_VCONTROL); - } else if (idx <= MIXSRC_LAST_GVAR) { + } +#endif + else if (idx <= MIXSRC_LAST_GVAR) { idx -= MIXSRC_FIRST_GVAR; #if defined(LIBOPENUI) char *s = strAppendStringWithIndex(dest, STR_GV, idx + 1); diff --git a/radio/src/switches.cpp b/radio/src/switches.cpp index 202277b0425..1d57501ad3f 100644 --- a/radio/src/switches.cpp +++ b/radio/src/switches.cpp @@ -773,15 +773,13 @@ bool getSwitch(swsrc_t swtch, uint8_t flags) result = false; #endif } +#if defined(VCONTROLS) && defined(COLORLCD) else if ((cs_idx >= SWSRC_FIRST_VIRTUAL_SWITCH) && (cs_idx <= SWSRC_LAST_VIRTUAL_SWITCH)) { -#if defined(VCONTROLS) cs_idx -= SWSRC_FIRST_VIRTUAL_SWITCH; const uint64_t mask = (1 << cs_idx); result = virtualSwitches & mask; -#else - result = false; -#endif } +#endif else { cs_idx -= SWSRC_FIRST_LOGICAL_SWITCH; result = lswFm[mixerCurrentFlightMode].lsw[cs_idx].state; diff --git a/radio/src/vcontrols.cpp b/radio/src/vcontrols.cpp index 4bffd76df85..6f311ecf802 100644 --- a/radio/src/vcontrols.cpp +++ b/radio/src/vcontrols.cpp @@ -2,5 +2,7 @@ #include "edgetx.h" +#if defined(VCONTROLS) && defined(COLORLCD) int16_t virtualInputs[MAX_VIRTUAL_INPUTS] = {}; -uint64_t virtualSwitches = 0; \ No newline at end of file +uint64_t virtualSwitches = 0; +#endif diff --git a/radio/src/vcontrols.h b/radio/src/vcontrols.h index d4803a860ce..7513eba9597 100644 --- a/radio/src/vcontrols.h +++ b/radio/src/vcontrols.h @@ -2,5 +2,7 @@ #include "dataconstants.h" +#if defined(VCONTROLS) && defined(COLORLCD) extern int16_t virtualInputs[MAX_VIRTUAL_INPUTS]; -extern uint64_t virtualSwitches; \ No newline at end of file +extern uint64_t virtualSwitches; +#endif From b48acd4a4330f663bdb14c041c68428af9938aa0 Mon Sep 17 00:00:00 2001 From: wimalopaan Date: Sun, 9 Feb 2025 08:33:51 +0100 Subject: [PATCH 04/11] added Copyright to new files --- radio/src/vcontrols.cpp | 23 ++++++++++++++++++++++- radio/src/vcontrols.h | 23 ++++++++++++++++++++++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/radio/src/vcontrols.cpp b/radio/src/vcontrols.cpp index 6f311ecf802..6aa5646c5b3 100644 --- a/radio/src/vcontrols.cpp +++ b/radio/src/vcontrols.cpp @@ -1,4 +1,25 @@ -#include "vcontrols.h" +/* + * 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 "vcontrols.h" #include "edgetx.h" diff --git a/radio/src/vcontrols.h b/radio/src/vcontrols.h index 7513eba9597..4aa46540eed 100644 --- a/radio/src/vcontrols.h +++ b/radio/src/vcontrols.h @@ -1,4 +1,25 @@ -#pragma once +/* + * 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. + */ + + #pragma once #include "dataconstants.h" From d7272dbb2a6fe515a8d4324614d1f1e7c413aeb6 Mon Sep 17 00:00:00 2001 From: wimalopaan Date: Sun, 9 Feb 2025 16:11:58 +0100 Subject: [PATCH 05/11] add LUA functions activateVirtualInput() and activateVirtualSwitch(). This way the list of available sources and switches is as short as possible, if a LUA script sets the activation accordingly. If no LUA script does activation, the virtuals do not show up at all. --- .../gui/colorlcd/controls/sourcechoice.cpp | 2 +- radio/src/gui/gui_common.cpp | 13 ++++++- radio/src/lua/api_general.cpp | 37 +++++++++++++++++-- radio/src/vcontrols.cpp | 3 ++ radio/src/vcontrols.h | 3 ++ 5 files changed, 51 insertions(+), 7 deletions(-) diff --git a/radio/src/gui/colorlcd/controls/sourcechoice.cpp b/radio/src/gui/colorlcd/controls/sourcechoice.cpp index 7a5a719d629..cb4f4644826 100644 --- a/radio/src/gui/colorlcd/controls/sourcechoice.cpp +++ b/radio/src/gui/colorlcd/controls/sourcechoice.cpp @@ -87,7 +87,7 @@ class SourceChoiceMenuToolbar : public MenuToolbar nullptr, STR_MENU_TRAINER); addButton(STR_CHAR_CHANNEL, MIXSRC_FIRST_CH, MIXSRC_LAST_CH, nullptr, STR_MENU_CHANNELS); -#if defined(VCONTROLS) +#if defined(VCONTROLS) && defined(COLORLCD) addButton("VI", MIXSRC_FIRST_VCONTROL, MIXSRC_LAST_VCONTROL, nullptr, STR_MENU_VCONTROL); #endif diff --git a/radio/src/gui/gui_common.cpp b/radio/src/gui/gui_common.cpp index f084206540e..49a9a3896a9 100644 --- a/radio/src/gui/gui_common.cpp +++ b/radio/src/gui/gui_common.cpp @@ -28,6 +28,10 @@ #include "switches.h" #include "mixes.h" +#if defined(VCONTROLS) && defined(COLORLCD) +#include "vcontrols.h" +#endif + #undef CPN #include "MultiSubtypeDefs.h" @@ -224,7 +228,11 @@ static bool isSourceTrainerAvailable(int source) { } #if defined(VCONTROLS) && defined(COLORLCD) static bool isSourceVControlAvailable(int source) { - return true; + if (source >= 0) { + const uint32_t mask = (1UL << source); + return (activeVirtualInputs & mask); + } + return false; } #endif static bool isSourceGvarAvailable(int source) { @@ -401,7 +409,8 @@ bool isSwitchAvailable(int swtch, SwitchContext context) #if defined(VCONTROLS) && defined(COLORLCD) if ((swtch >= SWSRC_FIRST_VIRTUAL_SWITCH) && (swtch <= SWSRC_LAST_VIRTUAL_SWITCH)) { - return true; + const uint64_t mask = (1UL << (swtch - SWSRC_FIRST_VIRTUAL_SWITCH)); + return (activeVirtualSwitches & mask); } #endif diff --git a/radio/src/lua/api_general.cpp b/radio/src/lua/api_general.cpp index 376f74e79b8..5e8edcfae20 100644 --- a/radio/src/lua/api_general.cpp +++ b/radio/src/lua/api_general.cpp @@ -2472,11 +2472,39 @@ static int luaSerialSetPower(lua_State* L) #endif #if defined(VCONTROLS) && defined(COLORLCD) +static int luaActivateVirtualSwitch(lua_State * L) { + const int sw = luaL_checkinteger(L, 1); + const bool on = lua_toboolean(L, 2); + + if (1 <= sw && sw <= MAX_VIRTUAL_SWITCHES) { + if (on) { + activeVirtualSwitches |= (1 << (sw - 1)); + } + else { + activeVirtualSwitches &= ~(1 << (sw - 1)); + } + } + return 0; +} +static int luaActivateVirtualInput(lua_State * L) { + const int ch = luaL_checkinteger(L, 1); + const bool on = lua_toboolean(L, 2); + + if (1 <= ch && ch <= MAX_VIRTUAL_INPUTS) { + if (on) { + activeVirtualInputs |= (1 << (ch - 1)); + } + else { + activeVirtualInputs &= ~(1 << (ch - 1)); + } + } + return 0; +} static int luaGetVirtualSwitch(lua_State * L) { const int sw = luaL_checkinteger(L, 1); - if (1 <= sw && sw <= 64) { + if (1 <= sw && sw <= MAX_VIRTUAL_SWITCHES) { const bool v = virtualSwitches & (1 << (sw - 1)); lua_pushboolean(L, v); } @@ -2491,7 +2519,7 @@ static int luaSetVirtualSwitch(lua_State * L) const int sw = luaL_checkinteger(L, 1); const bool on = lua_toboolean(L, 2); - if (1 <= sw && sw <= 64) { + if (1 <= sw && sw <= MAX_VIRTUAL_SWITCHES) { if (on) { virtualSwitches |= (1 << (sw - 1)); } @@ -2507,9 +2535,8 @@ static int luaSetVirtualInput(lua_State * L) int ch = luaL_checkinteger(L, 1); int value = std::clamp(luaL_checkinteger(L, 2), -1024, 1024); - if (1 <= ch && ch <= 16) { + if (1 <= ch && ch <= MAX_VIRTUAL_INPUTS) { virtualInputs[ch - 1] = value; -// TRACE("luaSetVirtualInput: %d, %d", (ch - 1), virtualInputs[ch - 1]); } return 0; } @@ -3052,6 +3079,8 @@ LROT_BEGIN(etxlib, NULL, 0) LROT_FUNCENTRY( setVirtualInput, luaSetVirtualInput) LROT_FUNCENTRY( setVirtualSwitch, luaSetVirtualSwitch) LROT_FUNCENTRY( getVirtualSwitch, luaGetVirtualSwitch) + LROT_FUNCENTRY( activateVirtualSwitch, luaActivateVirtualSwitch) + LROT_FUNCENTRY( activateVirtualInput, luaActivateVirtualInput) #endif LROT_FUNCENTRY( setStickySwitch, luaSetStickySwitch ) LROT_FUNCENTRY( getLogicalSwitchValue, luaGetLogicalSwitchValue ) diff --git a/radio/src/vcontrols.cpp b/radio/src/vcontrols.cpp index 6aa5646c5b3..3a40ff72e7f 100644 --- a/radio/src/vcontrols.cpp +++ b/radio/src/vcontrols.cpp @@ -26,4 +26,7 @@ #if defined(VCONTROLS) && defined(COLORLCD) int16_t virtualInputs[MAX_VIRTUAL_INPUTS] = {}; uint64_t virtualSwitches = 0; + +uint32_t activeVirtualInputs = 0; +uint64_t activeVirtualSwitches = 0; #endif diff --git a/radio/src/vcontrols.h b/radio/src/vcontrols.h index 4aa46540eed..fbb9acee4d3 100644 --- a/radio/src/vcontrols.h +++ b/radio/src/vcontrols.h @@ -26,4 +26,7 @@ #if defined(VCONTROLS) && defined(COLORLCD) extern int16_t virtualInputs[MAX_VIRTUAL_INPUTS]; extern uint64_t virtualSwitches; + +extern uint32_t activeVirtualInputs; +extern uint64_t activeVirtualSwitches; #endif From 172cd7d8e3710239a1bfaa7ee573ec205aa9adc8 Mon Sep 17 00:00:00 2001 From: wimalopaan Date: Sun, 9 Feb 2025 16:22:29 +0100 Subject: [PATCH 06/11] fixed bit-mask width for virtual switches --- radio/src/switches.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radio/src/switches.cpp b/radio/src/switches.cpp index 1d57501ad3f..5b0d7dfbc3a 100644 --- a/radio/src/switches.cpp +++ b/radio/src/switches.cpp @@ -776,7 +776,7 @@ bool getSwitch(swsrc_t swtch, uint8_t flags) #if defined(VCONTROLS) && defined(COLORLCD) else if ((cs_idx >= SWSRC_FIRST_VIRTUAL_SWITCH) && (cs_idx <= SWSRC_LAST_VIRTUAL_SWITCH)) { cs_idx -= SWSRC_FIRST_VIRTUAL_SWITCH; - const uint64_t mask = (1 << cs_idx); + const uint64_t mask = (1UL << cs_idx); result = virtualSwitches & mask; } #endif From b34c014b98efe2fe609771845c39c98c5f744bbf Mon Sep 17 00:00:00 2001 From: wimalopaan Date: Tue, 11 Feb 2025 20:09:16 +0100 Subject: [PATCH 07/11] reset virtual controls when switched between models --- radio/src/storage/storage_common.cpp | 8 ++++++++ radio/src/vcontrols.cpp | 9 +++++++++ radio/src/vcontrols.h | 2 ++ 3 files changed, 19 insertions(+) diff --git a/radio/src/storage/storage_common.cpp b/radio/src/storage/storage_common.cpp index 2fec387a5cd..a0017e8727d 100644 --- a/radio/src/storage/storage_common.cpp +++ b/radio/src/storage/storage_common.cpp @@ -25,6 +25,10 @@ #include "mixes.h" #include "switches.h" +#if defined(VCONTROLS) && defined(COLORLCD) +#include "vcontrols.h" +#endif + #if defined(COLORLCD) #include "view_main.h" #endif @@ -253,6 +257,10 @@ if(g_model.rssiSource) { logicalSwitchesInit(false); +#if defined(VCONTROLS) && defined(COLORLCD) + resetVirtualControls(); +#endif + restoreTimers(); for (int i=0; i Date: Sun, 2 Mar 2025 07:34:24 +0100 Subject: [PATCH 08/11] added the virtual switches to the lvgl switch picker --- radio/src/gui/gui_common.cpp | 10 ++++++++++ radio/src/lua/api_colorlcd_lvgl.cpp | 3 +++ 2 files changed, 13 insertions(+) diff --git a/radio/src/gui/gui_common.cpp b/radio/src/gui/gui_common.cpp index 49a9a3896a9..1cc19986f62 100644 --- a/radio/src/gui/gui_common.cpp +++ b/radio/src/gui/gui_common.cpp @@ -503,6 +503,13 @@ static bool isSwitchTelemAvailable(int swtch, bool invert) { return isTelemetryFieldAvailable(swtch); } +#if defined(VCONTROLS) && defined(COLORLCD) +static bool isVSwitchAvailable(int swtch, bool invert) { + const uint64_t mask = (1UL << swtch); + return (activeVirtualSwitches & mask); +} +#endif + static bool isSwitchOtherAvailable(int swtch, bool invert) { swtch += SWSRC_ON; if (invert && (swtch == SWSRC_ON || swtch == SWSRC_ONE)) @@ -528,6 +535,9 @@ static struct switchAvailableCheck switchChecks[] = { { SWSRC_FIRST_SWITCH, SWSRC_LAST_MULTIPOS_SWITCH, SW_SWITCH, isSwitchSwitchAvailable }, { SWSRC_FIRST_TRIM, SWSRC_LAST_TRIM, SW_TRIM, isSwitchTrimAvailable }, { SWSRC_FIRST_LOGICAL_SWITCH, SWSRC_LAST_LOGICAL_SWITCH, SW_LOGICAL_SWITCH, isSwitchLSAvailable }, +#if defined(VCONTROLS) && defined(COLORLCD) + { SWSRC_FIRST_VIRTUAL_SWITCH, SWSRC_LAST_VIRTUAL_SWITCH, SW_VIRTUAL, isVSwitchAvailable }, +#endif { SWSRC_FIRST_FLIGHT_MODE, SWSRC_LAST_FLIGHT_MODE, SW_FLIGHT_MODE, isSwitchFMAvailable }, { SWSRC_FIRST_SENSOR, SWSRC_LAST_SENSOR, SW_TELEM, isSwitchTelemAvailable }, { SWSRC_ON, SWSRC_COUNT - 1, SW_OTHER, isSwitchOtherAvailable }, diff --git a/radio/src/lua/api_colorlcd_lvgl.cpp b/radio/src/lua/api_colorlcd_lvgl.cpp index 5e910cd0062..3dc5772e940 100644 --- a/radio/src/lua/api_colorlcd_lvgl.cpp +++ b/radio/src/lua/api_colorlcd_lvgl.cpp @@ -393,6 +393,9 @@ LROT_BEGIN(lvgllib, NULL, 0) LROT_NUMENTRY(SW_SWITCH, SW_SWITCH) LROT_NUMENTRY(SW_TRIM, SW_TRIM) LROT_NUMENTRY(SW_LOGICAL_SWITCH, SW_LOGICAL_SWITCH) +#if defined(VCONTROLS) && defined(COLORLCD) + LROT_NUMENTRY(SW_VIRTUAL, SW_VIRTUAL) +#endif LROT_NUMENTRY(SW_TELEM, SW_TELEM) LROT_NUMENTRY(SW_OTHER, SW_OTHER) LROT_NUMENTRY(SW_CLEAR, SW_NONE) From 00082e3be2a5cd1a340701994edcc7fd906b44ff Mon Sep 17 00:00:00 2001 From: wimalopaan Date: Tue, 4 Mar 2025 17:54:51 +0100 Subject: [PATCH 09/11] fixed virtual switches greater 32 --- radio/src/lua/api_general.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/radio/src/lua/api_general.cpp b/radio/src/lua/api_general.cpp index 5e8edcfae20..3bf65b7a1d7 100644 --- a/radio/src/lua/api_general.cpp +++ b/radio/src/lua/api_general.cpp @@ -2478,10 +2478,10 @@ static int luaActivateVirtualSwitch(lua_State * L) { if (1 <= sw && sw <= MAX_VIRTUAL_SWITCHES) { if (on) { - activeVirtualSwitches |= (1 << (sw - 1)); + activeVirtualSwitches |= (1UL << (sw - 1)); } else { - activeVirtualSwitches &= ~(1 << (sw - 1)); + activeVirtualSwitches &= ~(1UL << (sw - 1)); } } return 0; @@ -2505,7 +2505,7 @@ static int luaGetVirtualSwitch(lua_State * L) const int sw = luaL_checkinteger(L, 1); if (1 <= sw && sw <= MAX_VIRTUAL_SWITCHES) { - const bool v = virtualSwitches & (1 << (sw - 1)); + const bool v = virtualSwitches & (1UL << (sw - 1)); lua_pushboolean(L, v); } else { @@ -2521,10 +2521,10 @@ static int luaSetVirtualSwitch(lua_State * L) if (1 <= sw && sw <= MAX_VIRTUAL_SWITCHES) { if (on) { - virtualSwitches |= (1 << (sw - 1)); + virtualSwitches |= (1UL << (sw - 1)); } else { - virtualSwitches &= ~(1 << (sw - 1)); + virtualSwitches &= ~(1UL << (sw - 1)); } // TRACE("luaSetVirtualSwitch: %d, %b", (sw - 1), on); } From 9d289ce6f73362c57780534e78216a92995c24d3 Mon Sep 17 00:00:00 2001 From: wimalopaan Date: Wed, 5 Mar 2025 14:44:48 +0100 Subject: [PATCH 10/11] fixed bit shifts on radio firmware --- radio/src/gui/gui_common.cpp | 4 ++-- radio/src/lua/api_general.cpp | 10 +++++----- radio/src/switches.cpp | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/radio/src/gui/gui_common.cpp b/radio/src/gui/gui_common.cpp index 1cc19986f62..145a01f08e1 100644 --- a/radio/src/gui/gui_common.cpp +++ b/radio/src/gui/gui_common.cpp @@ -409,7 +409,7 @@ bool isSwitchAvailable(int swtch, SwitchContext context) #if defined(VCONTROLS) && defined(COLORLCD) if ((swtch >= SWSRC_FIRST_VIRTUAL_SWITCH) && (swtch <= SWSRC_LAST_VIRTUAL_SWITCH)) { - const uint64_t mask = (1UL << (swtch - SWSRC_FIRST_VIRTUAL_SWITCH)); + const uint64_t mask = (uint64_t{1} << (swtch - SWSRC_FIRST_VIRTUAL_SWITCH)); return (activeVirtualSwitches & mask); } #endif @@ -505,7 +505,7 @@ static bool isSwitchTelemAvailable(int swtch, bool invert) { #if defined(VCONTROLS) && defined(COLORLCD) static bool isVSwitchAvailable(int swtch, bool invert) { - const uint64_t mask = (1UL << swtch); + const uint64_t mask = (uint64_t{1} << swtch); return (activeVirtualSwitches & mask); } #endif diff --git a/radio/src/lua/api_general.cpp b/radio/src/lua/api_general.cpp index 3bf65b7a1d7..97749f715f0 100644 --- a/radio/src/lua/api_general.cpp +++ b/radio/src/lua/api_general.cpp @@ -2478,10 +2478,10 @@ static int luaActivateVirtualSwitch(lua_State * L) { if (1 <= sw && sw <= MAX_VIRTUAL_SWITCHES) { if (on) { - activeVirtualSwitches |= (1UL << (sw - 1)); + activeVirtualSwitches |= (uint64_t{1} << (sw - 1)); } else { - activeVirtualSwitches &= ~(1UL << (sw - 1)); + activeVirtualSwitches &= ~(uint64_t{1} << (sw - 1)); } } return 0; @@ -2505,7 +2505,7 @@ static int luaGetVirtualSwitch(lua_State * L) const int sw = luaL_checkinteger(L, 1); if (1 <= sw && sw <= MAX_VIRTUAL_SWITCHES) { - const bool v = virtualSwitches & (1UL << (sw - 1)); + const bool v = virtualSwitches & (uint64_t{1} << (sw - 1)); lua_pushboolean(L, v); } else { @@ -2521,10 +2521,10 @@ static int luaSetVirtualSwitch(lua_State * L) if (1 <= sw && sw <= MAX_VIRTUAL_SWITCHES) { if (on) { - virtualSwitches |= (1UL << (sw - 1)); + virtualSwitches |= (uint64_t{1} << (sw - 1)); } else { - virtualSwitches &= ~(1UL << (sw - 1)); + virtualSwitches &= ~(uint64_t{1} << (sw - 1)); } // TRACE("luaSetVirtualSwitch: %d, %b", (sw - 1), on); } diff --git a/radio/src/switches.cpp b/radio/src/switches.cpp index 5b0d7dfbc3a..fbc6c52780b 100644 --- a/radio/src/switches.cpp +++ b/radio/src/switches.cpp @@ -776,7 +776,7 @@ bool getSwitch(swsrc_t swtch, uint8_t flags) #if defined(VCONTROLS) && defined(COLORLCD) else if ((cs_idx >= SWSRC_FIRST_VIRTUAL_SWITCH) && (cs_idx <= SWSRC_LAST_VIRTUAL_SWITCH)) { cs_idx -= SWSRC_FIRST_VIRTUAL_SWITCH; - const uint64_t mask = (1UL << cs_idx); + const uint64_t mask = (uint64_t{1} << cs_idx); result = virtualSwitches & mask; } #endif From f296d20de09b5eaf6b69494a34fbe31d42bdb103 Mon Sep 17 00:00:00 2001 From: wimalopaan Date: Thu, 6 Mar 2025 12:08:06 +0100 Subject: [PATCH 11/11] added luaGetVirstualInput --- radio/src/lua/api_general.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/radio/src/lua/api_general.cpp b/radio/src/lua/api_general.cpp index 97749f715f0..3fe71b70d1b 100644 --- a/radio/src/lua/api_general.cpp +++ b/radio/src/lua/api_general.cpp @@ -2526,7 +2526,6 @@ static int luaSetVirtualSwitch(lua_State * L) else { virtualSwitches &= ~(uint64_t{1} << (sw - 1)); } -// TRACE("luaSetVirtualSwitch: %d, %b", (sw - 1), on); } return 0; } @@ -2540,6 +2539,19 @@ static int luaSetVirtualInput(lua_State * L) } return 0; } +static int luaGetVirtualInput(lua_State * L) +{ + const int ch = luaL_checkinteger(L, 1); + + if (1 <= ch && ch <= MAX_VIRTUAL_INPUTS) { + const int value = virtualInputs[ch - 1]; + lua_pushinteger(L, value); + } + else { + lua_pushnil(L); + } + return 1; +} #endif #if defined(COLORLCD) @@ -3077,6 +3089,7 @@ LROT_BEGIN(etxlib, NULL, 0) #endif #if defined(VCONTROLS) && defined(COLORLCD) LROT_FUNCENTRY( setVirtualInput, luaSetVirtualInput) + LROT_FUNCENTRY( getVirtualInput, luaGetVirtualInput) LROT_FUNCENTRY( setVirtualSwitch, luaSetVirtualSwitch) LROT_FUNCENTRY( getVirtualSwitch, luaGetVirtualSwitch) LROT_FUNCENTRY( activateVirtualSwitch, luaActivateVirtualSwitch)