1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-14 20:10:08 +03:00

Global functions (only Firmware) - saves 20bytes flash on 9X stock

This commit is contained in:
bsongis 2014-09-16 14:34:48 +02:00
parent 5173907efd
commit 2f8b9347a4
55 changed files with 1328 additions and 1154 deletions

View file

@ -1015,8 +1015,8 @@ void CompareDialog::printSwitches()
str.append("<tr><td><table border=1 cellspacing=0 cellpadding=1 width=\"100%\">");
for (int i=0; i<GetCurrentFirmware()->getCapability(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("<tr>");
color=getColor1(sw1,sw2);
@ -1059,8 +1059,8 @@ void CompareDialog::printFSwitches()
str.append("</tr>");
for(int i=0; i<GetCurrentFirmware()->getCapability(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("<tr>");
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("<td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>");
}
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));
}

View file

@ -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; i<NUM_STICKS; i++)
expoData[i].clear();
for (int i=0; i<C9X_NUM_CSW; i++)
customSw[i].clear();
logicalSw[i].clear();
for (int i=0; i<C9X_MAX_CUSTOM_FUNCTIONS; i++)
funcSw[i].clear();
customFn[i].clear();
for (int i=0; i<C9X_MAX_CURVES; i++)
curves[i].clear(5);
for (int i=0; i<C9X_MAX_TIMERS; i++)

View file

