mirror of
https://github.com/opentx/opentx.git
synced 2025-07-19 14:25:11 +03:00
Merge pull request #621 from opentx/bsongis/Issue554_trims_relative_default
All good!
This commit is contained in:
commit
b12f76bc39
17 changed files with 310 additions and 194 deletions
|
@ -536,17 +536,57 @@ void ModelData::setDefault(uint8_t id)
|
||||||
sprintf(name, "MODEL%02d", id+1);
|
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();
|
int result = 0;
|
||||||
|
for (int i=0; i<C9X_MAX_PHASES; i++) {
|
||||||
for (uint8_t i=0; i<C9X_MAX_PHASES; i++) {
|
PhaseData & phase = phaseData[phaseIdx];
|
||||||
if (phase == 0 || phaseData[phase].trimRef[idx] < 0) return phase;
|
if (phase.trimMode[trimIdx] < 0) {
|
||||||
phase = phaseData[phase].trimRef[idx];
|
return result;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (phase.trimRef[trimIdx] == phaseIdx || phaseIdx == 0) {
|
||||||
|
return result + phase.trim[trimIdx];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
phaseIdx = phase.trimRef[trimIdx];
|
||||||
|
if (phase.trimMode[trimIdx] == 0)
|
||||||
|
result = 0;
|
||||||
|
else
|
||||||
|
result += phase.trim[trimIdx];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModelData::setTrimValue(int phaseIdx, int trimIdx, int value)
|
||||||
|
{
|
||||||
|
for (uint8_t i=0; i<C9X_MAX_PHASES; i++) {
|
||||||
|
PhaseData & phase = phaseData[phaseIdx];
|
||||||
|
int mode = phase.trimMode[trimIdx];
|
||||||
|
int p = phase.trimRef[trimIdx];
|
||||||
|
int & trim = phase.trim[trimIdx];
|
||||||
|
if (mode < 0)
|
||||||
|
return;
|
||||||
|
if (p == phaseIdx || phaseIdx == 0) {
|
||||||
|
trim = value;
|
||||||
|
break;;
|
||||||
|
}
|
||||||
|
else if (mode == 0) {
|
||||||
|
phaseIdx = p;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
trim = value - getTrimValue(p, trimIdx);
|
||||||
|
if (trim < -500)
|
||||||
|
trim = -500;
|
||||||
|
if (trim > 500)
|
||||||
|
trim = 500;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ModelData::removeGlobalVar(int & var)
|
void ModelData::removeGlobalVar(int & var)
|
||||||
{
|
{
|
||||||
if (var >= 126 && var <= 130)
|
if (var >= 126 && var <= 130)
|
||||||
|
|
|
@ -680,7 +680,8 @@ class FuncSwData { // Function Switches data
|
||||||
class PhaseData {
|
class PhaseData {
|
||||||
public:
|
public:
|
||||||
PhaseData() { clear(); }
|
PhaseData() { clear(); }
|
||||||
int trimRef[NUM_STICKS]; //
|
int trimMode[NUM_STICKS];
|
||||||
|
int trimRef[NUM_STICKS];
|
||||||
int trim[NUM_STICKS];
|
int trim[NUM_STICKS];
|
||||||
RawSwitch swtch;
|
RawSwitch swtch;
|
||||||
char name[10+1];
|
char name[10+1];
|
||||||
|
@ -688,7 +689,7 @@ class PhaseData {
|
||||||
unsigned int fadeOut;
|
unsigned int fadeOut;
|
||||||
int rotaryEncoders[2];
|
int rotaryEncoders[2];
|
||||||
int gvars[C9X_MAX_GVARS];
|
int gvars[C9X_MAX_GVARS];
|
||||||
void clear() { memset(this, 0, sizeof(PhaseData)); for (int i=0; i<NUM_STICKS; i++) trimRef[i] = -1; }
|
void clear() { memset(this, 0, sizeof(PhaseData)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class SwashRingData { // Swash Ring data
|
class SwashRingData { // Swash Ring data
|
||||||
|
@ -924,8 +925,9 @@ class ModelData {
|
||||||
void clear();
|
void clear();
|
||||||
bool isempty();
|
bool isempty();
|
||||||
void setDefault(uint8_t id);
|
void setDefault(uint8_t id);
|
||||||
unsigned int getTrimFlightPhase(uint8_t idx, int8_t phase);
|
|
||||||
|
|
||||||
|
int getTrimValue(int phaseIdx, int trimIdx);
|
||||||
|
void setTrimValue(int phaseIdx, int trimIdx, int value);
|
||||||
ModelData removeGlobalVars();
|
ModelData removeGlobalVars();
|
||||||
|
|
||||||
void clearMixes();
|
void clearMixes();
|
||||||
|
@ -1014,7 +1016,6 @@ enum Capability {
|
||||||
GvarsInCS,
|
GvarsInCS,
|
||||||
GvarsAreNamed,
|
GvarsAreNamed,
|
||||||
GvarsFlightPhases,
|
GvarsFlightPhases,
|
||||||
GvarsHaveSources,
|
|
||||||
GvarsName,
|
GvarsName,
|
||||||
NoTelemetryProtocol,
|
NoTelemetryProtocol,
|
||||||
TelemetryCustomScreens,
|
TelemetryCustomScreens,
|
||||||
|
|
|
@ -281,8 +281,6 @@ int Er9xInterface::getCapability(const Capability capability)
|
||||||
case ModelVoice:
|
case ModelVoice:
|
||||||
case Gvars:
|
case Gvars:
|
||||||
return 7;
|
return 7;
|
||||||
case GvarsHaveSources:
|
|
||||||
return 1;
|
|
||||||
case GetThrSwitch:
|
case GetThrSwitch:
|
||||||
return DSW_THR;
|
return DSW_THR;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -317,8 +317,6 @@ int Ersky9xInterface::getCapability(const Capability capability)
|
||||||
return 125;
|
return 125;
|
||||||
case MaxVolume:
|
case MaxVolume:
|
||||||
return 23;
|
return 23;
|
||||||
case GvarsHaveSources:
|
|
||||||
return 1;
|
|
||||||
case TelemetryMaxMultiplier:
|
case TelemetryMaxMultiplier:
|
||||||
return 2;
|
return 2;
|
||||||
case LCDWidth:
|
case LCDWidth:
|
||||||
|
|
|
@ -433,6 +433,12 @@ class PhaseField: public TransformedField {
|
||||||
for (int i=0; i<NUM_STICKS; i++)
|
for (int i=0; i<NUM_STICKS; i++)
|
||||||
internalField.Append(new SignedField<2>(trimExt[i]));
|
internalField.Append(new SignedField<2>(trimExt[i]));
|
||||||
}
|
}
|
||||||
|
else if (board == BOARD_TARANIS && version >= 216) {
|
||||||
|
for (int i=0; i<NUM_STICKS; i++) {
|
||||||
|
internalField.Append(new SignedField<11>(phase.trim[i]));
|
||||||
|
internalField.Append(new UnsignedField<5>(trimMode[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
for (int i=0; i<NUM_STICKS; i++)
|
for (int i=0; i<NUM_STICKS; i++)
|
||||||
internalField.Append(new SignedField<16>(trimBase[i]));
|
internalField.Append(new SignedField<16>(trimBase[i]));
|
||||||
|
@ -467,19 +473,27 @@ class PhaseField: public TransformedField {
|
||||||
virtual void beforeExport()
|
virtual void beforeExport()
|
||||||
{
|
{
|
||||||
for (int i=0; i<NUM_STICKS; i++) {
|
for (int i=0; i<NUM_STICKS; i++) {
|
||||||
int trim;
|
if (board == BOARD_TARANIS && version >= 216) {
|
||||||
if (phase.trimRef[i] >= 0) {
|
if (phase.trimMode[i] < 0)
|
||||||
trim = 501 + phase.trimRef[i] - (phase.trimRef[i] >= index ? 1 : 0);
|
trimMode[i] = TRIM_MODE_NONE;
|
||||||
|
else
|
||||||
|
trimMode[i] = 2*phase.trimRef[i] + phase.trimMode[i];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
trim = std::max(-500, std::min(500, phase.trim[i]));
|
int trim;
|
||||||
}
|
if (phase.trimMode[i] < 0)
|
||||||
if (board == BOARD_STOCK || (board == BOARD_M128 && version >= 215)) {
|
trim = 0;
|
||||||
trimBase[i] = trim >> 2;
|
else if (phase.trimRef[i] != index)
|
||||||
trimExt[i] = (trim & 0x03);
|
trim = 501 + phase.trimRef[i] - (phase.trimRef[i] > index ? 1 : 0);
|
||||||
}
|
else
|
||||||
else {
|
trim = std::max(-500, std::min(500, phase.trim[i]));
|
||||||
trimBase[i] = trim;
|
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()
|
virtual void afterImport()
|
||||||
{
|
{
|
||||||
for (int i=0; i<NUM_STICKS; i++) {
|
for (int i=0; i<NUM_STICKS; i++) {
|
||||||
int trim;
|
if (board == BOARD_TARANIS && version >= 216) {
|
||||||
if (board == BOARD_STOCK || (board == BOARD_M128 && version >= 215))
|
if (trimMode[i] == TRIM_MODE_NONE) {
|
||||||
trim = ((trimBase[i]) << 2) + (trimExt[i] & 0x03);
|
phase.trimMode[i] = -1;
|
||||||
else
|
}
|
||||||
trim = trimBase[i];
|
else {
|
||||||
if (trim > 500) {
|
phase.trimMode[i] = trimMode[i] % 2;
|
||||||
phase.trimRef[i] = trim - 501;
|
phase.trimRef[i] = trimMode[i] / 2;
|
||||||
if (phase.trimRef[i] >= index)
|
}
|
||||||
phase.trimRef[i] += 1;
|
|
||||||
phase.trim[i] = 0;
|
|
||||||
}
|
}
|
||||||
else {
|
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 rotencCount;
|
||||||
int trimBase[NUM_STICKS];
|
int trimBase[NUM_STICKS];
|
||||||
int trimExt[NUM_STICKS];
|
int trimExt[NUM_STICKS];
|
||||||
|
unsigned int trimMode[NUM_STICKS];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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)
|
void populateGvarUseCB(QComboBox *b, unsigned int phase)
|
||||||
{
|
{
|
||||||
b->addItem(QObject::tr("Own value"));
|
b->addItem(QObject::tr("Own value"));
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
#define TRIM_OFF 1
|
#define TRIM_OFF 1
|
||||||
#define TRIM_OFFSET 2
|
#define TRIM_OFFSET 2
|
||||||
|
|
||||||
|
#define TRIM_MODE_NONE 0x1F // 0b11111
|
||||||
|
|
||||||
void populateGvSourceCB(QComboBox *b, int value);
|
void populateGvSourceCB(QComboBox *b, int value);
|
||||||
void populateVoiceLangCB(QComboBox *b, QString language);
|
void populateVoiceLangCB(QComboBox *b, QString language);
|
||||||
void populateTTraceCB(QComboBox *b, int value);
|
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 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 populateFuncParamArmTCB(QComboBox *b, ModelData * g_model, char * value, QStringList & paramsList);
|
||||||
void populatePhasesCB(QComboBox *b, int value);
|
void populatePhasesCB(QComboBox *b, int value);
|
||||||
void populateTrimUseCB(QComboBox *b, unsigned int phase);
|
|
||||||
void populateGvarUseCB(QComboBox *b, unsigned int phase);
|
void populateGvarUseCB(QComboBox *b, unsigned int phase);
|
||||||
void populateCustomScreenFieldCB(QComboBox *b, unsigned int value, bool last, int hubproto);
|
void populateCustomScreenFieldCB(QComboBox *b, unsigned int value, bool last, int hubproto);
|
||||||
void populateTimerSwitchCB(QComboBox *b, int value);
|
void populateTimerSwitchCB(QComboBox *b, int value);
|
||||||
|
|
|
@ -17,9 +17,11 @@ FlightMode::FlightMode(QWidget * parent, ModelData & model, int phaseIdx, Genera
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
int modesCount = GetEepromInterface()->getCapability(FlightPhases);
|
||||||
|
|
||||||
// Phase name
|
// Phase name
|
||||||
QRegExp rx(CHAR_FOR_NAMES_REGEX);
|
QRegExp rx(CHAR_FOR_NAMES_REGEX);
|
||||||
if (GetEepromInterface()->getCapability(FlightPhases)) {
|
if (modesCount) {
|
||||||
ui->name->setValidator(new QRegExpValidator(rx, this));
|
ui->name->setValidator(new QRegExpValidator(rx, this));
|
||||||
ui->name->setMaxLength(GetEepromInterface()->getCapability(FlightModesName));
|
ui->name->setMaxLength(GetEepromInterface()->getCapability(FlightModesName));
|
||||||
connect(ui->name, SIGNAL(editingFinished()), this, SLOT(phaseName_editingFinished()));
|
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++) {
|
for (int i=0; i<4; i++) {
|
||||||
trimsLabel[i]->setText(labels[CONVERT_MODE(i+1)-1]);
|
trimsLabel[i]->setText(labels[CONVERT_MODE(i+1)-1]);
|
||||||
|
|
||||||
if (phaseIdx > 0) {
|
QComboBox * cb = trimsUse[i];
|
||||||
trimsUse[i]->setProperty("index", i);
|
cb->setProperty("index", i);
|
||||||
populateTrimUseCB(trimsUse[i], phaseIdx);
|
cb->addItem(QObject::tr("Trim disabled"), -1);
|
||||||
connect(trimsUse[i], SIGNAL(currentIndexChanged(int)), this, SLOT(phaseTrimUse_currentIndexChanged(int)));
|
for (int m=0; m<modesCount; m++) {
|
||||||
}
|
if (m == phaseIdx) {
|
||||||
else {
|
cb->addItem(QObject::tr("Own Trim"), m*2);
|
||||||
trimsUse[i]->hide();
|
}
|
||||||
|
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);
|
trimsValue[i]->setProperty("index", i);
|
||||||
connect(trimsValue[i], SIGNAL(valueChanged(int)), this, SLOT(phaseTrim_valueChanged()));
|
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);
|
QLabel *label = new QLabel(ui->gvGB);
|
||||||
label->setText(tr("GVAR%1").arg(i+1));
|
label->setText(tr("GVAR%1").arg(i+1));
|
||||||
gvLayout->addWidget(label, i, col++, 1, 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
|
// GVar name
|
||||||
int nameLen = GetEepromInterface()->getCapability(GvarsName);
|
int nameLen = GetEepromInterface()->getCapability(GvarsName);
|
||||||
if (nameLen > 0) {
|
if (nameLen > 0) {
|
||||||
|
@ -193,7 +189,6 @@ void FlightMode::update()
|
||||||
int chn = CONVERT_MODE(i+1)-1;
|
int chn = CONVERT_MODE(i+1)-1;
|
||||||
if (chn == 2/*TODO constant*/ && model.throttleReversed)
|
if (chn == 2/*TODO constant*/ && model.throttleReversed)
|
||||||
trimsSlider[i]->setInvertedAppearance(true);
|
trimsSlider[i]->setInvertedAppearance(true);
|
||||||
|
|
||||||
trimUpdate(i);
|
trimUpdate(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,23 +257,22 @@ void FlightMode::phaseFadeOut_editingFinished()
|
||||||
|
|
||||||
void FlightMode::trimUpdate(unsigned int trim)
|
void FlightMode::trimUpdate(unsigned int trim)
|
||||||
{
|
{
|
||||||
lock = true;
|
lock = true;
|
||||||
int chn = CONVERT_MODE(trim+1)-1;
|
int chn = CONVERT_MODE(trim+1)-1;
|
||||||
int value = phase.trim[chn];
|
int value = model.getTrimValue(phaseIdx, chn);
|
||||||
if (phaseIdx > 0 && phase.trimRef[chn] >= 0) {
|
trimsSlider[trim]->setValue(value);
|
||||||
trimsUse[trim]->setCurrentIndex(1 + phase.trimRef[chn] - (phase.trimRef[chn] >= phaseIdx ? 1 : 0));
|
trimsValue[trim]->setValue(value);
|
||||||
value = model.phaseData[model.getTrimFlightPhase(chn, phaseIdx)].trim[chn];
|
if (phase.trimMode[chn] < 0) {
|
||||||
trimsValue[trim]->setEnabled(false);
|
trimsUse[trim]->setCurrentIndex(0);
|
||||||
trimsSlider[trim]->setEnabled(false);
|
trimsValue[trim]->setEnabled(false);
|
||||||
}
|
trimsSlider[trim]->setEnabled(false);
|
||||||
else {
|
}
|
||||||
if (phaseIdx > 0) trimsUse[trim]->setCurrentIndex(0);
|
else {
|
||||||
trimsValue[trim]->setEnabled(true);
|
trimsUse[trim]->setCurrentIndex(1 + 2*phase.trimRef[chn] + phase.trimMode[chn] - (phase.trimRef[chn] > phaseIdx ? 1 : 0));
|
||||||
trimsSlider[trim]->setEnabled(true);
|
trimsValue[trim]->setEnabled(true);
|
||||||
}
|
trimsSlider[trim]->setEnabled(true);
|
||||||
trimsSlider[trim]->setValue(value);
|
}
|
||||||
trimsValue[trim]->setValue(value);
|
lock = false;
|
||||||
lock = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlightMode::phaseGVValue_editingFinished()
|
void FlightMode::phaseGVValue_editingFinished()
|
||||||
|
@ -380,15 +374,17 @@ void FlightMode::phaseTrimUse_currentIndexChanged(int index)
|
||||||
QComboBox *comboBox = qobject_cast<QComboBox*>(sender());
|
QComboBox *comboBox = qobject_cast<QComboBox*>(sender());
|
||||||
int trim = comboBox->property("index").toInt();
|
int trim = comboBox->property("index").toInt();
|
||||||
int chn = CONVERT_MODE(trim+1)-1;
|
int chn = CONVERT_MODE(trim+1)-1;
|
||||||
if (index == 0) {
|
int data = comboBox->itemData(index).toInt();
|
||||||
phase.trim[chn] = model.phaseData[model.getTrimFlightPhase(chn, phaseIdx)].trim[chn];
|
if (data < 0) {
|
||||||
phase.trimRef[chn] = -1;
|
phase.trimMode[chn] = -1;
|
||||||
|
phase.trimRef[chn] = 0;
|
||||||
|
phase.trim[chn] = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
phase.trimMode[chn] = data % 2;
|
||||||
|
phase.trimRef[chn] = data / 2;
|
||||||
phase.trim[chn] = 0;
|
phase.trim[chn] = 0;
|
||||||
phase.trimRef[chn] = index - 1 + (index > (int)phaseIdx ? 1 : 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trimUpdate(trim);
|
trimUpdate(trim);
|
||||||
emit modified();
|
emit modified();
|
||||||
}
|
}
|
||||||
|
@ -401,7 +397,7 @@ void FlightMode::phaseTrim_valueChanged()
|
||||||
int trim = spinBox->property("index").toInt();
|
int trim = spinBox->property("index").toInt();
|
||||||
int chn = CONVERT_MODE(trim+1)-1;
|
int chn = CONVERT_MODE(trim+1)-1;
|
||||||
int value = spinBox->value();
|
int value = spinBox->value();
|
||||||
phase.trim[chn] = value;
|
model.setTrimValue(phaseIdx, chn, value);
|
||||||
lock = true;
|
lock = true;
|
||||||
trimsSlider[trim]->setValue(value);
|
trimsSlider[trim]->setValue(value);
|
||||||
lock = false;
|
lock = false;
|
||||||
|
@ -416,7 +412,7 @@ void FlightMode::phaseTrimSlider_valueChanged()
|
||||||
int trim = slider->property("index").toInt();
|
int trim = slider->property("index").toInt();
|
||||||
int chn = CONVERT_MODE(trim+1)-1;
|
int chn = CONVERT_MODE(trim+1)-1;
|
||||||
int value = slider->value();
|
int value = slider->value();
|
||||||
phase.trim[chn] = value;
|
model.setTrimValue(phaseIdx, chn, value);
|
||||||
lock = true;
|
lock = true;
|
||||||
trimsValue[trim]->setValue(value);
|
trimsValue[trim]->setValue(value);
|
||||||
lock = false;
|
lock = false;
|
||||||
|
|
|
@ -497,6 +497,8 @@ void simulatorDialog::setValues()
|
||||||
{
|
{
|
||||||
TxOutputs outputs;
|
TxOutputs outputs;
|
||||||
simulator->getValues(outputs);
|
simulator->getValues(outputs);
|
||||||
|
Trims trims;
|
||||||
|
simulator->getTrims(trims);
|
||||||
|
|
||||||
ui->chnout_1->setValue(chVal(outputs.chans[0]));
|
ui->chnout_1->setValue(chVal(outputs.chans[0]));
|
||||||
ui->chnout_2->setValue(chVal(outputs.chans[1]));
|
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->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->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, 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->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, 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_ON "QLabel { background-color: #4CC417 }"
|
||||||
#define CSWITCH_OFF "QLabel { }"
|
#define CSWITCH_OFF "QLabel { }"
|
||||||
|
|
|
@ -383,6 +383,9 @@ void xsimulatorDialog::setValues()
|
||||||
{
|
{
|
||||||
TxOutputs outputs;
|
TxOutputs outputs;
|
||||||
simulator->getValues(outputs);
|
simulator->getValues(outputs);
|
||||||
|
|
||||||
|
Trims trims;
|
||||||
|
simulator->getTrims(trims);
|
||||||
|
|
||||||
ui->chnout_1->setValue(chVal(outputs.chans[0]));
|
ui->chnout_1->setValue(chVal(outputs.chans[0]));
|
||||||
ui->chnout_2->setValue(chVal(outputs.chans[1]));
|
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->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->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, 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->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, 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_ON "QLabel { background-color: #4CC417 }"
|
||||||
#define CSWITCH_OFF "QLabel { }"
|
#define CSWITCH_OFF "QLabel { }"
|
||||||
|
|
|
@ -122,7 +122,7 @@ PACK(typedef struct {
|
||||||
}) TimerData_v215;
|
}) TimerData_v215;
|
||||||
|
|
||||||
PACK(typedef struct {
|
PACK(typedef struct {
|
||||||
TRIMS_ARRAY;
|
int16_t trim[4];
|
||||||
int8_t swtch; // swtch of phase[0] is not used
|
int8_t swtch; // swtch of phase[0] is not used
|
||||||
char name[LEN_FP_NAME];
|
char name[LEN_FP_NAME];
|
||||||
uint8_t fadeIn;
|
uint8_t fadeIn;
|
||||||
|
@ -453,6 +453,22 @@ void ConvertModel_215_to_216(ModelData &model)
|
||||||
|
|
||||||
for (uint8_t i=0; i<9; i++) {
|
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
|
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.thrTraceSrc = oldModel.thrTraceSrc;
|
||||||
g_model.switchWarningStates = oldModel.switchWarningStates;
|
g_model.switchWarningStates = oldModel.switchWarningStates;
|
||||||
|
|
|
@ -1722,86 +1722,34 @@ FlightModesType editFlightModes(uint8_t x, uint8_t y, uint8_t event, FlightModes
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LCD_W >= 212
|
#if defined(PCBTARANIS)
|
||||||
|
|
||||||
enum FlightModesItems {
|
enum FlightModesItems {
|
||||||
ITEM_PHASES_NAME,
|
ITEM_PHASES_NAME,
|
||||||
ITEM_PHASES_SWITCH,
|
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_IN,
|
||||||
ITEM_PHASES_FADE_OUT,
|
ITEM_PHASES_FADE_OUT,
|
||||||
ITEM_PHASES_COUNT,
|
ITEM_PHASES_COUNT,
|
||||||
ITEM_PHASES_LAST = ITEM_PHASES_COUNT-1
|
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;
|
return (mode == TRIM_MODE_NONE || (mode%2) == 0 || (mode/2) != (m_posVert-1));
|
||||||
|
|
||||||
for (uint8_t t=0; t<NUM_STICKS; t++) {
|
|
||||||
putsTrimMode(x+t*FW, y, phase, t, (active && (s_editMode <= 0 || cursorPos==t)) ? INVERS : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (active) {
|
|
||||||
uint8_t cur = cursorPos;
|
|
||||||
if (s_editMode > 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 (cur<NUM_STICKS-1)
|
|
||||||
cur++;
|
|
||||||
else
|
|
||||||
s_editMode = 0;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(PCBTARANIS)
|
|
||||||
case EVT_KEY_BREAK(KEY_LEFT):
|
|
||||||
if (cur>0) cur--;
|
|
||||||
break;
|
|
||||||
case EVT_KEY_BREAK(KEY_RIGHT):
|
|
||||||
if (cur<NUM_STICKS-1) cur++;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(ROTARY_ENCODER_NAVIGATION) || defined(PCBTARANIS)
|
|
||||||
case EVT_ROTARY_LONG:
|
|
||||||
s_editMode = 0;
|
|
||||||
killEvents(event);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
cur = 0;
|
|
||||||
}
|
|
||||||
cursorPos = cur;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void menuModelFlightModesAll(uint8_t event)
|
void menuModelFlightModesAll(uint8_t event)
|
||||||
{
|
{
|
||||||
MENU(STR_MENUFLIGHTPHASES, menuTabModel, e_FlightModesAll, 1+MAX_PHASES+1, {0, NAVIGATION_LINE_BY_LINE|(ITEM_PHASES_LAST-2), NAVIGATION_LINE_BY_LINE|ITEM_PHASES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_PHASES_LAST, NAVIGATION_LINE_BY_LINE|NAVIGATION_LINE_BY_LINE|ITEM_PHASES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_PHASES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_PHASES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_PHASES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_PHASES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_PHASES_LAST, 0});
|
MENU(STR_MENUFLIGHTPHASES, menuTabModel, e_FlightModesAll, 1+MAX_PHASES+1, {0, NAVIGATION_LINE_BY_LINE|(ITEM_PHASES_LAST-5), NAVIGATION_LINE_BY_LINE|ITEM_PHASES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_PHASES_LAST, NAVIGATION_LINE_BY_LINE|NAVIGATION_LINE_BY_LINE|ITEM_PHASES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_PHASES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_PHASES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_PHASES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_PHASES_LAST, NAVIGATION_LINE_BY_LINE|ITEM_PHASES_LAST, 0});
|
||||||
|
|
||||||
int8_t sub = m_posVert - 1;
|
int8_t sub = m_posVert - 1;
|
||||||
|
|
||||||
horzpos_t posHorz = m_posHorz;
|
horzpos_t posHorz = m_posHorz;
|
||||||
if (sub==0 && posHorz > 0) { posHorz += 2; }
|
if (sub==0 && posHorz > 0) { posHorz += 5; }
|
||||||
|
|
||||||
if (sub<MAX_PHASES && posHorz>=0) {
|
if (sub<MAX_PHASES && posHorz>=0) {
|
||||||
displayColumnHeader(STR_PHASES_HEADERS, posHorz);
|
displayColumnHeader(STR_PHASES_HEADERS, posHorz);
|
||||||
|
@ -1828,35 +1776,41 @@ void menuModelFlightModesAll(uint8_t event)
|
||||||
for (uint8_t j=0; j<ITEM_PHASES_COUNT; j++) {
|
for (uint8_t j=0; j<ITEM_PHASES_COUNT; j++) {
|
||||||
uint8_t attr = ((sub==k && posHorz==j) ? ((s_editMode>0) ? BLINK|INVERS : INVERS) : 0);
|
uint8_t attr = ((sub==k && posHorz==j) ? ((s_editMode>0) ? BLINK|INVERS : INVERS) : 0);
|
||||||
uint8_t active = (attr && (s_editMode>0 || p1valdiff)) ;
|
uint8_t active = (attr && (s_editMode>0 || p1valdiff)) ;
|
||||||
switch(j)
|
switch (j) {
|
||||||
{
|
|
||||||
case ITEM_PHASES_NAME:
|
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;
|
break;
|
||||||
|
|
||||||
case ITEM_PHASES_SWITCH:
|
case ITEM_PHASES_SWITCH:
|
||||||
if (k == 0) {
|
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 {
|
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);
|
if (active) CHECK_INCDEC_MODELSWITCH(event, p->swtch, -NUM_SWITCH, NUM_SWITCH);
|
||||||
}
|
}
|
||||||
break;
|
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) {
|
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;
|
break;
|
||||||
|
|
||||||
case ITEM_PHASES_FADE_IN:
|
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);
|
if (active) p->fadeIn = checkIncDec(event, p->fadeIn, 0, DELAY_MAX, EE_MODEL|NO_INCDEC_MARKS);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ITEM_PHASES_FADE_OUT:
|
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);
|
if (active) p->fadeOut = checkIncDec(event, p->fadeOut, 0, DELAY_MAX, EE_MODEL|NO_INCDEC_MARKS);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1865,7 +1819,7 @@ void menuModelFlightModesAll(uint8_t event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // LCD_W >= 212
|
#else // PCBTARANIS
|
||||||
|
|
||||||
enum menuModelPhaseItems {
|
enum menuModelPhaseItems {
|
||||||
ITEM_MODEL_PHASE_NAME,
|
ITEM_MODEL_PHASE_NAME,
|
||||||
|
@ -2909,7 +2863,7 @@ void menuModelExpoOne(uint8_t event)
|
||||||
case EXPO_FIELD_SCALE:
|
case EXPO_FIELD_SCALE:
|
||||||
lcd_putsLeft(y, STR_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);
|
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;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -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);
|
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)
|
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) {
|
if (v > TRIM_EXTENDED_MAX) {
|
||||||
uint8_t p = v - TRIM_EXTENDED_MAX - 1;
|
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);
|
putsChnLetter(x, y, idx+1, att);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ROTARY_ENCODERS > 0
|
#if ROTARY_ENCODERS > 0
|
||||||
void putsRotaryEncoderMode(xcoord_t x, uint8_t y, uint8_t phase, uint8_t idx, LcdFlags att)
|
void putsRotaryEncoderMode(xcoord_t x, uint8_t y, uint8_t phase, uint8_t idx, LcdFlags att)
|
||||||
|
|
|
@ -1101,8 +1101,18 @@ PACK(typedef struct t_SwashRingData { // Swash Ring data
|
||||||
#if defined(PCBSTD)
|
#if defined(PCBSTD)
|
||||||
#define TRIMS_ARRAY int8_t trim[4]; int8_t trim_ext:8
|
#define TRIMS_ARRAY int8_t trim[4]; int8_t trim_ext:8
|
||||||
#define TRIMS_ARRAY_SIZE 5
|
#define TRIMS_ARRAY_SIZE 5
|
||||||
|
#define trim_t int16_t
|
||||||
#else
|
#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
|
#define TRIMS_ARRAY_SIZE 8
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1665,38 +1665,82 @@ uint8_t getFlightPhase()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int16_t getRawTrimValue(uint8_t phase, uint8_t idx)
|
trim_t getRawTrimValue(uint8_t phase, uint8_t idx)
|
||||||
{
|
{
|
||||||
PhaseData *p = phaseAddress(phase);
|
PhaseData *p = phaseAddress(phase);
|
||||||
#if defined(PCBSTD)
|
#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
|
#else
|
||||||
return p->trim[idx];
|
return p->trim[idx];
|
||||||
#endif
|
#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<MAX_PHASES; i++) {
|
||||||
|
trim_t v = getRawTrimValue(phase, idx);
|
||||||
|
if (v.mode < 0) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
unsigned int p = v.mode >> 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);
|
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; i<MAX_PHASES; i++) {
|
||||||
|
trim_t & v = phaseAddress(phase)->trim[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<int>(TRIM_EXTENDED_MIN, trim - getTrimValue(p, idx), TRIM_EXTENDED_MAX);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#elif defined(PCBSTD)
|
||||||
PhaseData *p = phaseAddress(phase);
|
PhaseData *p = phaseAddress(phase);
|
||||||
#if defined(PCBSTD)
|
|
||||||
p->trim[idx] = (int8_t)(trim >> 2);
|
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
|
#else
|
||||||
|
PhaseData *p = phaseAddress(phase);
|
||||||
p->trim[idx] = trim;
|
p->trim[idx] = trim;
|
||||||
#endif
|
#endif
|
||||||
eeDirty(EE_MODEL);
|
eeDirty(EE_MODEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(PCBTARANIS)
|
||||||
uint8_t getTrimFlightPhase(uint8_t phase, uint8_t idx)
|
uint8_t getTrimFlightPhase(uint8_t phase, uint8_t idx)
|
||||||
{
|
{
|
||||||
for (uint8_t i=0; i<MAX_PHASES; i++) {
|
for (uint8_t i=0; i<MAX_PHASES; i++) {
|
||||||
if (phase == 0) return 0;
|
if (phase == 0) return 0;
|
||||||
int16_t trim = getRawTrimValue(phase, idx);
|
trim_t trim = getRawTrimValue(phase, idx);
|
||||||
if (trim <= TRIM_EXTENDED_MAX) return phase;
|
if (trim <= TRIM_EXTENDED_MAX) return phase;
|
||||||
uint8_t result = trim-TRIM_EXTENDED_MAX-1;
|
uint8_t result = trim-TRIM_EXTENDED_MAX-1;
|
||||||
if (result >= phase) result++;
|
if (result >= phase) result++;
|
||||||
|
@ -1704,6 +1748,7 @@ uint8_t getTrimFlightPhase(uint8_t phase, uint8_t idx)
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(ROTARY_ENCODERS)
|
#if defined(ROTARY_ENCODERS)
|
||||||
uint8_t getRotaryEncoderFlightPhase(uint8_t idx)
|
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
|
// 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 idx = CONVERT_MODE((uint8_t)k/2);
|
||||||
uint8_t phase;
|
uint8_t phase;
|
||||||
int16_t before;
|
int before;
|
||||||
bool thro;
|
bool thro;
|
||||||
|
|
||||||
#if defined(GVARS)
|
#if defined(GVARS)
|
||||||
|
@ -2360,13 +2405,21 @@ uint8_t checkTrim(uint8_t event)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
phase = getTrimFlightPhase(s_perout_flight_phase, idx);
|
phase = getTrimFlightPhase(s_perout_flight_phase, idx);
|
||||||
|
#if defined(PCBTARANIS)
|
||||||
|
before = getTrimValue(phase, idx);
|
||||||
|
#else
|
||||||
before = getRawTrimValue(phase, idx);
|
before = getRawTrimValue(phase, idx);
|
||||||
|
#endif
|
||||||
thro = (idx==THR_STICK && g_model.thrTrim);
|
thro = (idx==THR_STICK && g_model.thrTrim);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define TRIM_REUSED() 0
|
#define TRIM_REUSED() 0
|
||||||
phase = getTrimFlightPhase(s_perout_flight_phase, idx);
|
phase = getTrimFlightPhase(s_perout_flight_phase, idx);
|
||||||
|
#if defined(PCBTARANIS)
|
||||||
|
before = getTrimValue(phase, idx);
|
||||||
|
#else
|
||||||
before = getRawTrimValue(phase, idx);
|
before = getRawTrimValue(phase, idx);
|
||||||
|
#endif
|
||||||
thro = (idx==THR_STICK && g_model.thrTrim);
|
thro = (idx==THR_STICK && g_model.thrTrim);
|
||||||
#endif
|
#endif
|
||||||
int8_t trimInc = g_model.trimInc + 1;
|
int8_t trimInc = g_model.trimInc + 1;
|
||||||
|
@ -4739,7 +4792,7 @@ void instantTrim()
|
||||||
if (i!=THR_STICK) {
|
if (i!=THR_STICK) {
|
||||||
// don't instant trim the throttle stick
|
// don't instant trim the throttle stick
|
||||||
uint8_t trim_phase = getTrimFlightPhase(s_perout_flight_phase, i);
|
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<int16_t>(TRIM_EXTENDED_MIN, (anas[i] + trims[i]) / 2, TRIM_EXTENDED_MAX);
|
||||||
setTrimValue(trim_phase, i, trim);
|
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) {
|
if (i!=THR_STICK || !g_model.thrTrim) {
|
||||||
int16_t original_trim = getTrimValue(s_perout_flight_phase, i);
|
int16_t original_trim = getTrimValue(s_perout_flight_phase, i);
|
||||||
for (uint8_t phase=0; phase<MAX_PHASES; phase++) {
|
for (uint8_t phase=0; phase<MAX_PHASES; phase++) {
|
||||||
int16_t trim = getRawTrimValue(phase, i);
|
#if defined(PCBTARANIS)
|
||||||
|
// TODO needs to be tested.
|
||||||
|
trim_t trim = getRawTrimValue(phase, i);
|
||||||
|
if (trim.mode / 2 == phase)
|
||||||
|
setTrimValue(phase, i, trim.value - original_trim);
|
||||||
|
#else
|
||||||
|
trim_t trim = getRawTrimValue(phase, i);
|
||||||
if (trim <= TRIM_EXTENDED_MAX)
|
if (trim <= TRIM_EXTENDED_MAX)
|
||||||
setTrimValue(phase, i, trim - original_trim);
|
setTrimValue(phase, i, trim - original_trim);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -875,10 +875,15 @@ int8_t getMovedSwitch();
|
||||||
#define getFlightPhase() 0
|
#define getFlightPhase() 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern uint8_t getTrimFlightPhase(uint8_t phase, uint8_t idx);
|
#if !defined(PCBTARANIS)
|
||||||
extern int16_t getRawTrimValue(uint8_t phase, uint8_t idx);
|
uint8_t getTrimFlightPhase(uint8_t phase, uint8_t idx);
|
||||||
extern int16_t getTrimValue(uint8_t phase, uint8_t idx);
|
#else
|
||||||
extern void setTrimValue(uint8_t phase, uint8_t idx, int16_t trim);
|
#define getTrimFlightPhase(phase, idx) (phase)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
trim_t getRawTrimValue(uint8_t phase, uint8_t idx);
|
||||||
|
int getTrimValue(uint8_t phase, uint8_t idx);
|
||||||
|
void setTrimValue(uint8_t phase, uint8_t idx, int trim);
|
||||||
|
|
||||||
#if defined(ROTARY_ENCODERS)
|
#if defined(ROTARY_ENCODERS)
|
||||||
int16_t getRotaryEncoder(uint8_t idx);
|
int16_t getRotaryEncoder(uint8_t idx);
|
||||||
|
|
|
@ -711,7 +711,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Taranis column headers
|
// Taranis column headers
|
||||||
#define TR_PHASES_HEADERS { " Name ", " Switch ", " Trims ", " Fade In ", " Fade Out " }
|
#define TR_PHASES_HEADERS { " Name ", " Switch ", " Rudder Trim ", " Elevator Trim ", " Throttle Trim ", " Aileron Trim ", " Fade In ", " Fade Out " }
|
||||||
#define TR_LIMITS_HEADERS { " Name ", " Subtrim ", " Min ", " Max ", " Direction ", " Curve ", " PPM Center ", " Subtrim mode " }
|
#define TR_LIMITS_HEADERS { " Name ", " Subtrim ", " Min ", " Max ", " Direction ", " Curve ", " PPM Center ", " Subtrim mode " }
|
||||||
#define TR_CSW_HEADERS { " Function ", " V1 ", " V2 ", " AND Switch ", " Duration ", " Delay " }
|
#define TR_CSW_HEADERS { " Function ", " V1 ", " V2 ", " AND Switch ", " Duration ", " Delay " }
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue