Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add virtual inputs and virtual switches #5885

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
8 changes: 8 additions & 0 deletions radio/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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).")
Expand Down Expand Up @@ -389,6 +390,10 @@ if(DISABLE_MCUCHECK)
add_definitions(-DDISABLE_MCUCHECK)
endif()

if(VCONTROLS)
add_definitions(-DVCONTROLS)
endif()

set(SRC
${SRC}
edgetx.cpp
Expand Down Expand Up @@ -427,6 +432,9 @@ if(GUI)
endforeach()
endif()

if(VCONTROLS)
set(SRC ${SRC} vcontrols.cpp)
endif()

if(USBJ_EX)
add_definitions(-DUSBJ_EX)
Expand Down
14 changes: 14 additions & 0 deletions radio/src/dataconstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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) && defined(COLORLCD)
SWSRC_FIRST_VIRTUAL_SWITCH SKIP,
SWSRC_LAST_VIRTUAL_SWITCH SKIP = SWSRC_FIRST_VIRTUAL_SWITCH + MAX_VIRTUAL_SWITCHES - 1,
#endif

SWSRC_ON,
SWSRC_ONE,

Expand Down Expand Up @@ -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,
};

Expand Down Expand Up @@ -547,6 +555,11 @@ enum MixSources {
MIXSRC_FIRST_CH SKIP,
MIXSRC_LAST_CH SKIP = MIXSRC_FIRST_CH + MAX_OUTPUT_CHANNELS - 1,

#if defined(VCONTROLS) && defined(COLORLCD)
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,

Expand Down Expand Up @@ -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 {
Expand Down
4 changes: 4 additions & 0 deletions radio/src/gui/colorlcd/controls/sourcechoice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) && defined(COLORLCD)
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,
Expand Down
2 changes: 2 additions & 0 deletions radio/src/gui/colorlcd/controls/switchchoice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
38 changes: 35 additions & 3 deletions radio/src/gui/gui_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
#include "switches.h"
#include "mixes.h"

#if defined(VCONTROLS) && defined(COLORLCD)
#include "vcontrols.h"
#endif

#undef CPN
#include "MultiSubtypeDefs.h"

Expand Down Expand Up @@ -222,7 +226,15 @@ 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) {
if (source >= 0) {
const uint32_t mask = (1UL << source);
return (activeVirtualInputs & mask);
}
return false;
}
#endif
static bool isSourceGvarAvailable(int source) {
#if defined(GVARS)
return modelGVEnabled();
Expand Down Expand Up @@ -282,6 +294,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 },
Expand All @@ -306,7 +321,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)
{
Expand Down Expand Up @@ -391,7 +406,14 @@ bool isSwitchAvailable(int swtch, SwitchContext context)
int index = (swtch - SWSRC_FIRST_TRIM) / 2;
return index < keysGetMaxTrims();
}


#if defined(VCONTROLS) && defined(COLORLCD)
if ((swtch >= SWSRC_FIRST_VIRTUAL_SWITCH) && (swtch <= SWSRC_LAST_VIRTUAL_SWITCH)) {
const uint64_t mask = (uint64_t{1} << (swtch - SWSRC_FIRST_VIRTUAL_SWITCH));
return (activeVirtualSwitches & mask);
}
#endif

if (swtch >= SWSRC_FIRST_LOGICAL_SWITCH && swtch <= SWSRC_LAST_LOGICAL_SWITCH) {
if (context == GeneralCustomFunctionsContext) {
return false;
Expand Down Expand Up @@ -481,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 = (uint64_t{1} << swtch);
return (activeVirtualSwitches & mask);
}
#endif

static bool isSwitchOtherAvailable(int swtch, bool invert) {
swtch += SWSRC_ON;
if (invert && (swtch == SWSRC_ON || swtch == SWSRC_ONE))
Expand All @@ -506,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 },
Expand Down
3 changes: 3 additions & 0 deletions radio/src/lua/api_colorlcd_lvgl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
96 changes: 96 additions & 0 deletions radio/src/lua/api_general.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@
#define RADIO_VERSION FLAVOUR
#endif

#if defined(VCONTROLS) && defined(COLORLCD)
#include <algorithm>
#include "vcontrols.h"
#endif

#define VERSION_OSNAME "EdgeTX"

#define FIND_FIELD_DESC 0x01
Expand Down Expand Up @@ -2466,6 +2471,89 @@ 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 |= (uint64_t{1} << (sw - 1));
}
else {
activeVirtualSwitches &= ~(uint64_t{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 <= MAX_VIRTUAL_SWITCHES) {
const bool v = virtualSwitches & (uint64_t{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);
const bool on = lua_toboolean(L, 2);

if (1 <= sw && sw <= MAX_VIRTUAL_SWITCHES) {
if (on) {
virtualSwitches |= (uint64_t{1} << (sw - 1));
}
else {
virtualSwitches &= ~(uint64_t{1} << (sw - 1));
}
}
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 <= MAX_VIRTUAL_INPUTS) {
virtualInputs[ch - 1] = value;
}
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)
static int shmVar[16] = {0};

Expand Down Expand Up @@ -2998,6 +3086,14 @@ LROT_BEGIN(etxlib, NULL, 0)
#if defined(COLORLCD)
LROT_FUNCENTRY( setShmVar, luaSetShmVar )
LROT_FUNCENTRY( getShmVar, luaGetShmVar )
#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)
LROT_FUNCENTRY( activateVirtualInput, luaActivateVirtualInput)
#endif
LROT_FUNCENTRY( setStickySwitch, luaSetStickySwitch )
LROT_FUNCENTRY( getLogicalSwitchValue, luaGetLogicalSwitchValue )
Expand Down
8 changes: 6 additions & 2 deletions radio/src/mixer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -480,7 +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) {
return virtualInputs[i - MIXSRC_FIRST_VCONTROL];
}
#endif
else if (i <= MIXSRC_LAST_GVAR) {
#if defined(GVARS)
return GVAR_VALUE(i - MIXSRC_FIRST_GVAR, getGVarFlightMode(mixerCurrentFlightMode, i - MIXSRC_FIRST_GVAR));
Expand All @@ -489,7 +494,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) {
Expand Down
8 changes: 8 additions & 0 deletions radio/src/storage/storage_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -253,6 +257,10 @@ if(g_model.rssiSource) {

logicalSwitchesInit(false);

#if defined(VCONTROLS) && defined(COLORLCD)
resetVirtualControls();
#endif

restoreTimers();

for (int i=0; i<MAX_TELEMETRY_SENSORS; i++) {
Expand Down
Loading