diff --git a/radio/src/gtests.cpp b/radio/src/gtests.cpp index dbb8df463..22e53b688 100644 --- a/radio/src/gtests.cpp +++ b/radio/src/gtests.cpp @@ -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) { diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index b4b744351..8f3d2d742 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -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< 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 (newValuespeedDown > 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 diff --git a/radio/src/simpgmspace.cpp b/radio/src/simpgmspace.cpp index b00c96be7..bd86354f0 100644 --- a/radio/src/simpgmspace.cpp +++ b/radio/src/simpgmspace.cpp @@ -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