diff --git a/companion/src/comparedialog.cpp b/companion/src/comparedialog.cpp
index 5ec3a277b..140d7be52 100644
--- a/companion/src/comparedialog.cpp
+++ b/companion/src/comparedialog.cpp
@@ -1015,8 +1015,8 @@ void CompareDialog::printSwitches()
str.append("
");
for (int i=0; igetCapability(LogicalSwitches); i++) {
GeneralSettings settings;
- QString sw1 = g_model1->customSw[i].toString(*g_model1, settings);
- QString sw2 = g_model2->customSw[i].toString(*g_model2, settings);
+ QString sw1 = g_model1->logicalSw[i].toString(*g_model1, settings);
+ QString sw2 = g_model2->logicalSw[i].toString(*g_model2, settings);
if (!(sw1.isEmpty() && sw2.isEmpty())) {
str.append("");
color=getColor1(sw1,sw2);
@@ -1059,8 +1059,8 @@ void CompareDialog::printFSwitches()
str.append(" ");
for(int i=0; igetCapability(CustomFunctions); i++)
{
- if (g_model1->funcSw[i].swtch.type || g_model2->funcSw[i].swtch.type) {
- if ((g_model1->funcSw[i].swtch != g_model2->funcSw[i].swtch) || (g_model1->funcSw[i].func!=g_model2->funcSw[i].func) || (g_model1->funcSw[i].adjustMode!=g_model2->funcSw[i].adjustMode) || (g_model1->funcSw[i].param!=g_model2->funcSw[i].param)) {
+ if (g_model1->customFn[i].swtch.type || g_model2->customFn[i].swtch.type) {
+ if ((g_model1->customFn[i].swtch != g_model2->customFn[i].swtch) || (g_model1->customFn[i].func!=g_model2->customFn[i].func) || (g_model1->customFn[i].adjustMode!=g_model2->customFn[i].adjustMode) || (g_model1->customFn[i].param!=g_model2->customFn[i].param)) {
color1="green";
color2="red";
} else {
@@ -1068,18 +1068,18 @@ void CompareDialog::printFSwitches()
color2="grey";
}
str.append("");
- if (g_model1->funcSw[i].swtch.type) {
- str.append(doTC(g_model1->funcSw[i].swtch.toString(),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 (g_model1->customFn[i].swtch.type) {
+ str.append(doTC(g_model1->customFn[i].swtch.toString(),color1));
+ str.append(doTC(g_model1->customFn[i].funcToString(),color1));
+ str.append(doTC(g_model1->customFn[i].paramToString(),color1));
+ int index=g_model1->customFn[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));
+ str.append(doTC(QString("%1").arg(g_model1->customFn[i].repeatParam),color1));
} else {
str.append(doTC( "---",color1));
}
if ((index<=FuncInstantTrim) || (index>FuncBackgroundMusicPause)) {
- str.append(doTC((g_model1->funcSw[i].enabled ? "ON" : "OFF"),color1));
+ str.append(doTC((g_model1->customFn[i].enabled ? "ON" : "OFF"),color1));
} else {
str.append(doTC( "---",color1));
}
@@ -1087,18 +1087,18 @@ void CompareDialog::printFSwitches()
str.append(" | | | | | ");
}
str.append(doTC(tr("SF")+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(g_model2->funcSw[i].funcToString(),color2));
- str.append(doTC(g_model2->funcSw[i].paramToString(),color2));
- int index=g_model2->funcSw[i].func;
+ if (g_model2->customFn[i].swtch.type) {
+ str.append(doTC(g_model2->customFn[i].swtch.toString(),color2));
+ str.append(doTC(g_model2->customFn[i].funcToString(),color2));
+ str.append(doTC(g_model2->customFn[i].paramToString(),color2));
+ int index=g_model2->customFn[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));
+ str.append(doTC(QString("%1").arg(g_model2->customFn[i].repeatParam),color2));
} else {
str.append(doTC( "---",color2));
}
if ((index<=FuncInstantTrim) || (index>FuncBackgroundMusicPause)) {
- str.append(doTC((g_model2->funcSw[i].enabled ? "ON" : "OFF"),color2));
+ str.append(doTC((g_model2->customFn[i].enabled ? "ON" : "OFF"),color2));
} else {
str.append(doTC( "---",color2));
}
diff --git a/companion/src/eeprominterface.cpp b/companion/src/eeprominterface.cpp
index 596c6f08b..bcad0c347 100644
--- a/companion/src/eeprominterface.cpp
+++ b/companion/src/eeprominterface.cpp
@@ -713,15 +713,15 @@ QString LogicalSwitchData::toString(const ModelData & model, const GeneralSettin
return result;
}
-void FuncSwData::clear()
+void CustomFunctionData::clear()
{
- memset(this, 0, sizeof(FuncSwData));
+ memset(this, 0, sizeof(CustomFunctionData));
if (!GetCurrentFirmware()->getCapability(SafetyChannelCustomFunction)) {
func = FuncTrainer;
}
}
-QString FuncSwData::funcToString()
+QString CustomFunctionData::funcToString()
{
ModelData model;
if (func >= FuncOverrideCH1 && func <= FuncOverrideCH32)
@@ -771,7 +771,7 @@ QString FuncSwData::funcToString()
}
}
-QString FuncSwData::paramToString()
+QString CustomFunctionData::paramToString()
{
QStringList qs;
if (func <= FuncInstantTrim) {
@@ -842,7 +842,7 @@ QString FuncSwData::paramToString()
return "";
}
-QString FuncSwData::repeatToString()
+QString CustomFunctionData::repeatToString()
{
if (repeatParam==0) {
return QObject::tr("No repeat");
@@ -1159,9 +1159,9 @@ void ModelData::clear()
for (int i=0; ifunc = func; }
+ CustomFunctionData(AssignFunc func=FuncOverrideCH1) { clear(); this->func = func; }
RawSwitch swtch;
AssignFunc func;
int param;
@@ -1019,8 +1019,8 @@ class ModelData {
ExpoData expoData[C9X_MAX_EXPOS];
CurveData curves[C9X_MAX_CURVES];
- LogicalSwitchData customSw[C9X_NUM_CSW];
- FuncSwData funcSw[C9X_MAX_CUSTOM_FUNCTIONS];
+ LogicalSwitchData logicalSw[C9X_NUM_CSW];
+ CustomFunctionData customFn[C9X_MAX_CUSTOM_FUNCTIONS];
SwashRingData swashRingData;
unsigned int thrTraceSrc;
unsigned int modelId;
@@ -1289,18 +1289,18 @@ inline void applyStickModeToModel(ModelData &model, unsigned int mode)
// virtual switches
for (int i=0; igetCapability(VoicesAsNumbers)) {
for (int i=0; iaddLayout(repeatLayout, i+1, 4);
- fswtchRepeat[i] = new RepeatComboBox(this, model.funcSw[i].repeatParam);
+ fswtchRepeat[i] = new RepeatComboBox(this, model.customFn[i].repeatParam);
repeatLayout->addWidget(fswtchRepeat[i], i+1);
connect(fswtchRepeat[i], SIGNAL(modified()), this, SLOT(onChildModified()));
@@ -308,12 +308,14 @@ void CustomFunctionsPanel::onChildModified()
void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
{
+ CustomFunctionData & cfn = model.customFn[i];
+
unsigned int widgetsMask = 0;
if (modified) {
- model.funcSw[i].swtch = RawSwitch(fswtchSwtch[i]->itemData(fswtchSwtch[i]->currentIndex()).toInt());
- model.funcSw[i].func = (AssignFunc)fswtchFunc[i]->currentIndex();
- model.funcSw[i].enabled = fswtchEnable[i]->isChecked();
- model.funcSw[i].adjustMode = (AssignFunc)fswtchGVmode[i]->currentIndex();
+ cfn.swtch = RawSwitch(fswtchSwtch[i]->itemData(fswtchSwtch[i]->currentIndex()).toInt());
+ cfn.func = (AssignFunc)fswtchFunc[i]->currentIndex();
+ cfn.enabled = fswtchEnable[i]->isChecked();
+ cfn.adjustMode = (AssignFunc)fswtchGVmode[i]->currentIndex();
}
int index = fswtchFunc[i]->currentIndex();
@@ -325,9 +327,9 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
fswtchParam[i]->setMinimum(-channelsMax);
fswtchParam[i]->setMaximum(channelsMax);
if (modified) {
- model.funcSw[i].param = fswtchParam[i]->value();
+ cfn.param = fswtchParam[i]->value();
}
- fswtchParam[i]->setValue(model.funcSw[i].param);
+ fswtchParam[i]->setValue(cfn.param);
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM + CUSTOM_FUNCTION_ENABLE;
}
else if (index==FuncLogs) {
@@ -335,15 +337,15 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
fswtchParam[i]->setMinimum(0);
fswtchParam[i]->setMaximum(25.5);
fswtchParam[i]->setSingleStep(0.1);
- if (modified) model.funcSw[i].param = fswtchParam[i]->value()*10.0;
- fswtchParam[i]->setValue(model.funcSw[i].param/10.0);
+ if (modified) cfn.param = fswtchParam[i]->value()*10.0;
+ fswtchParam[i]->setValue(cfn.param/10.0);
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM;
}
else if (index>=FuncAdjustGV1 && index<=FuncAdjustGVLast) {
- if (modified) model.funcSw[i].adjustMode = fswtchGVmode[i]->currentIndex();
+ if (modified) cfn.adjustMode = fswtchGVmode[i]->currentIndex();
widgetsMask |= CUSTOM_FUNCTION_GV_MODE + CUSTOM_FUNCTION_ENABLE;
- if (model.funcSw[i].adjustMode==0) {
- if (modified) model.funcSw[i].param = fswtchParam[i]->value();
+ if (cfn.adjustMode==0) {
+ if (modified) cfn.param = fswtchParam[i]->value();
fswtchParam[i]->setDecimals(0);
fswtchParam[i]->setSingleStep(1);
if (IS_ARM(GetEepromInterface()->getBoard())) {
@@ -354,32 +356,32 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
fswtchParam[i]->setMinimum(-125);
fswtchParam[i]->setMaximum(125);
}
- fswtchParam[i]->setValue(model.funcSw[i].param);
+ fswtchParam[i]->setValue(cfn.param);
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM;
}
else {
- if (modified) model.funcSw[i].param = fswtchParamT[i]->itemData(fswtchParamT[i]->currentIndex()).toInt();
- populateFuncParamCB(fswtchParamT[i], model, index, model.funcSw[i].param, model.funcSw[i].adjustMode);
+ if (modified) cfn.param = fswtchParamT[i]->itemData(fswtchParamT[i]->currentIndex()).toInt();
+ populateFuncParamCB(fswtchParamT[i], model, index, cfn.param, cfn.adjustMode);
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM;
}
}
else if (index==FuncReset) {
- if (modified) model.funcSw[i].param = (uint8_t)fswtchParamT[i]->currentIndex();
- populateFuncParamCB(fswtchParamT[i], model, index, model.funcSw[i].param);
+ if (modified) cfn.param = (uint8_t)fswtchParamT[i]->currentIndex();
+ populateFuncParamCB(fswtchParamT[i], model, index, cfn.param);
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM | CUSTOM_FUNCTION_ENABLE;
}
else if (index>=FuncSetTimer1 && index<=FuncSetTimer2) {
- if (modified) model.funcSw[i].param = fswtchParam[i]->value();
+ if (modified) cfn.param = fswtchParam[i]->value();
fswtchParam[i]->setDecimals(0);
fswtchParam[i]->setSingleStep(1);
fswtchParam[i]->setMinimum(0);
fswtchParam[i]->setMaximum(59*60+59);
- fswtchParam[i]->setValue(model.funcSw[i].param);
+ fswtchParam[i]->setValue(cfn.param);
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM + CUSTOM_FUNCTION_ENABLE;
}
else if (index==FuncVolume) {
- if (modified) model.funcSw[i].param = fswtchParamT[i]->itemData(fswtchParamT[i]->currentIndex()).toInt();
- populateFuncParamCB(fswtchParamT[i], model, index, model.funcSw[i].param);
+ if (modified) cfn.param = fswtchParamT[i]->itemData(fswtchParamT[i]->currentIndex()).toInt();
+ populateFuncParamCB(fswtchParamT[i], model, index, cfn.param);
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM + CUSTOM_FUNCTION_ENABLE;
}
else if (index==FuncPlaySound || index==FuncPlayHaptic || index==FuncPlayValue || index==FuncPlayPrompt || index==FuncPlayBoth || index==FuncBackgroundMusic) {
@@ -388,8 +390,8 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
fswtchRepeat[i]->update();
}
if (index==FuncPlayValue) {
- if (modified) model.funcSw[i].param = fswtchParamT[i]->itemData(fswtchParamT[i]->currentIndex()).toInt();
- populateFuncParamCB(fswtchParamT[i], model, index, model.funcSw[i].param);
+ if (modified) cfn.param = fswtchParamT[i]->itemData(fswtchParamT[i]->currentIndex()).toInt();
+ populateFuncParamCB(fswtchParamT[i], model, index, cfn.param);
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM + CUSTOM_FUNCTION_REPEAT;
}
else if (index==FuncPlayPrompt || index==FuncPlayBoth) {
@@ -408,38 +410,38 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
if (modified) {
if (fswtchParamGV[i]->isChecked()) {
fswtchParam[i]->setMinimum(1);
- model.funcSw[i].param = std::min(fswtchParam[i]->value(),5.0)+(fswtchParamGV[i]->isChecked() ? 250 : 0);
+ cfn.param = std::min(fswtchParam[i]->value(),5.0)+(fswtchParamGV[i]->isChecked() ? 250 : 0);
}
else {
- model.funcSw[i].param = fswtchParam[i]->value();
+ cfn.param = fswtchParam[i]->value();
}
}
- if (model.funcSw[i].param>250 && (index!=FuncPlayBoth)) {
+ if (cfn.param>250 && (index!=FuncPlayBoth)) {
fswtchParamGV[i]->setChecked(true);
- fswtchParam[i]->setValue(model.funcSw[i].param-250);
+ fswtchParam[i]->setValue(cfn.param-250);
fswtchParam[i]->setMaximum(5);
}
else {
fswtchParamGV[i]->setChecked(false);
- fswtchParam[i]->setValue(model.funcSw[i].param);
+ fswtchParam[i]->setValue(cfn.param);
}
- if (model.funcSw[i].param < 251)
+ if (cfn.param < 251)
widgetsMask |= CUSTOM_FUNCTION_PLAY;
}
else {
widgetsMask |= CUSTOM_FUNCTION_FILE_PARAM;
if (modified) {
- memset(model.funcSw[i].paramarm, 0, sizeof(model.funcSw[i].paramarm));
+ memset(cfn.paramarm, 0, sizeof(cfn.paramarm));
int vml = firmware->getCapability(VoicesMaxLength);
if (fswtchParamArmT[i]->currentText() != "----") {
widgetsMask |= CUSTOM_FUNCTION_PLAY;
for (int j=0; jcurrentText().length(), vml); j++) {
- model.funcSw[i].paramarm[j] = fswtchParamArmT[i]->currentText().toAscii().at(j);
+ cfn.paramarm[j] = fswtchParamArmT[i]->currentText().toAscii().at(j);
}
}
}
else {
- populateFuncParamArmTCB(fswtchParamArmT[i], model.funcSw[i].paramarm, paramarmList);
+ populateFuncParamArmTCB(fswtchParamArmT[i], cfn.paramarm, paramarmList);
if (fswtchParamArmT[i]->currentText() != "----") {
widgetsMask |= CUSTOM_FUNCTION_PLAY;
}
@@ -449,37 +451,37 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
else if (index==FuncBackgroundMusic) {
widgetsMask |= CUSTOM_FUNCTION_FILE_PARAM;
if (modified) {
- memset(model.funcSw[i].paramarm, 0, sizeof(model.funcSw[i].paramarm));
+ memset(cfn.paramarm, 0, sizeof(cfn.paramarm));
int vml=firmware->getCapability(VoicesMaxLength);
if (fswtchParamArmT[i]->currentText() != "----") {
widgetsMask |= CUSTOM_FUNCTION_PLAY;
for (int j=0; jcurrentText().length(),vml); j++) {
- model.funcSw[i].paramarm[j] = fswtchParamArmT[i]->currentText().toAscii().at(j);
+ cfn.paramarm[j] = fswtchParamArmT[i]->currentText().toAscii().at(j);
}
}
}
}
else if (index==FuncPlaySound) {
- if (modified) model.funcSw[i].param = (uint8_t)fswtchParamT[i]->currentIndex();
- populateFuncParamCB(fswtchParamT[i], model, index, model.funcSw[i].param);
+ if (modified) cfn.param = (uint8_t)fswtchParamT[i]->currentIndex();
+ populateFuncParamCB(fswtchParamT[i], model, index, cfn.param);
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM;
}
else if (index==FuncPlayHaptic) {
- if (modified) model.funcSw[i].param = (uint8_t)fswtchParamT[i]->currentIndex();
- populateFuncParamCB(fswtchParamT[i], model, index, model.funcSw[i].param);
+ if (modified) cfn.param = (uint8_t)fswtchParamT[i]->currentIndex();
+ populateFuncParamCB(fswtchParamT[i], model, index, cfn.param);
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM;
}
}
else if (index==FuncBacklight && IS_TARANIS_PLUS(GetEepromInterface()->getBoard())) {
- if (modified) model.funcSw[i].param = (uint8_t)fswtchBLcolor[i]->value();
- fswtchBLcolor[i]->setValue(model.funcSw[i].param);
+ if (modified) cfn.param = (uint8_t)fswtchBLcolor[i]->value();
+ fswtchBLcolor[i]->setValue(cfn.param);
widgetsMask |= CUSTOM_FUNCTION_BL_COLOR;
}
else {
- if (modified) model.funcSw[i].param = fswtchParam[i]->value();
+ if (modified) cfn.param = fswtchParam[i]->value();
fswtchParam[i]->setDecimals(0);
fswtchParam[i]->setSingleStep(1);
- fswtchParam[i]->setValue(model.funcSw[i].param);
+ fswtchParam[i]->setValue(cfn.param);
if (index <= FuncInstantTrim) {
widgetsMask |= CUSTOM_FUNCTION_ENABLE;
}
@@ -491,7 +493,7 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
fswtchParamArmT[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_FILE_PARAM);
fswtchEnable[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_ENABLE);
if (widgetsMask & CUSTOM_FUNCTION_ENABLE)
- fswtchEnable[i]->setChecked(model.funcSw[i].enabled);
+ fswtchEnable[i]->setChecked(cfn.enabled);
else
fswtchEnable[i]->setChecked(false);
fswtchRepeat[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_REPEAT);
@@ -507,11 +509,11 @@ void CustomFunctionsPanel::update()
lock = true;
for (int i=0; igetCapability(CustomFunctions); i++) {
if (!initialized) {
- populateSwitchCB(fswtchSwtch[i], model.funcSw[i].swtch, generalSettings, CustomFunctionsContext);
- populateFuncCB(fswtchFunc[i], model.funcSw[i].func);
- populateGVmodeCB(fswtchGVmode[i], model.funcSw[i].adjustMode);
- populateFuncParamCB(fswtchParamT[i], model, model.funcSw[i].func, model.funcSw[i].param, model.funcSw[i].adjustMode);
- populateFuncParamArmTCB(fswtchParamArmT[i], model.funcSw[i].paramarm, paramarmList);
+ populateSwitchCB(fswtchSwtch[i], model.customFn[i].swtch, generalSettings, CustomFunctionsContext);
+ populateFuncCB(fswtchFunc[i], model.customFn[i].func);
+ populateGVmodeCB(fswtchGVmode[i], model.customFn[i].adjustMode);
+ populateFuncParamCB(fswtchParamT[i], model, model.customFn[i].func, model.customFn[i].param, model.customFn[i].adjustMode);
+ populateFuncParamArmTCB(fswtchParamArmT[i], model.customFn[i].paramarm, paramarmList);
}
refreshCustomFunction(i);
}
@@ -525,14 +527,14 @@ 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));
+ CustomFunctionData *fsw = &model.customFn[selectedFunction];
+ memcpy(fsw, fswData.mid(0, sizeof(CustomFunctionData)).constData(), sizeof(CustomFunctionData));
lock = true;
- populateSwitchCB(fswtchSwtch[selectedFunction], model.funcSw[selectedFunction].swtch, generalSettings, CustomFunctionsContext);
- populateFuncCB(fswtchFunc[selectedFunction], model.funcSw[selectedFunction].func);
- populateGVmodeCB(fswtchGVmode[selectedFunction], model.funcSw[selectedFunction].adjustMode);
- populateFuncParamCB(fswtchParamT[selectedFunction], model, model.funcSw[selectedFunction].func, model.funcSw[selectedFunction].param, model.funcSw[selectedFunction].adjustMode);
- populateFuncParamArmTCB(fswtchParamArmT[selectedFunction], model.funcSw[selectedFunction].paramarm, paramarmList);
+ populateSwitchCB(fswtchSwtch[selectedFunction], model.customFn[selectedFunction].swtch, generalSettings, CustomFunctionsContext);
+ populateFuncCB(fswtchFunc[selectedFunction], model.customFn[selectedFunction].func);
+ populateGVmodeCB(fswtchGVmode[selectedFunction], model.customFn[selectedFunction].adjustMode);
+ populateFuncParamCB(fswtchParamT[selectedFunction], model, model.customFn[selectedFunction].func, model.customFn[selectedFunction].param, model.customFn[selectedFunction].adjustMode);
+ populateFuncParamArmTCB(fswtchParamArmT[selectedFunction], model.customFn[selectedFunction].paramarm, paramarmList);
refreshCustomFunction(selectedFunction);
lock = false;
emit modified();
@@ -541,11 +543,11 @@ void CustomFunctionsPanel::fswPaste()
void CustomFunctionsPanel::fswDelete()
{
- model.funcSw[selectedFunction].clear();
+ model.customFn[selectedFunction].clear();
// TODO update switch and func
lock = true;
- populateSwitchCB(fswtchSwtch[selectedFunction], model.funcSw[selectedFunction].swtch, generalSettings, CustomFunctionsContext);
- populateFuncCB(fswtchFunc[selectedFunction], model.funcSw[selectedFunction].func);
+ populateSwitchCB(fswtchSwtch[selectedFunction], model.customFn[selectedFunction].swtch, generalSettings, CustomFunctionsContext);
+ populateFuncCB(fswtchFunc[selectedFunction], model.customFn[selectedFunction].func);
refreshCustomFunction(selectedFunction);
lock = false;
emit modified();
@@ -554,7 +556,7 @@ void CustomFunctionsPanel::fswDelete()
void CustomFunctionsPanel::fswCopy()
{
QByteArray fswData;
- fswData.append((char*)&model.funcSw[selectedFunction], sizeof(FuncSwData));
+ fswData.append((char*)&model.customFn[selectedFunction], sizeof(CustomFunctionData));
QMimeData *mimeData = new QMimeData;
mimeData->setData("application/x-companion-fsw", fswData);
QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard);
@@ -590,7 +592,7 @@ void CustomFunctionsPanel::populateFuncCB(QComboBox *b, unsigned int value)
{
b->clear();
for (unsigned int i=0; iaddItem(FuncSwData(AssignFunc(i)).funcToString());
+ b->addItem(CustomFunctionData(AssignFunc(i)).funcToString());
if (((i>=FuncOverrideCH1 && i<=FuncOverrideCH32) && !firmware->getCapability(SafetyChannelCustomFunction)) ||
((i==FuncVolume || i==FuncBackgroundMusic || i==FuncBackgroundMusicPause) && !firmware->getCapability(HasVolume)) ||
((i==FuncPlayHaptic) && !firmware->getCapability(Haptic)) ||
diff --git a/companion/src/modeledit/logicalswitches.cpp b/companion/src/modeledit/logicalswitches.cpp
index 0c31be7b4..db620fc3e 100644
--- a/companion/src/modeledit/logicalswitches.cpp
+++ b/companion/src/modeledit/logicalswitches.cpp
@@ -138,11 +138,11 @@ void LogicalSwitchesPanel::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() == LS_FAMILY_VOFS) {
- RawSource source = RawSource(model.customSw[i].val1);
- RawSourceRange range = source.getRange(model, generalSettings, model.customSw[i].getRangeFlags());
- model.customSw[i].val2 = (cswitchOffset[i]->value() - range.offset) / range.step;
+ model.logicalSw[i].val1 = cswitchSource1[i]->itemData(value).toInt();
+ if (model.logicalSw[i].getFunctionFamily() == LS_FAMILY_VOFS) {
+ RawSource source = RawSource(model.logicalSw[i].val1);
+ RawSourceRange range = source.getRange(model, generalSettings, model.logicalSw[i].getRangeFlags());
+ model.logicalSw[i].val2 = (cswitchOffset[i]->value() - range.offset) / range.step;
setSwitchWidgetVisibility(i);
}
emit modified();
@@ -153,7 +153,7 @@ void LogicalSwitchesPanel::v2Edited(int value)
{
if (!lock) {
int i = sender()->property("index").toInt();
- model.customSw[i].val2 = cswitchSource2[i]->itemData(value).toInt();
+ model.logicalSw[i].val2 = cswitchSource2[i]->itemData(value).toInt();
emit modified();
}
}
@@ -162,7 +162,7 @@ void LogicalSwitchesPanel::andEdited(int value)
{
if (!lock) {
int index = sender()->property("index").toInt();
- model.customSw[index].andsw = cswitchAnd[index]->itemData(value).toInt();
+ model.logicalSw[index].andsw = cswitchAnd[index]->itemData(value).toInt();
emit modified();
}
}
@@ -171,7 +171,7 @@ void LogicalSwitchesPanel::durationEdited(double duration)
{
if (!lock) {
int index = sender()->property("index").toInt();
- model.customSw[index].duration = (uint8_t)round(duration*10);
+ model.logicalSw[index].duration = (uint8_t)round(duration*10);
emit modified();
}
}
@@ -180,7 +180,7 @@ void LogicalSwitchesPanel::delayEdited(double delay)
{
if (!lock) {
int index = sender()->property("index").toInt();
- model.customSw[index].delay = (uint8_t)round(delay*10);
+ model.logicalSw[index].delay = (uint8_t)round(delay*10);
emit modified();
}
}
@@ -190,30 +190,30 @@ void LogicalSwitchesPanel::edited()
if (!lock) {
lock = true;
int i = sender()->property("index").toInt();
- CSFunctionFamily oldFuncFamily = model.customSw[i].getFunctionFamily();
- model.customSw[i].func = csw[i]->itemData(csw[i]->currentIndex()).toInt();
- CSFunctionFamily newFuncFamily = model.customSw[i].getFunctionFamily();
+ CSFunctionFamily oldFuncFamily = model.logicalSw[i].getFunctionFamily();
+ model.logicalSw[i].func = csw[i]->itemData(csw[i]->currentIndex()).toInt();
+ CSFunctionFamily newFuncFamily = model.logicalSw[i].getFunctionFamily();
if (oldFuncFamily != newFuncFamily) {
if (newFuncFamily == LS_FAMILY_TIMER) {
- model.customSw[i].val1 = -119;
- model.customSw[i].val2 = -119;
+ model.logicalSw[i].val1 = -119;
+ model.logicalSw[i].val2 = -119;
}
else if (newFuncFamily == LS_FAMILY_EDGE) {
- model.customSw[i].val1 = 0;
- model.customSw[i].val2 = -129;
- model.customSw[i].val3 = 0;
+ model.logicalSw[i].val1 = 0;
+ model.logicalSw[i].val2 = -129;
+ model.logicalSw[i].val3 = 0;
}
else if (newFuncFamily == LS_FAMILY_STICKY) {
- model.customSw[i].val1 = 0;
- model.customSw[i].val2 = 0;
- model.customSw[i].delay = 0;
+ model.logicalSw[i].val1 = 0;
+ model.logicalSw[i].val2 = 0;
+ model.logicalSw[i].delay = 0;
}
else {
- model.customSw[i].val1 = 0;
- model.customSw[i].val2 = 0;
+ model.logicalSw[i].val1 = 0;
+ model.logicalSw[i].val2 = 0;
}
- model.customSw[i].andsw = 0;
+ model.logicalSw[i].andsw = 0;
setSwitchWidgetVisibility(i);
}
@@ -223,11 +223,11 @@ void LogicalSwitchesPanel::edited()
{
case LS_FAMILY_VOFS:
{
- source = RawSource(model.customSw[i].val1);
- RawSourceRange range = source.getRange(model, generalSettings, model.customSw[i].getRangeFlags());
+ source = RawSource(model.logicalSw[i].val1);
+ RawSourceRange range = source.getRange(model, generalSettings, model.logicalSw[i].getRangeFlags());
double value = source.isTimeBased() ? QTimeS(cswitchTOffset[i]->time()).seconds() : cswitchOffset[i]->value();
- model.customSw[i].val2 = round((value-range.offset)/range.step);;
- value = model.customSw[i].val2*range.step + range.offset;
+ model.logicalSw[i].val2 = round((value-range.offset)/range.step);;
+ value = model.logicalSw[i].val2*range.step + range.offset;
if (source.isTimeBased())
cswitchTOffset[i]->setTime(QTimeS(round(value)));
else
@@ -235,22 +235,22 @@ void LogicalSwitchesPanel::edited()
break;
}
case LS_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, 0.1);
- updateTimerParam(cswitchOffset[i], model.customSw[i].val2, 0.1);
+ model.logicalSw[i].val1 = TimToVal(cswitchValue[i]->value());
+ model.logicalSw[i].val2 = TimToVal(cswitchOffset[i]->value());
+ updateTimerParam(cswitchValue[i], model.logicalSw[i].val1, 0.1);
+ updateTimerParam(cswitchOffset[i], model.logicalSw[i].val2, 0.1);
break;
case LS_FAMILY_EDGE:
cswitchOffset2[i]->setSpecialValueText(tr("(no release)"));
if (sender() == cswitchOffset[i]) {
- model.customSw[i].val2 = TimToVal(cswitchOffset[i]->value());
- updateTimerParam(cswitchOffset[i], model.customSw[i].val2, 0.0);
+ model.logicalSw[i].val2 = TimToVal(cswitchOffset[i]->value());
+ updateTimerParam(cswitchOffset[i], model.logicalSw[i].val2, 0.0);
}
else {
- model.customSw[i].val3 = TimToVal(cswitchOffset2[i]->value()) - model.customSw[i].val2;
+ model.logicalSw[i].val3 = TimToVal(cswitchOffset2[i]->value()) - model.logicalSw[i].val2;
}
- updateTimerParam(cswitchOffset2[i], model.customSw[i].val2+model.customSw[i].val3, cswitchOffset[i]->value()-0.1);
- if (model.customSw[i].val3 == 0) {
+ updateTimerParam(cswitchOffset2[i], model.logicalSw[i].val2+model.logicalSw[i].val3, cswitchOffset[i]->value()-0.1);
+ if (model.logicalSw[i].val3 == 0) {
cswitchOffset2[i]->setSuffix("(infinite)");
}
else {
@@ -294,10 +294,10 @@ void LogicalSwitchesPanel::setSwitchWidgetVisibility(int i)
lock = true;
unsigned int mask = DELAY_ENABLED;
- RawSource source = RawSource(model.customSw[i].val1);
- RawSourceRange range = source.getRange(model, generalSettings, model.customSw[i].getRangeFlags());
+ RawSource source = RawSource(model.logicalSw[i].val1);
+ RawSourceRange range = source.getRange(model, generalSettings, model.logicalSw[i].getRangeFlags());
- switch (model.customSw[i].getFunctionFamily())
+ switch (model.logicalSw[i].getFunctionFamily())
{
case LS_FAMILY_VOFS:
mask |= SOURCE1_VISIBLE;
@@ -307,7 +307,7 @@ void LogicalSwitchesPanel::setSwitchWidgetVisibility(int i)
if (source.isTimeBased()) {
mask |= VALUE_TO_VISIBLE;
int maxTime = round(range.max);
- int value = round(range.step*model.customSw[i].val2 + range.offset);
+ int value = round(range.step*model.logicalSw[i].val2 + range.offset);
cswitchTOffset[i]->setMaximumTime(QTimeS(maxTime));
cswitchTOffset[i]->setDisplayFormat((maxTime>=3600)?"hh:mm:ss":"mm:ss");
cswitchTOffset[i]->setTime(QTimeS(value));
@@ -320,24 +320,24 @@ void LogicalSwitchesPanel::setSwitchWidgetVisibility(int i)
cswitchOffset[i]->setSuffix(" " + range.unit);
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);
+ cswitchOffset[i]->setValue(range.step*(model.logicalSw[i].val2/* TODO+source.getRawOffset(model)*/)+range.offset);
}
break;
case LS_FAMILY_STICKY:
// no break
case LS_FAMILY_VBOOL:
mask |= SOURCE1_VISIBLE | SOURCE2_VISIBLE;
- populateSwitchCB(cswitchSource1[i], RawSwitch(model.customSw[i].val1), generalSettings, LogicalSwitchesContext);
- populateSwitchCB(cswitchSource2[i], RawSwitch(model.customSw[i].val2), generalSettings, LogicalSwitchesContext);
+ populateSwitchCB(cswitchSource1[i], RawSwitch(model.logicalSw[i].val1), generalSettings, LogicalSwitchesContext);
+ populateSwitchCB(cswitchSource2[i], RawSwitch(model.logicalSw[i].val2), generalSettings, LogicalSwitchesContext);
break;
case LS_FAMILY_EDGE:
mask |= SOURCE1_VISIBLE | VALUE2_VISIBLE | VALUE3_VISIBLE;
mask &= ~DELAY_ENABLED;
- populateSwitchCB(cswitchSource1[i], RawSwitch(model.customSw[i].val1), generalSettings, LogicalSwitchesContext);
- updateTimerParam(cswitchOffset[i], model.customSw[i].val2, 0.0);
- updateTimerParam(cswitchOffset2[i], model.customSw[i].val2+model.customSw[i].val3, cswitchOffset[i]->value()-0.1);
+ populateSwitchCB(cswitchSource1[i], RawSwitch(model.logicalSw[i].val1), generalSettings, LogicalSwitchesContext);
+ updateTimerParam(cswitchOffset[i], model.logicalSw[i].val2, 0.0);
+ updateTimerParam(cswitchOffset2[i], model.logicalSw[i].val2+model.logicalSw[i].val3, cswitchOffset[i]->value()-0.1);
cswitchOffset2[i]->setSpecialValueText(tr("(no release)"));
- if (model.customSw[i].val3 == 0) {
+ if (model.logicalSw[i].val3 == 0) {
cswitchOffset2[i]->setSuffix(tr("(infinite)"));
}
else {
@@ -346,13 +346,13 @@ void LogicalSwitchesPanel::setSwitchWidgetVisibility(int i)
break;
case LS_FAMILY_VCOMP:
mask |= SOURCE1_VISIBLE | SOURCE2_VISIBLE;
- populateSourceCB(cswitchSource1[i], RawSource(model.customSw[i].val1), model, POPULATE_SOURCES | POPULATE_SCRIPT_OUTPUTS | POPULATE_VIRTUAL_INPUTS | POPULATE_TRIMS | POPULATE_SWITCHES | POPULATE_TELEMETRY | (firmware->getCapability(GvarsInCS) ? POPULATE_GVARS : 0));
- populateSourceCB(cswitchSource2[i], RawSource(model.customSw[i].val2), model, POPULATE_SOURCES | POPULATE_SCRIPT_OUTPUTS | POPULATE_VIRTUAL_INPUTS | POPULATE_TRIMS | POPULATE_SWITCHES | POPULATE_TELEMETRY | (firmware->getCapability(GvarsInCS) ? POPULATE_GVARS : 0));
+ populateSourceCB(cswitchSource1[i], RawSource(model.logicalSw[i].val1), model, POPULATE_SOURCES | POPULATE_SCRIPT_OUTPUTS | POPULATE_VIRTUAL_INPUTS | POPULATE_TRIMS | POPULATE_SWITCHES | POPULATE_TELEMETRY | (firmware->getCapability(GvarsInCS) ? POPULATE_GVARS : 0));
+ populateSourceCB(cswitchSource2[i], RawSource(model.logicalSw[i].val2), model, POPULATE_SOURCES | POPULATE_SCRIPT_OUTPUTS | POPULATE_VIRTUAL_INPUTS | POPULATE_TRIMS | POPULATE_SWITCHES | POPULATE_TELEMETRY | (firmware->getCapability(GvarsInCS) ? POPULATE_GVARS : 0));
break;
case LS_FAMILY_TIMER:
mask |= VALUE1_VISIBLE | VALUE2_VISIBLE;
- updateTimerParam(cswitchValue[i], model.customSw[i].val1, 0.1);
- updateTimerParam(cswitchOffset[i], model.customSw[i].val2, 0.1);
+ updateTimerParam(cswitchValue[i], model.logicalSw[i].val1, 0.1);
+ updateTimerParam(cswitchOffset[i], model.logicalSw[i].val2, 0.1);
break;
}
@@ -364,8 +364,8 @@ void LogicalSwitchesPanel::setSwitchWidgetVisibility(int i)
cswitchTOffset[i]->setVisible(mask & VALUE_TO_VISIBLE);
if (firmware->getCapability(LogicalSwitchesExt)) {
cswitchDelay[i]->setEnabled(mask & DELAY_ENABLED);
- cswitchDuration[i]->setValue(model.customSw[i].duration/10.0);
- cswitchDelay[i]->setValue(model.customSw[i].delay/10.0);
+ cswitchDuration[i]->setValue(model.logicalSw[i].duration/10.0);
+ cswitchDelay[i]->setValue(model.logicalSw[i].delay/10.0);
}
lock = false;
}
@@ -445,11 +445,11 @@ void LogicalSwitchesPanel::populateAndSwitchCB(QComboBox *b, const RawSwitch & v
void LogicalSwitchesPanel::updateLine(int i)
{
lock = true;
- populateCSWCB(csw[i], model.customSw[i].func);
+ populateCSWCB(csw[i], model.logicalSw[i].func);
lock = true;
setSwitchWidgetVisibility(i);
lock = true;
- populateAndSwitchCB(cswitchAnd[i], RawSwitch(model.customSw[i].andsw));
+ populateAndSwitchCB(cswitchAnd[i], RawSwitch(model.logicalSw[i].andsw));
lock = false;
}
@@ -466,7 +466,7 @@ void LogicalSwitchesPanel::cswPaste()
const QMimeData *mimeData = clipboard->mimeData();
if (mimeData->hasFormat("application/x-companion-csw")) {
QByteArray cswData = mimeData->data("application/x-companion-csw");
- LogicalSwitchData *csw = &model.customSw[selectedSwitch];
+ LogicalSwitchData *csw = &model.logicalSw[selectedSwitch];
memcpy(csw, cswData.mid(0, sizeof(LogicalSwitchData)).constData(), sizeof(LogicalSwitchData));
emit modified();
updateLine(selectedSwitch);
@@ -475,7 +475,7 @@ void LogicalSwitchesPanel::cswPaste()
void LogicalSwitchesPanel::cswDelete()
{
- model.customSw[selectedSwitch].clear();
+ model.logicalSw[selectedSwitch].clear();
emit modified();
updateLine(selectedSwitch);
}
@@ -483,7 +483,7 @@ void LogicalSwitchesPanel::cswDelete()
void LogicalSwitchesPanel::cswCopy()
{
QByteArray cswData;
- cswData.append((char*)&model.customSw[selectedSwitch],sizeof(LogicalSwitchData));
+ cswData.append((char*)&model.logicalSw[selectedSwitch],sizeof(LogicalSwitchData));
QMimeData *mimeData = new QMimeData;
mimeData->setData("application/x-companion-csw", cswData);
QApplication::clipboard()->setMimeData(mimeData,QClipboard::Clipboard);
diff --git a/companion/src/modeledit/templates.cpp b/companion/src/modeledit/templates.cpp
index de4175349..30b383ff6 100644
--- a/companion/src/modeledit/templates.cpp
+++ b/companion/src/modeledit/templates.cpp
@@ -60,9 +60,9 @@ Templates::~Templates()
void Templates::setSwitch(unsigned int idx, unsigned int func, int v1, int v2)
{
- g_model.customSw[idx-1].func = func;
- g_model.customSw[idx-1].val1 = v1;
- g_model.customSw[idx-1].val2 = v2;
+ g_model.logicalSw[idx-1].func = func;
+ g_model.logicalSw[idx-1].val1 = v1;
+ g_model.logicalSw[idx-1].val2 = v2;
}
void Templates::onDoubleClicked(QModelIndex index)
diff --git a/companion/src/printdialog.cpp b/companion/src/printdialog.cpp
index 15b208b88..02b94c223 100644
--- a/companion/src/printdialog.cpp
+++ b/companion/src/printdialog.cpp
@@ -577,10 +577,10 @@ void PrintDialog::printSwitches()
str.append("");
for (int i=0; igetCapability(LogicalSwitches); i++) {
- if (g_model->customSw[i].func) {
+ if (g_model->logicalSw[i].func) {
str.append("");
str.append(""+tr("L")+QString("%1 | ").arg(i+1));
- QString tstr = g_model->customSw[i].toString(*g_model, *g_eeGeneral);
+ QString tstr = g_model->logicalSw[i].toString(*g_model, *g_eeGeneral);
str.append(doTL(tstr,"green"));
str.append(" ");
sc++;
@@ -630,21 +630,21 @@ void PrintDialog::printFSwitches()
str.append(doTL(tr("Enabled"), "", true));
str.append("");
for(int i=0; igetCapability(CustomFunctions); i++) {
- if (g_model->funcSw[i].swtch.type!=SWITCH_TYPE_NONE) {
+ if (g_model->customFn[i].swtch.type!=SWITCH_TYPE_NONE) {
str.append("");
str.append(doTL(tr("SF%1").arg(i+1),"", true));
- str.append(doTL(g_model->funcSw[i].swtch.toString(),"green"));
- str.append(doTL(g_model->funcSw[i].funcToString(),"green"));
- str.append(doTL(g_model->funcSw[i].paramToString(),"green"));
- int index=g_model->funcSw[i].func;
- if ((g_model->funcSw[i].repeatParam>0) &&
+ str.append(doTL(g_model->customFn[i].swtch.toString(),"green"));
+ str.append(doTL(g_model->customFn[i].funcToString(),"green"));
+ str.append(doTL(g_model->customFn[i].paramToString(),"green"));
+ int index=g_model->customFn[i].func;
+ if ((g_model->customFn[i].repeatParam>0) &&
(index==FuncPlaySound || index==FuncPlayHaptic || index==FuncPlayValue || index==FuncPlayPrompt || index==FuncPlayBoth || index==FuncBackgroundMusic)) {
- str.append(doTL(QString("%1").arg(g_model->funcSw[i].repeatParam),"green"));
+ str.append(doTL(QString("%1").arg(g_model->customFn[i].repeatParam),"green"));
} else {
str.append(doTL( " ","green"));
}
if ((index<=FuncInstantTrim) || (index>FuncBackgroundMusicPause)) {
- str.append(doTL((g_model->funcSw[i].enabled ? "ON" : "OFF"),"green"));
+ str.append(doTL((g_model->customFn[i].enabled ? "ON" : "OFF"),"green"));
} else {
str.append(doTL( "---","green"));
}
diff --git a/companion/src/wizarddata.cpp b/companion/src/wizarddata.cpp
index 62a9f1c7c..b9764892d 100644
--- a/companion/src/wizarddata.cpp
+++ b/companion/src/wizarddata.cpp
@@ -110,11 +110,11 @@ WizMix::operator ModelData()
// Add the Throttle Cut option
if( options[THROTTLE_CUT_OPTION] && throttleChannel >=0 ){
- model.funcSw[switchIndex].swtch.type = SWITCH_TYPE_SWITCH;
- model.funcSw[switchIndex].swtch.index = isTaranis ? SWITCH_SF0 : SWITCH_THR;
- model.funcSw[switchIndex].enabled = 1;
- model.funcSw[switchIndex].func = (AssignFunc)throttleChannel;
- model.funcSw[switchIndex].param = -100;
+ model.customFn[switchIndex].swtch.type = SWITCH_TYPE_SWITCH;
+ model.customFn[switchIndex].swtch.index = isTaranis ? SWITCH_SF0 : SWITCH_THR;
+ model.customFn[switchIndex].enabled = 1;
+ model.customFn[switchIndex].func = (AssignFunc)throttleChannel;
+ model.customFn[switchIndex].param = -100;
}
// Add the Flight Timer option
diff --git a/radio/src/Makefile b/radio/src/Makefile
index 677365c4a..8ae616996 100644
--- a/radio/src/Makefile
+++ b/radio/src/Makefile
@@ -820,7 +820,7 @@ else
TTS_SRC = $(shell sh -c "if test -f $(STD_TTS_SRC); then echo $(STD_TTS_SRC); else echo translations/tts_en.cpp; fi")
endif
-CPPSRC += opentx.cpp strhelpers.cpp $(PULSESSRC) switches.cpp curves.cpp mixer.cpp stamp.cpp gui/menus.cpp gui/menu_model.cpp gui/menu_general.cpp gui/view_main.cpp gui/view_statistics.cpp $(EEPROMSRC) $(LCDSRC) keys.cpp maths.cpp translations.cpp fonts.cpp $(TTS_SRC)
+CPPSRC += opentx.cpp functions.cpp strhelpers.cpp $(PULSESSRC) switches.cpp curves.cpp mixer.cpp stamp.cpp gui/menus.cpp gui/menu_model.cpp gui/menu_general.cpp gui/view_main.cpp gui/view_statistics.cpp $(EEPROMSRC) $(LCDSRC) keys.cpp maths.cpp translations.cpp fonts.cpp $(TTS_SRC)
# Debugging format.
# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
diff --git a/radio/src/eeprom_conversions.cpp b/radio/src/eeprom_conversions.cpp
index 00adb9ade..59dd3f776 100644
--- a/radio/src/eeprom_conversions.cpp
+++ b/radio/src/eeprom_conversions.cpp
@@ -303,7 +303,7 @@ PACK(typedef struct {
}) param;
uint8_t mode:2;
uint8_t active:6;
-}) CustomFnData_v215;
+}) CustomFunctionData_v215;
#else
PACK(typedef struct {
int8_t swtch;
@@ -318,7 +318,7 @@ PACK(typedef struct {
}) param;
uint8_t mode:2;
uint8_t active:6;
-}) CustomFnData_v215;
+}) CustomFunctionData_v215;
#endif
PACK(typedef struct {
@@ -365,7 +365,7 @@ PACK(typedef struct {
int8_t points[NUM_POINTS];
LogicalSwitchData_v215 logicalSw[NUM_LOGICAL_SWITCH];
- CustomFnData_v215 funcSw[32];
+ CustomFunctionData_v215 customFn[32];
SwashRingData swashR;
FlightModeData_v215 flightModeData[MAX_FLIGHT_MODES];
@@ -407,7 +407,7 @@ PACK(typedef struct {
int8_t points[NUM_POINTS];
LogicalSwitchData logicalSw[NUM_LOGICAL_SWITCH];
- CustomFnData funcSw[NUM_CFN];
+ CustomFunctionData customFn[NUM_CFN];
SwashRingData swashR;
FlightModeData flightModeData[MAX_FLIGHT_MODES];
@@ -950,9 +950,9 @@ void ConvertModel_215_to_216(ModelData &model)
}
}
for (uint8_t i=0; i<32; i++) {
- CustomFnData & fn = newModel.funcSw[i];
- fn.swtch = ConvertSwitch_215_to_216(oldModel.funcSw[i].swtch);
- fn.func = oldModel.funcSw[i].func;
+ CustomFunctionData & fn = newModel.customFn[i];
+ fn.swtch = ConvertSwitch_215_to_216(oldModel.customFn[i].swtch);
+ fn.func = oldModel.customFn[i].func;
if (fn.func <= 15) {
fn.all.param = fn.func;
fn.func = FUNC_OVERRIDE_CHANNEL;
@@ -1001,20 +1001,20 @@ void ConvertModel_215_to_216(ModelData &model)
}
else {
fn.all.param = fn.func - 32 - IS_PCBSKY9X;
- fn.all.mode = oldModel.funcSw[i].mode;
+ fn.all.mode = oldModel.customFn[i].mode;
fn.func = FUNC_ADJUST_GVAR;
}
- fn.active = oldModel.funcSw[i].active;
+ fn.active = oldModel.customFn[i].active;
if (HAS_REPEAT_PARAM(fn.func)) {
fn.active *= 5;
}
if (fn.func == FUNC_PLAY_TRACK || fn.func == FUNC_BACKGND_MUSIC) {
- memcpy(fn.play.name, oldModel.funcSw[i].param.name, 8);
+ memcpy(fn.play.name, oldModel.customFn[i].param.name, 8);
}
else {
- fn.all.val = oldModel.funcSw[i].param.composite.val;
+ fn.all.val = oldModel.customFn[i].param.composite.val;
}
if (fn.func == FUNC_PLAY_VALUE || fn.func == FUNC_VOLUME || (IS_ADJUST_GV_FUNC(fn.func) && fn.all.mode == FUNC_ADJUST_GVAR_SOURCE)) {
#if defined(PCBTARANIS)
@@ -1199,8 +1199,8 @@ void ConvertModel_216_to_217(ModelData &model)
}
}
for (int i=0; i
+ * - Andreas Weitl
+ * - Bertrand Songis
+ * - Bryan J. Rentoul (Gruvin)
+ * - Cameron Weeks
+ * - Erez Raviv
+ * - Gabriel Birkus
+ * - Jean-Pierre Parisy
+ * - Karl Szmutny
+ * - Michael Blandford
+ * - Michal Hlavinka
+ * - Pat Mackenzie
+ * - Philip Moss
+ * - Rob Thomson
+ * - Romolo Manfredini
+ * - Thomas Husterer
+ *
+ * opentx is based on code named
+ * gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
+ * er9x by Erez Raviv: http://code.google.com/p/er9x/,
+ * and the original (and ongoing) project by
+ * Thomas Husterer, th9x: http://code.google.com/p/th9x/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "opentx.h"
+
+CustomFunctionsContext modelFunctionsContext = { 0 };
+
+#if defined(CPUARM)
+CustomFunctionsContext globalFunctionsContext = { 0 };
+#endif
+
+
+#if defined(DEBUG)
+/*
+ * This is a test function for debugging purpose, you may insert there your code and compile with the option DEBUG=YES
+ */
+void testFunc()
+{
+#ifdef SIMU
+ printf("testFunc\n"); fflush(stdout);
+#endif
+}
+#endif
+
+#if defined(VOICE)
+PLAY_FUNCTION(playValue, uint8_t idx)
+{
+ if (IS_FAI_FORBIDDEN(idx))
+ return;
+
+ getvalue_t val = getValue(idx);
+
+ switch (idx) {
+#if defined(CPUARM)
+ case MIXSRC_FIRST_TELEM+TELEM_TX_TIME-1:
+ PLAY_DURATION(val*60, PLAY_TIME);
+ break;
+#endif
+ case MIXSRC_FIRST_TELEM+TELEM_TX_VOLTAGE-1:
+ PLAY_NUMBER(val, 1+UNIT_VOLTS, PREC1);
+ break;
+ case MIXSRC_FIRST_TELEM+TELEM_TIMER1-1:
+ case MIXSRC_FIRST_TELEM+TELEM_TIMER2-1:
+#if defined(CPUARM)
+ case MIXSRC_FIRST_TELEM+TELEM_TIMER3-1:
+#endif
+ PLAY_DURATION(val, 0);
+ break;
+#if defined(CPUARM) && defined(FRSKY)
+ case MIXSRC_FIRST_TELEM+TELEM_SWR-1:
+ PLAY_NUMBER(val, 0, 0);
+ break;
+#endif
+#if defined(FRSKY)
+ case MIXSRC_FIRST_TELEM+TELEM_RSSI_TX-1:
+ case MIXSRC_FIRST_TELEM+TELEM_RSSI_RX-1:
+ PLAY_NUMBER(val, 1+UNIT_DBM, 0);
+ break;
+ case MIXSRC_FIRST_TELEM+TELEM_MIN_A1-1:
+ case MIXSRC_FIRST_TELEM+TELEM_MIN_A2-1:
+#if defined(CPUARM)
+ case MIXSRC_FIRST_TELEM+TELEM_MIN_A3-1:
+ case MIXSRC_FIRST_TELEM+TELEM_MIN_A4-1:
+#endif
+ idx -= TELEM_MIN_A1-TELEM_A1;
+ // no break
+ case MIXSRC_FIRST_TELEM+TELEM_A1-1:
+ case MIXSRC_FIRST_TELEM+TELEM_A2-1:
+#if defined(CPUARM)
+ case MIXSRC_FIRST_TELEM+TELEM_A3-1:
+ case MIXSRC_FIRST_TELEM+TELEM_A4-1:
+#endif
+ if (TELEMETRY_STREAMING()) {
+ idx -= (MIXSRC_FIRST_TELEM+TELEM_A1-1);
+ uint8_t att = 0;
+ int16_t converted_value = div10_and_round(applyChannelRatio(idx, val));;
+ if (ANA_CHANNEL_UNIT(idx) < UNIT_RAW) {
+ att = PREC1;
+ }
+ PLAY_NUMBER(converted_value, 1+ANA_CHANNEL_UNIT(idx), att);
+ }
+ break;
+ case MIXSRC_FIRST_TELEM+TELEM_CELL-1:
+ case MIXSRC_FIRST_TELEM+TELEM_MIN_CELL-1:
+ PLAY_NUMBER(div10_and_round(val), 1+UNIT_VOLTS, PREC1);
+ break;
+
+ case MIXSRC_FIRST_TELEM+TELEM_VFAS-1:
+ case MIXSRC_FIRST_TELEM+TELEM_CELLS_SUM-1:
+ case MIXSRC_FIRST_TELEM+TELEM_MIN_CELLS_SUM-1:
+ case MIXSRC_FIRST_TELEM+TELEM_MIN_VFAS-1:
+ PLAY_NUMBER(val, 1+UNIT_VOLTS, PREC1);
+ break;
+
+ case MIXSRC_FIRST_TELEM+TELEM_CURRENT-1:
+ case MIXSRC_FIRST_TELEM+TELEM_MAX_CURRENT-1:
+ PLAY_NUMBER(val, 1+UNIT_AMPS, PREC1);
+ break;
+
+ case MIXSRC_FIRST_TELEM+TELEM_ACCx-1:
+ case MIXSRC_FIRST_TELEM+TELEM_ACCy-1:
+ case MIXSRC_FIRST_TELEM+TELEM_ACCz-1:
+ PLAY_NUMBER(div10_and_round(val), 1+UNIT_G, PREC1);
+ break;
+
+ case MIXSRC_FIRST_TELEM+TELEM_VSPEED-1:
+ PLAY_NUMBER(div10_and_round(val), 1+UNIT_METERS_PER_SECOND, PREC1);
+ break;
+
+ case MIXSRC_FIRST_TELEM+TELEM_ASPEED-1:
+ case MIXSRC_FIRST_TELEM+TELEM_MAX_ASPEED-1:
+ PLAY_NUMBER(val/10, 1+UNIT_KTS, 0);
+ break;
+
+ case MIXSRC_FIRST_TELEM+TELEM_CONSUMPTION-1:
+ PLAY_NUMBER(val, 1+UNIT_MAH, 0);
+ break;
+
+ case MIXSRC_FIRST_TELEM+TELEM_POWER-1:
+ PLAY_NUMBER(val, 1+UNIT_WATTS, 0);
+ break;
+
+ case MIXSRC_FIRST_TELEM+TELEM_ALT-1:
+#if defined(PCBTARANIS)
+ PLAY_NUMBER(div10_and_round(val), 1+UNIT_DIST, PREC1);
+ break;
+#endif
+ case MIXSRC_FIRST_TELEM+TELEM_MIN_ALT-1:
+ case MIXSRC_FIRST_TELEM+TELEM_MAX_ALT-1:
+#if defined(WS_HOW_HIGH)
+ if (IS_IMPERIAL_ENABLE() && IS_USR_PROTO_WS_HOW_HIGH())
+ PLAY_NUMBER(val, 1+UNIT_FEET, 0);
+ else
+#endif
+ PLAY_NUMBER(val, 1+UNIT_DIST, 0);
+ break;
+
+ case MIXSRC_FIRST_TELEM+TELEM_RPM-1:
+ case MIXSRC_FIRST_TELEM+TELEM_MAX_RPM-1:
+ {
+ getvalue_t rpm = val;
+ if (rpm > 100)
+ rpm = 10 * div10_and_round(rpm);
+ if (rpm > 1000)
+ rpm = 10 * div10_and_round(rpm);
+ PLAY_NUMBER(rpm, 1+UNIT_RPMS, 0);
+ break;
+ }
+
+ case MIXSRC_FIRST_TELEM+TELEM_HDG-1:
+ PLAY_NUMBER(val, 1+UNIT_HDG, 0);
+ break;
+
+ default:
+ {
+ uint8_t unit = 1;
+ if (idx < MIXSRC_GVAR1)
+ val = calcRESXto100(val);
+ if (idx >= MIXSRC_FIRST_TELEM+TELEM_ALT-1 && idx <= MIXSRC_FIRST_TELEM+TELEM_GPSALT-1)
+ unit = idx - (MIXSRC_FIRST_TELEM+TELEM_ALT-1);
+ else if (idx >= MIXSRC_FIRST_TELEM+TELEM_MAX_T1-1 && idx <= MIXSRC_FIRST_TELEM+TELEM_MAX_DIST-1)
+ unit = 3 + idx - (MIXSRC_FIRST_TELEM+TELEM_MAX_T1-1);
+
+ unit = pgm_read_byte(bchunit_ar+unit);
+ PLAY_NUMBER(val, unit == UNIT_RAW ? 0 : unit+1, 0);
+ break;
+ }
+#else
+ default:
+ {
+ PLAY_NUMBER(val, 0, 0);
+ break;
+ }
+#endif
+ }
+}
+#endif
+
+#if defined(CPUARM)
+void playCustomFunctionFile(const CustomFunctionData *sd, uint8_t id)
+{
+ if (sd->play.name[0] != '\0') {
+ 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->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);
+ }
+}
+#endif
+
+#if defined(CPUARM)
+#define VOLUME_HYSTERESIS 10 // how much must a input value change to actually be considered for new volume setting
+getvalue_t requiredSpeakerVolumeRawLast = 1024 + 1; //initial value must be outside normal range
+#endif
+
+#if defined(CPUARM)
+void evalFunctions(const CustomFunctionData * functions, CustomFunctionsContext & functionsContext)
+#else
+#define functions g_model.customFn
+#define functionsContext modelFunctionsContext
+void evalFunctions()
+#endif
+{
+ MASK_FUNC_TYPE newActiveFunctions = 0;
+ MASK_CFN_TYPE newActiveSwitches = 0;
+
+#if defined(ROTARY_ENCODERS) && defined(GVARS)
+ static rotenc_t rePreviousValues[ROTARY_ENCODERS];
+#endif
+
+#if defined(OVERRIDE_CHANNEL_FUNCTION)
+ for (uint8_t i=0; i 0) {
+ mask = (1<<(CFN_CH_INDEX(cfn)-1));
+ }
+ newActiveFunctions |= mask;
+ break;
+ }
+
+ case FUNC_INSTANT_TRIM:
+ newActiveFunctions |= (1 << FUNCTION_INSTANT_TRIM);
+ if (!isFunctionActive(FUNCTION_INSTANT_TRIM)) {
+ if (g_menuStack[0] == menuMainView
+#if defined(FRSKY)
+ || g_menuStack[0] == menuTelemetryFrsky
+#endif
+#if defined(PCBTARANIS)
+ || g_menuStack[0] == menuMainViewChannelsMonitor
+ || g_menuStack[0] == menuChannelsView
+#endif
+ ) {
+ instantTrim();
+ }
+ }
+ break;
+
+ case FUNC_RESET:
+ switch (CFN_PARAM(cfn)) {
+ case FUNC_RESET_TIMER1:
+ case FUNC_RESET_TIMER2:
+#if defined(CPUARM)
+ case FUNC_RESET_TIMER3:
+#endif
+ timerReset(CFN_PARAM(cfn));
+ break;
+ case FUNC_RESET_FLIGHT:
+ flightReset();
+ break;
+#if defined(FRSKY)
+ case FUNC_RESET_TELEMETRY:
+ telemetryReset();
+ break;
+#endif
+#if ROTARY_ENCODERS > 0
+ case FUNC_RESET_ROTENC1:
+#if ROTARY_ENCODERS > 1
+ case FUNC_RESET_ROTENC2:
+#endif
+ g_rotenc[CFN_PARAM(cfn)-FUNC_RESET_ROTENC1] = 0;
+ break;
+#endif
+ }
+ break;
+
+#if defined(CPUARM)
+ case FUNC_SET_TIMER:
+ {
+ TimerState & timerState = timersStates[CFN_TIMER_INDEX(cfn)];
+ timerState.state = TMR_OFF; // is changed to RUNNING dep from mode
+ timerState.val = CFN_PARAM(cfn);
+ timerState.val_10ms = 0 ;
+ break;
+ }
+#endif
+
+#if defined(GVARS)
+ case FUNC_ADJUST_GVAR:
+ if (CFN_GVAR_MODE(cfn) == 0) {
+ SET_GVAR(CFN_GVAR_INDEX(cfn), CFN_PARAM(cfn), mixerCurrentFlightMode);
+ }
+ else if (CFN_GVAR_MODE(cfn) == 2) {
+ SET_GVAR(CFN_GVAR_INDEX(cfn), GVAR_VALUE(CFN_PARAM(cfn), mixerCurrentFlightMode), mixerCurrentFlightMode);
+ }
+ else if (CFN_GVAR_MODE(cfn) == 3) {
+ if (!(functionsContext.activeSwitches & switch_mask)) {
+ SET_GVAR(CFN_GVAR_INDEX(cfn), GVAR_VALUE(CFN_GVAR_INDEX(cfn), getGVarFlightPhase(mixerCurrentFlightMode, CFN_GVAR_INDEX(cfn))) + (CFN_PARAM(cfn) ? +1 : -1), mixerCurrentFlightMode);
+ }
+ }
+ else if (CFN_PARAM(cfn) >= MIXSRC_TrimRud && CFN_PARAM(cfn) <= MIXSRC_TrimAil) {
+ trimGvar[CFN_PARAM(cfn)-MIXSRC_TrimRud] = CFN_GVAR_INDEX(cfn);
+ }
+#if defined(ROTARY_ENCODERS)
+ else if (CFN_PARAM(cfn) >= MIXSRC_REa && CFN_PARAM(cfn) < MIXSRC_TrimRud) {
+ int8_t scroll = rePreviousValues[CFN_PARAM(cfn)-MIXSRC_REa] - (g_rotenc[CFN_PARAM(cfn)-MIXSRC_REa] / ROTARY_ENCODER_GRANULARITY);
+ if (scroll) {
+ SET_GVAR(CFN_GVAR_INDEX(cfn), GVAR_VALUE(CFN_GVAR_INDEX(cfn), getGVarFlightPhase(mixerCurrentFlightMode, CFN_GVAR_INDEX(cfn))) + scroll, mixerCurrentFlightMode);
+ }
+ }
+#endif
+ else {
+ SET_GVAR(CFN_GVAR_INDEX(cfn), calcRESXto100(getValue(CFN_PARAM(cfn))), mixerCurrentFlightMode);
+ }
+ break;
+#endif
+
+#if defined(CPUARM) && defined(SDCARD)
+ case FUNC_VOLUME:
+ {
+ getvalue_t raw = getValue(CFN_PARAM(cfn));
+ //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:
+#if defined(HAPTIC)
+ case FUNC_HAPTIC:
+#endif
+ {
+ tmr10ms_t tmr10ms = get_tmr10ms();
+ uint8_t repeatParam = CFN_PLAY_REPEAT(cfn);
+ if (!IS_SILENCE_PERIOD_ELAPSED() && repeatParam == CFN_PLAY_REPEAT_NOSTART) {
+ functionsContext.lastFunctionTime[i] = tmr10ms;
+ }
+ if (!functionsContext.lastFunctionTime[i] || (repeatParam && repeatParam!=CFN_PLAY_REPEAT_NOSTART && (signed)(tmr10ms-functionsContext.lastFunctionTime[i])>=100*repeatParam)) {
+ if (!IS_PLAYING(i+1)) {
+ functionsContext.lastFunctionTime[i] = tmr10ms;
+ if (CFN_FUNC(cfn) == FUNC_PLAY_SOUND) {
+ AUDIO_PLAY(AU_FRSKY_FIRST+CFN_PARAM(cfn));
+ }
+ else if (CFN_FUNC(cfn) == FUNC_PLAY_VALUE) {
+ PLAY_VALUE(CFN_PARAM(cfn), i+1);
+ }
+#if defined(HAPTIC)
+ else if (CFN_FUNC(cfn) == FUNC_HAPTIC) {
+ haptic.event(AU_FRSKY_LAST+CFN_PARAM(cfn));
+ }
+#endif
+ else {
+ playCustomFunctionFile(cfn, i+1);
+ }
+ }
+ }
+ break;
+ }
+
+ case FUNC_BACKGND_MUSIC:
+ newActiveFunctions |= (1 << FUNCTION_BACKGND_MUSIC);
+ if (!IS_PLAYING(i+1)) {
+ playCustomFunctionFile(cfn, 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(cfn);
+ if (!functionsContext.lastFunctionTime[i] || (CFN_FUNC(cfn)==FUNC_PLAY_BOTH && active!=(bool)(functionsContext.activeSwitches&switch_mask)) || (repeatParam && (signed)(tmr10ms-functionsContext.lastFunctionTime[i])>=1000*repeatParam)) {
+ functionsContext.lastFunctionTime[i] = tmr10ms;
+ uint8_t param = CFN_PARAM(cfn);
+ if (CFN_FUNC(cfn) == FUNC_PLAY_SOUND) {
+ AUDIO_PLAY(AU_FRSKY_FIRST+param);
+ }
+ else if (CFN_FUNC(cfn) == FUNC_PLAY_VALUE) {
+ PLAY_VALUE(param, i+1);
+ }
+ else {
+#if defined(GVARS)
+ if (CFN_FUNC(cfn) == FUNC_PLAY_TRACK && param > 250)
+ param = GVAR_VALUE(param-251, getGVarFlightPhase(mixerCurrentFlightMode, param-251));
+#endif
+ PUSH_CUSTOM_PROMPT(active ? param : param+1, i+1);
+ }
+ }
+ if (!active) {
+ // PLAY_BOTH would change activeFnSwitches otherwise
+ switch_mask = 0;
+ }
+ break;
+ }
+#else
+ case FUNC_PLAY_SOUND:
+ {
+ tmr10ms_t tmr10ms = get_tmr10ms();
+ uint8_t repeatParam = CFN_PLAY_REPEAT(cfn);
+ if (!functionsContext.lastFunctionTime[i] || (repeatParam && (signed)(tmr10ms-functionsContext.lastFunctionTime[i])>=1000*repeatParam)) {
+ functionsContext.lastFunctionTime[i] = tmr10ms;
+ AUDIO_PLAY(AU_FRSKY_FIRST+CFN_PARAM(cfn));
+ }
+ break;
+ }
+#endif
+
+#if defined(FRSKY) && defined(VARIO)
+ case FUNC_VARIO:
+ newActiveFunctions |= (1 << FUNCTION_VARIO);
+ break;
+#endif
+
+#if defined(HAPTIC) && !defined(CPUARM)
+ case FUNC_HAPTIC:
+ {
+ tmr10ms_t tmr10ms = get_tmr10ms();
+ uint8_t repeatParam = CFN_PLAY_REPEAT(cfn);
+ if (!functionsContext.lastFunctionTime[i] || (repeatParam && (signed)(tmr10ms-functionsContext.lastFunctionTime[i])>=1000*repeatParam)) {
+ functionsContext.lastFunctionTime[i] = tmr10ms;
+ haptic.event(AU_FRSKY_LAST+CFN_PARAM(cfn));
+ }
+ break;
+ }
+#endif
+
+#if defined(SDCARD)
+ case FUNC_LOGS:
+ if (CFN_PARAM(cfn)) {
+ newActiveFunctions |= (1 << FUNCTION_LOGS);
+ logDelay = CFN_PARAM(cfn);
+ }
+ break;
+#endif
+
+ case FUNC_BACKLIGHT:
+ newActiveFunctions |= (1 << FUNCTION_BACKLIGHT);
+ break;
+
+#if defined(DEBUG)
+ case FUNC_TEST:
+ testFunc();
+ break;
+#endif
+ }
+
+ newActiveSwitches |= switch_mask;
+ }
+ else {
+ functionsContext.lastFunctionTime[i] = 0;
+ }
+ }
+ }
+
+ functionsContext.activeSwitches = newActiveSwitches;
+ functionsContext.activeFunctions = newActiveFunctions;
+
+#if defined(ROTARY_ENCODERS) && defined(GVARS)
+ for (uint8_t i=0; i 0)
s_editMode = 0;
@@ -1128,6 +1131,14 @@ void menuGeneralSdManager(uint8_t _event)
}
#endif
+#if defined(CPUARM)
+void menuGeneralCustomFunctions(uint8_t event)
+{
+ MENU(STR_MENUGLOBALFUNCS, menuTabGeneral, e_GeneralCustomFunctions, NUM_CFN+1, {0, NAVIGATION_LINE_BY_LINE|4/*repeated*/});
+ return menuCustomFunctions(event, g_eeGeneral.customFn, globalFunctionsContext);
+}
+#endif
+
#if LCD_W >= 212
#define TRAINER_CALIB_POS 12
#else
@@ -1139,7 +1150,7 @@ void menuGeneralTrainer(uint8_t event)
uint8_t y;
bool slave = SLAVE_MODE();
- MENU(STR_MENUTRAINER, menuTabDiag, e_Trainer, (slave ? 1 : 7), {0, 2, 2, 2, 2, 0/*, 0*/});
+ MENU(STR_MENUTRAINER, menuTabGeneral, e_Trainer, (slave ? 1 : 7), {0, 2, 2, 2, 2, 0/*, 0*/});
if (slave) {
lcd_puts(7*FW, 4*FH, STR_SLAVE);
@@ -1211,7 +1222,7 @@ void menuGeneralTrainer(uint8_t event)
void menuGeneralVersion(uint8_t event)
{
- SIMPLE_MENU(STR_MENUVERSION, menuTabDiag, e_Vers, 1);
+ SIMPLE_MENU(STR_MENUVERSION, menuTabGeneral, e_Vers, 1);
lcd_putsLeft(MENU_TITLE_HEIGHT+FH, vers_stamp);
@@ -1241,7 +1252,7 @@ void displayKeyState(uint8_t x, uint8_t y, EnumKeys key)
void menuGeneralDiagKeys(uint8_t event)
{
- SIMPLE_MENU(STR_MENUDIAG, menuTabDiag, e_Keys, 1);
+ SIMPLE_MENU(STR_MENUDIAG, menuTabGeneral, e_Keys, 1);
lcd_puts(14*FW, MENU_TITLE_HEIGHT+2*FH, STR_VTRIM);
@@ -1289,7 +1300,7 @@ void menuGeneralDiagAna(uint8_t event)
#define ANAS_ITEMS_COUNT 2
#endif
- SIMPLE_MENU(STR_MENUANA, menuTabDiag, e_Ana, ANAS_ITEMS_COUNT);
+ SIMPLE_MENU(STR_MENUANA, menuTabGeneral, e_Ana, ANAS_ITEMS_COUNT);
STICK_SCROLL_DISABLE();
@@ -1362,7 +1373,7 @@ enum menuGeneralHwItems {
void menuGeneralHardware(uint8_t event)
{
- MENU(STR_HARDWARE, menuTabDiag, e_Hardware, ITEM_SETUP_HW_MAX+1, {0});
+ MENU(STR_HARDWARE, menuTabGeneral, e_Hardware, ITEM_SETUP_HW_MAX+1, {0});
uint8_t sub = m_posVert - 1;
@@ -1417,7 +1428,7 @@ enum menuGeneralHwItems {
#define GENERAL_HW_PARAM_OFS (2+(15*FW))
void menuGeneralHardware(uint8_t event)
{
- MENU(STR_HARDWARE, menuTabDiag, e_Hardware, ITEM_SETUP_HW_MAX+1, {0, 0, (uint8_t)-1, 0, 0, 0, IF_ROTARY_ENCODERS(0) CASE_BLUETOOTH(0)});
+ MENU(STR_HARDWARE, menuTabGeneral, e_Hardware, ITEM_SETUP_HW_MAX+1, {0, 0, (uint8_t)-1, 0, 0, 0, IF_ROTARY_ENCODERS(0) CASE_BLUETOOTH(0)});
uint8_t sub = m_posVert - 1;
@@ -1636,7 +1647,7 @@ void menuCommonCalib(uint8_t event)
void menuGeneralCalib(uint8_t event)
{
- check_simple(event, e_Calib, menuTabDiag, DIM(menuTabDiag), 0);
+ check_simple(event, e_Calib, menuTabGeneral, DIM(menuTabGeneral), 0);
if (menuEvent) {
calibrationState = 0;
diff --git a/radio/src/gui/menu_model.cpp b/radio/src/gui/menu_model.cpp
index e48254c8b..da5edc468 100644
--- a/radio/src/gui/menu_model.cpp
+++ b/radio/src/gui/menu_model.cpp
@@ -4410,18 +4410,18 @@ enum LogicalSwitchFields {
#endif
#if defined(CPUARM)
- #define INCDEC_DECLARE_VARS() uint8_t incdecFlag = EE_MODEL; IsValueAvailable isValueAvailable = NULL
- #define INCDEC_SET_FLAG(f) incdecFlag = (EE_MODEL|(f))
+ #define INCDEC_DECLARE_VARS(f) uint8_t incdecFlag = (f); IsValueAvailable isValueAvailable = NULL
+ #define INCDEC_SET_FLAG(f) incdecFlag = (f)
#define INCDEC_ENABLE_CHECK(fn) isValueAvailable = fn
#define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, incdecFlag, isValueAvailable)
#elif defined(CPUM64)
- #define INCDEC_DECLARE_VARS()
+ #define INCDEC_DECLARE_VARS(f)
#define INCDEC_SET_FLAG(f)
#define INCDEC_ENABLE_CHECK(fn)
#define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, EE_MODEL)
#else
- #define INCDEC_DECLARE_VARS() uint8_t incdecFlag = EE_MODEL
- #define INCDEC_SET_FLAG(f) incdecFlag = (EE_MODEL|(f))
+ #define INCDEC_DECLARE_VARS(f) uint8_t incdecFlag = (f)
+ #define INCDEC_SET_FLAG(f) incdecFlag = (f)
#define INCDEC_ENABLE_CHECK(fn)
#define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, incdecFlag)
#endif
@@ -4458,7 +4458,7 @@ void menuModelLogicalSwitchOne(uint8_t event)
int8_t sub = m_posVert;
- INCDEC_DECLARE_VARS();
+ INCDEC_DECLARE_VARS(EE_MODEL);
int v1_val = cs->v1;
@@ -4502,7 +4502,7 @@ void menuModelLogicalSwitchOne(uint8_t event)
else {
v1_val = (uint8_t)cs->v1;
putsMixerSource(CSWONE_2ND_COLUMN, y, v1_val, attr);
- INCDEC_SET_FLAG(INCDEC_SOURCE);
+ INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable);
}
if (attr) {
@@ -4533,7 +4533,7 @@ void menuModelLogicalSwitchOne(uint8_t event)
}
else if (cstate == LS_FAMILY_COMP) {
putsMixerSource(CSWONE_2ND_COLUMN, y, cs->v2, attr);
- INCDEC_SET_FLAG(INCDEC_SOURCE);
+ INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable);
}
else {
@@ -4547,7 +4547,7 @@ void menuModelLogicalSwitchOne(uint8_t event)
v2_min = 0;
else
v2_min = minTelemValue(v1_val - MIXSRC_FIRST_TELEM + 1);
- INCDEC_SET_FLAG(INCDEC_REP10 | NO_INCDEC_MARKS);
+ INCDEC_SET_FLAG(EE_MODEL | INCDEC_REP10 | NO_INCDEC_MARKS);
if (cs->v2 < v2_min || cs->v2 > v2_max) {
cs->v2 = 0;
eeDirty(EE_MODEL);
@@ -4675,7 +4675,7 @@ struct Clipboard {
ClipboardType type;
union {
LogicalSwitchData csw;
- CustomFnData cfn;
+ CustomFunctionData cfn;
} data;
};
@@ -4703,7 +4703,7 @@ void onLogicalSwitchesMenu(const char *result)
void menuModelLogicalSwitches(uint8_t event)
{
- INCDEC_DECLARE_VARS();
+ INCDEC_DECLARE_VARS(EE_MODEL);
MENU(STR_MENULOGICALSWITCHES, menuTabModel, e_LogicalSwitches, NUM_LOGICAL_SWITCH+1, {0, NAVIGATION_LINE_BY_LINE|LS_FIELD_LAST/*repeated...*/});
@@ -4761,7 +4761,7 @@ void menuModelLogicalSwitches(uint8_t event)
putsSwitches(CSW_3RD_COLUMN, y, cs->v2, attr2);
v1_min = SWSRC_FIRST_IN_LOGICAL_SWITCHES; v1_max = SWSRC_LAST_IN_LOGICAL_SWITCHES;
v2_min = SWSRC_FIRST_IN_LOGICAL_SWITCHES; v2_max = SWSRC_LAST_IN_LOGICAL_SWITCHES;
- INCDEC_SET_FLAG(INCDEC_SWITCH);
+ INCDEC_SET_FLAG(EE_MODEL | INCDEC_SWITCH);
INCDEC_ENABLE_CHECK(isSwitchAvailableInLogicalSwitches);
}
#if defined(CPUARM)
@@ -4772,11 +4772,11 @@ void menuModelLogicalSwitches(uint8_t event)
v2_min=-129; v2_max = 122;
v3_max = 222 - cs->v2;
if (horz == 1) {
- INCDEC_SET_FLAG(INCDEC_SWITCH);
+ INCDEC_SET_FLAG(EE_MODEL | INCDEC_SWITCH);
INCDEC_ENABLE_CHECK(isSwitchAvailableInLogicalSwitches);
}
else {
- INCDEC_SET_FLAG(0);
+ INCDEC_SET_FLAG(EE_MODEL);
INCDEC_ENABLE_CHECK(NULL);
}
}
@@ -4787,7 +4787,7 @@ void menuModelLogicalSwitches(uint8_t event)
#endif
putsMixerSource(CSW_2ND_COLUMN, y, v1_val, attr1);
putsMixerSource(CSW_3RD_COLUMN, y, cs->v2, attr2);
- INCDEC_SET_FLAG(INCDEC_SOURCE);
+ INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable);
}
else if (cstate == LS_FAMILY_TIMER) {
@@ -4795,7 +4795,7 @@ void menuModelLogicalSwitches(uint8_t event)
lcd_outdezAtt(CSW_3RD_COLUMN, y, lswTimerValue(cs->v2), LEFT|PREC1|attr2);
v1_min = v2_min = -128;
v1_max = v2_max = 122;
- INCDEC_SET_FLAG(0);
+ INCDEC_SET_FLAG(EE_MODEL);
INCDEC_ENABLE_CHECK(NULL);
}
else {
@@ -4804,11 +4804,11 @@ void menuModelLogicalSwitches(uint8_t event)
#endif
putsMixerSource(CSW_2ND_COLUMN, y, v1_val, attr1);
if (horz == 1) {
- INCDEC_SET_FLAG(INCDEC_SOURCE);
+ INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable);
}
else {
- INCDEC_SET_FLAG(0);
+ INCDEC_SET_FLAG(EE_MODEL);
INCDEC_ENABLE_CHECK(NULL);
}
#if defined(FRSKY)
@@ -4823,7 +4823,7 @@ void menuModelLogicalSwitches(uint8_t event)
else
v2_min = minTelemValue(v1_val - MIXSRC_FIRST_TELEM + 1);
if (horz == 2 && v2_max-v2_min > 1000)
- INCDEC_SET_FLAG(INCDEC_REP10 | NO_INCDEC_MARKS);
+ INCDEC_SET_FLAG(EE_MODEL | INCDEC_REP10 | NO_INCDEC_MARKS);
if (cs->v2 < v2_min || cs->v2 > v2_max) {
cs->v2 = 0;
eeDirty(EE_MODEL);
@@ -4955,7 +4955,7 @@ void menuModelLogicalSwitches(uint8_t event)
#endif
case LS_FIELD_ANDSW:
#if defined(CPUARM)
- INCDEC_SET_FLAG(INCDEC_SWITCH);
+ INCDEC_SET_FLAG(EE_MODEL | INCDEC_SWITCH);
INCDEC_ENABLE_CHECK(isSwitchAvailableInLogicalSwitches);
cs->andsw = CHECK_INCDEC_PARAM(event, cs->andsw, -MAX_LS_ANDSW, MAX_LS_ANDSW);
#else
@@ -4998,7 +4998,7 @@ void menuModelLogicalSwitches(uint8_t event)
void onCustomFunctionsFileSelectionMenu(const char *result)
{
int8_t sub = m_posVert - 1;
- CustomFnData * cf = &g_model.funcSw[sub];
+ CustomFunctionData * cf = &g_model.customFn[sub];
uint8_t func = CFN_FUNC(cf);
if (result == STR_UPDATE_LIST) {
@@ -5030,7 +5030,17 @@ void onCustomFunctionsFileSelectionMenu(const char *result)
void onCustomFunctionsMenu(const char *result)
{
int8_t sub = m_posVert-1;
- CustomFnData * cfn = &g_model.funcSw[sub];
+ CustomFunctionData * cfn;
+ uint8_t eeFlags;
+
+ if (g_menuStack[0] == menuModelCustomFunctions) {
+ cfn = &g_model.customFn[sub];
+ eeFlags = EE_MODEL;
+ }
+ else {
+ cfn = &g_eeGeneral.customFn[sub];
+ eeFlags = EE_GENERAL;
+ }
if (result == STR_COPY) {
clipboard.type = CLIPBOARD_TYPE_CUSTOM_FUNCTION;
@@ -5038,45 +5048,47 @@ void onCustomFunctionsMenu(const char *result)
}
else if (result == STR_PASTE) {
*cfn = clipboard.data.cfn;
- eeDirty(EE_MODEL);
+ eeDirty(eeFlags);
}
else if (result == STR_CLEAR) {
- memset(cfn, 0, sizeof(CustomFnData));
- eeDirty(EE_MODEL);
+ memset(cfn, 0, sizeof(CustomFunctionData));
+ eeDirty(eeFlags);
}
else if (result == STR_INSERT) {
- memmove(cfn+1, cfn, (NUM_CFN-sub-1)*sizeof(CustomFnData));
- memset(cfn, 0, sizeof(CustomFnData));
- eeDirty(EE_MODEL);
+ memmove(cfn+1, cfn, (NUM_CFN-sub-1)*sizeof(CustomFunctionData));
+ memset(cfn, 0, sizeof(CustomFunctionData));
+ eeDirty(eeFlags);
}
else if (result == STR_DELETE) {
- memmove(cfn, cfn+1, (NUM_CFN-sub-1)*sizeof(CustomFnData));
- memset(&g_model.funcSw[NUM_CFN-1], 0, sizeof(CustomFnData));
- eeDirty(EE_MODEL);
+ memmove(cfn, cfn+1, (NUM_CFN-sub-1)*sizeof(CustomFunctionData));
+ memset(&g_model.customFn[NUM_CFN-1], 0, sizeof(CustomFunctionData));
+ eeDirty(eeFlags);
}
}
#endif
-void menuModelCustomFunctions(uint8_t event)
+void menuCustomFunctions(uint8_t event, CustomFunctionData * functions, CustomFunctionsContext & functionsContext)
{
- MENU(STR_MENUCUSTOMFUNC, menuTabModel, e_CustomFunctions, NUM_CFN+1, {0, NAVIGATION_LINE_BY_LINE|4/*repeated*/});
-
int8_t sub = m_posVert - 1;
+#if defined(CPUARM) || defined(AUTOSWITCH)
+ uint8_t eeFlags = (functions == g_model.customFn) ? EE_MODEL : EE_GENERAL;
+#endif
+
#if defined(PCBTARANIS)
if (sub>=0 && m_posHorz<0 && event==EVT_KEY_LONG(KEY_ENTER) && !READ_ONLY()) {
killEvents(event);
- CustomFnData *sd = &g_model.funcSw[sub];
- if (!CFN_EMPTY(sd))
+ CustomFunctionData *cfn = &functions[sub];
+ if (!CFN_EMPTY(cfn))
MENU_ADD_ITEM(STR_COPY);
if (clipboard.type == CLIPBOARD_TYPE_CUSTOM_FUNCTION)
MENU_ADD_ITEM(STR_PASTE);
- if (!CFN_EMPTY(sd) && CFN_EMPTY(&g_model.funcSw[NUM_CFN-1]))
+ if (!CFN_EMPTY(cfn) && CFN_EMPTY(&functions[NUM_CFN-1]))
MENU_ADD_ITEM(STR_INSERT);
- if (!CFN_EMPTY(sd))
+ if (!CFN_EMPTY(cfn))
MENU_ADD_ITEM(STR_CLEAR);
for (int i=sub+1; i0) ? BLINK|INVERS : INVERS) : 0);
uint8_t active = (attr && (s_editMode>0 || p1valdiff));
switch (j) {
case 0:
- 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, isSwitchAvailableInCustomFunctions);
+ putsSwitches(MODEL_CUSTOM_FUNC_1ST_COLUMN, y, CFN_SWITCH(cfn), attr | ((functionsContext.activeSwitches & ((MASK_CFN_TYPE)1 << k)) ? BOLD : 0));
+ if (active || AUTOSWITCH_ENTER_LONG()) CHECK_INCDEC_SWITCH(event, CFN_SWITCH(cfn), SWSRC_FIRST, SWSRC_LAST, eeFlags, isSwitchAvailableInCustomFunctions);
break;
case 1:
- if (CFN_SWITCH(sd)) {
+ if (CFN_SWITCH(cfn)) {
+#if defined(CPUARM)
+ if (func == FUNC_OVERRIDE_CHANNEL) {
+ func = CFN_FUNC(cfn) = checkIncDec(event, CFN_FUNC(cfn), 0, FUNC_MAX-1, eeFlags, isAssignableFunctionAvailable);
+ }
+#endif
lcd_putsiAtt(MODEL_CUSTOM_FUNC_2ND_COLUMN, y, STR_VFSWFUNC, func, attr);
if (active) {
#if defined(CPUARM)
- CFN_FUNC(sd) = checkIncDec(event, CFN_FUNC(sd), 0, FUNC_MAX-1, EE_MODEL, isAssignableFunctionAvailable);
+ CFN_FUNC(cfn) = checkIncDec(event, CFN_FUNC(cfn), 0, FUNC_MAX-1, eeFlags, isAssignableFunctionAvailable);
#else
- CHECK_INCDEC_MODELVAR_ZERO(event, CFN_FUNC(sd), FUNC_MAX-1);
+ CHECK_INCDEC_MODELVAR_ZERO(event, CFN_FUNC(cfn), FUNC_MAX-1);
#endif
- if (checkIncDec_Ret) CFN_RESET(sd);
+ if (checkIncDec_Ret) CFN_RESET(cfn);
}
}
else {
@@ -5129,45 +5146,49 @@ void menuModelCustomFunctions(uint8_t event)
int8_t maxParam = NUM_CHNOUT-1;
#if defined(OVERRIDE_CHANNEL_FUNCTION)
if (func == FUNC_OVERRIDE_CHANNEL) {
- putsChn(lcdNextPos, y, CFN_CH_INDEX(sd)+1, attr);
+ putsChn(lcdNextPos, y, CFN_CH_INDEX(cfn)+1, attr);
}
else
#endif
if (func == FUNC_TRAINER) {
maxParam = 4;
#if defined(CPUARM)
- putsMixerSource(lcdNextPos, y, CFN_CH_INDEX(sd)==0 ? 0 : MIXSRC_Rud+CFN_CH_INDEX(sd)-1, attr);
+ putsMixerSource(lcdNextPos, y, CFN_CH_INDEX(cfn)==0 ? 0 : MIXSRC_Rud+CFN_CH_INDEX(cfn)-1, attr);
#else
- putsMixerSource(lcdNextPos, y, MIXSRC_Rud+CFN_CH_INDEX(sd)-1, attr);
+ putsMixerSource(lcdNextPos, y, MIXSRC_Rud+CFN_CH_INDEX(cfn)-1, attr);
#endif
}
#if defined(GVARS)
else if (func == FUNC_ADJUST_GVAR) {
maxParam = MAX_GVARS-1;
- putsStrIdx(lcdNextPos, y, STR_GV, CFN_GVAR_INDEX(sd)+1, attr);
- if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_GVAR_INDEX(sd), maxParam);
+ putsStrIdx(lcdNextPos, y, STR_GV, CFN_GVAR_INDEX(cfn)+1, attr);
+#if defined(CPUARM)
+ if (active) CFN_GVAR_INDEX(cfn) = checkIncDec(event, CFN_GVAR_INDEX(cfn), 0, maxParam, eeFlags);
+#else
+ if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_GVAR_INDEX(cfn), maxParam);
+#endif
break;
}
#endif
#if defined(CPUARM)
else if (func == FUNC_SET_TIMER) {
maxParam = MAX_TIMERS-1;
- putsStrIdx(lcdNextPos, y, STR_TIMER, CFN_TIMER_INDEX(sd)+1, attr);
- if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_TIMER_INDEX(sd), maxParam);
+ putsStrIdx(lcdNextPos, y, STR_TIMER, CFN_TIMER_INDEX(cfn)+1, attr);
+ if (active) CFN_TIMER_INDEX(cfn) = checkIncDec(event, CFN_TIMER_INDEX(cfn), 0, maxParam, eeFlags);
break;
}
#endif
else if (attr) {
REPEAT_LAST_CURSOR_MOVE();
}
- if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_CH_INDEX(sd), maxParam);
+ if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_CH_INDEX(cfn), maxParam);
break;
}
case 3:
{
- INCDEC_DECLARE_VARS();
- int16_t val_displayed = CFN_PARAM(sd);
+ INCDEC_DECLARE_VARS(eeFlags);
+ int16_t val_displayed = CFN_PARAM(cfn);
#if defined(CPUARM)
int16_t val_min = 0;
int16_t val_max = 255;
@@ -5177,12 +5198,12 @@ void menuModelCustomFunctions(uint8_t event)
#endif
if (func == FUNC_RESET) {
val_max = FUNC_RESET_PARAM_LAST;
- lcd_putsiAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, STR_VFSWRESET, CFN_PARAM(sd), attr);
+ lcd_putsiAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, STR_VFSWRESET, CFN_PARAM(cfn), attr);
}
#if defined(OVERRIDE_CHANNEL_FUNCTION)
else if (func == FUNC_OVERRIDE_CHANNEL) {
#if !defined(CPUARM)
- val_displayed = (int8_t)CFN_PARAM(sd);
+ val_displayed = (int8_t)CFN_PARAM(cfn);
#endif
val_min = -LIMIT_EXT_PERCENT; val_max = +LIMIT_EXT_PERCENT;
lcd_outdezAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr|LEFT);
@@ -5213,8 +5234,8 @@ void menuModelCustomFunctions(uint8_t event)
#else
coord_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);
+ if (ZEXIST(cfn->play.name))
+ lcd_putsnAtt(x, y, cfn->play.name, sizeof(cfn->play.name), attr);
else
lcd_putsiAtt(x, y, STR_VCSWFUNC, 0, attr);
if (active && event==EVT_KEY_BREAK(KEY_ENTER)) {
@@ -5227,7 +5248,7 @@ void menuModelCustomFunctions(uint8_t event)
strcpy(directory, SOUNDS_PATH);
strncpy(directory+SOUNDS_PATH_LNG_OFS, currentLanguagePack->id, 2);
}
- if (listSdFiles(directory, func==FUNC_PLAY_SCRIPT ? SCRIPTS_EXT : SOUNDS_EXT, sizeof(sd->play.name), sd->play.name)) {
+ if (listSdFiles(directory, func==FUNC_PLAY_SCRIPT ? SCRIPTS_EXT : SOUNDS_EXT, sizeof(cfn->play.name), cfn->play.name)) {
menuHandler = onCustomFunctionsFileSelectionMenu;
}
else {
@@ -5247,7 +5268,7 @@ void menuModelCustomFunctions(uint8_t event)
else if (func == FUNC_VOLUME) {
val_max = MIXSRC_LAST_CH;
putsMixerSource(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr);
- INCDEC_SET_FLAG(INCDEC_SOURCE);
+ INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable);
}
#elif defined(VOICE)
@@ -5293,24 +5314,24 @@ void menuModelCustomFunctions(uint8_t event)
#endif
#if defined(PCBTARANIS) && defined(REVPLUS)
else if (func == FUNC_BACKLIGHT) {
- displaySlider(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, CFN_PARAM(sd), 100, attr);
- INCDEC_SET_FLAG(NO_INCDEC_MARKS);
+ displaySlider(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, CFN_PARAM(cfn), 100, attr);
+ INCDEC_SET_FLAG(eeFlags | NO_INCDEC_MARKS);
val_min = 0;
val_max = 100;
}
#endif
#if defined(GVARS)
else if (func == FUNC_ADJUST_GVAR) {
- switch (CFN_GVAR_MODE(sd)) {
+ switch (CFN_GVAR_MODE(cfn)) {
case FUNC_ADJUST_GVAR_CONSTANT:
- val_displayed = (int16_t)CFN_PARAM(sd);
+ val_displayed = (int16_t)CFN_PARAM(cfn);
val_min = -CFN_GVAR_CST_MAX; val_max = +CFN_GVAR_CST_MAX;
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_SET_FLAG(INCDEC_SOURCE);
+ INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable);
break;
case FUNC_ADJUST_GVAR_GVAR:
@@ -5327,9 +5348,9 @@ void menuModelCustomFunctions(uint8_t event)
killEvents(event);
s_editMode = !s_editMode;
active = true;
- CFN_GVAR_MODE(sd) += 1;
+ CFN_GVAR_MODE(cfn) += 1;
#if defined(CPUARM)
- CFN_GVAR_MODE(sd) &= 0x03;
+ CFN_GVAR_MODE(cfn) &= 0x03;
#endif
val_displayed = 0;
}
@@ -5340,18 +5361,22 @@ void menuModelCustomFunctions(uint8_t event)
}
if (active) {
- CFN_PARAM(sd) = CHECK_INCDEC_PARAM(event, val_displayed, val_min, val_max);
+ CFN_PARAM(cfn) = 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);
+ menu_lcd_onoff(MODEL_CUSTOM_FUNC_4TH_COLUMN_ONOFF, y, CFN_ACTIVE(cfn), attr);
+#if defined(CPUARM)
+ if (active) CFN_ACTIVE(cfn) = checkIncDec(event, CFN_ACTIVE(cfn), 0, 1, eeFlags);
+#else
+ if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_ACTIVE(cfn), 1);
+#endif
}
else if (HAS_REPEAT_PARAM(func)) {
- if (CFN_PLAY_REPEAT(sd) == 0) {
+ if (CFN_PLAY_REPEAT(cfn) == 0) {
#if LCD_W >= 212
lcd_putsAtt(MODEL_CUSTOM_FUNC_4TH_COLUMN+2, y, "1x", attr);
#else
@@ -5359,7 +5384,7 @@ void menuModelCustomFunctions(uint8_t event)
#endif
}
#if defined(CPUARM)
- else if (CFN_PLAY_REPEAT(sd) == CFN_PLAY_REPEAT_NOSTART) {
+ else if (CFN_PLAY_REPEAT(cfn) == CFN_PLAY_REPEAT_NOSTART) {
#if LCD_W >= 212
lcd_putcAtt(MODEL_CUSTOM_FUNC_4TH_COLUMN-1, y, '!', attr);
lcd_putsAtt(MODEL_CUSTOM_FUNC_4TH_COLUMN+2, y, "1x", attr);
@@ -5369,15 +5394,15 @@ void menuModelCustomFunctions(uint8_t event)
}
#endif
else {
- lcd_outdezAtt(MODEL_CUSTOM_FUNC_4TH_COLUMN+2+FW, y, CFN_PLAY_REPEAT(sd)*CFN_PLAY_REPEAT_MUL, attr);
+ lcd_outdezAtt(MODEL_CUSTOM_FUNC_4TH_COLUMN+2+FW, y, CFN_PLAY_REPEAT(cfn)*CFN_PLAY_REPEAT_MUL, attr);
#if LCD_W >= 212
lcd_putcAtt(MODEL_CUSTOM_FUNC_4TH_COLUMN+2+FW, y, 's', attr);
#endif
}
#if defined(CPUARM)
- if (active) CFN_PLAY_REPEAT(sd) = checkIncDecModel(event, CFN_PLAY_REPEAT(sd)==CFN_PLAY_REPEAT_NOSTART?-1:CFN_PLAY_REPEAT(sd), -1, 60/CFN_PLAY_REPEAT_MUL);
+ if (active) CFN_PLAY_REPEAT(cfn) = checkIncDec(event, CFN_PLAY_REPEAT(cfn)==CFN_PLAY_REPEAT_NOSTART?-1:CFN_PLAY_REPEAT(cfn), -1, 60/CFN_PLAY_REPEAT_MUL, eeFlags);
#else
- if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_PLAY_REPEAT(sd), 60/CFN_PLAY_REPEAT_MUL);
+ if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_PLAY_REPEAT(cfn), 60/CFN_PLAY_REPEAT_MUL);
#endif
}
else if (attr) {
@@ -5389,6 +5414,12 @@ void menuModelCustomFunctions(uint8_t event)
}
}
+void menuModelCustomFunctions(uint8_t event)
+{
+ MENU(STR_MENUCUSTOMFUNC, menuTabModel, e_CustomFunctions, NUM_CFN+1, {0, NAVIGATION_LINE_BY_LINE|4/*repeated*/});
+ return menuCustomFunctions(event, g_model.customFn, modelFunctionsContext);
+}
+
#if defined(LUA_MODEL_SCRIPTS)
void onModelCustomScriptMenu(const char *result)
{
diff --git a/radio/src/gui/menus.cpp b/radio/src/gui/menus.cpp
index d8fc15a49..95fbbb281 100644
--- a/radio/src/gui/menus.cpp
+++ b/radio/src/gui/menus.cpp
@@ -1487,7 +1487,8 @@ bool isInputSourceAvailable(int source)
enum SwitchContext
{
LogicalSwitchesContext,
- CustomFunctionsContext,
+ ModelCustomFunctionsContext,
+ GeneralCustomFunctionsContext,
TimersContext,
MixesContext
};
@@ -1518,17 +1519,22 @@ bool isSwitchAvailable(int swtch, SwitchContext context)
}
#endif
- if (context != LogicalSwitchesContext && swtch >= SWSRC_FIRST_LOGICAL_SWITCH && swtch <= SWSRC_LAST_LOGICAL_SWITCH) {
- LogicalSwitchData * cs = lswAddress(swtch-SWSRC_FIRST_LOGICAL_SWITCH);
- return (cs->func != LS_FUNC_NONE);
+ if (swtch >= SWSRC_FIRST_LOGICAL_SWITCH && swtch <= SWSRC_LAST_LOGICAL_SWITCH) {
+ if (context == GeneralCustomFunctionsContext) {
+ return false;
+ }
+ else if (context != LogicalSwitchesContext) {
+ LogicalSwitchData * cs = lswAddress(swtch-SWSRC_FIRST_LOGICAL_SWITCH);
+ return (cs->func != LS_FUNC_NONE);
+ }
}
- if (context != CustomFunctionsContext && (swtch == SWSRC_ON || swtch == SWSRC_One)) {
+ if (context != ModelCustomFunctionsContext && context != GeneralCustomFunctionsContext && (swtch == SWSRC_ON || swtch == SWSRC_One)) {
return false;
}
if (swtch >= SWSRC_FIRST_FLIGHT_MODE && swtch <= SWSRC_LAST_FLIGHT_MODE) {
- if (context == MixesContext) {
+ if (context == MixesContext || context == GeneralCustomFunctionsContext) {
return false;
}
else {
@@ -1551,7 +1557,10 @@ bool isSwitchAvailableInLogicalSwitches(int swtch)
bool isSwitchAvailableInCustomFunctions(int swtch)
{
- return isSwitchAvailable(swtch, CustomFunctionsContext);
+ if (g_menuStack[0] == menuModelCustomFunctions)
+ return isSwitchAvailable(swtch, ModelCustomFunctionsContext);
+ else
+ return isSwitchAvailable(swtch, GeneralCustomFunctionsContext);
}
bool isSwitchAvailableInMixes(int swtch)
@@ -1587,15 +1596,23 @@ bool isLogicalSwitchFunctionAvailable(int function)
bool isAssignableFunctionAvailable(int function)
{
+ bool modelFunctions = (g_menuStack[0] == menuModelCustomFunctions);
+
switch (function) {
-#if !defined(OVERRIDE_CHANNEL_FUNCTION)
case FUNC_OVERRIDE_CHANNEL:
+#if defined(OVERRIDE_CHANNEL_FUNCTION)
+ return modelFunctions;
+#else
+ return false;
+#endif
+ case FUNC_ADJUST_GVAR:
+#if defined(GVARS)
+ return modelFunctions;
+#else
+ return false;
#endif
#if !defined(HAPTIC)
case FUNC_HAPTIC:
-#endif
-#if !defined(GVARS)
- case FUNC_ADJUST_GVAR:
#endif
case FUNC_PLAY_DIFF:
case FUNC_RESERVE1:
diff --git a/radio/src/gui/menus.h b/radio/src/gui/menus.h
index 0cc6854db..48056863c 100644
--- a/radio/src/gui/menus.h
+++ b/radio/src/gui/menus.h
@@ -103,6 +103,7 @@ void menu_lcd_onoff(coord_t x, coord_t y, uint8_t value, LcdFlags attr);
typedef void (*MenuFuncP)(uint8_t event);
typedef void (*MenuFuncP_PROGMEM)(uint8_t event);
extern const MenuFuncP_PROGMEM menuTabModel[];
+extern const MenuFuncP_PROGMEM menuTabGeneral[];
extern MenuFuncP g_menuStack[5];
extern uint8_t g_menuPos[4];
@@ -133,6 +134,7 @@ void menuTelemetryFrsky(uint8_t event);
#endif
void menuGeneralSetup(uint8_t event);
void menuGeneralCalib(uint8_t event);
+void menuCustomFunctions(uint8_t event, CustomFunctionData * functions, CustomFunctionsContext & functionsContext);
void menuModelSelect(uint8_t event);
void menuModelCustomFunctions(uint8_t event);
@@ -232,14 +234,20 @@ int8_t checkIncDecGen(uint8_t event, int8_t i_val, int8_t i_min, int8_t i_max);
bool isSwitchAvailableInTimers(int swtch);
bool isModuleAvailable(int module);
#define AUTOSWITCH_ENTER_LONG() (attr && event==EVT_KEY_LONG(KEY_ENTER))
+ #define CHECK_INCDEC_SWITCH(event, var, min, max, flags, available) \
+ var = checkIncDec(event, var, min, max, (flags)|INCDEC_SWITCH|NO_INCDEC_MARKS, available)
#define CHECK_INCDEC_MODELSWITCH(event, var, min, max, available) \
- var = checkIncDec(event,var,min,max,EE_MODEL|INCDEC_SWITCH|NO_INCDEC_MARKS, available)
+ CHECK_INCDEC_SWITCH(event, var, min, max, EE_MODEL, available)
#elif defined(AUTOSWITCH)
#define AUTOSWITCH_ENTER_LONG() (attr && event==EVT_KEY_LONG(KEY_ENTER))
+ #define CHECK_INCDEC_SWITCH(event, var, min, max, flags, available) \
+ var = checkIncDec(event, var, min, max, (flags)|INCDEC_SWITCH)
#define CHECK_INCDEC_MODELSWITCH(event, var, min, max, available) \
- var = checkIncDec(event,var,min,max,EE_MODEL|INCDEC_SWITCH)
+ CHECK_INCDEC_SWITCH(event, var, min, max, EE_MODEL, available)
#else
#define AUTOSWITCH_ENTER_LONG() (0)
+ #define CHECK_INCDEC_SWITCH(event, var, min, max, flags, available) \
+ CHECK_INCDEC_MODELVAR(event, var, min, max)
#define CHECK_INCDEC_MODELSWITCH(event, var, min, max, available) \
CHECK_INCDEC_MODELVAR(event, var, min, max)
#endif
diff --git a/radio/src/lua.cpp b/radio/src/lua.cpp
index d01f68fad..a4fdcfc80 100644
--- a/radio/src/lua.cpp
+++ b/radio/src/lua.cpp
@@ -998,7 +998,7 @@ static int luaModelGetCustomFunction(lua_State *L)
{
int idx = luaL_checkunsigned(L, 1);
if (idx < NUM_CFN) {
- CustomFnData * cfn = &g_model.funcSw[idx];
+ CustomFunctionData * cfn = &g_model.customFn[idx];
lua_newtable(L);
lua_pushtableinteger(L, "switch", CFN_SWITCH(cfn));
lua_pushtableinteger(L, "func", CFN_FUNC(cfn));
@@ -1022,8 +1022,8 @@ static int luaModelSetCustomFunction(lua_State *L)
{
int idx = luaL_checkunsigned(L, 1);
if (idx < NUM_CFN) {
- CustomFnData * cfn = &g_model.funcSw[idx];
- memclear(cfn, sizeof(CustomFnData));
+ CustomFunctionData * cfn = &g_model.customFn[idx];
+ memclear(cfn, sizeof(CustomFunctionData));
luaL_checktype(L, -1, LUA_TTABLE);
for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
luaL_checktype(L, -2, LUA_TSTRING); // key is string
@@ -1668,7 +1668,7 @@ bool luaLoadMixScript(uint8_t index)
bool luaLoadFunctionScript(uint8_t index)
{
- CustomFnData & fn = g_model.funcSw[index];
+ CustomFunctionData & fn = g_model.customFn[index];
if (fn.func == FUNC_PLAY_SCRIPT && ZEXIST(fn.play.name)) {
if (luaScriptsCount < MAX_SCRIPTS) {
@@ -1900,7 +1900,7 @@ void luaDoOneRunPermanentScript(uint8_t evt, int i)
}
}
else if (sid.reference >= SCRIPT_FUNC_FIRST && sid.reference <= SCRIPT_FUNC_LAST) {
- CustomFnData & fn = g_model.funcSw[sid.reference-SCRIPT_FUNC_FIRST];
+ CustomFunctionData & fn = g_model.customFn[sid.reference-SCRIPT_FUNC_FIRST];
if (!getSwitch(fn.swtch)) {
return;
}
diff --git a/radio/src/mixer.cpp b/radio/src/mixer.cpp
index be37379d8..f336703cb 100755
--- a/radio/src/mixer.cpp
+++ b/radio/src/mixer.cpp
@@ -1027,7 +1027,13 @@ void evalMixes(uint8_t tick10ms)
#if defined(CPUARM)
requiredSpeakerVolume = g_eeGeneral.speakerVolume + VOLUME_LEVEL_DEF;
#endif
+
+#if defined(CPUARM)
+ evalFunctions(g_eeGeneral.customFn, globalFunctionsContext);
+ evalFunctions(g_model.customFn, modelFunctionsContext);
+#else
evalFunctions();
+#endif
}
//========== LIMITS ===============
diff --git a/radio/src/myeeprom.h b/radio/src/myeeprom.h
index e24fcfaf6..67b026438 100644
--- a/radio/src/myeeprom.h
+++ b/radio/src/myeeprom.h
@@ -406,6 +406,192 @@ PACK(typedef struct {
int16_t spanPos;
}) CalibData;
+
+enum Functions {
+ // first the functions which need a checkbox
+ FUNC_OVERRIDE_CHANNEL,
+ FUNC_TRAINER,
+ FUNC_INSTANT_TRIM,
+ FUNC_RESET,
+#if defined(CPUARM)
+ FUNC_SET_TIMER,
+#endif
+ FUNC_ADJUST_GVAR,
+#if defined(CPUARM)
+ FUNC_VOLUME,
+ FUNC_RESERVE1,
+ FUNC_RESERVE2,
+ FUNC_RESERVE3,
+#endif
+
+ // then the other functions
+ FUNC_FIRST_WITHOUT_ENABLE,
+ FUNC_PLAY_SOUND = FUNC_FIRST_WITHOUT_ENABLE,
+ FUNC_PLAY_TRACK,
+#if !defined(CPUARM)
+ FUNC_PLAY_BOTH,
+#endif
+ FUNC_PLAY_VALUE,
+#if defined(CPUARM)
+ FUNC_PLAY_DIFF,
+ FUNC_PLAY_SCRIPT,
+ FUNC_RESERVE5,
+ FUNC_BACKGND_MUSIC,
+ FUNC_BACKGND_MUSIC_PAUSE,
+#endif
+ FUNC_VARIO,
+ FUNC_HAPTIC,
+#if !defined(PCBSTD)
+ FUNC_LOGS,
+#endif
+ FUNC_BACKLIGHT,
+#if defined(DEBUG)
+ FUNC_TEST, // should remain the last before MAX as not added in companion9x
+#endif
+ FUNC_MAX
+};
+
+#if defined(OVERRIDE_CHANNEL_FUNCTION)
+ #define HAS_ENABLE_PARAM(func) ((func) < FUNC_FIRST_WITHOUT_ENABLE)
+#else
+ #define HAS_ENABLE_PARAM(func) ((func) < FUNC_FIRST_WITHOUT_ENABLE && (func) != FUNC_OVERRIDE_CHANNEL)
+#endif
+
+#if defined(VOICE)
+ #define IS_PLAY_FUNC(func) ((func) >= FUNC_PLAY_SOUND && func <= FUNC_PLAY_VALUE)
+#else
+ #define IS_PLAY_FUNC(func) ((func) == FUNC_PLAY_SOUND)
+#endif
+
+#if defined(CPUARM)
+ #define IS_PLAY_BOTH_FUNC(func) (0)
+ #define IS_VOLUME_FUNC(func) ((func) == FUNC_VOLUME)
+#else
+ #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(HAPTIC)
+ #define IS_HAPTIC_FUNC(func) ((func) == FUNC_HAPTIC)
+#else
+ #define IS_HAPTIC_FUNC(func) (0)
+#endif
+
+#define HAS_REPEAT_PARAM(func) (IS_PLAY_FUNC(func) || IS_HAPTIC_FUNC(func))
+
+enum ResetFunctionParam {
+ FUNC_RESET_TIMER1,
+ FUNC_RESET_TIMER2,
+#if defined(CPUARM)
+ FUNC_RESET_TIMER3,
+#endif
+ FUNC_RESET_FLIGHT,
+#if defined(FRSKY)
+ FUNC_RESET_TELEMETRY,
+#endif
+#if ROTARY_ENCODERS > 0
+ FUNC_RESET_ROTENC1,
+#endif
+#if ROTARY_ENCODERS > 1
+ FUNC_RESET_ROTENC2,
+#endif
+ FUNC_RESET_PARAMS_COUNT,
+ FUNC_RESET_PARAM_LAST = FUNC_RESET_PARAMS_COUNT-1
+};
+
+enum AdjustGvarFunctionParam {
+ FUNC_ADJUST_GVAR_CONSTANT,
+ FUNC_ADJUST_GVAR_SOURCE,
+ FUNC_ADJUST_GVAR_GVAR,
+ FUNC_ADJUST_GVAR_INC,
+};
+
+#if defined(CPUARM)
+#if defined(PCBTARANIS)
+ #define LEN_CFN_NAME 8
+ #define CFN_SPARE_TYPE int32_t
+#else
+ #define LEN_CFN_NAME 6
+ #define CFN_SPARE_TYPE int16_t
+#endif
+PACK(typedef struct t_CustomFunctionData { // Function Switches data
+ int8_t swtch;
+ uint8_t func;
+ PACK(union {
+ PACK(struct {
+ char name[LEN_CFN_NAME];
+ }) play;
+
+ PACK(struct {
+ int16_t val;
+ uint8_t mode;
+ uint8_t param;
+ CFN_SPARE_TYPE spare2;
+ }) all;
+
+ PACK(struct {
+ int32_t val1;
+ CFN_SPARE_TYPE val2;
+ }) clear;
+ });
+ uint8_t active;
+}) CustomFunctionData;
+#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_INDEX(p) ((p)->all.param)
+#define CFN_GVAR_INDEX(p) ((p)->all.param)
+#define CFN_TIMER_INDEX(p) ((p)->all.param)
+#define CFN_PLAY_REPEAT(p) ((p)->active)
+#define CFN_PLAY_REPEAT_MUL 1
+#define CFN_PLAY_REPEAT_NOSTART 0xFF
+#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)
+#define CFN_GVAR_CST_MAX GVAR_LIMIT
+#else
+PACK(typedef struct t_CustomFunctionData {
+ PACK(union {
+ PACK(struct {
+ int16_t swtch:6;
+ uint16_t func:4;
+ uint16_t mode:2;
+ uint16_t param:3;
+ uint16_t active:1;
+ }) gvar;
+
+ PACK(struct {
+ int16_t swtch:6;
+ uint16_t func:4;
+ uint16_t param:4;
+ uint16_t spare:1;
+ uint16_t active:1;
+ }) all;
+ });
+ uint8_t value;
+}) CustomFunctionData;
+#define CFN_SWITCH(p) ((p)->all.swtch)
+#define CFN_FUNC(p) ((p)->all.func)
+#define CFN_ACTIVE(p) ((p)->all.active)
+#define CFN_CH_INDEX(p) ((p)->all.param)
+#define CFN_TIMER_INDEX(p) ((p)->all.param)
+#define CFN_GVAR_INDEX(p) ((p)->gvar.param)
+#define CFN_PLAY_REPEAT(p) ((p)->all.param)
+#define CFN_PLAY_REPEAT_MUL 10
+#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)
+#define CFN_GVAR_CST_MAX 125
+#endif
+
+
#if defined(PCBSTD)
#define N_PCBSTD_FIELD(x)
#else
@@ -466,6 +652,8 @@ PACK(typedef struct t_EEGeneral {
swstate_t switchUnlockStates;
+ ARM_FIELD(CustomFunctionData customFn[NUM_CFN])
+
}) EEGeneral;
#define SWITCHES_DELAY() uint8_t(15+g_eeGeneral.switchesDelay)
@@ -819,190 +1007,6 @@ PACK(typedef struct t_LogicalSwitchData { // Logical Switches data
}) LogicalSwitchData;
#endif
-enum Functions {
- // first the functions which need a checkbox
- FUNC_OVERRIDE_CHANNEL,
- FUNC_TRAINER,
- FUNC_INSTANT_TRIM,
- FUNC_RESET,
-#if defined(CPUARM)
- FUNC_SET_TIMER,
-#endif
- FUNC_ADJUST_GVAR,
-#if defined(CPUARM)
- FUNC_VOLUME,
- FUNC_RESERVE1,
- FUNC_RESERVE2,
- FUNC_RESERVE3,
-#endif
-
- // then the other functions
- FUNC_FIRST_WITHOUT_ENABLE,
- FUNC_PLAY_SOUND = FUNC_FIRST_WITHOUT_ENABLE,
- FUNC_PLAY_TRACK,
-#if !defined(CPUARM)
- FUNC_PLAY_BOTH,
-#endif
- FUNC_PLAY_VALUE,
-#if defined(CPUARM)
- FUNC_PLAY_DIFF,
- FUNC_PLAY_SCRIPT,
- FUNC_RESERVE5,
- FUNC_BACKGND_MUSIC,
- FUNC_BACKGND_MUSIC_PAUSE,
-#endif
- FUNC_VARIO,
- FUNC_HAPTIC,
-#if !defined(PCBSTD)
- FUNC_LOGS,
-#endif
- FUNC_BACKLIGHT,
-#if defined(DEBUG)
- FUNC_TEST, // should remain the last before MAX as not added in companion9x
-#endif
- FUNC_MAX
-};
-
-#if defined(OVERRIDE_CHANNEL_FUNCTION)
- #define HAS_ENABLE_PARAM(func) ((func) < FUNC_FIRST_WITHOUT_ENABLE)
-#else
- #define HAS_ENABLE_PARAM(func) ((func) < FUNC_FIRST_WITHOUT_ENABLE && (func) != FUNC_OVERRIDE_CHANNEL)
-#endif
-
-#if defined(VOICE)
- #define IS_PLAY_FUNC(func) ((func) >= FUNC_PLAY_SOUND && func <= FUNC_PLAY_VALUE)
-#else
- #define IS_PLAY_FUNC(func) ((func) == FUNC_PLAY_SOUND)
-#endif
-
-#if defined(CPUARM)
- #define IS_PLAY_BOTH_FUNC(func) (0)
- #define IS_VOLUME_FUNC(func) ((func) == FUNC_VOLUME)
-#else
- #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(HAPTIC)
- #define IS_HAPTIC_FUNC(func) ((func) == FUNC_HAPTIC)
-#else
- #define IS_HAPTIC_FUNC(func) (0)
-#endif
-
-#define HAS_REPEAT_PARAM(func) (IS_PLAY_FUNC(func) || IS_HAPTIC_FUNC(func))
-
-enum ResetFunctionParam {
- FUNC_RESET_TIMER1,
- FUNC_RESET_TIMER2,
-#if defined(CPUARM)
- FUNC_RESET_TIMER3,
-#endif
- FUNC_RESET_FLIGHT,
-#if defined(FRSKY)
- FUNC_RESET_TELEMETRY,
-#endif
-#if ROTARY_ENCODERS > 0
- FUNC_RESET_ROTENC1,
-#endif
-#if ROTARY_ENCODERS > 1
- FUNC_RESET_ROTENC2,
-#endif
- FUNC_RESET_PARAMS_COUNT,
- FUNC_RESET_PARAM_LAST = FUNC_RESET_PARAMS_COUNT-1
-};
-
-enum AdjustGvarFunctionParam {
- FUNC_ADJUST_GVAR_CONSTANT,
- FUNC_ADJUST_GVAR_SOURCE,
- FUNC_ADJUST_GVAR_GVAR,
- FUNC_ADJUST_GVAR_INC,
-};
-
-#if defined(CPUARM)
-#if defined(PCBTARANIS)
- #define LEN_CFN_NAME 8
- #define CFN_SPARE_TYPE int32_t
-#else
- #define LEN_CFN_NAME 6
- #define CFN_SPARE_TYPE int16_t
-#endif
-PACK(typedef struct t_CustomFnData { // Function Switches data
- int8_t swtch;
- uint8_t func;
- PACK(union {
- PACK(struct {
- char name[LEN_CFN_NAME];
- }) play;
-
- PACK(struct {
- int16_t val;
- uint8_t mode;
- uint8_t param;
- CFN_SPARE_TYPE spare2;
- }) all;
-
- PACK(struct {
- int32_t val1;
- CFN_SPARE_TYPE 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_INDEX(p) ((p)->all.param)
-#define CFN_GVAR_INDEX(p) ((p)->all.param)
-#define CFN_TIMER_INDEX(p) ((p)->all.param)
-#define CFN_PLAY_REPEAT(p) ((p)->active)
-#define CFN_PLAY_REPEAT_MUL 1
-#define CFN_PLAY_REPEAT_NOSTART 0xFF
-#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)
-#define CFN_GVAR_CST_MAX GVAR_LIMIT
-#else
-PACK(typedef struct t_CustomFnData {
- PACK(union {
- PACK(struct {
- int16_t swtch:6;
- uint16_t func:4;
- uint16_t mode:2;
- uint16_t param:3;
- uint16_t active:1;
- }) gvar;
-
- PACK(struct {
- int16_t swtch:6;
- uint16_t func:4;
- uint16_t param:4;
- uint16_t spare:1;
- uint16_t active:1;
- }) all;
- });
- uint8_t value;
-}) CustomFnData;
-#define CFN_SWITCH(p) ((p)->all.swtch)
-#define CFN_FUNC(p) ((p)->all.func)
-#define CFN_ACTIVE(p) ((p)->all.active)
-#define CFN_CH_INDEX(p) ((p)->all.param)
-#define CFN_TIMER_INDEX(p) ((p)->all.param)
-#define CFN_GVAR_INDEX(p) ((p)->gvar.param)
-#define CFN_PLAY_REPEAT(p) ((p)->all.param)
-#define CFN_PLAY_REPEAT_MUL 10
-#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)
-#define CFN_GVAR_CST_MAX 125
-#endif
-
enum TelemetryUnit {
UNIT_VOLTS,
UNIT_AMPS,
@@ -1832,7 +1836,7 @@ PACK(typedef struct {
int8_t points[NUM_POINTS];
LogicalSwitchData logicalSw[NUM_LOGICAL_SWITCH];
- CustomFnData funcSw[NUM_CFN];
+ CustomFunctionData customFn[NUM_CFN];
SwashRingData swashR;
FlightModeData flightModeData[MAX_FLIGHT_MODES];
diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp
index be454fa3e..96acb9cbd 100644
--- a/radio/src/opentx.cpp
+++ b/radio/src/opentx.cpp
@@ -1666,503 +1666,16 @@ FORCEINLINE void evalTrims()
}
}
-#if defined(DEBUG)
-/*
- * This is a test function for debugging purpose, you may insert there your code and compile with the option DEBUG=YES
- */
-void testFunc()
-{
-#ifdef SIMU
- printf("testFunc\n"); fflush(stdout);
-#endif
-}
-#endif
-
-MASK_FUNC_TYPE activeFunctions = 0;
-MASK_CFN_TYPE activeFnSwitches = 0;
-tmr10ms_t lastFunctionTime[NUM_CFN] = { 0 };
-
-#if defined(VOICE)
-PLAY_FUNCTION(playValue, uint8_t idx)
-{
- if (IS_FAI_FORBIDDEN(idx))
- return;
-
- getvalue_t val = getValue(idx);
-
- switch (idx) {
-#if defined(CPUARM)
- case MIXSRC_FIRST_TELEM+TELEM_TX_TIME-1:
- PLAY_DURATION(val*60, PLAY_TIME);
- break;
-#endif
- case MIXSRC_FIRST_TELEM+TELEM_TX_VOLTAGE-1:
- PLAY_NUMBER(val, 1+UNIT_VOLTS, PREC1);
- break;
- case MIXSRC_FIRST_TELEM+TELEM_TIMER1-1:
- case MIXSRC_FIRST_TELEM+TELEM_TIMER2-1:
-#if defined(CPUARM)
- case MIXSRC_FIRST_TELEM+TELEM_TIMER3-1:
-#endif
- PLAY_DURATION(val, 0);
- break;
-#if defined(CPUARM) && defined(FRSKY)
- case MIXSRC_FIRST_TELEM+TELEM_SWR-1:
- PLAY_NUMBER(val, 0, 0);
- break;
-#endif
-#if defined(FRSKY)
- case MIXSRC_FIRST_TELEM+TELEM_RSSI_TX-1:
- case MIXSRC_FIRST_TELEM+TELEM_RSSI_RX-1:
- PLAY_NUMBER(val, 1+UNIT_DBM, 0);
- break;
- case MIXSRC_FIRST_TELEM+TELEM_MIN_A1-1:
- case MIXSRC_FIRST_TELEM+TELEM_MIN_A2-1:
-#if defined(CPUARM)
- case MIXSRC_FIRST_TELEM+TELEM_MIN_A3-1:
- case MIXSRC_FIRST_TELEM+TELEM_MIN_A4-1:
-#endif
- idx -= TELEM_MIN_A1-TELEM_A1;
- // no break
- case MIXSRC_FIRST_TELEM+TELEM_A1-1:
- case MIXSRC_FIRST_TELEM+TELEM_A2-1:
-#if defined(CPUARM)
- case MIXSRC_FIRST_TELEM+TELEM_A3-1:
- case MIXSRC_FIRST_TELEM+TELEM_A4-1:
-#endif
- if (TELEMETRY_STREAMING()) {
- idx -= (MIXSRC_FIRST_TELEM+TELEM_A1-1);
- uint8_t att = 0;
- int16_t converted_value = div10_and_round(applyChannelRatio(idx, val));;
- if (ANA_CHANNEL_UNIT(idx) < UNIT_RAW) {
- att = PREC1;
- }
- PLAY_NUMBER(converted_value, 1+ANA_CHANNEL_UNIT(idx), att);
- }
- break;
- case MIXSRC_FIRST_TELEM+TELEM_CELL-1:
- case MIXSRC_FIRST_TELEM+TELEM_MIN_CELL-1:
- PLAY_NUMBER(div10_and_round(val), 1+UNIT_VOLTS, PREC1);
- break;
-
- case MIXSRC_FIRST_TELEM+TELEM_VFAS-1:
- case MIXSRC_FIRST_TELEM+TELEM_CELLS_SUM-1:
- case MIXSRC_FIRST_TELEM+TELEM_MIN_CELLS_SUM-1:
- case MIXSRC_FIRST_TELEM+TELEM_MIN_VFAS-1:
- PLAY_NUMBER(val, 1+UNIT_VOLTS, PREC1);
- break;
-
- case MIXSRC_FIRST_TELEM+TELEM_CURRENT-1:
- case MIXSRC_FIRST_TELEM+TELEM_MAX_CURRENT-1:
- PLAY_NUMBER(val, 1+UNIT_AMPS, PREC1);
- break;
-
- case MIXSRC_FIRST_TELEM+TELEM_ACCx-1:
- case MIXSRC_FIRST_TELEM+TELEM_ACCy-1:
- case MIXSRC_FIRST_TELEM+TELEM_ACCz-1:
- PLAY_NUMBER(div10_and_round(val), 1+UNIT_G, PREC1);
- break;
-
- case MIXSRC_FIRST_TELEM+TELEM_VSPEED-1:
- PLAY_NUMBER(div10_and_round(val), 1+UNIT_METERS_PER_SECOND, PREC1);
- break;
-
- case MIXSRC_FIRST_TELEM+TELEM_ASPEED-1:
- case MIXSRC_FIRST_TELEM+TELEM_MAX_ASPEED-1:
- PLAY_NUMBER(val/10, 1+UNIT_KTS, 0);
- break;
-
- case MIXSRC_FIRST_TELEM+TELEM_CONSUMPTION-1:
- PLAY_NUMBER(val, 1+UNIT_MAH, 0);
- break;
-
- case MIXSRC_FIRST_TELEM+TELEM_POWER-1:
- PLAY_NUMBER(val, 1+UNIT_WATTS, 0);
- break;
-
- case MIXSRC_FIRST_TELEM+TELEM_ALT-1:
-#if defined(PCBTARANIS)
- PLAY_NUMBER(div10_and_round(val), 1+UNIT_DIST, PREC1);
- break;
-#endif
- case MIXSRC_FIRST_TELEM+TELEM_MIN_ALT-1:
- case MIXSRC_FIRST_TELEM+TELEM_MAX_ALT-1:
-#if defined(WS_HOW_HIGH)
- if (IS_IMPERIAL_ENABLE() && IS_USR_PROTO_WS_HOW_HIGH())
- PLAY_NUMBER(val, 1+UNIT_FEET, 0);
- else
-#endif
- PLAY_NUMBER(val, 1+UNIT_DIST, 0);
- break;
-
- case MIXSRC_FIRST_TELEM+TELEM_RPM-1:
- case MIXSRC_FIRST_TELEM+TELEM_MAX_RPM-1:
- {
- getvalue_t rpm = val;
- if (rpm > 100)
- rpm = 10 * div10_and_round(rpm);
- if (rpm > 1000)
- rpm = 10 * div10_and_round(rpm);
- PLAY_NUMBER(rpm, 1+UNIT_RPMS, 0);
- break;
- }
-
- case MIXSRC_FIRST_TELEM+TELEM_HDG-1:
- PLAY_NUMBER(val, 1+UNIT_HDG, 0);
- break;
-
- default:
- {
- uint8_t unit = 1;
- if (idx < MIXSRC_GVAR1)
- val = calcRESXto100(val);
- if (idx >= MIXSRC_FIRST_TELEM+TELEM_ALT-1 && idx <= MIXSRC_FIRST_TELEM+TELEM_GPSALT-1)
- unit = idx - (MIXSRC_FIRST_TELEM+TELEM_ALT-1);
- else if (idx >= MIXSRC_FIRST_TELEM+TELEM_MAX_T1-1 && idx <= MIXSRC_FIRST_TELEM+TELEM_MAX_DIST-1)
- unit = 3 + idx - (MIXSRC_FIRST_TELEM+TELEM_MAX_T1-1);
-
- unit = pgm_read_byte(bchunit_ar+unit);
- PLAY_NUMBER(val, unit == UNIT_RAW ? 0 : unit+1, 0);
- break;
- }
-#else
- default:
- {
- PLAY_NUMBER(val, 0, 0);
- break;
- }
-#endif
- }
-}
-#endif
-
#if !defined(PCBSTD)
uint8_t mSwitchDuration[1+NUM_ROTARY_ENCODERS] = { 0 };
#define CFN_PRESSLONG_DURATION 100
#endif
#if defined(CPUARM)
-#define VOLUME_HYSTERESIS 10 // how much must a input value change to actually be considered for new volume setting
uint8_t currentSpeakerVolume = 255;
uint8_t requiredSpeakerVolume;
-getvalue_t requiredSpeakerVolumeRawLast = 1024 + 1; //initial value must be outside normal range
-
-inline void playCustomFunctionFile(CustomFnData *sd, uint8_t id)
-{
- if (sd->play.name[0] != '\0') {
- 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->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);
- }
-}
#endif
-void evalFunctions()
-{
- MASK_FUNC_TYPE newActiveFunctions = 0;
- MASK_CFN_TYPE newActiveFnSwitches = 0;
-
-#if defined(ROTARY_ENCODERS) && defined(GVARS)
- static rotenc_t rePreviousValues[ROTARY_ENCODERS];
-#endif
-
-#if defined(OVERRIDE_CHANNEL_FUNCTION)
- for (uint8_t i=0; i 0) {
- mask = (1<<(CFN_CH_INDEX(sd)-1));
- }
- newActiveFunctions |= mask;
- break;
- }
-
- case FUNC_INSTANT_TRIM:
- newActiveFunctions |= (1 << FUNCTION_INSTANT_TRIM);
- if (!isFunctionActive(FUNCTION_INSTANT_TRIM)) {
- if (g_menuStack[0] == menuMainView
-#if defined(FRSKY)
- || g_menuStack[0] == menuTelemetryFrsky
-#endif
-#if defined(PCBTARANIS)
- || g_menuStack[0] == menuMainViewChannelsMonitor
- || g_menuStack[0] == menuChannelsView
-#endif
- ) {
- instantTrim();
- }
- }
- break;
-
- case FUNC_RESET:
- switch (CFN_PARAM(sd)) {
- case FUNC_RESET_TIMER1:
- case FUNC_RESET_TIMER2:
-#if defined(CPUARM)
- case FUNC_RESET_TIMER3:
-#endif
- timerReset(CFN_PARAM(sd));
- break;
- case FUNC_RESET_FLIGHT:
- flightReset();
- break;
-#if defined(FRSKY)
- case FUNC_RESET_TELEMETRY:
- telemetryReset();
- break;
-#endif
-#if ROTARY_ENCODERS > 0
- case FUNC_RESET_ROTENC1:
-#if ROTARY_ENCODERS > 1
- case FUNC_RESET_ROTENC2:
-#endif
- g_rotenc[CFN_PARAM(sd)-FUNC_RESET_ROTENC1] = 0;
- break;
-#endif
- }
- break;
-
-#if defined(CPUARM)
- case FUNC_SET_TIMER:
- {
- TimerState & timerState = timersStates[CFN_TIMER_INDEX(sd)];
- timerState.state = TMR_OFF; // is changed to RUNNING dep from mode
- timerState.val = CFN_PARAM(sd);
- timerState.val_10ms = 0 ;
- break;
- }
-#endif
-
-#if defined(GVARS)
- case FUNC_ADJUST_GVAR:
- if (CFN_GVAR_MODE(sd) == 0) {
- SET_GVAR(CFN_GVAR_INDEX(sd), CFN_PARAM(sd), mixerCurrentFlightMode);
- }
- else if (CFN_GVAR_MODE(sd) == 2) {
- SET_GVAR(CFN_GVAR_INDEX(sd), GVAR_VALUE(CFN_PARAM(sd), mixerCurrentFlightMode), mixerCurrentFlightMode);
- }
- else if (CFN_GVAR_MODE(sd) == 3) {
- if (!(activeFnSwitches & switch_mask)) {
- SET_GVAR(CFN_GVAR_INDEX(sd), GVAR_VALUE(CFN_GVAR_INDEX(sd), getGVarFlightPhase(mixerCurrentFlightMode, CFN_GVAR_INDEX(sd))) + (CFN_PARAM(sd) ? +1 : -1), mixerCurrentFlightMode);
- }
- }
- else if (CFN_PARAM(sd) >= MIXSRC_TrimRud && CFN_PARAM(sd) <= MIXSRC_TrimAil) {
- trimGvar[CFN_PARAM(sd)-MIXSRC_TrimRud] = CFN_GVAR_INDEX(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_GVAR_INDEX(sd), GVAR_VALUE(CFN_GVAR_INDEX(sd), getGVarFlightPhase(mixerCurrentFlightMode, CFN_GVAR_INDEX(sd))) + scroll, mixerCurrentFlightMode);
- }
- }
-#endif
- else {
- SET_GVAR(CFN_GVAR_INDEX(sd), calcRESXto100(getValue(CFN_PARAM(sd))), mixerCurrentFlightMode);
- }
- break;
-#endif
-
-#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:
-#if defined(HAPTIC)
- case FUNC_HAPTIC:
-#endif
- {
- tmr10ms_t tmr10ms = get_tmr10ms();
- uint8_t repeatParam = CFN_PLAY_REPEAT(sd);
- if (!IS_SILENCE_PERIOD_ELAPSED() && repeatParam == CFN_PLAY_REPEAT_NOSTART)
- lastFunctionTime[i] = tmr10ms;
- if (!lastFunctionTime[i] || (repeatParam && repeatParam!=CFN_PLAY_REPEAT_NOSTART && (signed)(tmr10ms-lastFunctionTime[i])>=100*repeatParam)) {
- if (!IS_PLAYING(i+1)) {
- 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);
- }
-#if defined(HAPTIC)
- else if (CFN_FUNC(sd) == FUNC_HAPTIC) {
- haptic.event(AU_FRSKY_LAST+CFN_PARAM(sd));
- }
-#endif
- 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(mixerCurrentFlightMode, param-251));
-#endif
- PUSH_CUSTOM_PROMPT(active ? param : param+1, i+1);
- }
- }
- if (!active) {
- // PLAY_BOTH would change activeFnSwitches otherwise
- switch_mask = 0;
- }
- 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) && !defined(CPUARM)
- case FUNC_HAPTIC:
- {
- 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;
- haptic.event(AU_FRSKY_LAST+CFN_PARAM(sd));
- }
- break;
- }
-#endif
-
-#if defined(SDCARD)
- case FUNC_LOGS:
- if (CFN_PARAM(sd)) {
- 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;
- }
- }
- }
-
- activeFnSwitches = newActiveFnSwitches;
- activeFunctions = newActiveFunctions;
-
-#if defined(ROTARY_ENCODERS) && defined(GVARS)
- for (uint8_t i=0; i off, abs, stk, stk%, sw/!sw, !m_sw/!m_sw
int16_t prev;
@@ -1237,7 +1234,7 @@ PACK(typedef struct t_SwOn {
#define DELAY_POS_SHIFT 10
#define DELAY_POS_MARGIN 0
#define delayval_t int8_t
-PACK(typedef struct t_SwOn {
+PACK(typedef struct {
uint16_t delay:10;
int16_t now:2; // timer trigger source -> off, abs, stk, stk%, sw/!sw, !m_sw/!m_sw
int16_t prev:2;
@@ -1308,14 +1305,41 @@ enum FunctionsActive {
#define VARIO_REPEAT_ZERO 500/*ms*/
#define VARIO_REPEAT_MAX 80/*ms*/
-extern MASK_FUNC_TYPE activeFunctions;
-extern MASK_CFN_TYPE activeFnSwitches;
-extern tmr10ms_t lastFunctionTime[NUM_CFN];
+typedef struct {
+ MASK_FUNC_TYPE activeFunctions;
+ MASK_CFN_TYPE activeSwitches;
+ tmr10ms_t lastFunctionTime[NUM_CFN];
+ inline bool isFuunctionActive(uint8_t func)
+ {
+ return activeFunctions & ((MASK_FUNC_TYPE)1 << func);
+ }
+
+ void reset()
+ {
+ memclear(this, sizeof(*this));
+ }
+} CustomFunctionsContext;
+
+#if defined(CPUARM)
+extern CustomFunctionsContext modelFunctionsContext;
+extern CustomFunctionsContext globalFunctionsContext;
inline bool isFunctionActive(uint8_t func)
{
- return activeFunctions & ((uint8_t)1 << func);
+ return globalFunctionsContext.isFuunctionActive(func) || modelFunctionsContext.isFuunctionActive(func);
}
+void evalFunctions(const CustomFunctionData * functions, CustomFunctionsContext & functionsContext);
+inline void customFunctionsReset()
+{
+ globalFunctionsContext.reset();
+ modelFunctionsContext.reset();
+}
+#else
+extern CustomFunctionsContext modelFunctionsContext;
+#define isFunctionActive(func) modelFunctionsContext.isFuunctionActive(func)
+void evalFunctions();
+#define customFunctionsReset() modelFunctionsContext.reset()
+#endif
#if defined(ROTARY_ENCODERS)
// Global rotary encoder registers
@@ -1324,6 +1348,8 @@ inline bool isFunctionActive(uint8_t func)
extern volatile rotenc_t g_rotenc[1];
#endif
+#include "gui/menus.h"
+
#if defined (FRSKY)
// FrSky Telemetry
#include "telemetry/frsky.h"
diff --git a/radio/src/translations.cpp b/radio/src/translations.cpp
index 7a09e0818..23e150493 100644
--- a/radio/src/translations.cpp
+++ b/radio/src/translations.cpp
@@ -295,6 +295,7 @@ const pm_char STR_MENUDATEANDTIME[] PROGMEM = TR_MENUDATEANDTIME;
#endif
const pm_char STR_MENUTRAINER[] PROGMEM = TR_MENUTRAINER;
+const pm_char STR_MENUGLOBALFUNCS[] PROGMEM = TR_MENUGLOBALFUNCS;
const pm_char STR_MENUVERSION[] PROGMEM = TR_MENUVERSION;
const pm_char STR_MENUDIAG[] PROGMEM = TR_MENUDIAG;
const pm_char STR_MENUANA[] PROGMEM = TR_MENUANA;
diff --git a/radio/src/translations.h b/radio/src/translations.h
index ce06655e4..99a15a148 100644
--- a/radio/src/translations.h
+++ b/radio/src/translations.h
@@ -456,6 +456,7 @@ extern const pm_char STR_TRIMS2OFFSETS[];
extern const pm_char STR_MENURADIOSETUP[];
extern const pm_char STR_MENUDATEANDTIME[];
extern const pm_char STR_MENUTRAINER[];
+extern const pm_char STR_MENUGLOBALFUNCS[];
extern const pm_char STR_MENUVERSION[];
extern const pm_char STR_MENUDIAG[];
extern const pm_char STR_MENUANA[];
diff --git a/radio/src/translations/cz.h.txt b/radio/src/translations/cz.h.txt
index 5602a6406..f75792bbd 100644
--- a/radio/src/translations/cz.h.txt
+++ b/radio/src/translations/cz.h.txt
@@ -664,6 +664,7 @@
#define TR_MENURADIOSETUP "NASTAVENÍ RÁDIA"
#define TR_MENUDATEANDTIME "DATUM A čAS"
#define TR_MENUTRAINER "TRENÉR"
+#define TR_MENUGLOBALFUNCS "GLOBAL FUNCTIONS"
#define TR_MENUVERSION "VERZE"
#define TR_MENUDIAG "DIAG"
#define TR_MENUANA "ANALOGY"
diff --git a/radio/src/translations/de.h.txt b/radio/src/translations/de.h.txt
index ae9992e9d..907993a6c 100644
--- a/radio/src/translations/de.h.txt
+++ b/radio/src/translations/de.h.txt
@@ -667,6 +667,7 @@
#define TR_MENURADIOSETUP TR("SENDER-EINSTELLEN","SENDER-GRUNDEINSTELLUNGEN")
#define TR_MENUDATEANDTIME "DATUM UND ZEIT"
#define TR_MENUTRAINER TR("LEHRER/SCHÜLER","LEHRER/SCHÜLER")
+#define TR_MENUGLOBALFUNCS "GLOBAL FUNCTIONS"
#define TR_MENUVERSION "VERSION"
#define TR_MENUDIAG TR("Schalt.","Schalter-Test")
#define TR_MENUANA "Analog-Test"
diff --git a/radio/src/translations/en.h.txt b/radio/src/translations/en.h.txt
index 9e4649c13..2648ce22c 100644
--- a/radio/src/translations/en.h.txt
+++ b/radio/src/translations/en.h.txt
@@ -671,6 +671,7 @@
#define TR_MENURADIOSETUP "RADIO SETUP"
#define TR_MENUDATEANDTIME "DATE AND TIME"
#define TR_MENUTRAINER "TRAINER"
+#define TR_MENUGLOBALFUNCS "GLOBAL FUNCTIONS"
#define TR_MENUVERSION "VERSION"
#define TR_MENUDIAG TR("SWITCHES","SWITCH TEST")
#define TR_MENUANA TR("ANAS","ANALOG INPUTS")
diff --git a/radio/src/translations/es.h.txt b/radio/src/translations/es.h.txt
index cd07180b7..f9365bb2c 100644
--- a/radio/src/translations/es.h.txt
+++ b/radio/src/translations/es.h.txt
@@ -660,6 +660,7 @@
#define TR_MENURADIOSETUP "CONFIGURACION"
#define TR_MENUDATEANDTIME "FECHA Y HORA"
#define TR_MENUTRAINER "APRENDIZ"
+#define TR_MENUGLOBALFUNCS "GLOBAL FUNCTIONS"
#define TR_MENUVERSION "VERSION"
#define TR_MENUDIAG TR("INTERUPTS", "TEST INTERUP.")
#define TR_MENUANA TR("ANAS", "ENTRADAS ANALOG")
diff --git a/radio/src/translations/fi.h.txt b/radio/src/translations/fi.h.txt
index 1e2171cff..5c47bbe9f 100644
--- a/radio/src/translations/fi.h.txt
+++ b/radio/src/translations/fi.h.txt
@@ -660,6 +660,7 @@
#define TR_MENURADIOSETUP "RADIO SETUP"
#define TR_MENUDATEANDTIME "DATE AND TIME"
#define TR_MENUTRAINER "TRAINER"
+#define TR_MENUGLOBALFUNCS "GLOBAL FUNCTIONS"
#define TR_MENUVERSION "VERSION"
#define TR_MENUDIAG TR("SWITCHES","SWITCH TEST")
#define TR_MENUANA TR("ANAS","ANALOG INPUTS")
diff --git a/radio/src/translations/fr.h.txt b/radio/src/translations/fr.h.txt
index 077eab273..3cd8d2356 100644
--- a/radio/src/translations/fr.h.txt
+++ b/radio/src/translations/fr.h.txt
@@ -660,6 +660,7 @@
#define TR_MENURADIOSETUP "CONFIG RADIO"
#define TR_MENUDATEANDTIME "DATE ET HEURE"
#define TR_MENUTRAINER "ECOLAGE"
+#define TR_MENUGLOBALFUNCS "GLOBAL FUNCTIONS"
#define TR_MENUVERSION "VERSION"
#define TR_MENUDIAG TR("INTERS","TEST INTERRUPTEURS")
#define TR_MENUANA TR("ANAS","ENTREES ANALOGIQUES")
diff --git a/radio/src/translations/it.h.txt b/radio/src/translations/it.h.txt
index 5b942c041..b80ae46c0 100644
--- a/radio/src/translations/it.h.txt
+++ b/radio/src/translations/it.h.txt
@@ -660,6 +660,7 @@
#define TR_MENURADIOSETUP "CONFIGURATX"
#define TR_MENUDATEANDTIME "DATA E ORA"
#define TR_MENUTRAINER "MAESTRO/ALLIEVO"
+#define TR_MENUGLOBALFUNCS "GLOBAL FUNCTIONS"
#define TR_MENUVERSION "VERSIONE"
#define TR_MENUDIAG "DIAG"
#define TR_MENUANA "ANAS"
diff --git a/radio/src/translations/pl.h.txt b/radio/src/translations/pl.h.txt
index 35107e7c0..2a505f44b 100644
--- a/radio/src/translations/pl.h.txt
+++ b/radio/src/translations/pl.h.txt
@@ -660,6 +660,7 @@
#define TR_MENURADIOSETUP "USTAWIENIA RADIA"
#define TR_MENUDATEANDTIME "DATA I CZAS"
#define TR_MENUTRAINER "TRENER"
+#define TR_MENUGLOBALFUNCS "GLOBAL FUNCTIONS"
#define TR_MENUVERSION "WERSJA"
#define TR_MENUDIAG TR("PRZEŁ","TEST PRZEŁ")
#define TR_MENUANA TR("WE-ANA","WEJŚCIA ANALOG.")
diff --git a/radio/src/translations/pt.h.txt b/radio/src/translations/pt.h.txt
index 06d540e51..9519bfd21 100644
--- a/radio/src/translations/pt.h.txt
+++ b/radio/src/translations/pt.h.txt
@@ -660,6 +660,7 @@
#define TR_MENURADIOSETUP "AJUSTAR RADIO"
#define TR_MENUDATEANDTIME "DATA E HORA"
#define TR_MENUTRAINER "TRAINER"
+#define TR_MENUGLOBALFUNCS "GLOBAL FUNCTIONS"
#define TR_MENUVERSION "VERSAO"
#define TR_MENUDIAG "DIAGNOST"
#define TR_MENUANA "ANALOGICOS"
diff --git a/radio/src/translations/se.h.txt b/radio/src/translations/se.h.txt
index eeb7dacc9..f30e151c9 100644
--- a/radio/src/translations/se.h.txt
+++ b/radio/src/translations/se.h.txt
@@ -660,6 +660,7 @@
#define TR_MENURADIOSETUP "INSTÄLLNINGAR"
#define TR_MENUDATEANDTIME "DAG OCH TID"
#define TR_MENUTRAINER "TRAINER (PPM IN)"
+#define TR_MENUGLOBALFUNCS "GLOBAL FUNCTIONS"
#define TR_MENUVERSION "VERSION"
#define TR_MENUDIAG TR("BRYTARE","TEST AV BRYTARE")
#define TR_MENUANA "ANALOGA VÄRDEN"
| |