529 lines
16 KiB
C++
529 lines
16 KiB
C++
/*
|
|
* Copyright (C) EdgeTX
|
|
*
|
|
* Based on code named
|
|
* opentx - https://github.com/opentx/opentx
|
|
* th9x - http://code.google.com/p/th9x
|
|
* er9x - http://code.google.com/p/er9x
|
|
* gruvin9x - http://code.google.com/p/gruvin9x
|
|
*
|
|
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
|
|
#include "dataconstants.h"
|
|
#include "gtests.h"
|
|
#include "myeeprom.h"
|
|
|
|
#include "hal/adc_driver.h"
|
|
#include "hal/switch_driver.h"
|
|
|
|
void setLogicalSwitch(int index, uint16_t _func, int16_t _v1, int16_t _v2, int16_t _v3 = 0, uint8_t _delay = 0, uint8_t _duration = 0, int8_t _andsw = 0)
|
|
{
|
|
g_model.logicalSw[index].func = _func;
|
|
g_model.logicalSw[index].v1 = _v1;
|
|
g_model.logicalSw[index].v2 = _v2;
|
|
g_model.logicalSw[index].v3 = _v3;
|
|
g_model.logicalSw[index].delay = _delay;
|
|
g_model.logicalSw[index].duration = _duration;
|
|
g_model.logicalSw[index].andsw = _andsw;
|
|
}
|
|
|
|
#define SWSRC_SW1 (SWSRC_FIRST_LOGICAL_SWITCH)
|
|
#define SWSRC_SW2 (SWSRC_FIRST_LOGICAL_SWITCH + 1)
|
|
|
|
TEST(getSwitch, OldTypeStickyCSW)
|
|
{
|
|
RADIO_RESET();
|
|
MODEL_RESET();
|
|
MIXER_RESET();
|
|
|
|
int sw = findHwSwitch(SWITCH_3POS);
|
|
if (sw < 0) return; // no 3-pos switch on this target
|
|
int swPos = (sw * 3) + SWSRC_FIRST_SWITCH;
|
|
|
|
setLogicalSwitch(0, LS_FUNC_AND, swPos, SWSRC_NONE);
|
|
setLogicalSwitch(1, LS_FUNC_OR, SWSRC_SW1, SWSRC_SW2);
|
|
|
|
simuSetSwitch(sw, 0);
|
|
evalLogicalSwitches();
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW1));
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW2));
|
|
|
|
// now trigger SA0, both switches should become true
|
|
simuSetSwitch(sw, -1);
|
|
evalLogicalSwitches();
|
|
EXPECT_TRUE(getSwitch(SWSRC_SW1));
|
|
EXPECT_TRUE(getSwitch(SWSRC_SW2));
|
|
|
|
// now release SA0 and SW2 should stay true
|
|
simuSetSwitch(sw, 0);
|
|
evalLogicalSwitches();
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW1));
|
|
EXPECT_TRUE(getSwitch(SWSRC_SW2));
|
|
|
|
// now reset logical switches
|
|
logicalSwitchesReset();
|
|
evalLogicalSwitches();
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW1));
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW2));
|
|
}
|
|
|
|
// Tick logical switches for N cycles.
|
|
static void tickLogicalSwitches(int n)
|
|
{
|
|
for (int i = 0; i < n; i++) {
|
|
logicalSwitchesTimerTick();
|
|
evalLogicalSwitches();
|
|
}
|
|
}
|
|
|
|
// Sticky LS latches at startup when the set-condition is already satisfied.
|
|
// After logicalSwitchesReset(), lastValue starts at its CS_LAST_VALUE_INIT
|
|
// sentinel, so the first logicalSwitchesTimerTick() sees a 0->1 edge on the
|
|
// set-condition and latches immediately.
|
|
TEST(getSwitch, StickyLatchesAtStartupWhenSetConditionTrue)
|
|
{
|
|
RADIO_RESET();
|
|
MODEL_RESET();
|
|
MIXER_RESET();
|
|
|
|
int sw = findHwSwitch(SWITCH_3POS);
|
|
if (sw < 0) return; // no 3-pos switch on this target
|
|
int swUp = (sw * 3) + SWSRC_FIRST_SWITCH;
|
|
int swDn = swUp + 2;
|
|
|
|
// Pre-set the switch to the "set" position BEFORE creating the LS
|
|
simuSetSwitch(sw, -1);
|
|
|
|
setLogicalSwitch(0, LS_FUNC_STICKY, swUp, swDn);
|
|
|
|
// Simulate power-on
|
|
logicalSwitchesReset();
|
|
|
|
// After reset + tick, the set-condition is already true so sticky latches
|
|
tickLogicalSwitches(10);
|
|
EXPECT_TRUE(getSwitch(SWSRC_SW1))
|
|
<< "Sticky latches at startup when set-condition is already true";
|
|
|
|
// Reset via the reset-condition (swDn)
|
|
simuSetSwitch(sw, 1);
|
|
tickLogicalSwitches(5);
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW1)) << "Reset condition should unlatch sticky";
|
|
}
|
|
|
|
// Sticky LS stays false at startup when the set-condition is NOT satisfied.
|
|
TEST(getSwitch, StickyFalseAtStartupWhenSetConditionFalse)
|
|
{
|
|
RADIO_RESET();
|
|
MODEL_RESET();
|
|
MIXER_RESET();
|
|
|
|
int sw = findHwSwitch(SWITCH_3POS);
|
|
if (sw < 0) return; // no 3-pos switch on this target
|
|
int swUp = (sw * 3) + SWSRC_FIRST_SWITCH;
|
|
int swDn = swUp + 2;
|
|
|
|
// Switch in mid position - set-condition is false
|
|
simuSetSwitch(sw, 0);
|
|
|
|
setLogicalSwitch(0, LS_FUNC_STICKY, swUp, swDn);
|
|
|
|
logicalSwitchesReset();
|
|
tickLogicalSwitches(10);
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW1)) << "Sticky should not latch when condition is false";
|
|
|
|
// Now trigger a rising edge -> should latch
|
|
simuSetSwitch(sw, -1);
|
|
tickLogicalSwitches(5);
|
|
EXPECT_TRUE(getSwitch(SWSRC_SW1)) << "Sticky should latch on rising edge";
|
|
}
|
|
|
|
TEST(getSwitch, nullSW)
|
|
{
|
|
MODEL_RESET();
|
|
EXPECT_TRUE(getSwitch(0));
|
|
}
|
|
|
|
|
|
TEST(getSwitch, inputWithTrim)
|
|
{
|
|
MODEL_RESET();
|
|
setModelDefaults();
|
|
MIXER_RESET();
|
|
|
|
setLogicalSwitch(0, LS_FUNC_VPOS, MIXSRC_FIRST_INPUT, 0, 0);
|
|
anaSetFiltered(0, 0);
|
|
|
|
evalMixes(1);
|
|
evalLogicalSwitches();
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW1));
|
|
|
|
setTrimValue(0, 0, 32);
|
|
evalMixes(1);
|
|
evalLogicalSwitches();
|
|
EXPECT_TRUE(getSwitch(SWSRC_SW1));
|
|
}
|
|
|
|
TEST(evalLogicalSwitches, playFile)
|
|
{
|
|
SYSTEM_RESET();
|
|
MODEL_RESET();
|
|
setModelDefaults();
|
|
MIXER_RESET();
|
|
|
|
extern BitField<(MAX_LOGICAL_SWITCHES * 2/*on, off*/)> sdAvailableLogicalSwitchAudioFiles;
|
|
char filename[AUDIO_FILENAME_MAXLEN+1];
|
|
|
|
#define MODELNAME "MODEL01"
|
|
|
|
sdAvailableLogicalSwitchAudioFiles.setBit(INDEX_LOGICAL_SWITCH_AUDIO_FILE(0,AUDIO_EVENT_OFF));
|
|
sdAvailableLogicalSwitchAudioFiles.setBit(INDEX_LOGICAL_SWITCH_AUDIO_FILE(0,AUDIO_EVENT_ON));
|
|
sdAvailableLogicalSwitchAudioFiles.setBit(INDEX_LOGICAL_SWITCH_AUDIO_FILE(31,AUDIO_EVENT_OFF));
|
|
sdAvailableLogicalSwitchAudioFiles.setBit(INDEX_LOGICAL_SWITCH_AUDIO_FILE(31,AUDIO_EVENT_ON));
|
|
|
|
isAudioFileReferenced((LOGICAL_SWITCH_AUDIO_CATEGORY << 24) + (0 << 16) + AUDIO_EVENT_OFF, filename);
|
|
EXPECT_EQ(strcmp(filename, "/SOUNDS/en/" MODELNAME "/L1-off.wav"), 0);
|
|
isAudioFileReferenced((LOGICAL_SWITCH_AUDIO_CATEGORY << 24) + (0 << 16) + AUDIO_EVENT_ON, filename);
|
|
EXPECT_EQ(strcmp(filename, "/SOUNDS/en/" MODELNAME "/L1-on.wav"), 0);
|
|
isAudioFileReferenced((LOGICAL_SWITCH_AUDIO_CATEGORY << 24) + (31 << 16) + AUDIO_EVENT_OFF, filename);
|
|
EXPECT_EQ(strcmp(filename, "/SOUNDS/en/" MODELNAME "/L32-off.wav"), 0);
|
|
isAudioFileReferenced((LOGICAL_SWITCH_AUDIO_CATEGORY << 24) + (31 << 16) + AUDIO_EVENT_ON, filename);
|
|
EXPECT_EQ(strcmp(filename, "/SOUNDS/en/" MODELNAME "/L32-on.wav"), 0);
|
|
|
|
EXPECT_TRUE(isAudioFileReferenced((LOGICAL_SWITCH_AUDIO_CATEGORY << 24) + (31 << 16) + AUDIO_EVENT_ON, filename));
|
|
EXPECT_FALSE(isAudioFileReferenced((LOGICAL_SWITCH_AUDIO_CATEGORY << 24) + (32 << 16) + AUDIO_EVENT_ON, filename));
|
|
|
|
#undef MODELNAME
|
|
}
|
|
|
|
TEST(getSwitch, edgeInstant)
|
|
{
|
|
int sw1 = findHwSwitch(SWITCH_3POS);
|
|
int sw2 = findHwSwitch(SWITCH_3POS, sw1);
|
|
if (sw1 < 0 || sw2 < 0) return; // needs two distinct 3-pos switches
|
|
int sw1Pos = (sw1 * 3) + SWSRC_FIRST_SWITCH;
|
|
int sw2Pos = (sw2 * 3) + SWSRC_FIRST_SWITCH;
|
|
|
|
MODEL_RESET();
|
|
MIXER_RESET();
|
|
// LS1 setup: EDGE SD down (0:instant)
|
|
// LS2 setup: (EDGE SD down (0:instant)) AND SA down
|
|
setLogicalSwitch(0, LS_FUNC_EDGE, sw2Pos + 2, -129, -1);
|
|
setLogicalSwitch(1, LS_FUNC_EDGE, sw2Pos + 2, -129, -1, 0, 0, sw1Pos + 2);
|
|
|
|
simuSetSwitch(sw1, -1); //SA up
|
|
simuSetSwitch(sw2, 0); //SD mid
|
|
logicalSwitchesTimerTick();
|
|
evalLogicalSwitches();
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW1));
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW2));
|
|
|
|
// now trigger SD donw, LS1 should become true
|
|
simuSetSwitch(sw2, 1); //SD down
|
|
logicalSwitchesTimerTick();
|
|
evalLogicalSwitches();
|
|
EXPECT_TRUE(getSwitch(SWSRC_SW1));
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW2));
|
|
|
|
// now release SD and LS1 should become false
|
|
simuSetSwitch(sw2, 0); //SD mid
|
|
logicalSwitchesTimerTick();
|
|
evalLogicalSwitches();
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW1));
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW2));
|
|
|
|
// now reset logical switches
|
|
logicalSwitchesReset();
|
|
logicalSwitchesTimerTick();
|
|
evalLogicalSwitches();
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW1));
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW2));
|
|
|
|
// second part with SA down
|
|
|
|
simuSetSwitch(sw1, 1); //SA down
|
|
simuSetSwitch(sw2, 0); //SD mid
|
|
logicalSwitchesTimerTick();
|
|
evalLogicalSwitches();
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW1));
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW2));
|
|
|
|
// now trigger SD down, LS1 & LS2 should become true
|
|
simuSetSwitch(sw2, 1); //SD down
|
|
logicalSwitchesTimerTick();
|
|
evalLogicalSwitches();
|
|
EXPECT_TRUE(getSwitch(SWSRC_SW1));
|
|
EXPECT_TRUE(getSwitch(SWSRC_SW2));
|
|
|
|
// now release SA and LS1 & LS2 should stay false
|
|
simuSetSwitch(sw2, 0); //SD mid
|
|
logicalSwitchesTimerTick();
|
|
evalLogicalSwitches();
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW1));
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW2));
|
|
|
|
// now reset logical switches
|
|
logicalSwitchesReset();
|
|
logicalSwitchesTimerTick();
|
|
evalLogicalSwitches();
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW1));
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW2));
|
|
|
|
// now bug #2939
|
|
// SD is kept down and SA is toggled
|
|
simuSetSwitch(sw1, -1); //SA up
|
|
simuSetSwitch(sw2, 1); //SD down
|
|
logicalSwitchesTimerTick();
|
|
evalLogicalSwitches();
|
|
EXPECT_TRUE(getSwitch(SWSRC_SW1));
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW2));
|
|
|
|
simuSetSwitch(sw1, 1); //SA down
|
|
simuSetSwitch(sw2, 1); //SD down
|
|
logicalSwitchesTimerTick();
|
|
evalLogicalSwitches();
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW1));
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW2));
|
|
|
|
simuSetSwitch(sw1, -1); //SA up
|
|
simuSetSwitch(sw2, 1); //SD down
|
|
logicalSwitchesTimerTick();
|
|
evalLogicalSwitches();
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW1));
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW2));
|
|
|
|
//test what happens when EDGE condition is true and
|
|
//logical switches are reset - the switch should fire again
|
|
|
|
simuSetSwitch(sw1, 1); //SA down
|
|
simuSetSwitch(sw2, 1); //SD down
|
|
logicalSwitchesTimerTick();
|
|
evalLogicalSwitches();
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW1)); //switch will not trigger, because SF was already up
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW2));
|
|
|
|
logicalSwitchesReset();
|
|
logicalSwitchesTimerTick();
|
|
evalLogicalSwitches();
|
|
EXPECT_TRUE(getSwitch(SWSRC_SW1));
|
|
EXPECT_TRUE(getSwitch(SWSRC_SW2));
|
|
|
|
logicalSwitchesTimerTick();
|
|
evalLogicalSwitches();
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW1));
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW2));
|
|
}
|
|
|
|
TEST(getSwitch, edgeRelease)
|
|
{
|
|
int sw1 = findHwSwitch(SWITCH_3POS);
|
|
int sw2 = findHwSwitch(SWITCH_3POS, sw1);
|
|
if (sw1 < 0 || sw2 < 0) return; // needs two distinct 3-pos switches
|
|
int sw1Pos = (sw1 * 3) + SWSRC_FIRST_SWITCH;
|
|
int sw2Pos = (sw2 * 3) + SWSRC_FIRST_SWITCH;
|
|
|
|
MODEL_RESET();
|
|
MIXER_RESET();
|
|
// test for issue #2728
|
|
// LS1 setup: EDGE SDup (0:release)
|
|
// LS2 setup: (EDGE SDup (0:release)) AND SAup
|
|
setLogicalSwitch(0, LS_FUNC_EDGE, sw2Pos + 2, -129, 0);
|
|
setLogicalSwitch(1, LS_FUNC_EDGE, sw2Pos + 2, -129, 0, 0, 0, sw1Pos + 2 );
|
|
|
|
simuSetSwitch(sw1, -1); //SA down
|
|
simuSetSwitch(sw2, 0); //SD down
|
|
logicalSwitchesTimerTick();
|
|
evalLogicalSwitches();
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW1));
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW2));
|
|
|
|
simuSetSwitch(sw2, 1); //SD up
|
|
logicalSwitchesTimerTick();
|
|
evalLogicalSwitches();
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW1));
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW2));
|
|
|
|
simuSetSwitch(sw2, 0); //SD down
|
|
logicalSwitchesTimerTick();
|
|
evalLogicalSwitches();
|
|
EXPECT_TRUE(getSwitch(SWSRC_SW1));
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW2));
|
|
|
|
|
|
// second part with SAup
|
|
simuSetSwitch(sw1, 1); //SA up
|
|
simuSetSwitch(sw2, 0); //SD down
|
|
logicalSwitchesTimerTick();
|
|
evalLogicalSwitches();
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW1));
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW2));
|
|
|
|
simuSetSwitch(sw2, 1); //SD up
|
|
logicalSwitchesTimerTick();
|
|
evalLogicalSwitches();
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW1));
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW2));
|
|
|
|
simuSetSwitch(sw2, 0); //SD down
|
|
logicalSwitchesTimerTick();
|
|
evalLogicalSwitches();
|
|
EXPECT_TRUE(getSwitch(SWSRC_SW1));
|
|
EXPECT_TRUE(getSwitch(SWSRC_SW2));
|
|
|
|
// with switches reset both should remain false
|
|
logicalSwitchesReset();
|
|
logicalSwitchesTimerTick();
|
|
evalLogicalSwitches();
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW1));
|
|
EXPECT_FALSE(getSwitch(SWSRC_SW2));
|
|
|
|
}
|
|
|
|
uint8_t boardGetMaxSwitches();
|
|
|
|
TEST(FlexSwitches, switchGetPosition)
|
|
{
|
|
if (adcGetMaxInputs(ADC_INPUT_FLEX) == 0) return;
|
|
if (MAX_FLEX_SWITCHES == 0) return;
|
|
switchInit();
|
|
|
|
auto sw_idx = boardGetMaxSwitches();
|
|
auto sw_name = switchGetDefaultName(sw_idx);
|
|
EXPECT_STREQ("FL1", sw_name);
|
|
EXPECT_FALSE(switchIsFlexValid(sw_idx));
|
|
|
|
// Configure 1st FLEX input as switch
|
|
g_eeGeneral.potsConfig = FLEX_SWITCH;
|
|
switchConfigFlex(sw_idx, 0);
|
|
EXPECT_TRUE(switchIsFlexValid(sw_idx));
|
|
|
|
auto offset = adcGetInputOffset(ADC_INPUT_FLEX);
|
|
anaSetFiltered(offset, -1024);
|
|
EXPECT_EQ(SWITCH_HW_UP, switchGetPosition(sw_idx));
|
|
|
|
anaSetFiltered(offset, 0);
|
|
EXPECT_EQ(SWITCH_HW_MID, switchGetPosition(sw_idx));
|
|
|
|
anaSetFiltered(offset, +1024);
|
|
EXPECT_EQ(SWITCH_HW_DOWN, switchGetPosition(sw_idx));
|
|
}
|
|
|
|
TEST(FlexSwitches, getValue)
|
|
{
|
|
if (adcGetMaxInputs(ADC_INPUT_FLEX) == 0) return;
|
|
if (MAX_FLEX_SWITCHES == 0) return;
|
|
switchInit();
|
|
|
|
// Configure 1st FLEX input as switch
|
|
g_eeGeneral.potsConfig = FLEX_SWITCH;
|
|
auto sw_idx = boardGetMaxSwitches();
|
|
switchConfigFlex(sw_idx, 0);
|
|
|
|
g_eeGeneral.switchSetType(sw_idx, SWITCH_3POS);
|
|
EXPECT_EQ(SWITCH_3POS, g_model.getSwitchType(sw_idx));
|
|
|
|
auto offset = adcGetInputOffset(ADC_INPUT_FLEX);
|
|
anaSetFiltered(offset, -1024);
|
|
EXPECT_EQ(-1024, getValue(MIXSRC_FIRST_SWITCH + sw_idx));
|
|
|
|
anaSetFiltered(offset, 0);
|
|
EXPECT_EQ(0, getValue(MIXSRC_FIRST_SWITCH + sw_idx));
|
|
|
|
anaSetFiltered(offset, +1024);
|
|
EXPECT_EQ(+1024, getValue(MIXSRC_FIRST_SWITCH + sw_idx));
|
|
|
|
g_eeGeneral.switchSetType(sw_idx, SWITCH_2POS);
|
|
EXPECT_EQ(SWITCH_2POS, g_model.getSwitchType(sw_idx));
|
|
|
|
anaSetFiltered(offset, -1024);
|
|
EXPECT_EQ(-1024, getValue(MIXSRC_FIRST_SWITCH + sw_idx));
|
|
|
|
anaSetFiltered(offset, 0);
|
|
EXPECT_EQ(+1024, getValue(MIXSRC_FIRST_SWITCH + sw_idx));
|
|
|
|
anaSetFiltered(offset, +1024);
|
|
EXPECT_EQ(+1024, getValue(MIXSRC_FIRST_SWITCH + sw_idx));
|
|
}
|
|
|
|
TEST(FlexSwitches, getSwitch)
|
|
{
|
|
if (adcGetMaxInputs(ADC_INPUT_FLEX) == 0) return;
|
|
if (MAX_FLEX_SWITCHES == 0) return;
|
|
switchInit();
|
|
|
|
// Configure 1st FLEX input as switch
|
|
g_eeGeneral.potsConfig = FLEX_SWITCH;
|
|
auto sw_idx = boardGetMaxSwitches();
|
|
switchConfigFlex(sw_idx, 0);
|
|
|
|
g_eeGeneral.switchSetType(sw_idx, SWITCH_3POS);
|
|
EXPECT_EQ(SWITCH_3POS, g_model.getSwitchType(sw_idx));
|
|
|
|
auto offset = adcGetInputOffset(ADC_INPUT_FLEX);
|
|
anaSetFiltered(offset, -1024);
|
|
EXPECT_TRUE(getSwitch(SWSRC_FIRST_SWITCH + sw_idx * 3));
|
|
EXPECT_FALSE(getSwitch(SWSRC_FIRST_SWITCH + sw_idx * 3 + 1));
|
|
EXPECT_FALSE(getSwitch(SWSRC_FIRST_SWITCH + sw_idx * 3 + 2));
|
|
|
|
anaSetFiltered(offset, 0);
|
|
EXPECT_FALSE(getSwitch(SWSRC_FIRST_SWITCH + sw_idx * 3));
|
|
EXPECT_TRUE(getSwitch(SWSRC_FIRST_SWITCH + sw_idx * 3 + 1));
|
|
EXPECT_FALSE(getSwitch(SWSRC_FIRST_SWITCH + sw_idx * 3 + 2));
|
|
|
|
anaSetFiltered(offset, +1024);
|
|
EXPECT_FALSE(getSwitch(SWSRC_FIRST_SWITCH + sw_idx * 3));
|
|
EXPECT_FALSE(getSwitch(SWSRC_FIRST_SWITCH + sw_idx * 3 + 1));
|
|
EXPECT_TRUE(getSwitch(SWSRC_FIRST_SWITCH + sw_idx * 3 + 2));
|
|
}
|
|
|
|
#if defined(FUNCTION_SWITCHES)
|
|
TEST(FunctionSwitches, holdIsNotRepeatedToggle)
|
|
{
|
|
MODEL_RESET();
|
|
setModelDefaults();
|
|
switchInit();
|
|
|
|
for (uint8_t i = 0; i < switchGetMaxSwitches(); i++) {
|
|
if (!switchIsCustomSwitch(i)) continue;
|
|
// Toggle type with no group, so a phantom "switch moved" event
|
|
// flips the logical state and is observable
|
|
g_model.cfsSetType(i, SWITCH_TOGGLE);
|
|
g_model.cfsSetGroup(i, 0);
|
|
simuSetSwitch(i, -1);
|
|
}
|
|
|
|
setFSStartupPosition();
|
|
evalFunctionSwitches(); // sync previous state with all switches released
|
|
|
|
for (uint8_t i = 0; i < switchGetMaxSwitches(); i++) {
|
|
if (!switchIsCustomSwitch(i)) continue;
|
|
|
|
bool released = g_model.cfsState(i);
|
|
simuSetSwitch(i, 1);
|
|
evalFunctionSwitches();
|
|
bool pressed = g_model.cfsState(i);
|
|
EXPECT_NE(released, pressed) << "press did not toggle switch index " << (int)i;
|
|
|
|
// holding the switch must not generate further toggles
|
|
evalFunctionSwitches();
|
|
EXPECT_EQ(pressed, g_model.cfsState(i))
|
|
<< "hold re-toggled switch index " << (int)i;
|
|
evalFunctionSwitches();
|
|
EXPECT_EQ(pressed, g_model.cfsState(i))
|
|
<< "hold re-toggled switch index " << (int)i;
|
|
|
|
simuSetSwitch(i, -1);
|
|
evalFunctionSwitches();
|
|
}
|
|
}
|
|
#endif
|