chores(flysky): Separate AFHDS2A and AFHDS3 into 2 different module type (#3783)

* chores(flysky): separate AFHDS2A and AFHDS3 into 2 different module type

This should allow to remove some of the hacks added earlier.

* chore: Add some EL18 CI bits

* fix(afhds): cmake defs

* fix(ci): add el18 to commit-tests.sh

* chore(cpn): separate AFHDS2A and AFHDS3

* chore(cpn): remove binary import of afhds and legacy fxFreq field for afhds3

* fix(cpn): limit available internal afhds protocols to those supported by hardware

* chore(cpn): update Flysky int module test

* fix(cpn): compile error

* fix(cpn): afhds2a max channels

* fix: TR_MODULE_PROTOCOLS

* enh(cpn): more support for afhds2a and 3

* fix(cpn): rebase compile error

* fix(cpn): bit indexes

* fix(cpn): emi toString

* fix(cpn): limit available internal afhds protocols to those supported by hardware

* enh(cpn): add support for Flysky EL18

* fix(cpn): available protocols

* fix(cpn): rebase moduledata

* chore(cpn): add module fields to model print

* Separate AFHDS2A and AFHDS3 UI settings.

* Fix AFHDS3 conversion from old subtype value.
Fix 'Channel Range' layout on portrait LCD.

* Fix name.

---------

Co-authored-by: Peter Feerick <peter.feerick@gmail.com>
Co-authored-by: elecpower <neilh713@tpg.com.au>
Co-authored-by: Phil Mitchell <phil.a.mitchell@gmail.com>
This commit is contained in:
Raphael Coeffic
2023-09-07 19:24:03 +10:00
committed by GitHub
co-authored by Peter Feerick elecpower Phil Mitchell
parent 9515d29c9d
commit c4f1e7127d
59 changed files with 1098 additions and 463 deletions
+7 -5
View File
@@ -138,11 +138,13 @@ if(CROSSFIRE)
add_gui_src(crossfire_settings.cpp)
endif()
if(AFHDS2 OR AFHDS3)
add_gui_src(flysky_settings.cpp)
if(AFHDS3)
add_gui_src(afhds3_options.cpp)
endif()
if(AFHDS2)
add_gui_src(afhds2a_settings.cpp)
endif()
if(AFHDS3)
add_gui_src(afhds3_settings.cpp)
add_gui_src(afhds3_options.cpp)
endif()
if(MULTIMODULE)
+141
View File
@@ -0,0 +1,141 @@
/*
* Copyright (C) EdgeTX
*
* Based on code named
* opentx - https://github.com/opentx/opentx
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* 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 "afhds2a_settings.h"
#include "opentx.h"
#include "pulses/flysky.h"
#define SET_DIRTY() storageDirty(EE_MODEL)
class FSProtoOpts : public FormWindow
{
std::function<uint8_t()> _getMode;
std::function<void(uint8_t)> _setMode;
public:
FSProtoOpts(Window* parent, std::function<uint8_t()> getMode,
std::function<void(uint8_t)> setMode);
};
FSProtoOpts::FSProtoOpts(Window* parent, std::function<uint8_t()> getMode,
std::function<void(uint8_t)> setMode) :
FormWindow(parent, rect_t{}),
_getMode(std::move(getMode)),
_setMode(std::move(setMode))
{
setFlexLayout(LV_FLEX_FLOW_ROW);
// PPM / PWM
new Choice(
this, rect_t{}, STR_FLYSKY_PULSE_PROTO, 0, 1,
[=]() -> int { return _getMode() >> 1; },
[=](int v) {
_setMode((_getMode() & 1) | ((v & 1) << 1));
SET_DIRTY();
});
// SBUS / iBUS
new Choice(
this, rect_t{}, STR_FLYSKY_SERIAL_PROTO, 0, 1,
[=]() -> int { return _getMode() & 1; },
[=](int v) {
_setMode((_getMode() & 2) | (v & 1));
SET_DIRTY();
});
}
AFHDS2ASettings::AFHDS2ASettings(Window* parent, const FlexGridLayout& g,
uint8_t moduleIdx) :
FormWindow(parent, rect_t{}),
moduleIdx(moduleIdx),
md(&g_model.moduleData[moduleIdx]),
grid(g)
{
setFlexLayout();
FormWindow::Line* line;
// RX options:
line = newLine(&grid);
afhds2OptionsLabel = new StaticText(line, rect_t{}, STR_OPTIONS, 0, COLOR_THEME_PRIMARY1);
afhds2ProtoOpts = new FSProtoOpts(
line, [=]() { return md->flysky.mode; },
[=](uint8_t v) { md->flysky.mode = v; });
#if defined(PCBNV14)
if (getNV14RfFwVersion() >= 0x1000E) {
line = newLine(&grid);
static const char* _rf_power[] = {"Default", "High"};
afhds2RFPowerText = new StaticText(line, rect_t{}, STR_MULTI_RFPOWER);
afhds2RFPowerChoice = new Choice(line, rect_t{}, _rf_power, 0, 1,
GET_DEFAULT(md->flysky.rfPower),
[=](int32_t newValue) -> void {
md->flysky.rfPower = newValue;
resetPulsesAFHDS2();
});
#endif
}
hideAFHDS2Options();
}
void AFHDS2ASettings::hideAFHDS2Options()
{
lv_obj_add_flag(afhds2OptionsLabel->getLvObj(), LV_OBJ_FLAG_HIDDEN);
lv_obj_add_flag(afhds2ProtoOpts->getLvObj(), LV_OBJ_FLAG_HIDDEN);
#if defined(PCBNV14)
if (afhds2RFPowerText != nullptr)
lv_obj_add_flag(afhds2RFPowerText->getLvObj(), LV_OBJ_FLAG_HIDDEN);
if (afhds2RFPowerChoice != nullptr)
lv_obj_add_flag(afhds2RFPowerChoice->getLvObj(), LV_OBJ_FLAG_HIDDEN);
#endif
}
void AFHDS2ASettings::showAFHDS2Options()
{
lv_obj_clear_flag(afhds2OptionsLabel->getLvObj(), LV_OBJ_FLAG_HIDDEN);
lv_obj_clear_flag(afhds2ProtoOpts->getLvObj(), LV_OBJ_FLAG_HIDDEN);
#if defined(PCBNV14)
if (afhds2RFPowerText != nullptr)
lv_obj_clear_flag(afhds2RFPowerText->getLvObj(), LV_OBJ_FLAG_HIDDEN);
if (afhds2RFPowerChoice != nullptr)
{
lv_obj_clear_flag(afhds2RFPowerChoice->getLvObj(), LV_OBJ_FLAG_HIDDEN);
lv_event_send(afhds2RFPowerChoice->getLvObj(), LV_EVENT_VALUE_CHANGED, nullptr);
}
#endif
}
void AFHDS2ASettings::checkEvents() {
FormWindow::checkEvents();
}
void AFHDS2ASettings::update()
{
lastRefresh = get_tmr10ms();
if (isModuleAFHDS2A(moduleIdx)) {
showAFHDS2Options();
} else {
hideAFHDS2Options();
}
}
+51
View File
@@ -0,0 +1,51 @@
/*
* Copyright (C) EdgeTX
*
* Based on code named
* opentx - https://github.com/opentx/opentx
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* 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.
*/
#pragma once
#include "form.h"
#include "choice.h"
#include "module_setup.h"
struct ModuleData;
class AFHDS2ASettings : public FormWindow, public ModuleOptions
{
uint8_t moduleIdx;
ModuleData* md;
FlexGridLayout grid;
tmr10ms_t lastRefresh = 0;
Window* afhds2OptionsLabel = nullptr;
Window* afhds2ProtoOpts = nullptr;
#if defined(PCBNV14)
Window* afhds2RFPowerText = nullptr;
Window* afhds2RFPowerChoice = nullptr;
#endif
void hideAFHDS2Options();
void showAFHDS2Options();
void checkEvents() override;
void update() override;
public:
AFHDS2ASettings(Window* parent, const FlexGridLayout& g, uint8_t moduleIdx);
};
@@ -19,18 +19,9 @@
* GNU General Public License for more details.
*/
#include "flysky_settings.h"
#include "opentx.h"
#if defined(AFHDS3)
#include "afhds3_settings.h"
#include "afhds3_options.h"
#endif
#include "pulses/flysky.h"
#include "pulses/afhds3.h"
#include "pulses/afhds3_config.h"
#define SET_DIRTY() storageDirty(EE_MODEL)
#include "opentx.h"
static const char* _afhds3_region[] = { "CE", "FCC" };
@@ -44,44 +35,13 @@ static const char* _afhds3_phy_mode[] = {
"Lora 12ch",
};
class FSProtoOpts : public FormWindow
{
std::function<uint8_t()> _getMode;
std::function<void(uint8_t)> _setMode;
public:
FSProtoOpts(Window* parent, std::function<uint8_t()> getMode,
std::function<void(uint8_t)> setMode);
};
#include "pulses/flysky.h"
#include "pulses/afhds3.h"
#include "pulses/afhds3_config.h"
FSProtoOpts::FSProtoOpts(Window* parent, std::function<uint8_t()> getMode,
std::function<void(uint8_t)> setMode) :
FormWindow(parent, rect_t{}),
_getMode(std::move(getMode)),
_setMode(std::move(setMode))
{
setFlexLayout(LV_FLEX_FLOW_ROW);
#define SET_DIRTY() storageDirty(EE_MODEL)
// PPM / PWM
new Choice(
this, rect_t{}, STR_FLYSKY_PULSE_PROTO, 0, 1,
[=]() -> int { return _getMode() >> 1; },
[=](int v) {
_setMode((_getMode() & 1) | ((v & 1) << 1));
SET_DIRTY();
});
// SBUS / iBUS
new Choice(
this, rect_t{}, STR_FLYSKY_SERIAL_PROTO, 0, 1,
[=]() -> int { return _getMode() & 1; },
[=](int v) {
_setMode((_getMode() & 2) | (v & 1));
SET_DIRTY();
});
}
FlySkySettings::FlySkySettings(Window* parent, const FlexGridLayout& g,
AFHDS3Settings::AFHDS3Settings(Window* parent, const FlexGridLayout& g,
uint8_t moduleIdx) :
FormWindow(parent, rect_t{}),
moduleIdx(moduleIdx),
@@ -92,33 +52,6 @@ FlySkySettings::FlySkySettings(Window* parent, const FlexGridLayout& g,
FormWindow::Line* line;
#if defined(AFHDS2)
// RX options:
line = newLine(&grid);
afhds2OptionsLabel = new StaticText(line, rect_t{}, STR_OPTIONS, 0, COLOR_THEME_PRIMARY1);
afhds2ProtoOpts = new FSProtoOpts(
line, [=]() { return md->flysky.mode; },
[=](uint8_t v) { md->flysky.mode = v; });
#if defined(PCBNV14)
if (getNV14RfFwVersion() >= 0x1000E) {
line = newLine(&grid);
static const char* _rf_power[] = {"Default", "High"};
afhds2RFPowerText = new StaticText(line, rect_t{}, STR_MULTI_RFPOWER);
afhds2RFPowerChoice = new Choice(line, rect_t{}, _rf_power, 0, 1,
GET_DEFAULT(md->flysky.rfPower),
[=](int32_t newValue) -> void {
md->flysky.rfPower = newValue;
resetPulsesAFHDS2();
});
#endif
}
hideAFHDS2Options();
#endif
#if defined(AFHDS3)
// Status
line = newLine(&grid);
afhds3StatusLabel = new StaticText(line, rect_t{}, STR_MODULE_STATUS, 0, COLOR_THEME_PRIMARY1);
@@ -164,40 +97,9 @@ FlySkySettings::FlySkySettings(Window* parent, const FlexGridLayout& g,
}
hideAFHDS3Options();
#endif
}
#if defined(AFHDS2)
void FlySkySettings::hideAFHDS2Options()
{
lv_obj_add_flag(afhds2OptionsLabel->getLvObj(), LV_OBJ_FLAG_HIDDEN);
lv_obj_add_flag(afhds2ProtoOpts->getLvObj(), LV_OBJ_FLAG_HIDDEN);
#if defined(PCBNV14)
if (afhds2RFPowerText != nullptr)
lv_obj_add_flag(afhds2RFPowerText->getLvObj(), LV_OBJ_FLAG_HIDDEN);
if (afhds2RFPowerChoice != nullptr)
lv_obj_add_flag(afhds2RFPowerChoice->getLvObj(), LV_OBJ_FLAG_HIDDEN);
#endif
}
void FlySkySettings::showAFHDS2Options()
{
lv_obj_clear_flag(afhds2OptionsLabel->getLvObj(), LV_OBJ_FLAG_HIDDEN);
lv_obj_clear_flag(afhds2ProtoOpts->getLvObj(), LV_OBJ_FLAG_HIDDEN);
#if defined(PCBNV14)
if (afhds2RFPowerText != nullptr)
lv_obj_clear_flag(afhds2RFPowerText->getLvObj(), LV_OBJ_FLAG_HIDDEN);
if (afhds2RFPowerChoice != nullptr)
{
lv_obj_clear_flag(afhds2RFPowerChoice->getLvObj(), LV_OBJ_FLAG_HIDDEN);
lv_event_send(afhds2RFPowerChoice->getLvObj(), LV_EVENT_VALUE_CHANGED, nullptr);
}
#endif
}
#endif
#if defined(AFHDS3)
void FlySkySettings::hideAFHDS3Options()
void AFHDS3Settings::hideAFHDS3Options()
{
lv_obj_add_flag(afhds3StatusLabel->getLvObj(), LV_OBJ_FLAG_HIDDEN);
lv_obj_add_flag(afhds3StatusText->getLvObj(), LV_OBJ_FLAG_HIDDEN);
@@ -205,7 +107,7 @@ void FlySkySettings::hideAFHDS3Options()
lv_obj_add_flag(afhds3TypeForm->getLvObj(), LV_OBJ_FLAG_HIDDEN);
}
void FlySkySettings::showAFHDS3Options()
void AFHDS3Settings::showAFHDS3Options()
{
lv_obj_clear_flag(afhds3StatusLabel->getLvObj(), LV_OBJ_FLAG_HIDDEN);
lv_obj_clear_flag(afhds3StatusText->getLvObj(), LV_OBJ_FLAG_HIDDEN);
@@ -228,31 +130,21 @@ void FlySkySettings::showAFHDS3Options()
lv_obj_clear_state(afhds3Emi->getLvObj(), LV_STATE_DISABLED);
}
}
#endif
void FlySkySettings::checkEvents() {
void AFHDS3Settings::checkEvents() {
if (afhds3::getConfig(moduleIdx)->others.lastUpdated > lastRefresh) {
update();
}
FormWindow::checkEvents();
}
void FlySkySettings::update()
void AFHDS3Settings::update()
{
lastRefresh = get_tmr10ms();
#if defined(AFHDS2)
if (isModuleAFHDS2A(moduleIdx)) {
showAFHDS2Options();
} else {
hideAFHDS2Options();
}
#endif
#if defined(AFHDS3)
if (isModuleAFHDS3(moduleIdx)) {
showAFHDS3Options();
} else {
hideAFHDS3Options();
}
#endif
}
@@ -27,25 +27,13 @@
struct ModuleData;
class FlySkySettings : public FormWindow, public ModuleOptions
class AFHDS3Settings : public FormWindow, public ModuleOptions
{
uint8_t moduleIdx;
ModuleData* md;
FlexGridLayout grid;
tmr10ms_t lastRefresh = 0;
#if defined(AFHDS2)
Window* afhds2OptionsLabel = nullptr;
Window* afhds2ProtoOpts = nullptr;
#if defined(PCBNV14)
Window* afhds2RFPowerText = nullptr;
Window* afhds2RFPowerChoice = nullptr;
#endif
void hideAFHDS2Options();
void showAFHDS2Options();
#endif
#if defined(AFHDS3)
Window* afhds3StatusLabel = nullptr;
Window* afhds3StatusText = nullptr;
Window* afhds3TypeLabel = nullptr;
@@ -55,11 +43,10 @@ class FlySkySettings : public FormWindow, public ModuleOptions
Choice *afhds3RfPower = nullptr;
void hideAFHDS3Options();
void showAFHDS3Options();
#endif
void checkEvents() override;
void update() override;
public:
FlySkySettings(Window* parent, const FlexGridLayout& g, uint8_t moduleIdx);
AFHDS3Settings(Window* parent, const FlexGridLayout& g, uint8_t moduleIdx);
};
+6
View File
@@ -57,12 +57,18 @@ void ChannelRange::build()
chStart = new NumberEdit(this, rect_t{}, 1, 1, GET_DEFAULT(1 + getChannelsStart()));
chStart->setSetValueHandler([=](int newValue) { setStart(newValue); });
chStart->setPrefix(STR_CH);
#if LCD_H > LCD_W
chStart->setWidth(LCD_W/3-10);
#endif
chEnd = new NumberEdit(this, rect_t{}, 8, 8,
GET_DEFAULT(getChannelsStart() + 8 + getChannelsCount()));
chEnd->setPrefix(STR_CH);
chEnd->setSetValueHandler([=](int newValue) { setEnd(newValue); });
#if LCD_H > LCD_W
chEnd->setWidth(LCD_W/3-10);
#endif
}
void ChannelRange::setStart(uint8_t newValue)
+18 -36
View File
@@ -46,8 +46,12 @@
#include "crossfire_settings.h"
#endif
#if defined(AFHDS2) || defined(AFHDS3)
#include "flysky_settings.h"
#if defined(AFHDS2)
#include "afhds2a_settings.h"
#endif
#if defined(AFHDS3)
#include "afhds3_settings.h"
#endif
#if defined(AFHDS2)
@@ -213,9 +217,14 @@ void ModuleWindow::updateModule()
modOpts = new CrossfireSettings(this, grid, moduleIdx);
}
#endif
#if defined(AFHDS2) || defined(AFHDS3)
else if (isModuleFlySky(moduleIdx)) {
modOpts = new FlySkySettings(this, grid, moduleIdx);
#if defined(AFHDS2)
else if (isModuleAFHDS2A(moduleIdx)) {
modOpts = new AFHDS2ASettings(this, grid, moduleIdx);
}
#endif
#if defined(AFHDS3)
else if (isModuleAFHDS3(moduleIdx)) {
modOpts = new AFHDS3Settings(this, grid, moduleIdx);
}
#endif
#if defined(MULTIMODULE)
@@ -306,7 +315,7 @@ void ModuleWindow::updateModule()
}
#endif
#if defined(AFHDS2)
if (isModuleFlySky(moduleIdx)) resetPulsesAFHDS2();
if (isModuleAFHDS2A(moduleIdx)) resetPulsesAFHDS2();
#endif
if (isModuleDSMP(moduleIdx)) restartModule(moduleIdx);
return 0;
@@ -325,7 +334,7 @@ void ModuleWindow::updateModule()
#endif
moduleState[moduleIdx].mode = MODULE_MODE_BIND;
#if defined(AFHDS2)
if (isModuleFlySky(moduleIdx)) {
if (isModuleAFHDS2A(moduleIdx)) {
resetPulsesAFHDS2();
}
#endif
@@ -363,13 +372,13 @@ void ModuleWindow::updateModule()
} else {
moduleState[moduleIdx].mode = MODULE_MODE_RANGECHECK;
#if defined(AFHDS2)
if (isModuleFlySky(moduleIdx)) {
if (isModuleAFHDS2A(moduleIdx)) {
resetPulsesAFHDS2();
}
#endif
startRSSIDialog([=]() {
#if defined(AFHDS2)
if (isModuleFlySky(moduleIdx)) {
if (isModuleAFHDS2A(moduleIdx)) {
resetPulsesAFHDS2();
}
#endif
@@ -626,33 +635,6 @@ void ModuleSubTypeChoice::update()
setTextHandler(nullptr);
}
#endif
#if defined(AFHDS2) || defined(AFHDS3)
else if (isModuleFlySky(moduleIdx)) {
setMin(0);
setMax(FLYSKY_SUBTYPE_AFHDS2A);
setValues(STR_FLYSKY_PROTOCOLS);
setGetValueHandler(GET_DEFAULT(md->subType));
setSetValueHandler(SET_DEFAULT(md->subType));
#if defined(PCBNV14) && !defined(SIMU)
if (moduleIdx == INTERNAL_MODULE) {
if (hardwareOptions.pcbrev == PCBREV_NV14) {
md->subType = FLYSKY_SUBTYPE_AFHDS2A;
setAvailableHandler([](int v) { return v == FLYSKY_SUBTYPE_AFHDS2A; });
} else {
md->subType = FLYSKY_SUBTYPE_AFHDS3;
setAvailableHandler([](int v) { return v == FLYSKY_SUBTYPE_AFHDS3; });
}
}
#elif !defined(SIMU)
md->subType = FLYSKY_SUBTYPE_AFHDS3;
setAvailableHandler([](int v) { return v == FLYSKY_SUBTYPE_AFHDS3; });
#else
setAvailableHandler(nullptr);
#endif
setTextHandler(nullptr);
}
#endif
#if defined(MULTIMODULE)
else if (isModuleMultimodule(moduleIdx)) {
setMin(0);
+18 -4
View File
@@ -773,7 +773,8 @@ bool isModuleUsingSport(uint8_t moduleBay, uint8_t moduleType)
case MODULE_TYPE_ISRM_PXX2:
case MODULE_TYPE_R9M_LITE_PXX2:
case MODULE_TYPE_R9M_LITE_PRO_PXX2:
case MODULE_TYPE_FLYSKY:
case MODULE_TYPE_FLYSKY_AFHDS2A:
case MODULE_TYPE_FLYSKY_AFHDS3:
return false;
case MODULE_TYPE_XJT_PXX1:
@@ -823,8 +824,11 @@ bool isInternalModuleSupported(int moduleType)
#if defined(INTERNAL_MODULE_PPM)
case MODULE_TYPE_PPM: return true;
#endif
#if defined(INTERNAL_MODULE_AFHDS2A) || defined(INTERNAL_MODULE_AFHDS3)
case MODULE_TYPE_FLYSKY: return true;
#if defined(INTERNAL_MODULE_AFHDS2A)
case MODULE_TYPE_FLYSKY_AFHDS2A: return true;
#endif
#if defined(INTERNAL_MODULE_AFHDS3)
case MODULE_TYPE_FLYSKY_AFHDS3: return true;
#endif
}
return false;
@@ -963,7 +967,17 @@ bool isExternalModuleAvailable(int moduleType)
#endif
#if !defined(AFHDS3)
if (moduleType == MODULE_TYPE_FLYSKY)
if (moduleType == MODULE_TYPE_FLYSKY_AFHDS3)
return false;
#endif
#if !defined(AFHDS2)
if (moduleType == MODULE_TYPE_FLYSKY_AFHDS2A)
return false;
#endif
#if !defined(AFHDS3)
if (moduleType == MODULE_TYPE_FLYSKY_AFHDS3)
return false;
#endif