From 85f7a09b9cb14791ea16a3d44d727d4579fb3e12 Mon Sep 17 00:00:00 2001 From: Damjan Adamic Date: Tue, 18 Oct 2016 18:19:11 +0200 Subject: [PATCH] Fixes #3858: added edge detection to RESET and GVAR INC/DEC functions (#3921) * Fixes #3858: added edge detection to RESET and GVAR INC/DEC functions * Re #3858: Gtests added for Special Functions: FLIGHT_RESET and GVAR_INC * Re #3858: Gtests fixed * Re #3858: Gtests fixed 2 --- radio/src/functions.cpp | 57 +++++++-------- radio/src/tests/functions.cpp | 126 ++++++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+), 27 deletions(-) create mode 100644 radio/src/tests/functions.cpp diff --git a/radio/src/functions.cpp b/radio/src/functions.cpp index 151206996..32567e659 100644 --- a/radio/src/functions.cpp +++ b/radio/src/functions.cpp @@ -330,39 +330,42 @@ void evalFunctions() break; case FUNC_RESET: - switch (CFN_PARAM(cfn)) { - case FUNC_RESET_TIMER1: - case FUNC_RESET_TIMER2: + if (!(functionsContext.activeSwitches & switch_mask)) { + switch (CFN_PARAM(cfn)) { + case FUNC_RESET_TIMER1: + case FUNC_RESET_TIMER2: #if defined(CPUARM) - case FUNC_RESET_TIMER3: + case FUNC_RESET_TIMER3: #endif - timerReset(CFN_PARAM(cfn)); - break; - case FUNC_RESET_FLIGHT: - flightReset(); - break; + timerReset(CFN_PARAM(cfn)); + break; + case FUNC_RESET_FLIGHT: + flightReset(); + break; #if defined(TELEMETRY_FRSKY) - case FUNC_RESET_TELEMETRY: - telemetryReset(); - break; + case FUNC_RESET_TELEMETRY: + telemetryReset(); + break; #endif + #if ROTARY_ENCODERS > 0 - case FUNC_RESET_ROTENC1: + case FUNC_RESET_ROTENC1: #if ROTARY_ENCODERS > 1 - case FUNC_RESET_ROTENC2: + case FUNC_RESET_ROTENC2: #endif - rotencValue[CFN_PARAM(cfn)-FUNC_RESET_ROTENC1] = 0; - break; + rotencValue[CFN_PARAM(cfn)-FUNC_RESET_ROTENC1] = 0; + break; #endif - } -#if defined(CPUARM) - if (CFN_PARAM(cfn)>=FUNC_RESET_PARAM_FIRST_TELEM) { - uint8_t item = CFN_PARAM(cfn)-FUNC_RESET_PARAM_FIRST_TELEM; - if (item < MAX_TELEMETRY_SENSORS) { - telemetryItems[item].clear(); } - } +#if defined(CPUARM) + if (CFN_PARAM(cfn)>=FUNC_RESET_PARAM_FIRST_TELEM) { + uint8_t item = CFN_PARAM(cfn)-FUNC_RESET_PARAM_FIRST_TELEM; + if (item < MAX_TELEMETRY_SENSORS) { + telemetryItems[item].clear(); + } + } #endif + } break; #if defined(CPUARM) @@ -409,13 +412,13 @@ void evalFunctions() SET_GVAR(CFN_GVAR_INDEX(cfn), GVAR_VALUE(CFN_PARAM(cfn), getGVarFlightMode(mixerCurrentFlightMode, CFN_PARAM(cfn))), mixerCurrentFlightMode); } else if (CFN_GVAR_MODE(cfn) == FUNC_ADJUST_GVAR_INCDEC) { -#if defined(CPUARM) - SET_GVAR(CFN_GVAR_INDEX(cfn), limit(CFN_GVAR_CST_MIN+g_model.gvars[CFN_GVAR_INDEX(cfn)].min, GVAR_VALUE(CFN_GVAR_INDEX(cfn), getGVarFlightMode(mixerCurrentFlightMode, CFN_GVAR_INDEX(cfn))) + CFN_PARAM(cfn), CFN_GVAR_CST_MAX-g_model.gvars[CFN_GVAR_INDEX(cfn)].max), mixerCurrentFlightMode); -#else if (!(functionsContext.activeSwitches & switch_mask)) { +#if defined(CPUARM) + SET_GVAR(CFN_GVAR_INDEX(cfn), limit(CFN_GVAR_CST_MIN+g_model.gvars[CFN_GVAR_INDEX(cfn)].min, GVAR_VALUE(CFN_GVAR_INDEX(cfn), getGVarFlightMode(mixerCurrentFlightMode, CFN_GVAR_INDEX(cfn))) + CFN_PARAM(cfn), CFN_GVAR_CST_MAX-g_model.gvars[CFN_GVAR_INDEX(cfn)].max), mixerCurrentFlightMode); +#else SET_GVAR(CFN_GVAR_INDEX(cfn), GVAR_VALUE(CFN_GVAR_INDEX(cfn), getGVarFlightMode(mixerCurrentFlightMode, CFN_GVAR_INDEX(cfn))) + (CFN_PARAM(cfn) ? +1 : -1), mixerCurrentFlightMode); - } #endif + } } else if (CFN_PARAM(cfn) >= MIXSRC_TrimRud && CFN_PARAM(cfn) <= MIXSRC_TrimAil) { trimGvar[CFN_PARAM(cfn)-MIXSRC_TrimRud] = CFN_GVAR_INDEX(cfn); diff --git a/radio/src/tests/functions.cpp b/radio/src/tests/functions.cpp new file mode 100644 index 000000000..1c059a433 --- /dev/null +++ b/radio/src/tests/functions.cpp @@ -0,0 +1,126 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "gtests.h" + + +#if defined(CPUARM) +TEST(SpecialFunctions, SwitchFiledSize) +{ + // test the size of swtch member + g_model.customFn[0].swtch = SWSRC_LAST; + EXPECT_EQ(g_model.customFn[0].swtch, SWSRC_LAST) << "CustomFunctionData.swtch member is too small to hold all possible values"; + g_model.customFn[0].swtch = -SWSRC_LAST; + EXPECT_EQ(g_model.customFn[0].swtch, -SWSRC_LAST) << "CustomFunctionData.swtch member is too small to hold all possible values"; +} + +#if defined(PCBTARANIS) || defined(PCBHORUS) +TEST(SpecialFunctions, FlightReset) +{ + RADIO_RESET(); + MODEL_RESET(); + + g_model.customFn[0].swtch = SWSRC_SA0; + g_model.customFn[0].func = FUNC_RESET; + g_model.customFn[0].all.val = FUNC_RESET_FLIGHT; + g_model.customFn[0].active = true; + + // we (mis)use s_mixer_first_run_done for the flight reset detection + s_mixer_first_run_done = true; + evalFunctions(g_model.customFn, modelFunctionsContext); + EXPECT_EQ(s_mixer_first_run_done, true); + + // now trigger SA0 + simuSetSwitch(0, -1); + + // flightReset() should be called + evalFunctions(g_model.customFn, modelFunctionsContext); + EXPECT_EQ(s_mixer_first_run_done, false); + + // now set s_mixer_first_run_done to true, and it should stay true (flightReset() should not be called again) + s_mixer_first_run_done = true; + evalFunctions(g_model.customFn, modelFunctionsContext); + EXPECT_EQ(s_mixer_first_run_done, true) << "Flight Reset repeats!"; + +} + +#if defined(GVARS) +TEST(SpecialFunctions, GvarsInc) +{ + RADIO_RESET(); + MODEL_RESET(); + + simuSetSwitch(0, 0); // SA- + + g_model.customFn[0].swtch = SWSRC_SA0; + g_model.customFn[0].func = FUNC_ADJUST_GVAR; + g_model.customFn[0].all.mode = FUNC_ADJUST_GVAR_INCDEC; + g_model.customFn[0].all.param = 0; // GV1 + g_model.customFn[0].all.val = -1; // inc/dec value + g_model.customFn[0].active = true; + + g_model.flightModeData[0].gvars[0] = 10; // GV1 = 10; + evalFunctions(g_model.customFn, modelFunctionsContext); + EXPECT_EQ(g_model.flightModeData[0].gvars[0], 10); + + // now trigger SA0 + simuSetSwitch(0, -1); // SAdown + evalFunctions(g_model.customFn, modelFunctionsContext); + EXPECT_EQ(g_model.flightModeData[0].gvars[0], 9); + evalFunctions(g_model.customFn, modelFunctionsContext); + EXPECT_EQ(g_model.flightModeData[0].gvars[0], 9); + + simuSetSwitch(0, 0); // SA- + evalFunctions(g_model.customFn, modelFunctionsContext); + EXPECT_EQ(g_model.flightModeData[0].gvars[0], 9); + + simuSetSwitch(0, -1); // SAdown + evalFunctions(g_model.customFn, modelFunctionsContext); + EXPECT_EQ(g_model.flightModeData[0].gvars[0], 8); + evalFunctions(g_model.customFn, modelFunctionsContext); + EXPECT_EQ(g_model.flightModeData[0].gvars[0], 8); + + simuSetSwitch(0, 0); // SA- + evalFunctions(g_model.customFn, modelFunctionsContext); + EXPECT_EQ(g_model.flightModeData[0].gvars[0], 8); + + g_model.customFn[0].all.val = 10; // inc/dec value + + simuSetSwitch(0, -1); // SAdown + evalFunctions(g_model.customFn, modelFunctionsContext); + EXPECT_EQ(g_model.flightModeData[0].gvars[0], 18); + evalFunctions(g_model.customFn, modelFunctionsContext); + EXPECT_EQ(g_model.flightModeData[0].gvars[0], 18); + + simuSetSwitch(0, 0); // SA- + evalFunctions(g_model.customFn, modelFunctionsContext); + EXPECT_EQ(g_model.flightModeData[0].gvars[0], 18); + + simuSetSwitch(0, -1); // SAdown + evalFunctions(g_model.customFn, modelFunctionsContext); + EXPECT_EQ(g_model.flightModeData[0].gvars[0], 28); + evalFunctions(g_model.customFn, modelFunctionsContext); + EXPECT_EQ(g_model.flightModeData[0].gvars[0], 28); +} +#endif // #if defined(GVARS) + +#endif // #if defined(PCBTARANIS) || defined(PCBHORUS) + +#endif // #if defined(CPUARM)