@ -756,9 +756,9 @@ enum AssignFunc {
FuncReserve = -1
};
class FuncSwData { // Function Switches data
class CustomFunctionData { // Function Switches data
public:
FuncSwData(AssignFunc func=FuncOverrideCH1) { clear(); this->func = 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; i<C9X_NUM_CSW; i++) {
RawSource source;
switch (model.customSw[i].getFunctionFamily()) {
switch (model.logicalSw[i].getFunctionFamily()) {
case LS_FAMILY_VCOMP:
source = RawSource(model.customSw[i].val2);
source = RawSource(model.logicalSw[i].val2);
if (source.type == SOURCE_TYPE_STICK)
source.index = applyStickMode(source.index + 1, mode) - 1;
model.customSw[i].val2 = source.toValue();
model.logicalSw[i].val2 = source.toValue();
// no break
case LS_FAMILY_VOFS:
source = RawSource(model.customSw[i].val1);
source = RawSource(model.logicalSw[i].val1);
if (source.type == SOURCE_TYPE_STICK)
source.index = applyStickMode(source.index + 1, mode) - 1;
model.customSw[i].val1 = source.toValue();
model.logicalSw[i].val1 = source.toValue();
break;
default:
break;

View file

@ -378,9 +378,9 @@ t_Er9xModelData::operator ModelData ()
c9x.thrTrim = thrTrim;
c9x.trimInc = trimInc-2;
c9x.moduleData[0].ppmDelay = 300 + 50 * ppmDelay;
c9x.funcSw[0].func = FuncInstantTrim;
c9x.customFn[0].func = FuncInstantTrim;
if (trimSw) {
c9x.funcSw[0].swtch = er9xToSwitch(trimSw);
c9x.customFn[0].swtch = er9xToSwitch(trimSw);
}
c9x.beepANACenter = beepANACenter;
c9x.moduleData[0].ppmPulsePol = pulsePol;
@ -459,7 +459,7 @@ t_Er9xModelData::operator ModelData ()
}
for (int i=0; i<ER9X_NUM_CSW; i++)
c9x.customSw[i] = customSw[i];
c9x.logicalSw[i] = logicalSw[i];
// for (int i=0; i<ER9X_NUM_CHNOUT; i++)
// c9x.safetySw[i] = safetySw[i];

View file

@ -241,7 +241,7 @@ PACK(typedef struct t_Er9xModelData {
int8_t trim[4];
int8_t curves5[ER9X_MAX_CURVE5][5];
int8_t curves9[ER9X_MAX_CURVE9][9];
Er9xLogicalSwitchData customSw[ER9X_NUM_CSW];
Er9xLogicalSwitchData logicalSw[ER9X_NUM_CSW];
uint8_t frSkyVoltThreshold ;
int8_t tmrModeB;
uint8_t numVoice;

View file

@ -75,12 +75,12 @@ inline void applyStickModeToModel(Er9xModelData & model, unsigned int mode)
for (int i=0; i<ER9X_MAX_MIXERS; i++)
model.mixData[i].srcRaw = applyStickMode(model.mixData[i].srcRaw, mode);
for (int i=0; i<ER9X_NUM_CSW; i++) {
switch (LogicalSwitchData(model.customSw[i].func).getFunctionFamily()) {
switch (LogicalSwitchData(model.logicalSw[i].func).getFunctionFamily()) {
case LS_FAMILY_VCOMP:
model.customSw[i].v2 = applyStickMode(model.customSw[i].v2, mode);
model.logicalSw[i].v2 = applyStickMode(model.logicalSw[i].v2, mode);
// no break
case LS_FAMILY_VOFS:
model.customSw[i].v1 = applyStickMode(model.customSw[i].v1, mode);
model.logicalSw[i].v1 = applyStickMode(model.logicalSw[i].v1, mode);
break;
default:
break;

View file

@ -510,9 +510,9 @@ t_Ersky9xModelData_v10::operator ModelData ()
c9x.thrTrim = thrTrim;
c9x.trimInc = trimInc-2;
c9x.moduleData[0].ppmDelay = 300 + 50 * ppmDelay;
c9x.funcSw[0].func = FuncInstantTrim;
c9x.customFn[0].func = FuncInstantTrim;
if (trimSw) {
c9x.funcSw[0].swtch = er9xToSwitch(trimSw);
c9x.customFn[0].swtch = er9xToSwitch(trimSw);
}
c9x.beepANACenter = beepANACenter;
c9x.moduleData[0].ppmPulsePol = pulsePol;
@ -587,7 +587,7 @@ t_Ersky9xModelData_v10::operator ModelData ()
}
for (int i=0; i<ERSKY9X_NUM_CSW_V10; i++)
c9x.customSw[i] = customSw[i];
c9x.logicalSw[i] = logicalSw[i];
// for (int i=0; i<ERSKY9X_NUM_CHNOUT_V10; i++)
// c9x.safetySw[i] = safetySw[i];
@ -626,9 +626,9 @@ t_Ersky9xModelData_v11::operator ModelData ()
c9x.thrTrim = thrTrim;
c9x.trimInc = trimInc-2;
c9x.moduleData[0].ppmDelay = 300 + 50 * ppmDelay;
c9x.funcSw[0].func = FuncInstantTrim;
c9x.customFn[0].func = FuncInstantTrim;
if (trimSw) {
c9x.funcSw[0].swtch = er9xToSwitch(trimSw);
c9x.customFn[0].swtch = er9xToSwitch(trimSw);
}
c9x.beepANACenter = beepANACenter;
c9x.moduleData[0].ppmPulsePol = pulsePol;
@ -703,7 +703,7 @@ t_Ersky9xModelData_v11::operator ModelData ()
}
for (int i=0; i<ERSKY9X_NUM_CSW_V11; i++)
c9x.customSw[i] = customSw[i];
c9x.logicalSw[i] = logicalSw[i];
// for (int i=0; i<ERSKY9X_NUM_CHNOUT_V11; i++)
// c9x.safetySw[i] = safetySw[i];

View file

@ -246,13 +246,13 @@ PACK(typedef struct t_Ersky9xFlightModeData {
uint16_t spare ; // Future expansion
}) Ersky9xFlightModeData;
PACK(typedef struct t_Ersky9xFuncSwData { // Function Switches data
PACK(typedef struct t_Ersky9xCustomFunctionData { // Function Switches data
int8_t swtch; //input
uint8_t func;
char param[6];
uint8_t delay;
uint8_t spare;
}) Ersky9xFuncSwData;
}) Ersky9xCustomFunctionData;
PACK(typedef struct t_Ersky9xFrSkyChannelData_v10 {
uint8_t ratio; // 0.0 means not used, 0.1V steps EG. 6.6 Volts = 66. 25.1V = 251, etc.
@ -360,7 +360,7 @@ PACK(typedef struct t_Ersky9xModelData_v10 {
int8_t trim[4];
int8_t curves5[ERSKY9X_MAX_CURVE5][5];
int8_t curves9[ERSKY9X_MAX_CURVE9][9];
Ersky9xLogicalSwitchData_v10 customSw[ERSKY9X_NUM_CSW_V10];
Ersky9xLogicalSwitchData_v10 logicalSw[ERSKY9X_NUM_CSW_V10];
uint8_t frSkyVoltThreshold ;
uint8_t res3[2];
Ersky9xSafetySwData_v10 safetySw[ERSKY9X_NUM_CHNOUT_V10];
@ -409,7 +409,7 @@ PACK(typedef struct t_Ersky9xModelData_v11 {
int8_t curves5[ERSKY9X_MAX_CURVE5][5];
int8_t curves9[ERSKY9X_MAX_CURVE9][9];
int8_t curvexy[18];
Ersky9xLogicalSwitchData_v11 customSw[ERSKY9X_NUM_CSW_V11];
Ersky9xLogicalSwitchData_v11 logicalSw[ERSKY9X_NUM_CSW_V11];
uint8_t frSkyVoltThreshold ;
uint8_t bt_telemetry;
uint8_t numVoice; // 0-16, rest are Safety switches
@ -420,7 +420,7 @@ PACK(typedef struct t_Ersky9xModelData_v11 {
Ersky9xFrSkyAlarmData_v11 frskyAlarms ;
// Add 6 bytes for custom telemetry screen
uint8_t customDisplayIndex[6] ;
Ersky9xFuncSwData funcSw[ERSKY9X_NUM_FSW];
Ersky9xCustomFunctionData customFn[ERSKY9X_NUM_FSW];
Ersky9xFlightModeData flightModeData[6] ;
Ersky9xGvarData gvars[ERSKY9X_MAX_GVARS] ;

View file

@ -74,12 +74,12 @@ inline void applyStickModeToModel(Ersky9xModelData_v10 & model, unsigned int mod
for (int i=0; i<ERSKY9X_MAX_MIXERS_V10; i++)
model.mixData[i].srcRaw = applyStickMode(model.mixData[i].srcRaw, mode);
for (int i=0; i<ERSKY9X_NUM_CSW_V10; i++) {
switch (LogicalSwitchData(model.customSw[i].func).getFunctionFamily()) {
switch (LogicalSwitchData(model.logicalSw[i].func).getFunctionFamily()) {
case LS_FAMILY_VCOMP:
model.customSw[i].v2 = applyStickMode(model.customSw[i].v2, mode);
model.logicalSw[i].v2 = applyStickMode(model.logicalSw[i].v2, mode);
// no break
case LS_FAMILY_VOFS:
model.customSw[i].v1 = applyStickMode(model.customSw[i].v1, mode);
model.logicalSw[i].v1 = applyStickMode(model.logicalSw[i].v1, mode);
break;
default:
break;
@ -106,12 +106,12 @@ inline void applyStickModeToModel(Ersky9xModelData_v11 & model, unsigned int mod
for (int i=0; i<ERSKY9X_MAX_MIXERS_V11; i++)
model.mixData[i].srcRaw = applyStickMode(model.mixData[i].srcRaw, mode);
for (int i=0; i<ERSKY9X_NUM_CSW_V11; i++) {
switch (LogicalSwitchData(model.customSw[i].func).getFunctionFamily()) {
switch (LogicalSwitchData(model.logicalSw[i].func).getFunctionFamily()) {
case LS_FAMILY_VCOMP:
model.customSw[i].v2 = applyStickMode(model.customSw[i].v2, mode);
model.logicalSw[i].v2 = applyStickMode(model.logicalSw[i].v2, mode);
// no break
case LS_FAMILY_VOFS:
model.customSw[i].v1 = applyStickMode(model.customSw[i].v1, mode);
model.logicalSw[i].v1 = applyStickMode(model.logicalSw[i].v1, mode);
break;
default:
break;

View file

@ -322,9 +322,9 @@ Gruvin9xLogicalSwitchData::operator LogicalSwitchData ()
return c9x;
}
Gruvin9xFuncSwData::operator FuncSwData ()
Gruvin9xCustomFunctionData::operator CustomFunctionData ()
{
FuncSwData c9x;
CustomFunctionData c9x;
c9x.swtch = gruvin9xToSwitch(swtch);
c9x.func = (AssignFunc)(func + G9X_NUM_CHNOUT);
return c9x;
@ -476,7 +476,7 @@ t_Gruvin9xModelData_v102::operator ModelData ()
}
for (int i=0; i<G9X_NUM_CSW; i++)
c9x.customSw[i] = customSw[i];
c9x.logicalSw[i] = logicalSw[i];
// for (int i=0; i<G9X_NUM_CHNOUT; i++)
// c9x.safetySw[i] = safetySw[i];
c9x.swashRingData = swashR;
@ -546,7 +546,7 @@ t_Gruvin9xModelData_v103::operator ModelData ()
}
for (int i=0; i<G9X_NUM_CSW; i++)
c9x.customSw[i] = customSw[i];
c9x.logicalSw[i] = logicalSw[i];
// for (int i=0; i<G9X_NUM_CHNOUT; i++)
// c9x.safetySw[i] = safetySw[i];
c9x.swashRingData = swashR;
@ -633,9 +633,9 @@ t_Gruvin9xModelData_v105::operator ModelData ()
}
for (int i=0; i<G9X_NUM_CSW; i++)
c9x.customSw[i] = customSw[i];
c9x.logicalSw[i] = logicalSw[i];
for (int i=0; i<G9X_NUM_FSW; i++)
c9x.funcSw[i] = funcSw[i];
c9x.customFn[i] = customFn[i];
// for (int i=0; i<G9X_NUM_CHNOUT; i++)
// c9x.safetySw[i] = safetySw[i];
c9x.swashRingData = swashR;
@ -716,9 +716,9 @@ t_Gruvin9xModelData_v106::operator ModelData ()
}
for (int i=0; i<G9X_NUM_CSW; i++)
c9x.customSw[i] = customSw[i];
c9x.logicalSw[i] = logicalSw[i];
for (int i=0; i<G9X_NUM_FSW; i++)
c9x.funcSw[i] = funcSw[i];
c9x.customFn[i] = customFn[i];
// for (int i=0; i<G9X_NUM_CHNOUT; i++)
// c9x.safetySw[i] = safetySw[i];
c9x.swashRingData = swashR;

View file

@ -202,13 +202,13 @@ PACK(typedef struct t_Gruvin9xSafetySwData { // Safety Switches data
t_Gruvin9xSafetySwData() { memset(this, 0, sizeof(t_Gruvin9xSafetySwData)); }
}) Gruvin9xSafetySwData;
PACK(typedef struct t_Gruvin9xFuncSwData { // Function Switches data
PACK(typedef struct t_Gruvin9xCustomFunctionData { // Function Switches data
int8_t swtch; // input
uint8_t func;
operator FuncSwData();
t_Gruvin9xFuncSwData() { memset(this, 0, sizeof(t_Gruvin9xFuncSwData)); }
}) Gruvin9xFuncSwData;
operator CustomFunctionData();
t_Gruvin9xCustomFunctionData() { memset(this, 0, sizeof(t_Gruvin9xCustomFunctionData)); }
}) Gruvin9xCustomFunctionData;
PACK(typedef struct t_Gruvin9xFrSkyChannelData {
uint16_t ratio:12; // (Maximum resistor divider input volts +/- calibration. 0 means channel not used.
@ -309,7 +309,7 @@ PACK(typedef struct t_Gruvin9xModelData_v102 {
Gruvin9xExpoData expoData[G9X_MAX_EXPOS];
int8_t curves5[G9X_MAX_CURVE5][5];
int8_t curves9[G9X_MAX_CURVE9][9];
Gruvin9xLogicalSwitchData customSw[G9X_NUM_CSW];
Gruvin9xLogicalSwitchData logicalSw[G9X_NUM_CSW];
Gruvin9xSafetySwData safetySw[G9X_NUM_CHNOUT];
Gruvin9xSwashRingData swashR;
Gruvin9xFlightModeData_v102 flightModeData[G9X_MAX_FLIGHT_MODES];
@ -341,7 +341,7 @@ PACK(typedef struct t_Gruvin9xModelData_v103 {
Gruvin9xExpoData expoData[G9X_MAX_EXPOS];
int8_t curves5[G9X_MAX_CURVE5][5];
int8_t curves9[G9X_MAX_CURVE9][9];
Gruvin9xLogicalSwitchData customSw[G9X_NUM_CSW];
Gruvin9xLogicalSwitchData logicalSw[G9X_NUM_CSW];
Gruvin9xSafetySwData safetySw[G9X_NUM_CHNOUT];
Gruvin9xSwashRingData swashR;
Gruvin9xFlightModeData_v102 flightModeData[G9X_MAX_FLIGHT_MODES];
@ -373,9 +373,9 @@ PACK(typedef struct t_Gruvin9xModelData_v105 {
Gruvin9xExpoData expoData[G9X_MAX_EXPOS];
int8_t curves5[G9X_MAX_CURVE5][5];
int8_t curves9[G9X_MAX_CURVE9][9];
Gruvin9xLogicalSwitchData customSw[G9X_NUM_CSW];
Gruvin9xLogicalSwitchData logicalSw[G9X_NUM_CSW];
Gruvin9xSafetySwData safetySw[G9X_NUM_CHNOUT];
Gruvin9xFuncSwData funcSw[G9X_NUM_FSW];
Gruvin9xCustomFunctionData customFn[G9X_NUM_FSW];
Gruvin9xSwashRingData swashR;
Gruvin9xFlightModeData_v102 flightModeData[G9X_MAX_FLIGHT_MODES];
int16_t subtrim[NUM_STICKS];
@ -405,9 +405,9 @@ PACK(typedef struct t_Gruvin9xModelData_v106 {
Gruvin9xExpoData expoData[G9X_MAX_EXPOS];
int8_t curves5[G9X_MAX_CURVE5][5];
int8_t curves9[G9X_MAX_CURVE9][9];
Gruvin9xLogicalSwitchData customSw[G9X_NUM_CSW];
Gruvin9xLogicalSwitchData logicalSw[G9X_NUM_CSW];
Gruvin9xSafetySwData safetySw[G9X_NUM_CHNOUT];
Gruvin9xFuncSwData funcSw[G9X_NUM_FSW];
Gruvin9xCustomFunctionData customFn[G9X_NUM_FSW];
Gruvin9xSwashRingData swashR;
Gruvin9xFlightModeData_v106 flightModeData[G9X_MAX_FLIGHT_MODES];
Gruvin9xFrSkyData frsky;

View file

@ -339,9 +339,9 @@ Open9xGruvin9xLogicalSwitchData_v209::operator LogicalSwitchData ()
return c9x;
}
t_Open9xGruvin9xFuncSwData_v203::operator FuncSwData ()
t_Open9xGruvin9xCustomFunctionData_v203::operator CustomFunctionData ()
{
FuncSwData c9x;
CustomFunctionData c9x;
c9x.swtch = open9xStockToSwitch(swtch);
if (func < 16) {
c9x.func = (AssignFunc)(func);
@ -378,9 +378,9 @@ t_Open9xGruvin9xFuncSwData_v203::operator FuncSwData ()
return c9x;
}
t_Open9xGruvin9xFuncSwData_v210::operator FuncSwData ()
t_Open9xGruvin9xCustomFunctionData_v210::operator CustomFunctionData ()
{
FuncSwData c9x;
CustomFunctionData c9x;
c9x.swtch = open9xStockToSwitch(swtch);
c9x.param = param;
if (func < 22) {
@ -494,9 +494,9 @@ t_Open9xGruvin9xModelData_v207::operator ModelData ()
}
for (int i=0; i<12; i++)
c9x.customSw[i] = customSw[i];
c9x.logicalSw[i] = logicalSw[i];
for (int i=0; i<16; i++)
c9x.funcSw[i] = funcSw[i];
c9x.customFn[i] = customFn[i];
c9x.swashRingData = swashR;
c9x.frsky = frsky;
c9x.moduleData[0].ppmFrameLength = ppmFrameLength;
@ -577,9 +577,9 @@ t_Open9xGruvin9xModelData_v208::operator ModelData ()
}
}
for (int i=0; i<12; i++)
c9x.customSw[i] = customSw[i];
c9x.logicalSw[i] = logicalSw[i];
for (int i=0; i<16; i++)
c9x.funcSw[i] = funcSw[i];
c9x.customFn[i] = customFn[i];
c9x.swashRingData = swashR;
c9x.frsky = frsky;
c9x.frsky.varioSource = varioSource;
@ -666,9 +666,9 @@ t_Open9xGruvin9xModelData_v209::operator ModelData ()
}
}
for (int i=0; i<12; i++)
c9x.customSw[i] = customSw[i];
c9x.logicalSw[i] = logicalSw[i];
for (int i=0; i<16; i++)
c9x.funcSw[i] = funcSw[i];
c9x.customFn[i] = customFn[i];
c9x.swashRingData = swashR;
c9x.frsky = frsky;
c9x.frsky.varioSource = varioSource;
@ -759,9 +759,9 @@ t_Open9xGruvin9xModelData_v210::operator ModelData ()
}
}
for (int i=0; i<12; i++)
c9x.customSw[i] = customSw[i];
c9x.logicalSw[i] = logicalSw[i];
for (int i=0; i<16; i++)
c9x.funcSw[i] = funcSw[i];
c9x.customFn[i] = customFn[i];
c9x.swashRingData = swashR;
c9x.frsky = frsky;
c9x.switchWarningStates = switchWarningStates;
@ -846,9 +846,9 @@ t_Open9xGruvin9xModelData_v211::operator ModelData ()
}
}
for (int i=0; i<12; i++)
c9x.customSw[i] = customSw[i];
c9x.logicalSw[i] = logicalSw[i];
for (int i=0; i<16; i++)
c9x.funcSw[i] = funcSw[i];
c9x.customFn[i] = customFn[i];
c9x.swashRingData = swashR;
c9x.frsky = frsky;
c9x.switchWarningStates = switchWarningStates;

View file

@ -132,24 +132,24 @@ PACK(typedef struct t_Open9xGruvin9xLogicalSwitchData_v209 { // Custom Switches
RawSource toSource(int8_t value);
}) Open9xGruvin9xLogicalSwitchData_v209;
PACK(typedef struct t_Open9xGruvin9xFuncSwData_v203 { // Function Switches data
PACK(typedef struct t_Open9xGruvin9xCustomFunctionData_v203 { // Function Switches data
int8_t swtch; // input
uint8_t func;
uint8_t param;
operator FuncSwData();
t_Open9xGruvin9xFuncSwData_v203() { memset(this, 0, sizeof(t_Open9xGruvin9xFuncSwData_v203)); }
}) Open9xGruvin9xFuncSwData_v203;
operator CustomFunctionData();
t_Open9xGruvin9xCustomFunctionData_v203() { memset(this, 0, sizeof(t_Open9xGruvin9xCustomFunctionData_v203)); }
}) Open9xGruvin9xCustomFunctionData_v203;
PACK(typedef struct t_Open9xGruvin9xFuncSwData_v210 { // Function Switches data
PACK(typedef struct t_Open9xGruvin9xCustomFunctionData_v210 { // Function Switches data
int8_t swtch; // input
uint8_t func:5;
uint8_t delay:3;
uint8_t param;
operator FuncSwData();
t_Open9xGruvin9xFuncSwData_v210() { memset(this, 0, sizeof(t_Open9xGruvin9xFuncSwData_v210)); }
}) Open9xGruvin9xFuncSwData_v210;
operator CustomFunctionData();
t_Open9xGruvin9xCustomFunctionData_v210() { memset(this, 0, sizeof(t_Open9xGruvin9xCustomFunctionData_v210)); }
}) Open9xGruvin9xCustomFunctionData_v210;
PACK(typedef struct t_Open9xGruvin9xSwashRingData_v208 { // Swash Ring data
uint8_t invertELE:1;
@ -194,8 +194,8 @@ PACK(typedef struct t_Open9xGruvin9xModelData_v207 {
Open9xExpoData_v201 expoData[14];
int8_t curves5[8][5];
int8_t curves9[8][9];
Open9xGruvin9xLogicalSwitchData_v207 customSw[12];
Open9xFuncSwData_v203 funcSw[16];
Open9xGruvin9xLogicalSwitchData_v207 logicalSw[12];
Open9xCustomFunctionData_v203 customFn[16];
Open9xGruvin9xSwashRingData_v208 swashR;
Open9xGruvin9xFlightModeData_v207 flightModeData[5];
Open9xFrSkyData_v205 frsky;
@ -228,8 +228,8 @@ PACK(typedef struct t_Open9xGruvin9xModelData_v208 {
Open9xExpoData_v201 expoData[14];
int8_t curves5[8][5];
int8_t curves9[8][9];
Open9xGruvin9xLogicalSwitchData_v207 customSw[12];
Open9xGruvin9xFuncSwData_v203 funcSw[16];
Open9xGruvin9xLogicalSwitchData_v207 logicalSw[12];
Open9xGruvin9xCustomFunctionData_v203 customFn[16];
Open9xGruvin9xSwashRingData_v208 swashR;
Open9xGruvin9xFlightModeData_v208 flightModeData[5];
Open9xFrSkyData_v208 frsky;
@ -267,8 +267,8 @@ PACK(typedef struct t_Open9xGruvin9xModelData_v209 {
Open9xExpoData_v201 expoData[14];
int8_t curves5[8][5];
int8_t curves9[8][9];
Open9xGruvin9xLogicalSwitchData_v209 customSw[12];
Open9xGruvin9xFuncSwData_v203 funcSw[16];
Open9xGruvin9xLogicalSwitchData_v209 logicalSw[12];
Open9xGruvin9xCustomFunctionData_v203 customFn[16];
Open9xGruvin9xSwashRingData_v209 swashR;
Open9xGruvin9xFlightModeData_v208 flightModeData[5];
Open9xFrSkyData_v208 frsky;
@ -307,8 +307,8 @@ PACK(typedef struct t_Open9xGruvin9xModelData_v210 {
Open9xExpoData_v201 expoData[14];
int8_t curves[8];
int8_t points[112-8];
Open9xGruvin9xLogicalSwitchData_v209 customSw[12];
Open9xGruvin9xFuncSwData_v210 funcSw[16];
Open9xGruvin9xLogicalSwitchData_v209 logicalSw[12];
Open9xGruvin9xCustomFunctionData_v210 customFn[16];
Open9xGruvin9xSwashRingData_v209 swashR;
Open9xGruvin9xFlightModeData_v208 flightModeData[5];
@ -345,8 +345,8 @@ PACK(typedef struct t_Open9xGruvin9xModelData_v211 {
Open9xExpoData_v211 expoData[14];
int8_t curves[8];
int8_t points[112-8];
Open9xGruvin9xLogicalSwitchData_v209 customSw[12];
Open9xGruvin9xFuncSwData_v210 funcSw[16];
Open9xGruvin9xLogicalSwitchData_v209 logicalSw[12];
Open9xGruvin9xCustomFunctionData_v210 customFn[16];
Open9xGruvin9xSwashRingData_v209 swashR;
Open9xGruvin9xFlightModeData_v208 flightModeData[5];

View file

@ -571,9 +571,9 @@ t_Open9xArmLogicalSwitchData_v210::operator LogicalSwitchData ()
return c9x;
}
t_Open9xArmFuncSwData_v208::operator FuncSwData ()
t_Open9xArmCustomFunctionData_v208::operator CustomFunctionData ()
{
FuncSwData c9x;
CustomFunctionData c9x;
c9x.swtch = open9xArmToSwitch(swtch);
c9x.func = (AssignFunc)(func);
if (c9x.func <= FuncOverrideCH32) {
@ -589,9 +589,9 @@ t_Open9xArmFuncSwData_v208::operator FuncSwData ()
return c9x;
}
t_Open9xArmFuncSwData_v210::operator FuncSwData ()
t_Open9xArmCustomFunctionData_v210::operator CustomFunctionData ()
{
FuncSwData c9x;
CustomFunctionData c9x;
c9x.swtch = open9xArmToSwitch(swtch);
c9x.func = (AssignFunc)(func);
uint32_t value = *((uint32_t *)param);
@ -613,9 +613,9 @@ t_Open9xArmFuncSwData_v210::operator FuncSwData ()
return c9x;
}
t_Open9xArmFuncSwData_v211::operator FuncSwData ()
t_Open9xArmCustomFunctionData_v211::operator CustomFunctionData ()
{
FuncSwData c9x;
CustomFunctionData c9x;
c9x.swtch = open9xArmToSwitch(swtch);
c9x.func = (AssignFunc)(func);
uint32_t value = *((uint32_t *)param);
@ -798,9 +798,9 @@ t_Open9xArmModelData_v208::operator ModelData ()
}
}
for (int i=0; i<32; i++)
c9x.customSw[i] = customSw[i];
c9x.logicalSw[i] = logicalSw[i];
for (int i=0; i<32; i++)
c9x.funcSw[i] = funcSw[i];
c9x.customFn[i] = customFn[i];
c9x.swashRingData = swashR;
c9x.frsky = frsky;
c9x.frsky.varioSource = varioSource;
@ -887,9 +887,9 @@ t_Open9xArmModelData_v209::operator ModelData ()
}
}
for (int i=0; i<32; i++)
c9x.customSw[i] = customSw[i];
c9x.logicalSw[i] = logicalSw[i];
for (int i=0; i<32; i++)
c9x.funcSw[i] = funcSw[i];
c9x.customFn[i] = customFn[i];
c9x.swashRingData = swashR;
c9x.frsky = frsky;
c9x.frsky.varioSource = varioSource;
@ -977,9 +977,9 @@ t_Open9xArmModelData_v210::operator ModelData ()
}
}
for (int i=0; i<32; i++)
c9x.customSw[i] = customSw[i];
c9x.logicalSw[i] = logicalSw[i];
for (int i=0; i<32; i++)
c9x.funcSw[i] = funcSw[i];
c9x.customFn[i] = customFn[i];
c9x.swashRingData = swashR;
c9x.frsky = frsky;
c9x.frsky.varioSource = varioSource;
@ -1064,9 +1064,9 @@ t_Open9xArmModelData_v211::operator ModelData ()
}
}
for (int i=0; i<32; i++)
c9x.customSw[i] = customSw[i];
c9x.logicalSw[i] = logicalSw[i];
for (int i=0; i<32; i++)
c9x.funcSw[i] = funcSw[i];
c9x.customFn[i] = customFn[i];
c9x.swashRingData = swashR;
c9x.frsky = frsky;
c9x.switchWarningStates = switchWarningStates;
@ -1151,9 +1151,9 @@ t_Open9xArmModelData_v212::operator ModelData ()
}
}
for (int i=0; i<32; i++)
c9x.customSw[i] = customSw[i];
c9x.logicalSw[i] = logicalSw[i];
for (int i=0; i<32; i++)
c9x.funcSw[i] = funcSw[i];
c9x.customFn[i] = customFn[i];
c9x.swashRingData = swashR;
c9x.frsky = frsky;
c9x.switchWarningStates = switchWarningStates;

View file

@ -208,34 +208,34 @@ PACK(typedef struct t_Open9xArmLogicalSwitchData_v210 { // Custom Switches data
t_Open9xArmLogicalSwitchData_v210() { memset(this, 0, sizeof(t_Open9xArmLogicalSwitchData_v210)); }
}) Open9xArmLogicalSwitchData_v210;
PACK(typedef struct t_Open9xArmFuncSwData_v208 { // Function Switches data
PACK(typedef struct t_Open9xArmCustomFunctionData_v208 { // Function Switches data
int8_t swtch; // input
uint8_t func;
uint8_t param;
operator FuncSwData();
t_Open9xArmFuncSwData_v208() { memset(this, 0, sizeof(t_Open9xArmFuncSwData_v208)); }
}) Open9xArmFuncSwData_v208;
operator CustomFunctionData();
t_Open9xArmCustomFunctionData_v208() { memset(this, 0, sizeof(t_Open9xArmCustomFunctionData_v208)); }
}) Open9xArmCustomFunctionData_v208;
PACK(typedef struct t_Open9xArmFuncSwData_v210 { // Function Switches data
PACK(typedef struct t_Open9xArmCustomFunctionData_v210 { // Function Switches data
int8_t swtch; // input
uint8_t func;
char param[6];
operator FuncSwData();
t_Open9xArmFuncSwData_v210() { memset(this, 0, sizeof(t_Open9xArmFuncSwData_v210)); }
}) Open9xArmFuncSwData_v210;
operator CustomFunctionData();
t_Open9xArmCustomFunctionData_v210() { memset(this, 0, sizeof(t_Open9xArmCustomFunctionData_v210)); }
}) Open9xArmCustomFunctionData_v210;
PACK(typedef struct t_Open9xArmFuncSwData_v211 { // Function Switches data
PACK(typedef struct t_Open9xArmCustomFunctionData_v211 { // Function Switches data
int8_t swtch; // input
uint8_t func;
char param[6];
uint8_t delay;
uint8_t spare;
operator FuncSwData();
t_Open9xArmFuncSwData_v211() { memset(this, 0, sizeof(t_Open9xArmFuncSwData_v211)); }
}) Open9xArmFuncSwData_v211;
operator CustomFunctionData();
t_Open9xArmCustomFunctionData_v211() { memset(this, 0, sizeof(t_Open9xArmCustomFunctionData_v211)); }
}) Open9xArmCustomFunctionData_v211;
PACK(typedef struct t_Open9xArmSwashRingData_v208 { // Swash Ring data
uint8_t invertELE:1;
@ -332,8 +332,8 @@ PACK(typedef struct t_Open9xArmModelData_v208 {
Open9xArmExpoData_v208 expoData[32];
int8_t curves5[8][5];
int8_t curves9[8][9];
Open9xArmLogicalSwitchData_v208 customSw[32];
Open9xArmFuncSwData_v208 funcSw[32];
Open9xArmLogicalSwitchData_v208 logicalSw[32];
Open9xArmCustomFunctionData_v208 customFn[32];
Open9xArmSwashRingData_v208 swashR;
Open9xArmFlightModeData_v208 flightModeData[9];
Open9xFrSkyData_v208 frsky;
@ -371,8 +371,8 @@ PACK(typedef struct t_Open9xArmModelData_v209 {
Open9xArmExpoData_v208 expoData[32];
int8_t curves5[8][5];
int8_t curves9[8][9];
Open9xArmLogicalSwitchData_v209 customSw[32];
Open9xArmFuncSwData_v208 funcSw[32];
Open9xArmLogicalSwitchData_v209 logicalSw[32];
Open9xArmCustomFunctionData_v208 customFn[32];
Open9xArmSwashRingData_v209 swashR;
Open9xArmFlightModeData_v208 flightModeData[9];
Open9xFrSkyData_v208 frsky;
@ -411,8 +411,8 @@ PACK(typedef struct t_Open9xArmModelData_v210 {
Open9xArmExpoData_v210 expoData[32];
int8_t curves5[8][5];
int8_t curves9[8][9];
Open9xArmLogicalSwitchData_v210 customSw[32];
Open9xArmFuncSwData_v210 funcSw[32];
Open9xArmLogicalSwitchData_v210 logicalSw[32];
Open9xArmCustomFunctionData_v210 customFn[32];
Open9xArmSwashRingData_v209 swashR;
Open9xArmFlightModeData_v208 flightModeData[9];
Open9xArmFrSkyData_v210 frsky;
@ -450,8 +450,8 @@ PACK(typedef struct t_Open9xArmModelData_v211 {
Open9xArmExpoData_v210 expoData[32];
int16_t curves[16];
int8_t points[512];
Open9xArmLogicalSwitchData_v210 customSw[32];
Open9xArmFuncSwData_v211 funcSw[32];
Open9xArmLogicalSwitchData_v210 logicalSw[32];
Open9xArmCustomFunctionData_v211 customFn[32];
Open9xArmSwashRingData_v209 swashR;
Open9xArmFlightModeData_v208 flightModeData[9];
@ -488,8 +488,8 @@ PACK(typedef struct t_Open9xArmModelData_v212 {
Open9xArmExpoData_v212 expoData[32];
int16_t curves[16];
int8_t points[512];
Open9xArmLogicalSwitchData_v210 customSw[32];
Open9xArmFuncSwData_v211 funcSw[32];
Open9xArmLogicalSwitchData_v210 logicalSw[32];
Open9xArmCustomFunctionData_v211 customFn[32];
Open9xArmSwashRingData_v210 swashR;
Open9xArmFlightModeData_v212 flightModeData[9];

View file

@ -564,9 +564,9 @@ Open9xLogicalSwitchData_v209::operator LogicalSwitchData ()
return c9x;
}
t_Open9xFuncSwData_v201::operator FuncSwData ()
t_Open9xCustomFunctionData_v201::operator CustomFunctionData ()
{
FuncSwData c9x;
CustomFunctionData c9x;
c9x.swtch = open9xStockToSwitch(swtch);
c9x.func = (AssignFunc)(func+16);
return c9x;
@ -598,9 +598,9 @@ enum Functions {
FUNC_MAX
};
t_Open9xFuncSwData_v203::operator FuncSwData ()
t_Open9xCustomFunctionData_v203::operator CustomFunctionData ()
{
FuncSwData c9x;
CustomFunctionData c9x;
c9x.swtch = open9xStockToSwitch(swtch);
if (func < 16) {
c9x.enabled=param & 0x01;
@ -628,9 +628,9 @@ t_Open9xFuncSwData_v203::operator FuncSwData ()
return c9x;
}
t_Open9xFuncSwData_v210::operator FuncSwData ()
t_Open9xCustomFunctionData_v210::operator CustomFunctionData ()
{
FuncSwData c9x;
CustomFunctionData c9x;
c9x.swtch = open9xStockToSwitch(swtch);
c9x.param = param;
if (func < 22) {
@ -977,9 +977,9 @@ t_Open9xModelData_v201::operator ModelData ()
}
for (int i=0; i<12; i++)
c9x.customSw[i] = customSw[i];
c9x.logicalSw[i] = logicalSw[i];
for (int i=0; i<12; i++)
c9x.funcSw[i] = funcSw[i];
c9x.customFn[i] = customFn[i];
// for (int i=0; i<16; i++)
// c9x.safetySw[i] = safetySw[i];
c9x.swashRingData = swashR;
@ -1051,9 +1051,9 @@ t_Open9xModelData_v202::operator ModelData ()
}
for (int i=0; i<12; i++)
c9x.customSw[i] = customSw[i];
c9x.logicalSw[i] = logicalSw[i];
for (int i=0; i<12; i++)
c9x.funcSw[i] = funcSw[i];
c9x.customFn[i] = customFn[i];
// for (int i=0; i<16; i++)
// c9x.safetySw[i] = safetySw[i];
c9x.swashRingData = swashR;
@ -1127,9 +1127,9 @@ t_Open9xModelData_v203::operator ModelData ()
}
for (int i=0; i<12; i++)
c9x.customSw[i] = customSw[i];
c9x.logicalSw[i] = logicalSw[i];
for (int i=0; i<16; i++)
c9x.funcSw[i] = funcSw[i];
c9x.customFn[i] = customFn[i];
c9x.swashRingData = swashR;
c9x.frsky = frsky;
c9x.moduleData[0].ppmFrameLength = ppmFrameLength;
@ -1201,9 +1201,9 @@ t_Open9xModelData_v204::operator ModelData ()
}
for (int i=0; i<12; i++)
c9x.customSw[i] = customSw[i];
c9x.logicalSw[i] = logicalSw[i];
for (int i=0; i<16; i++)
c9x.funcSw[i] = funcSw[i];
c9x.customFn[i] = customFn[i];
c9x.swashRingData = swashR;
c9x.frsky = frsky;
c9x.frsky.rssiAlarms[0] = frskyRssiAlarms[0].get(0);
@ -1280,9 +1280,9 @@ t_Open9xModelData_v205::operator ModelData ()
}
for (int i=0; i<12; i++)
c9x.customSw[i] = customSw[i];
c9x.logicalSw[i] = logicalSw[i];
for (int i=0; i<16; i++)
c9x.funcSw[i] = funcSw[i];
c9x.customFn[i] = customFn[i];
c9x.swashRingData = swashR;
c9x.frsky = frsky;
c9x.moduleData[0].ppmFrameLength = ppmFrameLength;
@ -1366,9 +1366,9 @@ t_Open9xModelData_v208::operator ModelData ()
}
for (int i=0; i<12; i++)
c9x.customSw[i] = customSw[i];
c9x.logicalSw[i] = logicalSw[i];
for (int i=0; i<16; i++)
c9x.funcSw[i] = funcSw[i];
c9x.customFn[i] = customFn[i];
c9x.swashRingData = swashR;
c9x.frsky = frsky;
c9x.frsky.varioSource = varioSource;
@ -1459,9 +1459,9 @@ t_Open9xModelData_v209::operator ModelData ()
}
for (int i=0; i<12; i++)
c9x.customSw[i] = customSw[i];
c9x.logicalSw[i] = logicalSw[i];
for (int i=0; i<16; i++)
c9x.funcSw[i] = funcSw[i];
c9x.customFn[i] = customFn[i];
c9x.swashRingData = swashR;
c9x.frsky = frsky;
c9x.frsky.varioSource = varioSource;
@ -1556,9 +1556,9 @@ t_Open9xModelData_v210::operator ModelData ()
}
for (int i=0; i<12; i++)
c9x.customSw[i] = customSw[i];
c9x.logicalSw[i] = logicalSw[i];
for (int i=0; i<16; i++)
c9x.funcSw[i] = funcSw[i];
c9x.customFn[i] = customFn[i];
c9x.swashRingData = swashR;
c9x.frsky = frsky;
c9x.switchWarningStates = switchWarningStates;
@ -1644,9 +1644,9 @@ t_Open9xModelData_v211::operator ModelData ()
}
for (int i=0; i<12; i++)
c9x.customSw[i] = customSw[i];
c9x.logicalSw[i] = logicalSw[i];
for (int i=0; i<16; i++)
c9x.funcSw[i] = funcSw[i];
c9x.customFn[i] = customFn[i];
c9x.swashRingData = swashR;
c9x.frsky = frsky;
c9x.switchWarningStates = switchWarningStates;

View file

@ -247,32 +247,32 @@ PACK(typedef struct t_Open9xSafetySwData { // Safety Switches data
t_Open9xSafetySwData() { memset(this, 0, sizeof(t_Open9xSafetySwData)); }
}) Open9xSafetySwData;
PACK(typedef struct t_Open9xFuncSwData_v201 { // Function Switches data
PACK(typedef struct t_Open9xCustomFunctionData_v201 { // Function Switches data
int8_t swtch; // input
uint8_t func;
operator FuncSwData();
t_Open9xFuncSwData_v201() { memset(this, 0, sizeof(t_Open9xFuncSwData_v201)); }
}) Open9xFuncSwData_v201;
operator CustomFunctionData();
t_Open9xCustomFunctionData_v201() { memset(this, 0, sizeof(t_Open9xCustomFunctionData_v201)); }
}) Open9xCustomFunctionData_v201;
PACK(typedef struct t_Open9xFuncSwData_v203 { // Function Switches data
PACK(typedef struct t_Open9xCustomFunctionData_v203 { // Function Switches data
int8_t swtch; // input
uint8_t func;
uint8_t param;
operator FuncSwData();
t_Open9xFuncSwData_v203() { memset(this, 0, sizeof(t_Open9xFuncSwData_v203)); }
}) Open9xFuncSwData_v203;
operator CustomFunctionData();
t_Open9xCustomFunctionData_v203() { memset(this, 0, sizeof(t_Open9xCustomFunctionData_v203)); }
}) Open9xCustomFunctionData_v203;
PACK(typedef struct t_Open9xFuncSwData_v210 { // Function Switches data
PACK(typedef struct t_Open9xCustomFunctionData_v210 { // Function Switches data
int8_t swtch; // input
uint8_t func:5;
uint8_t delay:3;
uint8_t param;
operator FuncSwData();
t_Open9xFuncSwData_v210() { memset(this, 0, sizeof(t_Open9xFuncSwData_v210)); }
}) Open9xFuncSwData_v210;
operator CustomFunctionData();
t_Open9xCustomFunctionData_v210() { memset(this, 0, sizeof(t_Open9xCustomFunctionData_v210)); }
}) Open9xCustomFunctionData_v210;
PACK(typedef struct t_Open9xFrSkyChannelData_v201 {
uint8_t ratio; // 0.0 means not used, 0.1V steps EG. 6.6 Volts = 66. 25.1V = 251, etc.
@ -502,9 +502,9 @@ PACK(typedef struct t_Open9xModelData_v201 {
Open9xExpoData_v201 expoData[14];
int8_t curves5[8][5];
int8_t curves9[8][9];
Open9xLogicalSwitchData_v208 customSw[12];
Open9xLogicalSwitchData_v208 logicalSw[12];
Open9xSafetySwData safetySw[16];
Open9xFuncSwData_v201 funcSw[12];
Open9xCustomFunctionData_v201 customFn[12];
Open9xSwashRingData_v208 swashR;
Open9xFlightModeData_v201 flightModeData[5];
Open9xFrSkyData_v201 frsky;
@ -533,9 +533,9 @@ PACK(typedef struct t_Open9xModelData_v202 {
Open9xExpoData_v201 expoData[14];
int8_t curves5[8][5];
int8_t curves9[8][9];
Open9xLogicalSwitchData_v208 customSw[12];
Open9xLogicalSwitchData_v208 logicalSw[12];
Open9xSafetySwData safetySw[16];
Open9xFuncSwData_v201 funcSw[12];
Open9xCustomFunctionData_v201 customFn[12];
Open9xSwashRingData_v208 swashR;
Open9xFlightModeData_v201 flightModeData[5];
Open9xFrSkyData_v202 frsky;
@ -567,8 +567,8 @@ PACK(typedef struct t_Open9xModelData_v203 {
Open9xExpoData_v201 expoData[14];
int8_t curves5[8][5];
int8_t curves9[8][9];
Open9xLogicalSwitchData_v208 customSw[12];
Open9xFuncSwData_v203 funcSw[16];
Open9xLogicalSwitchData_v208 logicalSw[12];
Open9xCustomFunctionData_v203 customFn[16];
Open9xSwashRingData_v208 swashR;
Open9xFlightModeData_v201 flightModeData[5];
Open9xFrSkyData_v202 frsky;
@ -600,8 +600,8 @@ PACK(typedef struct t_Open9xModelData_v204 {
Open9xExpoData_v201 expoData[14];
int8_t curves5[8][5];
int8_t curves9[8][9];
Open9xLogicalSwitchData_v208 customSw[12];
Open9xFuncSwData_v203 funcSw[16];
Open9xLogicalSwitchData_v208 logicalSw[12];
Open9xCustomFunctionData_v203 customFn[16];
Open9xSwashRingData_v208 swashR;
Open9xFlightModeData_v201 flightModeData[5];
Open9xFrSkyData_v204 frsky;
@ -633,8 +633,8 @@ PACK(typedef struct t_Open9xModelData_v205 {
Open9xExpoData_v201 expoData[14];
int8_t curves5[8][5];
int8_t curves9[8][9];
Open9xLogicalSwitchData_v208 customSw[12];
Open9xFuncSwData_v203 funcSw[16];
Open9xLogicalSwitchData_v208 logicalSw[12];
Open9xCustomFunctionData_v203 customFn[16];
Open9xSwashRingData_v208 swashR;
Open9xFlightModeData_v201 flightModeData[5];
Open9xFrSkyData_v205 frsky;
@ -668,8 +668,8 @@ PACK(typedef struct t_Open9xModelData_v208 {
Open9xExpoData_v201 expoData[14];
int8_t curves5[8][5];
int8_t curves9[8][9];
Open9xLogicalSwitchData_v208 customSw[12];
Open9xFuncSwData_v203 funcSw[16];
Open9xLogicalSwitchData_v208 logicalSw[12];
Open9xCustomFunctionData_v203 customFn[16];
Open9xSwashRingData_v208 swashR;
Open9xFlightModeData_v201 flightModeData[5];
Open9xFrSkyData_v208 frsky;
@ -707,8 +707,8 @@ PACK(typedef struct t_Open9xModelData_v209 {
Open9xExpoData_v201 expoData[14];
int8_t curves5[8][5];
int8_t curves9[8][9];
Open9xLogicalSwitchData_v209 customSw[12];
Open9xFuncSwData_v203 funcSw[16];
Open9xLogicalSwitchData_v209 logicalSw[12];
Open9xCustomFunctionData_v203 customFn[16];
Open9xSwashRingData_v209 swashR;
Open9xFlightModeData_v201 flightModeData[5];
Open9xFrSkyData_v208 frsky;
@ -747,8 +747,8 @@ PACK(typedef struct t_Open9xModelData_v210 {
Open9xExpoData_v201 expoData[14];
int8_t curves[8];
int8_t points[112-8];
Open9xLogicalSwitchData_v209 customSw[12];
Open9xFuncSwData_v210 funcSw[16];
Open9xLogicalSwitchData_v209 logicalSw[12];
Open9xCustomFunctionData_v210 customFn[16];
Open9xSwashRingData_v209 swashR;
Open9xFlightModeData_v201 flightModeData[5];
@ -785,8 +785,8 @@ PACK(typedef struct t_Open9xModelData_v211 {
Open9xExpoData_v211 expoData[14];
int8_t curves[8];
int8_t points[112-8];
Open9xLogicalSwitchData_v209 customSw[12];
Open9xFuncSwData_v210 funcSw[16];
Open9xLogicalSwitchData_v209 logicalSw[12];
Open9xCustomFunctionData_v210 customFn[16];
Open9xSwashRingData_v209 swashR;
Open9xFlightModeData_v201 flightModeData[5];

View file

@ -65,6 +65,7 @@ namespace Open9xGruvin9x {
#include "radio/src/opentx.cpp"
#include "radio/src/strhelpers.cpp"
#include "radio/src/switches.cpp"
#include "radio/src/functions.cpp"
#include "radio/src/curves.cpp"
#include "radio/src/mixer.cpp"
#include "radio/src/pulses/pulses_avr.cpp"

View file

@ -66,6 +66,7 @@ namespace OpenTxM128 {
#include "radio/src/opentx.cpp"
#include "radio/src/strhelpers.cpp"
#include "radio/src/switches.cpp"
#include "radio/src/functions.cpp"
#include "radio/src/curves.cpp"
#include "radio/src/mixer.cpp"
#include "radio/src/pulses/pulses_avr.cpp"

View file

@ -71,6 +71,7 @@ namespace OpenTxM64 {
#include "radio/src/opentx.cpp"
#include "radio/src/strhelpers.cpp"
#include "radio/src/switches.cpp"
#include "radio/src/functions.cpp"
#include "radio/src/curves.cpp"
#include "radio/src/mixer.cpp"
#include "radio/src/pulses/pulses_avr.cpp"

View file

@ -78,6 +78,7 @@ namespace Open9xSky9x {
#include "radio/src/opentx.cpp"
#include "radio/src/strhelpers.cpp"
#include "radio/src/switches.cpp"
#include "radio/src/functions.cpp"
#include "radio/src/mixer.cpp"
#include "radio/src/curves.cpp"
#include "radio/src/targets/sky9x/pulses_driver.cpp"

View file

@ -81,6 +81,7 @@ inline int geteepromsize() {
#include "radio/src/opentx.cpp"
#include "radio/src/strhelpers.cpp"
#include "radio/src/switches.cpp"
#include "radio/src/functions.cpp"
#include "radio/src/curves.cpp"
#include "radio/src/mixer.cpp"
#include "radio/src/targets/taranis/pulses_driver.cpp"

View file

@ -1879,7 +1879,7 @@ class SwitchesWarningField: public TransformedField {
class ArmCustomFunctionField: public TransformedField {
public:
ArmCustomFunctionField(FuncSwData & fn, BoardEnum board, unsigned int version, unsigned int variant):
ArmCustomFunctionField(CustomFunctionData & fn, BoardEnum board, unsigned int version, unsigned int variant):
TransformedField(internalField),
internalField("CustomFunction"),
fn(fn),
@ -2073,7 +2073,7 @@ class ArmCustomFunctionField: public TransformedField {
protected:
StructField internalField;
FuncSwData & fn;
CustomFunctionData & fn;
BoardEnum board;
unsigned int version;
unsigned int variant;
@ -2086,7 +2086,7 @@ class ArmCustomFunctionField: public TransformedField {
class AvrCustomFunctionField: public TransformedField {
public:
AvrCustomFunctionField(FuncSwData & fn, BoardEnum board, unsigned int version, unsigned int variant):
AvrCustomFunctionField(CustomFunctionData & fn, BoardEnum board, unsigned int version, unsigned int variant):
TransformedField(internalField),
internalField("CustomFunction"),
fn(fn),
@ -2237,7 +2237,7 @@ class AvrCustomFunctionField: public TransformedField {
protected:
StructField internalField;
FuncSwData & fn;
CustomFunctionData & fn;
BoardEnum board;
unsigned int version;
unsigned int variant;
@ -2645,12 +2645,12 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, BoardEnum board, unsigne
internalField.Append(new InputField(modelData.expoData[i], board, version));
internalField.Append(new CurvesField(modelData.curves, board, version));
for (int i=0; i<MAX_CUSTOM_SWITCHES(board, version); i++)
internalField.Append(new LogicalSwitchField(modelData.customSw[i], board, version, variant, &modelData));
internalField.Append(new LogicalSwitchField(modelData.logicalSw[i], board, version, variant, &modelData));
for (int i=0; i<MAX_CUSTOM_FUNCTIONS(board, version); i++) {
if (IS_ARM(board))
internalField.Append(new ArmCustomFunctionField(modelData.funcSw[i], board, version, variant));
internalField.Append(new ArmCustomFunctionField(modelData.customFn[i], board, version, variant));
else
internalField.Append(new AvrCustomFunctionField(modelData.funcSw[i], board, version, variant));
internalField.Append(new AvrCustomFunctionField(modelData.customFn[i], board, version, variant));
}
internalField.Append(new HeliField(modelData.swashRingData, board, version, variant));
for (int i=0; i<MAX_FLIGHT_MODES(board, version); i++)

View file

@ -274,9 +274,9 @@ t_Th9xModelData::operator ModelData ()
c9x.thrTrim = thrTrim;
c9x.trimInc = trimInc;
c9x.moduleData[0].ppmDelay = 300 + 50 * ppmDelay;
c9x.funcSw[0].func = FuncTrims2Offsets;
c9x.customFn[0].func = FuncTrims2Offsets;
if (trimSw) {
c9x.funcSw[0].swtch = trimSw;
c9x.customFn[0].swtch = trimSw;
}
c9x.beepANACenter = beepANACenter;
c9x.pulsePol = pulsePol;

View file

@ -70,8 +70,8 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData & model,
if (!firmware->getCapability(VoicesAsNumbers)) {
for (int i=0; i<num_fsw; i++) {
if (model.funcSw[i].func==FuncPlayPrompt || model.funcSw[i].func==FuncBackgroundMusic) {
QString temp = model.funcSw[i].paramarm;
if (model.customFn[i].func==FuncPlayPrompt || model.customFn[i].func==FuncBackgroundMusic) {
QString temp = model.customFn[i].paramarm;
if (!temp.isEmpty()) {
if (!paramarmList.contains(temp)) {
paramarmList.append(temp);
@ -181,7 +181,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData & model,
QHBoxLayout *repeatLayout = new QHBoxLayout();
gridLayout->addLayout(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; j<std::min(fswtchParamArmT[i]->currentText().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; j<std::min(fswtchParamArmT[i]->currentText().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; i<firmware->getCapability(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; i<FuncCount; i++) {
b->addItem(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)) ||

View file

@ -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);

View file

@ -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)

View file

@ -577,10 +577,10 @@ void PrintDialog::printSwitches()
str.append("<tr><td><table border=0 cellspacing=0 cellpadding=3>");
for (int i=0; i<firmware->getCapability(LogicalSwitches); i++) {
if (g_model->customSw[i].func) {
if (g_model->logicalSw[i].func) {
str.append("<tr>");
str.append("<td width=\"60\"><b>"+tr("L")+QString("%1</b></td>").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("</tr>");
sc++;
@ -630,21 +630,21 @@ void PrintDialog::printFSwitches()
str.append(doTL(tr("Enabled"), "", true));
str.append("</tr>");
for(int i=0; i<firmware->getCapability(CustomFunctions); i++) {
if (g_model->funcSw[i].swtch.type!=SWITCH_TYPE_NONE) {
if (g_model->customFn[i].swtch.type!=SWITCH_TYPE_NONE) {
str.append("<tr>");
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( "&nbsp;","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"));
}

View file

@ -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

View file

@ -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.

View file

@ -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<NUM_CFN; i++) {
CustomFnData & fn = newModel.funcSw[i];
fn = oldModel.funcSw[i];
CustomFunctionData & fn = newModel.customFn[i];
fn = oldModel.customFn[i];
if (fn.func == FUNC_PLAY_VALUE || fn.func == FUNC_VOLUME || (IS_ADJUST_GV_FUNC(fn.func) && fn.all.mode == FUNC_ADJUST_GVAR_SOURCE)) {
fn.all.val = ConvertSource_216_to_217(fn.all.val);
}

View file

@ -394,9 +394,7 @@ void eeLoadModel(uint8_t id)
resumePulses();
}
activeFnSwitches = 0;
activeFunctions = 0;
memclear(lastFunctionTime, sizeof(lastFunctionTime));
customFunctionsReset();
for (uint8_t i=0; i<MAX_TIMERS; i++) {
if (g_model.timers[i].persistent) {

View file

@ -983,9 +983,7 @@ void eeLoadModel(uint8_t id)
resumePulses();
}
activeFnSwitches = 0;
activeFunctions = 0;
memclear(lastFunctionTime, sizeof(lastFunctionTime));
customFunctionsReset();
#if !defined(PCBSTD)
for (uint8_t i=0; i<MAX_TIMERS; i++) {

543
radio/src/functions.cpp Normal file
View file

@ -0,0 +1,543 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - 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<NUM_CHNOUT; i++) {
safetyCh[i] = OVERRIDE_CHANNEL_UNDEFINED;
}
#endif
#if defined(GVARS)
for (uint8_t i=0; i<NUM_STICKS; i++) {
trimGvar[i] = -1;
}
#endif
for (uint8_t i=0; i<NUM_CFN; i++) {
const CustomFunctionData *cfn = &functions[i];
int8_t swtch = CFN_SWITCH(cfn);
if (swtch) {
MASK_CFN_TYPE switch_mask = ((MASK_CFN_TYPE)1 << i);
#if defined(CPUARM)
bool active = getSwitch(swtch, IS_PLAY_FUNC(CFN_FUNC(cfn)) ? GETSWITCH_MIDPOS_DELAY : 0);
#else
bool active = getSwitch(swtch);
#endif
if (HAS_ENABLE_PARAM(CFN_FUNC(cfn))) {
active &= (bool)CFN_ACTIVE(cfn);
}
if (active || IS_PLAY_BOTH_FUNC(CFN_FUNC(cfn))) {
switch (CFN_FUNC(cfn)) {
#if defined(OVERRIDE_CHANNEL_FUNCTION)
case FUNC_OVERRIDE_CHANNEL:
safetyCh[CFN_CH_INDEX(cfn)] = CFN_PARAM(cfn);
break;
#endif
case FUNC_TRAINER:
{
uint8_t mask = 0x0f;
if (CFN_CH_INDEX(cfn) > 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<ROTARY_ENCODERS; i++) {
rePreviousValues[i] = (g_rotenc[i] / ROTARY_ENCODER_GRANULARITY);
}
#endif
}
#if !defined(CPUARM)
#undef functions
#undef functionsContext
#endif

View file

@ -73,6 +73,7 @@ const LanguagePack * LP_CONST languagePacks[] = {
enum EnumTabDiag {
e_Setup,
CASE_SDCARD(e_Sd)
CASE_CPUARM(e_GeneralCustomFunctions)
e_Trainer,
e_Vers,
e_Keys,
@ -83,6 +84,7 @@ enum EnumTabDiag {
void menuGeneralSetup(uint8_t event);
void menuGeneralSdManager(uint8_t event);
void menuGeneralCustomFunctions(uint8_t event);
void menuGeneralTrainer(uint8_t event);
void menuGeneralVersion(uint8_t event);
void menuGeneralDiagKeys(uint8_t event);
@ -90,9 +92,10 @@ void menuGeneralDiagAna(uint8_t event);
void menuGeneralHardware(uint8_t event);
void menuGeneralCalib(uint8_t event);
const MenuFuncP_PROGMEM menuTabDiag[] PROGMEM = {
const MenuFuncP_PROGMEM menuTabGeneral[] PROGMEM = {
menuGeneralSetup,
CASE_SDCARD(menuGeneralSdManager)
CASE_CPUARM(menuGeneralCustomFunctions)
menuGeneralTrainer,
menuGeneralVersion,
menuGeneralDiagKeys,
@ -215,7 +218,7 @@ void menuGeneralSetup(uint8_t event)
}
#endif
MENU(STR_MENURADIOSETUP, menuTabDiag, e_Setup, ITEM_SETUP_MAX+1, {0, CASE_RTCLOCK(2) CASE_RTCLOCK(2) CASE_BATTGRAPH(1) LABEL(SOUND), CASE_AUDIO(0) CASE_BUZZER(0) CASE_VOICE(0) CASE_CPUARM(0) CASE_CPUARM(0) CASE_CPUARM(0) 0, CASE_AUDIO(0) CASE_VARIO_CPUARM(LABEL(VARIO)) CASE_VARIO_CPUARM(0) CASE_VARIO_CPUARM(0) CASE_VARIO_CPUARM(0) CASE_VARIO_CPUARM(0) CASE_HAPTIC(LABEL(HAPTIC)) CASE_HAPTIC(0) CASE_HAPTIC(0) CASE_HAPTIC(0) 0, LABEL(ALARMS), 0, CASE_PCBSKY9X(0) CASE_PCBSKY9X(0) 0, 0, 0, IF_ROTARY_ENCODERS(0) LABEL(BACKLIGHT), 0, 0, CASE_CPUARM(0) CASE_REVPLUS(0) CASE_PWM_BACKLIGHT(0) CASE_PWM_BACKLIGHT(0) 0, CASE_SPLASH_PARAM(0) CASE_GPS(0) CASE_GPS(0) CASE_PXX(0) CASE_CPUARM(0) CASE_CPUARM(0) IF_FAI_CHOICE(0) CASE_MAVLINK(0) CASE_CPUARM(0) 0, COL_TX_MODE, CASE_PCBTARANIS(0) 1/*to force edit mode*/});
MENU(STR_MENURADIOSETUP, menuTabGeneral, e_Setup, ITEM_SETUP_MAX+1, {0, CASE_RTCLOCK(2) CASE_RTCLOCK(2) CASE_BATTGRAPH(1) LABEL(SOUND), CASE_AUDIO(0) CASE_BUZZER(0) CASE_VOICE(0) CASE_CPUARM(0) CASE_CPUARM(0) CASE_CPUARM(0) 0, CASE_AUDIO(0) CASE_VARIO_CPUARM(LABEL(VARIO)) CASE_VARIO_CPUARM(0) CASE_VARIO_CPUARM(0) CASE_VARIO_CPUARM(0) CASE_VARIO_CPUARM(0) CASE_HAPTIC(LABEL(HAPTIC)) CASE_HAPTIC(0) CASE_HAPTIC(0) CASE_HAPTIC(0) 0, LABEL(ALARMS), 0, CASE_PCBSKY9X(0) CASE_PCBSKY9X(0) 0, 0, 0, IF_ROTARY_ENCODERS(0) LABEL(BACKLIGHT), 0, 0, CASE_CPUARM(0) CASE_REVPLUS(0) CASE_PWM_BACKLIGHT(0) CASE_PWM_BACKLIGHT(0) 0, CASE_SPLASH_PARAM(0) CASE_GPS(0) CASE_GPS(0) CASE_PXX(0) CASE_CPUARM(0) CASE_CPUARM(0) IF_FAI_CHOICE(0) CASE_MAVLINK(0) CASE_CPUARM(0) 0, COL_TX_MODE, CASE_PCBTARANIS(0) 1/*to force edit mode*/});
uint8_t sub = m_posVert - 1;
@ -918,7 +921,7 @@ void menuGeneralSdManager(uint8_t _event)
#endif
uint8_t event = ((READ_ONLY() && EVT_KEY_MASK(_event) == KEY_ENTER) ? 0 : _event);
SIMPLE_MENU(SD_IS_HC() ? STR_SDHC_CARD : STR_SD_CARD, menuTabDiag, e_Sd, 1+reusableBuffer.sdmanager.count);
SIMPLE_MENU(SD_IS_HC() ? STR_SDHC_CARD : STR_SD_CARD, menuTabGeneral, e_Sd, 1+reusableBuffer.sdmanager.count);
if (s_editMode > 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;

View file

@ -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; i<NUM_CFN; i++) {
if (!CFN_EMPTY(&g_model.funcSw[i])) {
if (!CFN_EMPTY(&functions[i])) {
MENU_ADD_ITEM(STR_DELETE);
break;
}
@ -5093,27 +5105,32 @@ void menuModelCustomFunctions(uint8_t event)
putsStrIdx(0, y, STR_CF, k+1, (sub==k && m_posHorz<0) ? INVERS : 0);
#endif
CustomFnData *sd = &g_model.funcSw[k];
uint8_t func = CFN_FUNC(sd);
CustomFunctionData *cfn = &functions[k];
uint8_t func = CFN_FUNC(cfn);
for (uint8_t j=0; j<5; j++) {
uint8_t attr = ((sub==k && m_posHorz==j) ? ((s_editMode>0) ? BLINK|INVERS : INVERS) : 0);
uint8_t active = (attr && (s_editMode>0 || p1valdiff));
switch (j) {
case 0:
putsSwitches(MODEL_CUSTOM_FUNC_1ST_COLUMN, y, 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)
{

View file

@ -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) {
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:

View file

@ -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

View file

@ -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;
}

View file

@ -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 ===============

View file

@ -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];

View file

@ -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<NUM_CHNOUT; i++) {
safetyCh[i] = OVERRIDE_CHANNEL_UNDEFINED;
}
#endif
#if defined(GVARS)
for (uint8_t i=0; i<NUM_STICKS; i++) {
trimGvar[i] = -1;
}
#endif
for (uint8_t i=0; i<NUM_CFN; i++) {
CustomFnData *sd = &g_model.funcSw[i];
int8_t swtch = CFN_SWITCH(sd);
if (swtch) {
MASK_CFN_TYPE switch_mask = ((MASK_CFN_TYPE)1 << i);
#if defined(CPUARM)
bool active = getSwitch(swtch, IS_PLAY_FUNC(CFN_FUNC(sd)) ? GETSWITCH_MIDPOS_DELAY : 0);
#else
bool active = getSwitch(swtch);
#endif
if (HAS_ENABLE_PARAM(CFN_FUNC(sd))) {
active &= (bool)CFN_ACTIVE(sd);
}
if (active || IS_PLAY_BOTH_FUNC(CFN_FUNC(sd))) {
switch (CFN_FUNC(sd)) {
#if defined(OVERRIDE_CHANNEL_FUNCTION)
case FUNC_OVERRIDE_CHANNEL:
safetyCh[CFN_CH_INDEX(sd)] = CFN_PARAM(sd);
break;
#endif
case FUNC_TRAINER:
{
uint8_t mask = 0x0f;
if (CFN_CH_INDEX(sd) > 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<ROTARY_ENCODERS; i++) {
rePreviousValues[i] = (g_rotenc[i] / ROTARY_ENCODER_GRANULARITY);
}
#endif
}
uint8_t s_mixer_first_run_done = false;
void doMixerCalculations()

View file

@ -527,7 +527,6 @@ enum PotType {
#endif
#include "lcd.h"
#include "gui/menus.h"
#if defined(TEMPLATES)
#include "templates.h"
@ -1218,14 +1217,12 @@ void copyTrimsToOffset(uint8_t ch);
void copySticksToOffset(uint8_t ch);
void moveTrimsToOffsets();
void evalFunctions();
#if defined(CPUARM)
#define ACTIVE_PHASES_TYPE uint16_t
#define DELAY_POS_SHIFT 0
#define DELAY_POS_MARGIN 3
#define delayval_t int16_t
PACK(typedef struct t_SwOn {
PACK(typedef struct {
uint16_t delay;
int16_t now; // timer trigger source -> 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"

View file

@ -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;

View file

@ -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[];

View file

@ -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"

View file

@ -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"

View file

@ -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")

View file

@ -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")

View file

@ -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")

View file

@ -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")

View file

@ -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"

View file

@ -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.")

View file

@ -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"

View file

@ -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"