feat: special function to push customisable switches (#5497)

Co-authored-by: philmoz <phil.a.mitchell@gmail.com>
Co-authored-by: elecpower <elecpower@users.noreply.github.com>
This commit is contained in:
3djc
2024-09-14 11:56:42 +10:00
committed by GitHub
co-authored by philmoz elecpower
parent 40449bf730
commit d417228677
48 changed files with 287 additions and 27 deletions
+16
View File
@@ -468,6 +468,22 @@ int BoardJson::getSwitchTagNum(const SwitchesTable * switches, int index)
return -1;
}
const int BoardJson::getSwitchTypeOffset(Board::SwitchType type)
{
return getSwitchTypeOffset(m_switches, type);
}
// static
int BoardJson::getSwitchTypeOffset(const SwitchesTable * switches, Board::SwitchType type)
{
for (int i = 0; i < (int)switches->size(); i++) {
if (type == switches->at(i).type)
return i;
}
return 0;
}
const int BoardJson::getSwitchYamlIndex(const QString val, YamlLookupType ylt) const
{
for (int i = 0; i < (int)m_switches->size(); i++) {
+6 -4
View File
@@ -41,7 +41,7 @@ class BoardJson
};
struct InputDefn {
Board::AnalogInputType type = AIT_NONE;
Board::AnalogInputType type = AIT_NONE;
std::string tag = "";
std::string name = "";
std::string shortName = "";
@@ -61,7 +61,7 @@ class BoardJson
};
struct SwitchDefn {
Board::SwitchType type = Board::SWITCH_NOT_AVAILABLE;
Board::SwitchType type = Board::SWITCH_NOT_AVAILABLE;
std::string tag = "";
std::string name = "";
int flags = 0;
@@ -77,8 +77,8 @@ class BoardJson
typedef std::vector<SwitchDefn> SwitchesTable;
struct TrimDefn {
std::string tag = "";
std::string name = "";
std::string tag = "";
std::string name = "";
Board::LookupValueType cfgYaml = Board::LVT_TAG;
Board::LookupValueType refYaml = Board::LVT_NAME;
@@ -124,6 +124,7 @@ class BoardJson
const QString getSwitchName(int index) const;
const QString getSwitchTag(int index) const;
const int getSwitchTagNum(int index) const;
const int getSwitchTypeOffset(Board::SwitchType type);
const int getSwitchYamlIndex(const QString val, YamlLookupType ylt) const;
const QString getSwitchYamlName(int index, YamlLookupType ylt) const;
@@ -183,6 +184,7 @@ private:
static QString getSwitchName(const SwitchesTable * switches, int index);
static QString getSwitchTag(const SwitchesTable * switches, int index);
static int getSwitchTagNum(const SwitchesTable * switches, int index);
static int getSwitchTypeOffset(const SwitchesTable * switches, Board::SwitchType type);
static int getTrimIndex(const TrimsTable * trims, QString val, Board::LookupValueType lvt);
static QString getTrimName(const TrimsTable * trims, int index);
+5
View File
@@ -954,6 +954,11 @@ int Boards::getSwitchTagNum(int index, Board::Type board)
return getBoardJson(board)->getSwitchTagNum(index);
}
int Boards::getSwitchTypeOffset(Board::SwitchType type, Board::Type board)
{
return getBoardJson(board)->getSwitchTypeOffset(type);
}
int Boards::getSwitchYamlIndex(QString val, int ylt, Board::Type board)
{
return getBoardJson(board)->getSwitchYamlIndex(val, (BoardJson::YamlLookupType)ylt);
+1
View File
@@ -352,6 +352,7 @@ class Boards
static QString getSwitchName(int index, Board::Type board = Board::BOARD_UNKNOWN);
static QString getSwitchTag(int index, Board::Type board = Board::BOARD_UNKNOWN);
static int getSwitchTagNum(int index, Board::Type board = Board::BOARD_UNKNOWN);
static int getSwitchTypeOffset(Board::SwitchType type, Board::Type board = Board::BOARD_UNKNOWN);
static int getSwitchYamlIndex(QString val, int ylt, Board::Type board = Board::BOARD_UNKNOWN);
static QString getSwitchYamlName(int index, int ylt, Board::Type board = Board::BOARD_UNKNOWN);
@@ -132,6 +132,10 @@ QString CustomFunctionData::funcToString(const AssignFunc func, const ModelData
return tr("RGB leds");
else if (func == FuncLCDtoVideo)
return tr("LCD to Video");
else if (func >= FuncPushCustomSwitch1 && func <= FuncPushCustomSwitchLast) {
const int idx = Boards::getSwitchTypeOffset(Board::SWITCH_FUNC) + func - FuncPushCustomSwitch1 + 1;
return tr("Push Custom Switch %1").arg(RawSource(SOURCE_TYPE_SWITCH, idx).toString(model));
}
else {
return QString(CPN_STR_UNKNOWN_ITEM);
}
@@ -146,7 +150,7 @@ QString CustomFunctionData::paramToString(const ModelData * model) const
if ((func >= FuncOverrideCH1 && func <= FuncOverrideCHLast) || func == FuncSetScreen) {
return QString("%1").arg(param);
}
else if (func == FuncLogs) {
else if (func == FuncLogs || (func >= FuncPushCustomSwitch1 && func <= FuncPushCustomSwitchLast)) {
return QString("%1").arg(param / 10.0) + tr("s");
}
else if (func == FuncPlaySound) {
@@ -260,7 +264,8 @@ bool CustomFunctionData::isFuncAvailable(const int index, const ModelData * mode
((index == FuncSetScreen && !Boards::getCapability(fw->getBoard(), Board::HasColorLcd))) ||
((index == FuncDisableAudioAmp && !Boards::getCapability(fw->getBoard(), Board::HasAudioMuteGPIO))) ||
((index == FuncRGBLed && !Boards::getCapability(fw->getBoard(), Board::HasLedStripGPIO))) ||
((index == FuncLCDtoVideo && !IS_FATFISH_F16(fw->getBoard())))
((index == FuncLCDtoVideo && !IS_FATFISH_F16(fw->getBoard()))) ||
((index >= FuncPushCustomSwitch1 && index <= FuncPushCustomSwitchLast) && !Boards::getCapability(fw->getBoard(), Board::FunctionSwitches))
);
return !ret;
}
@@ -73,6 +73,8 @@ enum AssignFunc {
FuncDisableAudioAmp,
FuncRGBLed,
FuncLCDtoVideo,
FuncPushCustomSwitch1,
FuncPushCustomSwitchLast = FuncPushCustomSwitch1 + CPN_MAX_SWITCHES_FUNCTION - 1,
FuncCount,
FuncReserve = -1
};
@@ -63,6 +63,7 @@ static const YamlLookupTable customFnLut = {
{ FuncDisableAudioAmp, "DISABLE_AUDIO_AMP" },
{ FuncRGBLed, "RGB_LED" },
{ FuncLCDtoVideo, "LCD_TO_VIDEO" },
{ FuncPushCustomSwitch1, "PUSH_CUST_SWITCH" },
};
static const YamlLookupTable trainerLut = {
@@ -124,7 +125,8 @@ Node convert<CustomFunctionData>::encode(const CustomFunctionData& rhs)
int fn = rhs.func;
int p1 = 0;
if(fn >= FuncOverrideCH1 && fn <= FuncOverrideCHLast) {
if (fn >= FuncOverrideCH1 && fn <= FuncOverrideCHLast) {
p1 = fn - (int)FuncOverrideCH1;
fn = (int)FuncOverrideCH1;
} else if (fn >= FuncTrainer && fn <= FuncTrainerChannels) {
@@ -142,7 +144,11 @@ Node convert<CustomFunctionData>::encode(const CustomFunctionData& rhs)
} else if (fn >= FuncBindInternalModule && fn <= FuncBindExternalModule) {
p1 = fn - (int)FuncBindInternalModule;
fn = (int)FuncBindInternalModule;
} else if (fn >= FuncPushCustomSwitch1 && fn <= FuncPushCustomSwitchLast) {
p1 = fn - (int)FuncPushCustomSwitch1;
fn = (int)FuncPushCustomSwitch1;
}
node["func"] = LookupValue(customFnLut, fn);
bool add_comma = true;
@@ -217,6 +223,11 @@ Node convert<CustomFunctionData>::encode(const CustomFunctionData& rhs)
case FuncSetScreen:
def += std::to_string(rhs.param);
break;
case FuncPushCustomSwitch1:
def += std::to_string(p1);
def += ",";
def += std::to_string(rhs.param);
break;
default:
add_comma = false;
break;
@@ -264,18 +275,18 @@ bool convert<CustomFunctionData>::decode(const Node& node,
switch(rhs.func) {
case FuncOverrideCH1: {
int ch=0;
def >> ch;
rhs.func = (AssignFunc)((int)rhs.func + ch);
def.ignore();
def >> rhs.param;
int ch=0;
def >> ch;
rhs.func = (AssignFunc)((int)rhs.func + ch);
def.ignore();
def >> rhs.param;
} break;
case FuncTrainer: {
std::string value_str;
getline(def, value_str, ',');
int value=0;
Node(value_str) >> trainerLut >> value;
rhs.func = (AssignFunc)((int)rhs.func + value);
std::string value_str;
getline(def, value_str, ',');
int value=0;
Node(value_str) >> trainerLut >> value;
rhs.func = (AssignFunc)((int)rhs.func + value);
} break;
case FuncPlaySound: {
std::string snd;
@@ -379,6 +390,15 @@ bool convert<CustomFunctionData>::decode(const Node& node,
def >> param;
rhs.param = param;
} break;
case FuncPushCustomSwitch1: {
int sw = 0;
def >> sw;
rhs.func = (AssignFunc)((int)rhs.func + sw);
def.ignore();
int param = 0;
def >> param;
rhs.param = param;
} break;
default:
break;
}
+3 -2
View File
@@ -194,9 +194,10 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
case SOURCE_TYPE_SWITCH:
dfltName = Boards::getSwitchInfo(index - 1, board).name.c_str();
if (Boards::isSwitchFunc(index - 1, board)) {
if (model && index <= CPN_MAX_SWITCHES_FUNCTION) {
if (model) {
int fsindex = Boards::getSwitchTagNum(index - 1, board) - 1;
custName = QString(model->functionSwitchNames[fsindex]).trimmed();
if (fsindex >= 0 && fsindex < CPN_MAX_SWITCHES_FUNCTION)
custName = QString(model->functionSwitchNames[fsindex]).trimmed();
}
}
else {
+1 -1
View File
@@ -398,7 +398,7 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM;
}
}
else if (func == FuncLogs) {
else if (func == FuncLogs || (func >= FuncPushCustomSwitch1 && func <= FuncPushCustomSwitchLast)) {
fswtchParam[i]->setDecimals(1);
fswtchParam[i]->setMinimum(0);
fswtchParam[i]->setMaximum(25.5);
Executable → Regular
+54
View File
@@ -64,6 +64,9 @@ Functions cfn_sorted[] = {
/* 暂停背景音乐 */ FUNC_BACKGND_MUSIC_PAUSE,
/* 振动 */ FUNC_HAPTIC,
/* Lua脚本 */ FUNC_PLAY_SCRIPT,
#if defined(FUNCTION_SWITCHES)
/* Push CS */ FUNC_PUSH_CUST_SWITCH,
#endif
/* RGB LED 灯 */ FUNC_RGB_LED,
/* Vario传感器 */ FUNC_VARIO,
#elif defined(TRANSLATIONS_CZ)
@@ -92,6 +95,9 @@ Functions cfn_sorted[] = {
/* Podsvětlení */ FUNC_BACKLIGHT,
#endif
/* Přehrát wav */ FUNC_PLAY_TRACK,
#if defined(FUNCTION_SWITCHES)
/* Push CS */ FUNC_PUSH_CUST_SWITCH,
#endif
/* Reset */ FUNC_RESET,
/* RGB světlo */ FUNC_RGB_LED,
/* Snímek LCD */ FUNC_SCREENSHOT,
@@ -129,6 +135,9 @@ Functions cfn_sorted[] = {
/* Modul tilslut */ FUNC_BIND,
/* Nulstil */ FUNC_RESET,
/* Overskriv */ FUNC_OVERRIDE_CHANNEL,
#if defined(FUNCTION_SWITCHES)
/* Push CS */ FUNC_PUSH_CUST_SWITCH,
#endif
/* RGB led */ FUNC_RGB_LED,
/* Ræs tilstand */ FUNC_RACING_MODE,
/* SD Log */ FUNC_LOGS,
@@ -171,6 +180,9 @@ Functions cfn_sorted[] = {
/* Lehrer */ FUNC_TRAINER,
/* Lua Skript */ FUNC_PLAY_SCRIPT,
/* ModuleBind */ FUNC_BIND,
#if defined(FUNCTION_SWITCHES)
/* Push CS */ FUNC_PUSH_CUST_SWITCH,
#endif
/* RacingMode */ FUNC_RACING_MODE,
/* RangeCheck */ FUNC_RANGECHECK,
/* RGB LED */ FUNC_RGB_LED,
@@ -221,6 +233,9 @@ Functions cfn_sorted[] = {
/* Oir pista */ FUNC_PLAY_TRACK,
/* Oir sonido */ FUNC_PLAY_SOUND,
/* Oir valor */ FUNC_PLAY_VALUE,
#if defined(FUNCTION_SWITCHES)
/* Push CS */ FUNC_PUSH_CUST_SWITCH,
#endif
/* RacingMode */ FUNC_RACING_MODE,
/* Reset */ FUNC_RESET,
/* RGB leds */ FUNC_RGB_LED,
@@ -258,6 +273,9 @@ Functions cfn_sorted[] = {
/* Play Sound */ FUNC_PLAY_SOUND,
/* Play Track */ FUNC_PLAY_TRACK,
/* Play Value */ FUNC_PLAY_VALUE,
#if defined(FUNCTION_SWITCHES)
/* Push CS */ FUNC_PUSH_CUST_SWITCH,
#endif
/* RacingMode */ FUNC_RACING_MODE,
/* RangeCheck */ FUNC_RANGECHECK,
/* Reset */ FUNC_RESET,
@@ -302,6 +320,9 @@ Functions cfn_sorted[] = {
#endif
/* Pause Musique */ FUNC_BACKGND_MUSIC_PAUSE,
/* Photo Écran */ FUNC_SCREENSHOT,
#if defined(FUNCTION_SWITCHES)
/* Push CS */ FUNC_PUSH_CUST_SWITCH,
#endif
/* Racing Mode */ FUNC_RACING_MODE,
/* Régle Failsafe */ FUNC_SET_FAILSAFE,
/* Remise à 0 */ FUNC_RESET,
@@ -337,6 +358,9 @@ Functions cfn_sorted[] = {
/* Play Sound */ FUNC_PLAY_SOUND,
/* Play Track */ FUNC_PLAY_TRACK,
/* Play Value */ FUNC_PLAY_VALUE,
#if defined(FUNCTION_SWITCHES)
/* Push CS */ FUNC_PUSH_CUST_SWITCH,
#endif
/* RangeCheck */ FUNC_RANGECHECK,
/* Reset */ FUNC_RESET,
/* RGB leds */ FUNC_RGB_LED,
@@ -381,6 +405,9 @@ Functions cfn_sorted[] = {
/* Musica Sf || */ FUNC_BACKGND_MUSIC_PAUSE,
#if defined(COLORLCD)
/* No Touch */ FUNC_DISABLE_TOUCH,
#endif
#if defined(FUNCTION_SWITCHES)
/* Push CS */ FUNC_PUSH_CUST_SWITCH,
#endif
/* RangeCheck */ FUNC_RANGECHECK,
/* Regola */ FUNC_ADJUST_GVAR,
@@ -412,6 +439,9 @@ Functions cfn_sorted[] = {
/* LCD to Video */ FUNC_LCD_TO_VIDEO,
#endif
/* LUAスクリプト */ FUNC_PLAY_SCRIPT,
#if defined(FUNCTION_SWITCHES)
/* Push CS */ FUNC_PUSH_CUST_SWITCH,
#endif
/* RGB LED */ FUNC_RGB_LED,
/* SDログ出力 */ FUNC_LOGS,
/* オーディオアンプ OFF */ FUNC_DISABLE_AUDIO_AMP,
@@ -468,6 +498,9 @@ Functions cfn_sorted[] = {
/* Override */ FUNC_OVERRIDE_CHANNEL,
/* Play Track */ FUNC_PLAY_TRACK,
/* Play Value */ FUNC_PLAY_VALUE,
#if defined(FUNCTION_SWITCHES)
/* Push CS */ FUNC_PUSH_CUST_SWITCH,
#endif
/* RacingMode */ FUNC_RACING_MODE,
/* RangeCheck */ FUNC_RANGECHECK,
/* Reset */ FUNC_RESET,
@@ -508,6 +541,9 @@ Functions cfn_sorted[] = {
#endif
#if !defined(OLED_SCREEN)
/* Podświetl */ FUNC_BACKLIGHT,
#endif
#if defined(FUNCTION_SWITCHES)
/* Push CS */ FUNC_PUSH_CUST_SWITCH,
#endif
/* RacingMode */ FUNC_RACING_MODE,
/* RangeCheck */ FUNC_RANGECHECK,
@@ -554,6 +590,9 @@ Functions cfn_sorted[] = {
/* ModCorrida */ FUNC_RACING_MODE,
#if defined(COLORLCD)
/* No Touch */ FUNC_DISABLE_TOUCH,
#endif
#if defined(FUNCTION_SWITCHES)
/* Push CS */ FUNC_PUSH_CUST_SWITCH,
#endif
/* RangeCheck */ FUNC_RANGECHECK,
/* Rep Valor */ FUNC_PLAY_VALUE,
@@ -577,6 +616,9 @@ Functions cfn_sorted[] = {
#endif
/* Lua скрипт */ FUNC_PLAY_SCRIPT,
/* Play Value */ FUNC_PLAY_VALUE,
#if defined(FUNCTION_SWITCHES)
/* Push CS */ FUNC_PUSH_CUST_SWITCH,
#endif
/* RGB подсветка */ FUNC_RGB_LED,
/* SD логи */ FUNC_LOGS,
/* Авар управ */ FUNC_SET_FAILSAFE,
@@ -635,6 +677,9 @@ Functions cfn_sorted[] = {
/* Musik */ FUNC_BACKGND_MUSIC,
/* Parkoppla modul */ FUNC_BIND,
/* Pausa Musik */ FUNC_BACKGND_MUSIC_PAUSE,
#if defined(FUNCTION_SWITCHES)
/* Push CS */ FUNC_PUSH_CUST_SWITCH,
#endif
/* Range check */ FUNC_RANGECHECK,
/* RGB ledljus */ FUNC_RGB_LED,
/* Skärmbild */ FUNC_SCREENSHOT,
@@ -656,6 +701,9 @@ Functions cfn_sorted[] = {
/* Återställ */ FUNC_RESET,
#elif defined(TRANSLATIONS_TW)
/* Lua腳本 */ FUNC_PLAY_SCRIPT,
#if defined(FUNCTION_SWITCHES)
/* Push CS */ FUNC_PUSH_CUST_SWITCH,
#endif
/* RGB led燈 */ FUNC_RGB_LED,
/* Vario傳感器 */ FUNC_VARIO,
#if defined(OLED_SCREEN)
@@ -736,6 +784,9 @@ Functions cfn_sorted[] = {
/* LCD to Video */ FUNC_LCD_TO_VIDEO,
#endif
/* Lua Скрипт */ FUNC_PLAY_SCRIPT,
#if defined(FUNCTION_SWITCHES)
/* Push CS */ FUNC_PUSH_CUST_SWITCH,
#endif
/* RGB leds */ FUNC_RGB_LED,
/* SD лог */ FUNC_LOGS,
#else
@@ -763,6 +814,9 @@ Functions cfn_sorted[] = {
/* Play Sound */ FUNC_PLAY_SOUND,
/* Play Track */ FUNC_PLAY_TRACK,
/* Play Value */ FUNC_PLAY_VALUE,
#if defined(FUNCTION_SWITCHES)
/* Push CS */ FUNC_PUSH_CUST_SWITCH,
#endif
/* RacingMode */ FUNC_RACING_MODE,
/* RangeCheck */ FUNC_RANGECHECK,
/* Reset */ FUNC_RESET,
+3
View File
@@ -687,6 +687,9 @@ enum Functions {
FUNC_RGB_LED,
#if defined(VIDEO_SWITCH) || defined(CFN_ONLY)
FUNC_LCD_TO_VIDEO,
#endif
#if defined(FUNCTION_SWITCHES) || defined(CFN_ONLY)
FUNC_PUSH_CUST_SWITCH,
#endif
FUNC_TEST, // MUST remain last
#if defined(DEBUG)
+2 -2
View File
@@ -178,12 +178,12 @@ PACK(struct CustomFunctionData {
int16_t val;
uint8_t mode;
uint8_t param;
NOBACKUP(int32_t spare);
int32_t val2;
}) all;
NOBACKUP(PACK(struct {
int32_t val1;
NOBACKUP(int32_t val2);
int32_t val2;
}) clear);
}) NAME(fp) SKIP;
uint8_t active : 1 SKIP;
+1 -1
View File
@@ -470,7 +470,7 @@ inline bool isFunctionActive(uint8_t func)
{
return globalFunctionsContext.isFunctionActive(func) || modelFunctionsContext.isFunctionActive(func);
}
void evalFunctions(const CustomFunctionData * functions, CustomFunctionsContext & functionsContext);
void evalFunctions(CustomFunctionData * functions, CustomFunctionsContext & functionsContext);
inline void customFunctionsReset()
{
globalFunctionsContext.reset();
+36 -2
View File
@@ -137,10 +137,13 @@ bool isRepeatDelayElapsed(const CustomFunctionData * functions, CustomFunctionsC
#define VOLUME_HYSTERESIS 10 // how much must a input value change to actually be considered for new volume setting
getvalue_t requiredSpeakerVolumeRawLast = 1024 + 1; //initial value must be outside normal range
void evalFunctions(const CustomFunctionData * functions, CustomFunctionsContext & functionsContext)
void evalFunctions(CustomFunctionData * functions, CustomFunctionsContext & functionsContext)
{
MASK_FUNC_TYPE newActiveFunctions = 0;
MASK_CFN_TYPE newActiveSwitches = 0;
#if defined(FUNCTION_SWITCHES)
functionSwitchFunctionState = 0;
#endif
uint8_t playFirstIndex = (functions == g_model.customFn ? 1 : 1+MAX_SPECIAL_FUNCTIONS);
#define PLAY_INDEX (i+playFirstIndex)
@@ -161,7 +164,7 @@ void evalFunctions(const CustomFunctionData * functions, CustomFunctionsContext
bool videoEnabled = false;
#endif
for (uint8_t i=0; i<MAX_SPECIAL_FUNCTIONS; i++) {
const CustomFunctionData * cfn = &functions[i];
CustomFunctionData * cfn = &functions[i];
swsrc_t swtch = CFN_SWITCH(cfn);
if (swtch) {
MASK_CFN_TYPE switch_mask = ((MASK_CFN_TYPE)1 << i);
@@ -365,6 +368,22 @@ void evalFunctions(const CustomFunctionData * functions, CustomFunctionsContext
}
break;
#if defined(FUNCTION_SWITCHES)
case FUNC_PUSH_CUST_SWITCH:
if (CFN_PARAM(cfn)) { // Duration is set
if (! CFN_VAL2(cfn) ) { // Duration not started yet
CFN_VAL2(cfn) = timersGetMsTick() + CFN_PARAM(cfn) * 100;
functionSwitchFunctionState |= 1 << CFN_CS_INDEX(cfn);
}
else if (timersGetMsTick() < (uint32_t)CFN_VAL2(cfn) ) { // Still within push duration
functionSwitchFunctionState |= 1 << CFN_CS_INDEX(cfn);
}
}
else // No duration set
functionSwitchFunctionState |= 1 << CFN_CS_INDEX(cfn);
break;
#endif
case FUNC_BACKLIGHT: {
newActiveFunctions |= (1u << FUNCTION_BACKLIGHT);
if (!CFN_PARAM(cfn)) { // When no source is set, backlight works
@@ -434,6 +453,17 @@ void evalFunctions(const CustomFunctionData * functions, CustomFunctionsContext
newActiveSwitches |= switch_mask;
} else {
#if defined(FUNCTION_SWITCHES)
if (CFN_FUNC(cfn) == FUNC_PUSH_CUST_SWITCH) {
// Handling duration after function is active
if (timersGetMsTick() < (uint32_t)CFN_VAL2(cfn)) {
functionSwitchFunctionState |= 1 << CFN_CS_INDEX(cfn);
}
else {
CFN_VAL2(cfn) = 0;
}
}
#endif
functionsContext.lastFunctionTime[i] = 0;
#if defined(DANGEROUS_MODULE_FUNCTIONS)
if (functionsContext.activeSwitches & switch_mask) {
@@ -542,6 +572,10 @@ const char* funcGetLabel(uint8_t func)
case FUNC_LCD_TO_VIDEO:
return STR_SF_LCD_TO_VIDEO;
#endif
#if defined(FUNCTION_SWITCHES)
case FUNC_PUSH_CUST_SWITCH:
return STR_SF_PUSH_CUST_SWITCH;
#endif
#if defined(DEBUG)
case FUNC_TEST:
return STR_SF_TEST;
@@ -30,7 +30,10 @@
#define SD_LOGS_PERIOD_MIN 1 // 0.1s fastest period
#define SD_LOGS_PERIOD_MAX 255 // 25.5s slowest period
#define SD_LOGS_PERIOD_DEFAULT 10 // 1s default period for newly created SF
#define SD_LOGS_PERIOD_DEFAULT 10 // 1s default period for newly created SF
#define PUSH_CS_DURATION_MIN 0 // 0 no duration : as long as switch is true
#define PUSH_CS_DURATION_MAX 255 // 25.5s longest duration
void onCustomFunctionsFileSelectionMenu(const char * result)
{
@@ -269,6 +272,12 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
if (active) CFN_TIMER_INDEX(cfn) = checkIncDec(event, CFN_TIMER_INDEX(cfn), 0, maxParam, eeFlags, isTimerSourceAvailable);
break;
}
#if defined(FUNCTION_SWITCHES)
else if (func == FUNC_PUSH_CUST_SWITCH) {
maxParam = NUM_FUNCTIONS_SWITCHES - 1;
drawStringWithIndex(lcdNextPos +5, y, "SW", CFN_CS_INDEX(cfn) + 1, attr);
}
#endif
else if (attr) {
repeatLastCursorMove(event);
}
@@ -381,6 +390,15 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
INCDEC_ENABLE_CHECK(isSourceAvailable);
}
}
#if defined(FUNCTION_SWITCHES)
else if (func == FUNC_PUSH_CUST_SWITCH) {
val_min = PUSH_CS_DURATION_MIN;
val_max = PUSH_CS_DURATION_MAX;
lcdDrawNumber(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr|PREC1|LEFT);
lcdDrawChar(lcdLastRightPos, y, 's');
}
#endif
else if (func == FUNC_LOGS) {
val_min = SD_LOGS_PERIOD_MIN;
val_max = SD_LOGS_PERIOD_MAX;
@@ -212,6 +212,12 @@ void FunctionLineButton::refresh()
strcat(s, formatNumberAsString(CFN_PARAM(cfn)).c_str());
break;
#if defined(FUNCTION_SWITCHES)
case FUNC_PUSH_CUST_SWITCH:
sprintf(s + strlen(s), "%s%d", STR_SWITCH, CFN_CS_INDEX(cfn) + 1);
break;
#endif
case FUNC_LOGS:
strcat(
s,
@@ -286,6 +292,9 @@ static const lv_coord_t row_dsc[] = {LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST};
#define SD_LOGS_PERIOD_MAX 255 // 25.5s slowest period
#define SD_LOGS_PERIOD_DEFAULT 10 // 1s default period for newly created SF
#define PUSH_CS_DURATION_MIN 0 // 0 no duration : as long as switch is true
#define PUSH_CS_DURATION_MAX 255 // 25.5s longest duration
FunctionEditPage::FunctionEditPage(uint8_t index, EdgeTxIcon icon,
const char *title, const char *prefix) :
Page(icon), index(index)
@@ -483,6 +492,25 @@ void FunctionEditPage::updateSpecialFunctionOneWindow()
addNumberEdit(line, STR_VALUE, cfn, 0, 3);
break;
#if defined(FUNCTION_SWITCHES)
case FUNC_PUSH_CUST_SWITCH: {
new StaticText(line, rect_t{}, STR_SWITCH);
auto choice = new Choice(line, rect_t{}, 0, NUM_FUNCTIONS_SWITCHES - 1, GET_SET_DEFAULT(CFN_CS_INDEX(cfn)), STR_SWITCH);
choice->setTextHandler([=](int n) {
return std::string(STR_SWITCH) + std::to_string(n + 1);
});
line = specialFunctionOneWindow->newLine(grid);
auto edit = addNumberEdit(line, STR_INTERVAL, cfn, PUSH_CS_DURATION_MIN,
PUSH_CS_DURATION_MAX);
edit->setDisplayHandler([=](int32_t value) {
return formatNumberAsString(CFN_PARAM(cfn), PREC1, 0, nullptr, "s");
});
}
break;
#endif
case FUNC_LOGS: {
if (CFN_PARAM(cfn) == 0) // use stored value if SF exists
CFN_PARAM(cfn) = SD_LOGS_PERIOD_DEFAULT; // otherwise initialize with
+3
View File
@@ -3099,6 +3099,9 @@ LROT_BEGIN(etxcst, NULL, 0)
LROT_NUMENTRY( FUNC_BACKLIGHT, FUNC_BACKLIGHT )
LROT_NUMENTRY( FUNC_SCREENSHOT, FUNC_SCREENSHOT )
LROT_NUMENTRY( FUNC_RACING_MODE, FUNC_RACING_MODE )
#if defined(FUNCTION_SWITCHES)
LROT_NUMENTRY( FUNC_PUSH_CUST_SWITCH, FUNC_PUSH_CUST_SWITCH )
#endif
#if defined(COLORLCD)
LROT_NUMENTRY( FUNC_DISABLE_TOUCH, FUNC_DISABLE_TOUCH )
LROT_NUMENTRY( FUNC_SET_SCREEN, FUNC_SET_SCREEN )
+2
View File
@@ -58,6 +58,7 @@
#define CFN_FUNC(p) ((p)->func)
#define CFN_ACTIVE(p) ((p)->active)
#define CFN_CH_INDEX(p) ((p)->all.param)
#define CFN_CS_INDEX(p) ((p)->all.param)
#define CFN_GVAR_INDEX(p) ((p)->all.param)
#define CFN_TIMER_INDEX(p) ((p)->all.param)
#define CFN_PLAY_REPEAT(p) ((p)->repeat)
@@ -65,6 +66,7 @@
#define CFN_PLAY_REPEAT_NOSTART -1
#define CFN_GVAR_MODE(p) ((p)->all.mode)
#define CFN_PARAM(p) ((p)->all.val)
#define CFN_VAL2(p) ((p)->all.val2)
#define CFN_RESET(p) ((p)->active=0, (p)->clear.val1=0, (p)->clear.val2=0)
#define CFN_GVAR_CST_MIN -GVAR_MAX
#define CFN_GVAR_CST_MAX GVAR_MAX
@@ -1626,7 +1626,18 @@ static void r_customFn(void* user, uint8_t* data, uint32_t bitoffs,
case FUNC_LOGS: // 10th of seconds
CFN_PARAM(cfn) = yaml_str2uint(val, l_sep);
break;
#if defined(FUNCTION_SWITCHES)
case FUNC_PUSH_CUST_SWITCH:
CFN_CS_INDEX(cfn) = yaml_str2uint_ref(val, val_len); // SW index
// ","
if (!val_len || val[0] != ',') return;
val++; val_len--;
l_sep = find_sep(val, val_len);
CFN_PARAM(cfn) = yaml_str2int(val, l_sep); // Duration, 10th of seconds
break;
#endif
case FUNC_ADJUST_GVAR: {
CFN_GVAR_INDEX(cfn) = yaml_str2int_ref(val, l_sep);
@@ -1819,6 +1830,17 @@ static bool w_customFn(void* user, uint8_t* data, uint32_t bitoffs,
#if defined(COLORLCD)
case FUNC_SET_SCREEN:
#endif
#if defined(FUNCTION_SWITCHES)
case FUNC_PUSH_CUST_SWITCH:
str = yaml_unsigned2str(CFN_CS_INDEX(cfn)); // SW index
if (!wf(opaque, str, strlen(str))) return false;
if (!wf(opaque,",",1)) return false;
str = yaml_signed2str(CFN_PARAM(cfn)); // Duration
if (!wf(opaque, str, strlen(str))) return false;
break;
#endif
case FUNC_HAPTIC:
case FUNC_LOGS: // 10th of seconds
str = yaml_unsigned2str(CFN_PARAM(cfn));
@@ -86,6 +86,7 @@ const struct YamlIdStr enum_Functions[] = {
{ FUNC_SET_SCREEN, "SET_SCREEN" },
{ FUNC_DISABLE_AUDIO_AMP, "DISABLE_AUDIO_AMP" },
{ FUNC_RGB_LED, "RGB_LED" },
{ FUNC_PUSH_CUST_SWITCH, "PUSH_CUST_SWITCH" },
{ FUNC_TEST, "TEST" },
{ 0, NULL }
};
@@ -84,6 +84,7 @@ const struct YamlIdStr enum_Functions[] = {
{ FUNC_RACING_MODE, "RACING_MODE" },
{ FUNC_DISABLE_AUDIO_AMP, "DISABLE_AUDIO_AMP" },
{ FUNC_RGB_LED, "RGB_LED" },
{ FUNC_PUSH_CUST_SWITCH, "PUSH_CUST_SWITCH" },
{ FUNC_TEST, "TEST" },
{ 0, NULL }
};
@@ -84,6 +84,7 @@ const struct YamlIdStr enum_Functions[] = {
{ FUNC_RACING_MODE, "RACING_MODE" },
{ FUNC_DISABLE_AUDIO_AMP, "DISABLE_AUDIO_AMP" },
{ FUNC_RGB_LED, "RGB_LED" },
{ FUNC_PUSH_CUST_SWITCH, "PUSH_CUST_SWITCH" },
{ FUNC_TEST, "TEST" },
{ 0, NULL }
};
+6
View File
@@ -87,6 +87,7 @@ uint8_t potsPos[MAX_POTS];
// Pushed : SWSRC_Sx2 = +1024 = Sx(down) = state 1
uint8_t fsPreviousState = 0;
uint8_t functionSwitchFunctionState = 0;
void setFSStartupPosition()
{
@@ -131,6 +132,11 @@ void setFSLogicalState(uint8_t index, uint8_t value)
uint8_t getFSPhysicalState(uint8_t index)
{
#if defined(FUNCTION_SWITCHES)
if (bfSingleBitGet(functionSwitchFunctionState, index))
return true;
#endif
index += switchGetMaxSwitches();
return switchGetPosition(index) != SWITCH_HW_UP;
}
+1
View File
@@ -101,6 +101,7 @@ int firstSwitchInGroup(uint8_t group);
int groupDefaultSwitch(uint8_t group);
void setGroupSwitchState(uint8_t group, int defaultSwitch = -1);
uint8_t getFSPhysicalState(uint8_t index);
extern uint8_t functionSwitchFunctionState;
//led_driver.cpp
void fsLedOff(uint8_t);
@@ -26,7 +26,10 @@
#define SYSTEM_TICKS_1US ((CPU_FREQ + 500000) / 1000000)
#define SYSTEM_TICKS_01US ((CPU_FREQ + 5000000) / 10000000)
#define ticksNow() ((uint32_t)(DWT->CYCCNT))
uint32_t ticksNow()
{
return ((uint32_t)(DWT->CYCCNT));
}
void delaysInit()
{
@@ -28,4 +28,5 @@ EXTERN_C(void delaysInit());
EXTERN_C(void delay_01us(uint32_t count));
EXTERN_C(void delay_us(uint32_t count));
EXTERN_C(void delay_ms(uint32_t count));
EXTERN_C(uint32_t ticksNow());
+8
View File
@@ -25,6 +25,7 @@
#include <stdlib.h>
#include <assert.h>
#include "switches.h"
struct hw_switch_def {
const char* name;
@@ -64,6 +65,13 @@ SwitchHwPos boardSwitchGetPosition(uint8_t cat, uint8_t idx)
{
idx = get_switch_index(cat, idx);
#if defined(FUNCTION_SWITCHES)
if (IS_SWITCH_FS(idx + n_switches)) {
if (bfSingleBitGet(functionSwitchFunctionState, idx))
return SWITCH_HW_DOWN;
}
#endif
if (switchesStates[idx] < 0)
return SWITCH_HW_UP;
else if (switchesStates[idx] == 0)
+1
View File
@@ -173,6 +173,7 @@ const char STR_SWITCH_STARTUP[] = TR_SWITCH_STARTUP;
const char STR_FUNCTION_SWITCHES[] = TR_FUNCTION_SWITCHES;
const char STR_GROUP[] = TR_GROUP;
const char STR_GROUP_ALWAYS_ON[] = TR_GROUP_ALWAYS_ON;
const char STR_SF_PUSH_CUST_SWITCH[] = TR_SF_PUSH_CUST_SWITCH;
#endif
const char STR_ADJUST_GVAR[] = TR_ADJUST_GVAR;
const char STR_PLAY_TRACK[] = TR_PLAY_TRACK;
+1
View File
@@ -325,6 +325,7 @@ extern const char STR_SF_VOLUME[];
extern const char STR_SF_RACING_MODE[];
extern const char STR_SF_SCREENSHOT[];
extern const char STR_SF_LCD_TO_VIDEO[];
extern const char STR_SF_PUSH_CUST_SWITCH[];
extern const char STR_SF_TEST[];
extern const char STR_TRIMS[];
extern const char STR_MIRROR[];
+1
View File
@@ -110,6 +110,7 @@
#define TR_SF_DISABLE_TOUCH "禁用触摸"
#define TR_SF_DISABLE_AUDIO_AMP "关闭音频功放"
#define TR_SF_SET_SCREEN "选择主屏"
#define TR_SF_PUSH_CUST_SWITCH "Push CS"
#define TR_SF_LCD_TO_VIDEO "屏幕显示图传"
#define TR_FSW_RESET_TELEM "回传参数"
+1
View File
@@ -121,6 +121,7 @@
#define TR_SF_DISABLE_TOUCH "Deaktivace dotyku"
#define TR_SF_DISABLE_AUDIO_AMP "Vypnutí zesilovače zvuku"
#define TR_SF_SET_SCREEN "Vybrat hlavní obrazovku"
#define TR_SF_PUSH_CUST_SWITCH "Push CS"
#define TR_SF_LCD_TO_VIDEO "LCD to Video"
#define TR_FSW_RESET_TELEM TR("Telm","Telemetrie")
+1
View File
@@ -121,6 +121,7 @@
#define TR_SF_DISABLE_TOUCH "Ikke berøringsaktiv"
#define TR_SF_DISABLE_AUDIO_AMP TR("Sluk audio amp", "Sluk audio amplifier")
#define TR_SF_SET_SCREEN "Vælg hoved skærm"
#define TR_SF_PUSH_CUST_SWITCH "Push CS"
#define TR_SF_LCD_TO_VIDEO "LCD to Video"
#define TR_FSW_RESET_TELEM TR("Telm", "Telemetri")
+1
View File
@@ -118,6 +118,7 @@
#define TR_SF_DISABLE_TOUCH "Kein Touch"
#define TR_SF_DISABLE_AUDIO_AMP "Audio Verst. Aus"
#define TR_SF_SET_SCREEN "Set Main Screen"
#define TR_SF_PUSH_CUST_SWITCH "Push CS"
#define TR_SF_LCD_TO_VIDEO "LCD to Video"
#define TR_FSW_RESET_TELEM TR("Telm","Telemetrie")
+1
View File
@@ -119,6 +119,7 @@
#define TR_SF_DISABLE_TOUCH "No Touch"
#define TR_SF_DISABLE_AUDIO_AMP "Audio Amp Off"
#define TR_SF_SET_SCREEN "Set Main Screen"
#define TR_SF_PUSH_CUST_SWITCH "Push CS"
#define TR_SF_LCD_TO_VIDEO "LCD to Video"
#define TR_FSW_RESET_TELEM TR("Telm", "Telemetry")
+1
View File
@@ -116,6 +116,7 @@
#define TR_SF_DISABLE_TOUCH "No Touch"
#define TR_SF_DISABLE_AUDIO_AMP "Audio Amp Off"
#define TR_SF_SET_SCREEN "Set Main Screen"
#define TR_SF_PUSH_CUST_SWITCH "Push CS"
#define TR_SF_LCD_TO_VIDEO "LCD to Video"
#define TR_FSW_RESET_TELEM TR("Telm", "Telemetría")
+1
View File
@@ -119,6 +119,7 @@
#define TR_SF_DISABLE_TOUCH "No Touch"
#define TR_SF_DISABLE_AUDIO_AMP "Audio Amp Off"
#define TR_SF_SET_SCREEN "Set Main Screen"
#define TR_SF_PUSH_CUST_SWITCH "Push CS"
#define TR_SF_LCD_TO_VIDEO "LCD to Video"
#define TR_FSW_RESET_TELEM TR("Telm","Telemetry")
+1
View File
@@ -118,6 +118,7 @@
#define TR_SF_DISABLE_TOUCH "Non Tactile"
#define TR_SF_DISABLE_AUDIO_AMP "Désact. Ampli Audio"
#define TR_SF_SET_SCREEN "Définir Écran Princ."
#define TR_SF_PUSH_CUST_SWITCH "Push CS"
#define TR_SF_LCD_TO_VIDEO "LCD to Video"
#define TR_FSW_RESET_TELEM TR("Télem.", "Télémétrie")
+1
View File
@@ -122,6 +122,7 @@
#define TR_SF_DISABLE_TOUCH "ללא מסך מגע"
#define TR_SF_DISABLE_AUDIO_AMP "Audio Amp Off"
#define TR_SF_SET_SCREEN "הגדרת מסך ראשי"
#define TR_SF_PUSH_CUST_SWITCH "Push CS"
#define TR_SF_LCD_TO_VIDEO "LCD to Video"
#define TR_FSW_RESET_TELEM TR("Telm", "טלמטריה")
+1
View File
@@ -119,6 +119,7 @@
#define TR_SF_DISABLE_TOUCH "No Touch"
#define TR_SF_DISABLE_AUDIO_AMP "Amp Audio Off"
#define TR_SF_SET_SCREEN "Setta Schermo Princ."
#define TR_SF_PUSH_CUST_SWITCH "Push CS"
#define TR_SF_LCD_TO_VIDEO "LCD to Video"
#define TR_FSW_RESET_TELEM TR("Telm", "Telemetria")
+1
View File
@@ -119,6 +119,7 @@
#define TR_SF_DISABLE_TOUCH "非タッチ"
#define TR_SF_DISABLE_AUDIO_AMP "オーディオアンプ OFF"
#define TR_SF_SET_SCREEN "メイン画面設定"
#define TR_SF_PUSH_CUST_SWITCH "Push CS"
#define TR_SF_LCD_TO_VIDEO "LCD to Video"
#define TR_FSW_RESET_TELEM TR("Telm", "テレメトリー")
+1
View File
@@ -116,6 +116,7 @@
#define TR_SF_DISABLE_TOUCH "No Touch"
#define TR_SF_DISABLE_AUDIO_AMP "Audio Amp Off"
#define TR_SF_SET_SCREEN "Set Main Screen"
#define TR_SF_PUSH_CUST_SWITCH "Push CS"
#define TR_SF_LCD_TO_VIDEO "LCD to Video"
#define TR_FSW_RESET_TELEM TR("Telm", "Telemetrie")
+1
View File
@@ -115,6 +115,7 @@
#define TR_SF_DISABLE_TOUCH "No Touch"
#define TR_SF_DISABLE_AUDIO_AMP TR("Wycisz wzm.", "Wycisz wzmacniacz audio")
#define TR_SF_SET_SCREEN "Set Main Screen"
#define TR_SF_PUSH_CUST_SWITCH "Push CS"
#define TR_SF_LCD_TO_VIDEO "LCD to Video"
#define TR_FSW_RESET_TELEM TR("Telm", "Telemetra")
+1
View File
@@ -122,6 +122,7 @@
#define TR_SF_DISABLE_TOUCH "No Touch"
#define TR_SF_DISABLE_AUDIO_AMP "Amp Audio Desl"
#define TR_SF_SET_SCREEN "Def Tela Princ"
#define TR_SF_PUSH_CUST_SWITCH "Push CS"
#define TR_SF_LCD_TO_VIDEO "LCD to Video"
#define TR_FSW_RESET_TELEM TR("Telm", "Telemetria")
+1
View File
@@ -121,6 +121,7 @@
#define TR_SF_DISABLE_TOUCH "Сенсор вык"
#define TR_SF_DISABLE_AUDIO_AMP "Вык аудио усил."
#define TR_SF_SET_SCREEN "Выбр глав экран"
#define TR_SF_PUSH_CUST_SWITCH "Push CS"
#define TR_SF_LCD_TO_VIDEO "LCD to Video"
#define TR_FSW_RESET_TELEM TR("Телем", "Телеметрия")
+1
View File
@@ -123,6 +123,7 @@
#define TR_SF_DISABLE_TOUCH "Ej pekskärm"
#define TR_SF_DISABLE_AUDIO_AMP TR("Audioförst. av","Audioförstärkare av")
#define TR_SF_SET_SCREEN "Sätt huvudskärm"
#define TR_SF_PUSH_CUST_SWITCH "Push CS"
#define TR_SF_LCD_TO_VIDEO "LCD to Video"
#define TR_FSW_RESET_TELEM TR("Telm","Telemetri")
+1
View File
@@ -115,6 +115,7 @@
#define TR_SF_DISABLE_TOUCH "禁用觸摸"
#define TR_SF_DISABLE_AUDIO_AMP "關閉音頻功放"
#define TR_SF_SET_SCREEN "選擇主屏"
#define TR_SF_PUSH_CUST_SWITCH "Push CS"
#define TR_SF_LCD_TO_VIDEO "屏幕顯示圖傳"
#define TR_FSW_RESET_TELEM "回傳參數"
+1
View File
@@ -121,6 +121,7 @@
#define TR_SF_DISABLE_TOUCH "Сенсор вимк."
#define TR_SF_DISABLE_AUDIO_AMP "Підсил. вимк."
#define TR_SF_SET_SCREEN "Вибір гол. екр."
#define TR_SF_PUSH_CUST_SWITCH "Push CS"
#define TR_SF_LCD_TO_VIDEO "LCD to Video"
#define TR_FSW_RESET_TELEM TR("Телем", "Телеметрія")
+2
View File
@@ -1,5 +1,6 @@
#include <stdio.h>
#include <string.h>
#include <vector>
#include <algorithm>
#include <locale>
@@ -122,6 +123,7 @@ int main()
{ TR_SF_DISABLE_AUDIO_AMP, "FUNC_DISABLE_AUDIO_AMP", FUNC_DISABLE_AUDIO_AMP, "" },
{ TR_SF_RGBLEDS, "FUNC_RGB_LED", FUNC_RGB_LED, "" },
{ TR_SF_LCD_TO_VIDEO, "FUNC_LCD_TO_VIDEO", FUNC_LCD_TO_VIDEO, "defined(VIDEO_SWITCH)" },
{ TR_SF_PUSH_CUST_SWITCH, "FUNC_PUSH_CUST_SWITCH", FUNC_PUSH_CUST_SWITCH, "defined(FUNCTION_SWITCHES)" },
{ TR_SF_TEST, "FUNC_TEST", FUNC_TEST, "defined(DEBUG)" },
};