Global functions (only Firmware) - saves 20bytes flash on 9X stock

This commit is contained in:
bsongis
2014-09-18 11:44:09 +02:00
parent 5173907efd
commit 2f8b9347a4
55 changed files with 1328 additions and 1154 deletions
+1 -1
View File
@@ -820,7 +820,7 @@ else
TTS_SRC = $(shell sh -c "if test -f $(STD_TTS_SRC); then echo $(STD_TTS_SRC); else echo translations/tts_en.cpp; fi")
endif
CPPSRC += opentx.cpp strhelpers.cpp $(PULSESSRC) switches.cpp curves.cpp mixer.cpp stamp.cpp gui/menus.cpp gui/menu_model.cpp gui/menu_general.cpp gui/view_main.cpp gui/view_statistics.cpp $(EEPROMSRC) $(LCDSRC) keys.cpp maths.cpp translations.cpp fonts.cpp $(TTS_SRC)
CPPSRC += opentx.cpp functions.cpp strhelpers.cpp $(PULSESSRC) switches.cpp curves.cpp mixer.cpp stamp.cpp gui/menus.cpp gui/menu_model.cpp gui/menu_general.cpp gui/view_main.cpp gui/view_statistics.cpp $(EEPROMSRC) $(LCDSRC) keys.cpp maths.cpp translations.cpp fonts.cpp $(TTS_SRC)
# Debugging format.
# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
+13 -13
View File
@@ -303,7 +303,7 @@ PACK(typedef struct {
}) param;
uint8_t mode:2;
uint8_t active:6;
}) CustomFnData_v215;
}) CustomFunctionData_v215;
#else
PACK(typedef struct {
int8_t swtch;
@@ -318,7 +318,7 @@ PACK(typedef struct {
}) param;
uint8_t mode:2;
uint8_t active:6;
}) CustomFnData_v215;
}) CustomFunctionData_v215;
#endif
PACK(typedef struct {
@@ -365,7 +365,7 @@ PACK(typedef struct {
int8_t points[NUM_POINTS];
LogicalSwitchData_v215 logicalSw[NUM_LOGICAL_SWITCH];
CustomFnData_v215 funcSw[32];
CustomFunctionData_v215 customFn[32];
SwashRingData swashR;
FlightModeData_v215 flightModeData[MAX_FLIGHT_MODES];
@@ -407,7 +407,7 @@ PACK(typedef struct {
int8_t points[NUM_POINTS];
LogicalSwitchData logicalSw[NUM_LOGICAL_SWITCH];
CustomFnData funcSw[NUM_CFN];
CustomFunctionData customFn[NUM_CFN];
SwashRingData swashR;
FlightModeData flightModeData[MAX_FLIGHT_MODES];
@@ -950,9 +950,9 @@ void ConvertModel_215_to_216(ModelData &model)
}
}
for (uint8_t i=0; i<32; i++) {
CustomFnData & fn = newModel.funcSw[i];
fn.swtch = ConvertSwitch_215_to_216(oldModel.funcSw[i].swtch);
fn.func = oldModel.funcSw[i].func;
CustomFunctionData & fn = newModel.customFn[i];
fn.swtch = ConvertSwitch_215_to_216(oldModel.customFn[i].swtch);
fn.func = oldModel.customFn[i].func;
if (fn.func <= 15) {
fn.all.param = fn.func;
fn.func = FUNC_OVERRIDE_CHANNEL;
@@ -1001,20 +1001,20 @@ void ConvertModel_215_to_216(ModelData &model)
}
else {
fn.all.param = fn.func - 32 - IS_PCBSKY9X;
fn.all.mode = oldModel.funcSw[i].mode;
fn.all.mode = oldModel.customFn[i].mode;
fn.func = FUNC_ADJUST_GVAR;
}
fn.active = oldModel.funcSw[i].active;
fn.active = oldModel.customFn[i].active;
if (HAS_REPEAT_PARAM(fn.func)) {
fn.active *= 5;
}
if (fn.func == FUNC_PLAY_TRACK || fn.func == FUNC_BACKGND_MUSIC) {
memcpy(fn.play.name, oldModel.funcSw[i].param.name, 8);
memcpy(fn.play.name, oldModel.customFn[i].param.name, 8);
}
else {
fn.all.val = oldModel.funcSw[i].param.composite.val;
fn.all.val = oldModel.customFn[i].param.composite.val;
}
if (fn.func == FUNC_PLAY_VALUE || fn.func == FUNC_VOLUME || (IS_ADJUST_GV_FUNC(fn.func) && fn.all.mode == FUNC_ADJUST_GVAR_SOURCE)) {
#if defined(PCBTARANIS)
@@ -1199,8 +1199,8 @@ void ConvertModel_216_to_217(ModelData &model)
}
}
for (int i=0; i<NUM_CFN; i++) {
CustomFnData & fn = newModel.funcSw[i];
fn = oldModel.funcSw[i];
CustomFunctionData & fn = newModel.customFn[i];
fn = oldModel.customFn[i];
if (fn.func == FUNC_PLAY_VALUE || fn.func == FUNC_VOLUME || (IS_ADJUST_GV_FUNC(fn.func) && fn.all.mode == FUNC_ADJUST_GVAR_SOURCE)) {
fn.all.val = ConvertSource_216_to_217(fn.all.val);
}
+1 -3
View File
@@ -394,9 +394,7 @@ void eeLoadModel(uint8_t id)
resumePulses();
}
activeFnSwitches = 0;
activeFunctions = 0;
memclear(lastFunctionTime, sizeof(lastFunctionTime));
customFunctionsReset();
for (uint8_t i=0; i<MAX_TIMERS; i++) {
if (g_model.timers[i].persistent) {
+1 -3
View File
@@ -983,9 +983,7 @@ void eeLoadModel(uint8_t id)
resumePulses();
}
activeFnSwitches = 0;
activeFunctions = 0;
memclear(lastFunctionTime, sizeof(lastFunctionTime));
customFunctionsReset();
#if !defined(PCBSTD)
for (uint8_t i=0; i<MAX_TIMERS; i++) {
+543
View File
@@ -0,0 +1,543 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* 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 "opentx.h"
CustomFunctionsContext modelFunctionsContext = { 0 };
#if defined(CPUARM)
CustomFunctionsContext globalFunctionsContext = { 0 };
#endif
#if defined(DEBUG)
/*
* This is a test function for debugging purpose, you may insert there your code and compile with the option DEBUG=YES
*/
void testFunc()
{
#ifdef SIMU
printf("testFunc\n"); fflush(stdout);
#endif
}
#endif
#if defined(VOICE)
PLAY_FUNCTION(playValue, uint8_t idx)
{
if (IS_FAI_FORBIDDEN(idx))
return;
getvalue_t val = getValue(idx);
switch (idx) {
#if defined(CPUARM)
case MIXSRC_FIRST_TELEM+TELEM_TX_TIME-1:
PLAY_DURATION(val*60, PLAY_TIME);
break;
#endif
case MIXSRC_FIRST_TELEM+TELEM_TX_VOLTAGE-1:
PLAY_NUMBER(val, 1+UNIT_VOLTS, PREC1);
break;
case MIXSRC_FIRST_TELEM+TELEM_TIMER1-1:
case MIXSRC_FIRST_TELEM+TELEM_TIMER2-1:
#if defined(CPUARM)
case MIXSRC_FIRST_TELEM+TELEM_TIMER3-1:
#endif
PLAY_DURATION(val, 0);
break;
#if defined(CPUARM) && defined(FRSKY)
case MIXSRC_FIRST_TELEM+TELEM_SWR-1:
PLAY_NUMBER(val, 0, 0);
break;
#endif
#if defined(FRSKY)
case MIXSRC_FIRST_TELEM+TELEM_RSSI_TX-1:
case MIXSRC_FIRST_TELEM+TELEM_RSSI_RX-1:
PLAY_NUMBER(val, 1+UNIT_DBM, 0);
break;
case MIXSRC_FIRST_TELEM+TELEM_MIN_A1-1:
case MIXSRC_FIRST_TELEM+TELEM_MIN_A2-1:
#if defined(CPUARM)
case MIXSRC_FIRST_TELEM+TELEM_MIN_A3-1:
case MIXSRC_FIRST_TELEM+TELEM_MIN_A4-1:
#endif
idx -= TELEM_MIN_A1-TELEM_A1;
// no break
case MIXSRC_FIRST_TELEM+TELEM_A1-1:
case MIXSRC_FIRST_TELEM+TELEM_A2-1:
#if defined(CPUARM)
case MIXSRC_FIRST_TELEM+TELEM_A3-1:
case MIXSRC_FIRST_TELEM+TELEM_A4-1:
#endif
if (TELEMETRY_STREAMING()) {
idx -= (MIXSRC_FIRST_TELEM+TELEM_A1-1);
uint8_t att = 0;
int16_t converted_value = div10_and_round(applyChannelRatio(idx, val));;
if (ANA_CHANNEL_UNIT(idx) < UNIT_RAW) {
att = PREC1;
}
PLAY_NUMBER(converted_value, 1+ANA_CHANNEL_UNIT(idx), att);
}
break;
case MIXSRC_FIRST_TELEM+TELEM_CELL-1:
case MIXSRC_FIRST_TELEM+TELEM_MIN_CELL-1:
PLAY_NUMBER(div10_and_round(val), 1+UNIT_VOLTS, PREC1);
break;
case MIXSRC_FIRST_TELEM+TELEM_VFAS-1:
case MIXSRC_FIRST_TELEM+TELEM_CELLS_SUM-1:
case MIXSRC_FIRST_TELEM+TELEM_MIN_CELLS_SUM-1:
case MIXSRC_FIRST_TELEM+TELEM_MIN_VFAS-1:
PLAY_NUMBER(val, 1+UNIT_VOLTS, PREC1);
break;
case MIXSRC_FIRST_TELEM+TELEM_CURRENT-1:
case MIXSRC_FIRST_TELEM+TELEM_MAX_CURRENT-1:
PLAY_NUMBER(val, 1+UNIT_AMPS, PREC1);
break;
case MIXSRC_FIRST_TELEM+TELEM_ACCx-1:
case MIXSRC_FIRST_TELEM+TELEM_ACCy-1:
case MIXSRC_FIRST_TELEM+TELEM_ACCz-1:
PLAY_NUMBER(div10_and_round(val), 1+UNIT_G, PREC1);
break;
case MIXSRC_FIRST_TELEM+TELEM_VSPEED-1:
PLAY_NUMBER(div10_and_round(val), 1+UNIT_METERS_PER_SECOND, PREC1);
break;
case MIXSRC_FIRST_TELEM+TELEM_ASPEED-1:
case MIXSRC_FIRST_TELEM+TELEM_MAX_ASPEED-1:
PLAY_NUMBER(val/10, 1+UNIT_KTS, 0);
break;
case MIXSRC_FIRST_TELEM+TELEM_CONSUMPTION-1:
PLAY_NUMBER(val, 1+UNIT_MAH, 0);
break;
case MIXSRC_FIRST_TELEM+TELEM_POWER-1:
PLAY_NUMBER(val, 1+UNIT_WATTS, 0);
break;
case MIXSRC_FIRST_TELEM+TELEM_ALT-1:
#if defined(PCBTARANIS)
PLAY_NUMBER(div10_and_round(val), 1+UNIT_DIST, PREC1);
break;
#endif
case MIXSRC_FIRST_TELEM+TELEM_MIN_ALT-1:
case MIXSRC_FIRST_TELEM+TELEM_MAX_ALT-1:
#if defined(WS_HOW_HIGH)
if (IS_IMPERIAL_ENABLE() && IS_USR_PROTO_WS_HOW_HIGH())
PLAY_NUMBER(val, 1+UNIT_FEET, 0);
else
#endif
PLAY_NUMBER(val, 1+UNIT_DIST, 0);
break;
case MIXSRC_FIRST_TELEM+TELEM_RPM-1:
case MIXSRC_FIRST_TELEM+TELEM_MAX_RPM-1:
{
getvalue_t rpm = val;
if (rpm > 100)
rpm = 10 * div10_and_round(rpm);
if (rpm > 1000)
rpm = 10 * div10_and_round(rpm);
PLAY_NUMBER(rpm, 1+UNIT_RPMS, 0);
break;
}
case MIXSRC_FIRST_TELEM+TELEM_HDG-1:
PLAY_NUMBER(val, 1+UNIT_HDG, 0);
break;
default:
{
uint8_t unit = 1;
if (idx < MIXSRC_GVAR1)
val = calcRESXto100(val);
if (idx >= MIXSRC_FIRST_TELEM+TELEM_ALT-1 && idx <= MIXSRC_FIRST_TELEM+TELEM_GPSALT-1)
unit = idx - (MIXSRC_FIRST_TELEM+TELEM_ALT-1);
else if (idx >= MIXSRC_FIRST_TELEM+TELEM_MAX_T1-1 && idx <= MIXSRC_FIRST_TELEM+TELEM_MAX_DIST-1)
unit = 3 + idx - (MIXSRC_FIRST_TELEM+TELEM_MAX_T1-1);
unit = pgm_read_byte(bchunit_ar+unit);
PLAY_NUMBER(val, unit == UNIT_RAW ? 0 : unit+1, 0);
break;
}
#else
default:
{
PLAY_NUMBER(val, 0, 0);
break;
}
#endif
}
}
#endif
#if defined(CPUARM)
void playCustomFunctionFile(const CustomFunctionData *sd, uint8_t id)
{
if (sd->play.name[0] != '\0') {
char filename[sizeof(SOUNDS_PATH)+sizeof(sd->play.name)+sizeof(SOUNDS_EXT)] = SOUNDS_PATH "/";
strncpy(filename+SOUNDS_PATH_LNG_OFS, currentLanguagePack->id, 2);
strncpy(filename+sizeof(SOUNDS_PATH), sd->play.name, sizeof(sd->play.name));
filename[sizeof(SOUNDS_PATH)+sizeof(sd->play.name)] = '\0';
strcat(filename+sizeof(SOUNDS_PATH), SOUNDS_EXT);
PLAY_FILE(filename, sd->func==FUNC_BACKGND_MUSIC ? PLAY_BACKGROUND : 0, id);
}
}
#endif
#if defined(CPUARM)
#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
#endif
#if defined(CPUARM)
void evalFunctions(const CustomFunctionData * functions, CustomFunctionsContext & functionsContext)
#else
#define functions g_model.customFn
#define functionsContext modelFunctionsContext
void evalFunctions()
#endif
{
MASK_FUNC_TYPE newActiveFunctions = 0;
MASK_CFN_TYPE newActiveSwitches = 0;
#if defined(ROTARY_ENCODERS) && defined(GVARS)
static rotenc_t rePreviousValues[ROTARY_ENCODERS];
#endif
#if defined(OVERRIDE_CHANNEL_FUNCTION)
for (uint8_t i=0; i<NUM_CHNOUT; i++) {
safetyCh[i] = OVERRIDE_CHANNEL_UNDEFINED;
}
#endif
#if defined(GVARS)
for (uint8_t i=0; i<NUM_STICKS; i++) {
trimGvar[i] = -1;
}
#endif
for (uint8_t i=0; i<NUM_CFN; i++) {
const CustomFunctionData *cfn = &functions[i];
int8_t swtch = CFN_SWITCH(cfn);
if (swtch) {
MASK_CFN_TYPE switch_mask = ((MASK_CFN_TYPE)1 << i);
#if defined(CPUARM)
bool active = getSwitch(swtch, IS_PLAY_FUNC(CFN_FUNC(cfn)) ? GETSWITCH_MIDPOS_DELAY : 0);
#else
bool active = getSwitch(swtch);
#endif
if (HAS_ENABLE_PARAM(CFN_FUNC(cfn))) {
active &= (bool)CFN_ACTIVE(cfn);
}
if (active || IS_PLAY_BOTH_FUNC(CFN_FUNC(cfn))) {
switch (CFN_FUNC(cfn)) {
#if defined(OVERRIDE_CHANNEL_FUNCTION)
case FUNC_OVERRIDE_CHANNEL:
safetyCh[CFN_CH_INDEX(cfn)] = CFN_PARAM(cfn);
break;
#endif
case FUNC_TRAINER:
{
uint8_t mask = 0x0f;
if (CFN_CH_INDEX(cfn) > 0) {
mask = (1<<(CFN_CH_INDEX(cfn)-1));
}
newActiveFunctions |= mask;
break;
}
case FUNC_INSTANT_TRIM:
newActiveFunctions |= (1 << FUNCTION_INSTANT_TRIM);
if (!isFunctionActive(FUNCTION_INSTANT_TRIM)) {
if (g_menuStack[0] == menuMainView
#if defined(FRSKY)
|| g_menuStack[0] == menuTelemetryFrsky
#endif
#if defined(PCBTARANIS)
|| g_menuStack[0] == menuMainViewChannelsMonitor
|| g_menuStack[0] == menuChannelsView
#endif
) {
instantTrim();
}
}
break;
case FUNC_RESET:
switch (CFN_PARAM(cfn)) {
case FUNC_RESET_TIMER1:
case FUNC_RESET_TIMER2:
#if defined(CPUARM)
case FUNC_RESET_TIMER3:
#endif
timerReset(CFN_PARAM(cfn));
break;
case FUNC_RESET_FLIGHT:
flightReset();
break;
#if defined(FRSKY)
case FUNC_RESET_TELEMETRY:
telemetryReset();
break;
#endif
#if ROTARY_ENCODERS > 0
case FUNC_RESET_ROTENC1:
#if ROTARY_ENCODERS > 1
case FUNC_RESET_ROTENC2:
#endif
g_rotenc[CFN_PARAM(cfn)-FUNC_RESET_ROTENC1] = 0;
break;
#endif
}
break;
#if defined(CPUARM)
case FUNC_SET_TIMER:
{
TimerState & timerState = timersStates[CFN_TIMER_INDEX(cfn)];
timerState.state = TMR_OFF; // is changed to RUNNING dep from mode
timerState.val = CFN_PARAM(cfn);
timerState.val_10ms = 0 ;
break;
}
#endif
#if defined(GVARS)
case FUNC_ADJUST_GVAR:
if (CFN_GVAR_MODE(cfn) == 0) {
SET_GVAR(CFN_GVAR_INDEX(cfn), CFN_PARAM(cfn), mixerCurrentFlightMode);
}
else if (CFN_GVAR_MODE(cfn) == 2) {
SET_GVAR(CFN_GVAR_INDEX(cfn), GVAR_VALUE(CFN_PARAM(cfn), mixerCurrentFlightMode), mixerCurrentFlightMode);
}
else if (CFN_GVAR_MODE(cfn) == 3) {
if (!(functionsContext.activeSwitches & switch_mask)) {
SET_GVAR(CFN_GVAR_INDEX(cfn), GVAR_VALUE(CFN_GVAR_INDEX(cfn), getGVarFlightPhase(mixerCurrentFlightMode, CFN_GVAR_INDEX(cfn))) + (CFN_PARAM(cfn) ? +1 : -1), mixerCurrentFlightMode);
}
}
else if (CFN_PARAM(cfn) >= MIXSRC_TrimRud && CFN_PARAM(cfn) <= MIXSRC_TrimAil) {
trimGvar[CFN_PARAM(cfn)-MIXSRC_TrimRud] = CFN_GVAR_INDEX(cfn);
}
#if defined(ROTARY_ENCODERS)
else if (CFN_PARAM(cfn) >= MIXSRC_REa && CFN_PARAM(cfn) < MIXSRC_TrimRud) {
int8_t scroll = rePreviousValues[CFN_PARAM(cfn)-MIXSRC_REa] - (g_rotenc[CFN_PARAM(cfn)-MIXSRC_REa] / ROTARY_ENCODER_GRANULARITY);
if (scroll) {
SET_GVAR(CFN_GVAR_INDEX(cfn), GVAR_VALUE(CFN_GVAR_INDEX(cfn), getGVarFlightPhase(mixerCurrentFlightMode, CFN_GVAR_INDEX(cfn))) + scroll, mixerCurrentFlightMode);
}
}
#endif
else {
SET_GVAR(CFN_GVAR_INDEX(cfn), calcRESXto100(getValue(CFN_PARAM(cfn))), mixerCurrentFlightMode);
}
break;
#endif
#if defined(CPUARM) && defined(SDCARD)
case FUNC_VOLUME:
{
getvalue_t raw = getValue(CFN_PARAM(cfn));
//only set volume if input changed more than hysteresis
if (abs(requiredSpeakerVolumeRawLast - raw) > VOLUME_HYSTERESIS) {
requiredSpeakerVolumeRawLast = raw;
}
requiredSpeakerVolume = ((1024 + requiredSpeakerVolumeRawLast) * VOLUME_LEVEL_MAX) / 2048;
break;
}
#endif
#if defined(CPUARM) && defined(SDCARD)
case FUNC_PLAY_SOUND:
case FUNC_PLAY_TRACK:
case FUNC_PLAY_VALUE:
#if defined(HAPTIC)
case FUNC_HAPTIC:
#endif
{
tmr10ms_t tmr10ms = get_tmr10ms();
uint8_t repeatParam = CFN_PLAY_REPEAT(cfn);
if (!IS_SILENCE_PERIOD_ELAPSED() && repeatParam == CFN_PLAY_REPEAT_NOSTART) {
functionsContext.lastFunctionTime[i] = tmr10ms;
}
if (!functionsContext.lastFunctionTime[i] || (repeatParam && repeatParam!=CFN_PLAY_REPEAT_NOSTART && (signed)(tmr10ms-functionsContext.lastFunctionTime[i])>=100*repeatParam)) {
if (!IS_PLAYING(i+1)) {
functionsContext.lastFunctionTime[i] = tmr10ms;
if (CFN_FUNC(cfn) == FUNC_PLAY_SOUND) {
AUDIO_PLAY(AU_FRSKY_FIRST+CFN_PARAM(cfn));
}
else if (CFN_FUNC(cfn) == FUNC_PLAY_VALUE) {
PLAY_VALUE(CFN_PARAM(cfn), i+1);
}
#if defined(HAPTIC)
else if (CFN_FUNC(cfn) == FUNC_HAPTIC) {
haptic.event(AU_FRSKY_LAST+CFN_PARAM(cfn));
}
#endif
else {
playCustomFunctionFile(cfn, i+1);
}
}
}
break;
}
case FUNC_BACKGND_MUSIC:
newActiveFunctions |= (1 << FUNCTION_BACKGND_MUSIC);
if (!IS_PLAYING(i+1)) {
playCustomFunctionFile(cfn, i+1);
}
break;
case FUNC_BACKGND_MUSIC_PAUSE:
newActiveFunctions |= (1 << FUNCTION_BACKGND_MUSIC_PAUSE);
break;
#elif defined(VOICE)
case FUNC_PLAY_SOUND:
case FUNC_PLAY_TRACK:
case FUNC_PLAY_BOTH:
case FUNC_PLAY_VALUE:
{
tmr10ms_t tmr10ms = get_tmr10ms();
uint8_t repeatParam = CFN_PLAY_REPEAT(cfn);
if (!functionsContext.lastFunctionTime[i] || (CFN_FUNC(cfn)==FUNC_PLAY_BOTH && active!=(bool)(functionsContext.activeSwitches&switch_mask)) || (repeatParam && (signed)(tmr10ms-functionsContext.lastFunctionTime[i])>=1000*repeatParam)) {
functionsContext.lastFunctionTime[i] = tmr10ms;
uint8_t param = CFN_PARAM(cfn);
if (CFN_FUNC(cfn) == FUNC_PLAY_SOUND) {
AUDIO_PLAY(AU_FRSKY_FIRST+param);
}
else if (CFN_FUNC(cfn) == FUNC_PLAY_VALUE) {
PLAY_VALUE(param, i+1);
}
else {
#if defined(GVARS)
if (CFN_FUNC(cfn) == FUNC_PLAY_TRACK && param > 250)
param = GVAR_VALUE(param-251, getGVarFlightPhase(mixerCurrentFlightMode, param-251));
#endif
PUSH_CUSTOM_PROMPT(active ? param : param+1, i+1);
}
}
if (!active) {
// PLAY_BOTH would change activeFnSwitches otherwise
switch_mask = 0;
}
break;
}
#else
case FUNC_PLAY_SOUND:
{
tmr10ms_t tmr10ms = get_tmr10ms();
uint8_t repeatParam = CFN_PLAY_REPEAT(cfn);
if (!functionsContext.lastFunctionTime[i] || (repeatParam && (signed)(tmr10ms-functionsContext.lastFunctionTime[i])>=1000*repeatParam)) {
functionsContext.lastFunctionTime[i] = tmr10ms;
AUDIO_PLAY(AU_FRSKY_FIRST+CFN_PARAM(cfn));
}
break;
}
#endif
#if defined(FRSKY) && defined(VARIO)
case FUNC_VARIO:
newActiveFunctions |= (1 << FUNCTION_VARIO);
break;
#endif
#if defined(HAPTIC) && !defined(CPUARM)
case FUNC_HAPTIC:
{
tmr10ms_t tmr10ms = get_tmr10ms();
uint8_t repeatParam = CFN_PLAY_REPEAT(cfn);
if (!functionsContext.lastFunctionTime[i] || (repeatParam && (signed)(tmr10ms-functionsContext.lastFunctionTime[i])>=1000*repeatParam)) {
functionsContext.lastFunctionTime[i] = tmr10ms;
haptic.event(AU_FRSKY_LAST+CFN_PARAM(cfn));
}
break;
}
#endif
#if defined(SDCARD)
case FUNC_LOGS:
if (CFN_PARAM(cfn)) {
newActiveFunctions |= (1 << FUNCTION_LOGS);
logDelay = CFN_PARAM(cfn);
}
break;
#endif
case FUNC_BACKLIGHT:
newActiveFunctions |= (1 << FUNCTION_BACKLIGHT);
break;
#if defined(DEBUG)
case FUNC_TEST:
testFunc();
break;
#endif
}
newActiveSwitches |= switch_mask;
}
else {
functionsContext.lastFunctionTime[i] = 0;
}
}
}
functionsContext.activeSwitches = newActiveSwitches;
functionsContext.activeFunctions = newActiveFunctions;
#if defined(ROTARY_ENCODERS) && defined(GVARS)
for (uint8_t i=0; i<ROTARY_ENCODERS; i++) {
rePreviousValues[i] = (g_rotenc[i] / ROTARY_ENCODER_GRANULARITY);
}
#endif
}
#if !defined(CPUARM)
#undef functions
#undef functionsContext
#endif
+21 -10
View File
@@ -73,6 +73,7 @@ const LanguagePack * LP_CONST languagePacks[] = {
enum EnumTabDiag {
e_Setup,
CASE_SDCARD(e_Sd)
CASE_CPUARM(e_GeneralCustomFunctions)
e_Trainer,
e_Vers,
e_Keys,
@@ -83,6 +84,7 @@ enum EnumTabDiag {
void menuGeneralSetup(uint8_t event);
void menuGeneralSdManager(uint8_t event);
void menuGeneralCustomFunctions(uint8_t event);
void menuGeneralTrainer(uint8_t event);
void menuGeneralVersion(uint8_t event);
void menuGeneralDiagKeys(uint8_t event);
@@ -90,9 +92,10 @@ void menuGeneralDiagAna(uint8_t event);
void menuGeneralHardware(uint8_t event);
void menuGeneralCalib(uint8_t event);
const MenuFuncP_PROGMEM menuTabDiag[] PROGMEM = {
const MenuFuncP_PROGMEM menuTabGeneral[] PROGMEM = {
menuGeneralSetup,
CASE_SDCARD(menuGeneralSdManager)
CASE_CPUARM(menuGeneralCustomFunctions)
menuGeneralTrainer,
menuGeneralVersion,
menuGeneralDiagKeys,
@@ -215,7 +218,7 @@ void menuGeneralSetup(uint8_t event)
}
#endif
MENU(STR_MENURADIOSETUP, menuTabDiag, e_Setup, ITEM_SETUP_MAX+1, {0, CASE_RTCLOCK(2) CASE_RTCLOCK(2) CASE_BATTGRAPH(1) LABEL(SOUND), CASE_AUDIO(0) CASE_BUZZER(0) CASE_VOICE(0) CASE_CPUARM(0) CASE_CPUARM(0) CASE_CPUARM(0) 0, CASE_AUDIO(0) CASE_VARIO_CPUARM(LABEL(VARIO)) CASE_VARIO_CPUARM(0) CASE_VARIO_CPUARM(0) CASE_VARIO_CPUARM(0) CASE_VARIO_CPUARM(0) CASE_HAPTIC(LABEL(HAPTIC)) CASE_HAPTIC(0) CASE_HAPTIC(0) CASE_HAPTIC(0) 0, LABEL(ALARMS), 0, CASE_PCBSKY9X(0) CASE_PCBSKY9X(0) 0, 0, 0, IF_ROTARY_ENCODERS(0) LABEL(BACKLIGHT), 0, 0, CASE_CPUARM(0) CASE_REVPLUS(0) CASE_PWM_BACKLIGHT(0) CASE_PWM_BACKLIGHT(0) 0, CASE_SPLASH_PARAM(0) CASE_GPS(0) CASE_GPS(0) CASE_PXX(0) CASE_CPUARM(0) CASE_CPUARM(0) IF_FAI_CHOICE(0) CASE_MAVLINK(0) CASE_CPUARM(0) 0, COL_TX_MODE, CASE_PCBTARANIS(0) 1/*to force edit mode*/});
MENU(STR_MENURADIOSETUP, menuTabGeneral, e_Setup, ITEM_SETUP_MAX+1, {0, CASE_RTCLOCK(2) CASE_RTCLOCK(2) CASE_BATTGRAPH(1) LABEL(SOUND), CASE_AUDIO(0) CASE_BUZZER(0) CASE_VOICE(0) CASE_CPUARM(0) CASE_CPUARM(0) CASE_CPUARM(0) 0, CASE_AUDIO(0) CASE_VARIO_CPUARM(LABEL(VARIO)) CASE_VARIO_CPUARM(0) CASE_VARIO_CPUARM(0) CASE_VARIO_CPUARM(0) CASE_VARIO_CPUARM(0) CASE_HAPTIC(LABEL(HAPTIC)) CASE_HAPTIC(0) CASE_HAPTIC(0) CASE_HAPTIC(0) 0, LABEL(ALARMS), 0, CASE_PCBSKY9X(0) CASE_PCBSKY9X(0) 0, 0, 0, IF_ROTARY_ENCODERS(0) LABEL(BACKLIGHT), 0, 0, CASE_CPUARM(0) CASE_REVPLUS(0) CASE_PWM_BACKLIGHT(0) CASE_PWM_BACKLIGHT(0) 0, CASE_SPLASH_PARAM(0) CASE_GPS(0) CASE_GPS(0) CASE_PXX(0) CASE_CPUARM(0) CASE_CPUARM(0) IF_FAI_CHOICE(0) CASE_MAVLINK(0) CASE_CPUARM(0) 0, COL_TX_MODE, CASE_PCBTARANIS(0) 1/*to force edit mode*/});
uint8_t sub = m_posVert - 1;
@@ -918,7 +921,7 @@ void menuGeneralSdManager(uint8_t _event)
#endif
uint8_t event = ((READ_ONLY() && EVT_KEY_MASK(_event) == KEY_ENTER) ? 0 : _event);
SIMPLE_MENU(SD_IS_HC() ? STR_SDHC_CARD : STR_SD_CARD, menuTabDiag, e_Sd, 1+reusableBuffer.sdmanager.count);
SIMPLE_MENU(SD_IS_HC() ? STR_SDHC_CARD : STR_SD_CARD, menuTabGeneral, e_Sd, 1+reusableBuffer.sdmanager.count);
if (s_editMode > 0)
s_editMode = 0;
@@ -1128,6 +1131,14 @@ void menuGeneralSdManager(uint8_t _event)
}
#endif
#if defined(CPUARM)
void menuGeneralCustomFunctions(uint8_t event)
{
MENU(STR_MENUGLOBALFUNCS, menuTabGeneral, e_GeneralCustomFunctions, NUM_CFN+1, {0, NAVIGATION_LINE_BY_LINE|4/*repeated*/});
return menuCustomFunctions(event, g_eeGeneral.customFn, globalFunctionsContext);
}
#endif
#if LCD_W >= 212
#define TRAINER_CALIB_POS 12
#else
@@ -1139,7 +1150,7 @@ void menuGeneralTrainer(uint8_t event)
uint8_t y;
bool slave = SLAVE_MODE();
MENU(STR_MENUTRAINER, menuTabDiag, e_Trainer, (slave ? 1 : 7), {0, 2, 2, 2, 2, 0/*, 0*/});
MENU(STR_MENUTRAINER, menuTabGeneral, e_Trainer, (slave ? 1 : 7), {0, 2, 2, 2, 2, 0/*, 0*/});
if (slave) {
lcd_puts(7*FW, 4*FH, STR_SLAVE);
@@ -1211,7 +1222,7 @@ void menuGeneralTrainer(uint8_t event)
void menuGeneralVersion(uint8_t event)
{
SIMPLE_MENU(STR_MENUVERSION, menuTabDiag, e_Vers, 1);
SIMPLE_MENU(STR_MENUVERSION, menuTabGeneral, e_Vers, 1);
lcd_putsLeft(MENU_TITLE_HEIGHT+FH, vers_stamp);
@@ -1241,7 +1252,7 @@ void displayKeyState(uint8_t x, uint8_t y, EnumKeys key)
void menuGeneralDiagKeys(uint8_t event)
{
SIMPLE_MENU(STR_MENUDIAG, menuTabDiag, e_Keys, 1);
SIMPLE_MENU(STR_MENUDIAG, menuTabGeneral, e_Keys, 1);
lcd_puts(14*FW, MENU_TITLE_HEIGHT+2*FH, STR_VTRIM);
@@ -1289,7 +1300,7 @@ void menuGeneralDiagAna(uint8_t event)
#define ANAS_ITEMS_COUNT 2
#endif
SIMPLE_MENU(STR_MENUANA, menuTabDiag, e_Ana, ANAS_ITEMS_COUNT);
SIMPLE_MENU(STR_MENUANA, menuTabGeneral, e_Ana, ANAS_ITEMS_COUNT);
STICK_SCROLL_DISABLE();
@@ -1362,7 +1373,7 @@ enum menuGeneralHwItems {
void menuGeneralHardware(uint8_t event)
{
MENU(STR_HARDWARE, menuTabDiag, e_Hardware, ITEM_SETUP_HW_MAX+1, {0});
MENU(STR_HARDWARE, menuTabGeneral, e_Hardware, ITEM_SETUP_HW_MAX+1, {0});
uint8_t sub = m_posVert - 1;
@@ -1417,7 +1428,7 @@ enum menuGeneralHwItems {
#define GENERAL_HW_PARAM_OFS (2+(15*FW))
void menuGeneralHardware(uint8_t event)
{
MENU(STR_HARDWARE, menuTabDiag, e_Hardware, ITEM_SETUP_HW_MAX+1, {0, 0, (uint8_t)-1, 0, 0, 0, IF_ROTARY_ENCODERS(0) CASE_BLUETOOTH(0)});
MENU(STR_HARDWARE, menuTabGeneral, e_Hardware, ITEM_SETUP_HW_MAX+1, {0, 0, (uint8_t)-1, 0, 0, 0, IF_ROTARY_ENCODERS(0) CASE_BLUETOOTH(0)});
uint8_t sub = m_posVert - 1;
@@ -1636,7 +1647,7 @@ void menuCommonCalib(uint8_t event)
void menuGeneralCalib(uint8_t event)
{
check_simple(event, e_Calib, menuTabDiag, DIM(menuTabDiag), 0);
check_simple(event, e_Calib, menuTabGeneral, DIM(menuTabGeneral), 0);
if (menuEvent) {
calibrationState = 0;
+109 -78
View File
@@ -4410,18 +4410,18 @@ enum LogicalSwitchFields {
#endif
#if defined(CPUARM)
#define INCDEC_DECLARE_VARS() uint8_t incdecFlag = EE_MODEL; IsValueAvailable isValueAvailable = NULL
#define INCDEC_SET_FLAG(f) incdecFlag = (EE_MODEL|(f))
#define INCDEC_DECLARE_VARS(f) uint8_t incdecFlag = (f); IsValueAvailable isValueAvailable = NULL
#define INCDEC_SET_FLAG(f) incdecFlag = (f)
#define INCDEC_ENABLE_CHECK(fn) isValueAvailable = fn
#define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, incdecFlag, isValueAvailable)
#elif defined(CPUM64)
#define INCDEC_DECLARE_VARS()
#define INCDEC_DECLARE_VARS(f)
#define INCDEC_SET_FLAG(f)
#define INCDEC_ENABLE_CHECK(fn)
#define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, EE_MODEL)
#else
#define INCDEC_DECLARE_VARS() uint8_t incdecFlag = EE_MODEL
#define INCDEC_SET_FLAG(f) incdecFlag = (EE_MODEL|(f))
#define INCDEC_DECLARE_VARS(f) uint8_t incdecFlag = (f)
#define INCDEC_SET_FLAG(f) incdecFlag = (f)
#define INCDEC_ENABLE_CHECK(fn)
#define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, incdecFlag)
#endif
@@ -4458,7 +4458,7 @@ void menuModelLogicalSwitchOne(uint8_t event)
int8_t sub = m_posVert;
INCDEC_DECLARE_VARS();
INCDEC_DECLARE_VARS(EE_MODEL);
int v1_val = cs->v1;
@@ -4502,7 +4502,7 @@ void menuModelLogicalSwitchOne(uint8_t event)
else {
v1_val = (uint8_t)cs->v1;
putsMixerSource(CSWONE_2ND_COLUMN, y, v1_val, attr);
INCDEC_SET_FLAG(INCDEC_SOURCE);
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable);
}
if (attr) {
@@ -4533,7 +4533,7 @@ void menuModelLogicalSwitchOne(uint8_t event)
}
else if (cstate == LS_FAMILY_COMP) {
putsMixerSource(CSWONE_2ND_COLUMN, y, cs->v2, attr);
INCDEC_SET_FLAG(INCDEC_SOURCE);
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable);
}
else {
@@ -4547,7 +4547,7 @@ void menuModelLogicalSwitchOne(uint8_t event)
v2_min = 0;
else
v2_min = minTelemValue(v1_val - MIXSRC_FIRST_TELEM + 1);
INCDEC_SET_FLAG(INCDEC_REP10 | NO_INCDEC_MARKS);
INCDEC_SET_FLAG(EE_MODEL | INCDEC_REP10 | NO_INCDEC_MARKS);
if (cs->v2 < v2_min || cs->v2 > v2_max) {
cs->v2 = 0;
eeDirty(EE_MODEL);
@@ -4675,7 +4675,7 @@ struct Clipboard {
ClipboardType type;
union {
LogicalSwitchData csw;
CustomFnData cfn;
CustomFunctionData cfn;
} data;
};
@@ -4703,7 +4703,7 @@ void onLogicalSwitchesMenu(const char *result)
void menuModelLogicalSwitches(uint8_t event)
{
INCDEC_DECLARE_VARS();
INCDEC_DECLARE_VARS(EE_MODEL);
MENU(STR_MENULOGICALSWITCHES, menuTabModel, e_LogicalSwitches, NUM_LOGICAL_SWITCH+1, {0, NAVIGATION_LINE_BY_LINE|LS_FIELD_LAST/*repeated...*/});
@@ -4761,7 +4761,7 @@ void menuModelLogicalSwitches(uint8_t event)
putsSwitches(CSW_3RD_COLUMN, y, cs->v2, attr2);
v1_min = SWSRC_FIRST_IN_LOGICAL_SWITCHES; v1_max = SWSRC_LAST_IN_LOGICAL_SWITCHES;
v2_min = SWSRC_FIRST_IN_LOGICAL_SWITCHES; v2_max = SWSRC_LAST_IN_LOGICAL_SWITCHES;
INCDEC_SET_FLAG(INCDEC_SWITCH);
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SWITCH);
INCDEC_ENABLE_CHECK(isSwitchAvailableInLogicalSwitches);
}
#if defined(CPUARM)
@@ -4772,11 +4772,11 @@ void menuModelLogicalSwitches(uint8_t event)
v2_min=-129; v2_max = 122;
v3_max = 222 - cs->v2;
if (horz == 1) {
INCDEC_SET_FLAG(INCDEC_SWITCH);
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SWITCH);
INCDEC_ENABLE_CHECK(isSwitchAvailableInLogicalSwitches);
}
else {
INCDEC_SET_FLAG(0);
INCDEC_SET_FLAG(EE_MODEL);
INCDEC_ENABLE_CHECK(NULL);
}
}
@@ -4787,7 +4787,7 @@ void menuModelLogicalSwitches(uint8_t event)
#endif
putsMixerSource(CSW_2ND_COLUMN, y, v1_val, attr1);
putsMixerSource(CSW_3RD_COLUMN, y, cs->v2, attr2);
INCDEC_SET_FLAG(INCDEC_SOURCE);
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable);
}
else if (cstate == LS_FAMILY_TIMER) {
@@ -4795,7 +4795,7 @@ void menuModelLogicalSwitches(uint8_t event)
lcd_outdezAtt(CSW_3RD_COLUMN, y, lswTimerValue(cs->v2), LEFT|PREC1|attr2);
v1_min = v2_min = -128;
v1_max = v2_max = 122;
INCDEC_SET_FLAG(0);
INCDEC_SET_FLAG(EE_MODEL);
INCDEC_ENABLE_CHECK(NULL);
}
else {
@@ -4804,11 +4804,11 @@ void menuModelLogicalSwitches(uint8_t event)
#endif
putsMixerSource(CSW_2ND_COLUMN, y, v1_val, attr1);
if (horz == 1) {
INCDEC_SET_FLAG(INCDEC_SOURCE);
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable);
}
else {
INCDEC_SET_FLAG(0);
INCDEC_SET_FLAG(EE_MODEL);
INCDEC_ENABLE_CHECK(NULL);
}
#if defined(FRSKY)
@@ -4823,7 +4823,7 @@ void menuModelLogicalSwitches(uint8_t event)
else
v2_min = minTelemValue(v1_val - MIXSRC_FIRST_TELEM + 1);
if (horz == 2 && v2_max-v2_min > 1000)
INCDEC_SET_FLAG(INCDEC_REP10 | NO_INCDEC_MARKS);
INCDEC_SET_FLAG(EE_MODEL | INCDEC_REP10 | NO_INCDEC_MARKS);
if (cs->v2 < v2_min || cs->v2 > v2_max) {
cs->v2 = 0;
eeDirty(EE_MODEL);
@@ -4955,7 +4955,7 @@ void menuModelLogicalSwitches(uint8_t event)
#endif
case LS_FIELD_ANDSW:
#if defined(CPUARM)
INCDEC_SET_FLAG(INCDEC_SWITCH);
INCDEC_SET_FLAG(EE_MODEL | INCDEC_SWITCH);
INCDEC_ENABLE_CHECK(isSwitchAvailableInLogicalSwitches);
cs->andsw = CHECK_INCDEC_PARAM(event, cs->andsw, -MAX_LS_ANDSW, MAX_LS_ANDSW);
#else
@@ -4998,7 +4998,7 @@ void menuModelLogicalSwitches(uint8_t event)
void onCustomFunctionsFileSelectionMenu(const char *result)
{
int8_t sub = m_posVert - 1;
CustomFnData * cf = &g_model.funcSw[sub];
CustomFunctionData * cf = &g_model.customFn[sub];
uint8_t func = CFN_FUNC(cf);
if (result == STR_UPDATE_LIST) {
@@ -5030,7 +5030,17 @@ void onCustomFunctionsFileSelectionMenu(const char *result)
void onCustomFunctionsMenu(const char *result)
{
int8_t sub = m_posVert-1;
CustomFnData * cfn = &g_model.funcSw[sub];
CustomFunctionData * cfn;
uint8_t eeFlags;
if (g_menuStack[0] == menuModelCustomFunctions) {
cfn = &g_model.customFn[sub];
eeFlags = EE_MODEL;
}
else {
cfn = &g_eeGeneral.customFn[sub];
eeFlags = EE_GENERAL;
}
if (result == STR_COPY) {
clipboard.type = CLIPBOARD_TYPE_CUSTOM_FUNCTION;
@@ -5038,45 +5048,47 @@ void onCustomFunctionsMenu(const char *result)
}
else if (result == STR_PASTE) {
*cfn = clipboard.data.cfn;
eeDirty(EE_MODEL);
eeDirty(eeFlags);
}
else if (result == STR_CLEAR) {
memset(cfn, 0, sizeof(CustomFnData));
eeDirty(EE_MODEL);
memset(cfn, 0, sizeof(CustomFunctionData));
eeDirty(eeFlags);
}
else if (result == STR_INSERT) {
memmove(cfn+1, cfn, (NUM_CFN-sub-1)*sizeof(CustomFnData));
memset(cfn, 0, sizeof(CustomFnData));
eeDirty(EE_MODEL);
memmove(cfn+1, cfn, (NUM_CFN-sub-1)*sizeof(CustomFunctionData));
memset(cfn, 0, sizeof(CustomFunctionData));
eeDirty(eeFlags);
}
else if (result == STR_DELETE) {
memmove(cfn, cfn+1, (NUM_CFN-sub-1)*sizeof(CustomFnData));
memset(&g_model.funcSw[NUM_CFN-1], 0, sizeof(CustomFnData));
eeDirty(EE_MODEL);
memmove(cfn, cfn+1, (NUM_CFN-sub-1)*sizeof(CustomFunctionData));
memset(&g_model.customFn[NUM_CFN-1], 0, sizeof(CustomFunctionData));
eeDirty(eeFlags);
}
}
#endif
void menuModelCustomFunctions(uint8_t event)
void menuCustomFunctions(uint8_t event, CustomFunctionData * functions, CustomFunctionsContext & functionsContext)
{
MENU(STR_MENUCUSTOMFUNC, menuTabModel, e_CustomFunctions, NUM_CFN+1, {0, NAVIGATION_LINE_BY_LINE|4/*repeated*/});
int8_t sub = m_posVert - 1;
#if defined(CPUARM) || defined(AUTOSWITCH)
uint8_t eeFlags = (functions == g_model.customFn) ? EE_MODEL : EE_GENERAL;
#endif
#if defined(PCBTARANIS)
if (sub>=0 && m_posHorz<0 && event==EVT_KEY_LONG(KEY_ENTER) && !READ_ONLY()) {
killEvents(event);
CustomFnData *sd = &g_model.funcSw[sub];
if (!CFN_EMPTY(sd))
CustomFunctionData *cfn = &functions[sub];
if (!CFN_EMPTY(cfn))
MENU_ADD_ITEM(STR_COPY);
if (clipboard.type == CLIPBOARD_TYPE_CUSTOM_FUNCTION)
MENU_ADD_ITEM(STR_PASTE);
if (!CFN_EMPTY(sd) && CFN_EMPTY(&g_model.funcSw[NUM_CFN-1]))
if (!CFN_EMPTY(cfn) && CFN_EMPTY(&functions[NUM_CFN-1]))
MENU_ADD_ITEM(STR_INSERT);
if (!CFN_EMPTY(sd))
if (!CFN_EMPTY(cfn))
MENU_ADD_ITEM(STR_CLEAR);
for (int i=sub+1; i<NUM_CFN; i++) {
if (!CFN_EMPTY(&g_model.funcSw[i])) {
if (!CFN_EMPTY(&functions[i])) {
MENU_ADD_ITEM(STR_DELETE);
break;
}
@@ -5093,27 +5105,32 @@ void menuModelCustomFunctions(uint8_t event)
putsStrIdx(0, y, STR_CF, k+1, (sub==k && m_posHorz<0) ? INVERS : 0);
#endif
CustomFnData *sd = &g_model.funcSw[k];
uint8_t func = CFN_FUNC(sd);
CustomFunctionData *cfn = &functions[k];
uint8_t func = CFN_FUNC(cfn);
for (uint8_t j=0; j<5; j++) {
uint8_t attr = ((sub==k && m_posHorz==j) ? ((s_editMode>0) ? BLINK|INVERS : INVERS) : 0);
uint8_t active = (attr && (s_editMode>0 || p1valdiff));
switch (j) {
case 0:
putsSwitches(MODEL_CUSTOM_FUNC_1ST_COLUMN, y, CFN_SWITCH(sd), attr | ((activeFnSwitches & ((MASK_CFN_TYPE)1 << k)) ? BOLD : 0));
if (active || AUTOSWITCH_ENTER_LONG()) CHECK_INCDEC_MODELSWITCH(event, CFN_SWITCH(sd), SWSRC_FIRST, SWSRC_LAST, isSwitchAvailableInCustomFunctions);
putsSwitches(MODEL_CUSTOM_FUNC_1ST_COLUMN, y, CFN_SWITCH(cfn), attr | ((functionsContext.activeSwitches & ((MASK_CFN_TYPE)1 << k)) ? BOLD : 0));
if (active || AUTOSWITCH_ENTER_LONG()) CHECK_INCDEC_SWITCH(event, CFN_SWITCH(cfn), SWSRC_FIRST, SWSRC_LAST, eeFlags, isSwitchAvailableInCustomFunctions);
break;
case 1:
if (CFN_SWITCH(sd)) {
if (CFN_SWITCH(cfn)) {
#if defined(CPUARM)
if (func == FUNC_OVERRIDE_CHANNEL) {
func = CFN_FUNC(cfn) = checkIncDec(event, CFN_FUNC(cfn), 0, FUNC_MAX-1, eeFlags, isAssignableFunctionAvailable);
}
#endif
lcd_putsiAtt(MODEL_CUSTOM_FUNC_2ND_COLUMN, y, STR_VFSWFUNC, func, attr);
if (active) {
#if defined(CPUARM)
CFN_FUNC(sd) = checkIncDec(event, CFN_FUNC(sd), 0, FUNC_MAX-1, EE_MODEL, isAssignableFunctionAvailable);
CFN_FUNC(cfn) = checkIncDec(event, CFN_FUNC(cfn), 0, FUNC_MAX-1, eeFlags, isAssignableFunctionAvailable);
#else
CHECK_INCDEC_MODELVAR_ZERO(event, CFN_FUNC(sd), FUNC_MAX-1);
CHECK_INCDEC_MODELVAR_ZERO(event, CFN_FUNC(cfn), FUNC_MAX-1);
#endif
if (checkIncDec_Ret) CFN_RESET(sd);
if (checkIncDec_Ret) CFN_RESET(cfn);
}
}
else {
@@ -5129,45 +5146,49 @@ void menuModelCustomFunctions(uint8_t event)
int8_t maxParam = NUM_CHNOUT-1;
#if defined(OVERRIDE_CHANNEL_FUNCTION)
if (func == FUNC_OVERRIDE_CHANNEL) {
putsChn(lcdNextPos, y, CFN_CH_INDEX(sd)+1, attr);
putsChn(lcdNextPos, y, CFN_CH_INDEX(cfn)+1, attr);
}
else
#endif
if (func == FUNC_TRAINER) {
maxParam = 4;
#if defined(CPUARM)
putsMixerSource(lcdNextPos, y, CFN_CH_INDEX(sd)==0 ? 0 : MIXSRC_Rud+CFN_CH_INDEX(sd)-1, attr);
putsMixerSource(lcdNextPos, y, CFN_CH_INDEX(cfn)==0 ? 0 : MIXSRC_Rud+CFN_CH_INDEX(cfn)-1, attr);
#else
putsMixerSource(lcdNextPos, y, MIXSRC_Rud+CFN_CH_INDEX(sd)-1, attr);
putsMixerSource(lcdNextPos, y, MIXSRC_Rud+CFN_CH_INDEX(cfn)-1, attr);
#endif
}
#if defined(GVARS)
else if (func == FUNC_ADJUST_GVAR) {
maxParam = MAX_GVARS-1;
putsStrIdx(lcdNextPos, y, STR_GV, CFN_GVAR_INDEX(sd)+1, attr);
if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_GVAR_INDEX(sd), maxParam);
putsStrIdx(lcdNextPos, y, STR_GV, CFN_GVAR_INDEX(cfn)+1, attr);
#if defined(CPUARM)
if (active) CFN_GVAR_INDEX(cfn) = checkIncDec(event, CFN_GVAR_INDEX(cfn), 0, maxParam, eeFlags);
#else
if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_GVAR_INDEX(cfn), maxParam);
#endif
break;
}
#endif
#if defined(CPUARM)
else if (func == FUNC_SET_TIMER) {
maxParam = MAX_TIMERS-1;
putsStrIdx(lcdNextPos, y, STR_TIMER, CFN_TIMER_INDEX(sd)+1, attr);
if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_TIMER_INDEX(sd), maxParam);
putsStrIdx(lcdNextPos, y, STR_TIMER, CFN_TIMER_INDEX(cfn)+1, attr);
if (active) CFN_TIMER_INDEX(cfn) = checkIncDec(event, CFN_TIMER_INDEX(cfn), 0, maxParam, eeFlags);
break;
}
#endif
else if (attr) {
REPEAT_LAST_CURSOR_MOVE();
}
if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_CH_INDEX(sd), maxParam);
if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_CH_INDEX(cfn), maxParam);
break;
}
case 3:
{
INCDEC_DECLARE_VARS();
int16_t val_displayed = CFN_PARAM(sd);
INCDEC_DECLARE_VARS(eeFlags);
int16_t val_displayed = CFN_PARAM(cfn);
#if defined(CPUARM)
int16_t val_min = 0;
int16_t val_max = 255;
@@ -5177,12 +5198,12 @@ void menuModelCustomFunctions(uint8_t event)
#endif
if (func == FUNC_RESET) {
val_max = FUNC_RESET_PARAM_LAST;
lcd_putsiAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, STR_VFSWRESET, CFN_PARAM(sd), attr);
lcd_putsiAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, STR_VFSWRESET, CFN_PARAM(cfn), attr);
}
#if defined(OVERRIDE_CHANNEL_FUNCTION)
else if (func == FUNC_OVERRIDE_CHANNEL) {
#if !defined(CPUARM)
val_displayed = (int8_t)CFN_PARAM(sd);
val_displayed = (int8_t)CFN_PARAM(cfn);
#endif
val_min = -LIMIT_EXT_PERCENT; val_max = +LIMIT_EXT_PERCENT;
lcd_outdezAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr|LEFT);
@@ -5213,8 +5234,8 @@ void menuModelCustomFunctions(uint8_t event)
#else
coord_t x = (func == FUNC_PLAY_TRACK ? MODEL_CUSTOM_FUNC_2ND_COLUMN + FW + FW*strlen(TR_PLAY_TRACK) : MODEL_CUSTOM_FUNC_3RD_COLUMN);
#endif
if (ZEXIST(sd->play.name))
lcd_putsnAtt(x, y, sd->play.name, sizeof(sd->play.name), attr);
if (ZEXIST(cfn->play.name))
lcd_putsnAtt(x, y, cfn->play.name, sizeof(cfn->play.name), attr);
else
lcd_putsiAtt(x, y, STR_VCSWFUNC, 0, attr);
if (active && event==EVT_KEY_BREAK(KEY_ENTER)) {
@@ -5227,7 +5248,7 @@ void menuModelCustomFunctions(uint8_t event)
strcpy(directory, SOUNDS_PATH);
strncpy(directory+SOUNDS_PATH_LNG_OFS, currentLanguagePack->id, 2);
}
if (listSdFiles(directory, func==FUNC_PLAY_SCRIPT ? SCRIPTS_EXT : SOUNDS_EXT, sizeof(sd->play.name), sd->play.name)) {
if (listSdFiles(directory, func==FUNC_PLAY_SCRIPT ? SCRIPTS_EXT : SOUNDS_EXT, sizeof(cfn->play.name), cfn->play.name)) {
menuHandler = onCustomFunctionsFileSelectionMenu;
}
else {
@@ -5247,7 +5268,7 @@ void menuModelCustomFunctions(uint8_t event)
else if (func == FUNC_VOLUME) {
val_max = MIXSRC_LAST_CH;
putsMixerSource(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr);
INCDEC_SET_FLAG(INCDEC_SOURCE);
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable);
}
#elif defined(VOICE)
@@ -5293,24 +5314,24 @@ void menuModelCustomFunctions(uint8_t event)
#endif
#if defined(PCBTARANIS) && defined(REVPLUS)
else if (func == FUNC_BACKLIGHT) {
displaySlider(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, CFN_PARAM(sd), 100, attr);
INCDEC_SET_FLAG(NO_INCDEC_MARKS);
displaySlider(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, CFN_PARAM(cfn), 100, attr);
INCDEC_SET_FLAG(eeFlags | NO_INCDEC_MARKS);
val_min = 0;
val_max = 100;
}
#endif
#if defined(GVARS)
else if (func == FUNC_ADJUST_GVAR) {
switch (CFN_GVAR_MODE(sd)) {
switch (CFN_GVAR_MODE(cfn)) {
case FUNC_ADJUST_GVAR_CONSTANT:
val_displayed = (int16_t)CFN_PARAM(sd);
val_displayed = (int16_t)CFN_PARAM(cfn);
val_min = -CFN_GVAR_CST_MAX; val_max = +CFN_GVAR_CST_MAX;
lcd_outdezAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr|LEFT);
break;
case FUNC_ADJUST_GVAR_SOURCE:
val_max = MIXSRC_LAST_CH;
putsMixerSource(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr);
INCDEC_SET_FLAG(INCDEC_SOURCE);
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable);
break;
case FUNC_ADJUST_GVAR_GVAR:
@@ -5327,9 +5348,9 @@ void menuModelCustomFunctions(uint8_t event)
killEvents(event);
s_editMode = !s_editMode;
active = true;
CFN_GVAR_MODE(sd) += 1;
CFN_GVAR_MODE(cfn) += 1;
#if defined(CPUARM)
CFN_GVAR_MODE(sd) &= 0x03;
CFN_GVAR_MODE(cfn) &= 0x03;
#endif
val_displayed = 0;
}
@@ -5340,18 +5361,22 @@ void menuModelCustomFunctions(uint8_t event)
}
if (active) {
CFN_PARAM(sd) = CHECK_INCDEC_PARAM(event, val_displayed, val_min, val_max);
CFN_PARAM(cfn) = CHECK_INCDEC_PARAM(event, val_displayed, val_min, val_max);
}
break;
}
case 4:
if (HAS_ENABLE_PARAM(func)) {
menu_lcd_onoff(MODEL_CUSTOM_FUNC_4TH_COLUMN_ONOFF, y, CFN_ACTIVE(sd), attr);
if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_ACTIVE(sd), 1);
menu_lcd_onoff(MODEL_CUSTOM_FUNC_4TH_COLUMN_ONOFF, y, CFN_ACTIVE(cfn), attr);
#if defined(CPUARM)
if (active) CFN_ACTIVE(cfn) = checkIncDec(event, CFN_ACTIVE(cfn), 0, 1, eeFlags);
#else
if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_ACTIVE(cfn), 1);
#endif
}
else if (HAS_REPEAT_PARAM(func)) {
if (CFN_PLAY_REPEAT(sd) == 0) {
if (CFN_PLAY_REPEAT(cfn) == 0) {
#if LCD_W >= 212
lcd_putsAtt(MODEL_CUSTOM_FUNC_4TH_COLUMN+2, y, "1x", attr);
#else
@@ -5359,7 +5384,7 @@ void menuModelCustomFunctions(uint8_t event)
#endif
}
#if defined(CPUARM)
else if (CFN_PLAY_REPEAT(sd) == CFN_PLAY_REPEAT_NOSTART) {
else if (CFN_PLAY_REPEAT(cfn) == CFN_PLAY_REPEAT_NOSTART) {
#if LCD_W >= 212
lcd_putcAtt(MODEL_CUSTOM_FUNC_4TH_COLUMN-1, y, '!', attr);
lcd_putsAtt(MODEL_CUSTOM_FUNC_4TH_COLUMN+2, y, "1x", attr);
@@ -5369,15 +5394,15 @@ void menuModelCustomFunctions(uint8_t event)
}
#endif
else {
lcd_outdezAtt(MODEL_CUSTOM_FUNC_4TH_COLUMN+2+FW, y, CFN_PLAY_REPEAT(sd)*CFN_PLAY_REPEAT_MUL, attr);
lcd_outdezAtt(MODEL_CUSTOM_FUNC_4TH_COLUMN+2+FW, y, CFN_PLAY_REPEAT(cfn)*CFN_PLAY_REPEAT_MUL, attr);
#if LCD_W >= 212
lcd_putcAtt(MODEL_CUSTOM_FUNC_4TH_COLUMN+2+FW, y, 's', attr);
#endif
}
#if defined(CPUARM)
if (active) CFN_PLAY_REPEAT(sd) = checkIncDecModel(event, CFN_PLAY_REPEAT(sd)==CFN_PLAY_REPEAT_NOSTART?-1:CFN_PLAY_REPEAT(sd), -1, 60/CFN_PLAY_REPEAT_MUL);
if (active) CFN_PLAY_REPEAT(cfn) = checkIncDec(event, CFN_PLAY_REPEAT(cfn)==CFN_PLAY_REPEAT_NOSTART?-1:CFN_PLAY_REPEAT(cfn), -1, 60/CFN_PLAY_REPEAT_MUL, eeFlags);
#else
if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_PLAY_REPEAT(sd), 60/CFN_PLAY_REPEAT_MUL);
if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_PLAY_REPEAT(cfn), 60/CFN_PLAY_REPEAT_MUL);
#endif
}
else if (attr) {
@@ -5389,6 +5414,12 @@ void menuModelCustomFunctions(uint8_t event)
}
}
void menuModelCustomFunctions(uint8_t event)
{
MENU(STR_MENUCUSTOMFUNC, menuTabModel, e_CustomFunctions, NUM_CFN+1, {0, NAVIGATION_LINE_BY_LINE|4/*repeated*/});
return menuCustomFunctions(event, g_model.customFn, modelFunctionsContext);
}
#if defined(LUA_MODEL_SCRIPTS)
void onModelCustomScriptMenu(const char *result)
{
+28 -11
View File
@@ -1487,7 +1487,8 @@ bool isInputSourceAvailable(int source)
enum SwitchContext
{
LogicalSwitchesContext,
CustomFunctionsContext,
ModelCustomFunctionsContext,
GeneralCustomFunctionsContext,
TimersContext,
MixesContext
};
@@ -1518,17 +1519,22 @@ bool isSwitchAvailable(int swtch, SwitchContext context)
}
#endif
if (context != LogicalSwitchesContext && swtch >= SWSRC_FIRST_LOGICAL_SWITCH && swtch <= SWSRC_LAST_LOGICAL_SWITCH) {
LogicalSwitchData * cs = lswAddress(swtch-SWSRC_FIRST_LOGICAL_SWITCH);
return (cs->func != LS_FUNC_NONE);
if (swtch >= SWSRC_FIRST_LOGICAL_SWITCH && swtch <= SWSRC_LAST_LOGICAL_SWITCH) {
if (context == GeneralCustomFunctionsContext) {
return false;
}
else if (context != LogicalSwitchesContext) {
LogicalSwitchData * cs = lswAddress(swtch-SWSRC_FIRST_LOGICAL_SWITCH);
return (cs->func != LS_FUNC_NONE);
}
}
if (context != CustomFunctionsContext && (swtch == SWSRC_ON || swtch == SWSRC_One)) {
if (context != ModelCustomFunctionsContext && context != GeneralCustomFunctionsContext && (swtch == SWSRC_ON || swtch == SWSRC_One)) {
return false;
}
if (swtch >= SWSRC_FIRST_FLIGHT_MODE && swtch <= SWSRC_LAST_FLIGHT_MODE) {
if (context == MixesContext) {
if (context == MixesContext || context == GeneralCustomFunctionsContext) {
return false;
}
else {
@@ -1551,7 +1557,10 @@ bool isSwitchAvailableInLogicalSwitches(int swtch)
bool isSwitchAvailableInCustomFunctions(int swtch)
{
return isSwitchAvailable(swtch, CustomFunctionsContext);
if (g_menuStack[0] == menuModelCustomFunctions)
return isSwitchAvailable(swtch, ModelCustomFunctionsContext);
else
return isSwitchAvailable(swtch, GeneralCustomFunctionsContext);
}
bool isSwitchAvailableInMixes(int swtch)
@@ -1587,15 +1596,23 @@ bool isLogicalSwitchFunctionAvailable(int function)
bool isAssignableFunctionAvailable(int function)
{
bool modelFunctions = (g_menuStack[0] == menuModelCustomFunctions);
switch (function) {
#if !defined(OVERRIDE_CHANNEL_FUNCTION)
case FUNC_OVERRIDE_CHANNEL:
#if defined(OVERRIDE_CHANNEL_FUNCTION)
return modelFunctions;
#else
return false;
#endif
case FUNC_ADJUST_GVAR:
#if defined(GVARS)
return modelFunctions;
#else
return false;
#endif
#if !defined(HAPTIC)
case FUNC_HAPTIC:
#endif
#if !defined(GVARS)
case FUNC_ADJUST_GVAR:
#endif
case FUNC_PLAY_DIFF:
case FUNC_RESERVE1:
+10 -2
View File
@@ -103,6 +103,7 @@ void menu_lcd_onoff(coord_t x, coord_t y, uint8_t value, LcdFlags attr);
typedef void (*MenuFuncP)(uint8_t event);
typedef void (*MenuFuncP_PROGMEM)(uint8_t event);
extern const MenuFuncP_PROGMEM menuTabModel[];
extern const MenuFuncP_PROGMEM menuTabGeneral[];
extern MenuFuncP g_menuStack[5];
extern uint8_t g_menuPos[4];
@@ -133,6 +134,7 @@ void menuTelemetryFrsky(uint8_t event);
#endif
void menuGeneralSetup(uint8_t event);
void menuGeneralCalib(uint8_t event);
void menuCustomFunctions(uint8_t event, CustomFunctionData * functions, CustomFunctionsContext & functionsContext);
void menuModelSelect(uint8_t event);
void menuModelCustomFunctions(uint8_t event);
@@ -232,14 +234,20 @@ int8_t checkIncDecGen(uint8_t event, int8_t i_val, int8_t i_min, int8_t i_max);
bool isSwitchAvailableInTimers(int swtch);
bool isModuleAvailable(int module);
#define AUTOSWITCH_ENTER_LONG() (attr && event==EVT_KEY_LONG(KEY_ENTER))
#define CHECK_INCDEC_SWITCH(event, var, min, max, flags, available) \
var = checkIncDec(event, var, min, max, (flags)|INCDEC_SWITCH|NO_INCDEC_MARKS, available)
#define CHECK_INCDEC_MODELSWITCH(event, var, min, max, available) \
var = checkIncDec(event,var,min,max,EE_MODEL|INCDEC_SWITCH|NO_INCDEC_MARKS, available)
CHECK_INCDEC_SWITCH(event, var, min, max, EE_MODEL, available)
#elif defined(AUTOSWITCH)
#define AUTOSWITCH_ENTER_LONG() (attr && event==EVT_KEY_LONG(KEY_ENTER))
#define CHECK_INCDEC_SWITCH(event, var, min, max, flags, available) \
var = checkIncDec(event, var, min, max, (flags)|INCDEC_SWITCH)
#define CHECK_INCDEC_MODELSWITCH(event, var, min, max, available) \
var = checkIncDec(event,var,min,max,EE_MODEL|INCDEC_SWITCH)
CHECK_INCDEC_SWITCH(event, var, min, max, EE_MODEL, available)
#else
#define AUTOSWITCH_ENTER_LONG() (0)
#define CHECK_INCDEC_SWITCH(event, var, min, max, flags, available) \
CHECK_INCDEC_MODELVAR(event, var, min, max)
#define CHECK_INCDEC_MODELSWITCH(event, var, min, max, available) \
CHECK_INCDEC_MODELVAR(event, var, min, max)
#endif
+5 -5
View File
@@ -998,7 +998,7 @@ static int luaModelGetCustomFunction(lua_State *L)
{
int idx = luaL_checkunsigned(L, 1);
if (idx < NUM_CFN) {
CustomFnData * cfn = &g_model.funcSw[idx];
CustomFunctionData * cfn = &g_model.customFn[idx];
lua_newtable(L);
lua_pushtableinteger(L, "switch", CFN_SWITCH(cfn));
lua_pushtableinteger(L, "func", CFN_FUNC(cfn));
@@ -1022,8 +1022,8 @@ static int luaModelSetCustomFunction(lua_State *L)
{
int idx = luaL_checkunsigned(L, 1);
if (idx < NUM_CFN) {
CustomFnData * cfn = &g_model.funcSw[idx];
memclear(cfn, sizeof(CustomFnData));
CustomFunctionData * cfn = &g_model.customFn[idx];
memclear(cfn, sizeof(CustomFunctionData));
luaL_checktype(L, -1, LUA_TTABLE);
for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
luaL_checktype(L, -2, LUA_TSTRING); // key is string
@@ -1668,7 +1668,7 @@ bool luaLoadMixScript(uint8_t index)
bool luaLoadFunctionScript(uint8_t index)
{
CustomFnData & fn = g_model.funcSw[index];
CustomFunctionData & fn = g_model.customFn[index];
if (fn.func == FUNC_PLAY_SCRIPT && ZEXIST(fn.play.name)) {
if (luaScriptsCount < MAX_SCRIPTS) {
@@ -1900,7 +1900,7 @@ void luaDoOneRunPermanentScript(uint8_t evt, int i)
}
}
else if (sid.reference >= SCRIPT_FUNC_FIRST && sid.reference <= SCRIPT_FUNC_LAST) {
CustomFnData & fn = g_model.funcSw[sid.reference-SCRIPT_FUNC_FIRST];
CustomFunctionData & fn = g_model.customFn[sid.reference-SCRIPT_FUNC_FIRST];
if (!getSwitch(fn.swtch)) {
return;
}
+6
View File
@@ -1027,7 +1027,13 @@ void evalMixes(uint8_t tick10ms)
#if defined(CPUARM)
requiredSpeakerVolume = g_eeGeneral.speakerVolume + VOLUME_LEVEL_DEF;
#endif
#if defined(CPUARM)
evalFunctions(g_eeGeneral.customFn, globalFunctionsContext);
evalFunctions(g_model.customFn, modelFunctionsContext);
#else
evalFunctions();
#endif
}
//========== LIMITS ===============
+189 -185
View File
@@ -406,6 +406,192 @@ PACK(typedef struct {
int16_t spanPos;
}) CalibData;
enum Functions {
// first the functions which need a checkbox
FUNC_OVERRIDE_CHANNEL,
FUNC_TRAINER,
FUNC_INSTANT_TRIM,
FUNC_RESET,
#if defined(CPUARM)
FUNC_SET_TIMER,
#endif
FUNC_ADJUST_GVAR,
#if defined(CPUARM)
FUNC_VOLUME,
FUNC_RESERVE1,
FUNC_RESERVE2,
FUNC_RESERVE3,
#endif
// then the other functions
FUNC_FIRST_WITHOUT_ENABLE,
FUNC_PLAY_SOUND = FUNC_FIRST_WITHOUT_ENABLE,
FUNC_PLAY_TRACK,
#if !defined(CPUARM)
FUNC_PLAY_BOTH,
#endif
FUNC_PLAY_VALUE,
#if defined(CPUARM)
FUNC_PLAY_DIFF,
FUNC_PLAY_SCRIPT,
FUNC_RESERVE5,
FUNC_BACKGND_MUSIC,
FUNC_BACKGND_MUSIC_PAUSE,
#endif
FUNC_VARIO,
FUNC_HAPTIC,
#if !defined(PCBSTD)
FUNC_LOGS,
#endif
FUNC_BACKLIGHT,
#if defined(DEBUG)
FUNC_TEST, // should remain the last before MAX as not added in companion9x
#endif
FUNC_MAX
};
#if defined(OVERRIDE_CHANNEL_FUNCTION)
#define HAS_ENABLE_PARAM(func) ((func) < FUNC_FIRST_WITHOUT_ENABLE)
#else
#define HAS_ENABLE_PARAM(func) ((func) < FUNC_FIRST_WITHOUT_ENABLE && (func) != FUNC_OVERRIDE_CHANNEL)
#endif
#if defined(VOICE)
#define IS_PLAY_FUNC(func) ((func) >= FUNC_PLAY_SOUND && func <= FUNC_PLAY_VALUE)
#else
#define IS_PLAY_FUNC(func) ((func) == FUNC_PLAY_SOUND)
#endif
#if defined(CPUARM)
#define IS_PLAY_BOTH_FUNC(func) (0)
#define IS_VOLUME_FUNC(func) ((func) == FUNC_VOLUME)
#else
#define IS_PLAY_BOTH_FUNC(func) ((func) == FUNC_PLAY_BOTH)
#define IS_VOLUME_FUNC(func) (0)
#endif
#if defined(GVARS)
#define IS_ADJUST_GV_FUNC(func) ((func) == FUNC_ADJUST_GVAR)
#else
#define IS_ADJUST_GV_FUNC(func) (0)
#endif
#if defined(HAPTIC)
#define IS_HAPTIC_FUNC(func) ((func) == FUNC_HAPTIC)
#else
#define IS_HAPTIC_FUNC(func) (0)
#endif
#define HAS_REPEAT_PARAM(func) (IS_PLAY_FUNC(func) || IS_HAPTIC_FUNC(func))
enum ResetFunctionParam {
FUNC_RESET_TIMER1,
FUNC_RESET_TIMER2,
#if defined(CPUARM)
FUNC_RESET_TIMER3,
#endif
FUNC_RESET_FLIGHT,
#if defined(FRSKY)
FUNC_RESET_TELEMETRY,
#endif
#if ROTARY_ENCODERS > 0
FUNC_RESET_ROTENC1,
#endif
#if ROTARY_ENCODERS > 1
FUNC_RESET_ROTENC2,
#endif
FUNC_RESET_PARAMS_COUNT,
FUNC_RESET_PARAM_LAST = FUNC_RESET_PARAMS_COUNT-1
};
enum AdjustGvarFunctionParam {
FUNC_ADJUST_GVAR_CONSTANT,
FUNC_ADJUST_GVAR_SOURCE,
FUNC_ADJUST_GVAR_GVAR,
FUNC_ADJUST_GVAR_INC,
};
#if defined(CPUARM)
#if defined(PCBTARANIS)
#define LEN_CFN_NAME 8
#define CFN_SPARE_TYPE int32_t
#else
#define LEN_CFN_NAME 6
#define CFN_SPARE_TYPE int16_t
#endif
PACK(typedef struct t_CustomFunctionData { // Function Switches data
int8_t swtch;
uint8_t func;
PACK(union {
PACK(struct {
char name[LEN_CFN_NAME];
}) play;
PACK(struct {
int16_t val;
uint8_t mode;
uint8_t param;
CFN_SPARE_TYPE spare2;
}) all;
PACK(struct {
int32_t val1;
CFN_SPARE_TYPE val2;
}) clear;
});
uint8_t active;
}) CustomFunctionData;
#define CFN_EMPTY(p) (!(p)->swtch)
#define CFN_SWITCH(p) ((p)->swtch)
#define CFN_FUNC(p) ((p)->func)
#define CFN_ACTIVE(p) ((p)->active)
#define CFN_CH_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)->active)
#define CFN_PLAY_REPEAT_MUL 1
#define CFN_PLAY_REPEAT_NOSTART 0xFF
#define CFN_GVAR_MODE(p) ((p)->all.mode)
#define CFN_PARAM(p) ((p)->all.val)
#define CFN_RESET(p) ((p)->active=0, (p)->clear.val1=0, (p)->clear.val2=0)
#define CFN_GVAR_CST_MAX GVAR_LIMIT
#else
PACK(typedef struct t_CustomFunctionData {
PACK(union {
PACK(struct {
int16_t swtch:6;
uint16_t func:4;
uint16_t mode:2;
uint16_t param:3;
uint16_t active:1;
}) gvar;
PACK(struct {
int16_t swtch:6;
uint16_t func:4;
uint16_t param:4;
uint16_t spare:1;
uint16_t active:1;
}) all;
});
uint8_t value;
}) CustomFunctionData;
#define CFN_SWITCH(p) ((p)->all.swtch)
#define CFN_FUNC(p) ((p)->all.func)
#define CFN_ACTIVE(p) ((p)->all.active)
#define CFN_CH_INDEX(p) ((p)->all.param)
#define CFN_TIMER_INDEX(p) ((p)->all.param)
#define CFN_GVAR_INDEX(p) ((p)->gvar.param)
#define CFN_PLAY_REPEAT(p) ((p)->all.param)
#define CFN_PLAY_REPEAT_MUL 10
#define CFN_GVAR_MODE(p) ((p)->gvar.mode)
#define CFN_PARAM(p) ((p)->value)
#define CFN_RESET(p) ((p)->all.active = 0, CFN_PARAM(p) = 0)
#define CFN_GVAR_CST_MAX 125
#endif
#if defined(PCBSTD)
#define N_PCBSTD_FIELD(x)
#else
@@ -466,6 +652,8 @@ PACK(typedef struct t_EEGeneral {
swstate_t switchUnlockStates;
ARM_FIELD(CustomFunctionData customFn[NUM_CFN])
}) EEGeneral;
#define SWITCHES_DELAY() uint8_t(15+g_eeGeneral.switchesDelay)
@@ -819,190 +1007,6 @@ PACK(typedef struct t_LogicalSwitchData { // Logical Switches data
}) LogicalSwitchData;
#endif
enum Functions {
// first the functions which need a checkbox
FUNC_OVERRIDE_CHANNEL,
FUNC_TRAINER,
FUNC_INSTANT_TRIM,
FUNC_RESET,
#if defined(CPUARM)
FUNC_SET_TIMER,
#endif
FUNC_ADJUST_GVAR,
#if defined(CPUARM)
FUNC_VOLUME,
FUNC_RESERVE1,
FUNC_RESERVE2,
FUNC_RESERVE3,
#endif
// then the other functions
FUNC_FIRST_WITHOUT_ENABLE,
FUNC_PLAY_SOUND = FUNC_FIRST_WITHOUT_ENABLE,
FUNC_PLAY_TRACK,
#if !defined(CPUARM)
FUNC_PLAY_BOTH,
#endif
FUNC_PLAY_VALUE,
#if defined(CPUARM)
FUNC_PLAY_DIFF,
FUNC_PLAY_SCRIPT,
FUNC_RESERVE5,
FUNC_BACKGND_MUSIC,
FUNC_BACKGND_MUSIC_PAUSE,
#endif
FUNC_VARIO,
FUNC_HAPTIC,
#if !defined(PCBSTD)
FUNC_LOGS,
#endif
FUNC_BACKLIGHT,
#if defined(DEBUG)
FUNC_TEST, // should remain the last before MAX as not added in companion9x
#endif
FUNC_MAX
};
#if defined(OVERRIDE_CHANNEL_FUNCTION)
#define HAS_ENABLE_PARAM(func) ((func) < FUNC_FIRST_WITHOUT_ENABLE)
#else
#define HAS_ENABLE_PARAM(func) ((func) < FUNC_FIRST_WITHOUT_ENABLE && (func) != FUNC_OVERRIDE_CHANNEL)
#endif
#if defined(VOICE)
#define IS_PLAY_FUNC(func) ((func) >= FUNC_PLAY_SOUND && func <= FUNC_PLAY_VALUE)
#else
#define IS_PLAY_FUNC(func) ((func) == FUNC_PLAY_SOUND)
#endif
#if defined(CPUARM)
#define IS_PLAY_BOTH_FUNC(func) (0)
#define IS_VOLUME_FUNC(func) ((func) == FUNC_VOLUME)
#else
#define IS_PLAY_BOTH_FUNC(func) ((func) == FUNC_PLAY_BOTH)
#define IS_VOLUME_FUNC(func) (0)
#endif
#if defined(GVARS)
#define IS_ADJUST_GV_FUNC(func) ((func) == FUNC_ADJUST_GVAR)
#else
#define IS_ADJUST_GV_FUNC(func) (0)
#endif
#if defined(HAPTIC)
#define IS_HAPTIC_FUNC(func) ((func) == FUNC_HAPTIC)
#else
#define IS_HAPTIC_FUNC(func) (0)
#endif
#define HAS_REPEAT_PARAM(func) (IS_PLAY_FUNC(func) || IS_HAPTIC_FUNC(func))
enum ResetFunctionParam {
FUNC_RESET_TIMER1,
FUNC_RESET_TIMER2,
#if defined(CPUARM)
FUNC_RESET_TIMER3,
#endif
FUNC_RESET_FLIGHT,
#if defined(FRSKY)
FUNC_RESET_TELEMETRY,
#endif
#if ROTARY_ENCODERS > 0
FUNC_RESET_ROTENC1,
#endif
#if ROTARY_ENCODERS > 1
FUNC_RESET_ROTENC2,
#endif
FUNC_RESET_PARAMS_COUNT,
FUNC_RESET_PARAM_LAST = FUNC_RESET_PARAMS_COUNT-1
};
enum AdjustGvarFunctionParam {
FUNC_ADJUST_GVAR_CONSTANT,
FUNC_ADJUST_GVAR_SOURCE,
FUNC_ADJUST_GVAR_GVAR,
FUNC_ADJUST_GVAR_INC,
};
#if defined(CPUARM)
#if defined(PCBTARANIS)
#define LEN_CFN_NAME 8
#define CFN_SPARE_TYPE int32_t
#else
#define LEN_CFN_NAME 6
#define CFN_SPARE_TYPE int16_t
#endif
PACK(typedef struct t_CustomFnData { // Function Switches data
int8_t swtch;
uint8_t func;
PACK(union {
PACK(struct {
char name[LEN_CFN_NAME];
}) play;
PACK(struct {
int16_t val;
uint8_t mode;
uint8_t param;
CFN_SPARE_TYPE spare2;
}) all;
PACK(struct {
int32_t val1;
CFN_SPARE_TYPE val2;
}) clear;
});
uint8_t active;
}) CustomFnData;
#define CFN_EMPTY(p) (!(p)->swtch)
#define CFN_SWITCH(p) ((p)->swtch)
#define CFN_FUNC(p) ((p)->func)
#define CFN_ACTIVE(p) ((p)->active)
#define CFN_CH_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)->active)
#define CFN_PLAY_REPEAT_MUL 1
#define CFN_PLAY_REPEAT_NOSTART 0xFF
#define CFN_GVAR_MODE(p) ((p)->all.mode)
#define CFN_PARAM(p) ((p)->all.val)
#define CFN_RESET(p) ((p)->active=0, (p)->clear.val1=0, (p)->clear.val2=0)
#define CFN_GVAR_CST_MAX GVAR_LIMIT
#else
PACK(typedef struct t_CustomFnData {
PACK(union {
PACK(struct {
int16_t swtch:6;
uint16_t func:4;
uint16_t mode:2;
uint16_t param:3;
uint16_t active:1;
}) gvar;
PACK(struct {
int16_t swtch:6;
uint16_t func:4;
uint16_t param:4;
uint16_t spare:1;
uint16_t active:1;
}) all;
});
uint8_t value;
}) CustomFnData;
#define CFN_SWITCH(p) ((p)->all.swtch)
#define CFN_FUNC(p) ((p)->all.func)
#define CFN_ACTIVE(p) ((p)->all.active)
#define CFN_CH_INDEX(p) ((p)->all.param)
#define CFN_TIMER_INDEX(p) ((p)->all.param)
#define CFN_GVAR_INDEX(p) ((p)->gvar.param)
#define CFN_PLAY_REPEAT(p) ((p)->all.param)
#define CFN_PLAY_REPEAT_MUL 10
#define CFN_GVAR_MODE(p) ((p)->gvar.mode)
#define CFN_PARAM(p) ((p)->value)
#define CFN_RESET(p) ((p)->all.active = 0, CFN_PARAM(p) = 0)
#define CFN_GVAR_CST_MAX 125
#endif
enum TelemetryUnit {
UNIT_VOLTS,
UNIT_AMPS,
@@ -1832,7 +1836,7 @@ PACK(typedef struct {
int8_t points[NUM_POINTS];
LogicalSwitchData logicalSw[NUM_LOGICAL_SWITCH];
CustomFnData funcSw[NUM_CFN];
CustomFunctionData customFn[NUM_CFN];
SwashRingData swashR;
FlightModeData flightModeData[MAX_FLIGHT_MODES];
-487
View File
@@ -1666,503 +1666,16 @@ FORCEINLINE void evalTrims()
}
}
#if defined(DEBUG)
/*
* This is a test function for debugging purpose, you may insert there your code and compile with the option DEBUG=YES
*/
void testFunc()
{
#ifdef SIMU
printf("testFunc\n"); fflush(stdout);
#endif
}
#endif
MASK_FUNC_TYPE activeFunctions = 0;
MASK_CFN_TYPE activeFnSwitches = 0;
tmr10ms_t lastFunctionTime[NUM_CFN] = { 0 };
#if defined(VOICE)
PLAY_FUNCTION(playValue, uint8_t idx)
{
if (IS_FAI_FORBIDDEN(idx))
return;
getvalue_t val = getValue(idx);
switch (idx) {
#if defined(CPUARM)
case MIXSRC_FIRST_TELEM+TELEM_TX_TIME-1:
PLAY_DURATION(val*60, PLAY_TIME);
break;
#endif
case MIXSRC_FIRST_TELEM+TELEM_TX_VOLTAGE-1:
PLAY_NUMBER(val, 1+UNIT_VOLTS, PREC1);
break;
case MIXSRC_FIRST_TELEM+TELEM_TIMER1-1:
case MIXSRC_FIRST_TELEM+TELEM_TIMER2-1:
#if defined(CPUARM)
case MIXSRC_FIRST_TELEM+TELEM_TIMER3-1:
#endif
PLAY_DURATION(val, 0);
break;
#if defined(CPUARM) && defined(FRSKY)
case MIXSRC_FIRST_TELEM+TELEM_SWR-1:
PLAY_NUMBER(val, 0, 0);
break;
#endif
#if defined(FRSKY)
case MIXSRC_FIRST_TELEM+TELEM_RSSI_TX-1:
case MIXSRC_FIRST_TELEM+TELEM_RSSI_RX-1:
PLAY_NUMBER(val, 1+UNIT_DBM, 0);
break;
case MIXSRC_FIRST_TELEM+TELEM_MIN_A1-1:
case MIXSRC_FIRST_TELEM+TELEM_MIN_A2-1:
#if defined(CPUARM)
case MIXSRC_FIRST_TELEM+TELEM_MIN_A3-1:
case MIXSRC_FIRST_TELEM+TELEM_MIN_A4-1:
#endif
idx -= TELEM_MIN_A1-TELEM_A1;
// no break
case MIXSRC_FIRST_TELEM+TELEM_A1-1:
case MIXSRC_FIRST_TELEM+TELEM_A2-1:
#if defined(CPUARM)
case MIXSRC_FIRST_TELEM+TELEM_A3-1:
case MIXSRC_FIRST_TELEM+TELEM_A4-1:
#endif
if (TELEMETRY_STREAMING()) {
idx -= (MIXSRC_FIRST_TELEM+TELEM_A1-1);
uint8_t att = 0;
int16_t converted_value = div10_and_round(applyChannelRatio(idx, val));;
if (ANA_CHANNEL_UNIT(idx) < UNIT_RAW) {
att = PREC1;
}
PLAY_NUMBER(converted_value, 1+ANA_CHANNEL_UNIT(idx), att);
}
break;
case MIXSRC_FIRST_TELEM+TELEM_CELL-1:
case MIXSRC_FIRST_TELEM+TELEM_MIN_CELL-1:
PLAY_NUMBER(div10_and_round(val), 1+UNIT_VOLTS, PREC1);
break;
case MIXSRC_FIRST_TELEM+TELEM_VFAS-1:
case MIXSRC_FIRST_TELEM+TELEM_CELLS_SUM-1:
case MIXSRC_FIRST_TELEM+TELEM_MIN_CELLS_SUM-1:
case MIXSRC_FIRST_TELEM+TELEM_MIN_VFAS-1:
PLAY_NUMBER(val, 1+UNIT_VOLTS, PREC1);
break;
case MIXSRC_FIRST_TELEM+TELEM_CURRENT-1:
case MIXSRC_FIRST_TELEM+TELEM_MAX_CURRENT-1:
PLAY_NUMBER(val, 1+UNIT_AMPS, PREC1);
break;
case MIXSRC_FIRST_TELEM+TELEM_ACCx-1:
case MIXSRC_FIRST_TELEM+TELEM_ACCy-1:
case MIXSRC_FIRST_TELEM+TELEM_ACCz-1:
PLAY_NUMBER(div10_and_round(val), 1+UNIT_G, PREC1);
break;
case MIXSRC_FIRST_TELEM+TELEM_VSPEED-1:
PLAY_NUMBER(div10_and_round(val), 1+UNIT_METERS_PER_SECOND, PREC1);
break;
case MIXSRC_FIRST_TELEM+TELEM_ASPEED-1:
case MIXSRC_FIRST_TELEM+TELEM_MAX_ASPEED-1:
PLAY_NUMBER(val/10, 1+UNIT_KTS, 0);
break;
case MIXSRC_FIRST_TELEM+TELEM_CONSUMPTION-1:
PLAY_NUMBER(val, 1+UNIT_MAH, 0);
break;
case MIXSRC_FIRST_TELEM+TELEM_POWER-1:
PLAY_NUMBER(val, 1+UNIT_WATTS, 0);
break;
case MIXSRC_FIRST_TELEM+TELEM_ALT-1:
#if defined(PCBTARANIS)
PLAY_NUMBER(div10_and_round(val), 1+UNIT_DIST, PREC1);
break;
#endif
case MIXSRC_FIRST_TELEM+TELEM_MIN_ALT-1:
case MIXSRC_FIRST_TELEM+TELEM_MAX_ALT-1:
#if defined(WS_HOW_HIGH)
if (IS_IMPERIAL_ENABLE() && IS_USR_PROTO_WS_HOW_HIGH())
PLAY_NUMBER(val, 1+UNIT_FEET, 0);
else
#endif
PLAY_NUMBER(val, 1+UNIT_DIST, 0);
break;
case MIXSRC_FIRST_TELEM+TELEM_RPM-1:
case MIXSRC_FIRST_TELEM+TELEM_MAX_RPM-1:
{
getvalue_t rpm = val;
if (rpm > 100)
rpm = 10 * div10_and_round(rpm);
if (rpm > 1000)
rpm = 10 * div10_and_round(rpm);
PLAY_NUMBER(rpm, 1+UNIT_RPMS, 0);
break;
}
case MIXSRC_FIRST_TELEM+TELEM_HDG-1:
PLAY_NUMBER(val, 1+UNIT_HDG, 0);
break;
default:
{
uint8_t unit = 1;
if (idx < MIXSRC_GVAR1)
val = calcRESXto100(val);
if (idx >= MIXSRC_FIRST_TELEM+TELEM_ALT-1 && idx <= MIXSRC_FIRST_TELEM+TELEM_GPSALT-1)
unit = idx - (MIXSRC_FIRST_TELEM+TELEM_ALT-1);
else if (idx >= MIXSRC_FIRST_TELEM+TELEM_MAX_T1-1 && idx <= MIXSRC_FIRST_TELEM+TELEM_MAX_DIST-1)
unit = 3 + idx - (MIXSRC_FIRST_TELEM+TELEM_MAX_T1-1);
unit = pgm_read_byte(bchunit_ar+unit);
PLAY_NUMBER(val, unit == UNIT_RAW ? 0 : unit+1, 0);
break;
}
#else
default:
{
PLAY_NUMBER(val, 0, 0);
break;
}
#endif
}
}
#endif
#if !defined(PCBSTD)
uint8_t mSwitchDuration[1+NUM_ROTARY_ENCODERS] = { 0 };
#define CFN_PRESSLONG_DURATION 100
#endif
#if defined(CPUARM)
#define VOLUME_HYSTERESIS 10 // how much must a input value change to actually be considered for new volume setting
uint8_t currentSpeakerVolume = 255;
uint8_t requiredSpeakerVolume;
getvalue_t requiredSpeakerVolumeRawLast = 1024 + 1; //initial value must be outside normal range
inline void playCustomFunctionFile(CustomFnData *sd, uint8_t id)
{
if (sd->play.name[0] != '\0') {
char filename[sizeof(SOUNDS_PATH)+sizeof(sd->play.name)+sizeof(SOUNDS_EXT)] = SOUNDS_PATH "/";
strncpy(filename+SOUNDS_PATH_LNG_OFS, currentLanguagePack->id, 2);
strncpy(filename+sizeof(SOUNDS_PATH), sd->play.name, sizeof(sd->play.name));
filename[sizeof(SOUNDS_PATH)+sizeof(sd->play.name)] = '\0';
strcat(filename+sizeof(SOUNDS_PATH), SOUNDS_EXT);
PLAY_FILE(filename, sd->func==FUNC_BACKGND_MUSIC ? PLAY_BACKGROUND : 0, id);
}
}
#endif
void evalFunctions()
{
MASK_FUNC_TYPE newActiveFunctions = 0;
MASK_CFN_TYPE newActiveFnSwitches = 0;
#if defined(ROTARY_ENCODERS) && defined(GVARS)
static rotenc_t rePreviousValues[ROTARY_ENCODERS];
#endif
#if defined(OVERRIDE_CHANNEL_FUNCTION)
for (uint8_t i=0; i<NUM_CHNOUT; i++) {
safetyCh[i] = OVERRIDE_CHANNEL_UNDEFINED;
}
#endif
#if defined(GVARS)
for (uint8_t i=0; i<NUM_STICKS; i++) {
trimGvar[i] = -1;
}
#endif
for (uint8_t i=0; i<NUM_CFN; i++) {
CustomFnData *sd = &g_model.funcSw[i];
int8_t swtch = CFN_SWITCH(sd);
if (swtch) {
MASK_CFN_TYPE switch_mask = ((MASK_CFN_TYPE)1 << i);
#if defined(CPUARM)
bool active = getSwitch(swtch, IS_PLAY_FUNC(CFN_FUNC(sd)) ? GETSWITCH_MIDPOS_DELAY : 0);
#else
bool active = getSwitch(swtch);
#endif
if (HAS_ENABLE_PARAM(CFN_FUNC(sd))) {
active &= (bool)CFN_ACTIVE(sd);
}
if (active || IS_PLAY_BOTH_FUNC(CFN_FUNC(sd))) {
switch (CFN_FUNC(sd)) {
#if defined(OVERRIDE_CHANNEL_FUNCTION)
case FUNC_OVERRIDE_CHANNEL:
safetyCh[CFN_CH_INDEX(sd)] = CFN_PARAM(sd);
break;
#endif
case FUNC_TRAINER:
{
uint8_t mask = 0x0f;
if (CFN_CH_INDEX(sd) > 0) {
mask = (1<<(CFN_CH_INDEX(sd)-1));
}
newActiveFunctions |= mask;
break;
}
case FUNC_INSTANT_TRIM:
newActiveFunctions |= (1 << FUNCTION_INSTANT_TRIM);
if (!isFunctionActive(FUNCTION_INSTANT_TRIM)) {
if (g_menuStack[0] == menuMainView
#if defined(FRSKY)
|| g_menuStack[0] == menuTelemetryFrsky
#endif
#if defined(PCBTARANIS)
|| g_menuStack[0] == menuMainViewChannelsMonitor
|| g_menuStack[0] == menuChannelsView
#endif
) {
instantTrim();
}
}
break;
case FUNC_RESET:
switch (CFN_PARAM(sd)) {
case FUNC_RESET_TIMER1:
case FUNC_RESET_TIMER2:
#if defined(CPUARM)
case FUNC_RESET_TIMER3:
#endif
timerReset(CFN_PARAM(sd));
break;
case FUNC_RESET_FLIGHT:
flightReset();
break;
#if defined(FRSKY)
case FUNC_RESET_TELEMETRY:
telemetryReset();
break;
#endif
#if ROTARY_ENCODERS > 0
case FUNC_RESET_ROTENC1:
#if ROTARY_ENCODERS > 1
case FUNC_RESET_ROTENC2:
#endif
g_rotenc[CFN_PARAM(sd)-FUNC_RESET_ROTENC1] = 0;
break;
#endif
}
break;
#if defined(CPUARM)
case FUNC_SET_TIMER:
{
TimerState & timerState = timersStates[CFN_TIMER_INDEX(sd)];
timerState.state = TMR_OFF; // is changed to RUNNING dep from mode
timerState.val = CFN_PARAM(sd);
timerState.val_10ms = 0 ;
break;
}
#endif
#if defined(GVARS)
case FUNC_ADJUST_GVAR:
if (CFN_GVAR_MODE(sd) == 0) {
SET_GVAR(CFN_GVAR_INDEX(sd), CFN_PARAM(sd), mixerCurrentFlightMode);
}
else if (CFN_GVAR_MODE(sd) == 2) {
SET_GVAR(CFN_GVAR_INDEX(sd), GVAR_VALUE(CFN_PARAM(sd), mixerCurrentFlightMode), mixerCurrentFlightMode);
}
else if (CFN_GVAR_MODE(sd) == 3) {
if (!(activeFnSwitches & switch_mask)) {
SET_GVAR(CFN_GVAR_INDEX(sd), GVAR_VALUE(CFN_GVAR_INDEX(sd), getGVarFlightPhase(mixerCurrentFlightMode, CFN_GVAR_INDEX(sd))) + (CFN_PARAM(sd) ? +1 : -1), mixerCurrentFlightMode);
}
}
else if (CFN_PARAM(sd) >= MIXSRC_TrimRud && CFN_PARAM(sd) <= MIXSRC_TrimAil) {
trimGvar[CFN_PARAM(sd)-MIXSRC_TrimRud] = CFN_GVAR_INDEX(sd);
}
#if defined(ROTARY_ENCODERS)
else if (CFN_PARAM(sd) >= MIXSRC_REa && CFN_PARAM(sd) < MIXSRC_TrimRud) {
int8_t scroll = rePreviousValues[CFN_PARAM(sd)-MIXSRC_REa] - (g_rotenc[CFN_PARAM(sd)-MIXSRC_REa] / ROTARY_ENCODER_GRANULARITY);
if (scroll) {
SET_GVAR(CFN_GVAR_INDEX(sd), GVAR_VALUE(CFN_GVAR_INDEX(sd), getGVarFlightPhase(mixerCurrentFlightMode, CFN_GVAR_INDEX(sd))) + scroll, mixerCurrentFlightMode);
}
}
#endif
else {
SET_GVAR(CFN_GVAR_INDEX(sd), calcRESXto100(getValue(CFN_PARAM(sd))), mixerCurrentFlightMode);
}
break;
#endif
#if defined(CPUARM) && defined(SDCARD)
case FUNC_VOLUME:
{
getvalue_t raw = getValue(CFN_PARAM(sd));
//only set volume if input changed more than hysteresis
if (abs(requiredSpeakerVolumeRawLast - raw) > VOLUME_HYSTERESIS) {
requiredSpeakerVolumeRawLast = raw;
}
requiredSpeakerVolume = ((1024 + requiredSpeakerVolumeRawLast) * VOLUME_LEVEL_MAX) / 2048;
break;
}
#endif
#if defined(CPUARM) && defined(SDCARD)
case FUNC_PLAY_SOUND:
case FUNC_PLAY_TRACK:
case FUNC_PLAY_VALUE:
#if defined(HAPTIC)
case FUNC_HAPTIC:
#endif
{
tmr10ms_t tmr10ms = get_tmr10ms();
uint8_t repeatParam = CFN_PLAY_REPEAT(sd);
if (!IS_SILENCE_PERIOD_ELAPSED() && repeatParam == CFN_PLAY_REPEAT_NOSTART)
lastFunctionTime[i] = tmr10ms;
if (!lastFunctionTime[i] || (repeatParam && repeatParam!=CFN_PLAY_REPEAT_NOSTART && (signed)(tmr10ms-lastFunctionTime[i])>=100*repeatParam)) {
if (!IS_PLAYING(i+1)) {
lastFunctionTime[i] = tmr10ms;
if (CFN_FUNC(sd) == FUNC_PLAY_SOUND) {
AUDIO_PLAY(AU_FRSKY_FIRST+CFN_PARAM(sd));
}
else if (CFN_FUNC(sd) == FUNC_PLAY_VALUE) {
PLAY_VALUE(CFN_PARAM(sd), i+1);
}
#if defined(HAPTIC)
else if (CFN_FUNC(sd) == FUNC_HAPTIC) {
haptic.event(AU_FRSKY_LAST+CFN_PARAM(sd));
}
#endif
else {
playCustomFunctionFile(sd, i+1);
}
}
}
break;
}
case FUNC_BACKGND_MUSIC:
newActiveFunctions |= (1 << FUNCTION_BACKGND_MUSIC);
if (!IS_PLAYING(i+1)) {
playCustomFunctionFile(sd, i+1);
}
break;
case FUNC_BACKGND_MUSIC_PAUSE:
newActiveFunctions |= (1 << FUNCTION_BACKGND_MUSIC_PAUSE);
break;
#elif defined(VOICE)
case FUNC_PLAY_SOUND:
case FUNC_PLAY_TRACK:
case FUNC_PLAY_BOTH:
case FUNC_PLAY_VALUE:
{
tmr10ms_t tmr10ms = get_tmr10ms();
uint8_t repeatParam = CFN_PLAY_REPEAT(sd);
if (!lastFunctionTime[i] || (CFN_FUNC(sd)==FUNC_PLAY_BOTH && active!=(bool)(activeFnSwitches&switch_mask)) || (repeatParam && (signed)(tmr10ms-lastFunctionTime[i])>=1000*repeatParam)) {
lastFunctionTime[i] = tmr10ms;
uint8_t param = CFN_PARAM(sd);
if (CFN_FUNC(sd) == FUNC_PLAY_SOUND) {
AUDIO_PLAY(AU_FRSKY_FIRST+param);
}
else if (CFN_FUNC(sd) == FUNC_PLAY_VALUE) {
PLAY_VALUE(param, i+1);
}
else {
#if defined(GVARS)
if (CFN_FUNC(sd) == FUNC_PLAY_TRACK && param > 250)
param = GVAR_VALUE(param-251, getGVarFlightPhase(mixerCurrentFlightMode, param-251));
#endif
PUSH_CUSTOM_PROMPT(active ? param : param+1, i+1);
}
}
if (!active) {
// PLAY_BOTH would change activeFnSwitches otherwise
switch_mask = 0;
}
break;
}
#else
case FUNC_PLAY_SOUND:
{
tmr10ms_t tmr10ms = get_tmr10ms();
uint8_t repeatParam = CFN_PLAY_REPEAT(sd);
if (!lastFunctionTime[i] || (repeatParam && (signed)(tmr10ms-lastFunctionTime[i])>=1000*repeatParam)) {
lastFunctionTime[i] = tmr10ms;
AUDIO_PLAY(AU_FRSKY_FIRST+CFN_PARAM(sd));
}
break;
}
#endif
#if defined(FRSKY) && defined(VARIO)
case FUNC_VARIO:
newActiveFunctions |= (1 << FUNCTION_VARIO);
break;
#endif
#if defined(HAPTIC) && !defined(CPUARM)
case FUNC_HAPTIC:
{
tmr10ms_t tmr10ms = get_tmr10ms();
uint8_t repeatParam = CFN_PLAY_REPEAT(sd);
if (!lastFunctionTime[i] || (repeatParam && (signed)(tmr10ms-lastFunctionTime[i])>=1000*repeatParam)) {
lastFunctionTime[i] = tmr10ms;
haptic.event(AU_FRSKY_LAST+CFN_PARAM(sd));
}
break;
}
#endif
#if defined(SDCARD)
case FUNC_LOGS:
if (CFN_PARAM(sd)) {
newActiveFunctions |= (1 << FUNCTION_LOGS);
logDelay = CFN_PARAM(sd);
}
break;
#endif
case FUNC_BACKLIGHT:
newActiveFunctions |= (1 << FUNCTION_BACKLIGHT);
break;
#if defined(DEBUG)
case FUNC_TEST:
testFunc();
break;
#endif
}
newActiveFnSwitches |= switch_mask;
}
else {
lastFunctionTime[i] = 0;
}
}
}
activeFnSwitches = newActiveFnSwitches;
activeFunctions = newActiveFunctions;
#if defined(ROTARY_ENCODERS) && defined(GVARS)
for (uint8_t i=0; i<ROTARY_ENCODERS; i++) {
rePreviousValues[i] = (g_rotenc[i] / ROTARY_ENCODER_GRANULARITY);
}
#endif
}
uint8_t s_mixer_first_run_done = false;
void doMixerCalculations()
+35 -9
View File
@@ -527,7 +527,6 @@ enum PotType {
#endif
#include "lcd.h"
#include "gui/menus.h"
#if defined(TEMPLATES)
#include "templates.h"
@@ -1218,14 +1217,12 @@ void copyTrimsToOffset(uint8_t ch);
void copySticksToOffset(uint8_t ch);
void moveTrimsToOffsets();
void evalFunctions();
#if defined(CPUARM)
#define ACTIVE_PHASES_TYPE uint16_t
#define DELAY_POS_SHIFT 0
#define DELAY_POS_MARGIN 3
#define delayval_t int16_t
PACK(typedef struct t_SwOn {
PACK(typedef struct {
uint16_t delay;
int16_t now; // timer trigger source -> off, abs, stk, stk%, sw/!sw, !m_sw/!m_sw
int16_t prev;
@@ -1237,7 +1234,7 @@ PACK(typedef struct t_SwOn {
#define DELAY_POS_SHIFT 10
#define DELAY_POS_MARGIN 0
#define delayval_t int8_t
PACK(typedef struct t_SwOn {
PACK(typedef struct {
uint16_t delay:10;
int16_t now:2; // timer trigger source -> off, abs, stk, stk%, sw/!sw, !m_sw/!m_sw
int16_t prev:2;
@@ -1308,14 +1305,41 @@ enum FunctionsActive {
#define VARIO_REPEAT_ZERO 500/*ms*/
#define VARIO_REPEAT_MAX 80/*ms*/
extern MASK_FUNC_TYPE activeFunctions;
extern MASK_CFN_TYPE activeFnSwitches;
extern tmr10ms_t lastFunctionTime[NUM_CFN];
typedef struct {
MASK_FUNC_TYPE activeFunctions;
MASK_CFN_TYPE activeSwitches;
tmr10ms_t lastFunctionTime[NUM_CFN];
inline bool isFuunctionActive(uint8_t func)
{
return activeFunctions & ((MASK_FUNC_TYPE)1 << func);
}
void reset()
{
memclear(this, sizeof(*this));
}
} CustomFunctionsContext;
#if defined(CPUARM)
extern CustomFunctionsContext modelFunctionsContext;
extern CustomFunctionsContext globalFunctionsContext;
inline bool isFunctionActive(uint8_t func)
{
return activeFunctions & ((uint8_t)1 << func);
return globalFunctionsContext.isFuunctionActive(func) || modelFunctionsContext.isFuunctionActive(func);
}
void evalFunctions(const CustomFunctionData * functions, CustomFunctionsContext & functionsContext);
inline void customFunctionsReset()
{
globalFunctionsContext.reset();
modelFunctionsContext.reset();
}
#else
extern CustomFunctionsContext modelFunctionsContext;
#define isFunctionActive(func) modelFunctionsContext.isFuunctionActive(func)
void evalFunctions();
#define customFunctionsReset() modelFunctionsContext.reset()
#endif
#if defined(ROTARY_ENCODERS)
// Global rotary encoder registers
@@ -1324,6 +1348,8 @@ inline bool isFunctionActive(uint8_t func)
extern volatile rotenc_t g_rotenc[1];
#endif
#include "gui/menus.h"
#if defined (FRSKY)
// FrSky Telemetry
#include "telemetry/frsky.h"
+1
View File
@@ -295,6 +295,7 @@ const pm_char STR_MENUDATEANDTIME[] PROGMEM = TR_MENUDATEANDTIME;
#endif
const pm_char STR_MENUTRAINER[] PROGMEM = TR_MENUTRAINER;
const pm_char STR_MENUGLOBALFUNCS[] PROGMEM = TR_MENUGLOBALFUNCS;
const pm_char STR_MENUVERSION[] PROGMEM = TR_MENUVERSION;
const pm_char STR_MENUDIAG[] PROGMEM = TR_MENUDIAG;
const pm_char STR_MENUANA[] PROGMEM = TR_MENUANA;
+1
View File
@@ -456,6 +456,7 @@ extern const pm_char STR_TRIMS2OFFSETS[];
extern const pm_char STR_MENURADIOSETUP[];
extern const pm_char STR_MENUDATEANDTIME[];
extern const pm_char STR_MENUTRAINER[];
extern const pm_char STR_MENUGLOBALFUNCS[];
extern const pm_char STR_MENUVERSION[];
extern const pm_char STR_MENUDIAG[];
extern const pm_char STR_MENUANA[];
+1
View File
@@ -664,6 +664,7 @@
#define TR_MENURADIOSETUP "NASTAVENÍ RÁDIA"
#define TR_MENUDATEANDTIME "DATUM A čAS"
#define TR_MENUTRAINER "TRENÉR"
#define TR_MENUGLOBALFUNCS "GLOBAL FUNCTIONS"
#define TR_MENUVERSION "VERZE"
#define TR_MENUDIAG "DIAG"
#define TR_MENUANA "ANALOGY"
+1
View File
@@ -667,6 +667,7 @@
#define TR_MENURADIOSETUP TR("SENDER-EINSTELLEN","SENDER-GRUNDEINSTELLUNGEN")
#define TR_MENUDATEANDTIME "DATUM UND ZEIT"
#define TR_MENUTRAINER TR("LEHRER/SCHÜLER","LEHRER/SCHÜLER")
#define TR_MENUGLOBALFUNCS "GLOBAL FUNCTIONS"
#define TR_MENUVERSION "VERSION"
#define TR_MENUDIAG TR("Schalt.","Schalter-Test")
#define TR_MENUANA "Analog-Test"
+1
View File
@@ -671,6 +671,7 @@
#define TR_MENURADIOSETUP "RADIO SETUP"
#define TR_MENUDATEANDTIME "DATE AND TIME"
#define TR_MENUTRAINER "TRAINER"
#define TR_MENUGLOBALFUNCS "GLOBAL FUNCTIONS"
#define TR_MENUVERSION "VERSION"
#define TR_MENUDIAG TR("SWITCHES","SWITCH TEST")
#define TR_MENUANA TR("ANAS","ANALOG INPUTS")
+1
View File
@@ -660,6 +660,7 @@
#define TR_MENURADIOSETUP "CONFIGURACION"
#define TR_MENUDATEANDTIME "FECHA Y HORA"
#define TR_MENUTRAINER "APRENDIZ"
#define TR_MENUGLOBALFUNCS "GLOBAL FUNCTIONS"
#define TR_MENUVERSION "VERSION"
#define TR_MENUDIAG TR("INTERUPTS", "TEST INTERUP.")
#define TR_MENUANA TR("ANAS", "ENTRADAS ANALOG")
+1
View File
@@ -660,6 +660,7 @@
#define TR_MENURADIOSETUP "RADIO SETUP"
#define TR_MENUDATEANDTIME "DATE AND TIME"
#define TR_MENUTRAINER "TRAINER"
#define TR_MENUGLOBALFUNCS "GLOBAL FUNCTIONS"
#define TR_MENUVERSION "VERSION"
#define TR_MENUDIAG TR("SWITCHES","SWITCH TEST")
#define TR_MENUANA TR("ANAS","ANALOG INPUTS")
+1
View File
@@ -660,6 +660,7 @@
#define TR_MENURADIOSETUP "CONFIG RADIO"
#define TR_MENUDATEANDTIME "DATE ET HEURE"
#define TR_MENUTRAINER "ECOLAGE"
#define TR_MENUGLOBALFUNCS "GLOBAL FUNCTIONS"
#define TR_MENUVERSION "VERSION"
#define TR_MENUDIAG TR("INTERS","TEST INTERRUPTEURS")
#define TR_MENUANA TR("ANAS","ENTREES ANALOGIQUES")
+1
View File
@@ -660,6 +660,7 @@
#define TR_MENURADIOSETUP "CONFIGURATX"
#define TR_MENUDATEANDTIME "DATA E ORA"
#define TR_MENUTRAINER "MAESTRO/ALLIEVO"
#define TR_MENUGLOBALFUNCS "GLOBAL FUNCTIONS"
#define TR_MENUVERSION "VERSIONE"
#define TR_MENUDIAG "DIAG"
#define TR_MENUANA "ANAS"
+1
View File
@@ -660,6 +660,7 @@
#define TR_MENURADIOSETUP "USTAWIENIA RADIA"
#define TR_MENUDATEANDTIME "DATA I CZAS"
#define TR_MENUTRAINER "TRENER"
#define TR_MENUGLOBALFUNCS "GLOBAL FUNCTIONS"
#define TR_MENUVERSION "WERSJA"
#define TR_MENUDIAG TR("PRZEŁ","TEST PRZEŁ")
#define TR_MENUANA TR("WE-ANA","WEJŚCIA ANALOG.")
+1
View File
@@ -660,6 +660,7 @@
#define TR_MENURADIOSETUP "AJUSTAR RADIO"
#define TR_MENUDATEANDTIME "DATA E HORA"
#define TR_MENUTRAINER "TRAINER"
#define TR_MENUGLOBALFUNCS "GLOBAL FUNCTIONS"
#define TR_MENUVERSION "VERSAO"
#define TR_MENUDIAG "DIAGNOST"
#define TR_MENUANA "ANALOGICOS"
+1
View File
@@ -660,6 +660,7 @@
#define TR_MENURADIOSETUP "INSTÄLLNINGAR"
#define TR_MENUDATEANDTIME "DAG OCH TID"
#define TR_MENUTRAINER "TRAINER (PPM IN)"
#define TR_MENUGLOBALFUNCS "GLOBAL FUNCTIONS"
#define TR_MENUVERSION "VERSION"
#define TR_MENUDIAG TR("BRYTARE","TEST AV BRYTARE")
#define TR_MENUANA "ANALOGA VÄRDEN"