diff --git a/CREDITS.txt b/CREDITS.txt index c9f3d46c8..4d36d8d36 100644 --- a/CREDITS.txt +++ b/CREDITS.txt @@ -19,3 +19,4 @@ Grootwitbaas - 9xforums.com (mac) Adrian Amberg (splash screens) Wallaguest1 - 9xforums.com (splash screens) HC1969 - 9xforums.com (splash screens) + diff --git a/companion/src/comparedialog.cpp b/companion/src/comparedialog.cpp index 6b1609c0e..9a50f283c 100644 --- a/companion/src/comparedialog.cpp +++ b/companion/src/comparedialog.cpp @@ -83,7 +83,6 @@ void compareDialog::printDiff() printCurves(); printGvars(); printSwitches(); - printSafetySwitches(); printFSwitches(); printFrSky(); te->scrollToAnchor("1"); @@ -1041,8 +1040,8 @@ void compareDialog::printSwitches() str.append("

"+tr("Logical Switches")+"

"); str.append(""); for (int i=0; igetCapability(CustomSwitches); i++) { - QString sw1 = getCustomSwitchStr(&g_model1->customSw[i], *g_model1); - QString sw2 = getCustomSwitchStr(&g_model2->customSw[i], *g_model2); + QString sw1 = g_model1->customSw[i].toString(*g_model1); + QString sw2 = g_model2->customSw[i].toString(*g_model2); if (!(sw1.isEmpty() && sw2.isEmpty())) { str.append(""); color=getColor1(sw1,sw2); @@ -1096,8 +1095,8 @@ void compareDialog::printFSwitches() str.append(""); if (g_model1->funcSw[i].swtch.type) { str.append(doTC(g_model1->funcSw[i].swtch.toString(),color1)); - str.append(doTC(getFuncName(g_model1->funcSw[i].func),color1)); - str.append(doTC(FuncParam(g_model1->funcSw[i].func,g_model1->funcSw[i].param,g_model1->funcSw[i].paramarm, g_model1->funcSw[i].adjustMode),color1)); + str.append(doTC(g_model1->funcSw[i].funcToString(),color1)); + str.append(doTC(g_model1->funcSw[i].paramToString(),color1)); int index=g_model1->funcSw[i].func; if (index==FuncPlaySound || index==FuncPlayHaptic || index==FuncPlayValue || index==FuncPlayPrompt || index==FuncPlayBoth || index==FuncBackgroundMusic) { str.append(doTC(QString("%1").arg(g_model1->funcSw[i].repeatParam),color1)); @@ -1115,8 +1114,8 @@ void compareDialog::printFSwitches() str.append(doTC(tr("CF")+QString("%1").arg(i+1),"",true)); if (g_model2->funcSw[i].swtch.type) { str.append(doTC(g_model2->funcSw[i].swtch.toString(),color2)); - str.append(doTC(getFuncName(g_model2->funcSw[i].func),color2)); - str.append(doTC(FuncParam(g_model2->funcSw[i].func,g_model2->funcSw[i].param,g_model2->funcSw[i].paramarm, g_model2->funcSw[i].adjustMode),color2)); + str.append(doTC(g_model2->funcSw[i].funcToString(),color2)); + str.append(doTC(g_model2->funcSw[i].paramToString(),color2)); int index=g_model2->funcSw[i].func; if (index==FuncPlaySound || index==FuncPlayHaptic || index==FuncPlayValue || index==FuncPlayPrompt || index==FuncPlayBoth || index==FuncBackgroundMusic) { str.append(doTC(QString("%1").arg(g_model2->funcSw[i].repeatParam),color2)); @@ -1142,55 +1141,6 @@ void compareDialog::printFSwitches() te->append(str); } -void compareDialog::printSafetySwitches() -{ - QString color1; - QString color2; - int sc=0; - QString str = "
"; - str.append(""); - str.append("

"+tr("Safety Switches")+"

"); - str.append(""); - str.append(""); - str.append(""); - str.append(""); - str.append(""); - str.append(""); - for(int i=0; igetCapability(Outputs); i++) - { - if ((g_model1->safetySw[i].swtch.type!=SWITCH_TYPE_NONE)||(g_model2->safetySw[i].swtch.type!=SWITCH_TYPE_NONE)) { - if ((g_model1->safetySw[i].swtch!=g_model2->safetySw[i].swtch)||(g_model1->safetySw[i].val!=g_model2->safetySw[i].val)) { - color1="green"; - color2="red"; - } else { - color1="grey"; - color2="grey"; - } - str.append(""); - if (g_model1->safetySw[i].swtch.type) { - str.append(doTC(g_model1->safetySw[i].swtch.toString(),color1)); - str.append(doTC(QString::number(g_model1->safetySw[i].val),color1)); - } - else { - str.append(""); - } - str.append(doTC(tr("CH")+QString("%1").arg(i+1),"",true)); - if (g_model2->safetySw[i].swtch.type) { - str.append(doTC(g_model2->safetySw[i].swtch.toString(),color2)); - str.append(doTC(QString::number(g_model2->safetySw[i].val),color2)); - } else { - str.append(""); - } - str.append(""); - sc++; - } -} - str.append("
"+tr("Switch")+""+tr("Value")+" "+tr("Switch")+""+tr("Value")+"
    
"); - str.append("
"); - if (sc!=0) - te->append(str); -} - void compareDialog::printFrSky() { QString color; diff --git a/companion/src/eepromimportexport.h b/companion/src/eepromimportexport.h index ed5ab9ff5..91eda318c 100644 --- a/companion/src/eepromimportexport.h +++ b/companion/src/eepromimportexport.h @@ -93,6 +93,17 @@ class DataField { const char *name; }; +class ProxyField: public DataField { + public: + ProxyField(): + DataField("Proxy") + { + } + + virtual DataField * getField() = 0; + +}; + template class UnsignedField: public DataField { public: @@ -273,9 +284,10 @@ class SpareBitsField: public UnsignedField { template class CharField: public DataField { public: - CharField(char *field): + CharField(char *field, bool truncate=true): DataField("Char"), - field(field) + field(field), + truncate(truncate) { } @@ -283,7 +295,7 @@ class CharField: public DataField { { output.resize(N*8); int b = 0; - int len = strlen(field); + int len = truncate ? strlen(field) : N; for (int i=0; i=len ? 0 : field[i]); for (int j=0; j<8; j++, b++) { @@ -313,6 +325,7 @@ class CharField: public DataField { protected: char * field; + bool truncate; }; int8_t char2idx(char c); diff --git a/companion/src/eeprominterface.cpp b/companion/src/eeprominterface.cpp index ba52bd55f..7e838e19f 100644 --- a/companion/src/eeprominterface.cpp +++ b/companion/src/eeprominterface.cpp @@ -268,62 +268,52 @@ QString RawSwitch::toString() QObject::tr("S21"), QObject::tr("S22"), QObject::tr("S23"), QObject::tr("S24"), QObject::tr("S25"), QObject::tr("S26") }; - switch(type) { - case SWITCH_TYPE_SWITCH: - if (IS_TARANIS(GetEepromInterface()->getBoard())) - return index > 0 ? CHECK_IN_ARRAY(switchesX9D, index-1) : QString("!") + CHECK_IN_ARRAY(switchesX9D, -index-1); - else - return index > 0 ? CHECK_IN_ARRAY(switches9X, index-1) : QString("!") + CHECK_IN_ARRAY(switches9X, -index-1); - case SWITCH_TYPE_VIRTUAL: - return index > 0 ? CHECK_IN_ARRAY(virtualSwitches, index-1) : QString("!") + CHECK_IN_ARRAY(virtualSwitches, -index-1); - case SWITCH_TYPE_MULTIPOS_POT: - return CHECK_IN_ARRAY(multiposPots, index); - case SWITCH_TYPE_ON: - return QObject::tr("ON"); - case SWITCH_TYPE_ONM: - if (index==0) { - return QObject::tr("ONE"); - } - else if (index==1) { - return QObject::tr("!ONE"); - } - break; - case SWITCH_TYPE_TRN: - if (index==0) { - if (IS_TARANIS(GetEepromInterface()->getBoard())) - return SwitchDn('H')+"s"; - else - return QObject::tr("TRNs"); - } else if (index==1) { - if (IS_TARANIS(GetEepromInterface()->getBoard())) - return SwitchDn('H')+"l"; - else - return QObject::tr("TRNl"); - } - break; - case SWITCH_TYPE_REA: - if (index==0) { - if (GetEepromInterface()->getBoard() == BOARD_SKY9X) - return QObject::tr("REAs"); - } else if (index==1) { - if (GetEepromInterface()->getBoard() == BOARD_SKY9X) - return QObject::tr("REAl"); - } - break; - case SWITCH_TYPE_OFF: - return QObject::tr("OFF"); - case SWITCH_TYPE_MOMENT_SWITCH: - if (IS_TARANIS(GetEepromInterface()->getBoard())) - return index > 0 ? CHECK_IN_ARRAY(switchesX9D, index-1)+QString("t") : QString("!")+CHECK_IN_ARRAY(switchesX9D, -index-1)+QString("t"); - else - return index > 0 ? CHECK_IN_ARRAY(switches9X, index-1)+QString("t") : QString("!")+CHECK_IN_ARRAY(switches9X, -index-1)+QString("t"); - case SWITCH_TYPE_MOMENT_VIRTUAL: - return index > 0 ? CHECK_IN_ARRAY(virtualSwitches, index-1)+QString("t") : QString("!")+CHECK_IN_ARRAY(virtualSwitches, -index-1)+QString("t"); - default: - break; - } + static const QString trimsSwitches[] = { + QObject::tr("RudTrim Left"), QObject::tr("RudTrim Right"), + QObject::tr("EleTrim Down"), QObject::tr("EleTrim Up"), + QObject::tr("ThrTrim Down"), QObject::tr("ThrTrim Up"), + QObject::tr("AilTrim Left"), QObject::tr("AilTrim Right") + }; - return QObject::tr("----"); + static const QString rotaryEncoders[] = { + QObject::tr("REa"), QObject::tr("REb") + }; + + static const QString timerModes[] = { + QObject::tr("OFF"), QObject::tr("ABS"), + QObject::tr("THs"), QObject::tr("TH%"), QObject::tr("THt") + }; + + if (index < 0) { + return QString("!") + RawSwitch(type, -index).toString(); + } + else { + switch(type) { + case SWITCH_TYPE_SWITCH: + if (IS_TARANIS(GetEepromInterface()->getBoard())) + return CHECK_IN_ARRAY(switchesX9D, index-1); + else + return CHECK_IN_ARRAY(switches9X, index-1); + case SWITCH_TYPE_VIRTUAL: + return CHECK_IN_ARRAY(virtualSwitches, index-1); + case SWITCH_TYPE_MULTIPOS_POT: + return CHECK_IN_ARRAY(multiposPots, index-1); + case SWITCH_TYPE_TRIM: + return CHECK_IN_ARRAY(trimsSwitches, index-1); + case SWITCH_TYPE_ROTARY_ENCODER: + return CHECK_IN_ARRAY(rotaryEncoders, index-1); + case SWITCH_TYPE_ON: + return QObject::tr("ON"); + case SWITCH_TYPE_OFF: + return QObject::tr("OFF"); + case SWITCH_TYPE_NONE: + return QObject::tr("----"); + case SWITCH_TYPE_TIMER_MODE: + return CHECK_IN_ARRAY(timerModes, index); + default: + return QObject::tr("???"); + } + } } QString CurveReference::toString() @@ -345,6 +335,390 @@ QString CurveReference::toString() } } +CSFunctionFamily CustomSwData::getFunctionFamily() +{ + if (func == CS_FN_STAY) + return CS_FAMILY_STAY; + else if (func == CS_FN_TIMER) + return CS_FAMILY_TIMER; + else if (func == CS_FN_STICKY) + return CS_FAMILY_STICKY; + else if (func < CS_FN_AND || func > CS_FN_ELESS) + return CS_FAMILY_VOFS; + else if (func < CS_FN_EQUAL) + return CS_FAMILY_VBOOL; + else + return CS_FAMILY_VCOMP; +} + +QString CustomSwData::funcToString() +{ + switch (func) { + case CS_FN_OFF: + return QObject::tr("---"); + case CS_FN_VPOS: + return QObject::tr("a>x"); + case CS_FN_VNEG: + return QObject::tr("ax"); + case CS_FN_ANEG: + return QObject::tr("|a|b"); + case CS_FN_LESS: + return QObject::tr("a=b"); + case CS_FN_ELESS: + return QObject::tr("a<=b"); + case CS_FN_DPOS: + return QObject::tr("d>=x"); + case CS_FN_DAPOS: + return QObject::tr("|d|>=x"); + case CS_FN_VEQUAL: + return QObject::tr("a~x"); + case CS_FN_TIMER: + return QObject::tr("Timer"); + case CS_FN_STICKY: + return QObject::tr("Sticky"); + case CS_FN_STAY: + return QObject::tr("Stay"); + default: + return QObject::tr("Unknown"); + } +} + +QString CustomSwData::toString(const ModelData & model) +{ + QString result = ""; + + if (!func) + return result; + + if (andsw!=0) { + result +="( "; + } + switch (getFunctionFamily()) { + case CS_FAMILY_STAY: + result = QObject::tr("STAY(%1, [%2:%3])").arg(RawSwitch(val1).toString()).arg(ValToTim(val2)).arg(ValToTim(val2+val3)); + break; + case CS_FAMILY_STICKY: + result = QObject::tr("STICKY(%1, %2)").arg(RawSwitch(val1).toString()).arg(RawSwitch(val2).toString()); + break; + case CS_FAMILY_TIMER: + result = QObject::tr("TIMER(%1, %2)").arg(ValToTim(val1)).arg(ValToTim(val2)); + break; + case CS_FAMILY_VOFS: { + RawSource source = RawSource(val1, &model); + RawSourceRange range = source.getRange(); + if (val1) + result += source.toString(); + else + result += "0"; + result.remove(" "); + if (func == CS_FN_APOS || func == CS_FN_ANEG) + result = "|" + result + "|"; + else if (func == CS_FN_DAPOS) + result = "|d(" + result + ")|"; + else if (func == CS_FN_DPOS) result = "d(" + result + ")"; + if (func == CS_FN_APOS || func == CS_FN_VPOS || func == CS_FN_DAPOS || func == CS_FN_DPOS) + result += " > "; + else if (func == CS_FN_ANEG || func == CS_FN_VNEG) + result += " < "; + result += QString::number(range.step * (val2 /*TODO+ source.getRawOffset(model)*/) + range.offset); + break; + } + case CS_FAMILY_VBOOL: + result = RawSwitch(val1).toString(); + switch (func) { + case CS_FN_AND: + result += " AND "; + break; + case CS_FN_OR: + result += " OR "; + break; + case CS_FN_XOR: + result += " XOR "; + break; + default: + break; + } + result += RawSwitch(val2).toString(); + break; + + case CS_FAMILY_VCOMP: + if (val1) + result += RawSource(val1).toString(); + else + result += "0"; + switch (func) { + case CS_FN_EQUAL: + result += " = "; + break; + case CS_FN_NEQUAL: + result += " != "; + break; + case CS_FN_GREATER: + result += " > "; + break; + case CS_FN_LESS: + result += " < "; + break; + case CS_FN_EGREATER: + result += " >= "; + break; + case CS_FN_ELESS: + result += " <= "; + break; + default: + break; + } + if (val2) + result += RawSource(val2).toString(); + else + result += "0"; + break; + } + + if (andsw!=0) { + result +=" ) AND "; + result += RawSwitch(andsw).toString(); + } + + if (GetEepromInterface()->getCapability(CustomSwitchesExt)) { + if (delay) + result += QObject::tr(" Delay %1 sec").arg(delay/2.0); + if (duration) + result += QObject::tr(" Duration %1 sec").arg(duration/2.0); + } + + return result; +} + +#if 0 +QStringList FuncSwData::toStringList() +{ + QStringList result; + QStringList qs; + + result << swtch.toString(); + result << funcToString(); + + if (func < FuncInstantTrim) { + result << QString("%1").arg(param); + } + else if (func==FuncPlaySound) { + qs <<"Beep 1" << "Beep 2" << "Beep 3" << "Warn1" << "Warn2" << "Cheep" << "Ratata" << "Tick" << "Siren" << "Ring" ; + qs << "SciFi" << "Robot" << "Chirp" << "Tada" << "Crickt" << "AlmClk" ; + if (param>=0 && param<(int)qs.count()) + result << qs.at(param); + else + result << QObject::tr("Inconsistent parameter"); + } + else if (func==FuncPlayHaptic) { + qs << "0" << "1" << "2" << "3"; + if (param>=0 && param<(int)qs.count()) + result << qs.at(param); + else + result << QObject::tr("Inconsistent parameter"); + } + else if (func==FuncReset) { + qs.append( QObject::tr("Timer1")); + qs.append( QObject::tr("Timer2")); + qs.append( QObject::tr("All")); + qs.append( QObject::tr("Telemetry")); + if (param>=0 && param<(int)qs.count()) + result << qs.at(param); + else + result << QObject::tr("Inconsistent parameter"); + } + else if ((func==FuncVolume)|| (func==FuncPlayValue)) { + RawSource item(param); + result << item.toString(); + } + else if ((func==FuncPlayPrompt) || (func==FuncPlayBoth)) { + if ( GetEepromInterface()->getCapability(VoicesAsNumbers)) { + result << QString("%1").arg(param); + } else { + result << paramarm; + } + } + else if ((func>FuncBackgroundMusicPause) && (funcfuncSw[i].repeatParam),"green")); + } else { + str.append(doTC( " ","green")); + } + if ((index<=FuncInstantTrim) || (index>FuncBackgroundMusicPause)) { + str.append(doTC((g_model->funcSw[i].enabled ? "ON" : "OFF"),"green")); + } else { + str.append(doTC( "---","green")); + } + + return result; +} +#endif + +QString FuncSwData::funcToString() +{ + if (func >= FuncSafetyCh1 && func <= FuncSafetyCh32) + return QObject::tr("Safety %1").arg(RawSource(SOURCE_TYPE_CH, func).toString()); + else if (func == FuncTrainer) + return QObject::tr("Trainer"); + else if (func == FuncTrainerRUD) + return QObject::tr("Trainer RUD"); + else if (func == FuncTrainerELE) + return QObject::tr("Trainer ELE"); + else if (func == FuncTrainerTHR) + return QObject::tr("Trainer THR"); + else if (func == FuncTrainerAIL) + return QObject::tr("Trainer AIL"); + else if (func == FuncInstantTrim) + return QObject::tr("Instant Trim"); + else if (func == FuncPlaySound) + return QObject::tr("Play Sound"); + else if (func == FuncPlayHaptic) + return QObject::tr("Play Haptic"); + else if (func == FuncReset) + return QObject::tr("Reset"); + else if (func == FuncVario) + return QObject::tr("Vario"); + else if (func == FuncPlayPrompt) + return QObject::tr("Play Track"); + else if (func == FuncPlayBoth) + return QObject::tr("Play Both"); + else if (func == FuncPlayValue) + return QObject::tr("Play Value"); + else if (func == FuncLogs) + return QObject::tr("Start Logs"); + else if (func == FuncVolume) + return QObject::tr("Volume"); + else if (func == FuncBacklight) + return QObject::tr("Backlight"); + else if (func == FuncBackgroundMusic) + return QObject::tr("Background Music"); + else if (func == FuncBackgroundMusicPause) + return QObject::tr("Background Music Pause"); + else if (func >= FuncAdjustGV1 && func <= FuncAdjustGVLast) + return QObject::tr("Adjust GV%1").arg(func-FuncAdjustGV1+1); + else { + return QString("???"); // Highlight unknown functions with output of question marks.(BTW should not happen that we do not know what a function is) + } +} + +QString FuncSwData::paramToString() +{ + QStringList qs; + if (func <= FuncInstantTrim) { + return QString("%1").arg(param); + } + else if (func==FuncPlaySound) { + qs <<"Beep 1" << "Beep 2" << "Beep 3" << "Warn1" << "Warn2" << "Cheep" << "Ratata" << "Tick" << "Siren" << "Ring" ; + qs << "SciFi" << "Robot" << "Chirp" << "Tada" << "Crickt" << "AlmClk" ; + if (param>=0 && param<(int)qs.count()) + return qs.at(param); + else + return QObject::tr("Inconsistent parameter"); + } + else if (func==FuncPlayHaptic) { + qs << "0" << "1" << "2" << "3"; + if (param>=0 && param<(int)qs.count()) + return qs.at(param); + else + return QObject::tr("Inconsistent parameter"); + } + else if (func==FuncReset) { + qs.append( QObject::tr("Timer1")); + qs.append( QObject::tr("Timer2")); + qs.append( QObject::tr("All")); + qs.append( QObject::tr("Telemetry")); + if (param>=0 && param<(int)qs.count()) + return qs.at(param); + else + return QObject::tr("Inconsistent parameter"); + } + else if ((func==FuncVolume)|| (func==FuncPlayValue)) { + RawSource item(param); + return item.toString(); + } + else if ((func==FuncPlayPrompt) || (func==FuncPlayBoth)) { + if ( GetEepromInterface()->getCapability(VoicesAsNumbers)) { + return QString("%1").arg(param); + } else { + return paramarm; + } + } + else if ((func>FuncBackgroundMusicPause) && (funcgetBoard()) ? 5 : 10; + return QObject::tr("%1 sec").arg(step*repeatParam); + } +} + GeneralSettings::GeneralSettings() { memset(this, 0, sizeof(GeneralSettings)); @@ -497,7 +871,8 @@ void ModelData::clear() if (IS_TARANIS(board)) { moduleData[0].protocol=PXX_XJT_X16; moduleData[1].protocol=OFF; - } else { + } + else { moduleData[0].protocol=PPM; moduleData[1].protocol=OFF; } @@ -505,20 +880,17 @@ void ModelData::clear() phaseData[i].clear(); clearInputs(); clearMixes(); - for(int i=0; i<4; i++){ - mixData[i].destCh = i+1; - mixData[i].srcRaw = RawSource(SOURCE_TYPE_STICK, i); - mixData[i].weight = 100; - } + for (int i=0; iCS_FN_ELESS) ? CS_FAMILY_VOFS : (fnfunc = func; + } + unsigned int func; + int val1; + int val2; + int val3; + unsigned int delay; + unsigned int duration; + int andsw; + void clear() { memset(this, 0, sizeof(CustomSwData)); } + CSFunctionFamily getFunctionFamily(); + QString funcToString(); + QString toString(const ModelData & model); }; enum AssignFunc { FuncSafetyCh1 = 0, - FuncSafetyCh16 = FuncSafetyCh1+15, + FuncSafetyCh32 = FuncSafetyCh1+C9X_NUM_CHNOUT-1, FuncTrainer, FuncTrainerRUD, FuncTrainerELE, @@ -666,7 +658,7 @@ enum AssignFunc { class FuncSwData { // Function Switches data public: - FuncSwData() { clear(); } + FuncSwData(AssignFunc func=FuncSafetyCh1) { clear(); this->func = func; } RawSwitch swtch; AssignFunc func; int param; @@ -675,6 +667,10 @@ class FuncSwData { // Function Switches data unsigned int adjustMode; int repeatParam; void clear() { memset(this, 0, sizeof(FuncSwData)); } + QString funcToString(); + QString paramToString(); + QString repeatToString(); + QStringList toStringList(); }; class PhaseData { @@ -809,32 +805,17 @@ class MavlinkData { void clear() { memset(this, 0, sizeof(MavlinkData)); } }; -enum TimerMode { - TMRMODE_OFF=0, - TMRMODE_ABS, - TMRMODE_THs, - TMRMODE_THp, - TMRMODE_THt, - TMRMODE_FIRST_SWITCH, - TMRMODE_FIRST_MOMENT_SWITCH = TMRMODE_FIRST_SWITCH+64, - TMRMODE_FIRST_CHPERC = TMRMODE_FIRST_MOMENT_SWITCH+64, - - TMRMODE_FIRST_NEG_SWITCH=-TMRMODE_FIRST_SWITCH, - TMRMODE_FIRST_NEG_MOMENT_SWITCH=-TMRMODE_FIRST_MOMENT_SWITCH, - /* sw/!sw, !m_sw/!m_sw */ -}; - class TimerData { public: TimerData() { clear(); } - TimerMode mode; // timer trigger source -> off, abs, THs, TH%, THt, sw/!sw, !m_sw/!m_sw + RawSwitch mode; bool minuteBeep; unsigned int countdownBeep; bool dir; // 0=>Count Down, 1=>Count Up unsigned int val; bool persistent; int pvalue; - void clear() { memset(this, 0, sizeof(TimerData)); } + void clear() { memset(this, 0, sizeof(TimerData)); mode = RawSwitch(SWITCH_TYPE_TIMER_MODE, 0); } }; enum Protocol { @@ -897,11 +878,9 @@ class ModelData { CurveData curves[C9X_MAX_CURVES]; CustomSwData customSw[C9X_NUM_CSW]; FuncSwData funcSw[C9X_MAX_CUSTOM_FUNCTIONS]; - SafetySwData safetySw[C9X_NUM_CHNOUT]; SwashRingData swashRingData; unsigned int thrTraceSrc; int8_t traineron; // 0 disable trainer, 1 allow trainer - int8_t t2throttle; // Start timer2 using throttle unsigned int modelId; unsigned int switchWarningStates; // TODO structure @@ -1100,10 +1079,6 @@ class EEPROMInterface virtual int isAvailable(Protocol proto, int port=0) = 0; - virtual bool isAvailable(const RawSwitch & swtch, UseContext context) { return true; } - - virtual bool isAvailable(const RawSource & source, UseContext context) { return true; } - virtual SimulatorInterface * getSimulator() = 0; virtual const int getEEpromSize() = 0; @@ -1185,7 +1160,7 @@ inline void applyStickModeToModel(ModelData &model, unsigned int mode) // virtual switches for (int i=0; i 0 ? sw-22 : sw+22); + return RawSwitch(SWITCH_TYPE_SWITCH, sw > 0 ? sw-22 : sw+22); else - return RawSwitch(SWITCH_TYPE_MOMENT_VIRTUAL, sw > 0 ? sw-22-9 : sw+22+9); + return RawSwitch(SWITCH_TYPE_VIRTUAL, sw > 0 ? sw-22-9 : sw+22+9); } t_Er9xTrainerMix::t_Er9xTrainerMix() @@ -298,14 +298,6 @@ t_Er9xSafetySwData::t_Er9xSafetySwData() memset(this, 0, sizeof(t_Er9xSafetySwData)); } -t_Er9xSafetySwData::operator SafetySwData () -{ - SafetySwData c9x; - c9x.swtch = er9xToSwitch(swtch); - c9x.val = val; - return c9x; -} - t_Er9xFrSkyChannelData::t_Er9xFrSkyChannelData() { memset(this, 0, sizeof(t_Er9xFrSkyChannelData)); @@ -343,10 +335,11 @@ t_Er9xFrSkyData::operator FrSkyData () return c9x; } -TimerMode getEr9xTimerMode(int mode) +RawSwitch getEr9xTimerMode(int mode) { + /* if (mode <= -33) - return TimerMode(TMRMODE_FIRST_NEG_MOMENT_SWITCH+(mode+33)); + return TimerMode(TMRMODE_FIRST_NEG_SWITCH+(mode+33)); else if (mode <= -1) return TimerMode(TMRMODE_FIRST_NEG_SWITCH+(mode+1)); else if (mode < 16) @@ -354,7 +347,9 @@ TimerMode getEr9xTimerMode(int mode) else if (mode < 16+21) return TimerMode(TMRMODE_FIRST_SWITCH+(mode-16)); else - return TimerMode(TMRMODE_FIRST_MOMENT_SWITCH+(mode-16-21)); + return TimerMode(TMRMODE_FIRST_SWITCH+(mode-16-21)); + */ + return RawSwitch(); } t_Er9xModelData::operator ModelData () @@ -381,7 +376,7 @@ t_Er9xModelData::operator ModelData () break; } c9x.traineron= traineron; - c9x.t2throttle = t2throttle; + // c9x.t2throttle = t2throttle; c9x.moduleData[0].ppmFrameLength=ppmFrameLength; c9x.moduleData[0].channelsCount = 8 + 2 * ppmNCH; c9x.thrTrim = thrTrim; @@ -471,8 +466,8 @@ t_Er9xModelData::operator ModelData () for (int i=0; i 0 ? sw-34 : sw+34); + return RawSwitch(SWITCH_TYPE_SWITCH, sw > 0 ? sw-34 : sw+34); else - return RawSwitch(SWITCH_TYPE_MOMENT_VIRTUAL, sw > 0 ? sw-34-9 : sw+34+9); + return RawSwitch(SWITCH_TYPE_VIRTUAL, sw > 0 ? sw-34-9 : sw+34+9); } t_Ersky9xTrainerMix::t_Ersky9xTrainerMix() @@ -406,27 +404,11 @@ t_Ersky9xSafetySwData_v10::t_Ersky9xSafetySwData_v10() memset(this, 0, sizeof(t_Ersky9xSafetySwData_v10)); } -t_Ersky9xSafetySwData_v10::operator SafetySwData () -{ - SafetySwData c9x; - c9x.swtch = er9xToSwitch(swtch); - c9x.val = val; - return c9x; -} - t_Ersky9xSafetySwData_v11::t_Ersky9xSafetySwData_v11() { memset(this, 0, sizeof(t_Ersky9xSafetySwData_v11)); } -t_Ersky9xSafetySwData_v11::operator SafetySwData () -{ - SafetySwData c9x; - c9x.swtch = ersky9xToSwitch(opt.ss.swtch); - c9x.val = opt.ss.val; - return c9x; -} - t_Ersky9xFrSkyChannelData_v10::t_Ersky9xFrSkyChannelData_v10() { memset(this, 0, sizeof(t_Ersky9xFrSkyChannelData_v10)); @@ -612,8 +594,8 @@ t_Ersky9xModelData_v10::operator ModelData () for (int i=0; i #include "eeprominterface.h" -extern TimerMode getEr9xTimerMode(int mode); -extern int setEr9xTimerMode(TimerMode mode); +extern RawSwitch getEr9xTimerMode(int mode); //eeprom data #define ERSKY9X_MAX_MIXERS_V10 32 @@ -210,7 +209,6 @@ PACK(typedef struct t_Ersky9xSafetySwData_v10 { // Custom Switches data int8_t swtch; int8_t val; - operator SafetySwData(); t_Ersky9xSafetySwData_v10(); }) Ersky9xSafetySwData_v10; @@ -230,7 +228,6 @@ PACK(typedef struct t_Ersky9xSafetySwData_v11 { // Custom Switches data } vs ; } opt ; - operator SafetySwData(); t_Ersky9xSafetySwData_v11(); }) Ersky9xSafetySwData_v11; diff --git a/companion/src/firmwares/ersky9x/ersky9xinterface.cpp b/companion/src/firmwares/ersky9x/ersky9xinterface.cpp index 17229bb08..28d97d068 100644 --- a/companion/src/firmwares/ersky9x/ersky9xinterface.cpp +++ b/companion/src/firmwares/ersky9x/ersky9xinterface.cpp @@ -74,7 +74,7 @@ inline void applyStickModeToModel(Ersky9xModelData_v10 & model, unsigned int mod for (int i=0; i 0 ? sw-42 : sw+42); + return RawSwitch(SWITCH_TYPE_SWITCH, sw > 0 ? sw-42 : sw+42); else - return RawSwitch(SWITCH_TYPE_MOMENT_VIRTUAL, sw > 0 ? sw-42-9 : sw+42+9); + return RawSwitch(SWITCH_TYPE_VIRTUAL, sw > 0 ? sw-42-9 : sw+42+9); } RawSource open9xArm208ToSource(int8_t value) @@ -124,9 +124,9 @@ RawSource open9xArm210ToSource(int8_t value) t_Open9xArmTimerData_v202::operator TimerData () { TimerData c9x; - +/* if (mode <= -42) - c9x.mode = TimerMode(TMRMODE_FIRST_NEG_MOMENT_SWITCH+(mode+22)); + c9x.mode = TimerMode(TMRMODE_FIRST_NEG_SWITCH+(mode+22)); else if (mode <= -1) c9x.mode = TimerMode(TMRMODE_FIRST_NEG_SWITCH+(mode+1)); else if (mode < 5) @@ -134,8 +134,8 @@ t_Open9xArmTimerData_v202::operator TimerData () else if (mode < 5+41) c9x.mode = TimerMode(TMRMODE_FIRST_SWITCH+(mode-5)); else - c9x.mode = TimerMode(TMRMODE_FIRST_MOMENT_SWITCH+(mode-5-21)); - + c9x.mode = TimerMode(TMRMODE_FIRST_SWITCH+(mode-5-21)); +*/ c9x.val = val; c9x.persistent = false; c9x.dir = (val == 0); @@ -577,7 +577,7 @@ t_Open9xArmFuncSwData_v208::operator FuncSwData () FuncSwData c9x; c9x.swtch = open9xArmToSwitch(swtch); c9x.func = (AssignFunc)(func); - if (c9x.func <= FuncSafetyCh16) { + if (c9x.func <= FuncSafetyCh32) { c9x.enabled=param & 0x01; c9x.param = (param>>1)<<1; } diff --git a/companion/src/firmwares/opentx/open9xStockeeprom.cpp b/companion/src/firmwares/opentx/open9xStockeeprom.cpp index 9989cf8c5..0e6e010b6 100644 --- a/companion/src/firmwares/opentx/open9xStockeeprom.cpp +++ b/companion/src/firmwares/opentx/open9xStockeeprom.cpp @@ -74,13 +74,13 @@ RawSwitch open9xStockToSwitch(int8_t sw) else if (sw == 22) return RawSwitch(SWITCH_TYPE_ON); else if (sw == 44) - return RawSwitch(SWITCH_TYPE_ONM); + return RawSwitch(SWITCH_TYPE_ON); else if (sw == -22) return RawSwitch(SWITCH_TYPE_OFF); else if (swa <= 22+9) - return RawSwitch(SWITCH_TYPE_MOMENT_SWITCH, sw > 0 ? sw-22 : sw+22); + return RawSwitch(SWITCH_TYPE_SWITCH, sw > 0 ? sw-22 : sw+22); else - return RawSwitch(SWITCH_TYPE_MOMENT_VIRTUAL, sw > 0 ? sw-22-9 : sw+22+9); + return RawSwitch(SWITCH_TYPE_VIRTUAL, sw > 0 ? sw-22-9 : sw+22+9); } t_Open9xExpoData_v201::operator ExpoData () @@ -662,14 +662,6 @@ t_Open9xFuncSwData_v210::operator FuncSwData () return c9x; } -t_Open9xSafetySwData::operator SafetySwData () -{ - SafetySwData c9x; - c9x.swtch = open9xStockToSwitch(swtch); - c9x.val = val; - return c9x; -} - t_Open9xSwashRingData_v208::operator SwashRingData () { SwashRingData c9x; @@ -709,7 +701,7 @@ t_Open9xPhaseData_v201::operator PhaseData () t_Open9xTimerData_v201::operator TimerData () { TimerData c9x; - c9x.mode = TMRMODE_OFF; + // c9x.mode = TMRMODE_OFF; c9x.val = val; c9x.persistent = persistent; c9x.dir = dir; @@ -719,9 +711,9 @@ t_Open9xTimerData_v201::operator TimerData () t_Open9xTimerData_v202::operator TimerData () { TimerData c9x; - +/* if (mode <= -22) - c9x.mode = TimerMode(TMRMODE_FIRST_NEG_MOMENT_SWITCH+(mode+22)); + c9x.mode = TimerMode(TMRMODE_FIRST_NEG_SWITCH+(mode+22)); else if (mode <= -1) c9x.mode = TimerMode(TMRMODE_FIRST_NEG_SWITCH+(mode+1)); else if (mode < 5) @@ -729,8 +721,8 @@ t_Open9xTimerData_v202::operator TimerData () else if (mode < 5+21) c9x.mode = TimerMode(TMRMODE_FIRST_SWITCH+(mode-5)); else - c9x.mode = TimerMode(TMRMODE_FIRST_MOMENT_SWITCH+(mode-5-21)); - + c9x.mode = TimerMode(TMRMODE_FIRST_SWITCH+(mode-5-21)); +*/ c9x.val = val; c9x.persistent = false; c9x.dir = (val == 0); @@ -993,8 +985,8 @@ t_Open9xModelData_v201::operator ModelData () c9x.customSw[i] = customSw[i]; for (int i=0; i<12; i++) c9x.funcSw[i] = funcSw[i]; - for (int i=0; i= 216) { - for (int i=0; i<2; i++) { - for (int j=0; j<6; j++) { - addConversion(RawSwitch(SWITCH_TYPE_MULTIPOS_POT, i*6+j), val++); - } + if (version >= 216) { + for (int i=1; i<=GetEepromInterface()->getCapability(MultiposPots) * GetEepromInterface()->getCapability(MultiposPotsPositions); i++) { + addConversion(RawSwitch(SWITCH_TYPE_MULTIPOS_POT, -i), -val+offset); + addConversion(RawSwitch(SWITCH_TYPE_MULTIPOS_POT, i), val++); } } - addConversion(RawSwitch(SWITCH_TYPE_OFF), -val); - addConversion(RawSwitch(SWITCH_TYPE_ON), val++); + if (version >= 216) { + for (int i=1; i<=8; i++) { + addConversion(RawSwitch(SWITCH_TYPE_TRIM, -i), -val+offset); + addConversion(RawSwitch(SWITCH_TYPE_TRIM, i), val++); + } + } - for (int i=1; i<=MAX_SWITCHES_POSITION(board); i++) { - int s = switchIndex(i, board, version); - // addConversion(RawSwitch(SWITCH_TYPE_MOMENT_SWITCH, -s), -val); - addConversion(RawSwitch(SWITCH_TYPE_MOMENT_SWITCH, s), val++); + if (version >= 216) { + for (int i=1; i<=MAX_ROTARY_ENCODERS(board); i++) { + addConversion(RawSwitch(SWITCH_TYPE_ROTARY_ENCODER, -i), -val+offset); + addConversion(RawSwitch(SWITCH_TYPE_ROTARY_ENCODER, i), val++); + } } for (int i=1; i<=MAX_CUSTOM_SWITCHES(board, version); i++) { - // addConversion(RawSwitch(SWITCH_TYPE_MOMENT_VIRTUAL, -i), -val); - addConversion(RawSwitch(SWITCH_TYPE_MOMENT_VIRTUAL, i), val++); + addConversion(RawSwitch(SWITCH_TYPE_VIRTUAL, -i), -val+offset); + addConversion(RawSwitch(SWITCH_TYPE_VIRTUAL, i), val++); } - // addConversion(RawSwitch(SWITCH_TYPE_ONM, 1 ), -val); - addConversion(RawSwitch(SWITCH_TYPE_ONM, 0 ), val++); - addConversion(RawSwitch(SWITCH_TYPE_TRN, 0), val++); - addConversion(RawSwitch(SWITCH_TYPE_TRN, 1), val++); - addConversion(RawSwitch(SWITCH_TYPE_REA, 0), val++); - addConversion(RawSwitch(SWITCH_TYPE_REA, 1), val++); + addConversion(RawSwitch(SWITCH_TYPE_OFF), -val+offset); + addConversion(RawSwitch(SWITCH_TYPE_ON), val++); + + if (version < 216) { + // previous "moment" switches + for (int i=1; i<=MAX_SWITCHES_POSITION(board); i++) { + int s = switchIndex(i, board, version); + addConversion(RawSwitch(SWITCH_TYPE_SWITCH, s), val++); + } + + for (int i=1; i<=MAX_CUSTOM_SWITCHES(board, version); i++) { + addConversion(RawSwitch(SWITCH_TYPE_VIRTUAL, i), val++); + } + + // previous "One" switch + addConversion(RawSwitch(SWITCH_TYPE_ON), val++); + } } protected: @@ -264,59 +282,6 @@ class SourcesConversionTable: public ConversionTable { } }; -class TimerModeConversionTable: public ConversionTable { - - public: - TimerModeConversionTable(BoardEnum board, unsigned int version, unsigned long flags=0) - { - int val=0; - - addConversion(TMRMODE_OFF, val++); - addConversion(TMRMODE_ABS, val++); - addConversion(TMRMODE_THs, val++); - addConversion(TMRMODE_THp, val++); - addConversion(TMRMODE_THt, val++); - - int swCount = MAX_SWITCHES_POSITION(board) + MAX_CUSTOM_SWITCHES(board, version); - - for (int i=0; i > { - public: - TimerModeField(TimerMode & mode, BoardEnum board, unsigned int version, unsigned long flags=0): - ConversionField< SignedField<8> >(_mode, &conversionTable, "TimerMode"), - conversionTable(board, version, flags), - mode(mode), - _mode(0) - { - } - - virtual void beforeExport() - { - _mode = mode; - ConversionField< SignedField<8> >::beforeExport(); - } - - virtual void afterImport() - { - ConversionField< SignedField<8> >::afterImport(); - mode = (TimerMode)_mode; - } - - protected: - TimerModeConversionTable conversionTable; - TimerMode & mode; - int _mode; -}; - template class SwitchField: public ConversionField< SignedField > { public: @@ -1092,11 +1057,13 @@ class CustomSwitchesFunctionsTable: public ConversionTable { addConversion(CS_FN_VEQUAL, val++); addConversion(CS_FN_VPOS, val++); addConversion(CS_FN_VNEG, val++); + if (IS_ARM(board) && version >= 216) val++; // later RANGE addConversion(CS_FN_APOS, val++); addConversion(CS_FN_ANEG, val++); addConversion(CS_FN_AND, val++); addConversion(CS_FN_OR, val++); addConversion(CS_FN_XOR, val++); + if (IS_ARM(board) && version >= 216) addConversion(CS_FN_STAY, val++); addConversion(CS_FN_EQUAL, val++); if (!release21March2013) addConversion(CS_FN_NEQUAL, val++); @@ -1108,14 +1075,16 @@ class CustomSwitchesFunctionsTable: public ConversionTable { } addConversion(CS_FN_DPOS, val++); addConversion(CS_FN_DAPOS, val++); - addConversion(CS_FN_TIM, val++); + addConversion(CS_FN_TIMER, val++); + if (version >= 216) + addConversion(CS_FN_STICKY, val++); } }; -class CustomSwitchesAndSwitchesConversionTable: public ConversionTable { +class AndSwitchesConversionTable: public ConversionTable { public: - CustomSwitchesAndSwitchesConversionTable(BoardEnum board, unsigned int version) + AndSwitchesConversionTable(BoardEnum board, unsigned int version) { int val=0; addConversion(RawSwitch(SWITCH_TYPE_NONE), val++); @@ -1153,6 +1122,29 @@ class CustomSwitchesAndSwitchesConversionTable: public ConversionTable { } } + static ConversionTable * getInstance(BoardEnum board, unsigned int version) + { + if (IS_ARM(board) && version >= 216) + return new SwitchesConversionTable(board, version); + else + return new AndSwitchesConversionTable(board, version); + +#if 0 + static std::list internalCache; + + for (std::list::iterator it=internalCache.begin(); it!=internalCache.end(); it++) { + Cache element = *it; + if (element.board == board && element.version == version && element.flags == flags) + return element.table; + } + + Cache element(board, version, flags, new SwitchesConversionTable(board, version, flags)); + internalCache.push_back(element); + return element.table; +#endif + } + + protected: void addConversion(const RawSwitch & sw, const int b) @@ -1173,9 +1165,14 @@ class CustomSwitchField: public TransformedField { functionsConversionTable(board, version), sourcesConversionTable(SourcesConversionTable::getInstance(board, version, variant, (version >= 214 || (!IS_ARM(board) && version >= 213)) ? 0 : FLAG_NOSWITCHES)), switchesConversionTable(SwitchesConversionTable::getInstance(board, version)), - andswitchesConversionTable(board, version) + andswitchesConversionTable(AndSwitchesConversionTable::getInstance(board, version)) { - if (IS_ARM(board) && version >= 215) { + if (IS_ARM(board) && version >= 216) { + internalField.Append(new SignedField<8>(v1)); + internalField.Append(new SignedField<16>(v2)); + internalField.Append(new SignedField<16>(v3)); + } + else if (IS_ARM(board) && version >= 215) { internalField.Append(new SignedField<16>(v1)); internalField.Append(new SignedField<16>(v2)); } @@ -1189,13 +1186,13 @@ class CustomSwitchField: public TransformedField { internalField.Append(new UnsignedField<8>(csw.delay)); internalField.Append(new UnsignedField<8>(csw.duration)); if (version >= 214) { - internalField.Append(new ConversionField< SignedField<8> >((int &)csw.andsw, &andswitchesConversionTable, "AND switch")); + internalField.Append(new ConversionField< SignedField<8> >((int &)csw.andsw, andswitchesConversionTable, "AND switch")); } } else { if (version >= 213) { internalField.Append(new ConversionField< UnsignedField<4> >(csw.func, &functionsConversionTable, "Function")); - internalField.Append(new ConversionField< UnsignedField<4> >(csw.andsw, &andswitchesConversionTable, "AND switch")); + internalField.Append(new ConversionField< UnsignedField<4> >((unsigned int &)csw.andsw, andswitchesConversionTable, "AND switch")); } else { internalField.Append(new ConversionField< UnsignedField<8> >(csw.func, &functionsConversionTable, "Function")); @@ -1205,40 +1202,50 @@ class CustomSwitchField: public TransformedField { virtual void beforeExport() { - v1 = csw.val1; - v2 = csw.val2; - - if ((csw.func >= CS_FN_VPOS && csw.func <= CS_FN_ANEG) || (csw.func >= CS_FN_EQUAL && csw.func!=CS_FN_TIM)) { - sourcesConversionTable->exportValue(csw.val1, v1); + if (csw.func == CS_FN_STAY) { + switchesConversionTable->exportValue(csw.val1, v1); + v2 = csw.val2; + v3 = csw.val3; } - - if (csw.func >= CS_FN_EQUAL && csw.func <= CS_FN_ELESS) { - sourcesConversionTable->exportValue(csw.val2, v2); - } - - if (csw.func >= CS_FN_AND && csw.func <= CS_FN_XOR) { + else if ((csw.func >= CS_FN_AND && csw.func <= CS_FN_XOR) || csw.func == CS_FN_STICKY) { switchesConversionTable->exportValue(csw.val1, v1); switchesConversionTable->exportValue(csw.val2, v2); } + else if (csw.func >= CS_FN_EQUAL && csw.func <= CS_FN_ELESS) { + sourcesConversionTable->exportValue(csw.val1, v1); + sourcesConversionTable->exportValue(csw.val2, v2); + } + else { + if ((csw.func >= CS_FN_VPOS && csw.func <= CS_FN_ANEG) || (csw.func >= CS_FN_EQUAL && csw.func!=CS_FN_TIMER)) + sourcesConversionTable->exportValue(csw.val1, v1); + else + v1 = csw.val1; + v2 = csw.val2; + } } virtual void afterImport() { - csw.val1 = v1; - csw.val2 = v2; - - if ((csw.func >= CS_FN_VPOS && csw.func <= CS_FN_ANEG) || (csw.func >= CS_FN_EQUAL && csw.func!=CS_FN_TIM)) { - sourcesConversionTable->importValue(v1, csw.val1); + if (csw.func == CS_FN_STAY) { + switchesConversionTable->importValue(v1, csw.val1); + csw.val2 = v2; + csw.val3 = v3; } - - if (csw.func >= CS_FN_EQUAL && csw.func <= CS_FN_ELESS) { - sourcesConversionTable->importValue(v2, csw.val2); - } - - if (csw.func >= CS_FN_AND && csw.func <= CS_FN_XOR) { + else if ((csw.func >= CS_FN_AND && csw.func <= CS_FN_XOR) || csw.func == CS_FN_STICKY) { switchesConversionTable->importValue(v1, csw.val1); switchesConversionTable->importValue(v2, csw.val2); } + else if (csw.func >= CS_FN_EQUAL && csw.func <= CS_FN_ELESS) { + sourcesConversionTable->importValue(v1, csw.val1); + sourcesConversionTable->importValue(v2, csw.val2); + } + else { + if ((csw.func >= CS_FN_VPOS && csw.func <= CS_FN_ANEG) || (csw.func >= CS_FN_EQUAL && csw.func!=CS_FN_TIMER)) + sourcesConversionTable->importValue(v1, csw.val1); + else + csw.val1 = v1; + csw.val2 = v2; + } } protected: @@ -1250,9 +1257,10 @@ class CustomSwitchField: public TransformedField { CustomSwitchesFunctionsTable functionsConversionTable; SourcesConversionTable * sourcesConversionTable; SwitchesConversionTable * switchesConversionTable; - CustomSwitchesAndSwitchesConversionTable andswitchesConversionTable; + ConversionTable * andswitchesConversionTable; int v1; int v2; + int v3; }; class CustomFunctionsConversionTable: public ConversionTable { @@ -1262,7 +1270,13 @@ class CustomFunctionsConversionTable: public ConversionTable { { int val=0; - if (IS_ARM(board) || version < 213) { + if (version >= 216) { + for (int i=0; i<32; i++) { + addConversion(i, val); + } + val++; + } + else if (IS_ARM(board) || version < 213) { for (int i=0; i<16; i++) { addConversion(val, val); val++; @@ -1274,32 +1288,67 @@ class CustomFunctionsConversionTable: public ConversionTable { } val+=4; } - addConversion(FuncTrainer, val++); - addConversion(FuncTrainerRUD, val++); - addConversion(FuncTrainerELE, val++); - addConversion(FuncTrainerTHR, val++); - addConversion(FuncTrainerAIL, val++); + + if (version >= 216) { + addConversion(FuncTrainer, val); + addConversion(FuncTrainerRUD, val); + addConversion(FuncTrainerELE, val); + addConversion(FuncTrainerTHR, val); + addConversion(FuncTrainerAIL, val); + val++; + } + else { + addConversion(FuncTrainer, val++); + addConversion(FuncTrainerRUD, val++); + addConversion(FuncTrainerELE, val++); + addConversion(FuncTrainerTHR, val++); + addConversion(FuncTrainerAIL, val++); + } addConversion(FuncInstantTrim, val++); - addConversion(FuncPlaySound, val++); - if (!IS_TARANIS(board)) + if (version >= 216) { + addConversion(FuncReset, val++); + for (int i=0; i= 213 && !IS_ARM(board)) + addConversion(FuncPlayBoth, val++); + addConversion(FuncPlayValue, val++); + if (IS_ARM(board)) { + addConversion(FuncBackgroundMusic, val++); + addConversion(FuncBackgroundMusicPause, val++); + } + addConversion(FuncVario, val++); addConversion(FuncPlayHaptic, val++); - addConversion(FuncReset, val++); - addConversion(FuncVario, val++); - addConversion(FuncPlayPrompt, val++); - if (version >= 213 && !IS_ARM(board)) - addConversion(FuncPlayBoth, val++); - addConversion(FuncPlayValue, val++); - if (board == BOARD_GRUVIN9X || IS_ARM(board) ) - addConversion(FuncLogs, val++); - if (IS_ARM(board)) - addConversion(FuncVolume, val++); - addConversion(FuncBacklight, val++); - if (IS_ARM(board)) { - addConversion(FuncBackgroundMusic, val++); - addConversion(FuncBackgroundMusicPause, val++); + if (board == BOARD_GRUVIN9X || IS_ARM(board) ) + addConversion(FuncLogs, val++); + addConversion(FuncBacklight, val++); + } + else { + addConversion(FuncPlaySound, val++); + if (!IS_TARANIS(board)) + addConversion(FuncPlayHaptic, val++); + addConversion(FuncReset, val++); + addConversion(FuncVario, val++); + addConversion(FuncPlayPrompt, val++); + if (version >= 213 && !IS_ARM(board)) + addConversion(FuncPlayBoth, val++); + addConversion(FuncPlayValue, val++); + if (board == BOARD_GRUVIN9X || IS_ARM(board) ) + addConversion(FuncLogs, val++); + if (IS_ARM(board)) + addConversion(FuncVolume, val++); + addConversion(FuncBacklight, val++); + if (IS_ARM(board)) { + addConversion(FuncBackgroundMusic, val++); + addConversion(FuncBackgroundMusicPause, val++); + } + for (int i=0; i<5; i++) + addConversion(FuncAdjustGV1+i, val++); } - for (int i=0; i<5; i++) - addConversion(FuncAdjustGV1+i, val++); } }; @@ -1345,9 +1394,9 @@ class SwitchesWarningField: public TransformedField { unsigned int version; }; -class CustomFunctionField: public TransformedField { +class ArmCustomFunctionField: public TransformedField { public: - CustomFunctionField(FuncSwData & fn, BoardEnum board, unsigned int version, unsigned int variant): + ArmCustomFunctionField(FuncSwData & fn, BoardEnum board, unsigned int version, unsigned int variant): TransformedField(internalField), internalField("CustomFunction"), fn(fn), @@ -1355,201 +1404,324 @@ class CustomFunctionField: public TransformedField { version(version), variant(variant), functionsConversionTable(board, version), - sourcesConversionTable(SourcesConversionTable::getInstance(board, version, variant, FLAG_NONONE)), - _param(0), - _delay(0), - _union_param(0) + sourcesConversionTable(SourcesConversionTable::getInstance(board, version, variant, version >= 216 ? 0 : FLAG_NONONE)), + _active(0) { - memset(_arm_param, 0, sizeof(_arm_param)); + memset(_param, 0, sizeof(_param)); internalField.Append(new SwitchField<8>(fn.swtch, board, version)); - if (IS_ARM(board)) { - internalField.Append(new ConversionField< UnsignedField<8> >((unsigned int &)fn.func, &functionsConversionTable, "Function", ::QObject::tr("OpenTX on this board doesn't accept this function"))); - if (IS_TARANIS(board)) - internalField.Append(new CharField<10>(_arm_param)); - else - internalField.Append(new CharField<6>(_arm_param)); - if (version >= 214) { - internalField.Append(new UnsignedField<2>(_mode)); - internalField.Append(new SignedField<6>(_delay)); - } - else { - internalField.Append(new UnsignedField<8>((unsigned int &)_delay)); - } - if (version < 214) - internalField.Append(new SpareBitsField<8>()); + internalField.Append(new ConversionField< UnsignedField<8> >((unsigned int &)fn.func, &functionsConversionTable, "Function", ::QObject::tr("OpenTX on this board doesn't accept this function"))); + + if (IS_TARANIS(board)) + internalField.Append(new CharField<10>(_param, false)); + else + internalField.Append(new CharField<6>(_param, false)); + + if (version >= 216) { + internalField.Append(new UnsignedField<8>(_active)); + } + else if (version >= 214) { + internalField.Append(new UnsignedField<2>(_mode)); + internalField.Append(new UnsignedField<6>(_active)); } else { - if (version >= 213) { - internalField.Append(new UnsignedField<3>(_union_param)); - internalField.Append(new ConversionField< UnsignedField<5> >((unsigned int &)fn.func, &functionsConversionTable, "Function", ::QObject::tr("OpenTX on this board doesn't accept this function"))); - } - else { - internalField.Append(new ConversionField< UnsignedField<7> >((unsigned int &)fn.func, &functionsConversionTable, "Function", ::QObject::tr("OpenTX on this board doesn't accept this function"))); - internalField.Append(new BoolField<1>((bool &)fn.enabled)); - } - internalField.Append(new UnsignedField<8>(_param)); + internalField.Append(new UnsignedField<8>((unsigned int &)_active)); + internalField.Append(new SpareBitsField<8>()); } } virtual void beforeExport() { - if (IS_ARM(board)) { - _mode = 0; - if (fn.func == FuncPlaySound || fn.func == FuncPlayPrompt || fn.func == FuncPlayValue) - _delay = (version >= 216 ? fn.repeatParam : (fn.repeatParam/5)); - else - _delay = (fn.enabled ? 1 : 0); - if (fn.func <= FuncInstantTrim) { - *((uint32_t *)_arm_param) = fn.param; - } - else if (fn.func == FuncPlayPrompt || fn.func == FuncBackgroundMusic) { - memcpy(_arm_param, fn.paramarm, sizeof(_arm_param)); - } - else if (fn.func >= FuncAdjustGV1 && fn.func <= FuncAdjustGVLast) { - unsigned int value; - if (version >= 214) { - _mode = fn.adjustMode; - if (fn.adjustMode == 1) - sourcesConversionTable->exportValue(fn.param, (int &)value); - else if (fn.adjustMode == 2) - value = RawSource(fn.param).index; - else - value = fn.param; - } - else { - unsigned int value; - sourcesConversionTable->exportValue(fn.param, (int &)value); - } - *((uint32_t *)_arm_param) = value; - } - else if (fn.func == FuncPlayValue || fn.func == FuncVolume) { - unsigned int value; - sourcesConversionTable->exportValue(fn.param, (int &)value); - *((uint32_t *)_arm_param) = value; + _mode = 0; + + if (fn.func == FuncPlaySound || fn.func == FuncPlayPrompt || fn.func == FuncPlayValue) + _active = (version >= 216 ? fn.repeatParam : (fn.repeatParam/5)); + else + _active = (fn.enabled ? 1 : 0); + + if (fn.func >= FuncSafetyCh1 && fn.func <= FuncSafetyCh32) { + if (version >= 216) { + *((uint16_t *)_param) = fn.param; + *((uint8_t *)(_param+3)) = fn.func - FuncSafetyCh1; } else { - *((uint32_t *)_arm_param) = fn.param; + *((uint32_t *)_param) = fn.param; } } + else if (fn.func >= FuncTrainer && fn.func <= FuncTrainerAIL) { + if (version >= 216) + *((uint8_t *)(_param+3)) = fn.func - FuncTrainer; + } + else if (fn.func == FuncPlayPrompt || fn.func == FuncBackgroundMusic) { + memcpy(_param, fn.paramarm, sizeof(_param)); + } + else if (fn.func >= FuncAdjustGV1 && fn.func <= FuncAdjustGVLast) { + if (version >= 216) { + *((uint8_t *)(_param+2)) = fn.adjustMode; + *((uint8_t *)(_param+3)) = fn.func - FuncAdjustGV1; + unsigned int value; + if (fn.adjustMode == 1) + sourcesConversionTable->exportValue(fn.param, (int &)value); + else if (fn.adjustMode == 2) + value = RawSource(fn.param).index; + else + value = fn.param; + *((uint16_t *)_param) = value; + } + else if (version >= 214) { + unsigned int value; + _mode = fn.adjustMode; + if (fn.adjustMode == 1) + sourcesConversionTable->exportValue(fn.param, (int &)value); + else if (fn.adjustMode == 2) + value = RawSource(fn.param).index; + else + value = fn.param; + *((uint32_t *)_param) = value; + } + else { + unsigned int value; + sourcesConversionTable->exportValue(fn.param, (int &)value); + *((uint32_t *)_param) = value; + } + } + else if (fn.func == FuncPlayValue || fn.func == FuncVolume) { + unsigned int value; + sourcesConversionTable->exportValue(fn.param, (int &)value); + if (version >= 216) + *((uint16_t *)_param) = value; + else + *((uint32_t *)_param) = value; + } else { - /* the default behavior */ - _param = fn.param; - _union_param = (fn.enabled ? 1 : 0); - if (fn.func >= FuncAdjustGV1 && fn.func <= FuncAdjustGVLast) { - if (version >= 213) { - _union_param += (fn.adjustMode << 1); - if (fn.adjustMode == 1) - sourcesConversionTable->exportValue(fn.param, (int &)_param); - else if (fn.adjustMode == 2) - _param = RawSource(fn.param).index; - } - else { - sourcesConversionTable->exportValue(fn.param, (int &)_param); - } - } - else if (fn.func == FuncPlayValue) { - if (version >= 213) { - _union_param = fn.repeatParam / 10; - sourcesConversionTable->exportValue(fn.param, (int &)_param); - } - else { - SourcesConversionTable::getInstance(board, version, variant, FLAG_NONONE|FLAG_NOSWITCHES)->exportValue(fn.param, (int &)_param); - } - } - else if (fn.func == FuncPlaySound || fn.func == FuncPlayPrompt || fn.func == FuncPlayBoth) { - if (version >= 213) - _union_param = fn.repeatParam / 10; - } - else if (fn.func <= FuncSafetyCh16) { - if (version >= 213) - _union_param += ((fn.func % 4) << 1); - } + *((uint32_t *)_param) = fn.param; } } virtual void afterImport() { - if (IS_ARM(board)) { - if (fn.func == FuncPlaySound || fn.func == FuncPlayPrompt || fn.func == FuncPlayValue) - fn.repeatParam = (version >= 216 ? _delay : (_delay*5)); - else - fn.enabled = (_delay & 0x01); + if (fn.func == FuncPlaySound || fn.func == FuncPlayPrompt || fn.func == FuncPlayValue) + fn.repeatParam = (version >= 216 ? _active : (_active*5)); + else + fn.enabled = (_active & 0x01); - unsigned int value = *((uint32_t *)_arm_param); - if (fn.func <= FuncTrainer) { - fn.param = (int)value; - } - else if (fn.func <= FuncInstantTrim) { - fn.param = value; - } - else if (fn.func == FuncPlayPrompt || fn.func == FuncBackgroundMusic) { - memcpy(fn.paramarm, _arm_param, sizeof(fn.paramarm)); - } - else if (fn.func == FuncVolume) { - sourcesConversionTable->importValue(value, (int &)fn.param); - } - else if (fn.func >= FuncAdjustGV1 && fn.func <= FuncAdjustGVLast) { - if (version >= 214) { - fn.adjustMode = _mode; - if (fn.adjustMode == 1) - sourcesConversionTable->importValue(value, (int &)fn.param); - else if (fn.adjustMode == 2) - fn.param = RawSource(SOURCE_TYPE_GVAR, value).toValue(); - else - fn.param = value; - } - else { - sourcesConversionTable->importValue(value, (int &)fn.param); - } - } - else if (fn.func == FuncPlayValue) { - if (version >= 213) - sourcesConversionTable->importValue(value, (int &)fn.param); - else - SourcesConversionTable::getInstance(board, version, variant, FLAG_NONONE|FLAG_NOSWITCHES)->importValue(value, (int &)fn.param); - } - else { - fn.param = value; - } + unsigned int value=0, mode=0, index=0; + if (version >= 216) { + value = *((uint16_t *)_param); + mode = *((uint8_t *)(_param+2)); + index = *((uint8_t *)(_param+3)); } else { - fn.param = _param; - if (version >= 213) { - fn.enabled = (_union_param & 0x01); + value = *((uint32_t *)_param); + } + + if (fn.func >= FuncSafetyCh1 && fn.func <= FuncSafetyCh32) { + fn.func = AssignFunc(fn.func + index); + fn.param = (int)value; + } + else if (fn.func >= FuncTrainer && fn.func <= FuncTrainerAIL) { + fn.func = AssignFunc(fn.func + index); + fn.param = (int)value; + } + else if (fn.func == FuncPlayPrompt || fn.func == FuncBackgroundMusic) { + memcpy(fn.paramarm, _param, sizeof(fn.paramarm)); + } + else if (fn.func == FuncVolume) { + sourcesConversionTable->importValue(value, (int &)fn.param); + } + else if (fn.func >= FuncAdjustGV1 && fn.func <= FuncAdjustGVLast) { + if (version >= 216) { + fn.func = AssignFunc(fn.func + index); + fn.adjustMode = mode; + if (fn.adjustMode == 1) + sourcesConversionTable->importValue(value, (int &)fn.param); + else if (fn.adjustMode == 2) + fn.param = RawSource(SOURCE_TYPE_GVAR, value).toValue(); + else + fn.param = value; } - if (fn.func >= FuncAdjustGV1 && fn.func <= FuncAdjustGVLast) { - if (version >= 213) { - fn.adjustMode = ((_union_param >> 1) & 0x03); - if (fn.adjustMode == 1) - sourcesConversionTable->importValue(_param, (int &)fn.param); - else if (fn.adjustMode == 2) - fn.param = RawSource(SOURCE_TYPE_GVAR, _param).toValue(); - } - else { - sourcesConversionTable->importValue(_param, (int &)fn.param); - } + else if (version >= 214) { + fn.adjustMode = _mode; + if (fn.adjustMode == 1) + sourcesConversionTable->importValue(value, (int &)fn.param); + else if (fn.adjustMode == 2) + fn.param = RawSource(SOURCE_TYPE_GVAR, value).toValue(); + else + fn.param = value; } - else if (fn.func == FuncPlayValue) { - if (version >= 213) { - fn.repeatParam = _union_param * 10; - sourcesConversionTable->importValue(_param, (int &)fn.param); - } - else { - SourcesConversionTable::getInstance(board, version, variant, FLAG_NONONE|FLAG_NOSWITCHES)->importValue(_param, (int &)fn.param); - } - } - else if (fn.func == FuncPlaySound || fn.func == FuncPlayPrompt || fn.func == FuncPlayBoth) { - if (version >= 213) - fn.repeatParam = _union_param * 10; - } - else if (fn.func <= FuncSafetyCh16) { - if (version >= 213) { - fn.func = AssignFunc(((fn.func >> 2) << 2) + ((_union_param >> 1) & 0x03)); - } - fn.param = (int8_t)fn.param; + else { + sourcesConversionTable->importValue(value, (int &)fn.param); } } + else if (fn.func == FuncPlayValue) { + if (version >= 213) + sourcesConversionTable->importValue(value, (int &)fn.param); + else + SourcesConversionTable::getInstance(board, version, variant, FLAG_NONONE|FLAG_NOSWITCHES)->importValue(value, (int &)fn.param); + } + else { + fn.param = value; + } + } + + protected: + StructField internalField; + FuncSwData & fn; + BoardEnum board; + unsigned int version; + unsigned int variant; + CustomFunctionsConversionTable functionsConversionTable; + SourcesConversionTable * sourcesConversionTable; + char _param[10]; + unsigned int _active; + unsigned int _mode; +}; + +class AvrCustomFunctionField: public TransformedField { + public: + AvrCustomFunctionField(FuncSwData & fn, BoardEnum board, unsigned int version, unsigned int variant): + TransformedField(internalField), + internalField("CustomFunction"), + fn(fn), + board(board), + version(version), + variant(variant), + functionsConversionTable(board, version), + sourcesConversionTable(SourcesConversionTable::getInstance(board, version, variant, version >= 216 ? 0 : FLAG_NONONE)), + _param(0), + _union_param(0), + _active(0) + { + if (version >= 216) { + internalField.Append(new SwitchField<6>(fn.swtch, board, version)); + internalField.Append(new ConversionField< UnsignedField<4> >((unsigned int &)fn.func, &functionsConversionTable, "Function", ::QObject::tr("OpenTX on this board doesn't accept this function"))); + internalField.Append(new UnsignedField<5>(_union_param)); + internalField.Append(new UnsignedField<1>(_active)); + } + if (version >= 213) { + internalField.Append(new SwitchField<8>(fn.swtch, board, version)); + internalField.Append(new UnsignedField<3>(_union_param)); + internalField.Append(new ConversionField< UnsignedField<5> >((unsigned int &)fn.func, &functionsConversionTable, "Function", ::QObject::tr("OpenTX on this board doesn't accept this function"))); + } + else { + internalField.Append(new SwitchField<8>(fn.swtch, board, version)); + internalField.Append(new ConversionField< UnsignedField<7> >((unsigned int &)fn.func, &functionsConversionTable, "Function", ::QObject::tr("OpenTX on this board doesn't accept this function"))); + internalField.Append(new BoolField<1>((bool &)fn.enabled)); + } + internalField.Append(new UnsignedField<8>(_param)); + } + + virtual void beforeExport() + { + _param = fn.param; + _active = (fn.enabled ? 1 : 0); + + if (fn.func >= FuncSafetyCh1 && fn.func <= FuncSafetyCh32) { + if (version >= 216) + _union_param = fn.func - FuncSafetyCh1; + else if (version >= 213) + _active += ((fn.func % 4) << 1); + } + else if (fn.func >= FuncTrainer && fn.func <= FuncTrainerAIL) { + if (version >= 216) + _union_param = fn.func - FuncTrainer; + } + else if (fn.func >= FuncAdjustGV1 && fn.func <= FuncAdjustGVLast) { + if (version >= 216) { + _union_param = fn.adjustMode; + _union_param += (fn.func - FuncAdjustGV1) << 2; + if (fn.adjustMode == 1) + sourcesConversionTable->exportValue(fn.param, (int &)_param); + else if (fn.adjustMode == 2) + _param = RawSource(fn.param).index; + } + else if (version >= 213) { + _active += (fn.adjustMode << 1); + if (fn.adjustMode == 1) + sourcesConversionTable->exportValue(fn.param, (int &)_param); + else if (fn.adjustMode == 2) + _param = RawSource(fn.param).index; + } + else { + sourcesConversionTable->exportValue(fn.param, (int &)_param); + } + } + else if (fn.func == FuncPlayValue) { + if (version >= 216) { + _union_param = fn.repeatParam / 10; + sourcesConversionTable->exportValue(fn.param, (int &)_param); + } + else if (version >= 213) { + _active = fn.repeatParam / 10; + sourcesConversionTable->exportValue(fn.param, (int &)_param); + } + else { + SourcesConversionTable::getInstance(board, version, variant, FLAG_NONONE|FLAG_NOSWITCHES)->exportValue(fn.param, (int &)_param); + } + } + else if (fn.func == FuncPlaySound || fn.func == FuncPlayPrompt || fn.func == FuncPlayBoth) { + if (version >= 216) { + _union_param = fn.repeatParam / 10; + } + else if (version >= 213) { + _active = fn.repeatParam / 10; + } + } + } + + virtual void afterImport() + { + fn.param = _param; + if (version >= 213) { + fn.enabled = (_active & 0x01); + } + + if (fn.func >= FuncSafetyCh1 && fn.func <= FuncSafetyCh32) { + if (version >= 216) + fn.func = AssignFunc(fn.func + _union_param); + else if (version >= 213) + fn.func = AssignFunc(((fn.func >> 2) << 2) + ((_active >> 1) & 0x03)); + fn.param = (int8_t)fn.param; + } + else if (fn.func >= FuncTrainer && fn.func <= FuncTrainerAIL) { + if (version >= 216) + fn.func = AssignFunc(fn.func + _union_param); + } + else if (fn.func >= FuncAdjustGV1 && fn.func <= FuncAdjustGVLast) { + if (version >= 216) { + fn.func = AssignFunc(fn.func + (_union_param >> 2)); + fn.adjustMode = (_union_param & 0x03); + } + else if (version >= 213) { + fn.adjustMode = ((_active >> 1) & 0x03); + if (fn.adjustMode == 1) + sourcesConversionTable->importValue(_param, (int &)fn.param); + else if (fn.adjustMode == 2) + fn.param = RawSource(SOURCE_TYPE_GVAR, _param).toValue(); + } + else { + sourcesConversionTable->importValue(_param, (int &)fn.param); + } + } + else if (fn.func == FuncPlayValue) { + if (version >= 216) { + fn.repeatParam = _union_param * 10; + sourcesConversionTable->importValue(_param, (int &)fn.param); + } + else if (version >= 213) { + fn.repeatParam = _active * 10; + sourcesConversionTable->importValue(_param, (int &)fn.param); + } + else { + SourcesConversionTable::getInstance(board, version, variant, FLAG_NONONE|FLAG_NOSWITCHES)->importValue(_param, (int &)fn.param); + } + } + else if (fn.func == FuncPlaySound || fn.func == FuncPlayPrompt || fn.func == FuncPlayBoth) { + if (version >= 216) + fn.repeatParam = _union_param * 10; + else if (version >= 213) + fn.repeatParam = _active * 10; + } } protected: @@ -1560,11 +1732,10 @@ class CustomFunctionField: public TransformedField { unsigned int variant; CustomFunctionsConversionTable functionsConversionTable; SourcesConversionTable * sourcesConversionTable; - char _arm_param[10]; unsigned int _param; - int _delay; unsigned int _mode; unsigned int _union_param; + unsigned int _active; }; class FrskyScreenField: public DataField { @@ -1840,7 +2011,7 @@ Open9xModelDataNew::Open9xModelDataNew(ModelData & modelData, BoardEnum board, u } for (int i=0; i(modelData.timers[i].mode, board, version, POPULATE_TIMER_MODES)); if ((IS_ARM(board) || IS_2560(board)) && version >= 216) { internalField.Append(new UnsignedField<16>(modelData.timers[i].val)); internalField.Append(new UnsignedField<2>(modelData.timers[i].countdownBeep)); @@ -1917,8 +2088,12 @@ Open9xModelDataNew::Open9xModelDataNew(ModelData & modelData, BoardEnum board, u internalField.Append(new CurvesField(modelData.curves, board, version)); for (int i=0; i= 216) { + int count = 0; + for (int i=0; iaddOptions(ext_options); open9x->addOption("heli", QObject::tr("Enable heli menu and cyclic mix support")); open9x->addOption("templates", QObject::tr("Enable TEMPLATES menu")); @@ -1051,7 +1051,7 @@ void RegisterOpen9xFirmwares() firmwares.push_back(open9x); /* 9x board with M128 chip */ - open9x = new Open9xFirmware("opentx-9x128", QObject::tr("openTx for M128 / 9X board"), new Open9xInterface(BOARD_M128), geturl(BOARD_M128), getstamp(BOARD_M128),getrnurl(BOARD_M128), false); + open9x = new Open9xFirmware("opentx-9x128", QObject::tr("OpenTX for M128 / 9X board"), new Open9xInterface(BOARD_M128), geturl(BOARD_M128), getstamp(BOARD_M128),getrnurl(BOARD_M128), false); open9x->addOptions(ext_options); open9x->addOption("heli", QObject::tr("Enable heli menu and cyclic mix support")); open9x->addOption("templates", QObject::tr("Enable TEMPLATES menu")); @@ -1083,7 +1083,7 @@ void RegisterOpen9xFirmwares() firmwares.push_back(open9x); /* 9XR board */ - open9x = new Open9xFirmware("opentx-9xr", QObject::tr("openTx for 9XR"), new Open9xInterface(BOARD_STOCK), geturl(BOARD_STOCK), getstamp(BOARD_STOCK),getrnurl(BOARD_STOCK), false); + open9x = new Open9xFirmware("opentx-9xr", QObject::tr("OpenTX for 9XR"), new Open9xInterface(BOARD_STOCK), geturl(BOARD_STOCK), getstamp(BOARD_STOCK),getrnurl(BOARD_STOCK), false); open9x->addOptions(extr_options); open9x->addOption("heli", QObject::tr("Enable heli menu and cyclic mix support")); open9x->addOption("templates", QObject::tr("Enable TEMPLATES menu")); @@ -1117,7 +1117,7 @@ void RegisterOpen9xFirmwares() firmwares.push_back(open9x); /* 9XR board with M128 chip */ - open9x = new Open9xFirmware("opentx-9xr128", QObject::tr("openTx for 9XR with M128 chip"), new Open9xInterface(BOARD_M128), geturl(BOARD_M128), getstamp(BOARD_M128),getrnurl(BOARD_M128), false); + open9x = new Open9xFirmware("opentx-9xr128", QObject::tr("OpenTX for 9XR with M128 chip"), new Open9xInterface(BOARD_M128), geturl(BOARD_M128), getstamp(BOARD_M128),getrnurl(BOARD_M128), false); open9x->addOptions(extr_options); open9x->addOption("heli", QObject::tr("Enable heli menu and cyclic mix support")); open9x->addOption("templates", QObject::tr("Enable TEMPLATES menu")); @@ -1147,7 +1147,7 @@ void RegisterOpen9xFirmwares() firmwares.push_back(open9x); /* Gruvin9x board */ - open9x = new Open9xFirmware("opentx-gruvin9x", QObject::tr("openTx for Gruvin9x board / 9X"), new Open9xInterface(BOARD_GRUVIN9X), geturl(BOARD_GRUVIN9X), getstamp(BOARD_GRUVIN9X),getrnurl(BOARD_GRUVIN9X), false); + open9x = new Open9xFirmware("opentx-gruvin9x", QObject::tr("OpenTX for Gruvin9x board / 9X"), new Open9xInterface(BOARD_GRUVIN9X), geturl(BOARD_GRUVIN9X), getstamp(BOARD_GRUVIN9X),getrnurl(BOARD_GRUVIN9X), false); open9x->setVariantBase(FRSKY_VARIANT); open9x->addOption("heli", QObject::tr("Enable heli menu and cyclic mix support")); open9x->addOption("templates", QObject::tr("Enable TEMPLATES menu")); @@ -1177,7 +1177,7 @@ void RegisterOpen9xFirmwares() #ifndef __APPLE__ /* SKY9X board */ - open9x = new Open9xFirmware("opentx-sky9x", QObject::tr("openTx for Sky9x board / 9X"), new Open9xInterface(BOARD_SKY9X), geturl(BOARD_SKY9X), getstamp(BOARD_SKY9X),getrnurl(BOARD_SKY9X), true); + open9x = new Open9xFirmware("opentx-sky9x", QObject::tr("OpenTX for Sky9x board / 9X"), new Open9xInterface(BOARD_SKY9X), geturl(BOARD_SKY9X), getstamp(BOARD_SKY9X),getrnurl(BOARD_SKY9X), true); open9x->setVariantBase(FRSKY_VARIANT); open9x->addOption("heli", QObject::tr("Enable HELI menu and cyclic mix support")); open9x->addOption("templates", QObject::tr("Enable TEMPLATES menu")); @@ -1202,7 +1202,7 @@ void RegisterOpen9xFirmwares() #endif /* Taranis board */ - open9x = new Open9xFirmware("opentx-taranis", QObject::tr("openTx for FrSky Taranis"), new Open9xInterface(BOARD_TARANIS), geturl(BOARD_TARANIS), getstamp(BOARD_TARANIS),getrnurl(BOARD_TARANIS), true); + open9x = new Open9xFirmware("opentx-taranis", QObject::tr("OpenTX for FrSky Taranis"), new Open9xInterface(BOARD_TARANIS), geturl(BOARD_TARANIS), getstamp(BOARD_TARANIS),getrnurl(BOARD_TARANIS), true); open9x->addOption("noheli", QObject::tr("Disable HELI menu and cyclic mix support")); open9x->addOption("notemplates", QObject::tr("Disable TEMPLATES menu")); open9x->addOption("nogvars", QObject::tr("Disable Global variables")); @@ -1214,7 +1214,7 @@ void RegisterOpen9xFirmwares() QSettings settings; int rev4a = settings.value("rev4asupport",0).toInt(); if (rev4a) { - open9x = new Open9xFirmware("opentx-taranisrev4a", QObject::tr("openTx for FrSky Taranis Rev4a"), new Open9xInterface(BOARD_TARANIS_REV4a), geturl(BOARD_TARANIS_REV4a), getstamp(BOARD_TARANIS_REV4a),getrnurl(BOARD_TARANIS), true); + open9x = new Open9xFirmware("opentx-taranisrev4a", QObject::tr("OpenTX for FrSky Taranis Rev4a"), new Open9xInterface(BOARD_TARANIS_REV4a), geturl(BOARD_TARANIS_REV4a), getstamp(BOARD_TARANIS_REV4a),getrnurl(BOARD_TARANIS), true); open9x->addOption("noheli", QObject::tr("Disable HELI menu and cyclic mix support")); open9x->addOption("notemplates", QObject::tr("Disable TEMPLATES menu")); open9x->addOption("nogvars", QObject::tr("Disable Global variables")); diff --git a/companion/src/firmwares/th9x/th9xeeprom.cpp b/companion/src/firmwares/th9x/th9xeeprom.cpp index 8df98e04b..e8cb72353 100644 --- a/companion/src/firmwares/th9x/th9xeeprom.cpp +++ b/companion/src/firmwares/th9x/th9xeeprom.cpp @@ -2,18 +2,6 @@ #include "helpers.h" #include "th9xeeprom.h" -int8_t th9xFromSwitch(const RawSwitch & sw) -{ - switch (sw.type) { - case SWITCH_TYPE_SWITCH: - return sw.index; - case SWITCH_TYPE_VIRTUAL: - return sw.index > 0 ? (9 + sw.index) : (-9 -sw.index); - default: - return 0; - } -} - RawSwitch th9xToSwitch(int8_t sw) { if (sw == 0) @@ -266,7 +254,7 @@ t_Th9xModelData::operator ModelData () ModelData c9x; c9x.used = true; getEEPROMString(c9x.name, name, sizeof(name)); - switch(tmrMode) { + /*switch(tmrMode) { case 1: c9x.timers[0].mode = TMRMODE_ABS; break; @@ -279,7 +267,7 @@ t_Th9xModelData::operator ModelData () default: c9x.timers[0].mode = TMRMODE_OFF; break; - } + }*/ // c9x.timers[0].dir = tmrDir; c9x.timers[0].val = tmrVal; /*c9x.protocol = (Protocol)protocol; diff --git a/companion/src/helpers.cpp b/companion/src/helpers.cpp index 831728d87..0a648bb0f 100644 --- a/companion/src/helpers.cpp +++ b/companion/src/helpers.cpp @@ -117,165 +117,6 @@ void populateCustomScreenFieldCB(QComboBox *b, unsigned int value, bool last=fal b->setMaxVisibleItems(10); } -QString getRepeatString(unsigned int val) -{ - if (val==0) { - return QObject::tr("No repeat"); - } else { - unsigned int step = IS_ARM(GetEepromInterface()->getBoard()) ? 5 : 10; - return QObject::tr("%1 sec").arg(step*val); - } -} - -QString getFuncName(unsigned int val) -{ - if (val < NUM_SAFETY_CHNOUT) { - return QObject::tr("Safety %1").arg(RawSource(SOURCE_TYPE_CH, val).toString()); - } - else if (val == FuncTrainer) - return QObject::tr("Trainer"); - else if (val == FuncTrainerRUD) - return QObject::tr("Trainer RUD"); - else if (val == FuncTrainerELE) - return QObject::tr("Trainer ELE"); - else if (val == FuncTrainerTHR) - return QObject::tr("Trainer THR"); - else if (val == FuncTrainerAIL) - return QObject::tr("Trainer AIL"); - else if (val == FuncInstantTrim) - return QObject::tr("Instant Trim"); - else if (val == FuncPlaySound) - return QObject::tr("Play Sound"); - else if (val == FuncPlayHaptic) - return QObject::tr("Play Haptic"); - else if (val == FuncReset) - return QObject::tr("Reset"); - else if (val == FuncVario) - return QObject::tr("Vario"); - else if (val == FuncPlayPrompt) - return QObject::tr("Play Track"); - else if (val == FuncPlayBoth) - return QObject::tr("Play Both"); - else if (val == FuncPlayValue) - return QObject::tr("Play Value"); - else if (val == FuncLogs) - return QObject::tr("Start Logs"); - else if (val == FuncVolume) - return QObject::tr("Volume"); - else if (val == FuncBacklight) - return QObject::tr("Backlight"); - else if (val == FuncBackgroundMusic) - return QObject::tr("Background Music"); - else if (val == FuncBackgroundMusicPause) - return QObject::tr("Background Music Pause"); - else if (val >= FuncAdjustGV1 && val <= FuncAdjustGVLast) - return QObject::tr("Adjust GV%1").arg(val-FuncAdjustGV1+1); - else { - return QString("???"); // Highlight unknown functions with output of question marks.(BTW should not happen that we do not know what a function is) - } -} - -// TODO should be a toString() method in CustoSwData ... -QString getCustomSwitchStr(CustomSwData * customSw, const ModelData & model) -{ - QString result = ""; - - if (!customSw->func) - return result; - if (customSw->andsw!=0) { - result +="( "; - } - switch (getCSFunctionFamily(customSw->func)) { - case CS_FAMILY_TIMERS: - result = QString("TIM(%1 , %2)").arg(ValToTim(customSw->val1)).arg(ValToTim(customSw->val2)); - break; - case CS_FAMILY_VOFS: { - RawSource source = RawSource(customSw->val1, &model); - RawSourceRange range = source.getRange(); - if (customSw->val1) - result += source.toString(); - else - result += "0"; - result.remove(" "); - if (customSw->func == CS_FN_APOS || customSw->func == CS_FN_ANEG) - result = "|" + result + "|"; - else if (customSw->func == CS_FN_DAPOS) - result = "|d(" + result + ")|"; - else if (customSw->func == CS_FN_DPOS) result = "d(" + result + ")"; - if (customSw->func == CS_FN_APOS || customSw->func == CS_FN_VPOS || customSw->func == CS_FN_DAPOS || customSw->func == CS_FN_DPOS) - result += " > "; - else if (customSw->func == CS_FN_ANEG || customSw->func == CS_FN_VNEG) - result += " < "; - result += QString::number(range.step * (customSw->val2 /*TODO+ source.getRawOffset(model)*/) + range.offset); - break; - } - case CS_FAMILY_VBOOL: - result = RawSwitch(customSw->val1).toString(); - switch (customSw->func) { - case CS_FN_AND: - result += " AND "; - break; - case CS_FN_OR: - result += " OR "; - break; - case CS_FN_XOR: - result += " XOR "; - break; - default: - break; - } - result += RawSwitch(customSw->val2).toString(); - break; - - case CS_FAMILY_VCOMP: - if (customSw->val1) - result += RawSource(customSw->val1).toString(); - else - result += "0"; - switch (customSw->func) { - case CS_FN_EQUAL: - result += " = "; - break; - case CS_FN_NEQUAL: - result += " != "; - break; - case CS_FN_GREATER: - result += " > "; - break; - case CS_FN_LESS: - result += " < "; - break; - case CS_FN_EGREATER: - result += " >= "; - break; - case CS_FN_ELESS: - result += " <= "; - break; - default: - break; - } - if (customSw->val2) - result += RawSource(customSw->val2).toString(); - else - result += "0"; - break; - } - - if (customSw->andsw!=0) { - result +=" ) AND "; - result += RawSwitch(customSw->andsw).toString(); - } - - if (GetEepromInterface()->getCapability(CustomSwitchesExt)) { - if (customSw->delay) - result += QObject::tr(" Delay %1 sec").arg(customSw->delay/2.0); - if (customSw->duration) - result += QObject::tr(" Duration %1 sec").arg(customSw->duration/2.0); - } - - return result; -} - QString getProtocolStr(const int proto) { static const char *strings[] = { "OFF", @@ -290,186 +131,6 @@ QString getProtocolStr(const int proto) return CHECK_IN_ARRAY(strings, proto); } -void populateFuncCB(QComboBox *b, unsigned int value) -{ - b->clear(); - for (unsigned int i = 0; i < FuncCount; i++) { - b->addItem(getFuncName(i)); - if (!GetEepromInterface()->getCapability(HasVolume)) { - if (i==FuncVolume || i==FuncBackgroundMusic || i==FuncBackgroundMusicPause) { - QModelIndex index = b->model()->index(i, 0); - QVariant v(0); - b->model()->setData(index, v, Qt::UserRole - 1); - } - } - if ((i==FuncPlayHaptic) && !GetEepromInterface()->getCapability(Haptic)) { - QModelIndex index = b->model()->index(i, 0); - QVariant v(0); - b->model()->setData(index, v, Qt::UserRole - 1); - } - if ((i==FuncPlayBoth) && !GetEepromInterface()->getCapability(HasBeeper)) { - QModelIndex index = b->model()->index(i, 0); - QVariant v(0); - b->model()->setData(index, v, Qt::UserRole - 1); - } - if ((i==FuncLogs) && !GetEepromInterface()->getCapability(HasSDLogs)) { - QModelIndex index = b->model()->index(i, 0); - QVariant v(0); - b->model()->setData(index, v, Qt::UserRole - 1); - } - } - b->setCurrentIndex(value); - b->setMaxVisibleItems(10); -} - -QString FuncParam(uint function, int value, QString paramT,unsigned int adjustmode) -{ - QStringList qs; - if (function <= FuncInstantTrim) { - return QString("%1").arg(value); - } - else if (function==FuncPlaySound) { - qs <<"Beep 1" << "Beep 2" << "Beep 3" << "Warn1" << "Warn2" << "Cheep" << "Ratata" << "Tick" << "Siren" << "Ring" ; - qs << "SciFi" << "Robot" << "Chirp" << "Tada" << "Crickt" << "AlmClk" ; - if (value>=0 && value<(int)qs.count()) - return qs.at(value); - else - return QObject::tr("Inconsistent parameter"); - } - else if (function==FuncPlayHaptic) { - qs << "0" << "1" << "2" << "3"; - if (value>=0 && value<(int)qs.count()) - return qs.at(value); - else - return QObject::tr("Inconsistent parameter"); - } - else if (function==FuncReset) { - qs.append( QObject::tr("Timer1")); - qs.append( QObject::tr("Timer2")); - qs.append( QObject::tr("All")); - qs.append( QObject::tr("Telemetry")); - if (value>=0 && value<(int)qs.count()) - return qs.at(value); - else - return QObject::tr("Inconsistent parameter"); - } - else if ((function==FuncVolume)|| (function==FuncPlayValue)) { - RawSource item(value); - return item.toString(); - } - else if ((function==FuncPlayPrompt) || (function==FuncPlayBoth)) { - if ( GetEepromInterface()->getCapability(VoicesAsNumbers)) { - return QString("%1").arg(value); - } else { - return paramT; - } - } else if ((function>FuncBackgroundMusicPause) && (functionclear(); - b->addItem("----"); - - QString currentvalue(value); - foreach ( QString entry, paramsList ) { - b->addItem(entry); - if (entry==currentvalue) { - b->setCurrentIndex(b->count()-1); - } - } -} - -void populateFuncParamCB(QComboBox *b, const ModelData & model, uint function, unsigned int value, unsigned int adjustmode) -{ - QStringList qs; - b->clear(); - if (function==FuncPlaySound) { - qs <<"Beep 1" << "Beep 2" << "Beep 3" << "Warn1" << "Warn2" << "Cheep" << "Ratata" << "Tick" << "Siren" << "Ring" ; - qs << "SciFi" << "Robot" << "Chirp" << "Tada" << "Crickt" << "AlmClk" ; - b->addItems(qs); - b->setCurrentIndex(value); - } - else if (function==FuncPlayHaptic) { - qs << "0" << "1" << "2" << "3"; - b->addItems(qs); - b->setCurrentIndex(value); - } - else if (function==FuncReset) { - qs.append( QObject::tr("Timer1")); - qs.append( QObject::tr("Timer2")); - qs.append( QObject::tr("All")); - qs.append( QObject::tr("Telemetry")); - int reCount = GetEepromInterface()->getCapability(RotaryEncoders); - if (reCount == 1) { - qs.append( QObject::tr("Rotary Encoder")); - } - else if (reCount == 2) { - qs.append( QObject::tr("REa")); - qs.append( QObject::tr("REb")); - } - b->addItems(qs); - b->setCurrentIndex(value); - } - else if (function==FuncVolume) { - populateSourceCB(b, RawSource(value), model, POPULATE_SOURCES|POPULATE_TRIMS); - } - else if (function==FuncPlayValue) { - populateSourceCB(b, RawSource(value), model, POPULATE_SOURCES|POPULATE_VIRTUAL_INPUTS|POPULATE_SWITCHES|POPULATE_GVARS|POPULATE_TRIMS|POPULATE_TELEMETRYEXT); - } - else if (function>=FuncAdjustGV1 && function<=FuncAdjustGVLast) { - switch (adjustmode) { - case 1: - populateSourceCB(b, RawSource(value), model, POPULATE_SOURCES|POPULATE_TRIMS|POPULATE_SWITCHES); - break; - case 2: - populateSourceCB(b, RawSource(value), model, POPULATE_GVARS); - break; - case 3: - b->clear(); - b->addItem("-1", 0); - b->addItem("+1", 1); - b->setCurrentIndex(value); - break; - } - } - else { - b->hide(); - } -} - -void populateGVmodeCB(QComboBox *b, unsigned int value) -{ - b->clear(); - b->addItem(QObject::tr("Value")); - b->addItem(QObject::tr("Source")); - b->addItem(QObject::tr("GVAR")); - b->addItem(QObject::tr("Increment")); - b->setCurrentIndex(value); -} - void populatePhasesCB(QComboBox *b, int value) { for (int i=-GetEepromInterface()->getCapability(FlightPhases); i<=GetEepromInterface()->getCapability(FlightPhases); i++) { @@ -694,88 +355,6 @@ void populateGvarUseCB(QComboBox *b, unsigned int phase) } } -void populateTimerSwitchCB(QComboBox *b, int value) -{ - b->clear(); - uint8_t count=0; - for (int i=-128; i<128; i++) { - QString timerMode = getTimerMode(i); - if (!timerMode.isEmpty()) { - b->addItem(getTimerMode(i), i); - if (i==value) - b->setCurrentIndex(b->count()-1); - count++; - } - } - b->setMaxVisibleItems(10); -} - -QString getTimerMode(int tm) { - - QString stt = "OFFABSTHsTH%THt"; - - QString s; - - if (tm >= 0 && tm <= TMRMODE_THt) { - return stt.mid(abs(tm)*3, 3); - } - - int tma = abs(tm); - - if (tma >= TMRMODE_FIRST_SWITCH && tma < TMRMODE_FIRST_SWITCH + GetEepromInterface()->getCapability(SwitchesPositions)) { - s = RawSwitch(SWITCH_TYPE_SWITCH, tma - TMRMODE_FIRST_SWITCH + 1).toString(); - if (tm < 0) s.prepend("!"); - return s; - } - - if (tma >= TMRMODE_FIRST_SWITCH + GetEepromInterface()->getCapability(SwitchesPositions) && tma < TMRMODE_FIRST_SWITCH + GetEepromInterface()->getCapability(SwitchesPositions) + GetEepromInterface()->getCapability(CustomSwitches)) { - s = RawSwitch(SWITCH_TYPE_VIRTUAL, tma - TMRMODE_FIRST_SWITCH - GetEepromInterface()->getCapability(SwitchesPositions) + 1).toString(); - if (tm < 0) s.prepend("!"); - return s; - } - - if (tma >= TMRMODE_FIRST_MOMENT_SWITCH && tma < TMRMODE_FIRST_MOMENT_SWITCH + GetEepromInterface()->getCapability(SwitchesPositions)) { - s = RawSwitch(SWITCH_TYPE_SWITCH, tma - TMRMODE_FIRST_MOMENT_SWITCH + 1).toString()+"t"; - if (tm < 0) s.prepend("!"); - return s; - } - - if (tma >= TMRMODE_FIRST_MOMENT_SWITCH + GetEepromInterface()->getCapability(SwitchesPositions) && tma < TMRMODE_FIRST_MOMENT_SWITCH + GetEepromInterface()->getCapability(SwitchesPositions) + GetEepromInterface()->getCapability(CustomSwitches)) { - s = RawSwitch(SWITCH_TYPE_VIRTUAL, tma - TMRMODE_FIRST_MOMENT_SWITCH - GetEepromInterface()->getCapability(SwitchesPositions) + 1).toString()+"t"; - if (tm < 0) s.prepend("!"); - return s; - } - if (tma >=TMRMODE_FIRST_CHPERC && tma 33) { - tma-=32; - } - if (tma < 10) { - s=stt.mid(abs(tma)*3, 3); - } else if (tma <19) { - s=QString("SW%1").arg(tma-9); - } else { - s=QString("SW")+QChar('A'+tma-19); - } - if (tm<0) { - s.prepend("!"); - } else if (tm>33) { - s.append("m"); - } - return s; -} - void populateBacklightCB(QComboBox *b, const uint8_t value) { QString strings[] = { QObject::tr("OFF"), QObject::tr("Keys"), QObject::tr("Sticks"), QObject::tr("Keys + Sticks"), QObject::tr("ON"), NULL }; @@ -788,105 +367,111 @@ void populateBacklightCB(QComboBox *b, const uint8_t value) } } -void populateSwitchCB(QComboBox *b, const RawSwitch & value, unsigned long attr, UseContext context) +void populateAndSwitchCB(QComboBox *b, const RawSwitch & value) +{ + if (IS_ARM(GetEepromInterface()->getBoard())) { + populateSwitchCB(b, value); + } + else { + RawSwitch item; + + b->clear(); + + item = RawSwitch(SWITCH_TYPE_NONE); + b->addItem(item.toString(), item.toValue()); + if (item == value) b->setCurrentIndex(b->count()-1); + + for (int i=1; i<=GetEepromInterface()->getCapability(SwitchesPositions); i++) { + item = RawSwitch(SWITCH_TYPE_SWITCH, i); + b->addItem(item.toString(), item.toValue()); + if (item == value) b->setCurrentIndex(b->count()-1); + } + + for (int i=1; i<=6; i++) { + item = RawSwitch(SWITCH_TYPE_VIRTUAL, i); + b->addItem(item.toString(), item.toValue()); + if (item == value) b->setCurrentIndex(b->count()-1); + } + } +} + +void populateSwitchCB(QComboBox *b, const RawSwitch & value, unsigned long attr) { RawSwitch item; b->clear(); - if (attr & POPULATE_AND_SWITCHES) { - if (GetEepromInterface()->getCapability(HasNegAndSwitches)) { - for (int i=-GetEepromInterface()->getCapability(CustomAndSwitches); i<=-1; i++) { - item = RawSwitch(SWITCH_TYPE_VIRTUAL, i); - b->addItem(item.toString(), item.toValue()); - if (item == value) b->setCurrentIndex(b->count()-1); - } - for (int i=-GetEepromInterface()->getCapability(SwitchesPositions); i<=-1; i++) { - item = RawSwitch(SWITCH_TYPE_SWITCH, i); - if (GetEepromInterface()->isAvailable(item, context)) { - b->addItem(item.toString(), item.toValue()); - if (item == value) b->setCurrentIndex(b->count()-1); - } - } - } - item = RawSwitch(SWITCH_TYPE_NONE); - if (GetEepromInterface()->isAvailable(item, context)) { - b->addItem(item.toString(), item.toValue()); - if (item == value) b->setCurrentIndex(b->count()-1); - } - for (int i=1; i<=GetEepromInterface()->getCapability(SwitchesPositions); i++) { - item = RawSwitch(SWITCH_TYPE_SWITCH, i); - if (GetEepromInterface()->isAvailable(item, context)) { - b->addItem(item.toString(), item.toValue()); - if (item == value) b->setCurrentIndex(b->count()-1); - } - } - for (int i=1; i<=GetEepromInterface()->getCapability(CustomAndSwitches); i++) { - item = RawSwitch(SWITCH_TYPE_VIRTUAL, i); - b->addItem(item.toString(), item.toValue()); - if (item == value) b->setCurrentIndex(b->count()-1); - } - return; - } - -#if 0 - // TODO check ... I removed negative toggle switches in the FW, no? - if (attr & POPULATE_MSWITCHES) { - if (attr & POPULATE_ONOFF) { - item = RawSwitch(SWITCH_TYPE_ONM, 1); - b->addItem(item.toString(), item.toValue()); - if (item == value) b->setCurrentIndex(b->count()-1); - } - - for (int i=-GetEepromInterface()->getCapability(CustomSwitches); i<0; i++) { - item = RawSwitch(SWITCH_TYPE_MOMENT_VIRTUAL, i); - b->addItem(item.toString(), item.toValue()); - if (item == value) b->setCurrentIndex(b->count()-1); - } - for (int i=-GetEepromInterface()->getCapability(SwitchesPositions); i<0; i++) { - item = RawSwitch(SWITCH_TYPE_MOMENT_SWITCH, i); - b->addItem(item.toString(), item.toValue()); - if (item == value) b->setCurrentIndex(b->count()-1); - } - } -#endif - if (attr & POPULATE_ONOFF) { item = RawSwitch(SWITCH_TYPE_OFF); - if (GetEepromInterface()->isAvailable(item, context)) { - b->addItem(item.toString(), item.toValue()); - if (item == value) b->setCurrentIndex(b->count()-1); - } + b->addItem(item.toString(), item.toValue()); + if (item == value) b->setCurrentIndex(b->count()-1); } for (int i=-GetEepromInterface()->getCapability(CustomSwitches); i<0; i++) { item = RawSwitch(SWITCH_TYPE_VIRTUAL, i); - if (GetEepromInterface()->isAvailable(item, context)) { - b->addItem(item.toString(), item.toValue()); - if (item == value) b->setCurrentIndex(b->count()-1); - } + b->addItem(item.toString(), item.toValue()); + if (item == value) b->setCurrentIndex(b->count()-1); + } + + for (int i=-GetEepromInterface()->getCapability(RotaryEncoders); i<0; i++) { + item = RawSwitch(SWITCH_TYPE_ROTARY_ENCODER, i); + b->addItem(item.toString(), item.toValue()); + if (item == value) b->setCurrentIndex(b->count()-1); + } + + for (int i=-8; i<0; i++) { + item = RawSwitch(SWITCH_TYPE_TRIM, i); + b->addItem(item.toString(), item.toValue()); + if (item == value) b->setCurrentIndex(b->count()-1); + } + + for (int i=-GetEepromInterface()->getCapability(MultiposPots) * GetEepromInterface()->getCapability(MultiposPotsPositions); i<0; i++) { + item = RawSwitch(SWITCH_TYPE_MULTIPOS_POT, i); + b->addItem(item.toString(), item.toValue()); + if (item == value) b->setCurrentIndex(b->count()-1); } for (int i=-GetEepromInterface()->getCapability(SwitchesPositions); i<0; i++) { item = RawSwitch(SWITCH_TYPE_SWITCH, i); - if (GetEepromInterface()->isAvailable(item, context)) { + b->addItem(item.toString(), item.toValue()); + if (item == value) b->setCurrentIndex(b->count()-1); + } + + if (attr & POPULATE_TIMER_MODES) { + for (int i=0; i<5; i++) { + item = RawSwitch(SWITCH_TYPE_TIMER_MODE, i); b->addItem(item.toString(), item.toValue()); if (item == value) b->setCurrentIndex(b->count()-1); } } - - item = RawSwitch(SWITCH_TYPE_NONE); - if (GetEepromInterface()->isAvailable(item, context)) { + else { + item = RawSwitch(SWITCH_TYPE_NONE); b->addItem(item.toString(), item.toValue()); if (item == value) b->setCurrentIndex(b->count()-1); } for (int i=1; i<=GetEepromInterface()->getCapability(SwitchesPositions); i++) { item = RawSwitch(SWITCH_TYPE_SWITCH, i); - if (GetEepromInterface()->isAvailable(item, context)) { - b->addItem(item.toString(), item.toValue()); - if (item == value) b->setCurrentIndex(b->count()-1); - } + b->addItem(item.toString(), item.toValue()); + if (item == value) b->setCurrentIndex(b->count()-1); + } + + for (int i=1; i<=GetEepromInterface()->getCapability(MultiposPots) * GetEepromInterface()->getCapability(MultiposPotsPositions); i++) { + item = RawSwitch(SWITCH_TYPE_MULTIPOS_POT, i); + b->addItem(item.toString(), item.toValue()); + if (item == value) b->setCurrentIndex(b->count()-1); + } + + for (int i=1; i<=8; i++) { + item = RawSwitch(SWITCH_TYPE_TRIM, i); + b->addItem(item.toString(), item.toValue()); + if (item == value) b->setCurrentIndex(b->count()-1); + } + + for (int i=1; i<=GetEepromInterface()->getCapability(RotaryEncoders); i++) { + item = RawSwitch(SWITCH_TYPE_ROTARY_ENCODER, i); + b->addItem(item.toString(), item.toValue()); + if (item == value) b->setCurrentIndex(b->count()-1); } for (int i=1; i<=GetEepromInterface()->getCapability(CustomSwitches); i++) { @@ -895,66 +480,12 @@ void populateSwitchCB(QComboBox *b, const RawSwitch & value, unsigned long attr, if (item == value) b->setCurrentIndex(b->count()-1); } - if (IS_TARANIS(GetEepromInterface()->getBoard())) { - for (int i=0; igetCapability(MultiposPots) * GetEepromInterface()->getCapability(MultiposPotsPositions); i++) { - item = RawSwitch(SWITCH_TYPE_MULTIPOS_POT, i); - b->addItem(item.toString(), item.toValue()); - if (item == value) b->setCurrentIndex(b->count()-1); - } - } - if (attr & POPULATE_ONOFF) { item = RawSwitch(SWITCH_TYPE_ON); b->addItem(item.toString(), item.toValue()); if (item == value) b->setCurrentIndex(b->count()-1); } - if (attr & POPULATE_MSWITCHES) { - for (int i=1; i<=GetEepromInterface()->getCapability(SwitchesPositions); i++) { - item = RawSwitch(SWITCH_TYPE_MOMENT_SWITCH, i); - b->addItem(item.toString(), item.toValue()); - if (item == value) b->setCurrentIndex(b->count()-1); - } - - for (int i=1; i<=GetEepromInterface()->getCapability(CustomSwitches); i++) { - item = RawSwitch(SWITCH_TYPE_MOMENT_VIRTUAL, i); - b->addItem(item.toString(), item.toValue()); - if (item == value) b->setCurrentIndex(b->count()-1); - } - } - - if (attr & POPULATE_MSWITCHES) { - if (attr & POPULATE_ONOFF) { - item = RawSwitch(SWITCH_TYPE_ONM); - b->addItem(item.toString(), item.toValue()); - if (item == value) b->setCurrentIndex(b->count()-1); - } - if (IS_ARM(GetEepromInterface()->getBoard())) { - item = RawSwitch(SWITCH_TYPE_TRN,0); - if (GetEepromInterface()->isAvailable(item, context)) { - b->addItem(item.toString(), item.toValue()); - if (item == value) b->setCurrentIndex(b->count()-1); - } - item = RawSwitch(SWITCH_TYPE_TRN,1); - if (GetEepromInterface()->isAvailable(item, context)) { - b->addItem(item.toString(), item.toValue()); - if (item == value) b->setCurrentIndex(b->count()-1); - } - } - if (GetEepromInterface()->getBoard()==BOARD_SKY9X) { - item = RawSwitch(SWITCH_TYPE_REA,0); - if (GetEepromInterface()->isAvailable(item, context)) { - b->addItem(item.toString(), item.toValue()); - if (item == value) b->setCurrentIndex(b->count()-1); - } - item = RawSwitch(SWITCH_TYPE_REA,1); - if (GetEepromInterface()->isAvailable(item, context)) { - b->addItem(item.toString(), item.toValue()); - if (item == value) b->setCurrentIndex(b->count()-1); - } - } - } - b->setMaxVisibleItems(10); } @@ -1104,35 +635,6 @@ void populateSourceCB(QComboBox *b, const RawSource & source, const ModelData & b->setMaxVisibleItems(10); } -#define CSWITCH_STR "---- a~x a>x ax |a|b a=b a<=b d>=x |d|>=xTIM " -#define CSW_NUM_FUNC 18 // TODO enum -#define CSW_LEN_FUNC 6 -int csw_values[]={ - CS_FN_OFF, - CS_FN_VEQUAL, // added at the end to avoid everything renumbered - CS_FN_VPOS, - CS_FN_VNEG, - CS_FN_APOS, - CS_FN_ANEG, - CS_FN_AND, - CS_FN_OR, - CS_FN_XOR, - CS_FN_EQUAL, - CS_FN_NEQUAL, - CS_FN_GREATER, - CS_FN_LESS, - CS_FN_EGREATER, - CS_FN_ELESS, - CS_FN_DPOS, - CS_FN_DAPOS, - CS_FN_TIM -}; - -QString getCSWFunc(int val) -{ - return QString(CSWITCH_STR).mid(val*CSW_LEN_FUNC, CSW_LEN_FUNC); -} - float ValToTim(int value) { return ((value < -109 ? 129+value : (value < 7 ? (113+value)*5 : (53+value)*10))/10.0); @@ -1153,14 +655,39 @@ int TimToVal(float value) void populateCSWCB(QComboBox *b, int value) { + int order[] = { + CS_FN_OFF, + CS_FN_VEQUAL, // added at the end to avoid everything renumbered + CS_FN_VPOS, + CS_FN_VNEG, + // CS_FN_RANGE, + CS_FN_APOS, + CS_FN_ANEG, + CS_FN_AND, + CS_FN_OR, + CS_FN_XOR, + CS_FN_STAY, + CS_FN_EQUAL, + CS_FN_NEQUAL, + CS_FN_GREATER, + CS_FN_LESS, + CS_FN_EGREATER, + CS_FN_ELESS, + CS_FN_DPOS, + CS_FN_DAPOS, + CS_FN_TIMER, + CS_FN_STICKY + }; + b->clear(); - for (int i = 0; i < CSW_NUM_FUNC; i++) { - b->addItem(getCSWFunc(i),csw_values[i]); - if (i>GetEepromInterface()->getCapability(CSFunc)) { - QModelIndex index = b->model()->index(i, 0); - QVariant v(0); - } - if (value == csw_values[i]) { + for (int i=0; iaddItem(CustomSwData(func).funcToString(), func); +// if (i>GetEepromInterface()->getCapability(CSFunc)) { +// QModelIndex index = b->model()->index(i, 0); +// QVariant v(0); +// } + if (value == func) { b->setCurrentIndex(b->count()-1); } } @@ -1328,7 +855,7 @@ QString getTrimInc(ModelData * g_model) QString getTimerStr(TimerData & timer) { QString str = ", " + (timer.dir ? QObject::tr("Count Up") : QObject::tr("Count Down")); - return QObject::tr("%1:%2, ").arg(timer.val/60, 2, 10, QChar('0')).arg(timer.val%60, 2, 10, QChar('0')) + getTimerMode(timer.mode) + str; + return QObject::tr("%1:%2, ").arg(timer.val/60, 2, 10, QChar('0')).arg(timer.val%60, 2, 10, QChar('0')) + timer.mode.toString() + str; } QString getProtocol(ModelData * g_model) @@ -1369,13 +896,6 @@ QString getPhasesStr(unsigned int phases, ModelData & model) } } -float c9xexpou(float point, float coeff) -{ - float x=point*1024.0/100.0; - float k=coeff*256.0/100.0; - return ((k*x*x*x/(1024*1024) + x*(256-k) + 128) / 256)/1024.0*100; -} - QString getCenterBeep(ModelData * g_model) { //RETA123 diff --git a/companion/src/helpers.h b/companion/src/helpers.h index 2d7f08ad6..4c742faad 100644 --- a/companion/src/helpers.h +++ b/companion/src/helpers.h @@ -82,19 +82,13 @@ class CurveGroup : public QObject { }; #define POPULATE_ONOFF 0x01 -#define POPULATE_MSWITCHES 0x02 -#define POPULATE_AND_SWITCHES 0x04 -void populateSwitchCB(QComboBox *b, const RawSwitch & value, unsigned long attr=0, UseContext context=DefaultContext); -void populateFuncCB(QComboBox *b, unsigned int value); -void populateGVmodeCB(QComboBox *b, unsigned int value); -QString FuncParam(uint function, int value, QString paramT="",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); +#define POPULATE_TIMER_MODES 0x02 +void populateAndSwitchCB(QComboBox *b, const RawSwitch & value); +void populateSwitchCB(QComboBox *b, const RawSwitch & value, unsigned long attr=0); + void populatePhasesCB(QComboBox *b, int value); void populateGvarUseCB(QComboBox *b, unsigned int phase); void populateCustomScreenFieldCB(QComboBox *b, unsigned int value, bool last, int hubproto); -void populateTimerSwitchCB(QComboBox *b, int value); -QString getCustomSwitchStr(CustomSwData * customSw, const ModelData & model); QString getProtocolStr(const int proto); QString getPhasesStr(unsigned int phases, ModelData & model); @@ -113,13 +107,8 @@ QString getPhasesStr(unsigned int phases, ModelData & model); void populateGVCB(QComboBox *b, int value); void populateSourceCB(QComboBox *b, const RawSource &source, const ModelData & model, unsigned int flags); void populateCSWCB(QComboBox *b, int value); -QString getTimerMode(int tm); -QString getTimerModeB(int tm); QString getPhaseName(int val, char * phasename=NULL); QString getInputStr(ModelData & model, int index); -QString getCSWFunc(int val); -QString getFuncName(unsigned int val); -QString getRepeatString(unsigned int val); QString getSignedStr(int value); QString getGVarString(int16_t val, bool sign=false); QString image2qstring(QImage image); @@ -139,7 +128,6 @@ QString getFrSkyProtocol(int protocol); QString getFrSkyMeasure(int units); QString getFrSkySrc(int index); -float c9xexpou(float point, float coeff); float ValToTim(int value); int TimToVal(float value); diff --git a/companion/src/modeledit/curves.cpp b/companion/src/modeledit/curves.cpp index fe54f3d7d..1112b1dde 100644 --- a/companion/src/modeledit/curves.cpp +++ b/companion/src/modeledit/curves.cpp @@ -495,6 +495,13 @@ void ModelEdit::on_ca_ctype_CB_currentIndexChanged() } } +float c9xexpou(float point, float coeff) +{ + float x=point*1024.0/100.0; + float k=coeff*256.0/100.0; + return ((k*x*x*x/(1024*1024) + x*(256-k) + 128) / 256)/1024.0*100; +} + void ModelEdit::on_ca_apply_PB_clicked() { int index=ui->ca_ctype_CB->currentIndex(); diff --git a/companion/src/modeledit/customfunctions.cpp b/companion/src/modeledit/customfunctions.cpp index bbbe15fdf..d2468bc19 100644 --- a/companion/src/modeledit/customfunctions.cpp +++ b/companion/src/modeledit/customfunctions.cpp @@ -36,6 +36,16 @@ void RepeatComboBox::onIndexChanged(int index) emit modified(); } +void RepeatComboBox::update() +{ + unsigned int step = IS_ARM(GetEepromInterface()->getBoard()) ? 1 : 10; + int value = repeatParam/step; + if (step == 1) { + value++; + } + setCurrentIndex(value); +} + CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings): ModelPanel(parent, model), generalSettings(generalSettings), @@ -52,7 +62,6 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData & model, lock = true; int num_fsw = GetEepromInterface()->getCapability(CustomFunctions); - QStringList paramarmList; if (!GetEepromInterface()->getCapability(VoicesAsNumbers)) { for (int i=0; isetContextMenuPolicy(Qt::CustomContextMenu); + label->setMouseTracking(true); + label->setProperty("index", i); + label->setText(tr("CF%1").arg(i+1)); + gridLayout->addWidget(label, i+1, 0); + connect(label, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(fsw_customContextMenuRequested(QPoint))); + // The switch fswtchSwtch[i] = new QComboBox(this); fswtchSwtch[i]->setProperty("index", i); connect(fswtchSwtch[i], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited())); gridLayout->addWidget(fswtchSwtch[i], i+1, 1); - populateSwitchCB(fswtchSwtch[i], model.funcSw[i].swtch, POPULATE_MSWITCHES|POPULATE_ONOFF); + populateSwitchCB(fswtchSwtch[i], model.funcSw[i].swtch, POPULATE_ONOFF); // The function fswtchFunc[i] = new QComboBox(this); @@ -135,7 +153,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData & model, fswtchParamArmT[i] = new QComboBox(this); fswtchParamArmT[i]->setProperty("index", i); - populateFuncParamArmTCB(fswtchParamArmT[i],&model, model.funcSw[i].paramarm, paramarmList); + populateFuncParamArmTCB(fswtchParamArmT[i], model.funcSw[i].paramarm, paramarmList); fswtchParamArmT[i]->setEditable(true); paramLayout->addWidget(fswtchParamArmT[i]); @@ -286,7 +304,7 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) int index = fswtchFunc[i]->currentIndex(); - if (index>=FuncSafetyCh1 && index<=FuncSafetyCh16) { + if (index>=FuncSafetyCh1 && index<=FuncSafetyCh32) { fswtchParam[i]->setDecimals(0); fswtchParam[i]->setSingleStep(1); fswtchParam[i]->setMinimum(-125); @@ -337,6 +355,7 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) else if (index==FuncPlaySound || index==FuncPlayHaptic || index==FuncPlayValue || index==FuncPlayPrompt || index==FuncPlayBoth || index==FuncBackgroundMusic) { if (index != FuncBackgroundMusic && GetEepromInterface()->getCapability(HasFuncRepeat)) { widgetsMask |= CUSTOM_FUNCTION_REPEAT; + fswtchRepeat[i]->update(); } if (index==FuncPlayValue) { if (modified) model.funcSw[i].param = fswtchParamT[i]->itemData(fswtchParamT[i]->currentIndex()).toInt(); @@ -381,14 +400,20 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) widgetsMask |= CUSTOM_FUNCTION_FILE_PARAM; if (modified) { memset(model.funcSw[i].paramarm, 0, sizeof(model.funcSw[i].paramarm)); - int vml=GetEepromInterface()->getCapability(VoicesMaxLength); + int vml = GetEepromInterface()->getCapability(VoicesMaxLength); if (fswtchParamArmT[i]->currentText() != "----") { widgetsMask |= CUSTOM_FUNCTION_PLAY; - for (int j=0; jcurrentText().length(),vml); j++) { + for (int j=0; jcurrentText().length(), vml); j++) { model.funcSw[i].paramarm[j] = fswtchParamArmT[i]->currentText().toAscii().at(j); } } } + else { + populateFuncParamArmTCB(fswtchParamArmT[i], model.funcSw[i].paramarm, paramarmList); + if (fswtchParamArmT[i]->currentText() != "----") { + widgetsMask |= CUSTOM_FUNCTION_PLAY; + } + } } } else if (index==FuncBackgroundMusic) { @@ -453,13 +478,13 @@ void CustomFunctionsPanel::fswPaste() const QMimeData *mimeData = clipboard->mimeData(); if (mimeData->hasFormat("application/x-companion-fsw")) { QByteArray fswData = mimeData->data("application/x-companion-fsw"); - FuncSwData *fsw = &model.funcSw[selectedFunction]; memcpy(fsw, fswData.mid(0, sizeof(FuncSwData)).constData(), sizeof(FuncSwData)); - // TODO update switch and func - populateSwitchCB(fswtchSwtch[selectedFunction], model.funcSw[selectedFunction].swtch, POPULATE_MSWITCHES|POPULATE_ONOFF); + lock = true; + populateSwitchCB(fswtchSwtch[selectedFunction], model.funcSw[selectedFunction].swtch, POPULATE_ONOFF); populateFuncCB(fswtchFunc[selectedFunction], model.funcSw[selectedFunction].func); refreshCustomFunction(selectedFunction); + lock = false; emit modified(); } } @@ -468,7 +493,7 @@ void CustomFunctionsPanel::fswDelete() { model.funcSw[selectedFunction].clear(); // TODO update switch and func - populateSwitchCB(fswtchSwtch[selectedFunction], model.funcSw[selectedFunction].swtch, POPULATE_MSWITCHES|POPULATE_ONOFF); + populateSwitchCB(fswtchSwtch[selectedFunction], model.funcSw[selectedFunction].swtch, POPULATE_ONOFF); populateFuncCB(fswtchFunc[selectedFunction], model.funcSw[selectedFunction].func); refreshCustomFunction(selectedFunction); emit modified(); @@ -476,17 +501,17 @@ void CustomFunctionsPanel::fswDelete() void CustomFunctionsPanel::fswCopy() { - QByteArray fswData; - fswData.append((char*)&model.funcSw[selectedFunction],sizeof(FuncSwData)); - QMimeData *mimeData = new QMimeData; - mimeData->setData("application/x-companion-fsw", fswData); - QApplication::clipboard()->setMimeData(mimeData,QClipboard::Clipboard); + QByteArray fswData; + fswData.append((char*)&model.funcSw[selectedFunction], sizeof(FuncSwData)); + QMimeData *mimeData = new QMimeData; + mimeData->setData("application/x-companion-fsw", fswData); + QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard); } void CustomFunctionsPanel::fswCut() { - fswCopy(); - fswDelete(); + fswCopy(); + fswDelete(); } void CustomFunctionsPanel::fsw_customContextMenuRequested(QPoint pos) @@ -508,3 +533,124 @@ void CustomFunctionsPanel::fsw_customContextMenuRequested(QPoint pos) contextMenu.exec(globalPos); } + +void CustomFunctionsPanel::populateFuncCB(QComboBox *b, unsigned int value) +{ + b->clear(); + for (unsigned int i=0; iaddItem(FuncSwData(AssignFunc(i)).funcToString()); + if (!GetEepromInterface()->getCapability(HasVolume)) { + if (i==FuncVolume || i==FuncBackgroundMusic || i==FuncBackgroundMusicPause) { + QModelIndex index = b->model()->index(i, 0); + QVariant v(0); + b->model()->setData(index, v, Qt::UserRole - 1); + } + } + if ((i==FuncPlayHaptic) && !GetEepromInterface()->getCapability(Haptic)) { + QModelIndex index = b->model()->index(i, 0); + QVariant v(0); + b->model()->setData(index, v, Qt::UserRole - 1); + } + if ((i==FuncPlayBoth) && !GetEepromInterface()->getCapability(HasBeeper)) { + QModelIndex index = b->model()->index(i, 0); + QVariant v(0); + b->model()->setData(index, v, Qt::UserRole - 1); + } + if ((i==FuncLogs) && !GetEepromInterface()->getCapability(HasSDLogs)) { + QModelIndex index = b->model()->index(i, 0); + QVariant v(0); + b->model()->setData(index, v, Qt::UserRole - 1); + } + } + b->setCurrentIndex(value); + b->setMaxVisibleItems(10); +} + +void CustomFunctionsPanel::populateGVmodeCB(QComboBox *b, unsigned int value) +{ + b->clear(); + b->addItem(QObject::tr("Value")); + b->addItem(QObject::tr("Source")); + b->addItem(QObject::tr("GVAR")); + b->addItem(QObject::tr("Increment")); + b->setCurrentIndex(value); +} + +void CustomFunctionsPanel::populateFuncParamArmTCB(QComboBox *b, char * value, QStringList & paramsList) +{ + b->clear(); + b->addItem("----"); + + bool added = false; + QString currentvalue(value); + foreach ( QString entry, paramsList ) { + b->addItem(entry); + if (entry==currentvalue) { + b->setCurrentIndex(b->count()-1); + added = true; + } + } + + if (!added && strlen(value)) { + b->addItem(value); + b->setCurrentIndex(b->count()-1); + } +} + +void CustomFunctionsPanel::populateFuncParamCB(QComboBox *b, const ModelData & model, uint function, unsigned int value, unsigned int adjustmode) +{ + QStringList qs; + b->clear(); + if (function==FuncPlaySound) { + qs <<"Beep 1" << "Beep 2" << "Beep 3" << "Warn1" << "Warn2" << "Cheep" << "Ratata" << "Tick" << "Siren" << "Ring" ; + qs << "SciFi" << "Robot" << "Chirp" << "Tada" << "Crickt" << "AlmClk" ; + b->addItems(qs); + b->setCurrentIndex(value); + } + else if (function==FuncPlayHaptic) { + qs << "0" << "1" << "2" << "3"; + b->addItems(qs); + b->setCurrentIndex(value); + } + else if (function==FuncReset) { + qs.append( QObject::tr("Timer1")); + qs.append( QObject::tr("Timer2")); + qs.append( QObject::tr("All")); + qs.append( QObject::tr("Telemetry")); + int reCount = GetEepromInterface()->getCapability(RotaryEncoders); + if (reCount == 1) { + qs.append( QObject::tr("Rotary Encoder")); + } + else if (reCount == 2) { + qs.append( QObject::tr("REa")); + qs.append( QObject::tr("REb")); + } + b->addItems(qs); + b->setCurrentIndex(value); + } + else if (function==FuncVolume) { + populateSourceCB(b, RawSource(value), model, POPULATE_SOURCES|POPULATE_TRIMS); + } + else if (function==FuncPlayValue) { + populateSourceCB(b, RawSource(value), model, POPULATE_SOURCES|POPULATE_VIRTUAL_INPUTS|POPULATE_SWITCHES|POPULATE_GVARS|POPULATE_TRIMS|POPULATE_TELEMETRYEXT); + } + else if (function>=FuncAdjustGV1 && function<=FuncAdjustGVLast) { + switch (adjustmode) { + case 1: + populateSourceCB(b, RawSource(value), model, POPULATE_SOURCES|POPULATE_TRIMS|POPULATE_SWITCHES); + break; + case 2: + populateSourceCB(b, RawSource(value), model, POPULATE_GVARS); + break; + case 3: + b->clear(); + b->addItem("-1", 0); + b->addItem("+1", 1); + b->setCurrentIndex(value); + break; + } + } + else { + b->hide(); + } +} diff --git a/companion/src/modeledit/customfunctions.h b/companion/src/modeledit/customfunctions.h index ccb73582e..0730e46c6 100644 --- a/companion/src/modeledit/customfunctions.h +++ b/companion/src/modeledit/customfunctions.h @@ -19,6 +19,7 @@ class RepeatComboBox: public QComboBox public: RepeatComboBox(QWidget *parent, int & repeatParam); + void update(); signals: void modified(); @@ -55,7 +56,13 @@ class CustomFunctionsPanel : public ModelPanel void fswCut(); private: + void populateFuncCB(QComboBox *b, unsigned int value); + void populateGVmodeCB(QComboBox *b, unsigned int value); + void populateFuncParamCB(QComboBox *b, const ModelData & model, uint function, unsigned int value, unsigned int adjustmode=0); + void populateFuncParamArmTCB(QComboBox *b, char * value, QStringList & paramsList); + GeneralSettings & generalSettings; + QStringList paramarmList; bool phononLock; QComboBox * fswtchSwtch[C9X_MAX_CUSTOM_FUNCTIONS]; QComboBox * fswtchFunc[C9X_MAX_CUSTOM_FUNCTIONS]; @@ -65,7 +72,7 @@ class CustomFunctionsPanel : public ModelPanel QComboBox * fswtchParamT[C9X_MAX_CUSTOM_FUNCTIONS]; QComboBox * fswtchParamArmT[C9X_MAX_CUSTOM_FUNCTIONS]; QCheckBox * fswtchEnable[C9X_MAX_CUSTOM_FUNCTIONS]; - QComboBox * fswtchRepeat[C9X_MAX_CUSTOM_FUNCTIONS]; + RepeatComboBox * fswtchRepeat[C9X_MAX_CUSTOM_FUNCTIONS]; QComboBox * fswtchGVmode[C9X_MAX_CUSTOM_FUNCTIONS]; #ifdef PHONON Phonon::MediaObject *clickObject; diff --git a/companion/src/modeledit/customswitches.cpp b/companion/src/modeledit/customswitches.cpp index 68d3fc34f..72c9404f0 100644 --- a/companion/src/modeledit/customswitches.cpp +++ b/companion/src/modeledit/customswitches.cpp @@ -46,7 +46,7 @@ CustomSwitchesPanel::CustomSwitchesPanel(QWidget * parent, ModelData & model): // V1 cswitchSource1[i] = new QComboBox(this); cswitchSource1[i]->setProperty("index",i); - connect(cswitchSource1[i], SIGNAL(currentIndexChanged(int)), this, SLOT(edited())); + connect(cswitchSource1[i], SIGNAL(currentIndexChanged(int)), this, SLOT(v1Edited(int))); gridLayout->addWidget(cswitchSource1[i], i+1, 2); cswitchSource1[i]->setVisible(false); cswitchValue[i] = new QDoubleSpinBox(this); @@ -62,7 +62,7 @@ CustomSwitchesPanel::CustomSwitchesPanel(QWidget * parent, ModelData & model): // V2 cswitchSource2[i] = new QComboBox(this); cswitchSource2[i]->setProperty("index", i); - connect(cswitchSource2[i], SIGNAL(currentIndexChanged(int)), this, SLOT(edited())); + connect(cswitchSource2[i], SIGNAL(currentIndexChanged(int)), this, SLOT(v2Edited(int))); gridLayout->addWidget(cswitchSource2[i], i+1, 3); cswitchSource2[i]->setVisible(false); cswitchOffset[i] = new QDoubleSpinBox(this); @@ -78,9 +78,8 @@ CustomSwitchesPanel::CustomSwitchesPanel(QWidget * parent, ModelData & model): // AND cswitchAnd[i] = new QComboBox(this); cswitchAnd[i]->setProperty("index", i); - connect(cswitchAnd[i], SIGNAL(currentIndexChanged(int)), this, SLOT(edited())); + connect(cswitchAnd[i], SIGNAL(currentIndexChanged(int)), this, SLOT(andEdited(int))); gridLayout->addWidget(cswitchAnd[i], i+1, 4); - cswitchAnd[i]->setVisible(false); if (GetEepromInterface()->getCapability(CustomSwitchesExt)) { // Duration @@ -91,9 +90,8 @@ CustomSwitchesPanel::CustomSwitchesPanel(QWidget * parent, ModelData & model): cswitchDuration[i]->setMinimum(0); cswitchDuration[i]->setAccelerated(true); cswitchDuration[i]->setDecimals(1); - connect(cswitchDuration[i],SIGNAL(editingFinished()), this, SLOT(edited())); + connect(cswitchDuration[i], SIGNAL(valueChanged(double)), this, SLOT(durationEdited(double))); gridLayout->addWidget(cswitchDuration[i], i+1, 5); - cswitchDuration[i]->setVisible(false); // Delay cswitchDelay[i] = new QDoubleSpinBox(this); @@ -103,9 +101,8 @@ CustomSwitchesPanel::CustomSwitchesPanel(QWidget * parent, ModelData & model): cswitchDelay[i]->setMinimum(0); cswitchDelay[i]->setAccelerated(true); cswitchDelay[i]->setDecimals(1); - connect(cswitchDelay[i], SIGNAL(editingFinished()), this, SLOT(edited())); + connect(cswitchDelay[i], SIGNAL(valueChanged(double)), this, SLOT(delayEdited(double))); gridLayout->addWidget(cswitchDelay[i], i+1, 6); - cswitchDelay[i]->setVisible(false); } } @@ -116,59 +113,99 @@ CustomSwitchesPanel::~CustomSwitchesPanel() { } +void CustomSwitchesPanel::v1Edited(int value) +{ + if (!lock) { + int i = sender()->property("index").toInt(); + model.customSw[i].val1 = cswitchSource1[i]->itemData(value).toInt(); + if (model.customSw[i].getFunctionFamily() == CS_FAMILY_VOFS) { + RawSource source = RawSource(model.customSw[i].val1, &model); + if (source.type == SOURCE_TYPE_TELEMETRY) { + if (model.customSw[i].func > CS_FN_ELESS && model.customSw[i].func < CS_FN_VEQUAL) { + model.customSw[i].val2 = 0; + } + else { + model.customSw[i].val2 = -128; + } + } + else { + RawSourceRange range = source.getRange(); + if (model.customSw[i].func > CS_FN_ELESS && model.customSw[i].func < CS_FN_VEQUAL) { + model.customSw[i].val2 = (cswitchOffset[i]->value() / range.step); + } + else { + model.customSw[i].val2 = (cswitchOffset[i]->value() - range.offset) / range.step/* TODO - source.getRawOffset(model)*/; + } + } + setSwitchWidgetVisibility(i); + } + emit modified(); + } +} + +void CustomSwitchesPanel::v2Edited(int value) +{ + if (!lock) { + int i = sender()->property("index").toInt(); + model.customSw[i].val2 = cswitchSource2[i]->itemData(value).toInt(); + emit modified(); + } +} + +void CustomSwitchesPanel::andEdited(int value) +{ + if (!lock) { + int index = sender()->property("index").toInt(); + model.customSw[index].andsw = cswitchAnd[index]->itemData(value).toInt(); + emit modified(); + } +} + +void CustomSwitchesPanel::durationEdited(double duration) +{ + int index = sender()->property("index").toInt(); + model.customSw[index].duration = (uint8_t)round(duration*2); + emit modified(); +} + +void CustomSwitchesPanel::delayEdited(double delay) +{ + int index = sender()->property("index").toInt(); + model.customSw[index].delay = (uint8_t)round(delay*2); + emit modified(); +} + void CustomSwitchesPanel::edited() { if (!lock) { lock = true; int i = sender()->property("index").toInt(); - bool chAr; - float value, step; - int newval; - chAr = (getCSFunctionFamily(model.customSw[i].func) != getCSFunctionFamily(csw[i]->itemData(csw[i]->currentIndex()).toInt())); - model.customSw[i].func = csw[i]->itemData(csw[i]->currentIndex()).toInt(); - if(chAr) { - if (getCSFunctionFamily(model.customSw[i].func)==CS_FAMILY_TIMERS) { + int newFunc = csw[i]->itemData(csw[i]->currentIndex()).toInt(); + bool chAr = (model.customSw[i].getFunctionFamily() != CustomSwData(newFunc).getFunctionFamily()); + model.customSw[i].func = newFunc; + if (chAr) { + if (model.customSw[i].getFunctionFamily() == CS_FAMILY_TIMER) { model.customSw[i].val1 = -119; model.customSw[i].val2 = -119; - } else { + } + else if (model.customSw[i].getFunctionFamily() == CS_FAMILY_STAY) { + model.customSw[i].val1 = 0; + model.customSw[i].val2 = -129; + model.customSw[i].val3 = 0; + } + else { model.customSw[i].val1 = 0; model.customSw[i].val2 = 0; } model.customSw[i].andsw = 0; setSwitchWidgetVisibility(i); } - if (GetEepromInterface()->getCapability(CustomSwitchesExt)) { - model.customSw[i].duration= (uint8_t)round(cswitchDuration[i]->value()*2); - model.customSw[i].delay= (uint8_t)round(cswitchDelay[i]->value()*2); - } + RawSource source; - switch (getCSFunctionFamily(model.customSw[i].func)) + switch (model.customSw[i].getFunctionFamily()) { - case (CS_FAMILY_VOFS): - if (model.customSw[i].val1 != cswitchSource1[i]->itemData(cswitchSource1[i]->currentIndex()).toInt()) { - source = RawSource(model.customSw[i].val1, &model); - model.customSw[i].val1 = cswitchSource1[i]->itemData(cswitchSource1[i]->currentIndex()).toInt(); - RawSource newSource = RawSource(model.customSw[i].val1, &model); - if (newSource.type == SOURCE_TYPE_TELEMETRY) { - if (model.customSw[i].func>CS_FN_ELESS && model.customSw[i].funcCS_FN_ELESS && model.customSw[i].funcvalue() / range.step); - } - else { - model.customSw[i].val2 = (cswitchOffset[i]->value() - range.offset) / range.step/* TODO - source.getRawOffset(model)*/; - } - } - setSwitchWidgetVisibility(i); - } - else { + case CS_FAMILY_VOFS: + { source = RawSource(model.customSw[i].val1, &model); RawSourceRange range = source.getRange(); if (model.customSw[i].func>CS_FN_ELESS && model.customSw[i].funcvalue(); - newval=TimToVal(value); - if (newval>model.customSw[i].val2) { - if (value >=60) { - value=round(value); - step=1; - } else if (value>=2) { - value=(round(value*2.0)/2); - step=0.5; - } else { - step=0.1; - } - } else { - if (value <=2) { - step=0.1; - } else if (value<=60) { - value=(round(value*2.0)/2); - step=0.5; - } else { - value=round(value); - step=1; - } - } - model.customSw[i].val2=TimToVal(value); - value=ValToTim(model.customSw[i].val2); - cswitchOffset[i]->setValue(value); - cswitchOffset[i]->setSingleStep(step); - - value=cswitchValue[i]->value(); - newval=TimToVal(value); - if (newval>model.customSw[i].val1) { - if (value >=60) { - value=round(value); - step=1; - } else if (value>=2) { - value=(round(value*2.0)/2); - step=0.5; - } else { - step=0.1; - } - } else { - if (value <=2) { - step=0.1; - } else if (value<=60) { - value=(round(value*2.0)/2); - step=0.5; - } else { - value=round(value); - step=1; - } - } - model.customSw[i].val1=TimToVal(value); - value=ValToTim(model.customSw[i].val1); - cswitchValue[i]->setValue(value); - cswitchValue[i]->setSingleStep(step); + case CS_FAMILY_TIMER: + model.customSw[i].val1 = TimToVal(cswitchValue[i]->value()); + model.customSw[i].val2 = TimToVal(cswitchOffset[i]->value()); + updateTimerParam(cswitchValue[i], model.customSw[i].val1); + updateTimerParam(cswitchOffset[i], model.customSw[i].val2); break; - } - case (CS_FAMILY_VBOOL): - case (CS_FAMILY_VCOMP): - model.customSw[i].val1 = cswitchSource1[i]->itemData(cswitchSource1[i]->currentIndex()).toInt(); - model.customSw[i].val2 = cswitchSource2[i]->itemData(cswitchSource2[i]->currentIndex()).toInt(); + case CS_FAMILY_STAY: + model.customSw[i].val2 = TimToVal(cswitchOffset[i]->value()); + updateTimerParam(cswitchOffset[i], model.customSw[i].val2, true); + break; + default: break; } - model.customSw[i].andsw = cswitchAnd[i]->itemData(cswitchAnd[i]->currentIndex()).toInt(); emit modified(); lock = false; } } +void CustomSwitchesPanel::updateTimerParam(QDoubleSpinBox *sb, int timer, bool allowZero) +{ + sb->setVisible(true); + sb->setDecimals(1); + sb->setMinimum(allowZero ? 0.0 : 0.1); + sb->setMaximum(175); + float value = ValToTim(timer); + if (value>60) + sb->setSingleStep(1); + else if (value>2) + sb->setSingleStep(0.5); + else + sb->setSingleStep(0.1); + sb->setValue(value); +} + void CustomSwitchesPanel::setSwitchWidgetVisibility(int i) { + lock = true; + RawSource source = RawSource(model.customSw[i].val1, &model); RawSourceRange range = source.getRange(); - switch (getCSFunctionFamily(model.customSw[i].func)) + switch (model.customSw[i].getFunctionFamily()) { case CS_FAMILY_VOFS: cswitchSource1[i]->setVisible(true); @@ -270,13 +273,15 @@ void CustomSwitchesPanel::setSwitchWidgetVisibility(int i) cswitchOffset[i]->setMinimum(range.step*-127); cswitchOffset[i]->setMaximum(range.step*127); cswitchOffset[i]->setValue(range.step*model.customSw[i].val2); - } else { + } + else { cswitchOffset[i]->setMinimum(range.min); cswitchOffset[i]->setMaximum(range.max); cswitchOffset[i]->setValue(range.step*(model.customSw[i].val2/* TODO+source.getRawOffset(model)*/)+range.offset); } break; case CS_FAMILY_VBOOL: + case CS_FAMILY_STICKY: cswitchSource1[i]->setVisible(true); cswitchSource2[i]->setVisible(true); cswitchValue[i]->setVisible(false); @@ -284,6 +289,13 @@ void CustomSwitchesPanel::setSwitchWidgetVisibility(int i) populateSwitchCB(cswitchSource1[i], RawSwitch(model.customSw[i].val1)); populateSwitchCB(cswitchSource2[i], RawSwitch(model.customSw[i].val2)); break; + case CS_FAMILY_STAY: + cswitchSource1[i]->setVisible(true); + cswitchSource2[i]->setVisible(false); + cswitchValue[i]->setVisible(false); + populateSwitchCB(cswitchSource1[i], RawSwitch(model.customSw[i].val1)); + updateTimerParam(cswitchOffset[i], model.customSw[i].val2, true); + break; case CS_FAMILY_VCOMP: cswitchSource1[i]->setVisible(true); cswitchSource2[i]->setVisible(true); @@ -292,54 +304,32 @@ void CustomSwitchesPanel::setSwitchWidgetVisibility(int i) populateSourceCB(cswitchSource1[i], RawSource(model.customSw[i].val1), model, POPULATE_SOURCES | POPULATE_VIRTUAL_INPUTS | POPULATE_TRIMS | POPULATE_SWITCHES | POPULATE_TELEMETRY | (GetEepromInterface()->getCapability(GvarsInCS) ? POPULATE_GVARS : 0)); populateSourceCB(cswitchSource2[i], RawSource(model.customSw[i].val2), model, POPULATE_SOURCES | POPULATE_TRIMS | POPULATE_VIRTUAL_INPUTS | POPULATE_SWITCHES | POPULATE_TELEMETRY | (GetEepromInterface()->getCapability(GvarsInCS) ? POPULATE_GVARS : 0)); break; - case CS_FAMILY_TIMERS: + case CS_FAMILY_TIMER: cswitchSource1[i]->setVisible(false); cswitchSource2[i]->setVisible(false); - cswitchValue[i]->setVisible(true); - cswitchOffset[i]->setVisible(true); - cswitchOffset[i]->setDecimals(1); - cswitchOffset[i]->setMinimum(0.1); - cswitchOffset[i]->setMaximum(175); - float value=ValToTim(model.customSw[i].val2); - cswitchOffset[i]->setSingleStep(0.1); - if (value>60) { - cswitchOffset[i]->setSingleStep(1); - } else if (value>2) { - cswitchOffset[i]->setSingleStep(0.5); - } - cswitchOffset[i]->setValue(value); - - cswitchValue[i]->setDecimals(1); - cswitchValue[i]->setMinimum(0.1); - cswitchValue[i]->setMaximum(175); - value=ValToTim(model.customSw[i].val1); - cswitchValue[i]->setSingleStep(0.1); - if (value>60) { - cswitchValue[i]->setSingleStep(1); - } else if (value>2) { - cswitchValue[i]->setSingleStep(0.5); - } - cswitchValue[i]->setValue(value); + updateTimerParam(cswitchValue[i], model.customSw[i].val1); + updateTimerParam(cswitchOffset[i], model.customSw[i].val2); break; } - cswitchAnd[i]->setVisible(true); - populateSwitchCB(cswitchAnd[i], RawSwitch(model.customSw[i].andsw), POPULATE_AND_SWITCHES); - if (GetEepromInterface()->getCapability(CustomSwitchesExt)) { - cswitchDuration[i]->setVisible(true); - cswitchDuration[i]->setValue(model.customSw[i].duration/2.0); - cswitchDelay[i]->setVisible(true); - cswitchDelay[i]->setValue(model.customSw[i].delay/2.0); - } + + lock = false; } void CustomSwitchesPanel::update() { - lock = true; for (int i=0; igetCapability(CustomSwitches); i++) { + lock = true; populateCSWCB(csw[i], model.customSw[i].func); + lock = false; setSwitchWidgetVisibility(i); + lock = true; + populateAndSwitchCB(cswitchAnd[i], RawSwitch(model.customSw[i].andsw)); + if (GetEepromInterface()->getCapability(CustomSwitchesExt)) { + cswitchDuration[i]->setValue(model.customSw[i].duration/2.0); + cswitchDelay[i]->setValue(model.customSw[i].delay/2.0); + } + lock = false; } - lock = false; } void CustomSwitchesPanel::cswPaste() diff --git a/companion/src/modeledit/customswitches.h b/companion/src/modeledit/customswitches.h index c00ad60b6..0ff1973d6 100644 --- a/companion/src/modeledit/customswitches.h +++ b/companion/src/modeledit/customswitches.h @@ -17,6 +17,11 @@ class CustomSwitchesPanel : public ModelPanel private slots: void edited(); + void v1Edited(int value); + void v2Edited(int value); + void andEdited(int value); + void durationEdited(double duration); + void delayEdited(double delay); void csw_customContextMenuRequested(QPoint pos); void cswDelete(); void cswCopy(); @@ -36,6 +41,8 @@ class CustomSwitchesPanel : public ModelPanel int selectedSwitch; void updateSelectedSwitch(); + void updateV2(int index); + void updateTimerParam(QDoubleSpinBox *sb, int timer, bool allowZero=false); }; diff --git a/companion/src/modeledit/setup.cpp b/companion/src/modeledit/setup.cpp index 4d0b24efa..a3ee674a1 100644 --- a/companion/src/modeledit/setup.cpp +++ b/companion/src/modeledit/setup.cpp @@ -11,8 +11,10 @@ TimerPanel::TimerPanel(QWidget *parent, ModelData & model, TimerData & timer): { ui->setupUi(this); + lock = true; + // Mode - populateTimerSwitchCB(ui->mode, timer.mode); + populateSwitchCB(ui->mode, timer.mode, POPULATE_TIMER_MODES); if (!GetEepromInterface()->getCapability(PermTimers)) { ui->persistent->hide(); @@ -23,6 +25,8 @@ TimerPanel::TimerPanel(QWidget *parent, ModelData & model, TimerData & timer): ui->countdownBeep->addItem(tr("Beeps")); if (IS_ARM(GetEepromInterface()->getBoard()) || IS_2560(GetEepromInterface()->getBoard())) ui->countdownBeep->addItem(tr("Countdown")); + + lock = false; } TimerPanel::~TimerPanel() @@ -63,8 +67,10 @@ void TimerPanel::on_value_editingFinished() void TimerPanel::on_mode_currentIndexChanged(int index) { - timer.mode = TimerMode(ui->mode->itemData(index).toInt()); - emit modified(); + if (!lock) { + timer.mode = RawSwitch(ui->mode->itemData(index).toInt()); + emit modified(); + } } void TimerPanel::on_persistent_toggled(bool checked) diff --git a/companion/src/modeledit/telemetry.cpp b/companion/src/modeledit/telemetry.cpp index 014def777..1b5fd285f 100644 --- a/companion/src/modeledit/telemetry.cpp +++ b/companion/src/modeledit/telemetry.cpp @@ -352,7 +352,7 @@ void TelemetryCustomScreen::updateBar(int line) RawSource source = RawSource(SOURCE_TYPE_TELEMETRY, index-1, &model); RawSourceRange range = source.getRange(true); int max = round((range.max - range.min) / range.step); - if (255-screen.body.bars[line].barMax > max) + if (int(255-screen.body.bars[line].barMax) > max) screen.body.bars[line].barMax = 255 - max; minSB[line]->setEnabled(true); minSB[line]->setDecimals(range.decimals); diff --git a/companion/src/printdialog.cpp b/companion/src/printdialog.cpp index 45d149c97..be95c92be 100644 --- a/companion/src/printdialog.cpp +++ b/companion/src/printdialog.cpp @@ -54,7 +54,6 @@ printDialog::printDialog(QWidget *parent, GeneralSettings *gg, ModelData *gm, QS printCurves(); printGvars(); printSwitches(); - printSafetySwitches(); printFSwitches(); printFrSky(); @@ -651,7 +650,7 @@ void printDialog::printSwitches() } else { str.append(""+tr("LS")+('A'+(i-9))+""); } - QString tstr = getCustomSwitchStr(&g_model->customSw[i], *g_model); + QString tstr = g_model->customSw[i].toString(*g_model); str.append(doTC(tstr,"green")); str.append(""); sc++; @@ -693,33 +692,6 @@ void printDialog::printGvars() } } -void printDialog::printSafetySwitches() -{ - int sc=0; - QString str = ""; - str.append(""); - str.append("

"+tr("Safety Switches")+"

"); - str.append(""); - str.append(doTC(tr("Switch"), "", true)); - str.append(doTL(tr("Value"), "", true)); - str.append(""); - for(int i=0; igetCapability(Outputs); i++) - { - if (g_model->safetySw[i].swtch.type) { - str.append(""); - str.append(doTC(tr("CH")+QString("%1").arg(i+1),"",true)); - str.append(doTC(g_model->safetySw[i].swtch.toString(),"green")); - str.append(doTC(QString::number(g_model->safetySw[i].val),"green")); - str.append(""); - sc++; - } - } - str.append("
 
"); - str.append("
"); - if (sc!=0) - te->append(str); -} - void printDialog::printFSwitches() { int sc=0; @@ -736,8 +708,8 @@ void printDialog::printFSwitches() if (g_model->funcSw[i].swtch.type!=SWITCH_TYPE_NONE) { str.append(""); str.append(doTC(g_model->funcSw[i].swtch.toString(),"green")); - str.append(doTC(getFuncName(g_model->funcSw[i].func),"green")); - str.append(doTC(FuncParam(g_model->funcSw[i].func,g_model->funcSw[i].param,g_model->funcSw[i].paramarm, g_model->funcSw[i].adjustMode),"green")); + str.append(doTC(g_model->funcSw[i].funcToString(),"green")); + str.append(doTC(g_model->funcSw[i].paramToString(),"green")); int index=g_model->funcSw[i].func; if (index==FuncPlaySound || index==FuncPlayHaptic || index==FuncPlayValue || index==FuncPlayPrompt || index==FuncPlayBoth || index==FuncBackgroundMusic) { str.append(doTC(QString("%1").arg(g_model->funcSw[i].repeatParam),"green")); diff --git a/radio/src/audio_arm.cpp b/radio/src/audio_arm.cpp index dc16ff64a..5d2fb1be9 100644 --- a/radio/src/audio_arm.cpp +++ b/radio/src/audio_arm.cpp @@ -571,7 +571,7 @@ void AudioQueue::wakeup() } // mix the background context - if (!isFunctionActive(FUNC_BACKGND_MUSIC_PAUSE)) { + if (!isFunctionActive(FUNCTION_BACKGND_MUSIC_PAUSE)) { result = mixAudioContext(backgroundContext, buffer, g_eeGeneral.varioVolume, g_eeGeneral.backgroundVolume, fade); if (result > 0) { size = max(size, result); diff --git a/radio/src/eeprom_conversions.cpp b/radio/src/eeprom_conversions.cpp index f40f07325..eb0ff91c7 100644 --- a/radio/src/eeprom_conversions.cpp +++ b/radio/src/eeprom_conversions.cpp @@ -196,15 +196,18 @@ void ConvertGeneralSettings_215_to_216(EEGeneral &settings) #if defined(PCBTARANIS) int ConvertSwitch_215_to_216(int swtch) { - if (swtch < SWSRC_ON) + if (swtch <= SWSRC_LAST_SWITCH) return swtch; else - return swtch + (2*6); // 2 * 6-pos pots added as switches + return swtch + (2*4) + (2*6); // 4 trims and 2 * 6-pos added as switches } #else inline int ConvertSwitch_215_to_216(int swtch) { - return swtch; + if (swtch <= SWSRC_LAST_SWITCH) + return swtch; + else + return swtch + (2*4) + 1; // 4 trims and REa added } #endif @@ -219,7 +222,7 @@ void ConvertModel_215_to_216(ModelData &model) // Custom Switches: better precision for x when A comes from telemetry // Main View: altitude in top bar // Mixes: GVARS in weight moved from 512 to 4096 and -512 to -4096, because GVARS may be used in limits [-1250:1250] - // Switches: two 6-pos pots added + // Switches: two 6-pos pots added, REa added to Sky9x TRACE("Model conversion from v215 to v216"); @@ -378,13 +381,13 @@ void ConvertModel_215_to_216(ModelData &model) #if defined(PCBTARANIS) CustomSwData * cs = &g_model.customSw[i]; uint8_t cstate = cswFamily(cs->func); - if (cstate == CS_VOFS || cstate == CS_VCOMP || cstate == CS_VDIFF) { + if (cstate == CS_FAMILY_OFS || cstate == CS_FAMILY_COMP || cstate == CS_FAMILY_DIFF) { if (cs->v1 > 0) cs->v1 += MAX_INPUTS + MAX_SCRIPTS*MAX_SCRIPT_OUTPUTS; if (cs->v1 > MIXSRC_GVAR1+4) cs->v1 += 4; } - if (cstate == CS_VOFS || cstate == CS_VDIFF) { + if (cstate == CS_FAMILY_OFS || cstate == CS_FAMILY_DIFF) { if (cs->v1 >= MIXSRC_FIRST_TELEM) { - switch (cs->v1) { + switch ((uint8_t)cs->v1) { case MIXSRC_FIRST_TELEM + TELEM_TM1-1: case MIXSRC_FIRST_TELEM + TELEM_TM2-1: cs->v2 = (cs->v2+128) * 3; @@ -426,7 +429,7 @@ void ConvertModel_215_to_216(ModelData &model) } } } - if (cstate == CS_VCOMP) { + if (cstate == CS_FAMILY_COMP) { if (cs->v2 > 0) cs->v2 += MAX_INPUTS + MAX_SCRIPTS*MAX_SCRIPT_OUTPUTS; if (cs->v2 > MIXSRC_GVAR1+4) cs->v2 += 4; } @@ -435,7 +438,7 @@ void ConvertModel_215_to_216(ModelData &model) for (uint8_t i=0; i<32; i++) { g_model.funcSw[i] = oldModel.funcSw[i]; CustomFnData *sd = &g_model.funcSw[i]; - if (CFN_FUNC(sd) == FUNC_PLAY_VALUE || CFN_FUNC(sd) == FUNC_VOLUME || (IS_ADJUST_GV_FUNCTION(sd) && CFN_GVAR_MODE(sd) == FUNC_ADJUST_GVAR_SOURCE)) { + if (CFN_FUNC(sd) == FUNC_PLAY_VALUE || CFN_FUNC(sd) == FUNC_VOLUME || (IS_ADJUST_GV_FUNC(CFN_FUNC(sd)) && CFN_GVAR_MODE(sd) == FUNC_ADJUST_GVAR_SOURCE)) { #if defined(PCBTARANIS) CFN_PARAM(sd) += 1 + MAX_INPUTS + MAX_SCRIPTS*MAX_SCRIPT_OUTPUTS; #endif diff --git a/radio/src/eeprom_raw.cpp b/radio/src/eeprom_raw.cpp index 5439e89a9..718fe3558 100644 --- a/radio/src/eeprom_raw.cpp +++ b/radio/src/eeprom_raw.cpp @@ -383,7 +383,6 @@ void eeLoadModel(uint8_t id) resumePulses(); } - activeSwitches = 0; activeFnSwitches = 0; activeFunctions = 0; memclear(lastFunctionTime, sizeof(lastFunctionTime)); diff --git a/radio/src/eeprom_rlc.cpp b/radio/src/eeprom_rlc.cpp index a56834186..f6f62502e 100644 --- a/radio/src/eeprom_rlc.cpp +++ b/radio/src/eeprom_rlc.cpp @@ -948,7 +948,6 @@ void eeLoadModel(uint8_t id) resumePulses(); } - activeSwitches = 0; activeFnSwitches = 0; activeFunctions = 0; memclear(lastFunctionTime, sizeof(lastFunctionTime)); diff --git a/radio/src/gui/menu_model.cpp b/radio/src/gui/menu_model.cpp index 4d12c3557..89847da43 100644 --- a/radio/src/gui/menu_model.cpp +++ b/radio/src/gui/menu_model.cpp @@ -1051,7 +1051,7 @@ void menuModelSetup(uint8_t event) } else { putsStrIdx(0*FW, y, STR_TIMER, k>=ITEM_MODEL_TIMER2 ? 2 : 1); - putsTmrMode(MODEL_SETUP_2ND_COLUMN, y, timer->mode, m_posHorz==0 ? attr : 0); + putsTimerMode(MODEL_SETUP_2ND_COLUMN, y, timer->mode, m_posHorz==0 ? attr : 0); putsTime(MODEL_SETUP_2ND_COLUMN+5*FW-2+5*FWNUM+1, y, timer->start, m_posHorz==1 ? attr : 0, m_posHorz==2 ? attr : 0); #if defined(PCBTARANIS) if (attr && m_posHorz < 0) lcd_filled_rect(MODEL_SETUP_2ND_COLUMN, y, LCD_W-MODEL_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH, 8); @@ -1060,7 +1060,7 @@ void menuModelSetup(uint8_t event) div_t qr = div(timer->start, 60); switch (m_posHorz) { case 0: - CHECK_INCDEC_MODELVAR(event, timer->mode, -2*(NUM_PSWITCH+NUM_CSW), TMR_VAROFS-1+2*(NUM_PSWITCH+NUM_CSW)); + CHECK_INCDEC_MODELVAR(event, timer->mode, SWSRC_FIRST, TMR_VAROFS+SWSRC_LAST-1/*--- which is OFF*/); break; case 1: CHECK_INCDEC_MODELVAR_ZERO(event, qr.quot, 59); @@ -1786,8 +1786,8 @@ void menuModelFlightModesAll(uint8_t event) lcd_puts((5+LEN_FP_NAME)*FW, y, STR_DEFAULT); } else { - putsSwitches((5+LEN_FP_NAME)*FW, y, p->swtch, attr); - if (active) CHECK_INCDEC_MODELSWITCH(event, p->swtch, -NUM_SWITCH, NUM_SWITCH); + putsSwitches((5+LEN_FP_NAME)*FW+FW/2, y, p->swtch, attr); + if (active) CHECK_INCDEC_MODELSWITCH(event, p->swtch, SWSRC_FIRST, SWSRC_LAST); } break; @@ -4128,6 +4128,9 @@ enum CustomSwitchFields { CSW_FIELD_FUNCTION, CSW_FIELD_V1, CSW_FIELD_V2, +#if defined(PCBTARANIS) + CSW_FIELD_V3, +#endif CSW_FIELD_ANDSW, #if defined(CPUARM) CSW_FIELD_DURATION, @@ -4139,10 +4142,10 @@ enum CustomSwitchFields { #if LCD_W >= 212 #define CSW_1ST_COLUMN (4*FW-3) - #define CSW_2ND_COLUMN (8*FW+1) - #define CSW_3RD_COLUMN (14*FW) - #define CSW_4TH_COLUMN (21*FW+1) - #define CSW_5TH_COLUMN (26*FW+1) + #define CSW_2ND_COLUMN (8*FW+2+FW/2) + #define CSW_3RD_COLUMN (14*FW+1+FW/2) + #define CSW_4TH_COLUMN (22*FW) + #define CSW_5TH_COLUMN (26*FW+3) #define CSW_6TH_COLUMN (31*FW+1) #else #define CSW_1ST_COLUMN (4*FW-3) @@ -4162,7 +4165,8 @@ void menuModelCustomSwitchOne(uint8_t event) CustomSwData * cs = cswAddress(s_currIdx); uint8_t sw = SWSRC_SW1+s_currIdx; putsSwitches(14*FW, 0, sw, (getSwitch(sw) ? BOLD : 0)); - SIMPLE_SUBMENU_NOTITLE(CSW_FIELD_COUNT); + + SUBMENU_NOTITLE(CSW_FIELD_COUNT, {0, 0, 1, 0 /*, 0...*/}); int8_t sub = m_posVert; @@ -4176,10 +4180,18 @@ void menuModelCustomSwitchOne(uint8_t event) lcd_putsLeft(y, STR_FUNC); lcd_putsiAtt(CSWONE_2ND_COLUMN, y, STR_VCSWFUNC, cs->func, attr); if (attr) { - CHECK_INCDEC_MODELVAR_ZERO(event, cs->func, CS_MAXF); - if (cstate != cswFamily(cs->func)) { - cs->v1 = 0; - cs->v2 = 0; + cs->func = checkIncDec(event, cs->func, 0, CS_MAXF, EE_MODEL, isFunctionAvailable); + uint8_t new_cstate = cswFamily(cs->func); + if (cstate != new_cstate) { + if (new_cstate == CS_FAMILY_TIMER) { + cs->v1 = cs->v2 = -119; + } + else if (new_cstate == CS_FAMILY_STAY) { + cs->v1 = 0; cs->v2 = -129; cs->v3 = 0; + } + else { + cs->v1 = cs->v2 = 0; + } } } break; @@ -4187,11 +4199,11 @@ void menuModelCustomSwitchOne(uint8_t event) { lcd_putsLeft(y, STR_V1); int8_t v1_min=0, v1_max=MIXSRC_LAST_TELEM; - if (cstate == CS_VBOOL) { + if (cstate == CS_FAMILY_BOOL || cstate == CS_FAMILY_STICKY || cstate == CS_FAMILY_STAY) { putsSwitches(CSWONE_2ND_COLUMN, y, cs->v1, attr); v1_min = SWSRC_OFF+1; v1_max = SWSRC_ON-1; } - else if (cstate == CS_VTIMER) { + else if (cstate == CS_FAMILY_TIMER) { lcd_outdezAtt(CSWONE_2ND_COLUMN, y, cs->v1+1, LEFT|attr); v1_max = 99; } @@ -4206,16 +4218,32 @@ void menuModelCustomSwitchOne(uint8_t event) case CSW_FIELD_V2: { lcd_putsLeft(y, STR_V2); - int8_t v2_min=0, v2_max=MIXSRC_LAST_TELEM; - if (cstate == CS_VBOOL) { + int16_t v2_min=0, v2_max=MIXSRC_LAST_TELEM; + if (cstate == CS_FAMILY_BOOL || cstate == CS_FAMILY_STICKY) { putsSwitches(CSWONE_2ND_COLUMN, y, cs->v2, attr); v2_min = SWSRC_OFF+1; v2_max = SWSRC_ON-1; } - else if (cstate == CS_VTIMER) { + else if (cstate == CS_FAMILY_TIMER) { lcd_outdezAtt(CSWONE_2ND_COLUMN, y, cs->v2+1, LEFT|attr); v2_max = 99; } - else if (cstate == CS_VCOMP) { + else if (cstate == CS_FAMILY_STAY) { + lcd_putc(CSWONE_2ND_COLUMN-4, y, '['); + lcd_outdezAtt(CSWONE_2ND_COLUMN, y, cswTimerValue(cs->v2), LEFT|PREC1|(m_posHorz==0 ? attr : 0)); + lcd_putc(lcdLastPos, y, ':'); + if (cs->v3 == 0) + lcd_putsAtt(lcdLastPos+3, y, "--", (m_posHorz==1 ? attr : 0)); + else + lcd_outdezAtt(lcdLastPos+3, y, cswTimerValue(cs->v2+cs->v3), LEFT|PREC1|(m_posHorz==1 ? attr : 0)); + lcd_putc(lcdLastPos, y, ']'); + if (s_editMode <= 0) continue; + if (attr && m_posHorz==1) { + CHECK_INCDEC_MODELVAR(event, cs->v3, 0, 222 - cs->v2); + break; + } + v2_min=-129; v2_max = 122; + } + else if (cstate == CS_FAMILY_COMP) { putsMixerSource(CSWONE_2ND_COLUMN, y, cs->v2, attr); } else { @@ -4223,7 +4251,7 @@ void menuModelCustomSwitchOne(uint8_t event) if (cs->v1 >= MIXSRC_FIRST_TELEM) { putsTelemetryChannel(CSWONE_2ND_COLUMN, y, cs->v1 - MIXSRC_FIRST_TELEM, convertCswTelemValue(cs), attr|LEFT); v2_max = maxTelemValue(cs->v1 - MIXSRC_FIRST_TELEM + 1); - if (cstate == CS_VOFS) { + if (cstate == CS_FAMILY_OFS) { v2_min = -128; v2_max -= 128; } @@ -4252,7 +4280,7 @@ void menuModelCustomSwitchOne(uint8_t event) case CSW_FIELD_ANDSW: lcd_putsLeft(y, STR_AND_SWITCH); putsSwitches(CSWONE_2ND_COLUMN, y, cs->andsw, attr); - if (attr) CHECK_INCDEC_MODELVAR(event, cs->andsw, -NUM_SWITCH, NUM_SWITCH); + if (attr) CHECK_INCDEC_MODELVAR(event, cs->andsw, -MAX_CSW_ANDSW, MAX_CSW_ANDSW); break; case CSW_FIELD_DURATION: lcd_putsLeft(y, STR_DURATION); @@ -4312,15 +4340,26 @@ void menuModelCustomSwitches(uint8_t event) // CSW params uint8_t cstate = cswFamily(cs->func); - if (cstate == CS_VBOOL) { + if (cstate == CS_FAMILY_BOOL || cstate == CS_FAMILY_STICKY) { putsSwitches(CSW_2ND_COLUMN, y, cs->v1, 0); putsSwitches(CSW_3RD_COLUMN, y, cs->v2, 0); } - else if (cstate == CS_VCOMP) { + else if (cstate == CS_FAMILY_COMP) { putsMixerSource(CSW_2ND_COLUMN, y, cs->v1, 0); putsMixerSource(CSW_3RD_COLUMN, y, cs->v2, 0); } - else if (cstate == CS_VTIMER) { + else if (cstate == CS_FAMILY_STAY) { + putsSwitches(CSW_2ND_COLUMN, y, cs->v1, 0); + lcd_putc(CSW_3RD_COLUMN-4, y, '['); + lcd_outdezAtt(CSW_3RD_COLUMN, y, cswTimerValue(cs->v2), LEFT|PREC1); + lcd_putc(lcdLastPos, y, ':'); + if (cs->v3 == 0) + lcd_puts(lcdLastPos+3, y, "--"); + else + lcd_outdezAtt(lcdLastPos+3, y, cswTimerValue(cs->v2+cs->v3), LEFT|PREC1); + lcd_putc(lcdLastPos-1, y, ']'); + } + else if (cstate == CS_FAMILY_TIMER) { lcd_outdezAtt(CSW_2ND_COLUMN, y, cs->v1+1, LEFT); lcd_outdezAtt(CSW_3RD_COLUMN, y, cs->v2+1, LEFT); } @@ -4397,15 +4436,15 @@ void menuModelCustomSwitches(uint8_t event) #endif #if defined(PCBTARANIS) - if (sub>=0 && horz<0 && event==EVT_KEY_LONG(KEY_ENTER) && !READ_ONLY()) { - killEvents(event); - CustomSwData * cs = cswAddress(sub); - if (cs->func) MENU_ADD_ITEM(STR_COPY); - if (clipboard.type == CLIPBOARD_TYPE_CUSTOM_SWITCH) - MENU_ADD_ITEM(STR_PASTE); - if (cs->func || cs->v1 || cs->v2 || cs->delay || cs->duration || cs->andsw) MENU_ADD_ITEM(STR_DELETE); - menuHandler = onCustomSwitchesMenu; - } + if (sub>=0 && horz<0 && event==EVT_KEY_LONG(KEY_ENTER) && !READ_ONLY()) { + killEvents(event); + CustomSwData * cs = cswAddress(sub); + if (cs->func) MENU_ADD_ITEM(STR_COPY); + if (clipboard.type == CLIPBOARD_TYPE_CUSTOM_SWITCH) + MENU_ADD_ITEM(STR_PASTE); + if (cs->func || cs->v1 || cs->v2 || cs->delay || cs->duration || cs->andsw) MENU_ADD_ITEM(STR_DELETE); + menuHandler = onCustomSwitchesMenu; + } #endif for (uint8_t i=0; ifunc); #if defined(CPUARM) int16_t v1_min=0, v1_max=MIXSRC_LAST_TELEM, v2_min=0, v2_max=MIXSRC_LAST_TELEM; + int16_t v3_min=0, v3_max=100; #else int8_t v1_min=0, v1_max=MIXSRC_LAST_TELEM, v2_min=0, v2_max=MIXSRC_LAST_TELEM; #endif - if (cstate == CS_VBOOL) { + if (cstate == CS_FAMILY_BOOL || cstate == CS_FAMILY_STICKY) { putsSwitches(CSW_2ND_COLUMN, y, cs->v1, attr1); putsSwitches(CSW_3RD_COLUMN, y, cs->v2, attr2); v1_min = SWSRC_OFF+1; v1_max = SWSRC_ON-1; v2_min = SWSRC_OFF+1; v2_max = SWSRC_ON-1; INCDEC_SET_FLAG(INCDEC_SWITCH); - INCDEC_ENABLE_CHECK(NULL); + INCDEC_ENABLE_CHECK(isSwitchAvailableInCustomSwitches); } - else if (cstate == CS_VCOMP) { +#if defined(CPUARM) + else if (cstate == CS_FAMILY_STAY) { + putsSwitches(CSW_2ND_COLUMN, y, cs->v1, attr1); + lcd_putc(CSW_3RD_COLUMN-4, y, '['); + lcd_outdezAtt(CSW_3RD_COLUMN, y, cswTimerValue(cs->v2), LEFT|PREC1|attr2); + lcd_putc(lcdLastPos, y, ':'); + if (cs->v3 == 0) + lcd_putsAtt(lcdLastPos+3, y, "--", (horz==CSW_FIELD_V3 ? attr : 0)); + else + lcd_outdezAtt(lcdLastPos+3, y, cswTimerValue(cs->v2+cs->v3), LEFT|PREC1|(horz==CSW_FIELD_V3 ? attr : 0)); + lcd_putc(lcdLastPos, y, ']'); + v1_min = SWSRC_OFF+1; v1_max = SWSRC_ON-1; + v2_min=-129; v2_max = 122; + v3_max = 222 - cs->v2; + if (horz == 1) { + INCDEC_SET_FLAG(INCDEC_SWITCH); + INCDEC_ENABLE_CHECK(isSwitchAvailable); + } + else { + INCDEC_SET_FLAG(0); + INCDEC_ENABLE_CHECK(NULL); + } + } +#endif + else if (cstate == CS_FAMILY_COMP) { putsMixerSource(CSW_2ND_COLUMN, y, cs->v1, attr1); putsMixerSource(CSW_3RD_COLUMN, y, cs->v2, attr2); INCDEC_SET_FLAG(INCDEC_SOURCE); INCDEC_ENABLE_CHECK(isSourceAvailable); } - else if (cstate == CS_VTIMER) { + else if (cstate == CS_FAMILY_TIMER) { lcd_outdezAtt(CSW_2ND_COLUMN, y, cswTimerValue(cs->v1), LEFT|PREC1|attr1); lcd_outdezAtt(CSW_3RD_COLUMN, y, cswTimerValue(cs->v2), LEFT|PREC1|attr2); v1_min = v2_min = -128; @@ -4474,7 +4538,7 @@ void menuModelCustomSwitches(uint8_t event) eeDirty(EE_MODEL); } #else - if (cstate == CS_VOFS) { + if (cstate == CS_FAMILY_OFS) { v2_min = -128; v2_max -= 128; } @@ -4504,31 +4568,69 @@ void menuModelCustomSwitches(uint8_t event) #endif } - // CSW and switch - putsSwitches(CSW_4TH_COLUMN, y, cs->andsw, horz==3 ? attr : 0); + // CSW AND switch +#if defined(CPUARM) + putsSwitches(CSW_4TH_COLUMN, y, cs->andsw, horz==CSW_FIELD_ANDSW ? attr : 0); +#else + uint8_t andsw = cs->andsw; + if (andsw > SWSRC_LAST_SWITCH) { + andsw += SWSRC_SW1-SWSRC_LAST_SWITCH-1; + } + putsSwitches(CSW_4TH_COLUMN, y, andsw, horz==CSW_FIELD_ANDSW ? attr : 0); +#endif #if defined(CPUARM) // CSW duration if (cs->duration > 0) - lcd_outdezAtt(CSW_5TH_COLUMN, y, 5*cs->duration, (horz==4 ? attr : 0)|PREC1|LEFT); + lcd_outdezAtt(CSW_5TH_COLUMN, y, 5*cs->duration, (horz==CSW_FIELD_DURATION ? attr : 0)|PREC1|LEFT); else - lcd_putsiAtt(CSW_5TH_COLUMN, y, STR_MMMINV, 0, horz==4 ? attr : 0); + lcd_putsiAtt(CSW_5TH_COLUMN, y, STR_MMMINV, 0, horz==CSW_FIELD_DURATION ? attr : 0); // CSW delay - if (cs->delay > 0) - lcd_outdezAtt(CSW_6TH_COLUMN, y, 5*cs->delay, (horz==5 ? attr : 0)|PREC1|LEFT); - else - lcd_putsiAtt(CSW_6TH_COLUMN, y, STR_MMMINV, 0, horz==5 ? attr : 0); + if (cstate == CS_FAMILY_STAY) { + lcd_puts(CSW_6TH_COLUMN, y, "N/A"); + if (attr && horz == CSW_FIELD_DELAY) { + REPEAT_LAST_CURSOR_MOVE(); + } + } + else if (cs->delay > 0) { + lcd_outdezAtt(CSW_6TH_COLUMN, y, 5*cs->delay, (horz==CSW_FIELD_DELAY ? attr : 0)|PREC1|LEFT); + } + else { + lcd_putsiAtt(CSW_6TH_COLUMN, y, STR_MMMINV, 0, horz==CSW_FIELD_DELAY ? attr : 0); + } + + if (attr && horz == CSW_FIELD_V3 && cstate != CS_FAMILY_STAY) { + REPEAT_LAST_CURSOR_MOVE(); + } #endif + if ((s_editMode>0 || p1valdiff) && attr) { switch (horz) { case CSW_FIELD_FUNCTION: { +#if defined(CPUARM) + cs->func = checkIncDec(event, cs->func, 0, CS_MAXF, EE_MODEL, isFunctionAvailable); +#else CHECK_INCDEC_MODELVAR_ZERO(event, cs->func, CS_MAXF); +#endif uint8_t new_cstate = cswFamily(cs->func); - if (cstate != new_cstate) - cs->v1 = cs->v2 = (new_cstate==CS_VTIMER ? -119/*1.0*/ : 0); + if (cstate != new_cstate) { +#if defined(CPUARM) + if (new_cstate == CS_FAMILY_TIMER) { + cs->v1 = cs->v2 = -119; + } + else if (new_cstate == CS_FAMILY_STAY) { + cs->v1 = 0; cs->v2 = -129; cs->v3 = 0; + } + else { + cs->v1 = cs->v2 = 0; + } +#else + cs->v1 = cs->v2 = (new_cstate==CS_FAMILY_TIMER ? -119/*1.0*/ : 0); +#endif + } break; } case CSW_FIELD_V1: @@ -4537,10 +4639,9 @@ void menuModelCustomSwitches(uint8_t event) case CSW_FIELD_V2: cs->v2 = CHECK_INCDEC_PARAM(event, cs->v2, v2_min, v2_max); #if defined(PCBTARANIS) - if (cstate==CS_VOFS && cs->v1!=0 && event==EVT_KEY_LONG(KEY_ENTER)) { + if (cstate==CS_FAMILY_OFS && cs->v1!=0 && event==EVT_KEY_LONG(KEY_ENTER)) { killEvents(event); getvalue_t x = getValue(cs->v1); - TRACE("AUTO x=%d", x); if (cs->v1 < MIXSRC_GVAR1) cs->v2 = calcRESXto100(x); else if (cs->v1 - MIXSRC_FIRST_TELEM + 1 == TELEM_ALT) @@ -4549,9 +4650,16 @@ void menuModelCustomSwitches(uint8_t event) } #endif break; +#if defined(CPUARM) + case CSW_FIELD_V3: + cs->v3 = CHECK_INCDEC_PARAM(event, cs->v3, v3_min, v3_max); + break; +#endif case CSW_FIELD_ANDSW: #if defined(CPUARM) - CHECK_INCDEC_MODELSWITCH(event, cs->andsw, -MAX_CSW_ANDSW, MAX_CSW_ANDSW); + INCDEC_SET_FLAG(INCDEC_SWITCH); + INCDEC_ENABLE_CHECK(isSwitchAvailableInCustomSwitches); + cs->andsw = CHECK_INCDEC_PARAM(event, cs->andsw, -MAX_CSW_ANDSW, MAX_CSW_ANDSW); #else CHECK_INCDEC_MODELVAR_ZERO(event, cs->andsw, MAX_CSW_ANDSW); #endif @@ -4596,14 +4704,14 @@ void onCustomFunctionsFileSelectionMenu(const char *result) if (result == STR_UPDATE_LIST) { char directory[] = SOUNDS_PATH; strncpy(directory+SOUNDS_PATH_LNG_OFS, currentLanguagePack->id, 2); - if (!listSdFiles(directory, SOUNDS_EXT, sizeof(g_model.funcSw[sub].param), NULL)) { + if (!listSdFiles(directory, SOUNDS_EXT, sizeof(g_model.funcSw[sub].play.name), NULL)) { POPUP_WARNING(STR_NO_SOUNDS_ON_SD); s_menu_flags = 0; } } else { // The user choosed a wav file in the list - memcpy(g_model.funcSw[sub].param.name, result, sizeof(g_model.funcSw[sub].param.name)); + memcpy(g_model.funcSw[sub].play.name, result, sizeof(g_model.funcSw[sub].play.name)); eeDirty(EE_MODEL); } } @@ -4643,7 +4751,7 @@ void onCustomFunctionsMenu(const char *result) void menuModelCustomFunctions(uint8_t event) { - MENU(STR_MENUCUSTOMFUNC, menuTabModel, e_CustomFunctions, NUM_CFN+1, {0, NAVIGATION_LINE_BY_LINE|3/*repeated*/}); + MENU(STR_MENUCUSTOMFUNC, menuTabModel, e_CustomFunctions, NUM_CFN+1, {0, NAVIGATION_LINE_BY_LINE|4/*repeated*/}); uint8_t y; uint8_t k = 0; @@ -4676,249 +4784,218 @@ void menuModelCustomFunctions(uint8_t event) #endif CustomFnData *sd = &g_model.funcSw[k]; - for (uint8_t j=0; j<4; j++) { + uint8_t func = CFN_FUNC(sd); + for (uint8_t j=0; j<5; j++) { uint8_t attr = ((sub==k && m_posHorz==j) ? ((s_editMode>0) ? BLINK|INVERS : INVERS) : 0); uint8_t active = (attr && (s_editMode>0 || p1valdiff)); switch (j) { case 0: - putsSwitches(MODEL_CUSTOM_FUNC_1ST_COLUMN, y, sd->swtch, attr | ((activeFnSwitches & ((MASK_CFN_TYPE)1 << k)) ? BOLD : 0)); - if (active || AUTOSWITCH_ENTER_LONG()) CHECK_INCDEC_MODELSWITCH(event, sd->swtch, SWSRC_FIRST, SWSRC_LAST); + putsSwitches(MODEL_CUSTOM_FUNC_1ST_COLUMN, y, CFN_SWITCH(sd), attr | ((activeFnSwitches & ((MASK_CFN_TYPE)1 << k)) ? BOLD : 0)); + if (active || AUTOSWITCH_ENTER_LONG()) CHECK_INCDEC_MODELSWITCH(event, CFN_SWITCH(sd), SWSRC_FIRST, SWSRC_LAST); break; case 1: - if (sd->swtch) { - uint8_t func_displayed; - if (CFN_FUNC(sd) < FUNC_TRAINER) { - func_displayed = 0; - } - else if (CFN_FUNC(sd) <= FUNC_TRAINER + NUM_STICKS) { - func_displayed = 1; - } -#if defined(DEBUG) - else if (CFN_FUNC(sd) == FUNC_TEST) { -#if defined(GVARS) - func_displayed = FUNC_TEST - FUNC_TRAINER - NUM_STICKS - MAX_GVARS + 2; -#else - func_displayed = FUNC_TEST - FUNC_TRAINER - NUM_STICKS + 1; -#endif - } -#endif -#if defined(GVARS) - else if (CFN_FUNC(sd) >= FUNC_ADJUST_GV1) { - func_displayed = FUNC_ADJUST_GV1 - FUNC_TRAINER - NUM_STICKS + 1; - } -#endif - else { - func_displayed = 2 + CFN_FUNC(sd) - FUNC_TRAINER - NUM_STICKS - 1; - } - - lcd_putsiAtt(MODEL_CUSTOM_FUNC_2ND_COLUMN, y, STR_VFSWFUNC, func_displayed, attr); - if (CFN_FUNC(sd) < FUNC_TRAINER) { - putsChn(lcdNextPos, y, CFN_CH_NUMBER(sd)+1, attr); - } - else if (CFN_FUNC(sd) <= FUNC_TRAINER + NUM_STICKS) { - if (CFN_FUNC(sd) != FUNC_TRAINER) - putsMixerSource(lcdNextPos, y, MIXSRC_Rud+CFN_FUNC(sd)-FUNC_TRAINER-1, attr); - } -#if defined(GVARS) - else if (CFN_FUNC(sd) >= FUNC_ADJUST_GV1) { - putsStrIdx(lcdNextPos, y, STR_GV, CFN_FUNC(sd)-FUNC_ADJUST_GV1+1, attr); - } -#endif - + if (CFN_SWITCH(sd)) { + lcd_putsiAtt(MODEL_CUSTOM_FUNC_2ND_COLUMN, y, STR_VFSWFUNC, func, attr); if (active) { -#if defined(CPUARM) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_FUNC(sd), FUNC_MAX-1); -#else - if (CFN_FUNC(sd) < FUNC_TRAINER) { - CHECK_INCDEC_MODELVAR_ZERO(event, sd->internal.func_safety.func, 16); - } - else { - CHECK_INCDEC_MODELVAR_ZERO(event, CFN_FUNC(sd), FUNC_MAX-1); - if (CFN_FUNC(sd) < FUNC_TRAINER) - sd->internal.func_safety.func = 15; - } -#endif if (checkIncDec_Ret) CFN_RESET(sd); } } - else if (attr) { - REPEAT_LAST_CURSOR_MOVE(); + else { + j = 4; // skip other fields + if (sub==k && m_posHorz > 0) { + REPEAT_LAST_CURSOR_MOVE(); + } } break; case 2: - if (sd->swtch) { - INCDEC_DECLARE_VARS(); - int16_t val_displayed = CFN_PARAM(sd); - int8_t val_min = 0; - uint8_t val_max = 255; - if (CFN_FUNC(sd) == FUNC_PLAY_SOUND) { -#if defined(AUDIO) - val_max = AU_FRSKY_LAST-AU_FRSKY_FIRST-1; - lcd_putsiAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, STR_FUNCSOUNDS, val_displayed, attr); -#else - break; -#endif - } -#if defined(HAPTIC) - else if (CFN_FUNC(sd) == FUNC_HAPTIC) { - val_max = 3; - lcd_outdezAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr|LEFT); - } -#endif -#if defined(CPUARM) && defined(SDCARD) - else if (CFN_FUNC(sd) == FUNC_PLAY_TRACK || CFN_FUNC(sd) == FUNC_BACKGND_MUSIC) { -#if LCD_W >= 212 - xcoord_t x = MODEL_CUSTOM_FUNC_3RD_COLUMN; -#else - xcoord_t x = (CFN_FUNC(sd) == FUNC_PLAY_TRACK ? MODEL_CUSTOM_FUNC_2ND_COLUMN + FW + FW*strlen(TR_PLAY_TRACK) : MODEL_CUSTOM_FUNC_3RD_COLUMN); -#endif - if (ZEXIST(sd->param.name)) - lcd_putsnAtt(x, y, sd->param.name, sizeof(sd->param.name), attr); - else - lcd_putsiAtt(x, y, STR_VCSWFUNC, 0, attr); - if (active && event==EVT_KEY_BREAK(KEY_ENTER)) { - s_editMode = 0; - char directory[] = SOUNDS_PATH; - strncpy(directory+SOUNDS_PATH_LNG_OFS, currentLanguagePack->id, 2); - if (listSdFiles(directory, SOUNDS_EXT, sizeof(sd->param.name), sd->param.name)) { - menuHandler = onCustomFunctionsFileSelectionMenu; - } - else { - POPUP_WARNING(STR_NO_SOUNDS_ON_SD); - s_menu_flags = 0; - } - } - break; - } - else if (CFN_FUNC(sd) == FUNC_PLAY_VALUE) { - val_max = MIXSRC_FIRST_TELEM + TELEM_DISPLAY_MAX - 1; - putsMixerSource(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr); - INCDEC_ENABLE_CHECK(isSourceAvailable); - } -#endif -#if defined(CPUARM) - else if (CFN_FUNC(sd) == FUNC_VOLUME) { - val_max = MIXSRC_LAST_CH; - putsMixerSource(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr); - INCDEC_ENABLE_CHECK(isSourceAvailable); - } -#elif defined(VOICE) - else if (CFN_FUNC(sd) == FUNC_PLAY_TRACK) { -#if defined(GVARS) - if (attr && event==EVT_KEY_LONG(KEY_ENTER)) { - killEvents(event); - s_editMode = !s_editMode; - active = true; - val_displayed = (val_displayed > 250 ? 0 : 251); - } - if (val_displayed > 250) { - putsStrIdx(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, STR_GV, val_displayed-250, attr); - } - else { - lcd_outdezAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed+PROMPT_CUSTOM_BASE, attr|LEFT); - } -#else - lcd_outdezAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed+PROMPT_CUSTOM_BASE, attr|LEFT); -#endif - } - else if (CFN_FUNC(sd) == FUNC_PLAY_BOTH) { - lcd_putcAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN+3*FWNUM, y, '|', attr); - lcd_outdezAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN+3*FWNUM, y, val_displayed+PROMPT_CUSTOM_BASE, attr); - lcd_outdezAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN+2+3*FWNUM, y, (val_displayed+PROMPT_CUSTOM_BASE+1)%10, attr|LEFT); - } - else if (CFN_FUNC(sd) == FUNC_PLAY_VALUE) { - val_max = MIXSRC_FIRST_TELEM + TELEM_DISPLAY_MAX - 1; - putsMixerSource(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr); - INCDEC_ENABLE_CHECK(isSourceAvailable); - } -#endif -#if defined(SDCARD) - else if (CFN_FUNC(sd) == FUNC_LOGS) { - if (val_displayed) { - lcd_outdezAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr|PREC1|LEFT); - lcd_putc(lcdLastPos, y, 's'); - } - else { - lcd_putsiAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, STR_MMMINV, 0, attr); - } - } -#endif - else if (CFN_FUNC(sd) == FUNC_RESET) { - val_max = FUNC_RESET_PARAM_LAST; - lcd_putsiAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, STR_VFSWRESET, CFN_PARAM(sd), attr); - } - else if (CFN_FUNC(sd) < FUNC_TRAINER) { - val_displayed = (int8_t)CFN_PARAM(sd); - val_min = -125; val_max = 125; - lcd_outdezAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr|LEFT); - } -#if defined(GVARS) - else if (CFN_FUNC(sd) >= FUNC_ADJUST_GV1 -#if defined(DEBUG) - && CFN_FUNC(sd) <= FUNC_ADJUST_GVLAST -#endif - ) { - switch (CFN_GVAR_MODE(sd)) { - case FUNC_ADJUST_GVAR_CONSTANT: - val_displayed = (int8_t)CFN_PARAM(sd); - val_min = -125; val_max = 125; - lcd_outdezAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr|LEFT); - break; - case FUNC_ADJUST_GVAR_SOURCE: - val_max = MIXSRC_LAST_CH; - putsMixerSource(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr); - INCDEC_ENABLE_CHECK(isSourceAvailable); - break; - case FUNC_ADJUST_GVAR_GVAR: - val_max = MAX_GVARS-1; - putsStrIdx(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, STR_GV, val_displayed+1, attr); - break; - default: // FUNC_ADJUST_GVAR_INC - val_max = 1; - lcd_putsiAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, PSTR("\002-1+1"), val_displayed, attr); - break; - } - - if (attr && event==EVT_KEY_LONG(KEY_ENTER)) { - killEvents(event); - s_editMode = !s_editMode; - active = true; - CFN_GVAR_MODE(sd) += 1; - val_displayed = 0; - } - } -#endif - else { - if (attr) m_posHorz = (CURSOR_MOVED_LEFT(event) ? 1 : 3); - break; - } - - if (active) { - CFN_PARAM(sd) = CHECK_INCDEC_PARAM(event, val_displayed, val_min, val_max); - } + { + int8_t maxParam = NUM_CHNOUT-1; + if (func == FUNC_SAFETY_CHANNEL) { + putsChn(lcdNextPos, y, CFN_CH_NUMBER(sd)+1, attr); } + else if (func == FUNC_TRAINER) { + maxParam = 4; +#if defined(CPUARM) + putsMixerSource(lcdNextPos, y, CFN_CH_NUMBER(sd)==0 ? 0 : MIXSRC_Rud+CFN_CH_NUMBER(sd)-1, attr); +#else + putsMixerSource(lcdNextPos, y, MIXSRC_Rud+CFN_CH_NUMBER(sd)-1, attr); +#endif + } +#if defined(GVARS) + else if (func == FUNC_ADJUST_GVAR) { + maxParam = MAX_GVARS-1; + putsStrIdx(lcdNextPos, y, STR_GV, CFN_GVAR_NUMBER(sd)+1, attr); + if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_GVAR_NUMBER(sd), maxParam); + break; + } +#endif else if (attr) { REPEAT_LAST_CURSOR_MOVE(); } + if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_CH_NUMBER(sd), maxParam); break; + } case 3: - if (sd->swtch && (CFN_FUNC(sd) <= FUNC_INSTANT_TRIM || CFN_FUNC(sd) == FUNC_RESET -#if defined(GVARS) - // TODO #define - || CFN_FUNC(sd) >= FUNC_ADJUST_GV1 + { + INCDEC_DECLARE_VARS(); + int16_t val_displayed = CFN_PARAM(sd); + int8_t val_min = 0; + uint8_t val_max = 255; + if (func == FUNC_SAFETY_CHANNEL) { + val_displayed = (int8_t)CFN_PARAM(sd); + val_min = -125; val_max = 125; + lcd_outdezAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr|LEFT); + } +#if defined(AUDIO) + else if (func == FUNC_PLAY_SOUND) { + val_max = AU_FRSKY_LAST-AU_FRSKY_FIRST-1; + lcd_putsiAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, STR_FUNCSOUNDS, val_displayed, attr); + break; + } +#endif +#if defined(HAPTIC) + else if (func == FUNC_HAPTIC) { + val_max = 3; + lcd_outdezAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr|LEFT); + } +#endif +#if defined(CPUARM) && defined(SDCARD) + else if (func == FUNC_PLAY_TRACK || func == FUNC_BACKGND_MUSIC) { +#if LCD_W >= 212 + xcoord_t x = MODEL_CUSTOM_FUNC_3RD_COLUMN; +#else + xcoord_t x = (func == FUNC_PLAY_TRACK ? MODEL_CUSTOM_FUNC_2ND_COLUMN + FW + FW*strlen(TR_PLAY_TRACK) : MODEL_CUSTOM_FUNC_3RD_COLUMN); +#endif + if (ZEXIST(sd->play.name)) + lcd_putsnAtt(x, y, sd->play.name, sizeof(sd->play.name), attr); + else + lcd_putsiAtt(x, y, STR_VCSWFUNC, 0, attr); + if (active && event==EVT_KEY_BREAK(KEY_ENTER)) { + s_editMode = 0; + char directory[] = SOUNDS_PATH; + strncpy(directory+SOUNDS_PATH_LNG_OFS, currentLanguagePack->id, 2); + if (listSdFiles(directory, SOUNDS_EXT, sizeof(sd->play.name), sd->play.name)) { + menuHandler = onCustomFunctionsFileSelectionMenu; + } + else { + POPUP_WARNING(STR_NO_SOUNDS_ON_SD); + s_menu_flags = 0; + } + } + break; + } + else if (func == FUNC_PLAY_VALUE) { + val_max = MIXSRC_FIRST_TELEM + TELEM_DISPLAY_MAX - 1; + putsMixerSource(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr); + INCDEC_ENABLE_CHECK(isSourceAvailable); + } #endif #if defined(CPUARM) - // TODO #define - || CFN_FUNC(sd) == FUNC_VOLUME + else if (func == FUNC_VOLUME) { + val_max = MIXSRC_LAST_CH; + putsMixerSource(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr); + INCDEC_ENABLE_CHECK(isSourceAvailable); + } +#elif defined(VOICE) + else if (func == FUNC_PLAY_TRACK) { +#if defined(GVARS) + if (attr && event==EVT_KEY_LONG(KEY_ENTER)) { + killEvents(event); + s_editMode = !s_editMode; + active = true; + val_displayed = (val_displayed > 250 ? 0 : 251); + } + if (val_displayed > 250) { + putsStrIdx(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, STR_GV, val_displayed-250, attr); + } + else { + lcd_outdezAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed+PROMPT_CUSTOM_BASE, attr|LEFT); + } +#else + lcd_outdezAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed+PROMPT_CUSTOM_BASE, attr|LEFT); #endif - )) { + } + else if (func == FUNC_PLAY_BOTH) { + lcd_putcAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN+3*FWNUM, y, '|', attr); + lcd_outdezAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN+3*FWNUM, y, val_displayed+PROMPT_CUSTOM_BASE, attr); + lcd_outdezAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN+2+3*FWNUM, y, (val_displayed+PROMPT_CUSTOM_BASE+1)%10, attr|LEFT); + } + else if (func == FUNC_PLAY_VALUE) { + val_max = MIXSRC_FIRST_TELEM + TELEM_DISPLAY_MAX - 1; + putsMixerSource(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr); + INCDEC_ENABLE_CHECK(isSourceAvailable); + } +#endif +#if defined(SDCARD) + else if (func == FUNC_LOGS) { + if (val_displayed) { + lcd_outdezAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr|PREC1|LEFT); + lcd_putc(lcdLastPos, y, 's'); + } + else { + lcd_putsiAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, STR_MMMINV, 0, attr); + } + } +#endif + else if (func == FUNC_RESET) { + val_max = FUNC_RESET_PARAM_LAST; + lcd_putsiAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, STR_VFSWRESET, CFN_PARAM(sd), attr); + } +#if defined(GVARS) + else if (func == FUNC_ADJUST_GVAR) { + switch (CFN_GVAR_MODE(sd)) { + case FUNC_ADJUST_GVAR_CONSTANT: + val_displayed = (int8_t)CFN_PARAM(sd); + val_min = -125; val_max = 125; + lcd_outdezAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr|LEFT); + break; + case FUNC_ADJUST_GVAR_SOURCE: + val_max = MIXSRC_LAST_CH; + putsMixerSource(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr); + INCDEC_ENABLE_CHECK(isSourceAvailable); + break; + case FUNC_ADJUST_GVAR_GVAR: + val_max = MAX_GVARS-1; + putsStrIdx(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, STR_GV, val_displayed+1, attr); + break; + default: // FUNC_ADJUST_GVAR_INC + val_max = 1; + lcd_putsiAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, PSTR("\002-1+1"), val_displayed, attr); + break; + } + + if (attr && event==EVT_KEY_LONG(KEY_ENTER)) { + killEvents(event); + s_editMode = !s_editMode; + active = true; + CFN_GVAR_MODE(sd) += 1; +#if defined(CPUARM) + CFN_GVAR_MODE(sd) &= 0x03; +#endif + val_displayed = 0; + } + } +#endif + else if (attr) { + REPEAT_LAST_CURSOR_MOVE(); + } + + if (active) { + CFN_PARAM(sd) = CHECK_INCDEC_PARAM(event, val_displayed, val_min, val_max); + } + break; + } + + case 4: + if (HAS_ENABLE_PARAM(func)) { menu_lcd_onoff(MODEL_CUSTOM_FUNC_4TH_COLUMN_ONOFF, y, CFN_ACTIVE(sd), attr); if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_ACTIVE(sd), 1); } - else if (sd->swtch && HAS_REPEAT_PARAM(sd)) { + else if (HAS_REPEAT_PARAM(sd)) { if (CFN_PLAY_REPEAT(sd) == 0) { #if LCD_W >= 212 lcd_putsAtt(MODEL_CUSTOM_FUNC_4TH_COLUMN+2, y, "1x", attr); diff --git a/radio/src/gui/menus.cpp b/radio/src/gui/menus.cpp index 9277f05b3..e6cbfccee 100644 --- a/radio/src/gui/menus.cpp +++ b/radio/src/gui/menus.cpp @@ -228,18 +228,6 @@ int16_t checkIncDec(uint8_t event, int16_t val, int16_t i_min, int16_t i_max, ui #endif } } - - if (event == EVT_KEY_LONG(KEY_ENTER) && i_max > SWSRC_ON) { - s_editMode = !s_editMode; - if (newval > SWSRC_ON) - newval -= (NUM_SWITCH+1); - else if (newval > 0) - newval += (NUM_SWITCH+1); - else if (newval < SWSRC_OFF) - newval += (NUM_SWITCH+1); - else if (newval < 0) - newval -= (NUM_SWITCH+1); - } } #endif @@ -976,7 +964,7 @@ int8_t switchMenuItem(uint8_t x, uint8_t y, int8_t value, LcdFlags attr, uint8_t { lcd_putsColumnLeft(x, y, STR_SWITCH); putsSwitches(x, y, value, attr); - if (attr) CHECK_INCDEC_MODELSWITCH(event, value, -NUM_SWITCH, NUM_SWITCH); + if (attr) CHECK_INCDEC_MODELSWITCH(event, value, SWSRC_FIRST, SWSRC_LAST); return value; } @@ -1046,6 +1034,16 @@ int16_t gvarMenuItem(uint8_t x, uint8_t y, int16_t value, int16_t min, int16_t m } #endif +void repeatLastCursorMove(uint8_t event) +{ + if (CURSOR_MOVED_LEFT(event) || CURSOR_MOVED_RIGHT(event)) { + putEvent(event); + } + else { + m_posHorz = 0; + } +} + #if LCD_W >= 212 #define MENU_X 30 #define MENU_Y 16 @@ -1250,7 +1248,7 @@ bool isInputSourceAvailable(int16_t source) return false; } -bool isSwitchAvailable(int16_t swtch) +bool isSwitchAvailableInCustomSwitches(int16_t swtch) { if (swtch < 0) { if (swtch <= -SWSRC_ON) @@ -1276,6 +1274,15 @@ bool isSwitchAvailable(int16_t swtch) } #endif + return true; +} + +bool isSwitchAvailable(int16_t swtch) +{ + if (!isSwitchAvailableInCustomSwitches(swtch)) { + return false; + } + if (swtch >= SWSRC_FIRST_CSW && swtch <= SWSRC_LAST_CSW) { CustomSwData * cs = cswAddress(swtch-SWSRC_FIRST_CSW); return (cs->func != CS_OFF); @@ -1283,4 +1290,11 @@ bool isSwitchAvailable(int16_t swtch) return true; } + +// Not available yet, will be needed if we implement the Range function later... +bool isFunctionAvailable(int16_t function) +{ + return function != CS_RANGE; +} + #endif diff --git a/radio/src/gui/menus.h b/radio/src/gui/menus.h index 872af4fa3..eed58fd97 100644 --- a/radio/src/gui/menus.h +++ b/radio/src/gui/menus.h @@ -190,7 +190,9 @@ int8_t checkIncDecGen(uint8_t event, int8_t i_val, int8_t i_min, int8_t i_max); var = checkIncDecModelZero(event,var,max) #if defined(CPUARM) + bool isFunctionAvailable(int16_t function); bool isSwitchAvailable(int16_t swtch); + bool isSwitchAvailableInCustomSwitches(int16_t swtch); #define AUTOSWITCH_ENTER_LONG() (attr && event==EVT_KEY_LONG(KEY_ENTER)) #define CHECK_INCDEC_MODELSWITCH(event, var, min, max) \ var = checkIncDec(event,var,min,max,EE_MODEL|INCDEC_SWITCH|NO_INCDEC_MARKS, isSwitchAvailable) @@ -400,7 +402,8 @@ void pushMenuTextView(const char *filename); #define REPEAT_LAST_CURSOR_MOVE() { if (EVT_KEY_MASK(event) >= 0x0e) putEvent(event); else m_posHorz = 0; } #define MOVE_CURSOR_FROM_HERE() if (m_posHorz > 0) REPEAT_LAST_CURSOR_MOVE() #else - #define REPEAT_LAST_CURSOR_MOVE() m_posHorz = 0; + void repeatLastCursorMove(uint8_t event); + #define REPEAT_LAST_CURSOR_MOVE() repeatLastCursorMove(event) #define MOVE_CURSOR_FROM_HERE() REPEAT_LAST_CURSOR_MOVE() #endif diff --git a/radio/src/gui/view_main.cpp b/radio/src/gui/view_main.cpp index 93c6e0dfa..a0ba1fbe8 100644 --- a/radio/src/gui/view_main.cpp +++ b/radio/src/gui/view_main.cpp @@ -295,7 +295,7 @@ void displayTopBar() x -= 12; } - if (isFunctionActive(FUNC_LOGS)) { + if (isFunctionActive(FUNCTION_LOGS)) { LCD_NOTIF_ICON(x, ICON_LOGS); x -= 12; } @@ -343,7 +343,7 @@ void displayTimers() if (g_model.timers[0].mode) { TimerState & timerState = timersStates[0]; putsTime(TIMERS_X, TIMER1_Y, timerState.val, MIDSIZE|LEFT, MIDSIZE|LEFT); - putsTmrMode(TIMERS_X, TIMER1_Y-6, g_model.timers[0].mode, STRCONDENSED|SMLSIZE); + putsTimerMode(TIMERS_X, TIMER1_Y-6, g_model.timers[0].mode, SMLSIZE); if (g_model.timers[0].persistent) lcd_putcAtt(TIMERS_R, TIMER1_Y+1, 'P', SMLSIZE); if (timerState.val < 0) { if (BLINK_ON_PHASE) { @@ -356,7 +356,7 @@ void displayTimers() if (g_model.timers[1].mode) { TimerState & timerState = timersStates[1]; putsTime(TIMERS_X, TIMER2_Y, timerState.val, MIDSIZE|LEFT, MIDSIZE|LEFT); - putsTmrMode(TIMERS_X, TIMER2_Y-6, g_model.timers[1].mode, STRCONDENSED|SMLSIZE); + putsTimerMode(TIMERS_X, TIMER2_Y-6, g_model.timers[1].mode, SMLSIZE); if (g_model.timers[1].persistent) lcd_putcAtt(TIMERS_R, TIMER2_Y+1, 'P', SMLSIZE); if (timerState.val < 0) { if (BLINK_ON_PHASE) { @@ -373,7 +373,7 @@ void displayTimers() TimerState & timerState = timersStates[0]; uint8_t att = DBLSIZE | (timerState.val<0 ? BLINK|INVERS : 0); putsTime(12*FW+2+10*FWNUM-4, FH*2, timerState.val, att, att); - putsTmrMode(timerState.val >= 0 ? 9*FW-FW/2+3 : 9*FW-FW/2-4, FH*3, g_model.timers[0].mode, STRCONDENSED); + putsTimerMode(timerState.val >= 0 ? 9*FW-FW/2+3 : 9*FW-FW/2-4, FH*3, g_model.timers[0].mode); } } #endif @@ -818,7 +818,7 @@ void menuMainView(uint8_t event) } else { // timer2 putsTime(33+FW+2+10*FWNUM-4, FH*5, timersStates[1].val, DBLSIZE, DBLSIZE); - putsTmrMode(timersStates[1].val >= 0 ? 20-FW/2+5 : 20-FW/2-2, FH*6, g_model.timers[1].mode, STRCONDENSED); + putsTimerMode(timersStates[1].val >= 0 ? 20-FW/2+5 : 20-FW/2-2, FH*6, g_model.timers[1].mode); // lcd_outdezNAtt(33+11*FW, FH*6, s_timerVal_10ms[1], LEADING0, 2); // 1/100s } #endif // PCBTARANIS diff --git a/radio/src/lcd.cpp b/radio/src/lcd.cpp index ed9f798e1..e076fd278 100644 --- a/radio/src/lcd.cpp +++ b/radio/src/lcd.cpp @@ -1040,41 +1040,6 @@ void putsSwitches(xcoord_t x, uint8_t y, int8_t idx, LcdFlags att) lcd_vlineStip(x-2, y, 8, 0x5E/*'!'*/); idx = -idx; } - -#if ROTARY_ENCODERS > 0 - else if (idx >= SWSRC_FIRST_ROTENC_SWITCH) { - idx -= SWSRC_FIRST_ROTENC_SWITCH; - char suffix = (idx & 1) ? CHR_LONG : CHR_SHORT; - lcd_putsiAtt(x, y, STR_VRENCODERS, idx/2, att); - return lcd_putcAtt(lcdLastPos, y, suffix, att); - } -#endif - -#if !defined(PCBSTD) - else if (idx >= SWSRC_TRAINER_SHORT) { - idx -= SWSRC_TRAINER_SHORT; - char suffix = (idx & 1) ? CHR_LONG : CHR_SHORT; -#if ROTARY_ENCODERS > 0 - if (idx >= 2) { - idx -= 2; - lcd_putsiAtt(x, y, STR_VRENCODERS, idx/2, att); - } - else -#endif - { - lcd_putsiAtt(x, y, STR_VSWITCHES, SWSRC_TRAINER-1, att); - } - return lcd_putcAtt(lcdLastPos, y, suffix, att); - } -#endif - - if (idx > SWSRC_ON) { - idx -= SWSRC_ON; - if (idx != SWSRC_ON && (~att & STRCONDENSED)) { - lcd_putsiAtt(x, y, STR_VSWITCHES, idx-1, att); - return lcd_putcAtt(lcdLastPos, y, CHR_TOGGLE, att); - } - } lcd_putsiAtt(x, y, STR_VSWITCHES, idx-1, att); } @@ -1141,22 +1106,15 @@ void putsCurve(xcoord_t x, uint8_t y, int8_t idx, LcdFlags att) } #endif -void putsTmrMode(xcoord_t x, uint8_t y, int8_t mode, LcdFlags att) +void putsTimerMode(xcoord_t x, uint8_t y, int8_t mode, LcdFlags att) { - if (mode < 0) { - mode = TMR_VAROFS - mode - 1; - lcd_putcAtt(x-1*FW, y, '!', att); + if (mode >= 0) { + if (mode < TMR_VAROFS) + return lcd_putsiAtt(x, y, STR_VTMRMODES, mode, att); + else + mode -= (TMR_VAROFS-1); } - else if (mode < TMR_VAROFS) { - lcd_putsiAtt(x, y, STR_VTMRMODES, mode, att); - return; - } - - if (mode >= TMR_VAROFS+NUM_PSWITCH+NUM_CSW) { - mode++; - } - - putsSwitches(x, y, mode-(TMR_VAROFS-1), att); + putsSwitches(x, y, mode, att); } #if defined(PCBTARANIS) diff --git a/radio/src/lcd.h b/radio/src/lcd.h index 223901be7..5becc5c57 100644 --- a/radio/src/lcd.h +++ b/radio/src/lcd.h @@ -83,7 +83,6 @@ /* no 0x80 here because of "GV"1 which is aligned LEFT */ /* no 0x10 here because of "MODEL"01 which uses LEADING0 */ #define BSS 0x20 -#define STRCONDENSED 0x80 /* means that THRm will be displayed as THR */ #define ZCHAR 0x80 /* lcd outdez flags */ @@ -174,7 +173,7 @@ void putsFlightPhase(xcoord_t x, uint8_t y, int8_t idx, LcdFlags att=0); void putsCurveRef(xcoord_t x, uint8_t y, CurveRef &curve, LcdFlags att); #endif void putsCurve(xcoord_t x, uint8_t y, int8_t idx, LcdFlags att=0); -void putsTmrMode(xcoord_t x, uint8_t y, int8_t mode, LcdFlags att); +void putsTimerMode(xcoord_t x, uint8_t y, int8_t mode, LcdFlags att=0); void putsTrimMode(xcoord_t x, uint8_t y, uint8_t phase, uint8_t idx, LcdFlags att); #if defined(ROTARY_ENCODERS) void putsRotaryEncoderMode(xcoord_t x, uint8_t y, uint8_t phase, uint8_t idx, LcdFlags att); diff --git a/radio/src/logs.cpp b/radio/src/logs.cpp index 58c47eacc..41cf29b8d 100644 --- a/radio/src/logs.cpp +++ b/radio/src/logs.cpp @@ -175,7 +175,7 @@ void writeLogs() { static const pm_char * error_displayed = NULL; - if (isFunctionActive(FUNC_LOGS) && logDelay > 0) { + if (isFunctionActive(FUNCTION_LOGS) && logDelay > 0) { tmr10ms_t tmr10ms = get_tmr10ms(); if (lastLogTime == 0 || (tmr10ms_t)(tmr10ms - lastLogTime) >= (tmr10ms_t)logDelay*10) { lastLogTime = tmr10ms; diff --git a/radio/src/maths.cpp b/radio/src/maths.cpp index 6cee8d2d7..346a7dba7 100644 --- a/radio/src/maths.cpp +++ b/radio/src/maths.cpp @@ -120,7 +120,7 @@ void varioWakeup() static tmr10ms_t s_varioTmr; tmr10ms_t tmr10ms = get_tmr10ms(); - if (isFunctionActive(FUNC_VARIO)) { + if (isFunctionActive(FUNCTION_VARIO)) { #if defined(AUDIO) cli(); int16_t verticalSpeed = frskyData.hub.varioSpeed; diff --git a/radio/src/myeeprom.h b/radio/src/myeeprom.h index de33b0706..fd1f6db60 100644 --- a/radio/src/myeeprom.h +++ b/radio/src/myeeprom.h @@ -668,14 +668,42 @@ PACK( union u_int8int16_t { #endif +enum CswFunctions { + CS_OFF, + CS_VEQUAL, // v==offset + CS_VPOS, // v>offset + CS_VNEG, // voffset + CS_ANEG, // |v|= FUNC_ADJUST_GV1 && CFN_FUNC(sd) <= FUNC_ADJUST_GVLAST) +#define HAS_ENABLE_PARAM(func) (func < FUNC_FIRST_WITHOUT_ENABLE) + +#if defined(CPUARM) + #define IS_PLAY_BOTH_FUNC(func) (0) + #define IS_VOLUME_FUNC(func) (func == FUNC_VOLUME) #else - #define IS_ADJUST_GV_FUNCTION(sd) (0) + #define IS_PLAY_BOTH_FUNC(func) (func == FUNC_PLAY_BOTH) + #define IS_VOLUME_FUNC(func) (0) +#endif + +#if defined(GVARS) + #define IS_ADJUST_GV_FUNC(func) (func == FUNC_ADJUST_GVAR) +#else + #define IS_ADJUST_GV_FUNC(func) (0) #endif #if defined(VOICE) @@ -786,56 +811,68 @@ PACK(typedef struct t_CustomFnData { // Function Switches data int8_t swtch; uint8_t func; PACK(union { - char name[LEN_CFN_NAME]; + struct { + char name[LEN_CFN_NAME]; + } play; + struct { int16_t val; - int16_t ext1; - int16_t ext2; - } composite; - }) param; - uint8_t mode:2; - uint8_t active:6; + uint8_t mode; + uint8_t param; + int16_t spare2; + } all; + + struct { + int32_t val1; + int16_t val2; + } clear; + }); + uint8_t active; }) CustomFnData; #define CFN_EMPTY(p) (!(p)->swtch) +#define CFN_SWITCH(p) ((p)->swtch) #define CFN_FUNC(p) ((p)->func) #define CFN_ACTIVE(p) ((p)->active) -#define CFN_CH_NUMBER(p) (CFN_FUNC(p)) +#define CFN_CH_NUMBER(p) ((p)->all.param) #define CFN_PLAY_REPEAT(p) ((p)->active) #define CFN_PLAY_REPEAT_MUL 1 #define CFN_PLAY_REPEAT_NOSTART 0x3F -#define CFN_GVAR_MODE(p) ((p)->mode) -#define CFN_PARAM(p) ((p)->param.composite.val) -#define CFN_RESET(p) (p->active = 0, memset(&(p)->param, 0, sizeof((p)->param))) +#define CFN_GVAR_NUMBER(p) ((p)->all.param) +#define CFN_GVAR_MODE(p) ((p)->all.mode) +#define CFN_PARAM(p) ((p)->all.val) +#define CFN_RESET(p) ((p)->active=0, (p)->clear.val1=0, (p)->clear.val2=0) #else PACK(typedef struct t_CustomFnData { - int8_t swtch; // input - union { + PACK(union { struct { - uint8_t param:3; - uint8_t func:5; - } func_param; + int8_t swtch:6; + uint16_t func:4; + uint8_t mode:2; + uint8_t param:3; + uint8_t active:1; + } gvar; struct { - uint8_t active:1; - uint8_t param:2; - uint8_t func:5; - } func_param_enable; + int8_t swtch:6; + uint16_t func:4; + uint8_t param:4; + uint8_t spare:1; + uint8_t active:1; + } all; + }); - struct { - uint8_t active:1; - uint8_t func:7; - } func_safety; - } internal; - uint8_t param; + uint8_t value; }) CustomFnData; -#define CFN_FUNC(p) ((p)->internal.func_param.func) -#define CFN_ACTIVE(p) ((p)->internal.func_param_enable.active) -#define CFN_CH_NUMBER(p) ((p)->internal.func_safety.func) -#define CFN_PLAY_REPEAT(p) ((p)->internal.func_param.param) +#define CFN_SWITCH(p) ((p)->all.swtch) +#define CFN_FUNC(p) ((p)->all.func) +#define CFN_ACTIVE(p) ((p)->all.active) +#define CFN_CH_NUMBER(p) ((p)->all.param) +#define CFN_PLAY_REPEAT(p) ((p)->all.param) #define CFN_PLAY_REPEAT_MUL 10 -#define CFN_GVAR_MODE(p) ((p)->internal.func_param_enable.param) -#define CFN_PARAM(p) ((p)->param) -#define CFN_RESET(p) ((p)->internal.func_param_enable.active = 0, CFN_PARAM(p) = 0) +#define CFN_GVAR_NUMBER(p) ((p)->gvar.param) +#define CFN_GVAR_MODE(p) ((p)->gvar.mode) +#define CFN_PARAM(p) ((p)->value) +#define CFN_RESET(p) ((p)->all.active = 0, CFN_PARAM(p) = 0) #endif enum TelemetryUnit { @@ -1166,6 +1203,7 @@ enum SwitchSources { SWSRC_SG2, SWSRC_SH0, SWSRC_SH2, + SWSRC_TRAINER = SWSRC_SH2, #else SWSRC_ID0 = SWSRC_FIRST_SWITCH, SWSRC_ID1, @@ -1181,11 +1219,37 @@ enum SwitchSources { SWSRC_AIL, SWSRC_GEA, SWSRC_TRN, + SWSRC_TRAINER = SWSRC_TRN, +#endif + + SWSRC_LAST_SWITCH = SWSRC_TRAINER, + +#if defined(PCBTARANIS) + SWSRC_P11, + SWSRC_P16 = SWSRC_P11+5, + SWSRC_P21, + SWSRC_P26 = SWSRC_P21+5, +#endif + + SWSRC_FIRST_TRIM, + SWSRC_TrimRudLeft = SWSRC_FIRST_TRIM, + SWSRC_TrimRudRight, + SWSRC_TrimEleDown, + SWSRC_TrimEleUp, + SWSRC_TrimThrDown, + SWSRC_TrimThrUp, + SWSRC_TrimAilLeft, + SWSRC_TrimAilRight, + SWSRC_LAST_TRIM = SWSRC_TrimAilRight, + +#if defined(PCBSKY9X) + SWSRC_REa, +#elif defined(PCBGRUVIN9X) || defined(PCBMEGA2560) + SWSRC_REa, + SWSRC_REb, #endif SWSRC_FIRST_CSW, - SWSRC_LAST_SWITCH = SWSRC_FIRST_CSW-1, - SWSRC_SW1 = SWSRC_FIRST_CSW, SWSRC_SW2, SWSRC_SW3, @@ -1200,34 +1264,11 @@ enum SwitchSources { SWSRC_SWC, SWSRC_LAST_CSW = SWSRC_SW1+NUM_CSW-1, -#if defined(PCBTARANIS) - SWSRC_P11, - SWSRC_P16 = SWSRC_P11+5, - SWSRC_P21, - SWSRC_P26 = SWSRC_P21+5, -#endif - SWSRC_ON, - - SWSRC_FIRST_MOMENT_SWITCH, - SWSRC_LAST_MOMENT_SWITCH = SWSRC_FIRST_MOMENT_SWITCH+SWSRC_LAST_CSW, - -#if !defined(PCBSTD) - SWSRC_TRAINER_SHORT, - SWSRC_TRAINER_LONG, -#endif - -#if ROTARY_ENCODERS > 0 - SWSRC_FIRST_ROTENC_SWITCH, - SWSRC_LAST_ROTENC_SWITCH = SWSRC_FIRST_ROTENC_SWITCH+(2*ROTARY_ENCODERS)-1, -#endif - - SWSRC_COUNT, - SWSRC_FIRST = -SWSRC_LAST_MOMENT_SWITCH, - SWSRC_LAST = SWSRC_COUNT-1, - SWSRC_OFF = -SWSRC_ON, - SWSRC_TRAINER = SWSRC_SW1-1, + + SWSRC_FIRST = SWSRC_OFF, + SWSRC_LAST = SWSRC_ON }; enum MixSources { diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index 3f4085d08..520368b54 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -448,10 +448,23 @@ CustomSwData *cswAddress(uint8_t idx) uint8_t cswFamily(uint8_t func) { - return (funcsrcRaw = i+1; - if (!isSourceAvailable(mix->srcRaw)) { - mix->srcRaw = MIXSRC_Rud - 1 + stick_index; - } #else mix->srcRaw = MIXSRC_Rud - 1 + channel_order(i+1); #endif @@ -573,9 +583,9 @@ void modelDefault(uint8_t id) g_model.frsky.channels[0].ratio = 132; #endif -#ifdef MAVLINK - g_model.mavlink.rc_rssi_scale = 15; - g_model.mavlink.pc_rssi_en = 1; +#if defined(MAVLINK) + g_model.mavlink.rc_rssi_scale = 15; + g_model.mavlink.pc_rssi_en = 1; #endif } @@ -1343,7 +1353,6 @@ void getSwitchesPosition() CHECK_2POS(SW_SH); switchesPos = newPos; -#if defined(PCBTARANIS) for (int i=0; i= SWSRC_P11 && cs_idx <= SWSRC_P26) { + else if (cs_idx <= SWSRC_P26) { result = POT_POSITION(cs_idx-SWSRC_P11); } +#endif + else if (cs_idx <= SWSRC_LAST_TRIM) { + result = trimDown(cs_idx-SWSRC_FIRST_TRIM); + } +#if ROTARY_ENCODERS > 0 + else if (cs_idx == SWSRC_REa) { + result = REA_DOWN(); + } +#endif +#if ROTARY_ENCODERS > 1 + else if (cs_idx == SWSRC_REb) { + result = REB_DOWN(); + } #endif else { cs_idx -= SWSRC_FIRST_CSW; @@ -1403,12 +1424,19 @@ bool getSwitch(int8_t swtch) s_last_switch_used |= mask; CustomSwData * cs = cswAddress(cs_idx); +#if defined(CPUARM) + int8_t s = cs->andsw; +#else uint8_t s = cs->andsw; + if (s > SWSRC_LAST_SWITCH) { + s += SWSRC_SW1-SWSRC_LAST_SWITCH-1; + } +#endif if (cs->func == CS_OFF || (s && !getSwitch(s))) { csLastValue[cs_idx] = CS_LAST_VALUE_INIT; result = false; } - else if ((s=cswFamily(cs->func)) == CS_VBOOL) { + else if ((s=cswFamily(cs->func)) == CS_FAMILY_BOOL) { bool res1 = getSwitch(cs->v1); bool res2 = getSwitch(cs->v2); switch (cs->func) { @@ -1424,13 +1452,21 @@ bool getSwitch(int8_t swtch) break; } } - else if (s == CS_VTIMER) { - result = csLastValue[cs_idx] <= 0; + else if (s == CS_FAMILY_TIMER) { + result = (csLastValue[cs_idx] <= 0); } + else if (s == CS_FAMILY_STICKY) { + result = (csLastValue[cs_idx] & (1<<0)); + } +#if defined(CPUARM) + else if (s == CS_FAMILY_STAY) { + result = (csLastValue[cs_idx] & (1<<0)); + } +#endif else { getvalue_t x = getValue(cs->v1); getvalue_t y; - if (s == CS_VCOMP) { + if (s == CS_FAMILY_COMP) { y = getValue(cs->v2); switch (cs->func) { @@ -1455,7 +1491,7 @@ bool getSwitch(int8_t swtch) y = convertCswTelemValue(cs); #if defined(FRSKY_HUB) && defined(GAUGES) - if (s == CS_VOFS) { + if (s == CS_FAMILY_OFS) { uint8_t idx = cs->v1-MIXSRC_FIRST_TELEM+1-TELEM_ALT; if (idx < THLD_MAX) { // Fill the threshold array @@ -1530,15 +1566,20 @@ bool getSwitch(int8_t swtch) cswDelays[cs_idx] = get_tmr10ms() + (cs->delay*50); } } + if (cs->duration) { - if (result && !cswStates[cs_idx]) + if (result && !cswStates[cs_idx]) { cswDurations[cs_idx] = get_tmr10ms() + (cs->duration*50); + } cswStates[cs_idx] = result; + result = false; if (cswDurations[cs_idx] > get_tmr10ms()) { result = true; - if (cs->delay) cswDelays[cs_idx] = get_tmr10ms() + (cs->delay*50); + } + else if (s == CS_FAMILY_STICKY) { + csLastValue[cs_idx] &= ~(1<<0); } } #endif @@ -2002,7 +2043,7 @@ getvalue_t convertCswTelemValue(CustomSwData * cs) #if defined(CPUARM) val = convert16bitsTelemValue(cs->v1 - MIXSRC_FIRST_TELEM + 1, cs->v2); #else - if (cswFamily(cs->func)==CS_VOFS) + if (cswFamily(cs->func)==CS_FAMILY_OFS) val = convert8bitsTelemValue(cs->v1 - MIXSRC_FIRST_TELEM + 1, 128+cs->v2); else val = convert8bitsTelemValue(cs->v1 - MIXSRC_FIRST_TELEM + 1, 128+cs->v2) - convert8bitsTelemValue(cs->v1 - MIXSRC_FIRST_TELEM + 1, 128); @@ -2075,7 +2116,7 @@ void checkBacklight() backlightOn(); } - bool backlightOn = (g_eeGeneral.backlightMode == e_backlight_mode_on || lightOffCounter || isFunctionActive(FUNC_BACKLIGHT)); + bool backlightOn = (g_eeGeneral.backlightMode == e_backlight_mode_on || lightOffCounter || isFunctionActive(FUNCTION_BACKLIGHT)); if (flashCounter) backlightOn = !backlightOn; if (backlightOn) BACKLIGHT_ON(); @@ -2893,7 +2934,7 @@ void evalInputs(uint8_t mode) } if (ch < NUM_STICKS) { //only do this for sticks - if (mode <= e_perout_mode_inactive_phase && (isFunctionActive(FUNC_TRAINER) || isFunctionActive(FUNC_TRAINER_RUD+ch))) { + if (mode <= e_perout_mode_inactive_phase && isFunctionActive(FUNCTION_TRAINER+ch)) { // trainer mode TrainerMix* td = &g_eeGeneral.trainer.mix[ch]; if (td->mode) { @@ -2951,7 +2992,6 @@ void testFunc() #endif MASK_FUNC_TYPE activeFunctions = 0; -MASK_CFN_TYPE activeSwitches = 0; MASK_CFN_TYPE activeFnSwitches = 0; tmr10ms_t lastFunctionTime[NUM_CFN] = { 0 }; @@ -3096,10 +3136,10 @@ uint8_t fnSwitchDuration[NUM_CFN] = { 0 }; inline void playCustomFunctionFile(CustomFnData *sd, uint8_t id) { - char filename[sizeof(SOUNDS_PATH)+sizeof(sd->param.name)+sizeof(SOUNDS_EXT)] = SOUNDS_PATH "/"; + char filename[sizeof(SOUNDS_PATH)+sizeof(sd->play.name)+sizeof(SOUNDS_EXT)] = SOUNDS_PATH "/"; strncpy(filename+SOUNDS_PATH_LNG_OFS, currentLanguagePack->id, 2); - strncpy(filename+sizeof(SOUNDS_PATH), sd->param.name, sizeof(sd->param.name)); - filename[sizeof(SOUNDS_PATH)+sizeof(sd->param.name)] = '\0'; + strncpy(filename+sizeof(SOUNDS_PATH), sd->play.name, sizeof(sd->play.name)); + filename[sizeof(SOUNDS_PATH)+sizeof(sd->play.name)] = '\0'; strcat(filename+sizeof(SOUNDS_PATH), SOUNDS_EXT); PLAY_FILE(filename, sd->func==FUNC_BACKGND_MUSIC ? PLAY_BACKGROUND : 0, id); } @@ -3112,300 +3152,240 @@ bool evalFunctionsFirstTime = true; void evalFunctions() { MASK_FUNC_TYPE newActiveFunctions = 0; - MASK_CFN_TYPE newActiveSwitches = 0; MASK_CFN_TYPE newActiveFnSwitches = 0; #if defined(ROTARY_ENCODERS) && defined(GVARS) static rotenc_t rePreviousValues[ROTARY_ENCODERS]; #endif - for (uint8_t i=0; iswtch; + int8_t swtch = CFN_SWITCH(sd); if (swtch) { - MASK_FUNC_TYPE function_mask = (CFN_FUNC(sd) >= FUNC_TRAINER ? ((MASK_FUNC_TYPE)1 << (CFN_FUNC(sd)-FUNC_TRAINER)) : 0); MASK_CFN_TYPE switch_mask = ((MASK_CFN_TYPE)1 << i); - uint8_t momentary = 0; - -#if !defined(PCBSTD) - - #define MOMENTARY_START_TEST() ( (momentary && !(activeSwitches & switch_mask) && active) || \ - (short_long==1 && !active && mSwitchDuration[mswitch]>0 && mSwitchDuration[mswitch] NUM_SWITCH+1) { - momentary = 1; - swtch -= NUM_SWITCH+1; - } - if (swtch < -NUM_SWITCH-1) { - momentary = 1; - swtch += NUM_SWITCH+1; - } bool active = getSwitch(swtch); - if (active) newActiveSwitches |= switch_mask; - if (momentary || short_long) { -#if !defined(PCBSTD) - bool swState = active; -#endif - - if (MOMENTARY_START_TEST()) { - - if (short_long) { - active = false; - momentary = true; - } - else { - active = !(activeFnSwitches & switch_mask); -#if !defined(CPUARM) - if (CFN_FUNC(sd) == FUNC_PLAY_BOTH && !active) { - momentary = true; - } - else -#endif - { - momentary = false; - } - } - } - else if (swtch == SWSRC_ON) { - active = false; - momentary = false; - } - else { - active = (activeFnSwitches & switch_mask); - momentary = false; - } -#if !defined(PCBSTD) - if (short_long && !(mSwitchDurationIncremented & (1< 0) { + mask = (1<<(CFN_CH_NUMBER(sd)-1)); + } + newActiveFunctions |= mask; + break; } - if (!(activeFunctions & function_mask)) { - if (CFN_FUNC(sd) == FUNC_INSTANT_TRIM) { + case FUNC_INSTANT_TRIM: + if (!isFunctionActive(FUNCTION_INSTANT_TRIM)) { + newActiveFunctions |= (1 << FUNCTION_INSTANT_TRIM); if (g_menuStack[0] == menuMainView #if defined(FRSKY) || g_menuStack[0] == menuTelemetryFrsky #endif - ) + ) instantTrim(); } - } - } - else if (CFN_FUNC(sd) <= FUNC_INSTANT_TRIM || CFN_FUNC(sd) == FUNC_RESET) { - active = false; - } + break; - if (CFN_FUNC(sd) == FUNC_RESET) { - switch (CFN_PARAM(sd)) { - case FUNC_RESET_TIMER1: - case FUNC_RESET_TIMER2: - resetTimer(CFN_PARAM(sd)); - break; - case FUNC_RESET_ALL: - resetAll(); - break; + case FUNC_RESET: + switch (CFN_PARAM(sd)) { + case FUNC_RESET_TIMER1: + case FUNC_RESET_TIMER2: + resetTimer(CFN_PARAM(sd)); + break; + case FUNC_RESET_ALL: + resetAll(); + break; #if defined(FRSKY) - case FUNC_RESET_TELEMETRY: - resetTelemetry(); - break; + case FUNC_RESET_TELEMETRY: + resetTelemetry(); + break; #endif #if ROTARY_ENCODERS > 0 - case FUNC_RESET_ROTENC1: + case FUNC_RESET_ROTENC1: #if ROTARY_ENCODERS > 1 - case FUNC_RESET_ROTENC2: + case FUNC_RESET_ROTENC2: #endif - g_rotenc[CFN_PARAM(sd)-FUNC_RESET_ROTENC1] = 0; - break; + g_rotenc[CFN_PARAM(sd)-FUNC_RESET_ROTENC1] = 0; + break; #endif - } - } - -#if defined(SDCARD) - else if (CFN_FUNC(sd) == FUNC_LOGS) { - logDelay = CFN_PARAM(sd); - } -#endif - -#if defined(HAPTIC) - else if (CFN_FUNC(sd) == FUNC_HAPTIC) { - haptic.event(AU_FRSKY_LAST+CFN_PARAM(sd)); - } -#endif - -#if defined(CPUARM) && defined(SDCARD) - else if (CFN_FUNC(sd) == FUNC_PLAY_SOUND || CFN_FUNC(sd) == FUNC_PLAY_TRACK || CFN_FUNC(sd) == FUNC_PLAY_VALUE) { - tmr10ms_t tmr10ms = get_tmr10ms(); - uint8_t repeatParam = CFN_PLAY_REPEAT(sd); - if (evalFunctionsFirstTime && 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)) { - lastFunctionTime[i] = tmr10ms; - if (CFN_FUNC(sd) == FUNC_PLAY_SOUND) { - AUDIO_PLAY(AU_FRSKY_FIRST+CFN_PARAM(sd)); - } - else if (CFN_FUNC(sd) == FUNC_PLAY_VALUE) { - PLAY_VALUE(CFN_PARAM(sd), i+1); - } - else { - playCustomFunctionFile(sd, i+1); - } } - } - } - else if (CFN_FUNC(sd) == FUNC_BACKGND_MUSIC) { - if (!IS_PLAYING(i+1)) { - playCustomFunctionFile(sd, i+1); - } - } - else if (CFN_FUNC(sd) == FUNC_VOLUME) { - if (CFN_ACTIVE(sd)) { - getvalue_t raw = getValue(CFN_PARAM(sd)); - //only set volume if input changed more than hysteresis - if (abs(requiredSpeakerVolumeRawLast - raw) > VOLUME_HYSTERESIS) { - requiredSpeakerVolumeRawLast = raw; - } - requiredSpeakerVolume = ((1024 + requiredSpeakerVolumeRawLast) * VOLUME_LEVEL_MAX) / 2048; - } - else { - active = false; - } - } -#elif defined(VOICE) - else if (CFN_FUNC(sd) == FUNC_PLAY_SOUND || CFN_FUNC(sd) == FUNC_PLAY_TRACK || CFN_FUNC(sd) == FUNC_PLAY_BOTH || CFN_FUNC(sd) == FUNC_PLAY_VALUE) { - tmr10ms_t tmr10ms = get_tmr10ms(); - uint8_t repeatParam = CFN_PLAY_REPEAT(sd); - if (!lastFunctionTime[i] || (CFN_FUNC(sd)==FUNC_PLAY_BOTH && active!=(bool)(activeFnSwitches&switch_mask)) || (repeatParam && (signed)(tmr10ms-lastFunctionTime[i])>=1000*repeatParam)) { - lastFunctionTime[i] = tmr10ms; - uint8_t param = CFN_PARAM(sd); - if (CFN_FUNC(sd) == FUNC_PLAY_SOUND) { - AUDIO_PLAY(AU_FRSKY_FIRST+param); - } - else if (CFN_FUNC(sd) == FUNC_PLAY_VALUE) { - PLAY_VALUE(param, i+1); - } - else { -#if defined(GVARS) - if (CFN_FUNC(sd) == FUNC_PLAY_TRACK && param > 250) - param = GVAR_VALUE(param-251, getGVarFlightPhase(s_perout_flight_phase, param-251)); -#endif - PUSH_CUSTOM_PROMPT(active ? param : param+1, i+1); - } - } - } -#else - else if (CFN_FUNC(sd) == FUNC_PLAY_SOUND) { - tmr10ms_t tmr10ms = get_tmr10ms(); - uint8_t repeatParam = CFN_PLAY_REPEAT(sd); - if (!lastFunctionTime[i] || (repeatParam && (signed)(tmr10ms-lastFunctionTime[i])>=1000*repeatParam)) { - lastFunctionTime[i] = tmr10ms; - AUDIO_PLAY(AU_FRSKY_FIRST+CFN_PARAM(sd)); - } - } -#endif - -#if defined(DEBUG) - else if (CFN_FUNC(sd) == FUNC_TEST) { - testFunc(); - } -#endif + break; #if defined(GVARS) - else if (CFN_FUNC(sd) >= FUNC_ADJUST_GV1) { - if (CFN_ACTIVE(sd)) { + case FUNC_ADJUST_GVAR: if (CFN_GVAR_MODE(sd) == 0) { - SET_GVAR(CFN_FUNC(sd)-FUNC_ADJUST_GV1, CFN_PARAM(sd), s_perout_flight_phase); + SET_GVAR(CFN_GVAR_NUMBER(sd), CFN_PARAM(sd), s_perout_flight_phase); } else if (CFN_GVAR_MODE(sd) == 2) { - SET_GVAR(CFN_FUNC(sd)-FUNC_ADJUST_GV1, GVAR_VALUE(CFN_PARAM(sd), s_perout_flight_phase), s_perout_flight_phase); + SET_GVAR(CFN_GVAR_NUMBER(sd), GVAR_VALUE(CFN_PARAM(sd), s_perout_flight_phase), s_perout_flight_phase); } else if (CFN_GVAR_MODE(sd) == 3) { if (!(activeFnSwitches & switch_mask)) { - SET_GVAR(CFN_FUNC(sd)-FUNC_ADJUST_GV1, GVAR_VALUE(CFN_FUNC(sd)-FUNC_ADJUST_GV1, getGVarFlightPhase(s_perout_flight_phase, CFN_FUNC(sd)-FUNC_ADJUST_GV1)) + (CFN_PARAM(sd) ? +1 : -1), s_perout_flight_phase); + SET_GVAR(CFN_GVAR_NUMBER(sd), GVAR_VALUE(CFN_GVAR_NUMBER(sd), getGVarFlightPhase(s_perout_flight_phase, CFN_GVAR_NUMBER(sd))) + (CFN_PARAM(sd) ? +1 : -1), s_perout_flight_phase); } } else if (CFN_PARAM(sd) >= MIXSRC_TrimRud && CFN_PARAM(sd) <= MIXSRC_TrimAil) { - trimGvar[CFN_PARAM(sd)-MIXSRC_TrimRud] = CFN_FUNC(sd)-FUNC_ADJUST_GV1; + trimGvar[CFN_PARAM(sd)-MIXSRC_TrimRud] = CFN_GVAR_NUMBER(sd); } #if defined(ROTARY_ENCODERS) 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_FUNC(sd)-FUNC_ADJUST_GV1, GVAR_VALUE(CFN_FUNC(sd)-FUNC_ADJUST_GV1, getGVarFlightPhase(s_perout_flight_phase, CFN_FUNC(sd)-FUNC_ADJUST_GV1)) + scroll, s_perout_flight_phase); + SET_GVAR(CFN_GVAR_NUMBER(sd), GVAR_VALUE(CFN_GVAR_NUMBER(sd), getGVarFlightPhase(s_perout_flight_phase, CFN_GVAR_NUMBER(sd))) + scroll, s_perout_flight_phase); } } #endif else { - SET_GVAR(CFN_FUNC(sd)-FUNC_ADJUST_GV1, limit((getvalue_t)-1250, getValue(CFN_PARAM(sd)), (getvalue_t)1250) / 10, s_perout_flight_phase); + SET_GVAR(CFN_GVAR_NUMBER(sd), limit((getvalue_t)-1250, getValue(CFN_PARAM(sd)), (getvalue_t)1250) / 10, s_perout_flight_phase); } - } - else { - active = false; - } - } + break; #endif - if (active) { - newActiveFnSwitches |= switch_mask; - newActiveFunctions |= function_mask; +#if defined(CPUARM) && defined(SDCARD) + case FUNC_VOLUME: + { + getvalue_t raw = getValue(CFN_PARAM(sd)); + //only set volume if input changed more than hysteresis + if (abs(requiredSpeakerVolumeRawLast - raw) > VOLUME_HYSTERESIS) { + requiredSpeakerVolumeRawLast = raw; + } + requiredSpeakerVolume = ((1024 + requiredSpeakerVolumeRawLast) * VOLUME_LEVEL_MAX) / 2048; + break; + } +#endif + +#if defined(CPUARM) && defined(SDCARD) + case FUNC_PLAY_SOUND: + case FUNC_PLAY_TRACK: + case FUNC_PLAY_VALUE: + { + tmr10ms_t tmr10ms = get_tmr10ms(); + uint8_t repeatParam = CFN_PLAY_REPEAT(sd); + if (evalFunctionsFirstTime && 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)) { + lastFunctionTime[i] = tmr10ms; + if (CFN_FUNC(sd) == FUNC_PLAY_SOUND) { + AUDIO_PLAY(AU_FRSKY_FIRST+CFN_PARAM(sd)); + } + else if (CFN_FUNC(sd) == FUNC_PLAY_VALUE) { + PLAY_VALUE(CFN_PARAM(sd), i+1); + } + else { + playCustomFunctionFile(sd, i+1); + } + } + } + break; + } + + case FUNC_BACKGND_MUSIC: + newActiveFunctions |= (1 << FUNCTION_BACKGND_MUSIC); + if (!IS_PLAYING(i+1)) { + playCustomFunctionFile(sd, i+1); + } + break; + + case FUNC_BACKGND_MUSIC_PAUSE: + newActiveFunctions |= (1 << FUNCTION_BACKGND_MUSIC_PAUSE); + break; + +#elif defined(VOICE) + case FUNC_PLAY_SOUND: + case FUNC_PLAY_TRACK: + case FUNC_PLAY_BOTH: + case FUNC_PLAY_VALUE: + { + tmr10ms_t tmr10ms = get_tmr10ms(); + uint8_t repeatParam = CFN_PLAY_REPEAT(sd); + if (!lastFunctionTime[i] || (CFN_FUNC(sd)==FUNC_PLAY_BOTH && active!=(bool)(activeFnSwitches&switch_mask)) || (repeatParam && (signed)(tmr10ms-lastFunctionTime[i])>=1000*repeatParam)) { + lastFunctionTime[i] = tmr10ms; + uint8_t param = CFN_PARAM(sd); + if (CFN_FUNC(sd) == FUNC_PLAY_SOUND) { + AUDIO_PLAY(AU_FRSKY_FIRST+param); + } + else if (CFN_FUNC(sd) == FUNC_PLAY_VALUE) { + PLAY_VALUE(param, i+1); + } + else { +#if defined(GVARS) + if (CFN_FUNC(sd) == FUNC_PLAY_TRACK && param > 250) + param = GVAR_VALUE(param-251, getGVarFlightPhase(s_perout_flight_phase, param-251)); +#endif + PUSH_CUSTOM_PROMPT(active ? param : param+1, i+1); + } + } + break; + } +#else + case FUNC_PLAY_SOUND: + { + tmr10ms_t tmr10ms = get_tmr10ms(); + uint8_t repeatParam = CFN_PLAY_REPEAT(sd); + if (!lastFunctionTime[i] || (repeatParam && (signed)(tmr10ms-lastFunctionTime[i])>=1000*repeatParam)) { + lastFunctionTime[i] = tmr10ms; + AUDIO_PLAY(AU_FRSKY_FIRST+CFN_PARAM(sd)); + } + break; + } +#endif + +#if defined(FRSKY) && defined(VARIO) + case FUNC_VARIO: + newActiveFunctions |= (1 << FUNCTION_VARIO); + break; +#endif + +#if defined(HAPTIC) + case FUNC_HAPTIC: + haptic.event(AU_FRSKY_LAST+CFN_PARAM(sd)); + break; +#endif + +#if defined(SDCARD) + case FUNC_LOGS: + newActiveFunctions |= (1 << FUNCTION_LOGS); + logDelay = CFN_PARAM(sd); + break; +#endif + + case FUNC_BACKLIGHT: + newActiveFunctions |= (1 << FUNCTION_BACKLIGHT); + break; + +#if defined(DEBUG) + case FUNC_TEST: + testFunc(); + break; +#endif } + + newActiveFnSwitches |= switch_mask; } else { lastFunctionTime[i] = 0; @@ -3413,7 +3393,7 @@ void evalFunctions() fnSwitchDuration[i] = 0; #endif #if defined(CPUARM) && defined(SDCARD) - if (CFN_FUNC(sd) == FUNC_BACKGND_MUSIC && isFunctionActive(FUNC_BACKGND_MUSIC)) { + if (CFN_FUNC(sd) == FUNC_BACKGND_MUSIC && isFunctionActive(FUNCTION_BACKGND_MUSIC)) { STOP_PLAY(i+1); } #endif @@ -3421,13 +3401,13 @@ void evalFunctions() } } - activeSwitches = newActiveSwitches; activeFnSwitches = newActiveFnSwitches; activeFunctions = newActiveFunctions; #if defined(ROTARY_ENCODERS) && defined(GVARS) - for (uint8_t i=0; isum = 0; } - uint8_t atm = (tm >= 0 ? tm : TMR_VAROFS-tm-1); - // value for time described in timer->mode // OFFABSTHsTH%THt - if (atm == TMRMODE_THR_REL) { + if (tm == TMRMODE_THR_REL) { timerState->cnt++; timerState->sum+=val; } - if (atm>=(TMR_VAROFS+NUM_SWITCH)){ // toggeled switch - if(!(timerState->toggled | timerState->sum | timerState->cnt | timerState->lastPos)) { timerState->lastPos = tm < 0; timerState->sum = 1; } // if initializing then init the lastPos - uint8_t swPos = getSwitch(tm>0 ? tm-(TMR_VAROFS+NUM_SWITCH-1) : tm+NUM_SWITCH); - if (swPos && !timerState->lastPos) timerState->toggled = !timerState->toggled; // if switch is flipped first time -> change counter state - timerState->lastPos = swPos; - } - if ((timerState->val_10ms += tick10ms) >= 100) { timerState->val_10ms -= 100 ; int16_t newTimerVal = timerState->val; if (tv) newTimerVal = tv - newTimerVal; - if (atm==TMRMODE_ABS) { + if (tm == TMRMODE_ABS) { newTimerVal++; } - else if (atm==TMRMODE_THR) { + else if (tm == TMRMODE_THR) { if (val) newTimerVal++; } - else if (atm==TMRMODE_THR_REL) { + 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) @@ -4028,19 +3997,17 @@ void doMixerCalculations() #endif timerState->cnt=0; } - else if (atm==TMRMODE_THR_TRG) { + else if (tm == TMRMODE_THR_TRG) { if (val || newTimerVal > 0) newTimerVal++; } else { - if (atm<(TMR_VAROFS+NUM_SWITCH)) - timerState->toggled = tm>0 ? getSwitch(tm-(TMR_VAROFS-1)) : !getSwitch(-tm); // normal switch - if (timerState->toggled) + if (tm > 0) tm -= (TMR_VAROFS-1); + if (getSwitch(tm)) newTimerVal++; } - switch(timerState->state) - { + switch (timerState->state) { case TMR_RUNNING: if (tv && newTimerVal>=(int16_t)tv) { AUDIO_TIMER_00(g_model.timers[i].countdownBeep); @@ -4098,6 +4065,55 @@ void doMixerCalculations() *lastValue -= 1; } } + else if (cs->func == CS_STICKY) { + PACK(typedef struct { + bool state; + bool 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 ^= true; + if (!before) { + lastValue.state = false; + } + } + } + else { + bool now = getSwitch(cs->v1); + if (before != now) { + lastValue.last ^= true; + if (!before) { + lastValue.state = true; + } + } + } + } +#if defined(CPUARM) + else if (cs->func == CS_STAY) { + PACK(typedef struct { + uint8_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 @@ -4267,7 +4283,7 @@ void opentxClose() hapticOff(); #endif -#if defined(CPUARM) +#if defined(CPUARM) && defined(FRSKY) if((g_model.frsky.mAhPersistent) && (g_model.frsky.storedMah != frskyData.hub.currentConsumption)) { g_model.frsky.storedMah = frskyData.hub.currentConsumption; eeDirty(EE_MODEL); diff --git a/radio/src/opentx.h b/radio/src/opentx.h index eaf36e142..8da0f1d9d 100644 --- a/radio/src/opentx.h +++ b/radio/src/opentx.h @@ -397,7 +397,6 @@ enum EnumKeys { #define NUM_PSWITCH (SWSRC_LAST_SWITCH-SWSRC_FIRST_SWITCH+1) #define NUM_POTSSW (NUM_XPOTS*6) -#define NUM_SWITCH (NUM_PSWITCH+NUM_CSW+NUM_POTSSW) #if defined(PCBTARANIS) #define KEY_RIGHT KEY_PLUS @@ -623,33 +622,6 @@ enum BaseCurves { #define SWASH_TYPE_90 4 #define SWASH_TYPE_NUM 4 -enum CswFunctions { - CS_OFF, - CS_VEQUAL, // v==offset - CS_VPOS, // v>offset - CS_VNEG, // voffset - CS_ANEG, // |v|> 3; - - for (int i=1; i<7; i++) - { - //INP_B_KEY_MEN 1 .. INP_B_KEY_LFT 6 - keys[enuk].input(in & (1< 0 - #define rotencDown() (!(PIOB->PIO_PDSR & 0x40)) + #define REA_DOWN() (!(PIOB->PIO_PDSR & 0x40)) #else - #define rotencDown() 0 + #define REA_DOWN() (0) #endif // Debug driver diff --git a/radio/src/targets/sky9x/keys_driver.cpp b/radio/src/targets/sky9x/keys_driver.cpp index 604db4f8b..7851a447e 100644 --- a/radio/src/targets/sky9x/keys_driver.cpp +++ b/radio/src/targets/sky9x/keys_driver.cpp @@ -113,9 +113,14 @@ uint32_t readTrims() return result; } +uint8_t trimDown(uint8_t idx) +{ + return readTrims() & (1 << idx); +} + uint8_t keyDown() { - return (~readKeys() & 0x7E) || rotencDown(); + return (~readKeys() & 0x7E) || REA_DOWN(); } void readKeysAndTrims() @@ -123,7 +128,7 @@ void readKeysAndTrims() register uint32_t i; #if ROTARY_ENCODERS > 0 - keys[BTN_REa].input(rotencDown(), BTN_REa); + keys[BTN_REa].input(REA_DOWN(), BTN_REa); #endif uint8_t enuk = KEY_MENU; diff --git a/radio/src/targets/stock/board_stock.cpp b/radio/src/targets/stock/board_stock.cpp index 8f1fd72eb..eaf5f2201 100644 --- a/radio/src/targets/stock/board_stock.cpp +++ b/radio/src/targets/stock/board_stock.cpp @@ -234,37 +234,38 @@ bool switchState(EnumKeys enuk) return result; } -#ifndef SIMU -FORCEINLINE -#endif -void readKeysAndTrims() +// Trim switches ... +static const pm_uchar crossTrim[] PROGMEM ={ + 1<x\0 ""ax""|a|b\0 ""ax\0 ""ax""|a|b\0 ""a 2 - #define TR_ROTARY_ENCODERS_VSRCRAW "REa ""REb ""REc ""REd " -#elif defined(PCBGRUVIN9X) && ROTARY_ENCODERS <= 2 - #define TR_ROTARY_ENCODERS_VSRCRAW "REa ""REb " + #define TR_ROTARY_ENCODERS "REa\0" + #define TR_ROTENC_SWITCHES "REa" +#elif defined(PCBGRUVIN9X) || defined(PCBMEGA2560) + #define TR_ROTARY_ENCODERS "REa\0""REb\0" + #define TR_ROTENC_SWITCHES "REa""REb" #else - #define TR_ROTARY_ENCODERS_VSRCRAW + #define TR_ROTARY_ENCODERS + #define TR_ROTENC_SWITCHES +#endif + +#if defined(PCBTARANIS) + #define TR_6POS_POTS "P11""P12""P13""P14""P15""P16""P21""P22""P23""P24""P25""P26" + #define TR_VSWITCHES "SA\300""SA-""SA\301""SB\300""SB-""SB\301""SC\300""SC-""SC\301""SD\300""SD-""SD\301""SE\300""SE-""SE\301""SF\300""SF\301""SG\300""SG-""SG\301""SH\300""SH\301" TR_6POS_POTS TR_TRIMS_SWITCHES TR_ROTENC_SWITCHES TR_CUSTOMSW +#elif defined(CPUARM) + #define TR_VSWITCHES TR_9X_3POS_SWITCHES "THR""RUD""ELE""AIL""GEA""TRN" TR_TRIMS_SWITCHES TR_ROTENC_SWITCHES TR_CUSTOMSW +#else + #define TR_VSWITCHES TR_9X_3POS_SWITCHES "THR""RUD""ELE""AIL""GEA""TRN" TR_TRIMS_SWITCHES TR_ROTENC_SWITCHES TR_CUSTOMSW #endif #if defined(HELI) @@ -356,7 +375,7 @@ #define TR_CYC_VSRCRAW "[C1]""[C2]""[C3]" #endif -#define TR_VSRCRAW "---\0""Rud\0""Ele\0""Thr\0""Ail\0" TR_POTS_VSRCRAW TR_ROTARY_ENCODERS_VSRCRAW "MAX\0" TR_CYC_VSRCRAW "TrmR" "TrmE" "TrmT" "TrmA" TR_SW_VSRCRAW +#define TR_VSRCRAW "---\0""Rud\0""Ele\0""Thr\0""Ail\0" TR_POTS_VSRCRAW TR_ROTARY_ENCODERS "MAX\0" TR_CYC_VSRCRAW "TrmR" "TrmE" "TrmT" "TrmA" TR_SW_VSRCRAW #define LEN_VTMRMODES "\003" #define TR_VTMRMODES "OFF""ABS""THs""TH%""THt" @@ -713,7 +732,7 @@ // Taranis column headers #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_CSW_HEADERS { " Function ", " V1 ", " V2 ", " AND Switch ", " Duration ", " Delay " } +#define TR_CSW_HEADERS { " Function ", " V1 ", " V2 ", " V2 ", " AND Switch ", " Duration ", " Delay " } // About screen #define TR_ABOUTUS TR(" ABOUT ", "ABOUT") diff --git a/radio/src/translations/es.h.txt b/radio/src/translations/es.h.txt index d1c923ea7..952bc68fa 100644 --- a/radio/src/translations/es.h.txt +++ b/radio/src/translations/es.h.txt @@ -335,9 +335,9 @@ #if defined(PCBTARANIS) #define TR_6POS_POTS "P11""P12""P13""P14""P15""P16""P21""P22""P23""P24""P25""P26" - #define TR_VSWITCHES "SA\300""SA-""SA\301""SB\300""SB-""SB\301""SC\300""SC-""SC\301""SD\300""SD-""SD\301""SE\300""SE-""SE\301""SF\300""SF\301""SG\300""SG-""SG\301""SH\300""SH\301" TR_CUSTOMSW TR_6POS_POTS "Uno" + #define TR_VSWITCHES "SA\300""SA-""SA\301""SB\300""SB-""SB\301""SC\300""SC-""SC\301""SD\300""SD-""SD\301""SE\300""SE-""SE\301""SF\300""SF\301""SG\300""SG-""SG\301""SH\300""SH\301" TR_CUSTOMSW TR_6POS_POTS #else - #define TR_VSWITCHES TR_9X_3POS_SWITCHES "ACE""DIR""ELE""ALE""GEA""TRN" TR_CUSTOMSW "Uno" + #define TR_VSWITCHES TR_9X_3POS_SWITCHES "ACE""DIR""ELE""ALE""GEA""TRN" TR_CUSTOMSW #endif #if defined(PCBSKY9X) diff --git a/radio/src/translations/fr.h.txt b/radio/src/translations/fr.h.txt index e018ef0a5..8cf9b660f 100644 --- a/radio/src/translations/fr.h.txt +++ b/radio/src/translations/fr.h.txt @@ -335,9 +335,9 @@ #if defined(PCBTARANIS) #define TR_6POS_POTS "P11""P12""P13""P14""P15""P16""P21""P22""P23""P24""P25""P26" - #define TR_VSWITCHES "SA\300""SA-""SA\301""SB\300""SB-""SB\301""SC\300""SC-""SC\301""SD\300""SD-""SD\301""SE\300""SE-""SE\301""SF\300""SF\301""SG\300""SG-""SG\301""SH\300""SH\301" TR_CUSTOMSW TR_6POS_POTS "1*\0" + #define TR_VSWITCHES "SA\300""SA-""SA\301""SB\300""SB-""SB\301""SC\300""SC-""SC\301""SD\300""SD-""SD\301""SE\300""SE-""SE\301""SF\300""SF\301""SG\300""SG-""SG\301""SH\300""SH\301" TR_CUSTOMSW TR_6POS_POTS #else - #define TR_VSWITCHES TR_9X_3POS_SWITCHES "THR""RUD""ELE""AIL""GEA""TRN" TR_CUSTOMSW "1*\0" + #define TR_VSWITCHES TR_9X_3POS_SWITCHES "THR""RUD""ELE""AIL""GEA""TRN" TR_CUSTOMSW #endif #if defined(PCBSKY9X) diff --git a/radio/src/translations/it.h.txt b/radio/src/translations/it.h.txt index fc59b9576..e767bc8f2 100644 --- a/radio/src/translations/it.h.txt +++ b/radio/src/translations/it.h.txt @@ -337,7 +337,7 @@ #define TR_6POS_POTS "P11""P12""P13""P14""P15""P16""P21""P22""P23""P24""P25""P26" #define TR_VSWITCHES "SA\300""SA-""SA\301""SB\300""SB-""SB\301""SC\300""SC-""SC\301""SD\300""SD-""SD\301""SE\300""SE-""SE\301""SF\300""SF\301""SG\300""SG-""SG\301""SH\300""SH\301" TR_CUSTOMSW TR_6POS_POTS "1*\0" #else - #define TR_VSWITCHES TR_9X_3POS_SWITCHES "THR""RUD""ELE""AIL""GEA""TRN" TR_CUSTOMSW "One" + #define TR_VSWITCHES TR_9X_3POS_SWITCHES "THR""RUD""ELE""AIL""GEA""TRN" TR_CUSTOMSW #endif #if defined(PCBSKY9X) diff --git a/radio/src/translations/pl.h.txt b/radio/src/translations/pl.h.txt index f2de7379f..677cdf107 100644 --- a/radio/src/translations/pl.h.txt +++ b/radio/src/translations/pl.h.txt @@ -335,9 +335,9 @@ #if defined(PCBTARANIS) #define TR_6POS_POTS "P11""P12""P13""P14""P15""P16""P21""P22""P23""P24""P25""P26" - #define TR_VSWITCHES "SA\300""SA-""SA\301""SB\300""SB-""SB\301""SC\300""SC-""SC\301""SD\300""SD-""SD\301""SE\300""SE-""SE\301""SF\300""SF\301""SG\300""SG-""SG\301""SH\300""SH\301" TR_CUSTOMSW TR_6POS_POTS " * " + #define TR_VSWITCHES "SA\300""SA-""SA\301""SB\300""SB-""SB\301""SC\300""SC-""SC\301""SD\300""SD-""SD\301""SE\300""SE-""SE\301""SF\300""SF\301""SG\300""SG-""SG\301""SH\300""SH\301" TR_CUSTOMSW TR_6POS_POTS #else - #define TR_VSWITCHES TR_9X_3POS_SWITCHES "GAZ""SK ""LOT""SW ""GEA""TRN" TR_CUSTOMSW " * " + #define TR_VSWITCHES TR_9X_3POS_SWITCHES "GAZ""SK ""LOT""SW ""GEA""TRN" TR_CUSTOMSW #endif #if defined(PCBSKY9X) diff --git a/radio/src/translations/pt.h.txt b/radio/src/translations/pt.h.txt index 3a78386ed..1c722ed02 100644 --- a/radio/src/translations/pt.h.txt +++ b/radio/src/translations/pt.h.txt @@ -335,9 +335,9 @@ #if defined(PCBTARANIS) #define TR_6POS_POTS "P11""P12""P13""P14""P15""P16""P21""P22""P23""P24""P25""P26" - #define TR_VSWITCHES "SA\300""SA-""SA\301""SB\300""SB-""SB\301""SC\300""SC-""SC\301""SD\300""SD-""SD\301""SE\300""SE-""SE\301""SF\300""SF\301""SG\300""SG-""SG\301""SH\300""SH\301" TR_CUSTOMSW TR_6POS_POTS "1*\0" + #define TR_VSWITCHES "SA\300""SA-""SA\301""SB\300""SB-""SB\301""SC\300""SC-""SC\301""SD\300""SD-""SD\301""SE\300""SE-""SE\301""SF\300""SF\301""SG\300""SG-""SG\301""SH\300""SH\301" TR_CUSTOMSW TR_6POS_POTS #else - #define TR_VSWITCHES TR_9X_3POS_SWITCHES "THR""RUD""ELE""AIL""GEA""TRN" TR_CUSTOMSW "1*\0" + #define TR_VSWITCHES TR_9X_3POS_SWITCHES "THR""RUD""ELE""AIL""GEA""TRN" TR_CUSTOMSW #endif #if defined(PCBSKY9X) diff --git a/radio/src/translations/se.h.txt b/radio/src/translations/se.h.txt index 6a3b32bfc..c585a356b 100644 --- a/radio/src/translations/se.h.txt +++ b/radio/src/translations/se.h.txt @@ -335,9 +335,9 @@ #if defined(PCBTARANIS) #define TR_6POS_POTS "P11""P12""P13""P14""P15""P16""P21""P22""P23""P24""P25""P26" - #define TR_VSWITCHES "SA\300""SA-""SA\301""SB\300""SB-""SB\301""SC\300""SC-""SC\301""SD\300""SD-""SD\301""SE\300""SE-""SE\301""SF\300""SF\301""SG\300""SG-""SG\301""SH\300""SH\301" TR_CUSTOMSW TR_6POS_POTS "One" + #define TR_VSWITCHES "SA\300""SA-""SA\301""SB\300""SB-""SB\301""SC\300""SC-""SC\301""SD\300""SD-""SD\301""SE\300""SE-""SE\301""SF\300""SF\301""SG\300""SG-""SG\301""SH\300""SH\301" TR_CUSTOMSW TR_6POS_POTS #else - #define TR_VSWITCHES TR_9X_3POS_SWITCHES "THR""RUD""ELE""AIL""GEA""TRN" TR_CUSTOMSW "One" + #define TR_VSWITCHES TR_9X_3POS_SWITCHES "THR""RUD""ELE""AIL""GEA""TRN" TR_CUSTOMSW #endif #if defined(PCBSKY9X)