From 2fbd4ff13a402322095aed4c63c4bdf89929a60d Mon Sep 17 00:00:00 2001 From: bsongis Date: Thu, 15 May 2014 12:08:57 +0200 Subject: [PATCH] Mixer code splitted differently --- radio/src/audio_arm.cpp | 2 +- radio/src/audio_arm.h | 5 +- radio/src/audio_avr.h | 2 +- radio/src/buzzer.h | 2 +- radio/src/curves.cpp | 4 +- radio/src/eeprom_raw.cpp | 3 - radio/src/eeprom_rlc.cpp | 3 - radio/src/gtests.cpp | 48 ++--- radio/src/gui/menu_model.cpp | 4 +- radio/src/gui/menus.cpp | 6 +- radio/src/gui/view_main.cpp | 6 +- radio/src/mixer.cpp | 407 +++-------------------------------- radio/src/myeeprom.h | 6 +- radio/src/opentx.cpp | 394 ++++++++++++++++++++++++++++++--- radio/src/opentx.h | 22 +- radio/src/switches.cpp | 4 +- 16 files changed, 449 insertions(+), 469 deletions(-) diff --git a/radio/src/audio_arm.cpp b/radio/src/audio_arm.cpp index 08c875e6e..72f770c56 100644 --- a/radio/src/audio_arm.cpp +++ b/radio/src/audio_arm.cpp @@ -445,7 +445,7 @@ tmr10ms_t timeAutomaticPromptsSilence = 0; void playModelEvent(uint8_t category, uint8_t index, uint8_t event) { char filename[AUDIO_FILENAME_MAXLEN+1]; - if ((get_tmr10ms()-timeAutomaticPromptsSilence > 50) && isAudioFileReferenced((category << 24) + (index << 16) + event, filename)) { + if (IS_SILENCE_PERIOD_ELAPSED() && isAudioFileReferenced((category << 24) + (index << 16) + event, filename)) { audioQueue.playFile(filename); } } diff --git a/radio/src/audio_arm.h b/radio/src/audio_arm.h index 17a6768e3..fa0478010 100644 --- a/radio/src/audio_arm.h +++ b/radio/src/audio_arm.h @@ -331,14 +331,15 @@ void pushPrompt(uint16_t prompt, uint8_t id=0); #define PLAY_SWITCH_MOVED(sw) playModelEvent(SWITCH_AUDIO_CATEGORY, sw) #define PLAY_LOGICAL_SWITCH_OFF(sw) playModelEvent(LOGICAL_SWITCH_AUDIO_CATEGORY, sw, AUDIO_EVENT_OFF) #define PLAY_LOGICAL_SWITCH_ON(sw) playModelEvent(LOGICAL_SWITCH_AUDIO_CATEGORY, sw, AUDIO_EVENT_ON) - #define SKIP_AUTOMATIC_PROMPTS() timeAutomaticPromptsSilence = get_tmr10ms() + #define START_SILENCE_PERIOD() timeAutomaticPromptsSilence = get_tmr10ms() + #define IS_SILENCE_PERIOD_ELAPSED() (get_tmr10ms()-timeAutomaticPromptsSilence > 50) #else #define PLAY_PHASE_OFF(phase) #define PLAY_PHASE_ON(phase) #define PLAY_SWITCH_MOVED(sw) #define PLAY_LOGICAL_SWITCH_OFF(sw) #define PLAY_LOGICAL_SWITCH_ON(sw) - #define SKIP_AUTOMATIC_PROMPTS() + #define START_SILENCE_PERIOD() #endif void referenceSystemAudioFiles(); diff --git a/radio/src/audio_avr.h b/radio/src/audio_avr.h index 691305655..28ac65afa 100644 --- a/radio/src/audio_avr.h +++ b/radio/src/audio_avr.h @@ -160,6 +160,6 @@ void audioDefevent(uint8_t e); #define PLAY_SWITCH_MOVED(sw) #define PLAY_LOGICAL_SWITCH_OFF(sw) #define PLAY_LOGICAL_SWITCH_ON(sw) -#define SKIP_AUTOMATIC_PROMPTS() +#define START_SILENCE_PERIOD() #endif diff --git a/radio/src/buzzer.h b/radio/src/buzzer.h index 6d901bbbb..ac0ae1453 100644 --- a/radio/src/buzzer.h +++ b/radio/src/buzzer.h @@ -105,7 +105,7 @@ void beep(uint8_t val); #define PLAY_SWITCH_MOVED(sw) #define PLAY_LOGICAL_SWITCH_OFF(sw) #define PLAY_LOGICAL_SWITCH_ON(sw) - #define SKIP_AUTOMATIC_PROMPTS() + #define START_SILENCE_PERIOD() #endif #if !defined(CPUARM) diff --git a/radio/src/curves.cpp b/radio/src/curves.cpp index c6eaffccc..3cd2cd91c 100755 --- a/radio/src/curves.cpp +++ b/radio/src/curves.cpp @@ -250,7 +250,7 @@ int applyCurve(int x, CurveRef & curve) switch (curve.type) { case CURVE_REF_DIFF: { - int curveParam = calc100to256(GET_GVAR(curve.value, -100, 100, s_perout_flight_mode)); + int curveParam = calc100to256(GET_GVAR(curve.value, -100, 100, s_current_mixer_flight_mode)); if (curveParam > 0 && x < 0) x = (x * (256 - curveParam)) >> 8; else if (curveParam < 0 && x > 0) @@ -259,7 +259,7 @@ int applyCurve(int x, CurveRef & curve) } case CURVE_REF_EXPO: - return expo(x, GET_GVAR(curve.value, -100, 100, s_perout_flight_mode)); + return expo(x, GET_GVAR(curve.value, -100, 100, s_current_mixer_flight_mode)); case CURVE_REF_FUNC: switch (curve.value) { diff --git a/radio/src/eeprom_raw.cpp b/radio/src/eeprom_raw.cpp index 5578393fb..a77d4ce6c 100644 --- a/radio/src/eeprom_raw.cpp +++ b/radio/src/eeprom_raw.cpp @@ -395,9 +395,6 @@ void eeLoadModel(uint8_t id) activeFnSwitches = 0; activeFunctions = 0; memclear(lastFunctionTime, sizeof(lastFunctionTime)); -#if defined(CPUARM) - evalFunctionsFirstTime = true; -#endif for (uint8_t i=0; i> 8)); \ } \ @@ -555,7 +555,7 @@ TEST(Mixer, RecursiveAddChannelAfterInactivePhase) do { \ int32_t value = chans[(channel)]; \ for (int i=1; i<=(duration); i++) { \ - perOut(e_perout_mode_normal, 1); \ + evalFlightModeMixes(e_perout_mode_normal, 1); \ EXPECT_EQ(chans[(channel)], value); \ } \ } while (0) @@ -575,7 +575,7 @@ TEST(Mixer, SlowOnSwitch) s_mixer_first_run_done = true; - perOut(e_perout_mode_normal, 0); + evalFlightModeMixes(e_perout_mode_normal, 0); EXPECT_EQ(chans[0], 0); simuSetSwitch(0, 1); @@ -598,7 +598,7 @@ TEST(Mixer, SlowUpOnSwitch) g_model.mixData[0].speedDown = 0; simuSetSwitch(0, 0); - perOut(e_perout_mode_normal, 0); + evalFlightModeMixes(e_perout_mode_normal, 0); s_mixer_first_run_done = true; EXPECT_EQ(chans[0], 0); @@ -606,7 +606,7 @@ TEST(Mixer, SlowUpOnSwitch) CHECK_SLOW_MOVEMENT(0, +1, 250); simuSetSwitch(0, 0); - perOut(e_perout_mode_normal, 1); + evalFlightModeMixes(e_perout_mode_normal, 1); EXPECT_EQ(chans[0], 0); lastAct = 0; @@ -629,13 +629,13 @@ TEST(Mixer, SlowOnPhase) g_model.mixData[0].speedDown = SLOW_STEP*5; s_mixer_first_run_done = true; - s_perout_flight_mode = 0; - perOut(e_perout_mode_normal, 0); + s_current_mixer_flight_mode = 0; + evalFlightModeMixes(e_perout_mode_normal, 0); EXPECT_EQ(chans[0], 0); CHECK_SLOW_MOVEMENT(0, +1, 250); - s_perout_flight_mode = 1; + s_current_mixer_flight_mode = 1; CHECK_SLOW_MOVEMENT(0, -1, 250); } @@ -659,15 +659,15 @@ TEST(Mixer, SlowOnSwitchAndPhase) g_model.mixData[0].speedDown = SLOW_STEP*5; s_mixer_first_run_done = true; - perOut(e_perout_mode_normal, 0); + evalFlightModeMixes(e_perout_mode_normal, 0); EXPECT_EQ(chans[0], 0); simuSetSwitch(0, 1); - s_perout_flight_mode = 0; + s_current_mixer_flight_mode = 0; CHECK_SLOW_MOVEMENT(0, +1, 250); simuSetSwitch(0, -1); - s_perout_flight_mode = 1; + s_current_mixer_flight_mode = 1; CHECK_SLOW_MOVEMENT(0, -1, 250); } #endif @@ -704,7 +704,7 @@ TEST(Mixer, SlowDisabledOnStartup) g_model.mixData[0].speedUp = SLOW_STEP*5; g_model.mixData[0].speedDown = SLOW_STEP*5; - perOut(e_perout_mode_normal, 0); + evalFlightModeMixes(e_perout_mode_normal, 0); EXPECT_EQ(chans[0], CHANNEL_MAX); } @@ -755,16 +755,16 @@ TEST(Mixer, SlowOnSwitchReplace) g_model.mixData[1].speedDown = SLOW_STEP*5; simuSetSwitch(0, 0); - perOut(e_perout_mode_normal, 1); + evalFlightModeMixes(e_perout_mode_normal, 1); EXPECT_EQ(chans[0], CHANNEL_MAX/2); simuSetSwitch(0, 1); - perOut(e_perout_mode_normal, 1); + evalFlightModeMixes(e_perout_mode_normal, 1); // slow is not applied, but it's better than the first mix not applied at all! EXPECT_EQ(chans[0], CHANNEL_MAX); simuSetSwitch(0, 0); - perOut(e_perout_mode_normal, 1); + evalFlightModeMixes(e_perout_mode_normal, 1); // slow is not applied, but it's better than the first mix not applied at all! EXPECT_EQ(chans[0], CHANNEL_MAX/2); } diff --git a/radio/src/gui/menu_model.cpp b/radio/src/gui/menu_model.cpp index ad266f146..c79743249 100644 --- a/radio/src/gui/menu_model.cpp +++ b/radio/src/gui/menu_model.cpp @@ -1856,7 +1856,7 @@ void menuModelFlightModesAll(uint8_t event) if (k==MAX_FLIGHT_MODES) { // last line available - add the "check trims" line lcd_putsLeft((LCD_LINES-1)*FH+1, STR_CHECKTRIMS); - putsFlightMode(OFS_CHECKTRIMS, (LCD_LINES-1)*FH+1, s_perout_flight_mode+1); + putsFlightMode(OFS_CHECKTRIMS, (LCD_LINES-1)*FH+1, s_current_mixer_flight_mode+1); if (sub==MAX_FLIGHT_MODES && !trimsCheckTimer) { lcd_status_line(); } @@ -2166,7 +2166,7 @@ void menuModelFlightModesAll(uint8_t event) #endif lcd_putsLeft((LCD_LINES-1)*FH+1, STR_CHECKTRIMS); - putsFlightMode(OFS_CHECKTRIMS, (LCD_LINES-1)*FH+1, s_perout_flight_mode+1); + putsFlightMode(OFS_CHECKTRIMS, (LCD_LINES-1)*FH+1, s_current_mixer_flight_mode+1); if (sub==MAX_FLIGHT_MODES && !trimsCheckTimer) { lcd_status_line(); } diff --git a/radio/src/gui/menus.cpp b/radio/src/gui/menus.cpp index 2c539d4fd..799c1adf5 100644 --- a/radio/src/gui/menus.cpp +++ b/radio/src/gui/menus.cpp @@ -1167,11 +1167,11 @@ int16_t gvarMenuItem(uint8_t x, uint8_t y, int16_t value, int16_t min, int16_t m s_editMode = !s_editMode; #if defined(CPUARM) if (attr & PREC1) - value = (GV_IS_GV_VALUE(value, min, max) ? GET_GVAR(value, min, max, s_perout_flight_mode)*10 : delta); + value = (GV_IS_GV_VALUE(value, min, max) ? GET_GVAR(value, min, max, s_current_mixer_flight_mode)*10 : delta); else - value = (GV_IS_GV_VALUE(value, min, max) ? GET_GVAR(value, min, max, s_perout_flight_mode) : delta); + value = (GV_IS_GV_VALUE(value, min, max) ? GET_GVAR(value, min, max, s_current_mixer_flight_mode) : delta); #else - value = (GV_IS_GV_VALUE(value, min, max) ? GET_GVAR(value, min, max, s_perout_flight_mode) : delta); + value = (GV_IS_GV_VALUE(value, min, max) ? GET_GVAR(value, min, max, s_current_mixer_flight_mode) : delta); #endif eeDirty(EE_MODEL); } diff --git a/radio/src/gui/view_main.cpp b/radio/src/gui/view_main.cpp index f3fdb48bd..cd77607f8 100644 --- a/radio/src/gui/view_main.cpp +++ b/radio/src/gui/view_main.cpp @@ -646,7 +646,7 @@ void menuMainView(uint8_t event) { // Flight Phase Name - uint8_t phase = s_perout_flight_mode; + uint8_t phase = s_current_mixer_flight_mode; lcd_putsnAtt(PHASE_X, PHASE_Y, g_model.phaseData[phase].name, sizeof(g_model.phaseData[phase].name), ZCHAR|PHASE_FLAGS); // Model Name @@ -858,13 +858,13 @@ void menuMainView(uint8_t event) putsStrIdx(BITMAP_X+FW, BITMAP_Y+FH-1, STR_GV, s_gvar_last+1); lcd_putsnAtt(BITMAP_X+4*FW+FW/2, BITMAP_Y+FH-1, g_model.gvars[s_gvar_last].name, LEN_GVAR_NAME, ZCHAR); lcd_putsAtt(BITMAP_X+FW, BITMAP_Y+2*FH+3, PSTR("[\010]"), BOLD); - lcd_outdezAtt(BITMAP_X+5*FW+FW/2, BITMAP_Y+2*FH+3, GVAR_VALUE(s_gvar_last, s_perout_flight_mode), BOLD); + lcd_outdezAtt(BITMAP_X+5*FW+FW/2, BITMAP_Y+2*FH+3, GVAR_VALUE(s_gvar_last, s_current_mixer_flight_mode), BOLD); #else s_warning = STR_GLOBAL_VAR; displayBox(); lcd_putsnAtt(16, 5*FH, g_model.gvars[s_gvar_last].name, LEN_GVAR_NAME, ZCHAR); lcd_putsAtt(16+7*FW, 5*FH, PSTR("[\010]"), BOLD); - lcd_outdezAtt(16+7*FW+4*FW+FW/2, 5*FH, GVAR_VALUE(s_gvar_last, s_perout_flight_mode), BOLD); + lcd_outdezAtt(16+7*FW+4*FW+FW/2, 5*FH, GVAR_VALUE(s_gvar_last, s_current_mixer_flight_mode), BOLD); s_warning = NULL; #endif } diff --git a/radio/src/mixer.cpp b/radio/src/mixer.cpp index d7a3c9ff6..39856c596 100755 --- a/radio/src/mixer.cpp +++ b/radio/src/mixer.cpp @@ -67,8 +67,6 @@ int16_t ex_chans[NUM_CHNOUT] = {0}; // Outputs (before LIMITS) of the last perMa #endif #endif -bool s_mixer_first_run_done = false; - void applyExpos(int16_t *anas, uint8_t mode APPLY_EXPOS_EXTRA_PARAMS) { #if defined(PCBTARANIS) @@ -91,7 +89,7 @@ void applyExpos(int16_t *anas, uint8_t mode APPLY_EXPOS_EXTRA_PARAMS) if (!EXPO_VALID(ed)) break; // end of list if (ed->chn == cur_chn) continue; - if (ed->phases & (1<phases & (1<swtch)) { #if defined(PCBTARANIS) @@ -130,18 +128,18 @@ void applyExpos(int16_t *anas, uint8_t mode APPLY_EXPOS_EXTRA_PARAMS) if (ed->curveMode == MODE_CURVE) v = applyCurve(v, curveParam); else - v = expo(v, GET_GVAR(curveParam, -100, 100, s_perout_flight_mode)); + v = expo(v, GET_GVAR(curveParam, -100, 100, s_current_mixer_flight_mode)); } #endif //========== WEIGHT =============== - int16_t weight = GET_GVAR(ed->weight, MIN_EXPO_WEIGHT, 100, s_perout_flight_mode); + int16_t weight = GET_GVAR(ed->weight, MIN_EXPO_WEIGHT, 100, s_current_mixer_flight_mode); weight = calc100to256(weight); v = ((int32_t)v * weight) >> 8; #if defined(PCBTARANIS) //========== OFFSET =============== - int16_t offset = GET_GVAR(ed->offset, -100, 100, s_perout_flight_mode); + int16_t offset = GET_GVAR(ed->offset, -100, 100, s_current_mixer_flight_mode); if (offset) v += calc100toRESX(offset); //========== TRIMS ================ @@ -291,7 +289,7 @@ getvalue_t getValue(uint8_t i) return 0; #endif - else if (i<=MIXSRC_TrimAil) return calc1000toRESX((int16_t)8 * getTrimValue(s_perout_flight_mode, i-MIXSRC_TrimRud)); + else if (i<=MIXSRC_TrimAil) return calc1000toRESX((int16_t)8 * getTrimValue(s_current_mixer_flight_mode, i-MIXSRC_TrimRud)); #if defined(PCBTARANIS) else if (i==MIXSRC_SA) return (switchState(SW_SA0) ? -1024 : (switchState(SW_SA1) ? 0 : 1024)); @@ -317,7 +315,7 @@ getvalue_t getValue(uint8_t i) else if (i<=MIXSRC_LAST_CH) return ex_chans[i-MIXSRC_CH1]; #if defined(GVARS) - else if (i<=MIXSRC_LAST_GVAR) return GVAR_VALUE(i-MIXSRC_GVAR1, getGVarFlightPhase(s_perout_flight_mode, i-MIXSRC_GVAR1)); + else if (i<=MIXSRC_LAST_GVAR) return GVAR_VALUE(i-MIXSRC_GVAR1, getGVarFlightPhase(s_current_mixer_flight_mode, i-MIXSRC_GVAR1)); #endif else if (i==MIXSRC_FIRST_TELEM-1+TELEM_TX_VOLTAGE) return g_vbat100mV; @@ -522,8 +520,8 @@ void evalInputs(uint8_t mode) #define HELI_ANAS_ARRAY anas #endif -uint8_t s_perout_flight_mode; -void perOut(uint8_t mode, uint8_t tick10ms) +uint8_t s_current_mixer_flight_mode; +void evalFlightModeMixes(uint8_t mode, uint8_t tick10ms) { evalInputs(mode); @@ -627,7 +625,7 @@ void perOut(uint8_t mode, uint8_t tick10ms) //========== PHASE && SWITCH ===== bool mixCondition = (md->phases != 0 || md->swtch); - delayval_t mixEnabled = !(md->phases & (1 << s_perout_flight_mode)) && getSwitch(md->swtch); + delayval_t mixEnabled = !(md->phases & (1 << s_current_mixer_flight_mode)) && getSwitch(md->swtch); if (mixEnabled && md->srcRaw >= MIXSRC_FIRST_TRAINER && md->srcRaw <= MIXSRC_LAST_TRAINER && !ppmInValid) { mixEnabled = 0; @@ -716,7 +714,7 @@ void perOut(uint8_t mode, uint8_t tick10ms) if (apply_offset_and_curve) { #if !defined(PCBTARANIS) // OFFSET is now applied AFTER weight on Taranis //========== OFFSET / SOURCE =============== - int16_t offset = GET_GVAR(MD_OFFSET(md), GV_RANGELARGE_NEG, GV_RANGELARGE, s_perout_flight_mode); + int16_t offset = GET_GVAR(MD_OFFSET(md), GV_RANGELARGE_NEG, GV_RANGELARGE, s_current_mixer_flight_mode); if (offset) v += calc100toRESX_16Bits(offset); #endif @@ -759,7 +757,7 @@ void perOut(uint8_t mode, uint8_t tick10ms) } // saves 12 bytes code if done here and not together with weight; unknown reason - int16_t weight = GET_GVAR(MD_WEIGHT(md), GV_RANGELARGE_NEG, GV_RANGELARGE, s_perout_flight_mode); + int16_t weight = GET_GVAR(MD_WEIGHT(md), GV_RANGELARGE_NEG, GV_RANGELARGE, s_current_mixer_flight_mode); weight = calc100to256_16Bits(weight); //========== SPEED =============== @@ -820,7 +818,7 @@ void perOut(uint8_t mode, uint8_t tick10ms) //========== OFFSET / AFTER =============== #if defined(PCBTARANIS) if (apply_offset_and_curve) { - int16_t offset = GET_GVAR(MD_OFFSET(md), GV_RANGELARGE_NEG, GV_RANGELARGE, s_perout_flight_mode); + int16_t offset = GET_GVAR(MD_OFFSET(md), GV_RANGELARGE_NEG, GV_RANGELARGE, s_current_mixer_flight_mode); if (offset) dv += calc100toRESX_16Bits(offset) << 8; } #endif @@ -833,7 +831,7 @@ void perOut(uint8_t mode, uint8_t tick10ms) #else if (md->curveMode == MODE_DIFFERENTIAL) { // @@@2 also recalculate curveParam to a 256 basis which ease the calculation later a lot - int16_t curveParam = calc100to256(GET_GVAR(md->curveParam, -100, 100, s_perout_flight_mode)); + int16_t curveParam = calc100to256(GET_GVAR(md->curveParam, -100, 100, s_current_mixer_flight_mode)); if (curveParam > 0 && dv < 0) dv = (dv * (256 - curveParam)) >> 8; else if (curveParam < 0 && dv > 0) @@ -917,45 +915,15 @@ void perOut(uint8_t mode, uint8_t tick10ms) int32_t sum_chans512[NUM_CHNOUT] = {0}; -MIX_FUNCTION_RESULT doMixerCalculations() + +#define MAX_ACT 0xffff + +void evalMixes(uint8_t tick10ms) { #if defined(PCBGRUVIN9X) && defined(DEBUG) && !defined(VOICE) PORTH |= 0x40; // PORTH:6 LOW->HIGH signals start of mixer interrupt #endif - static tmr10ms_t lastTMR = 0; - - tmr10ms_t tmr10ms = get_tmr10ms(); - uint8_t tick10ms = (tmr10ms >= lastTMR ? tmr10ms - lastTMR : 1); - // handle tick10ms overrun - // correct overflow handling costs a lot of code; happens only each 11 min; - // therefore forget the exact calculation and use only 1 instead; good compromise - -#if !defined(CPUARM) - lastTMR = tmr10ms; -#endif - - getADC(); - - getSwitchesPosition(lastTMR == 0); - -#if defined(CPUARM) - lastTMR = tmr10ms; -#endif - -#if defined(PCBSKY9X) && !defined(REVA) && !defined(SIMU) - Current_analogue = (Current_analogue*31 + s_anaFilt[8] ) >> 5 ; - if (Current_analogue > Current_max) - Current_max = Current_analogue ; -#elif defined(CPUM2560) && !defined(SIMU) - // For PCB V4, use our own 1.2V, external reference (connected to ADC3) - ADCSRB &= ~(1<> 4) * fp_act[p]; weight += fp_act[p]; @@ -1003,15 +971,13 @@ MIX_FUNCTION_RESULT doMixerCalculations() s_last_switch_used = 0; } assert(weight); - s_perout_flight_mode = phase; + s_current_mixer_flight_mode = phase; } else { - s_perout_flight_mode = phase; - perOut(e_perout_mode_normal, tick10ms); + s_current_mixer_flight_mode = phase; + evalFlightModeMixes(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 @@ -1044,299 +1010,7 @@ MIX_FUNCTION_RESULT doMixerCalculations() sei(); } -#if defined(PCBGRUVIN9X) && defined(DEBUG) && !defined(VOICE) - PORTH &= ~0x40; // PORTH:6 HIGH->LOW signals end of mixer interrupt -#endif - - // Bandgap has had plenty of time to settle... -#if !defined(CPUARM) - getADC_bandgap(); -#endif - -#if defined(CPUARM) - if (!tick10ms) return false; //make sure the rest happen only every 10ms. -#else - if (!tick10ms) return; //make sure the rest happen only every 10ms. -#endif - -#if !defined(CPUM64) && !defined(ACCURAT_THROTTLE_TIMER) - // code cost is about 16 bytes for higher throttle accuracy for timer - // would not be noticable anyway, because all version up to this change had only 16 steps; - // now it has already 32 steps; this define would increase to 128 steps - #define ACCURAT_THROTTLE_TIMER -#endif - - /* Throttle trace */ - int16_t val; - - if (g_model.thrTraceSrc > NUM_POTS) { - uint8_t ch = g_model.thrTraceSrc-NUM_POTS-1; - val = channelOutputs[ch]; - - LimitData *lim = limitAddress(ch); - int16_t gModelMax = LIMIT_MAX_RESX(lim); - int16_t gModelMin = LIMIT_MIN_RESX(lim); - - if (lim->revert) - val = -val + gModelMax; - else - val = val - gModelMin; - -#if defined(PPM_LIMITS_SYMETRICAL) - if (lim->symetrical) - val -= calc1000toRESX(lim->offset); -#endif - - - gModelMax -= gModelMin; // we compare difference between Max and Mix for recaling needed; Max and Min are shifted to 0 by default - // usually max is 1024 min is -1024 --> max-min = 2048 full range - -#ifdef ACCURAT_THROTTLE_TIMER - if (gModelMax!=0 && gModelMax!=2048) val = (int32_t) (val << 11) / (gModelMax); // rescaling only needed if Min, Max differs -#else - // @@@ open.20.fsguruh optimized calculation; now *8 /8 instead of 10 base; (*16/16 already cause a overrun; unsigned calculation also not possible, because v may be negative) - gModelMax+=255; // force rounding up --> gModelMax is bigger --> val is smaller - gModelMax >>= (10-2); - - if (gModelMax!=0 && gModelMax!=8) { - val = (val << 3) / gModelMax; // rescaling only needed if Min, Max differs - } -#endif - - if (val<0) val=0; // prevent val be negative, which would corrupt throttle trace and timers; could occur if safetyswitch is smaller than limits - } - else { -#ifdef PCBTARANIS - val = RESX + calibratedStick[g_model.thrTraceSrc == 0 ? THR_STICK : g_model.thrTraceSrc+NUM_STICKS-1]; -#else - val = RESX + rawAnas[g_model.thrTraceSrc == 0 ? THR_STICK : g_model.thrTraceSrc+NUM_STICKS-1]; -#endif - } - -#if defined(ACCURAT_THROTTLE_TIMER) - val >>= (RESX_SHIFT-6); // calibrate it (resolution increased by factor 4) -#else - val >>= (RESX_SHIFT-4); // calibrate it -#endif - - // Timers start - for (uint8_t i=0; istate == TMR_OFF) { - timerState->state = TMR_RUNNING; - timerState->cnt = 0; - timerState->sum = 0; - } - - // value for time described in timer->mode - // OFFABSTHsTH%THt - if (tm == TMRMODE_THR_REL) { - timerState->cnt++; - timerState->sum+=val; - } - - if ((timerState->val_10ms += tick10ms) >= 100) { - timerState->val_10ms -= 100 ; - int16_t newTimerVal = timerState->val; - if (tv) newTimerVal = tv - newTimerVal; - - if (tm == TMRMODE_ABS) { - newTimerVal++; - } - else if (tm == TMRMODE_THR) { - if (val) newTimerVal++; - } - else if (tm == TMRMODE_THR_REL) { - // @@@ open.20.fsguruh: why so complicated? we have already a s_sum field; use it for the half seconds (not showable) as well - // check for s_cnt[i]==0 is not needed because we are shure it is at least 1 -#if defined(ACCURAT_THROTTLE_TIMER) - if ((timerState->sum/timerState->cnt)>=128) { // throttle was normalized to 0 to 128 value (throttle/64*2 (because - range is added as well) - newTimerVal++; // add second used of throttle - timerState->sum-=128*timerState->cnt; - } -#else - if ((timerState->sum/timerState->cnt)>=32) { // throttle was normalized to 0 to 32 value (throttle/16*2 (because - range is added as well) - newTimerVal++; // add second used of throttle - timerState->sum-=32*timerState->cnt; - } -#endif - timerState->cnt=0; - } - else if (tm == TMRMODE_THR_TRG) { - if (val || newTimerVal > 0) - newTimerVal++; - } - else { - if (tm > 0) tm -= (TMR_VAROFS-1); - if (getSwitch(tm)) - newTimerVal++; - } - - switch (timerState->state) { - case TMR_RUNNING: - if (tv && newTimerVal>=(int16_t)tv) { - AUDIO_TIMER_00(g_model.timers[i].countdownBeep); - timerState->state = TMR_NEGATIVE; - } - break; - case TMR_NEGATIVE: - if (newTimerVal >= (int16_t)tv + MAX_ALERT_TIME) timerState->state = TMR_STOPPED; - break; - } - - if (tv) newTimerVal = tv - newTimerVal; // if counting backwards - display backwards - - if (newTimerVal != timerState->val) { - timerState->val = newTimerVal; - if (timerState->state == TMR_RUNNING) { - if (g_model.timers[i].countdownBeep && g_model.timers[i].start) { - if (newTimerVal==30) AUDIO_TIMER_30(); - if (newTimerVal==20) AUDIO_TIMER_20(); - if (newTimerVal<=10) AUDIO_TIMER_LT10(g_model.timers[i].countdownBeep, newTimerVal); - } - if (g_model.timers[i].minuteBeep && (newTimerVal % 60)==0) { - AUDIO_TIMER_MINUTE(newTimerVal); - } - } - } - } - } - } //endfor timer loop (only two) - - static uint8_t s_cnt_100ms; - static uint8_t s_cnt_1s; - static uint8_t s_cnt_samples_thr_1s; - static uint16_t s_sum_samples_thr_1s; - - s_cnt_samples_thr_1s++; - s_sum_samples_thr_1s+=val; - - if ((s_cnt_100ms += tick10ms) >= 10) { // 0.1sec - s_cnt_100ms -= 10; - s_cnt_1s += 1; - - for (uint8_t i=0; ifunc == LS_FUNC_TIMER) { - int16_t *lastValue = &csLastValue[i]; - if (*lastValue == 0 || *lastValue == CS_LAST_VALUE_INIT) { - *lastValue = -cswTimerValue(cs->v1); - } - else if (*lastValue < 0) { - if (++(*lastValue) == 0) - *lastValue = cswTimerValue(cs->v2); - } - else { // if (*lastValue > 0) - *lastValue -= 1; - } - } - else if (cs->func == LS_FUNC_STICKY) { - PACK(typedef struct { - uint8_t state; - uint8_t last; - }) cs_sticky_struct; - cs_sticky_struct & lastValue = (cs_sticky_struct &)csLastValue[i]; - bool before = lastValue.last & 0x01; - if (lastValue.state) { - bool now = getSwitch(cs->v2); - if (now != before) { - lastValue.last ^= 1; - if (!before) { - lastValue.state = 0; - } - } - } - else { - bool now = getSwitch(cs->v1); - if (before != now) { - lastValue.last ^= 1; - if (!before) { - lastValue.state = 1; - } - } - } - } -#if defined(CPUARM) - else if (cs->func == LS_FUNC_STAY) { - PACK(typedef struct { - uint16_t state:1; - uint16_t duration:15; - }) cs_stay_struct; - - cs_stay_struct & lastValue = (cs_stay_struct &)csLastValue[i]; - lastValue.state = false; - bool state = getSwitch(cs->v1); - if (state) { - if (cs->v3 == 0 && lastValue.duration == cswTimerValue(cs->v2)) - lastValue.state = true; - if (lastValue.duration < 1000) - lastValue.duration++; - } - else { - if (lastValue.duration > cswTimerValue(cs->v2) && lastValue.duration <= cswTimerValue(cs->v2+cs->v3)) - lastValue.state = true; - lastValue.duration = 0; - } - } -#endif - } - - if (s_cnt_1s >= 10) { // 1sec - s_cnt_1s -= 10; - s_timeCumTot += 1; - - struct t_inactivity *ptrInactivity = &inactivity; - FORCE_INDIRECT(ptrInactivity) ; - ptrInactivity->counter++; - if ((((uint8_t)ptrInactivity->counter)&0x07)==0x01 && g_eeGeneral.inactivityTimer && g_vbat100mV>50 && ptrInactivity->counter > ((uint16_t)g_eeGeneral.inactivityTimer*60)) - AUDIO_INACTIVITY(); - -#if defined(AUDIO) - if (mixWarning & 1) if ((s_timeCumTot&0x03)==0) AUDIO_MIX_WARNING(1); - if (mixWarning & 2) if ((s_timeCumTot&0x03)==1) AUDIO_MIX_WARNING(2); - if (mixWarning & 4) if ((s_timeCumTot&0x03)==2) AUDIO_MIX_WARNING(3); -#endif - -#if defined(ACCURAT_THROTTLE_TIMER) - val = s_sum_samples_thr_1s / s_cnt_samples_thr_1s; - s_timeCum16ThrP += (val>>3); // s_timeCum16ThrP would overrun if we would store throttle value with higher accuracy; therefore stay with 16 steps - if (val) s_timeCumThr += 1; - s_sum_samples_thr_1s>>=2; // correct better accuracy now, because trace graph can show this information; in case thrtrace is not active, the compile should remove this -#else - val = s_sum_samples_thr_1s / s_cnt_samples_thr_1s; - s_timeCum16ThrP += (val>>1); - if (val) s_timeCumThr += 1; -#endif - -#if defined(THRTRACE) - // throttle trace is done every 10 seconds; Tracebuffer is adjusted to screen size. - // in case buffer runs out, it wraps around - // resolution for y axis is only 32, therefore no higher value makes sense - s_cnt_samples_thr_10s += s_cnt_samples_thr_1s; - s_sum_samples_thr_10s += s_sum_samples_thr_1s; - - if (++s_cnt_10s >= 10) { // 10s - s_cnt_10s -= 10; - val = s_sum_samples_thr_10s / s_cnt_samples_thr_10s; - s_sum_samples_thr_10s = 0; - s_cnt_samples_thr_10s = 0; - - s_traceBuf[s_traceWr++] = val; - if (s_traceWr >= MAXTRACE) s_traceWr = 0; - if (s_traceCnt >= 0) s_traceCnt++; - } -#endif - - s_cnt_samples_thr_1s = 0; - s_sum_samples_thr_1s = 0; - } - } - - if (s_fade_flight_phases) { + if (tick10ms && s_fade_flight_phases) { uint16_t tick_delta = delta * tick10ms; for (uint8_t p=0; p= 200) { - AUDIO_PLAY(AU_FRSKY_CHEEP); - count_dsm_range = 0; - } - } -#endif - -#if defined(PXX) - static uint8_t count_pxx = 0; - for (uint8_t i = 0; i < NUM_MODULES; i++) { - if (pxxFlag[i] & (PXX_SEND_RANGECHECK | PXX_SEND_RXNUM)) { - if (++count_pxx >= 250) { - AUDIO_PLAY(AU_FRSKY_CHEEP); - count_pxx = 0; - } - } - } -#endif - -#if defined(CPUARM) - return true; +#if defined(PCBGRUVIN9X) && defined(DEBUG) && !defined(VOICE) + PORTH &= ~0x40; // PORTH:6 HIGH->LOW signals end of mixer interrupt #endif } + +#if !defined(CPUM64) && !defined(ACCURAT_THROTTLE_TIMER) + // code cost is about 16 bytes for higher throttle accuracy for timer + // would not be noticable anyway, because all version up to this change had only 16 steps; + // now it has already 32 steps; this define would increase to 128 steps + #define ACCURAT_THROTTLE_TIMER +#endif + + diff --git a/radio/src/myeeprom.h b/radio/src/myeeprom.h index ac4328aca..fe9791771 100644 --- a/radio/src/myeeprom.h +++ b/radio/src/myeeprom.h @@ -524,9 +524,9 @@ PACK(typedef struct t_ExpoData { #define limit_min_max_t int16_t #define LIMIT_EXT_PERCENT 150 #define LIMIT_EXT_MAX (LIMIT_EXT_PERCENT*10) - #define LIMIT_MAX(lim) (GV_IS_GV_VALUE(lim->max, -LIMIT_EXT_MAX, LIMIT_EXT_MAX) ? GET_GVAR(lim->max, -LIMIT_EXT_MAX, LIMIT_EXT_MAX, s_perout_flight_mode)*10 : lim->max+1000) - #define LIMIT_MIN(lim) (GV_IS_GV_VALUE(lim->min, -LIMIT_EXT_MAX, LIMIT_EXT_MAX) ? GET_GVAR(lim->min, -LIMIT_EXT_MAX, LIMIT_EXT_MAX, s_perout_flight_mode)*10 : lim->min-1000) - #define LIMIT_OFS(lim) (GV_IS_GV_VALUE(lim->offset, -1000, 1000) ? GET_GVAR(lim->offset, -1000, 1000, s_perout_flight_mode)*10 : lim->offset) + #define LIMIT_MAX(lim) (GV_IS_GV_VALUE(lim->max, -LIMIT_EXT_MAX, LIMIT_EXT_MAX) ? GET_GVAR(lim->max, -LIMIT_EXT_MAX, LIMIT_EXT_MAX, s_current_mixer_flight_mode)*10 : lim->max+1000) + #define LIMIT_MIN(lim) (GV_IS_GV_VALUE(lim->min, -LIMIT_EXT_MAX, LIMIT_EXT_MAX) ? GET_GVAR(lim->min, -LIMIT_EXT_MAX, LIMIT_EXT_MAX, s_current_mixer_flight_mode)*10 : lim->min-1000) + #define LIMIT_OFS(lim) (GV_IS_GV_VALUE(lim->offset, -1000, 1000) ? GET_GVAR(lim->offset, -1000, 1000, s_current_mixer_flight_mode)*10 : lim->offset) #define LIMIT_MAX_RESX(lim) calc1000toRESX(LIMIT_MAX(lim)) #define LIMIT_MIN_RESX(lim) calc1000toRESX(LIMIT_MIN(lim)) #define LIMIT_OFS_RESX(lim) calc1000toRESX(LIMIT_OFS(lim)) diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index 6066433ed..29c6b1e2b 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -241,7 +241,7 @@ void per10ms() telemetryInterrupt10ms(); #endif - // These moved here from perOut() to improve beep trigger reliability. + // These moved here from evalFlightModeMixes() to improve beep trigger reliability. #if defined(PWM_BACKLIGHT) if ((g_tmr10ms&0x03) == 0x00) backlightFade(); // increment or decrement brightness until target brightness is reached @@ -574,7 +574,7 @@ uint8_t getTrimFlightPhase(uint8_t phase, uint8_t idx) #if defined(ROTARY_ENCODERS) uint8_t getRotaryEncoderFlightPhase(uint8_t idx) { - uint8_t phase = s_perout_flight_mode; + uint8_t phase = s_current_mixer_flight_mode; for (uint8_t i=0; i 2 @@ -1054,7 +1054,7 @@ void checkAll() clearKeyEvents(); - SKIP_AUTOMATIC_PROMPTS(); + START_SILENCE_PERIOD(); } #if defined(MODULE_ALWAYS_SEND_PULSES) @@ -1232,13 +1232,13 @@ uint8_t checkTrim(uint8_t event) #if defined(PCBSTD) phase = 0; #else - phase = getGVarFlightPhase(s_perout_flight_mode, trimGvar[idx]); + phase = getGVarFlightPhase(s_current_mixer_flight_mode, trimGvar[idx]); #endif before = GVAR_VALUE(trimGvar[idx], phase); thro = false; } else { - phase = getTrimFlightPhase(s_perout_flight_mode, idx); + phase = getTrimFlightPhase(s_current_mixer_flight_mode, idx); #if defined(PCBTARANIS) before = getTrimValue(phase, idx); #else @@ -1247,7 +1247,7 @@ uint8_t checkTrim(uint8_t event) thro = (idx==THR_STICK && g_model.thrTrim); } #else - phase = getTrimFlightPhase(s_perout_flight_mode, idx); + phase = getTrimFlightPhase(s_current_mixer_flight_mode, idx); #if defined(PCBTARANIS) before = getTrimValue(phase, idx); #else @@ -1585,7 +1585,7 @@ void resetAll() s_last_switch_value = 0; s_mixer_first_run_done = false; - SKIP_AUTOMATIC_PROMPTS(); + START_SILENCE_PERIOD(); RESET_THR_TRACE(); } @@ -1603,7 +1603,7 @@ uint16_t s_sum_samples_thr_10s; FORCEINLINE void evalTrims() { - uint8_t phase = s_perout_flight_mode; + uint8_t phase = s_current_mixer_flight_mode; for (uint8_t i=0; i throttle trim if applicable int16_t trim = getTrimValue(phase, i); @@ -1803,10 +1803,6 @@ inline void playCustomFunctionFile(CustomFnData *sd, uint8_t id) } #endif -#if defined(CPUARM) -bool evalFunctionsFirstTime = true; -#endif - void evalFunctions() { MASK_FUNC_TYPE newActiveFunctions = 0; @@ -1912,14 +1908,14 @@ void evalFunctions() #if defined(GVARS) case FUNC_ADJUST_GVAR: if (CFN_GVAR_MODE(sd) == 0) { - SET_GVAR(CFN_GVAR_INDEX(sd), CFN_PARAM(sd), s_perout_flight_mode); + SET_GVAR(CFN_GVAR_INDEX(sd), CFN_PARAM(sd), s_current_mixer_flight_mode); } else if (CFN_GVAR_MODE(sd) == 2) { - SET_GVAR(CFN_GVAR_INDEX(sd), GVAR_VALUE(CFN_PARAM(sd), s_perout_flight_mode), s_perout_flight_mode); + SET_GVAR(CFN_GVAR_INDEX(sd), GVAR_VALUE(CFN_PARAM(sd), s_current_mixer_flight_mode), s_current_mixer_flight_mode); } else if (CFN_GVAR_MODE(sd) == 3) { if (!(activeFnSwitches & switch_mask)) { - SET_GVAR(CFN_GVAR_INDEX(sd), GVAR_VALUE(CFN_GVAR_INDEX(sd), getGVarFlightPhase(s_perout_flight_mode, CFN_GVAR_INDEX(sd))) + (CFN_PARAM(sd) ? +1 : -1), s_perout_flight_mode); + SET_GVAR(CFN_GVAR_INDEX(sd), GVAR_VALUE(CFN_GVAR_INDEX(sd), getGVarFlightPhase(s_current_mixer_flight_mode, CFN_GVAR_INDEX(sd))) + (CFN_PARAM(sd) ? +1 : -1), s_current_mixer_flight_mode); } } else if (CFN_PARAM(sd) >= MIXSRC_TrimRud && CFN_PARAM(sd) <= MIXSRC_TrimAil) { @@ -1929,12 +1925,12 @@ void evalFunctions() 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(s_perout_flight_mode, CFN_GVAR_INDEX(sd))) + scroll, s_perout_flight_mode); + SET_GVAR(CFN_GVAR_INDEX(sd), GVAR_VALUE(CFN_GVAR_INDEX(sd), getGVarFlightPhase(s_current_mixer_flight_mode, CFN_GVAR_INDEX(sd))) + scroll, s_current_mixer_flight_mode); } } #endif else { - SET_GVAR(CFN_GVAR_INDEX(sd), limit((getvalue_t)-LIMIT_EXT_MAX, getValue(CFN_PARAM(sd)), (getvalue_t)LIMIT_EXT_MAX) / 10, s_perout_flight_mode); + SET_GVAR(CFN_GVAR_INDEX(sd), limit((getvalue_t)-LIMIT_EXT_MAX, getValue(CFN_PARAM(sd)), (getvalue_t)LIMIT_EXT_MAX) / 10, s_current_mixer_flight_mode); } break; #endif @@ -1962,7 +1958,7 @@ void evalFunctions() { tmr10ms_t tmr10ms = get_tmr10ms(); uint8_t repeatParam = CFN_PLAY_REPEAT(sd); - if (evalFunctionsFirstTime && repeatParam == CFN_PLAY_REPEAT_NOSTART) + 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)) { @@ -2017,7 +2013,7 @@ void evalFunctions() else { #if defined(GVARS) if (CFN_FUNC(sd) == FUNC_PLAY_TRACK && param > 250) - param = GVAR_VALUE(param-251, getGVarFlightPhase(s_perout_flight_mode, param-251)); + param = GVAR_VALUE(param-251, getGVarFlightPhase(s_current_mixer_flight_mode, param-251)); #endif PUSH_CUSTOM_PROMPT(active ? param : param+1, i+1); } @@ -2086,12 +2082,351 @@ void evalFunctions() rePreviousValues[i] = (g_rotenc[i] / ROTARY_ENCODER_GRANULARITY); } #endif - -#if defined(CPUARM) - evalFunctionsFirstTime = false; -#endif } +uint8_t s_mixer_first_run_done = false; + +void doMixerCalculations() +{ + static tmr10ms_t lastTMR = 0; + + tmr10ms_t tmr10ms = get_tmr10ms(); + uint8_t tick10ms = (tmr10ms >= lastTMR ? tmr10ms - lastTMR : 1); + // handle tick10ms overrun + // correct overflow handling costs a lot of code; happens only each 11 min; + // therefore forget the exact calculation and use only 1 instead; good compromise + +#if !defined(CPUARM) + lastTMR = tmr10ms; +#endif + + getADC(); + + getSwitchesPosition(!s_mixer_first_run_done); + +#if defined(CPUARM) + lastTMR = tmr10ms; +#endif + +#if defined(PCBSKY9X) && !defined(REVA) && !defined(SIMU) + Current_analogue = (Current_analogue*31 + s_anaFilt[8] ) >> 5 ; + if (Current_analogue > Current_max) + Current_max = Current_analogue ; +#elif defined(CPUM2560) && !defined(SIMU) + // For PCB V4, use our own 1.2V, external reference (connected to ADC3) + ADCSRB &= ~(1< NUM_POTS) { + uint8_t ch = g_model.thrTraceSrc-NUM_POTS-1; + val = channelOutputs[ch]; + + LimitData *lim = limitAddress(ch); + int16_t gModelMax = LIMIT_MAX_RESX(lim); + int16_t gModelMin = LIMIT_MIN_RESX(lim); + + if (lim->revert) + val = -val + gModelMax; + else + val = val - gModelMin; + +#if defined(PPM_LIMITS_SYMETRICAL) + if (lim->symetrical) + val -= calc1000toRESX(lim->offset); +#endif + + + gModelMax -= gModelMin; // we compare difference between Max and Mix for recaling needed; Max and Min are shifted to 0 by default + // usually max is 1024 min is -1024 --> max-min = 2048 full range + +#ifdef ACCURAT_THROTTLE_TIMER + if (gModelMax!=0 && gModelMax!=2048) val = (int32_t) (val << 11) / (gModelMax); // rescaling only needed if Min, Max differs +#else + // @@@ open.20.fsguruh optimized calculation; now *8 /8 instead of 10 base; (*16/16 already cause a overrun; unsigned calculation also not possible, because v may be negative) + gModelMax+=255; // force rounding up --> gModelMax is bigger --> val is smaller + gModelMax >>= (10-2); + + if (gModelMax!=0 && gModelMax!=8) { + val = (val << 3) / gModelMax; // rescaling only needed if Min, Max differs + } +#endif + + if (val<0) val=0; // prevent val be negative, which would corrupt throttle trace and timers; could occur if safetyswitch is smaller than limits + } + else { +#ifdef PCBTARANIS + val = RESX + calibratedStick[g_model.thrTraceSrc == 0 ? THR_STICK : g_model.thrTraceSrc+NUM_STICKS-1]; +#else + val = RESX + rawAnas[g_model.thrTraceSrc == 0 ? THR_STICK : g_model.thrTraceSrc+NUM_STICKS-1]; +#endif + } + +#if defined(ACCURAT_THROTTLE_TIMER) + val >>= (RESX_SHIFT-6); // calibrate it (resolution increased by factor 4) +#else + val >>= (RESX_SHIFT-4); // calibrate it +#endif + + // Timers start + for (uint8_t i=0; istate == TMR_OFF) { + timerState->state = TMR_RUNNING; + timerState->cnt = 0; + timerState->sum = 0; + } + + // value for time described in timer->mode + // OFFABSTHsTH%THt + if (tm == TMRMODE_THR_REL) { + timerState->cnt++; + timerState->sum+=val; + } + + if ((timerState->val_10ms += tick10ms) >= 100) { + timerState->val_10ms -= 100 ; + int16_t newTimerVal = timerState->val; + if (tv) newTimerVal = tv - newTimerVal; + + if (tm == TMRMODE_ABS) { + newTimerVal++; + } + else if (tm == TMRMODE_THR) { + if (val) newTimerVal++; + } + else if (tm == TMRMODE_THR_REL) { + // @@@ open.20.fsguruh: why so complicated? we have already a s_sum field; use it for the half seconds (not showable) as well + // check for s_cnt[i]==0 is not needed because we are shure it is at least 1 +#if defined(ACCURAT_THROTTLE_TIMER) + if ((timerState->sum/timerState->cnt)>=128) { // throttle was normalized to 0 to 128 value (throttle/64*2 (because - range is added as well) + newTimerVal++; // add second used of throttle + timerState->sum-=128*timerState->cnt; + } +#else + if ((timerState->sum/timerState->cnt)>=32) { // throttle was normalized to 0 to 32 value (throttle/16*2 (because - range is added as well) + newTimerVal++; // add second used of throttle + timerState->sum-=32*timerState->cnt; + } +#endif + timerState->cnt=0; + } + else if (tm == TMRMODE_THR_TRG) { + if (val || newTimerVal > 0) + newTimerVal++; + } + else { + if (tm > 0) tm -= (TMR_VAROFS-1); + if (getSwitch(tm)) + newTimerVal++; + } + + switch (timerState->state) { + case TMR_RUNNING: + if (tv && newTimerVal>=(int16_t)tv) { + AUDIO_TIMER_00(g_model.timers[i].countdownBeep); + timerState->state = TMR_NEGATIVE; + } + break; + case TMR_NEGATIVE: + if (newTimerVal >= (int16_t)tv + MAX_ALERT_TIME) timerState->state = TMR_STOPPED; + break; + } + + if (tv) newTimerVal = tv - newTimerVal; // if counting backwards - display backwards + + if (newTimerVal != timerState->val) { + timerState->val = newTimerVal; + if (timerState->state == TMR_RUNNING) { + if (g_model.timers[i].countdownBeep && g_model.timers[i].start) { + if (newTimerVal==30) AUDIO_TIMER_30(); + if (newTimerVal==20) AUDIO_TIMER_20(); + if (newTimerVal<=10) AUDIO_TIMER_LT10(g_model.timers[i].countdownBeep, newTimerVal); + } + if (g_model.timers[i].minuteBeep && (newTimerVal % 60)==0) { + AUDIO_TIMER_MINUTE(newTimerVal); + } + } + } + } + } + } //endfor timer loop (only two) + + static uint8_t s_cnt_100ms; + static uint8_t s_cnt_1s; + static uint8_t s_cnt_samples_thr_1s; + static uint16_t s_sum_samples_thr_1s; + + s_cnt_samples_thr_1s++; + s_sum_samples_thr_1s+=val; + + if ((s_cnt_100ms += tick10ms) >= 10) { // 0.1sec + s_cnt_100ms -= 10; + s_cnt_1s += 1; + + for (uint8_t i=0; ifunc == LS_FUNC_TIMER) { + int16_t *lastValue = &csLastValue[i]; + if (*lastValue == 0 || *lastValue == CS_LAST_VALUE_INIT) { + *lastValue = -cswTimerValue(cs->v1); + } + else if (*lastValue < 0) { + if (++(*lastValue) == 0) + *lastValue = cswTimerValue(cs->v2); + } + else { // if (*lastValue > 0) + *lastValue -= 1; + } + } + else if (cs->func == LS_FUNC_STICKY) { + PACK(typedef struct { + uint8_t state; + uint8_t last; + }) cs_sticky_struct; + cs_sticky_struct & lastValue = (cs_sticky_struct &)csLastValue[i]; + bool before = lastValue.last & 0x01; + if (lastValue.state) { + bool now = getSwitch(cs->v2); + if (now != before) { + lastValue.last ^= 1; + if (!before) { + lastValue.state = 0; + } + } + } + else { + bool now = getSwitch(cs->v1); + if (before != now) { + lastValue.last ^= 1; + if (!before) { + lastValue.state = 1; + } + } + } + } +#if defined(CPUARM) + else if (cs->func == LS_FUNC_STAY) { + PACK(typedef struct { + uint16_t state:1; + uint16_t duration:15; + }) cs_stay_struct; + + cs_stay_struct & lastValue = (cs_stay_struct &)csLastValue[i]; + lastValue.state = false; + bool state = getSwitch(cs->v1); + if (state) { + if (cs->v3 == 0 && lastValue.duration == cswTimerValue(cs->v2)) + lastValue.state = true; + if (lastValue.duration < 1000) + lastValue.duration++; + } + else { + if (lastValue.duration > cswTimerValue(cs->v2) && lastValue.duration <= cswTimerValue(cs->v2+cs->v3)) + lastValue.state = true; + lastValue.duration = 0; + } + } +#endif + } + + if (s_cnt_1s >= 10) { // 1sec + s_cnt_1s -= 10; + s_timeCumTot += 1; + + struct t_inactivity *ptrInactivity = &inactivity; + FORCE_INDIRECT(ptrInactivity) ; + ptrInactivity->counter++; + if ((((uint8_t)ptrInactivity->counter)&0x07)==0x01 && g_eeGeneral.inactivityTimer && g_vbat100mV>50 && ptrInactivity->counter > ((uint16_t)g_eeGeneral.inactivityTimer*60)) + AUDIO_INACTIVITY(); + +#if defined(AUDIO) + if (mixWarning & 1) if ((s_timeCumTot&0x03)==0) AUDIO_MIX_WARNING(1); + if (mixWarning & 2) if ((s_timeCumTot&0x03)==1) AUDIO_MIX_WARNING(2); + if (mixWarning & 4) if ((s_timeCumTot&0x03)==2) AUDIO_MIX_WARNING(3); +#endif + +#if defined(ACCURAT_THROTTLE_TIMER) + val = s_sum_samples_thr_1s / s_cnt_samples_thr_1s; + s_timeCum16ThrP += (val>>3); // s_timeCum16ThrP would overrun if we would store throttle value with higher accuracy; therefore stay with 16 steps + if (val) s_timeCumThr += 1; + s_sum_samples_thr_1s>>=2; // correct better accuracy now, because trace graph can show this information; in case thrtrace is not active, the compile should remove this +#else + val = s_sum_samples_thr_1s / s_cnt_samples_thr_1s; + s_timeCum16ThrP += (val>>1); + if (val) s_timeCumThr += 1; +#endif + +#if defined(THRTRACE) + // throttle trace is done every 10 seconds; Tracebuffer is adjusted to screen size. + // in case buffer runs out, it wraps around + // resolution for y axis is only 32, therefore no higher value makes sense + s_cnt_samples_thr_10s += s_cnt_samples_thr_1s; + s_sum_samples_thr_10s += s_sum_samples_thr_1s; + + if (++s_cnt_10s >= 10) { // 10s + s_cnt_10s -= 10; + val = s_sum_samples_thr_10s / s_cnt_samples_thr_10s; + s_sum_samples_thr_10s = 0; + s_cnt_samples_thr_10s = 0; + + s_traceBuf[s_traceWr++] = val; + if (s_traceWr >= MAXTRACE) s_traceWr = 0; + if (s_traceCnt >= 0) s_traceCnt++; + } +#endif + + s_cnt_samples_thr_1s = 0; + s_sum_samples_thr_1s = 0; + } + } + +#if defined(DSM2) + static uint8_t count_dsm_range = 0; + if (dsm2Flag & (DSM2_BIND_FLAG | DSM2_RANGECHECK_FLAG)) { + if (++count_dsm_range >= 200) { + AUDIO_PLAY(AU_FRSKY_CHEEP); + count_dsm_range = 0; + } + } +#endif + +#if defined(PXX) + static uint8_t count_pxx = 0; + for (uint8_t i = 0; i < NUM_MODULES; i++) { + if (pxxFlag[i] & (PXX_SEND_RANGECHECK | PXX_SEND_RXNUM)) { + if (++count_pxx >= 250) { + AUDIO_PLAY(AU_FRSKY_CHEEP); + count_pxx = 0; + } + } + } +#endif + +#if defined(CPUARM) + checkTrims(); +#endif + } + + s_mixer_first_run_done = true; +} #define TIME_TO_WRITE() (s_eeDirtyMsk && (tmr10ms_t)(get_tmr10ms() - s_eeDirtyTime10ms) >= (tmr10ms_t)WRITE_DELAY_10MS) @@ -2739,7 +3074,7 @@ void instantTrim() for (uint8_t i=0; i(TRIM_EXTENDED_MIN, (calibratedStick[i] + trims[i]) / 2, TRIM_EXTENDED_MAX); #else @@ -2757,7 +3092,7 @@ void copyTrimsToOffset(uint8_t ch) { pauseMixerCalculations(); int32_t zero = (int32_t)channelOutputs[ch]; - perOut(e_perout_mode_nosticks+e_perout_mode_notrainer, 0); + evalFlightModeMixes(e_perout_mode_nosticks+e_perout_mode_notrainer, 0); int32_t val = chans[ch]; LimitData *ld = limitAddress(ch); limit_min_max_t lim = LIMIT_MAX(ld); @@ -2781,12 +3116,12 @@ void moveTrimsToOffsets() // copy state of 3 primary to subtrim pauseMixerCalculations(); - perOut(e_perout_mode_noinput, 0); // do output loop - zero input sticks and trims + evalFlightModeMixes(e_perout_mode_noinput, 0); // do output loop - zero input sticks and trims for (uint8_t i=0; i= SWSRC_FIRST_FLIGHT_MODE) { uint8_t idx = cs_idx - SWSRC_FIRST_FLIGHT_MODE; - result = (idx == s_perout_flight_mode); + result = (idx == s_current_mixer_flight_mode); } #endif else { @@ -489,7 +489,7 @@ void checkSwitches() } uint8_t potMode = g_model.nPotsToWarn >> 6; if (potMode) { - perOut(e_perout_mode_normal, 0); + evalFlightModeMixes(e_perout_mode_normal, 0); bad_pots = 0; for (uint8_t i=0; i> 4)) > 1)) {