Issue #773 fixed (+ non regression tests added)
This commit is contained in:
+68
-29
@@ -42,7 +42,10 @@
|
||||
|
||||
void doMixerCalculations();
|
||||
|
||||
#define MODEL_RESET() memset(&g_model, 0, sizeof(g_model))
|
||||
#define MODEL_RESET() \
|
||||
memset(&g_model, 0, sizeof(g_model)); \
|
||||
extern bool s_mixer_first_run_done; \
|
||||
s_mixer_first_run_done = false;
|
||||
|
||||
#define MIXER_RESET() \
|
||||
memset(channelOutputs, 0, sizeof(channelOutputs)); \
|
||||
@@ -62,6 +65,7 @@ uint16_t anaIn(uint8_t chan)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(PCBTARANIS)
|
||||
TEST(Trims, greaterTrimLink)
|
||||
{
|
||||
MODEL_RESET();
|
||||
@@ -88,6 +92,7 @@ TEST(Trims, infiniteChainedTrims)
|
||||
setTrimValue(3, 0, TRIM_EXTENDED_MAX+3); // link to FP2 trim
|
||||
EXPECT_EQ(getRawTrimValue(getTrimFlightPhase(0, 2), 0), 32);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(outdezNAtt, test_unsigned)
|
||||
{
|
||||
@@ -565,16 +570,18 @@ TEST(Mixer, SlowOnSwitch)
|
||||
g_model.mixData[0].srcRaw = MIXSRC_MAX;
|
||||
g_model.mixData[0].weight = 100;
|
||||
g_model.mixData[0].swtch = SWSRC_THR;
|
||||
g_model.mixData[0].speedUp = 10;
|
||||
g_model.mixData[0].speedDown = 10;
|
||||
g_model.mixData[0].speedUp = SLOW_STEP*5;
|
||||
g_model.mixData[0].speedDown = SLOW_STEP*5;
|
||||
|
||||
s_mixer_first_run_done = true;
|
||||
|
||||
perOut(e_perout_mode_normal, 0);
|
||||
EXPECT_EQ(chans[0], 0);
|
||||
|
||||
simuSetSwitch(0, 1);
|
||||
CHECK_SLOW_MOVEMENT(0, +1, 250);
|
||||
|
||||
simuSetSwitch(0, 0);
|
||||
simuSetSwitch(0, -1);
|
||||
CHECK_SLOW_MOVEMENT(0, -1, 250);
|
||||
}
|
||||
|
||||
@@ -587,11 +594,12 @@ TEST(Mixer, SlowUpOnSwitch)
|
||||
g_model.mixData[0].srcRaw = MIXSRC_MAX;
|
||||
g_model.mixData[0].weight = 100;
|
||||
g_model.mixData[0].swtch = SWSRC_THR;
|
||||
g_model.mixData[0].speedUp = 10;
|
||||
g_model.mixData[0].speedUp = SLOW_STEP*5;
|
||||
g_model.mixData[0].speedDown = 0;
|
||||
|
||||
simuSetSwitch(0, 0);
|
||||
perOut(e_perout_mode_normal, 0);
|
||||
s_mixer_first_run_done = true;
|
||||
EXPECT_EQ(chans[0], 0);
|
||||
|
||||
simuSetSwitch(0, 1);
|
||||
@@ -605,20 +613,22 @@ TEST(Mixer, SlowUpOnSwitch)
|
||||
simuSetSwitch(0, 1);
|
||||
CHECK_SLOW_MOVEMENT(0, +1, 100);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(Mixer, SlowOnPhase)
|
||||
{
|
||||
MODEL_RESET();
|
||||
MIXER_RESET();
|
||||
g_model.phaseData[1].swtch = SWSRC_THR;
|
||||
g_model.phaseData[1].swtch = TR(SWSRC_THR, SWSRC_SA0);
|
||||
g_model.mixData[0].destCh = 0;
|
||||
g_model.mixData[0].mltpx = MLTPX_ADD;
|
||||
g_model.mixData[0].srcRaw = MIXSRC_MAX;
|
||||
g_model.mixData[0].weight = 100;
|
||||
g_model.mixData[0].phases = 0x2 + 0x4 + 0x8 + 0x10 /*only enabled in phase 0*/;
|
||||
g_model.mixData[0].speedUp = 10;
|
||||
g_model.mixData[0].speedDown = 10;
|
||||
g_model.mixData[0].speedUp = SLOW_STEP*5;
|
||||
g_model.mixData[0].speedDown = SLOW_STEP*5;
|
||||
|
||||
s_mixer_first_run_done = true;
|
||||
s_perout_flight_phase = 0;
|
||||
perOut(e_perout_mode_normal, 0);
|
||||
EXPECT_EQ(chans[0], 0);
|
||||
@@ -629,20 +639,26 @@ TEST(Mixer, SlowOnPhase)
|
||||
CHECK_SLOW_MOVEMENT(0, -1, 250);
|
||||
}
|
||||
|
||||
#if !defined(CPUARM)
|
||||
TEST(Mixer, SlowOnSwitchAndPhase)
|
||||
{
|
||||
MODEL_RESET();
|
||||
MIXER_RESET();
|
||||
g_model.phaseData[1].swtch = SWSRC_THR;
|
||||
g_model.phaseData[1].swtch = TR(SWSRC_THR, SWSRC_SA0);
|
||||
g_model.mixData[0].destCh = 0;
|
||||
g_model.mixData[0].mltpx = MLTPX_ADD;
|
||||
g_model.mixData[0].srcRaw = MIXSRC_MAX;
|
||||
g_model.mixData[0].weight = 100;
|
||||
g_model.mixData[0].swtch = SWSRC_THR;
|
||||
g_model.mixData[0].swtch = TR(SWSRC_THR, SWSRC_SA0);
|
||||
#if defined(CPUARM)
|
||||
g_model.mixData[0].phases = 0x2 + 0x4 + 0x8 + 0x10 + 0x20 + 0x40 + 0x80 + 0x100 /*only enabled in phase 0*/;
|
||||
#else
|
||||
g_model.mixData[0].phases = 0x2 + 0x4 + 0x8 + 0x10 /*only enabled in phase 0*/;
|
||||
g_model.mixData[0].speedUp = 10;
|
||||
g_model.mixData[0].speedDown = 10;
|
||||
#endif
|
||||
g_model.mixData[0].speedUp = SLOW_STEP*5;
|
||||
g_model.mixData[0].speedDown = SLOW_STEP*5;
|
||||
|
||||
s_mixer_first_run_done = true;
|
||||
perOut(e_perout_mode_normal, 0);
|
||||
EXPECT_EQ(chans[0], 0);
|
||||
|
||||
@@ -650,25 +666,26 @@ TEST(Mixer, SlowOnSwitchAndPhase)
|
||||
s_perout_flight_phase = 0;
|
||||
CHECK_SLOW_MOVEMENT(0, +1, 250);
|
||||
|
||||
simuSetSwitch(0, 0);
|
||||
simuSetSwitch(0, -1);
|
||||
s_perout_flight_phase = 1;
|
||||
CHECK_SLOW_MOVEMENT(0, -1, 250);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(PCBTARANIS)
|
||||
TEST(Mixer, SlowOnSwitchSource)
|
||||
{
|
||||
MODEL_RESET();
|
||||
MIXER_RESET();
|
||||
g_model.mixData[0].destCh = 0;
|
||||
g_model.mixData[0].mltpx = MLTPX_ADD;
|
||||
g_model.mixData[0].srcRaw = MIXSRC_THR;
|
||||
g_model.mixData[0].srcRaw = TR(MIXSRC_THR, MIXSRC_SA);
|
||||
g_model.mixData[0].weight = 100;
|
||||
g_model.mixData[0].speedUp = 10;
|
||||
g_model.mixData[0].speedDown = 10;
|
||||
g_model.mixData[0].speedUp = SLOW_STEP*5;
|
||||
g_model.mixData[0].speedDown = SLOW_STEP*5;
|
||||
|
||||
simuSetSwitch(0, 0);
|
||||
s_mixer_first_run_done = true;
|
||||
|
||||
simuSetSwitch(0, -1);
|
||||
CHECK_SLOW_MOVEMENT(0, -1, 250);
|
||||
EXPECT_EQ(chans[0], -CHANNEL_MAX);
|
||||
|
||||
@@ -676,6 +693,22 @@ TEST(Mixer, SlowOnSwitchSource)
|
||||
CHECK_SLOW_MOVEMENT(0, +1, 500);
|
||||
}
|
||||
|
||||
TEST(Mixer, SlowDisabledOnStartup)
|
||||
{
|
||||
MODEL_RESET();
|
||||
MIXER_RESET();
|
||||
g_model.mixData[0].destCh = 0;
|
||||
g_model.mixData[0].mltpx = MLTPX_ADD;
|
||||
g_model.mixData[0].srcRaw = MIXSRC_MAX;
|
||||
g_model.mixData[0].weight = 100;
|
||||
g_model.mixData[0].speedUp = SLOW_STEP*5;
|
||||
g_model.mixData[0].speedDown = SLOW_STEP*5;
|
||||
|
||||
perOut(e_perout_mode_normal, 0);
|
||||
EXPECT_EQ(chans[0], CHANNEL_MAX);
|
||||
}
|
||||
|
||||
#if !defined(PCBTARANIS)
|
||||
TEST(Mixer, SlowAndDelayOnReplace3POSSource)
|
||||
{
|
||||
MODEL_RESET();
|
||||
@@ -685,9 +718,11 @@ TEST(Mixer, SlowAndDelayOnReplace3POSSource)
|
||||
g_model.mixData[0].srcRaw = MIXSRC_3POS;
|
||||
g_model.mixData[0].weight = 100;
|
||||
g_model.mixData[0].delayUp = 10;
|
||||
g_model.mixData[0].speedUp = 10;
|
||||
g_model.mixData[0].speedDown = 10;
|
||||
g_model.mixData[0].speedUp = SLOW_STEP*5;
|
||||
g_model.mixData[0].speedDown = SLOW_STEP*5;
|
||||
|
||||
s_mixer_first_run_done = true;
|
||||
|
||||
simuSetSwitch(3, -1);
|
||||
CHECK_SLOW_MOVEMENT(0, -1, 250);
|
||||
EXPECT_EQ(chans[0], -CHANNEL_MAX);
|
||||
@@ -717,7 +752,7 @@ TEST(Mixer, SlowOnSwitchReplace)
|
||||
g_model.mixData[1].srcRaw = MIXSRC_MAX;
|
||||
g_model.mixData[1].weight = 100;
|
||||
g_model.mixData[1].swtch = SWSRC_THR;
|
||||
g_model.mixData[1].speedDown = 10;
|
||||
g_model.mixData[1].speedDown = SLOW_STEP*5;
|
||||
|
||||
simuSetSwitch(0, 0);
|
||||
perOut(e_perout_mode_normal, 1);
|
||||
@@ -745,16 +780,19 @@ TEST(Mixer, NoTrimOnInactiveMix)
|
||||
g_model.mixData[0].srcRaw = MIXSRC_Thr;
|
||||
g_model.mixData[0].weight = 100;
|
||||
g_model.mixData[0].swtch = SWSRC_THR;
|
||||
g_model.mixData[0].speedUp = 10;
|
||||
g_model.mixData[0].speedDown = 10;
|
||||
g_model.mixData[0].speedUp = SLOW_STEP*5;
|
||||
g_model.mixData[0].speedDown = SLOW_STEP*5;
|
||||
setTrimValue(0, 2, 256);
|
||||
|
||||
s_mixer_first_run_done = true;
|
||||
|
||||
simuSetSwitch(0, 1);
|
||||
CHECK_SLOW_MOVEMENT(0, 1, 100);
|
||||
|
||||
simuSetSwitch(0, 0);
|
||||
simuSetSwitch(0, -1);
|
||||
CHECK_SLOW_MOVEMENT(0, -1, 100);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(Mixer, SlowOnMultiply)
|
||||
{
|
||||
@@ -768,20 +806,21 @@ TEST(Mixer, SlowOnMultiply)
|
||||
g_model.mixData[1].mltpx = MLTPX_MUL;
|
||||
g_model.mixData[1].srcRaw = MIXSRC_MAX;
|
||||
g_model.mixData[1].weight = 100;
|
||||
g_model.mixData[1].swtch = SWSRC_THR;
|
||||
g_model.mixData[1].speedUp = 10;
|
||||
g_model.mixData[1].speedDown = 10;
|
||||
g_model.mixData[1].swtch = TR(SWSRC_THR, SWSRC_SA0);
|
||||
g_model.mixData[1].speedUp = SLOW_STEP*5;
|
||||
g_model.mixData[1].speedDown = SLOW_STEP*5;
|
||||
|
||||
s_mixer_first_run_done = true;
|
||||
|
||||
simuSetSwitch(0, 1);
|
||||
CHECK_SLOW_MOVEMENT(0, 1, 250);
|
||||
|
||||
simuSetSwitch(0, 0);
|
||||
simuSetSwitch(0, -1);
|
||||
CHECK_NO_MOVEMENT(0, CHANNEL_MAX, 250);
|
||||
|
||||
simuSetSwitch(0, 1);
|
||||
CHECK_NO_MOVEMENT(0, CHANNEL_MAX, 250);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(Curves, LinearIntpol)
|
||||
{
|
||||
|
||||
@@ -2983,6 +2983,8 @@ void resetTimer(uint8_t idx)
|
||||
timerState.val_10ms = 0 ;
|
||||
}
|
||||
|
||||
bool s_mixer_first_run_done = false;
|
||||
|
||||
void resetAll()
|
||||
{
|
||||
static bool firstReset = true;
|
||||
@@ -3001,6 +3003,7 @@ void resetAll()
|
||||
}
|
||||
|
||||
s_last_switch_value = 0;
|
||||
s_mixer_first_run_done = false;
|
||||
|
||||
SKIP_AUTOMATIC_PROMPTS();
|
||||
|
||||
@@ -3855,21 +3858,21 @@ void perOut(uint8_t mode, uint8_t tick10ms)
|
||||
// the unit of the stored value is the value from md->speedUp or md->speedDown divide SLOW_STEP seconds; e.g. value 4 means 4/SLOW_STEP = 2 seconds for CPU64
|
||||
// because we get a tick each 10msec, we need 100 ticks for one second
|
||||
// the value in md->speedXXX gives the time it should take to do a full movement from -100 to 100 therefore 200%. This equals 2048 in recalculated internal range
|
||||
if (tick10ms) {
|
||||
if (tick10ms || !s_mixer_first_run_done) {
|
||||
// only if already time is passed add or substract a value according the speed configured
|
||||
int32_t rate = (int32_t) tick10ms << (DEL_MULT_SHIFT+11); // = DEL_MULT*2048*tick10ms
|
||||
// rate equals a full range for one second; if less time is passed rate is accordingly smaller
|
||||
// if one second passed, rate would be 2048 (full motion)*256(recalculated weight)*100(100 ticks needed for one second)
|
||||
int32_t currentValue = ((int32_t) v<<DEL_MULT_SHIFT);
|
||||
if (diff > 0) {
|
||||
if (md->speedUp > 0) {
|
||||
if (s_mixer_first_run_done && md->speedUp > 0) {
|
||||
// if a speed upwards is defined recalculate the new value according configured speed; the higher the speed the smaller the add value is
|
||||
int32_t newValue = tact+rate/((int16_t)(100/SLOW_STEP)*md->speedUp);
|
||||
if (newValue<currentValue) currentValue = newValue; // Endposition; prevent toggling around the destination
|
||||
}
|
||||
}
|
||||
else { // if is <0 because ==0 is not possible
|
||||
if (md->speedDown > 0) {
|
||||
if (s_mixer_first_run_done && md->speedDown > 0) {
|
||||
// see explanation in speedUp
|
||||
int32_t newValue = tact-rate/((int16_t)(100/SLOW_STEP)*md->speedDown);
|
||||
if (newValue>currentValue) currentValue = newValue; // Endposition; prevent toggling around the destination
|
||||
@@ -4092,6 +4095,8 @@ void doMixerCalculations()
|
||||
perOut(e_perout_mode_normal, tick10ms);
|
||||
}
|
||||
|
||||
s_mixer_first_run_done = true;
|
||||
|
||||
//========== FUNCTIONS ===============
|
||||
// must be done after mixing because some functions use the inputs/channels values
|
||||
// must be done before limits because of the applyLimit function: it checks for safety switches which would be not initialized otherwise
|
||||
|
||||
@@ -101,12 +101,12 @@ sem_t *eeprom_write_sem;
|
||||
#if defined(PCBTARANIS)
|
||||
#define SWITCH_CASE(swtch, pin, mask) \
|
||||
case swtch: \
|
||||
if (state) pin &= ~(mask); else pin |= (mask); \
|
||||
if (state > 0) pin &= ~(mask); else pin |= (mask); \
|
||||
break;
|
||||
#else
|
||||
#define SWITCH_CASE(swtch, pin, mask) \
|
||||
case swtch: \
|
||||
if (state) pin |= (mask); else pin &= ~(mask); \
|
||||
if (state > 0) pin |= (mask); else pin &= ~(mask); \
|
||||
break;
|
||||
#endif
|
||||
#define SWITCH_3_CASE(swtch, pin1, pin2, mask1, mask2) \
|
||||
@@ -116,13 +116,13 @@ sem_t *eeprom_write_sem;
|
||||
break;
|
||||
#define KEY_CASE(key, pin, mask) \
|
||||
case key: \
|
||||
if (state) pin &= ~mask; else pin |= mask;\
|
||||
if (state > 0) pin &= ~mask; else pin |= mask;\
|
||||
break;
|
||||
#define TRIM_CASE KEY_CASE
|
||||
#else
|
||||
#define SWITCH_CASE(swtch, pin, mask) \
|
||||
case swtch: \
|
||||
if (state) pin &= ~(mask); else pin |= (mask); \
|
||||
if (state > 0) pin &= ~(mask); else pin |= (mask); \
|
||||
break;
|
||||
#define SWITCH_3_CASE(swtch, pin1, pin2, mask1, mask2) \
|
||||
case swtch: \
|
||||
@@ -131,7 +131,7 @@ sem_t *eeprom_write_sem;
|
||||
break;
|
||||
#define KEY_CASE(key, pin, mask) \
|
||||
case key: \
|
||||
if (state) pin |= (mask); else pin &= ~(mask);\
|
||||
if (state > 0) pin |= (mask); else pin &= ~(mask);\
|
||||
break;
|
||||
#define TRIM_CASE KEY_CASE
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user