diff --git a/companion/src/eeprominterface.cpp b/companion/src/eeprominterface.cpp index 9b5126780..ba52bd55f 100644 --- a/companion/src/eeprominterface.cpp +++ b/companion/src/eeprominterface.cpp @@ -536,17 +536,57 @@ void ModelData::setDefault(uint8_t id) sprintf(name, "MODEL%02d", id+1); } -unsigned int ModelData::getTrimFlightPhase(uint8_t idx, int8_t phase) +int ModelData::getTrimValue(int phaseIdx, int trimIdx) { - // if (phase == -1) phase = getFlightPhase(); - - for (uint8_t i=0; i 500) + trim = 500; + break; + } + } +} + void ModelData::removeGlobalVar(int & var) { if (var >= 126 && var <= 130) diff --git a/companion/src/eeprominterface.h b/companion/src/eeprominterface.h index 38b713c24..b7715251b 100644 --- a/companion/src/eeprominterface.h +++ b/companion/src/eeprominterface.h @@ -680,7 +680,8 @@ class FuncSwData { // Function Switches data class PhaseData { public: PhaseData() { clear(); } - int trimRef[NUM_STICKS]; // + int trimMode[NUM_STICKS]; + int trimRef[NUM_STICKS]; int trim[NUM_STICKS]; RawSwitch swtch; char name[10+1]; @@ -688,7 +689,7 @@ class PhaseData { unsigned int fadeOut; int rotaryEncoders[2]; int gvars[C9X_MAX_GVARS]; - void clear() { memset(this, 0, sizeof(PhaseData)); for (int i=0; i(trimExt[i])); } + else if (board == BOARD_TARANIS && version >= 216) { + for (int i=0; i(phase.trim[i])); + internalField.Append(new UnsignedField<5>(trimMode[i])); + } + } else { for (int i=0; i(trimBase[i])); @@ -467,19 +473,27 @@ class PhaseField: public TransformedField { virtual void beforeExport() { for (int i=0; i= 0) { - trim = 501 + phase.trimRef[i] - (phase.trimRef[i] >= index ? 1 : 0); + if (board == BOARD_TARANIS && version >= 216) { + if (phase.trimMode[i] < 0) + trimMode[i] = TRIM_MODE_NONE; + else + trimMode[i] = 2*phase.trimRef[i] + phase.trimMode[i]; } else { - trim = std::max(-500, std::min(500, phase.trim[i])); - } - if (board == BOARD_STOCK || (board == BOARD_M128 && version >= 215)) { - trimBase[i] = trim >> 2; - trimExt[i] = (trim & 0x03); - } - else { - trimBase[i] = trim; + int trim; + if (phase.trimMode[i] < 0) + trim = 0; + else if (phase.trimRef[i] != index) + trim = 501 + phase.trimRef[i] - (phase.trimRef[i] > index ? 1 : 0); + else + trim = std::max(-500, std::min(500, phase.trim[i])); + if (board == BOARD_STOCK || (board == BOARD_M128 && version >= 215)) { + trimBase[i] = trim >> 2; + trimExt[i] = (trim & 0x03); + } + else { + trimBase[i] = trim; + } } } } @@ -487,21 +501,31 @@ class PhaseField: public TransformedField { virtual void afterImport() { for (int i=0; i= 215)) - trim = ((trimBase[i]) << 2) + (trimExt[i] & 0x03); - else - trim = trimBase[i]; - if (trim > 500) { - phase.trimRef[i] = trim - 501; - if (phase.trimRef[i] >= index) - phase.trimRef[i] += 1; - phase.trim[i] = 0; + if (board == BOARD_TARANIS && version >= 216) { + if (trimMode[i] == TRIM_MODE_NONE) { + phase.trimMode[i] = -1; + } + else { + phase.trimMode[i] = trimMode[i] % 2; + phase.trimRef[i] = trimMode[i] / 2; + } } else { - phase.trim[i] = trim; + int trim; + if (board == BOARD_STOCK || (board == BOARD_M128 && version >= 215)) + trim = ((trimBase[i]) << 2) + (trimExt[i] & 0x03); + else + trim = trimBase[i]; + if (trim > 500) { + phase.trimRef[i] = trim - 501; + if (phase.trimRef[i] >= index) + phase.trimRef[i] += 1; + phase.trim[i] = 0; + } + else { + phase.trim[i] = trim; + } } - } } @@ -514,6 +538,7 @@ class PhaseField: public TransformedField { int rotencCount; int trimBase[NUM_STICKS]; int trimExt[NUM_STICKS]; + unsigned int trimMode[NUM_STICKS]; }; diff --git a/companion/src/helpers.cpp b/companion/src/helpers.cpp index c27a88672..831728d87 100644 --- a/companion/src/helpers.cpp +++ b/companion/src/helpers.cpp @@ -684,19 +684,6 @@ void CurveGroup::valuesChanged() } } -void populateTrimUseCB(QComboBox *b, unsigned int phase) -{ - b->addItem(QObject::tr("Own trim")); - unsigned int num_phases = GetEepromInterface()->getCapability(FlightPhases); - if (num_phases>0) { - for (unsigned int i = 0; i < num_phases; i++) { - if (i != phase) { - b->addItem(QObject::tr("Flight mode %1 trim").arg(i)); - } - } - } -} - void populateGvarUseCB(QComboBox *b, unsigned int phase) { b->addItem(QObject::tr("Own value")); diff --git a/companion/src/helpers.h b/companion/src/helpers.h index 9cef155e7..2d7f08ad6 100644 --- a/companion/src/helpers.h +++ b/companion/src/helpers.h @@ -23,6 +23,8 @@ #define TRIM_OFF 1 #define TRIM_OFFSET 2 +#define TRIM_MODE_NONE 0x1F // 0b11111 + void populateGvSourceCB(QComboBox *b, int value); void populateVoiceLangCB(QComboBox *b, QString language); void populateTTraceCB(QComboBox *b, int value); @@ -89,7 +91,6 @@ QString FuncParam(uint function, int value, QString paramT="",unsigned int adjus void populateFuncParamCB(QComboBox *b, const ModelData & model, uint function, unsigned int value, unsigned int adjustmode=0); void populateFuncParamArmTCB(QComboBox *b, ModelData * g_model, char * value, QStringList & paramsList); void populatePhasesCB(QComboBox *b, int value); -void populateTrimUseCB(QComboBox *b, unsigned int phase); void populateGvarUseCB(QComboBox *b, unsigned int phase); void populateCustomScreenFieldCB(QComboBox *b, unsigned int value, bool last, int hubproto); void populateTimerSwitchCB(QComboBox *b, int value); diff --git a/companion/src/modeledit/flightmodes.cpp b/companion/src/modeledit/flightmodes.cpp index 4a4e5e651..a5cd400a0 100644 --- a/companion/src/modeledit/flightmodes.cpp +++ b/companion/src/modeledit/flightmodes.cpp @@ -17,9 +17,11 @@ FlightMode::FlightMode(QWidget * parent, ModelData & model, int phaseIdx, Genera { ui->setupUi(this); + int modesCount = GetEepromInterface()->getCapability(FlightPhases); + // Phase name QRegExp rx(CHAR_FOR_NAMES_REGEX); - if (GetEepromInterface()->getCapability(FlightPhases)) { + if (modesCount) { ui->name->setValidator(new QRegExpValidator(rx, this)); ui->name->setMaxLength(GetEepromInterface()->getCapability(FlightModesName)); connect(ui->name, SIGNAL(editingFinished()), this, SLOT(phaseName_editingFinished())); @@ -66,14 +68,19 @@ FlightMode::FlightMode(QWidget * parent, ModelData & model, int phaseIdx, Genera for (int i=0; i<4; i++) { trimsLabel[i]->setText(labels[CONVERT_MODE(i+1)-1]); - if (phaseIdx > 0) { - trimsUse[i]->setProperty("index", i); - populateTrimUseCB(trimsUse[i], phaseIdx); - connect(trimsUse[i], SIGNAL(currentIndexChanged(int)), this, SLOT(phaseTrimUse_currentIndexChanged(int))); - } - else { - trimsUse[i]->hide(); + QComboBox * cb = trimsUse[i]; + cb->setProperty("index", i); + cb->addItem(QObject::tr("Trim disabled"), -1); + for (int m=0; maddItem(QObject::tr("Own Trim"), m*2); + } + else if (phaseIdx > 0) { + cb->addItem(QObject::tr("Use Trim from Flight mode %1").arg(m), m*2); + cb->addItem(QObject::tr("Use Trim from Flight mode %1 + Own Trim as an offset").arg(m), m*2+1); + } } + connect(cb, SIGNAL(currentIndexChanged(int)), this, SLOT(phaseTrimUse_currentIndexChanged(int))); trimsValue[i]->setProperty("index", i); connect(trimsValue[i], SIGNAL(valueChanged(int)), this, SLOT(phaseTrim_valueChanged())); @@ -123,17 +130,6 @@ FlightMode::FlightMode(QWidget * parent, ModelData & model, int phaseIdx, Genera QLabel *label = new QLabel(ui->gvGB); label->setText(tr("GVAR%1").arg(i+1)); gvLayout->addWidget(label, i, col++, 1, 1); -#if 0 - // TODO remove this capability? - // GVar source (er9x/ersky9x) - if (GetEepromInterface()->getCapability(GvarsHaveSources)) { - QComboBox *source = new QComboBox(ui->gvGB); - source->setProperty("index", i); - populateGvSourceCB(source, model.gvsource[i]); - // connect(source, SIGNAL(currentIndexChanged(int)), this, SLOT(phaseGVSource_currentIndexChanged(int))); - gvLayout->addWidget(source, i, col++, 1, 1); - } -#endif // GVar name int nameLen = GetEepromInterface()->getCapability(GvarsName); if (nameLen > 0) { @@ -193,7 +189,6 @@ void FlightMode::update() int chn = CONVERT_MODE(i+1)-1; if (chn == 2/*TODO constant*/ && model.throttleReversed) trimsSlider[i]->setInvertedAppearance(true); - trimUpdate(i); } @@ -262,23 +257,22 @@ void FlightMode::phaseFadeOut_editingFinished() void FlightMode::trimUpdate(unsigned int trim) { - lock = true; - int chn = CONVERT_MODE(trim+1)-1; - int value = phase.trim[chn]; - if (phaseIdx > 0 && phase.trimRef[chn] >= 0) { - trimsUse[trim]->setCurrentIndex(1 + phase.trimRef[chn] - (phase.trimRef[chn] >= phaseIdx ? 1 : 0)); - value = model.phaseData[model.getTrimFlightPhase(chn, phaseIdx)].trim[chn]; - trimsValue[trim]->setEnabled(false); - trimsSlider[trim]->setEnabled(false); - } - else { - if (phaseIdx > 0) trimsUse[trim]->setCurrentIndex(0); - trimsValue[trim]->setEnabled(true); - trimsSlider[trim]->setEnabled(true); - } - trimsSlider[trim]->setValue(value); - trimsValue[trim]->setValue(value); - lock = false; + lock = true; + int chn = CONVERT_MODE(trim+1)-1; + int value = model.getTrimValue(phaseIdx, chn); + trimsSlider[trim]->setValue(value); + trimsValue[trim]->setValue(value); + if (phase.trimMode[chn] < 0) { + trimsUse[trim]->setCurrentIndex(0); + trimsValue[trim]->setEnabled(false); + trimsSlider[trim]->setEnabled(false); + } + else { + trimsUse[trim]->setCurrentIndex(1 + 2*phase.trimRef[chn] + phase.trimMode[chn] - (phase.trimRef[chn] > phaseIdx ? 1 : 0)); + trimsValue[trim]->setEnabled(true); + trimsSlider[trim]->setEnabled(true); + } + lock = false; } void FlightMode::phaseGVValue_editingFinished() @@ -380,15 +374,17 @@ void FlightMode::phaseTrimUse_currentIndexChanged(int index) QComboBox *comboBox = qobject_cast(sender()); int trim = comboBox->property("index").toInt(); int chn = CONVERT_MODE(trim+1)-1; - if (index == 0) { - phase.trim[chn] = model.phaseData[model.getTrimFlightPhase(chn, phaseIdx)].trim[chn]; - phase.trimRef[chn] = -1; + int data = comboBox->itemData(index).toInt(); + if (data < 0) { + phase.trimMode[chn] = -1; + phase.trimRef[chn] = 0; + phase.trim[chn] = 0; } else { + phase.trimMode[chn] = data % 2; + phase.trimRef[chn] = data / 2; phase.trim[chn] = 0; - phase.trimRef[chn] = index - 1 + (index > (int)phaseIdx ? 1 : 0); } - trimUpdate(trim); emit modified(); } @@ -401,7 +397,7 @@ void FlightMode::phaseTrim_valueChanged() int trim = spinBox->property("index").toInt(); int chn = CONVERT_MODE(trim+1)-1; int value = spinBox->value(); - phase.trim[chn] = value; + model.setTrimValue(phaseIdx, chn, value); lock = true; trimsSlider[trim]->setValue(value); lock = false; @@ -416,7 +412,7 @@ void FlightMode::phaseTrimSlider_valueChanged() int trim = slider->property("index").toInt(); int chn = CONVERT_MODE(trim+1)-1; int value = slider->value(); - phase.trim[chn] = value; + model.setTrimValue(phaseIdx, chn, value); lock = true; trimsValue[trim]->setValue(value); lock = false; diff --git a/companion/src/simulatordialog.cpp b/companion/src/simulatordialog.cpp index 1bbddf4ef..85cc110d2 100644 --- a/companion/src/simulatordialog.cpp +++ b/companion/src/simulatordialog.cpp @@ -497,6 +497,8 @@ void simulatorDialog::setValues() { TxOutputs outputs; simulator->getValues(outputs); + Trims trims; + simulator->getTrims(trims); ui->chnout_1->setValue(chVal(outputs.chans[0])); ui->chnout_2->setValue(chVal(outputs.chans[1])); @@ -536,11 +538,11 @@ void simulatorDialog::setValues() ui->chnoutV_16->setText(QString("%1").arg((qreal)outputs.chans[15]*100/1024, 0, 'f', 1)); } - ui->leftXPerc->setText(QString("X %1%").arg((qreal)nodeLeft->getX()*100, 2, 'f', 0)); - ui->leftYPerc->setText(QString("Y %1%").arg((qreal)nodeLeft->getY()*-100, 2, 'f', 0)); + ui->leftXPerc->setText(QString("X %1%").arg((qreal)nodeLeft->getX()*100+trims.values[0]/5, 2, 'f', 0)); + ui->leftYPerc->setText(QString("Y %1%").arg((qreal)nodeLeft->getY()*-100+trims.values[1]/5, 2, 'f', 0)); - ui->rightXPerc->setText(QString("X %1%").arg((qreal)nodeRight->getX()*100, 2, 'f', 0)); - ui->rightYPerc->setText(QString("Y %1%").arg((qreal)nodeRight->getY()*-100, 2, 'f', 0)); + ui->rightXPerc->setText(QString("X %1%").arg((qreal)nodeRight->getX()*100+trims.values[2]/5, 2, 'f', 0)); + ui->rightYPerc->setText(QString("Y %1%").arg((qreal)nodeRight->getY()*-100+trims.values[3]/5, 2, 'f', 0)); #define CSWITCH_ON "QLabel { background-color: #4CC417 }" #define CSWITCH_OFF "QLabel { }" diff --git a/companion/src/xsimulatordialog.cpp b/companion/src/xsimulatordialog.cpp index 488439715..07524bb04 100644 --- a/companion/src/xsimulatordialog.cpp +++ b/companion/src/xsimulatordialog.cpp @@ -383,6 +383,9 @@ void xsimulatorDialog::setValues() { TxOutputs outputs; simulator->getValues(outputs); + + Trims trims; + simulator->getTrims(trims); ui->chnout_1->setValue(chVal(outputs.chans[0])); ui->chnout_2->setValue(chVal(outputs.chans[1])); @@ -422,11 +425,11 @@ void xsimulatorDialog::setValues() ui->chnoutV_16->setText(QString("%1").arg((qreal)outputs.chans[15]*100/1024, 0, 'f', 1)); } - ui->leftXPerc->setText(QString("X %1%").arg((qreal)nodeLeft->getX()*100, 2, 'f', 0)); - ui->leftYPerc->setText(QString("Y %1%").arg((qreal)nodeLeft->getY()*-100, 2, 'f', 0)); + ui->leftXPerc->setText(QString("X %1%").arg((qreal)nodeLeft->getX()*100+trims.values[0]/5, 2, 'f', 0)); + ui->leftYPerc->setText(QString("Y %1%").arg((qreal)nodeLeft->getY()*-100+trims.values[1]/5, 2, 'f', 0)); - ui->rightXPerc->setText(QString("X %1%").arg((qreal)nodeRight->getX()*100, 2, 'f', 0)); - ui->rightYPerc->setText(QString("Y %1%").arg((qreal)nodeRight->getY()*-100, 2, 'f', 0)); + ui->rightXPerc->setText(QString("X %1%").arg((qreal)nodeRight->getX()*100+trims.values[2]/5, 2, 'f', 0)); + ui->rightYPerc->setText(QString("Y %1%").arg((qreal)nodeRight->getY()*-100+trims.values[3]/5, 2, 'f', 0)); #define CSWITCH_ON "QLabel { background-color: #4CC417 }" #define CSWITCH_OFF "QLabel { }" diff --git a/radio/src/eeprom_conversions.cpp b/radio/src/eeprom_conversions.cpp index b78db9acb..f40f07325 100644 --- a/radio/src/eeprom_conversions.cpp +++ b/radio/src/eeprom_conversions.cpp @@ -122,7 +122,7 @@ PACK(typedef struct { }) TimerData_v215; PACK(typedef struct { - TRIMS_ARRAY; + int16_t trim[4]; int8_t swtch; // swtch of phase[0] is not used char name[LEN_FP_NAME]; uint8_t fadeIn; @@ -453,6 +453,22 @@ void ConvertModel_215_to_216(ModelData &model) for (uint8_t i=0; i<9; i++) { memcpy(&g_model.phaseData[i], &oldModel.phaseData[i], sizeof(oldModel.phaseData[i])); // the last 4 gvars will remain blank +#if defined(PCBTARANIS) + for (uint8_t t=0; t<4; t++) { + int trim = oldModel.phaseData[i].trim[t]; + if (trim > 500) { + trim -= 501; + if (trim >= i) + trim += 1; + g_model.phaseData[i].trim[t].mode = 2*trim; + g_model.phaseData[i].trim[t].value = 0; + } + else { + g_model.phaseData[i].trim[t].mode = 2*i; + g_model.phaseData[i].trim[t].value = trim; + } + } +#endif } g_model.thrTraceSrc = oldModel.thrTraceSrc; g_model.switchWarningStates = oldModel.switchWarningStates; diff --git a/radio/src/gui/menu_model.cpp b/radio/src/gui/menu_model.cpp index 689196b01..4d12c3557 100644 --- a/radio/src/gui/menu_model.cpp +++ b/radio/src/gui/menu_model.cpp @@ -1722,86 +1722,34 @@ FlightModesType editFlightModes(uint8_t x, uint8_t y, uint8_t event, FlightModes return value; } -#if LCD_W >= 212 +#if defined(PCBTARANIS) enum FlightModesItems { ITEM_PHASES_NAME, ITEM_PHASES_SWITCH, - ITEM_PHASES_TRIMS, + ITEM_PHASES_TRIM_RUD, + ITEM_PHASES_TRIM_ELE, + ITEM_PHASES_TRIM_THR, + ITEM_PHASES_TRIM_AIL, ITEM_PHASES_FADE_IN, ITEM_PHASES_FADE_OUT, ITEM_PHASES_COUNT, ITEM_PHASES_LAST = ITEM_PHASES_COUNT-1 }; -void editPhaseTrims(uint8_t x, uint8_t y, uint8_t phase, uint8_t event, uint8_t active) +bool isTrimModeAvailable(int16_t mode) { - static uint8_t cursorPos = 0; - - for (uint8_t t=0; t 0) { - if (p1valdiff || IS_ROTARY_RIGHT(event) || IS_ROTARY_LEFT(event) || event==EVT_KEY_FIRST(KEY_DOWN) || event==EVT_KEY_FIRST(KEY_UP) - || event==EVT_KEY_REPT(KEY_DOWN) || event==EVT_KEY_REPT(KEY_UP)) { - int16_t v = getRawTrimValue(phase, cur); - if (v < TRIM_EXTENDED_MAX) v = TRIM_EXTENDED_MAX; - v = checkIncDec(event, v, TRIM_EXTENDED_MAX, TRIM_EXTENDED_MAX+MAX_PHASES-1, EE_MODEL); - if (checkIncDec_Ret) { - if (v == TRIM_EXTENDED_MAX) v = 0; - setTrimValue(phase, cur, v); - } - } - - switch (event) { -#if defined(ROTARY_ENCODER_NAVIGATION) || defined(PCBTARANIS) - case EVT_ROTARY_BREAK: - if (s_editMode == EDIT_MODIFY_FIELD) { - s_editMode = EDIT_MODIFY_STRING; - cur = 0; - } - else if (cur0) cur--; - break; - case EVT_KEY_BREAK(KEY_RIGHT): - if (cur 0) { posHorz += 2; } + if (sub==0 && posHorz > 0) { posHorz += 5; } if (sub=0) { displayColumnHeader(STR_PHASES_HEADERS, posHorz); @@ -1828,35 +1776,41 @@ void menuModelFlightModesAll(uint8_t event) for (uint8_t j=0; j0) ? BLINK|INVERS : INVERS) : 0); uint8_t active = (attr && (s_editMode>0 || p1valdiff)) ; - switch(j) - { + switch (j) { case ITEM_PHASES_NAME: - editName(4*FW, y, p->name, sizeof(p->name), event, attr); + editName(4*FW-1, y, p->name, sizeof(p->name), event, attr); break; case ITEM_PHASES_SWITCH: if (k == 0) { - lcd_puts((5+LEN_FP_NAME)*FW+FW/2, y, STR_DEFAULT); + lcd_puts((5+LEN_FP_NAME)*FW, y, STR_DEFAULT); } else { - putsSwitches((5+LEN_FP_NAME)*FW+FW/2, y, p->swtch, attr); + putsSwitches((5+LEN_FP_NAME)*FW, y, p->swtch, attr); if (active) CHECK_INCDEC_MODELSWITCH(event, p->swtch, -NUM_SWITCH, NUM_SWITCH); } break; - case ITEM_PHASES_TRIMS: + case ITEM_PHASES_TRIM_RUD: + case ITEM_PHASES_TRIM_ELE: + case ITEM_PHASES_TRIM_THR: + case ITEM_PHASES_TRIM_AIL: if (k != 0) { - editPhaseTrims((10+LEN_FP_NAME)*FW+FW/2, y, k, event, attr); + uint8_t t = j-ITEM_PHASES_TRIM_RUD; + putsTrimMode((4+LEN_FP_NAME)*FW+j*(5*FW/2), y, k, t, attr); + if (active) { + trim_t & v = p->trim[t]; + v.mode = checkIncDec(event, v.mode==TRIM_MODE_NONE ? -1 : v.mode, -1, 2*MAX_PHASES-1, EE_MODEL, isTrimModeAvailable); + } } break; - case ITEM_PHASES_FADE_IN: - lcd_outdezAtt(29*FW, y, (10/DELAY_STEP)*p->fadeIn, attr|PREC1); + lcd_outdezAtt(32*FW-2, y, (10/DELAY_STEP)*p->fadeIn, attr|PREC1); if (active) p->fadeIn = checkIncDec(event, p->fadeIn, 0, DELAY_MAX, EE_MODEL|NO_INCDEC_MARKS); break; case ITEM_PHASES_FADE_OUT: - lcd_outdezAtt(34*FW, y, (10/DELAY_STEP)*p->fadeOut, attr|PREC1); + lcd_outdezAtt(35*FW, y, (10/DELAY_STEP)*p->fadeOut, attr|PREC1); if (active) p->fadeOut = checkIncDec(event, p->fadeOut, 0, DELAY_MAX, EE_MODEL|NO_INCDEC_MARKS); break; @@ -1865,7 +1819,7 @@ void menuModelFlightModesAll(uint8_t event) } } -#else // LCD_W >= 212 +#else // PCBTARANIS enum menuModelPhaseItems { ITEM_MODEL_PHASE_NAME, @@ -2909,7 +2863,7 @@ void menuModelExpoOne(uint8_t event) case EXPO_FIELD_SCALE: lcd_putsLeft(y, STR_SCALE); putsTelemetryChannel(EXPO_ONE_2ND_COLUMN, y, ed->srcRaw - MIXSRC_FIRST_TELEM, convertTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1, ed->scale), LEFT|attr); - if (attr) ed->scale = checkIncDec(event, ed->scale, 0, maxTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1), EE_MODEL, NULL); + if (attr) ed->scale = checkIncDec(event, ed->scale, 0, maxTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1), EE_MODEL); break; #endif diff --git a/radio/src/lcd.cpp b/radio/src/lcd.cpp index 890811d5a..ed9f798e1 100644 --- a/radio/src/lcd.cpp +++ b/radio/src/lcd.cpp @@ -1159,9 +1159,28 @@ void putsTmrMode(xcoord_t x, uint8_t y, int8_t mode, LcdFlags att) putsSwitches(x, y, mode-(TMR_VAROFS-1), att); } +#if defined(PCBTARANIS) void putsTrimMode(xcoord_t x, uint8_t y, uint8_t phase, uint8_t idx, LcdFlags att) { - int16_t v = getRawTrimValue(phase, idx); + trim_t v = getRawTrimValue(phase, idx); + unsigned int mode = v.mode; + unsigned int p = mode >> 1; + + if (mode == TRIM_MODE_NONE) { + lcd_putsAtt(x, y, "--", att); + } + else { + if (mode % 2 == 0) + lcd_putcAtt(x, y, ':', att|FIXEDWIDTH); + else + lcd_putcAtt(x, y, '+', att|FIXEDWIDTH); + lcd_putcAtt(lcdNextPos, y, '0'+p, att); + } +} +#else +void putsTrimMode(xcoord_t x, uint8_t y, uint8_t phase, uint8_t idx, LcdFlags att) +{ + trim_t v = getRawTrimValue(phase, idx); if (v > TRIM_EXTENDED_MAX) { uint8_t p = v - TRIM_EXTENDED_MAX - 1; @@ -1172,6 +1191,7 @@ void putsTrimMode(xcoord_t x, uint8_t y, uint8_t phase, uint8_t idx, LcdFlags at putsChnLetter(x, y, idx+1, att); } } +#endif #if ROTARY_ENCODERS > 0 void putsRotaryEncoderMode(xcoord_t x, uint8_t y, uint8_t phase, uint8_t idx, LcdFlags att) diff --git a/radio/src/myeeprom.h b/radio/src/myeeprom.h index 8bb233a52..de33b0706 100644 --- a/radio/src/myeeprom.h +++ b/radio/src/myeeprom.h @@ -1101,8 +1101,18 @@ PACK(typedef struct t_SwashRingData { // Swash Ring data #if defined(PCBSTD) #define TRIMS_ARRAY int8_t trim[4]; int8_t trim_ext:8 #define TRIMS_ARRAY_SIZE 5 + #define trim_t int16_t #else - #define TRIMS_ARRAY int16_t trim[4] + #if defined(PCBTARANIS) + PACK(typedef struct { + int16_t value:11; + uint16_t mode:5; + }) trim_t; + #define TRIM_MODE_NONE 0x1F // 0b11111 + #else + #define trim_t int16_t + #endif + #define TRIMS_ARRAY trim_t trim[4] #define TRIMS_ARRAY_SIZE 8 #endif diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index 0aeccb617..3f4085d08 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -1665,38 +1665,82 @@ uint8_t getFlightPhase() } #endif -int16_t getRawTrimValue(uint8_t phase, uint8_t idx) +trim_t getRawTrimValue(uint8_t phase, uint8_t idx) { PhaseData *p = phaseAddress(phase); #if defined(PCBSTD) - return (((int16_t)p->trim[idx]) << 2) + ((p->trim_ext >> (2*idx)) & 0x03); + return (((trim_t)p->trim[idx]) << 2) + ((p->trim_ext >> (2*idx)) & 0x03); #else return p->trim[idx]; #endif } -int16_t getTrimValue(uint8_t phase, uint8_t idx) +int getTrimValue(uint8_t phase, uint8_t idx) { +#if defined(PCBTARANIS) + int result = 0; + for (uint8_t i=0; i> 1; + if (p == phase || phase == 0) { + return result + v.value; + } + else { + phase = p; + if (v.mode % 2 != 0) { + result += v.value; + } + } + } + } + return 0; +#else return getRawTrimValue(getTrimFlightPhase(phase, idx), idx); +#endif } -void setTrimValue(uint8_t phase, uint8_t idx, int16_t trim) +void setTrimValue(uint8_t phase, uint8_t idx, int trim) { +#if defined(PCBTARANIS) + for (uint8_t i=0; itrim[idx]; + if (v.mode < 0) + return; + unsigned int p = v.mode >> 1; + if (p == phase || phase == 0) { + v.value = trim; + break;; + } + else if (v.mode % 2 == 0) { + phase = p; + } + else { + v.value = limit(TRIM_EXTENDED_MIN, trim - getTrimValue(p, idx), TRIM_EXTENDED_MAX); + break; + } + } +#elif defined(PCBSTD) PhaseData *p = phaseAddress(phase); -#if defined(PCBSTD) p->trim[idx] = (int8_t)(trim >> 2); - p->trim_ext = (p->trim_ext & ~(0x03 << (2*idx))) + (((trim & 0x03) << (2*idx))); + idx <<= 1; + p->trim_ext = (p->trim_ext & ~(0x03 << idx)) + (((trim & 0x03) << idx)); #else + PhaseData *p = phaseAddress(phase); p->trim[idx] = trim; #endif eeDirty(EE_MODEL); } +#if !defined(PCBTARANIS) uint8_t getTrimFlightPhase(uint8_t phase, uint8_t idx) { for (uint8_t i=0; i= phase) result++; @@ -1704,6 +1748,7 @@ uint8_t getTrimFlightPhase(uint8_t phase, uint8_t idx) } return 0; } +#endif #if defined(ROTARY_ENCODERS) uint8_t getRotaryEncoderFlightPhase(uint8_t idx) @@ -2344,7 +2389,7 @@ uint8_t checkTrim(uint8_t event) // LH_DWN LH_UP LV_DWN LV_UP RV_DWN RV_UP RH_DWN RH_UP uint8_t idx = CONVERT_MODE((uint8_t)k/2); uint8_t phase; - int16_t before; + int before; bool thro; #if defined(GVARS) @@ -2360,13 +2405,21 @@ uint8_t checkTrim(uint8_t event) } else { phase = getTrimFlightPhase(s_perout_flight_phase, idx); +#if defined(PCBTARANIS) + before = getTrimValue(phase, idx); +#else before = getRawTrimValue(phase, idx); +#endif thro = (idx==THR_STICK && g_model.thrTrim); } #else #define TRIM_REUSED() 0 phase = getTrimFlightPhase(s_perout_flight_phase, idx); +#if defined(PCBTARANIS) + before = getTrimValue(phase, idx); +#else before = getRawTrimValue(phase, idx); +#endif thro = (idx==THR_STICK && g_model.thrTrim); #endif int8_t trimInc = g_model.trimInc + 1; @@ -4739,7 +4792,7 @@ void instantTrim() if (i!=THR_STICK) { // don't instant trim the throttle stick uint8_t trim_phase = getTrimFlightPhase(s_perout_flight_phase, i); - int16_t trim = limit((int16_t)TRIM_EXTENDED_MIN, (int16_t)((anas[i] + trims[i]) / 2), (int16_t)TRIM_EXTENDED_MAX); + int16_t trim = limit(TRIM_EXTENDED_MIN, (anas[i] + trims[i]) / 2, TRIM_EXTENDED_MAX); setTrimValue(trim_phase, i, trim); } } @@ -4797,9 +4850,16 @@ void moveTrimsToOffsets() // copy state of 3 primary to subtrim if (i!=THR_STICK || !g_model.thrTrim) { int16_t original_trim = getTrimValue(s_perout_flight_phase, i); for (uint8_t phase=0; phase