Backports: (#287)
- Remove module choice from special function set failsafe (backport #8156) - Fix mixer overflow (backport #7747) - Bars inverse (backport #7709) - Fix scale and telemetry fields (backport #7704) Cosmetics
This commit is contained in:
@@ -58,8 +58,11 @@ class SensorData {
|
||||
TELEM_CELL_INDEX_4,
|
||||
TELEM_CELL_INDEX_5,
|
||||
TELEM_CELL_INDEX_6,
|
||||
// TELEM_CELL_INDEX_7, // PCBI6X: uses RAM and I don't think someone will use 8S with i6X
|
||||
// TELEM_CELL_INDEX_8,
|
||||
TELEM_CELL_INDEX_HIGHEST,
|
||||
TELEM_CELL_INDEX_DELTA,
|
||||
TELEM_CELL_INDEX_LAST = TELEM_CELL_INDEX_DELTA
|
||||
};
|
||||
|
||||
enum
|
||||
|
||||
@@ -242,10 +242,10 @@ void menuModelDisplay(event_t event)
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
bar.barMin = checkIncDec(event, bar.barMin, barMin, bar.barMax, EE_MODEL|NO_INCDEC_MARKS);
|
||||
bar.barMin = checkIncDec(event, bar.barMin, barMin, barMax, EE_MODEL|NO_INCDEC_MARKS);
|
||||
break;
|
||||
case 2:
|
||||
bar.barMax = checkIncDec(event, bar.barMax, bar.barMin, barMax, EE_MODEL|NO_INCDEC_MARKS);
|
||||
bar.barMax = checkIncDec(event, bar.barMax, barMin, barMax, EE_MODEL|NO_INCDEC_MARKS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +83,8 @@ void menuModelFlightModeOne(event_t event)
|
||||
int8_t editMode = s_editMode;
|
||||
|
||||
#if defined(GVARS) && !defined(PCBSTD)
|
||||
if (s_currIdx == 0 && sub>=ITEM_MODEL_FLIGHT_MODE_SWITCH) sub += VERTICAL_SHIFT;
|
||||
if (s_currIdx == 0 && sub>=ITEM_MODEL_FLIGHT_MODE_SWITCH)
|
||||
sub += VERTICAL_SHIFT;
|
||||
|
||||
for (uint8_t k=0; k<LCD_LINES-1; k++) {
|
||||
coord_t y = MENU_HEADER_HEIGHT + 1 + k*FH;
|
||||
|
||||
@@ -118,7 +118,7 @@ void menuModelExpoOne(event_t event)
|
||||
|
||||
case EXPO_FIELD_SCALE:
|
||||
lcdDrawTextAlignedLeft(y, STR_SCALE);
|
||||
drawSensorCustomValue(EXPO_ONE_2ND_COLUMN, y, (ed->srcRaw - MIXSRC_FIRST_TELEM)/3, convertTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1, ed->scale), attr);
|
||||
drawSensorCustomValue(EXPO_ONE_2ND_COLUMN, y, (ed->srcRaw - MIXSRC_FIRST_TELEM)/3, convertTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1, ed->scale), RIGHT | attr);
|
||||
if (attr) ed->scale = checkIncDec(event, ed->scale, 0, maxTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1), EE_MODEL);
|
||||
break;
|
||||
|
||||
|
||||
@@ -428,7 +428,7 @@ void menuModelSetup(event_t event)
|
||||
break;
|
||||
case 2:
|
||||
qr.rem -= checkIncDecModel(event, qr.rem+2, 1, 62)-2;
|
||||
timer->start -= qr.rem ;
|
||||
timer->start -= qr.rem;
|
||||
if ((int16_t)timer->start < 0) timer->start=0;
|
||||
if ((int16_t)timer->start > 5999) timer->start=32399; // 8:59:59
|
||||
break;
|
||||
|
||||
@@ -291,10 +291,12 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
|
||||
lcdDrawNumber(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr|LEFT);
|
||||
}
|
||||
#endif // OVERRIDE_CHANNEL_FUNCTION
|
||||
else if (func >= FUNC_SET_FAILSAFE && func <= FUNC_BIND) {
|
||||
#if defined(DANGEROUS_MODULE_FUNCTIONS)
|
||||
else if (func >= FUNC_RANGECHECK && func <= FUNC_BIND) {
|
||||
val_max = NUM_MODULES-1;
|
||||
lcdDrawTextAtIndex(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, "\004Int.Ext.", CFN_PARAM(cfn), attr);
|
||||
}
|
||||
#endif
|
||||
else if (func == FUNC_SET_TIMER) {
|
||||
getMixSrcRange(MIXSRC_FIRST_TIMER, val_min, val_max);
|
||||
drawTimer(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr|LEFT, attr);
|
||||
|
||||
@@ -298,7 +298,7 @@ void menuModelSensor(event_t event)
|
||||
case SENSOR_FIELD_PARAM2:
|
||||
if (sensor->type == TELEM_TYPE_CALCULATED) {
|
||||
if (sensor->formula == TELEM_FORMULA_CELL) {
|
||||
sensor->cell.index = editChoice(SENSOR_2ND_COLUMN, y, STR_CELLINDEX, STR_VCELLINDEX, sensor->cell.index, 0, 8, attr, event);
|
||||
sensor->cell.index = editChoice(SENSOR_2ND_COLUMN, y, STR_CELLINDEX, STR_VCELLINDEX, sensor->cell.index, TELEM_CELL_INDEX_LOWEST, TELEM_CELL_INDEX_LAST, attr, event);
|
||||
break;
|
||||
}
|
||||
else if (sensor->formula == TELEM_FORMULA_DIST) {
|
||||
|
||||
@@ -71,27 +71,20 @@ bool displayGaugesTelemetryScreen(FrSkyScreenData & screen)
|
||||
barMin = calc100toRESX(barMin);
|
||||
barMax = calc100toRESX(barMax);
|
||||
}
|
||||
if (source && barMax > barMin) {
|
||||
if (source) {
|
||||
uint8_t y = barHeight+6+i*(barHeight+6);
|
||||
drawSource(0, y+barHeight/2-3, source, SMLSIZE);
|
||||
lcdDrawRect(BAR_LEFT, y, BAR_WIDTH+1, barHeight+2);
|
||||
getvalue_t value = getValue(source);
|
||||
|
||||
uint8_t thresholdX = 0;
|
||||
|
||||
|
||||
uint8_t width = barCoord(value, barMin, barMax);
|
||||
|
||||
uint8_t width = (barMin < barMax) ? barCoord(value, barMin, barMax) : 99 - barCoord(value, barMax, barMin);
|
||||
uint8_t barShade = SOLID;
|
||||
|
||||
lcdDrawFilledRect(BAR_LEFT+1, y+1, width, barHeight, barShade);
|
||||
|
||||
for (uint8_t j=24; j<99; j+=25) {
|
||||
if (j>thresholdX || j>width) {
|
||||
lcdDrawSolidVerticalLine(j*BAR_WIDTH/100+BAR_LEFT+1, y+1, barHeight);
|
||||
}
|
||||
}
|
||||
|
||||
if (thresholdX) {
|
||||
lcdDrawVerticalLine(BAR_LEFT+1+thresholdX, y-2, barHeight+3, DOTTED);
|
||||
lcdDrawSolidHorizontalLine(BAR_LEFT+thresholdX, y-2, 3);
|
||||
|
||||
@@ -245,10 +245,10 @@ void menuModelDisplay(event_t event)
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
bar.barMin = checkIncDec(event, bar.barMin, barMin, bar.barMax, EE_MODEL|NO_INCDEC_MARKS);
|
||||
bar.barMin = checkIncDec(event, bar.barMin, barMin, barMax, EE_MODEL|NO_INCDEC_MARKS);
|
||||
break;
|
||||
case 2:
|
||||
bar.barMax = checkIncDec(event, bar.barMax, bar.barMin, barMax, EE_MODEL|NO_INCDEC_MARKS);
|
||||
bar.barMax = checkIncDec(event, bar.barMax, barMin, barMax, EE_MODEL|NO_INCDEC_MARKS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -265,10 +265,12 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
|
||||
lcdDrawNumber(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr|LEFT);
|
||||
}
|
||||
#endif
|
||||
else if (func >= FUNC_SET_FAILSAFE && func <= FUNC_BIND) {
|
||||
#if defined(DANGEROUS_MODULE_FUNCTIONS)
|
||||
else if (func >= FUNC_RANGECHECK && func <= FUNC_BIND) {
|
||||
val_max = NUM_MODULES-1;
|
||||
lcdDrawTextAtIndex(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, "\004Int.Ext.", CFN_PARAM(cfn), attr);
|
||||
}
|
||||
#endif
|
||||
else if (func == FUNC_SET_TIMER) {
|
||||
getMixSrcRange(MIXSRC_FIRST_TIMER, val_min, val_max);
|
||||
drawTimer(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr|LEFT|TIMEHOUR, attr);
|
||||
|
||||
@@ -280,7 +280,7 @@ void menuModelSensor(event_t event)
|
||||
case SENSOR_FIELD_PARAM2:
|
||||
if (sensor->type == TELEM_TYPE_CALCULATED) {
|
||||
if (sensor->formula == TELEM_FORMULA_CELL) {
|
||||
sensor->cell.index = editChoice(SENSOR_2ND_COLUMN, y, STR_CELLINDEX, STR_VCELLINDEX, sensor->cell.index, 0, 8, attr, event);
|
||||
sensor->cell.index = editChoice(SENSOR_2ND_COLUMN, y, STR_CELLINDEX, STR_VCELLINDEX, sensor->cell.index, TELEM_CELL_INDEX_LOWEST, TELEM_CELL_INDEX_LAST, attr, event);
|
||||
break;
|
||||
}
|
||||
else if (sensor->formula == TELEM_FORMULA_DIST) {
|
||||
|
||||
@@ -67,14 +67,14 @@ void displayGaugesTelemetryScreen(FrSkyScreenData & screen)
|
||||
barMin = calc100toRESX(barMin);
|
||||
barMax = calc100toRESX(barMax);
|
||||
}
|
||||
if (source && barMax > barMin) {
|
||||
if (source) {
|
||||
int y = barHeight+6+i*(barHeight+6);
|
||||
drawSource(0, y+barHeight-5, source, 0);
|
||||
lcdDrawRect(BAR_LEFT, y, BAR_WIDTH+1, barHeight+2);
|
||||
getvalue_t value = getValue(source);
|
||||
drawSourceValue(BAR_LEFT+2+BAR_WIDTH, y+barHeight-5, source, LEFT);
|
||||
uint8_t thresholdX = 0;
|
||||
int width = barCoord(value, barMin, barMax);
|
||||
uint8_t width = (barMin < barMax) ? barCoord(value, barMin, barMax) : limit(0, 151 - barCoord(value, barMax, barMin), 151);
|
||||
uint8_t barShade = SOLID;
|
||||
lcdDrawFilledRect(BAR_LEFT+1, y+1, width, barHeight, barShade);
|
||||
for (uint8_t j=24; j<99; j+=25) {
|
||||
|
||||
@@ -243,7 +243,7 @@ bool menuModelExpoOne(event_t event)
|
||||
drawSource(EXPO_ONE_2ND_COLUMN, y, ed->srcRaw, menuHorizontalPosition==0 ? attr : 0);
|
||||
if (attr && menuHorizontalPosition==0) ed->srcRaw = checkIncDec(event, ed->srcRaw, INPUTSRC_FIRST, INPUTSRC_LAST, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isInputSourceAvailable);
|
||||
if (ed->srcRaw >= MIXSRC_FIRST_TELEM) {
|
||||
drawSensorCustomValue(EXPO_ONE_2ND_COLUMN+75, y, (ed->srcRaw - MIXSRC_FIRST_TELEM)/3, convertTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1, ed->scale), LEFT|(menuHorizontalPosition==1?attr:0));
|
||||
drawSensorCustomValue(EXPO_ONE_2ND_COLUMN+75, y, (ed->srcRaw - MIXSRC_FIRST_TELEM)/3, getValue(ed->srcRaw), LEFT|(menuHorizontalPosition==1?attr:0));
|
||||
if (attr && menuHorizontalPosition == 1) ed->scale = checkIncDec(event, ed->scale, 0, maxTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1), EE_MODEL);
|
||||
}
|
||||
else if (attr) {
|
||||
|
||||
@@ -285,7 +285,7 @@ bool menuModelSensor(event_t event)
|
||||
if (sensor->type == TELEM_TYPE_CALCULATED) {
|
||||
if (sensor->formula == TELEM_FORMULA_CELL) {
|
||||
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_CELLINDEX);
|
||||
sensor->cell.index = editChoice(SENSOR_2ND_COLUMN, y, STR_VCELLINDEX, sensor->cell.index, 0, 8, attr, event);
|
||||
sensor->cell.index = editChoice(SENSOR_2ND_COLUMN, y, STR_VCELLINDEX, sensor->cell.index, TELEM_CELL_INDEX_LOWEST, TELEM_CELL_INDEX_LAST, attr, event);
|
||||
break;
|
||||
}
|
||||
else if (sensor->formula == TELEM_FORMULA_DIST) {
|
||||
|
||||
@@ -49,14 +49,16 @@ void GaugeWidget::refresh()
|
||||
uint16_t color = persistentData->options[3].unsignedValue;
|
||||
|
||||
int32_t value = getValue(index);
|
||||
int32_t value_in_range = value;
|
||||
if (value < min)
|
||||
value_in_range = min;
|
||||
else if (value > max)
|
||||
value_in_range = max;
|
||||
|
||||
int w = divRoundClosest(zone.w * (value_in_range - min), (max - min));
|
||||
int percent = divRoundClosest(100 * (value_in_range - min), (max - min));
|
||||
if (min > max) {
|
||||
SWAP(min, max);
|
||||
value = value - min - max;
|
||||
}
|
||||
|
||||
value = limit(min, value, max);
|
||||
|
||||
int w = divRoundClosest(zone.w * (value - min), (max - min));
|
||||
int percent = divRoundClosest(100 * (value - min), (max - min));
|
||||
|
||||
// Gauge label
|
||||
drawSource(zone.x, zone.y, index, SMLSIZE | TEXT_INVERTED_COLOR);
|
||||
|
||||
+1
-1
@@ -951,7 +951,7 @@ void evalMixes(uint8_t tick10ms)
|
||||
mixerCurrentFlightMode = p;
|
||||
evalFlightModeMixes(p==fm ? e_perout_mode_normal : e_perout_mode_inactive_flight_mode, p==fm ? tick10ms : 0);
|
||||
for (uint8_t i=0; i<MAX_OUTPUT_CHANNELS; i++)
|
||||
sum_chans512[i] += (chans[i] >> 4) * fp_act[p];
|
||||
sum_chans512[i] += limit<int32_t>(-0x6fff, chans[i] >> 4, 0x6fff) * fp_act[p];
|
||||
weight += fp_act[p];
|
||||
}
|
||||
LS_RECURSIVE_EVALUATION_RESET();
|
||||
|
||||
@@ -1748,9 +1748,8 @@ volatile rotenc_t rotencValue[1] = {0};
|
||||
uint8_t rotencSpeed;
|
||||
#endif
|
||||
|
||||
#define OPENTX_INIT_ARGS
|
||||
|
||||
void opentxInit(OPENTX_INIT_ARGS) {
|
||||
void opentxInit()
|
||||
{
|
||||
TRACE("opentxInit");
|
||||
|
||||
#if defined(GUI)
|
||||
|
||||
@@ -125,8 +125,11 @@ enum {
|
||||
TELEM_CELL_INDEX_4,
|
||||
TELEM_CELL_INDEX_5,
|
||||
TELEM_CELL_INDEX_6,
|
||||
// TELEM_CELL_INDEX_7, // PCBI6X: uses more RAM and I don't think someone will use 8S with i6X
|
||||
// TELEM_CELL_INDEX_8,
|
||||
TELEM_CELL_INDEX_HIGHEST,
|
||||
TELEM_CELL_INDEX_DELTA,
|
||||
TELEM_CELL_INDEX_LAST = TELEM_CELL_INDEX_DELTA
|
||||
};
|
||||
|
||||
PACK(struct CellValue
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#define TELEMETRY_AVERAGE_COUNT 3 // we actually average one more reading!
|
||||
#define RAW_FRSKY_MINMAX(v) v.values[TELEMETRY_AVERAGE_COUNT-1]
|
||||
#define MAX_CELLS 6
|
||||
#define MAX_CELLS 6 // 8, PCBI6X, uses RAM and I don't think someone will use 8S with i6X
|
||||
|
||||
class TelemetryValueWithMin {
|
||||
public:
|
||||
|
||||
@@ -60,6 +60,7 @@ inline void MODEL_RESET()
|
||||
memset(&anaInValues, 0, sizeof(anaInValues));
|
||||
extern uint8_t s_mixer_first_run_done;
|
||||
s_mixer_first_run_done = false;
|
||||
evalMixes(1); // this is needed to reset fp_act
|
||||
lastFlightMode = 255;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,22 @@ class MixerTest : public OpenTxTest {};
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define CHECK_FLIGHT_MODE_TRANSITION(channel, duration, initValue, endValue) \
|
||||
do { \
|
||||
uint32_t delta = 0xffff / duration; \
|
||||
int32_t weightInit = 0xffff; \
|
||||
int32_t weightEnd = 0; \
|
||||
for (int i = 0; i <= (duration); i++) { \
|
||||
evalMixes(1); \
|
||||
GTEST_ASSERT_LE( abs(((initValue) * weightInit + (endValue) * weightEnd) / 0xffff - channelOutputs[(channel)]), 1); \
|
||||
weightInit = weightInit - delta; \
|
||||
weightEnd = weightEnd + delta; \
|
||||
} \
|
||||
for (int i = 0; i < 100; i++) { /* be sure the transition is finished*/ \
|
||||
evalMixes(1); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
TEST_F(TrimsTest, throttleTrim)
|
||||
{
|
||||
g_model.thrTrim = 1;
|
||||
@@ -660,3 +676,48 @@ TEST(Trainer, UnpluggedTest)
|
||||
ppmInput[0] = 1024;
|
||||
CHECK_DELAY(0, 5000);
|
||||
}
|
||||
|
||||
TEST_F(MixerTest, flightModeTransition)
|
||||
{
|
||||
SYSTEM_RESET();
|
||||
MODEL_RESET();
|
||||
MIXER_RESET();
|
||||
modelDefault(0);
|
||||
g_model.flightModeData[1].swtch = TR(SWSRC_ID2, SWSRC_SA2);
|
||||
g_model.flightModeData[0].fadeIn = 100;
|
||||
g_model.flightModeData[0].fadeOut = 100;
|
||||
g_model.flightModeData[1].fadeIn = 100;
|
||||
g_model.flightModeData[1].fadeOut = 100;
|
||||
g_model.mixData[0].destCh = 0;
|
||||
g_model.mixData[0].mltpx = MLTPX_REP;
|
||||
g_model.mixData[0].srcRaw = MIXSRC_MAX;
|
||||
g_model.mixData[0].flightModes = 0b11110;
|
||||
g_model.mixData[0].weight = 100;
|
||||
g_model.mixData[1].destCh = 0;
|
||||
g_model.mixData[1].mltpx = MLTPX_REP;
|
||||
g_model.mixData[1].srcRaw = MIXSRC_MAX;
|
||||
g_model.mixData[1].flightModes = 0b11101;
|
||||
g_model.mixData[1].weight = -10;
|
||||
evalMixes(1);
|
||||
simuSetSwitch(0, 1);
|
||||
CHECK_FLIGHT_MODE_TRANSITION(0, 1000, 1024, -102);
|
||||
}
|
||||
|
||||
TEST_F(MixerTest, flightModeOverflow)
|
||||
{
|
||||
SYSTEM_RESET();
|
||||
MODEL_RESET();
|
||||
MIXER_RESET();
|
||||
modelDefault(0);
|
||||
g_model.flightModeData[1].swtch = TR(SWSRC_ID2, SWSRC_SA2);
|
||||
g_model.flightModeData[0].fadeIn = 100;
|
||||
g_model.flightModeData[0].fadeOut = 100;
|
||||
g_model.mixData[0].destCh = 0;
|
||||
g_model.mixData[0].mltpx = MLTPX_REP;
|
||||
g_model.mixData[0].srcRaw = MIXSRC_MAX;
|
||||
g_model.mixData[0].flightModes = 0;
|
||||
g_model.mixData[0].weight = 250;
|
||||
evalMixes(1);
|
||||
simuSetSwitch(0, 1);
|
||||
CHECK_FLIGHT_MODE_TRANSITION(0, 1000, 1024, 1024);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user