Mixer code splitted differently
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
+1
-1
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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<MAX_TIMERS; i++) {
|
||||
if (g_model.timers[i].persistent) {
|
||||
|
||||
@@ -974,9 +974,6 @@ void eeLoadModel(uint8_t id)
|
||||
activeFnSwitches = 0;
|
||||
activeFunctions = 0;
|
||||
memclear(lastFunctionTime, sizeof(lastFunctionTime));
|
||||
#if defined(CPUARM)
|
||||
evalFunctionsFirstTime = true;
|
||||
#endif
|
||||
|
||||
#if !defined(PCBSTD)
|
||||
for (uint8_t i=0; i<MAX_TIMERS; i++) {
|
||||
|
||||
+24
-24
@@ -371,15 +371,15 @@ TEST(Mixer, R2029Comment)
|
||||
g_model.mixData[1].weight = 100;
|
||||
anaInValues[THR_STICK] = 1024;
|
||||
simuSetSwitch(0, 1);
|
||||
perOut(e_perout_mode_normal, 0);
|
||||
evalFlightModeMixes(e_perout_mode_normal, 0);
|
||||
EXPECT_EQ(chans[0], 0);
|
||||
EXPECT_EQ(chans[1], CHANNEL_MAX);
|
||||
simuSetSwitch(0, 0);
|
||||
perOut(e_perout_mode_normal, 0);
|
||||
evalFlightModeMixes(e_perout_mode_normal, 0);
|
||||
EXPECT_EQ(chans[0], 0);
|
||||
EXPECT_EQ(chans[1], 0);
|
||||
simuSetSwitch(0, 1);
|
||||
perOut(e_perout_mode_normal, 0);
|
||||
evalFlightModeMixes(e_perout_mode_normal, 0);
|
||||
EXPECT_EQ(chans[0], 0);
|
||||
EXPECT_EQ(chans[1], CHANNEL_MAX);
|
||||
}
|
||||
@@ -398,7 +398,7 @@ TEST(Mixer, Cascaded3Channels)
|
||||
g_model.mixData[2].srcRaw = MIXSRC_THR;
|
||||
g_model.mixData[2].weight = 100;
|
||||
simuSetSwitch(0, 1);
|
||||
perOut(e_perout_mode_normal, 0);
|
||||
evalFlightModeMixes(e_perout_mode_normal, 0);
|
||||
EXPECT_EQ(chans[0], CHANNEL_MAX);
|
||||
EXPECT_EQ(chans[1], CHANNEL_MAX);
|
||||
EXPECT_EQ(chans[2], CHANNEL_MAX);
|
||||
@@ -415,7 +415,7 @@ TEST(Mixer, CascadedOrderedChannels)
|
||||
g_model.mixData[1].srcRaw = MIXSRC_CH1;
|
||||
g_model.mixData[1].weight = 100;
|
||||
simuSetSwitch(0, 1);
|
||||
perOut(e_perout_mode_normal, 0);
|
||||
evalFlightModeMixes(e_perout_mode_normal, 0);
|
||||
EXPECT_EQ(chans[0], CHANNEL_MAX);
|
||||
EXPECT_EQ(chans[1], CHANNEL_MAX);
|
||||
}
|
||||
@@ -471,7 +471,7 @@ TEST(Mixer, InfiniteRecursiveChannels)
|
||||
g_model.mixData[2].destCh = 2;
|
||||
g_model.mixData[2].srcRaw = MIXSRC_CH1;
|
||||
g_model.mixData[2].weight = 100;
|
||||
perOut(e_perout_mode_normal, 0);
|
||||
evalFlightModeMixes(e_perout_mode_normal, 0);
|
||||
EXPECT_EQ(chans[2], 0);
|
||||
EXPECT_EQ(chans[1], 0);
|
||||
EXPECT_EQ(chans[0], 0);
|
||||
@@ -484,7 +484,7 @@ TEST(Mixer, BlockingChannel)
|
||||
g_model.mixData[0].destCh = 0;
|
||||
g_model.mixData[0].srcRaw = MIXSRC_CH1;
|
||||
g_model.mixData[0].weight = 100;
|
||||
perOut(e_perout_mode_normal, 0);
|
||||
evalFlightModeMixes(e_perout_mode_normal, 0);
|
||||
EXPECT_EQ(chans[0], 0);
|
||||
}
|
||||
|
||||
@@ -503,7 +503,7 @@ TEST(Mixer, RecursiveAddChannel)
|
||||
g_model.mixData[2].destCh = 1;
|
||||
g_model.mixData[2].srcRaw = MIXSRC_Rud;
|
||||
g_model.mixData[2].weight = 100;
|
||||
perOut(e_perout_mode_normal, 0);
|
||||
evalFlightModeMixes(e_perout_mode_normal, 0);
|
||||
EXPECT_EQ(chans[0], CHANNEL_MAX/2);
|
||||
EXPECT_EQ(chans[1], 0);
|
||||
}
|
||||
@@ -538,14 +538,14 @@ TEST(Mixer, RecursiveAddChannelAfterInactivePhase)
|
||||
|
||||
#define CHECK_NO_MOVEMENT(channel, value, duration) \
|
||||
for (int i=1; i<=(duration); i++) { \
|
||||
perOut(e_perout_mode_normal, 1); \
|
||||
evalFlightModeMixes(e_perout_mode_normal, 1); \
|
||||
EXPECT_EQ(chans[(channel)], (value)); \
|
||||
}
|
||||
|
||||
#define CHECK_SLOW_MOVEMENT(channel, sign, duration) \
|
||||
do { \
|
||||
for (int i=1; i<=(duration); i++) { \
|
||||
perOut(e_perout_mode_normal, 1); \
|
||||
evalFlightModeMixes(e_perout_mode_normal, 1); \
|
||||
lastAct = lastAct + (sign) * (1<<19)/500; /* 100 on ARM */ \
|
||||
EXPECT_EQ(chans[(channel)], 256 * (lastAct >> 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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
+34
-373
@@ -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<<s_perout_flight_mode))
|
||||
if (ed->phases & (1<<s_current_mixer_flight_mode))
|
||||
continue;
|
||||
if (getSwitch(ed->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<<MUX5);
|
||||
ADMUX = 0x03|ADC_VREF_TYPE; // Switch MUX to internal reference
|
||||
#elif defined(PCBSTD) && !defined(SIMU)
|
||||
ADMUX = 0x1E|ADC_VREF_TYPE; // Switch MUX to internal reference
|
||||
#endif
|
||||
|
||||
#define MAX_ACT 0xffff
|
||||
static uint16_t fp_act[MAX_FLIGHT_MODES] = {0};
|
||||
static uint16_t delta = 0;
|
||||
static ACTIVE_PHASES_TYPE s_fade_flight_phases = 0;
|
||||
@@ -994,8 +962,8 @@ MIX_FUNCTION_RESULT doMixerCalculations()
|
||||
for (uint8_t p=0; p<MAX_FLIGHT_MODES; p++) {
|
||||
s_last_switch_used = 0;
|
||||
if (s_fade_flight_phases & ((ACTIVE_PHASES_TYPE)1 << p)) {
|
||||
s_perout_flight_mode = p;
|
||||
perOut(p==phase ? e_perout_mode_normal : e_perout_mode_inactive_phase, p==phase ? tick10ms : 0);
|
||||
s_current_mixer_flight_mode = p;
|
||||
evalFlightModeMixes(p==phase ? e_perout_mode_normal : e_perout_mode_inactive_phase, p==phase ? tick10ms : 0);
|
||||
for (uint8_t i=0; i<NUM_CHNOUT; i++)
|
||||
sum_chans512[i] += (chans[i] >> 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; i<MAX_TIMERS; i++) {
|
||||
int8_t tm = g_model.timers[i].mode;
|
||||
uint16_t tv = g_model.timers[i].start;
|
||||
TimerState * timerState = &timersStates[i];
|
||||
|
||||
if (tm) {
|
||||
if (timerState->state == 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; i<NUM_LOGICAL_SWITCH; i++) {
|
||||
LogicalSwitchData * cs = cswAddress(i);
|
||||
if (cs->func == 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<MAX_FLIGHT_MODES; p++) {
|
||||
ACTIVE_PHASES_TYPE phaseMask = ((ACTIVE_PHASES_TYPE)1 << p);
|
||||
@@ -1361,29 +1035,16 @@ MIX_FUNCTION_RESULT doMixerCalculations()
|
||||
}
|
||||
} //endif s_fade_fligh_phases
|
||||
|
||||
#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)
|
||||
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
|
||||
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
+364
-30
@@ -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<MAX_FLIGHT_MODES; i++) {
|
||||
if (phase == 0) return 0;
|
||||
#if ROTARY_ENCODERS > 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<NUM_STICKS; i++) {
|
||||
// do trim -> 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<<MUX5);
|
||||
ADMUX = 0x03|ADC_VREF_TYPE; // Switch MUX to internal reference
|
||||
#elif defined(PCBSTD) && !defined(SIMU)
|
||||
ADMUX = 0x1E|ADC_VREF_TYPE; // Switch MUX to internal reference
|
||||
#endif
|
||||
|
||||
evalMixes(tick10ms);
|
||||
|
||||
#if !defined(CPUARM)
|
||||
// Bandgap has had plenty of time to settle...
|
||||
getADC_bandgap();
|
||||
#endif
|
||||
|
||||
if (tick10ms) {
|
||||
/* 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; i<MAX_TIMERS; i++) {
|
||||
int8_t tm = g_model.timers[i].mode;
|
||||
uint16_t tv = g_model.timers[i].start;
|
||||
TimerState * timerState = &timersStates[i];
|
||||
|
||||
if (tm) {
|
||||
if (timerState->state == 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; i<NUM_LOGICAL_SWITCH; i++) {
|
||||
LogicalSwitchData * cs = cswAddress(i);
|
||||
if (cs->func == 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<NUM_STICKS; i++) {
|
||||
if (i!=THR_STICK) {
|
||||
// don't instant trim the throttle stick
|
||||
uint8_t trim_phase = getTrimFlightPhase(s_perout_flight_mode, i);
|
||||
uint8_t trim_phase = getTrimFlightPhase(s_current_mixer_flight_mode, i);
|
||||
#if defined(PCBTARANIS)
|
||||
int16_t trim = limit<int16_t>(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<NUM_CHNOUT; i++) {
|
||||
zeros[i] = applyLimits(i, chans[i]);
|
||||
}
|
||||
|
||||
perOut(e_perout_mode_noinput-e_perout_mode_notrims, 0); // do output loop - only trims
|
||||
evalFlightModeMixes(e_perout_mode_noinput-e_perout_mode_notrims, 0); // do output loop - only trims
|
||||
|
||||
for (uint8_t i=0; i<NUM_CHNOUT; i++) {
|
||||
int16_t output = applyLimits(i, chans[i]) - zeros[i];
|
||||
@@ -2803,7 +3138,7 @@ void moveTrimsToOffsets() // copy state of 3 primary to subtrim
|
||||
// reset all trims, except throttle (if throttle trim)
|
||||
for (uint8_t i=0; i<NUM_STICKS; i++) {
|
||||
if (i!=THR_STICK || !g_model.thrTrim) {
|
||||
int16_t original_trim = getTrimValue(s_perout_flight_mode, i);
|
||||
int16_t original_trim = getTrimValue(s_current_mixer_flight_mode, i);
|
||||
for (uint8_t phase=0; phase<MAX_FLIGHT_MODES; phase++) {
|
||||
#if defined(PCBTARANIS)
|
||||
trim_t trim = getRawTrimValue(phase, i);
|
||||
@@ -3028,9 +3363,8 @@ void mixerTask(void * pdata)
|
||||
uint16_t t0 = getTmr2MHz();
|
||||
|
||||
CoEnterMutexSection(mixerMutex);
|
||||
bool tick10ms = doMixerCalculations();
|
||||
doMixerCalculations();
|
||||
CoLeaveMutexSection(mixerMutex);
|
||||
if (tick10ms) checkTrims();
|
||||
|
||||
#if defined(FRSKY) || defined(MAVLINK)
|
||||
telemetryWakeup();
|
||||
|
||||
+6
-16
@@ -653,7 +653,7 @@ enum StartupWarningStates {
|
||||
#define FORCE_INDIRECT(ptr) __asm__ __volatile__ ("" : "=e" (ptr) : "0" (ptr))
|
||||
#endif
|
||||
|
||||
extern uint8_t s_perout_flight_mode;
|
||||
extern uint8_t s_current_mixer_flight_mode;
|
||||
|
||||
#if defined(CPUARM)
|
||||
#define bitfield_channels_t uint32_t
|
||||
@@ -667,15 +667,9 @@ extern uint8_t s_perout_flight_mode;
|
||||
extern unsigned char *_estack;
|
||||
#endif
|
||||
|
||||
void perOut(uint8_t mode, uint8_t tick10ms);
|
||||
|
||||
#if defined(CPUARM)
|
||||
#define MIX_FUNCTION_RESULT bool
|
||||
#else
|
||||
#define MIX_FUNCTION_RESULT void
|
||||
#endif
|
||||
|
||||
MIX_FUNCTION_RESULT doMixerCalculations();
|
||||
void evalFlightModeMixes(uint8_t mode, uint8_t tick10ms);
|
||||
void evalMixes(uint8_t tick10ms);
|
||||
void doMixerCalculations();
|
||||
|
||||
void perMain();
|
||||
NOINLINE void per10ms();
|
||||
@@ -1106,7 +1100,7 @@ struct CurveInfo {
|
||||
extern CurveInfo curveInfo(uint8_t idx);
|
||||
#endif
|
||||
|
||||
// static variables used in perOut - moved here so they don't interfere with the stack
|
||||
// static variables used in evalFlightModeMixes - moved here so they don't interfere with the stack
|
||||
// It's also easier to initialize them here.
|
||||
#if defined(PCBTARANIS)
|
||||
extern int8_t virtualInputsTrims[NUM_INPUTS];
|
||||
@@ -1118,7 +1112,7 @@ extern int16_t anas [NUM_INPUTS];
|
||||
extern int16_t trims[NUM_STICKS];
|
||||
extern BeepANACenter bpanaCenter;
|
||||
|
||||
extern bool s_mixer_first_run_done;
|
||||
extern uint8_t s_mixer_first_run_done;
|
||||
|
||||
extern int8_t s_currCh;
|
||||
uint8_t getExpoMixCount(uint8_t expo);
|
||||
@@ -1225,10 +1219,6 @@ extern MASK_FUNC_TYPE activeFunctions;
|
||||
extern MASK_CFN_TYPE activeFnSwitches;
|
||||
extern tmr10ms_t lastFunctionTime[NUM_CFN];
|
||||
|
||||
#if defined(CPUARM)
|
||||
extern bool evalFunctionsFirstTime;
|
||||
#endif
|
||||
|
||||
inline bool isFunctionActive(uint8_t func)
|
||||
{
|
||||
return activeFunctions & ((uint8_t)1 << func);
|
||||
|
||||
@@ -212,7 +212,7 @@ bool getSwitch(int8_t swtch)
|
||||
#if defined(CPUARM) && defined(FLIGHT_MODES)
|
||||
else if (cs_idx >= 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<NUM_POTS; i++) {
|
||||
if (!(g_model.nPotsToWarn & (1 << i)) && (abs(g_model.potPosition[i] - (getValue(MIXSRC_FIRST_POT+i) >> 4)) > 1)) {
|
||||
|
||||
Reference in New Issue
Block a user