diff --git a/companion/src/firmwares/boards.cpp b/companion/src/firmwares/boards.cpp index 2a6e0d2a2..1551ffec8 100644 --- a/companion/src/firmwares/boards.cpp +++ b/companion/src/firmwares/boards.cpp @@ -575,8 +575,8 @@ StringTagMappingTable Boards::getAnalogNamesLookupTable(Board::Type board) }); } else if (IS_FLYSKY_NV14(board)) { tbl.insert(tbl.end(), { - {"VRA", "POT1"}, - {"VRB", "POT2"}, + {"S1", "POT1"}, + {"S2", "POT2"}, }); } else if (IS_HORUS_X10(board) || IS_FAMILY_T16(board)) { tbl.insert(tbl.end(), { @@ -873,10 +873,10 @@ int Boards::getDefaultInternalModules(Board::Type board) case BOARD_JUMPER_TLITE: case BOARD_JUMPER_TPRO: return (int)MODULE_TYPE_MULTIMODULE; - + case BOARD_RADIOMASTER_ZORRO: return (int)MODULE_TYPE_CROSSFIRE; - + case BOARD_FLYSKY_NV14: return (int)MODULE_TYPE_FLYSKY; diff --git a/companion/src/firmwares/edgetx/yaml_generalsettings.cpp b/companion/src/firmwares/edgetx/yaml_generalsettings.cpp index 58ee69c43..b61b8c91d 100644 --- a/companion/src/firmwares/edgetx/yaml_generalsettings.cpp +++ b/companion/src/firmwares/edgetx/yaml_generalsettings.cpp @@ -169,6 +169,7 @@ Node convert::encode(const GeneralSettings& rhs) node["disableAlarmWarning"] = (int)rhs.disableAlarmWarning; node["disableRssiPoweroffAlarm"] = (int)rhs.disableRssiPoweroffAlarm; node["USBMode"] = rhs.usbMode; + node["stickDeadZone"] = rhs.stickDeadZone; node["jackMode"] = rhs.jackMode; node["hapticMode"] = rhs.hapticMode; node["stickMode"] = rhs.stickMode; @@ -349,6 +350,7 @@ bool convert::decode(const Node& node, GeneralSettings& rhs) node["disableAlarmWarning"] >> rhs.disableAlarmWarning; node["disableRssiPoweroffAlarm"] >> rhs.disableRssiPoweroffAlarm; node["USBMode"] >> rhs.usbMode; + node["stickDeadZone"] >> rhs.stickDeadZone; node["jackMode"] >> rhs.jackMode; node["hapticMode"] >> rhs.hapticMode; node["stickMode"] >> rhs.stickMode; diff --git a/companion/src/firmwares/generalsettings.cpp b/companion/src/firmwares/generalsettings.cpp index 1e68b2b37..181c27b0e 100644 --- a/companion/src/firmwares/generalsettings.cpp +++ b/companion/src/firmwares/generalsettings.cpp @@ -249,6 +249,9 @@ void GeneralSettings::init() internalModule = g.profile[g.sessionId()].defaultInternalModule(); + if (IS_FLYSKY_NV14(board)) + stickDeadZone = 2; + } void GeneralSettings::setDefaultControlTypes(Board::Type board) @@ -589,6 +592,20 @@ AbstractStaticItemModel * GeneralSettings::internalModuleBaudrateItemModel() return mdl; } +// static +AbstractStaticItemModel * GeneralSettings::stickDeadZoneItemModel() +{ + AbstractStaticItemModel * mdl = new AbstractStaticItemModel(); + mdl->setName(AIM_GS_STICKDEADZONE); + + for (int i = 0; i <= 7; i++) { + mdl->appendToItemList(i ? QString::number((int)(2 << (i - 1))) : QString::number(0), i); + } + + mdl->loadItemList(); + return mdl; +} + /* TrainerMix */ diff --git a/companion/src/firmwares/generalsettings.h b/companion/src/firmwares/generalsettings.h index 411db520d..3da7d996e 100644 --- a/companion/src/firmwares/generalsettings.h +++ b/companion/src/firmwares/generalsettings.h @@ -40,6 +40,7 @@ constexpr char AIM_GS_ANTENNAMODE[] {"gs.antennamode"}; constexpr char AIM_GS_BLUETOOTHMODE[] {"gs.bluetoothmode"}; constexpr char AIM_GS_SERIALMODE[] {"gs.serialmode%1"}; constexpr char AIM_GS_INTMODULEBAUDRATE[] {"gs.intmodulebaudrate"}; +constexpr char AIM_GS_STICKDEADZONE[] {"gs.stickdeadzone"}; constexpr char AIM_TRAINERMIX_MODE[] {"trainermix.mode"}; constexpr char AIM_TRAINERMIX_SRC[] {"trainermix.src"}; @@ -151,7 +152,7 @@ class GeneralSettings { SP_VCP, SP_COUNT, }; - + GeneralSettings() { clear(); } void clear(); void init(); @@ -186,6 +187,7 @@ class GeneralSettings { bool disableAlarmWarning; bool disableRssiPoweroffAlarm; unsigned int usbMode; + unsigned int stickDeadZone; unsigned int jackMode; bool sportPower; BeeperMode hapticMode; @@ -281,4 +283,5 @@ class GeneralSettings { static AbstractStaticItemModel * bluetoothModeItemModel(); static AbstractStaticItemModel * serialModeItemModel(int port_nr); static AbstractStaticItemModel * internalModuleBaudrateItemModel(); + static AbstractStaticItemModel * stickDeadZoneItemModel(); }; diff --git a/companion/src/generaledit/hardware.cpp b/companion/src/generaledit/hardware.cpp index 54728c30f..5403392a1 100644 --- a/companion/src/generaledit/hardware.cpp +++ b/companion/src/generaledit/hardware.cpp @@ -41,7 +41,7 @@ class ExclusiveComboGroup: public QObject QList combos; std::function filter; - + public: ExclusiveComboGroup(QObject *parent, std::function filter) : QObject(parent), filter(std::move(filter)) @@ -105,6 +105,8 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings int count; int row = 0; + addSection(tr("Sticks"), row); + count = Boards::getCapability(board, Board::Sticks); if (count) { for (int i = 0; i < count; i++) { @@ -112,6 +114,16 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings } } + if (IS_FLYSKY_NV14(board)) { + addLabel(tr("Dead zone"), row, 0); + AutoComboBox *spnStickDeadZone = new AutoComboBox(this); + spnStickDeadZone->setModel(GeneralSettings::stickDeadZoneItemModel()); + spnStickDeadZone->setField(generalSettings.stickDeadZone, this); + addParams(row, spnStickDeadZone); + } + + addSection(tr("Pots"), row); + count = Boards::getCapability(board, Board::Pots); count -= firmware->getCapability(HasFlySkyGimbals) ? 2 : 0; if (count > 0) { @@ -120,22 +132,26 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings } } + addSection(tr("Sliders"), row); + count = Boards::getCapability(board, Board::Sliders); if (count) { for (int i = 0; i < count; i++) { addSlider(i, row); } - addLine(row); } + addSection(tr("Switches"), row); + count = Boards::getCapability(board, Board::Switches); if (count) { for (int i = 0; i < count; i++) { addSwitch(i, row); } - addLine(row); } + addLine(row); + if (Boards::getCapability(board, Board::HasRTC)) { addLabel(tr("RTC Battery Check"), row, 0); AutoCheckBox *rtcCheckDisable = new AutoCheckBox(this); @@ -194,7 +210,7 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings generalSettings.internalModuleBaudrate = 0; internalModuleBaudRate->setVisible(false); } - + addParams(row, internalModule, internalModuleBaudRate); row++; } @@ -386,3 +402,9 @@ void HardwarePanel::addParams(int & row, QWidget * widget1, QWidget * widget2) grid->addLayout(subgrid, row, 1); row++; } + +void HardwarePanel::addSection(QString text, int & row) +{ + addLabel(QString("%1").arg(text), row, 0); + row++; +} diff --git a/companion/src/generaledit/hardware.h b/companion/src/generaledit/hardware.h index c23a663a4..ebd1bb77d 100644 --- a/companion/src/generaledit/hardware.h +++ b/companion/src/generaledit/hardware.h @@ -57,4 +57,5 @@ class HardwarePanel : public GeneralPanel void addLabel(QString text, int row, int col); void addLine(int & row); void addParams(int & row, QWidget * widget1, QWidget * widget2 = nullptr); + void addSection(QString text, int & row); }; diff --git a/radio/src/datastructs.h b/radio/src/datastructs.h index 0b9226a24..051750385 100644 --- a/radio/src/datastructs.h +++ b/radio/src/datastructs.h @@ -141,6 +141,9 @@ static inline void check_struct() CHKSIZE(RadioData, 901); CHKSIZE(ModelData, 11023); #endif +#elif defined(PCBNV14) + CHKSIZE(RadioData, 849); + CHKSIZE(ModelData, 10839); #endif #undef CHKSIZE diff --git a/radio/src/datastructs_private.h b/radio/src/datastructs_private.h index 4222bd14f..0be20cbeb 100644 --- a/radio/src/datastructs_private.h +++ b/radio/src/datastructs_private.h @@ -823,7 +823,7 @@ PACK(struct TrainerData { #if defined(BUZZER) #define BUZZER_FIELD int8_t buzzerMode:2 // -2=quiet, -1=only alarms, 0=no keys, 1=all (only used on AVR radios without audio hardware) #else - #define BUZZER_FIELD int8_t spare4:2 SKIP + #define BUZZER_FIELD int8_t spare1:2 SKIP #endif PACK(struct RadioData { @@ -913,6 +913,12 @@ PACK(struct RadioData { GYRO_FIELDS NOBACKUP(int8_t uartSampleMode:2); // See UartSampleModes +#if defined(STICK_DEAD_ZONE) + NOBACKUP(uint8_t stickDeadZone:3); + NOBACKUP(uint8_t spare2:3 SKIP); +#else + NOBACKUP(uint8_t spare2:6 SKIP); +#endif }); #undef SWITCHES_WARNING_DATA diff --git a/radio/src/gui/colorlcd/radio_hardware.cpp b/radio/src/gui/colorlcd/radio_hardware.cpp index ab03c8b7a..4446a6799 100644 --- a/radio/src/gui/colorlcd/radio_hardware.cpp +++ b/radio/src/gui/colorlcd/radio_hardware.cpp @@ -346,6 +346,20 @@ void RadioHardwarePage::build(FormWindow * window) grid.nextLine(); } +#if defined(STICK_DEAD_ZONE) + new StaticText(window, grid.getLabelSlot(true), STR_DEAD_ZONE); + auto choice = + new Choice(window, grid.getFieldSlot(2,0), 0, 7, + GET_DEFAULT(g_eeGeneral.stickDeadZone), [=](uint8_t newValue) { + g_eeGeneral.stickDeadZone = newValue; + SET_DIRTY(); + }); + choice->setTextHandler([](uint8_t value) { + return std::to_string(value ? 2 << (value - 1) : 0); + }); + grid.nextLine(); +#endif + // Pots new Subtitle(window, grid.getLineSlot(), STR_POTS, 0, COLOR_THEME_PRIMARY1); grid.nextLine(); diff --git a/radio/src/mixer.cpp b/radio/src/mixer.cpp index cdb90e6df..b5ec0af6c 100644 --- a/radio/src/mixer.cpp +++ b/radio/src/mixer.cpp @@ -442,6 +442,23 @@ void evalInputs(uint8_t mode) { BeepANACenter anaCenter = 0; +#if defined(STICK_DEAD_ZONE) + static int16_t P_OFFSET = 0; + static int16_t N_OFFSET = 0; + static float aParam = 0.0f; + static float bParam = 0.0f; + static int16_t lastDeadZone = -1; + + if (lastDeadZone != g_eeGeneral.stickDeadZone) { + P_OFFSET = + (g_eeGeneral.stickDeadZone ? 2 << (g_eeGeneral.stickDeadZone - 1) : 0); + N_OFFSET = (-1) * P_OFFSET; + aParam = 1024.0 / (1024.0 - (float)P_OFFSET); + bParam = 1024.0 * (aParam - 1.0f); + lastDeadZone = g_eeGeneral.stickDeadZone; + } +#endif + for (uint8_t i = 0; i < NUM_STICKS + NUM_POTS + NUM_SLIDERS; i++) { // normalization [0..2048] -> [-1024..1024] uint8_t ch = (i < NUM_STICKS ? CONVERT_MODE(i) : i); @@ -461,6 +478,22 @@ void evalInputs(uint8_t mode) if (v < -RESX) v = -RESX; if (v > RESX) v = RESX; +#if defined(STICK_DEAD_ZONE) + // dead zone invented by FlySky in my opinion it should goes into ADC + // float calculations are not efficient + if (g_eeGeneral.stickDeadZone && ch != THR_STICK) { + if (v > P_OFFSET) { + // y=ax+b + v = (int)((aParam * (float)v) - bParam); + } else if ((v <= P_OFFSET) && (v >= N_OFFSET)) { + v = 0; + } else if (v < N_OFFSET) { + // y=ax+b + v = (int)((aParam * (float)v) + bParam); + } + } +#endif + if (g_model.throttleReversed && ch==THR_STICK) { v = -v; } diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index 23b6b6a5a..443e0f189 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -298,7 +298,12 @@ void generalDefault() g_eeGeneral.slidersConfig = DEFAULT_SLIDERS_CONFIG; #endif - // vBatWarn is voltage in 100mV, vBatMin is in 100mV but with -9V offset, vBatMax has a -12V offset +#if defined(STICK_DEAD_ZONE) + g_eeGeneral.stickDeadZone = DEFAULT_STICK_DEADZONE; +#endif + + // vBatWarn is voltage in 100mV, vBatMin is in 100mV but with -9V offset, + // vBatMax has a -12V offset g_eeGeneral.vBatWarn = BATTERY_WARN; if (BATTERY_MIN != 90) g_eeGeneral.vBatMin = BATTERY_MIN - 90; diff --git a/radio/src/storage/storage_common.cpp b/radio/src/storage/storage_common.cpp index 295395f45..2c1a6dadc 100644 --- a/radio/src/storage/storage_common.cpp +++ b/radio/src/storage/storage_common.cpp @@ -98,6 +98,11 @@ void postRadioSettingsLoad() g_eeGeneral.internalModule = DEFAULT_INTERNAL_MODULE; } #endif +#if defined(STICK_DEAD_ZONE) + if (!g_eeGeneral.stickDeadZone) { + g_eeGeneral.stickDeadZone = DEFAULT_STICK_DEADZONE; + } +#endif } #if defined(EXTERNAL_ANTENNA) && defined(INTERNAL_MODULE_PXX1) diff --git a/radio/src/storage/yaml/yaml_datastructs_nv14.cpp b/radio/src/storage/yaml/yaml_datastructs_nv14.cpp index 8396a53c8..878fa3379 100644 --- a/radio/src/storage/yaml/yaml_datastructs_nv14.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_nv14.cpp @@ -438,6 +438,8 @@ static const struct YamlNode struct_RadioData[] = { YAML_STRUCT("themeData", 480, struct_OpenTxTheme__PersistentData, NULL), YAML_STRING("ownerRegistrationID", 8), YAML_SIGNED( "uartSampleMode", 2 ), + YAML_UNSIGNED( "stickDeadZone", 3 ), + YAML_PADDING( 2 ), YAML_END }; static const struct YamlNode struct_unsigned_8[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_t12.cpp b/radio/src/storage/yaml/yaml_datastructs_t12.cpp index 5726f045f..1330d527f 100644 --- a/radio/src/storage/yaml/yaml_datastructs_t12.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_t12.cpp @@ -407,6 +407,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_STRING("bluetoothName", 10), YAML_STRING("ownerRegistrationID", 8), YAML_SIGNED( "uartSampleMode", 2 ), + YAML_PADDING( 5 ), YAML_END }; static const struct YamlNode struct_unsigned_8[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_t8.cpp b/radio/src/storage/yaml/yaml_datastructs_t8.cpp index 3c73ce91d..2748ad0c7 100644 --- a/radio/src/storage/yaml/yaml_datastructs_t8.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_t8.cpp @@ -407,6 +407,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_STRING("bluetoothName", 10), YAML_STRING("ownerRegistrationID", 8), YAML_SIGNED( "uartSampleMode", 2 ), + YAML_PADDING( 5 ), YAML_END }; static const struct YamlNode struct_unsigned_8[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_tlite.cpp b/radio/src/storage/yaml/yaml_datastructs_tlite.cpp index 3c73ce91d..2748ad0c7 100644 --- a/radio/src/storage/yaml/yaml_datastructs_tlite.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_tlite.cpp @@ -407,6 +407,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_STRING("bluetoothName", 10), YAML_STRING("ownerRegistrationID", 8), YAML_SIGNED( "uartSampleMode", 2 ), + YAML_PADDING( 5 ), YAML_END }; static const struct YamlNode struct_unsigned_8[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_tpro.cpp b/radio/src/storage/yaml/yaml_datastructs_tpro.cpp index c100ce619..02a48684c 100644 --- a/radio/src/storage/yaml/yaml_datastructs_tpro.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_tpro.cpp @@ -413,6 +413,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_PADDING( 144 ), YAML_STRING("ownerRegistrationID", 8), YAML_SIGNED( "uartSampleMode", 2 ), + YAML_PADDING( 5 ), YAML_END }; static const struct YamlNode struct_unsigned_8[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_tx12.cpp b/radio/src/storage/yaml/yaml_datastructs_tx12.cpp index cc0f3babb..b1d225cd0 100644 --- a/radio/src/storage/yaml/yaml_datastructs_tx12.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_tx12.cpp @@ -407,6 +407,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_STRING("bluetoothName", 10), YAML_STRING("ownerRegistrationID", 8), YAML_SIGNED( "uartSampleMode", 2 ), + YAML_PADDING( 5 ), YAML_END }; static const struct YamlNode struct_unsigned_8[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_x10.cpp b/radio/src/storage/yaml/yaml_datastructs_x10.cpp index 17a6e8623..2d5dac3bf 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x10.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x10.cpp @@ -459,6 +459,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_STRUCT("themeData", 480, struct_OpenTxTheme__PersistentData, NULL), YAML_STRING("ownerRegistrationID", 8), YAML_SIGNED( "uartSampleMode", 2 ), + YAML_PADDING( 5 ), YAML_END }; static const struct YamlNode struct_unsigned_8[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_x12s.cpp b/radio/src/storage/yaml/yaml_datastructs_x12s.cpp index 12f341b49..f9a617778 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x12s.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x12s.cpp @@ -457,6 +457,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_STRUCT("themeData", 480, struct_OpenTxTheme__PersistentData, NULL), YAML_STRING("ownerRegistrationID", 8), YAML_SIGNED( "uartSampleMode", 2 ), + YAML_PADDING( 5 ), YAML_END }; static const struct YamlNode struct_unsigned_8[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_x7.cpp b/radio/src/storage/yaml/yaml_datastructs_x7.cpp index 3c73ce91d..2748ad0c7 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x7.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x7.cpp @@ -407,6 +407,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_STRING("bluetoothName", 10), YAML_STRING("ownerRegistrationID", 8), YAML_SIGNED( "uartSampleMode", 2 ), + YAML_PADDING( 5 ), YAML_END }; static const struct YamlNode struct_unsigned_8[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_x9d.cpp b/radio/src/storage/yaml/yaml_datastructs_x9d.cpp index abc9e6580..d0a348e38 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x9d.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x9d.cpp @@ -414,6 +414,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_STRING("bluetoothName", 10), YAML_STRING("ownerRegistrationID", 8), YAML_SIGNED( "uartSampleMode", 2 ), + YAML_PADDING( 5 ), YAML_END }; static const struct YamlNode struct_unsigned_8[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_x9e.cpp b/radio/src/storage/yaml/yaml_datastructs_x9e.cpp index 38fc39633..376191a88 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x9e.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x9e.cpp @@ -453,6 +453,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_STRING("bluetoothName", 10), YAML_STRING("ownerRegistrationID", 8), YAML_SIGNED( "uartSampleMode", 2 ), + YAML_PADDING( 5 ), YAML_END }; static const struct YamlNode struct_unsigned_8[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_x9lite.cpp b/radio/src/storage/yaml/yaml_datastructs_x9lite.cpp index c87263c2a..87739b509 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x9lite.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x9lite.cpp @@ -392,6 +392,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_PADDING( 120 ), YAML_STRING("ownerRegistrationID", 8), YAML_SIGNED( "uartSampleMode", 2 ), + YAML_PADDING( 5 ), YAML_END }; static const struct YamlNode struct_unsigned_8[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_x9lites.cpp b/radio/src/storage/yaml/yaml_datastructs_x9lites.cpp index 675c2a95c..c9220415c 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x9lites.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x9lites.cpp @@ -402,6 +402,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_STRING("bluetoothName", 10), YAML_STRING("ownerRegistrationID", 8), YAML_SIGNED( "uartSampleMode", 2 ), + YAML_PADDING( 5 ), YAML_END }; static const struct YamlNode struct_unsigned_8[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_xlite.cpp b/radio/src/storage/yaml/yaml_datastructs_xlite.cpp index 17cdb6b3b..da1da3b80 100644 --- a/radio/src/storage/yaml/yaml_datastructs_xlite.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_xlite.cpp @@ -399,6 +399,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_STRING("bluetoothName", 10), YAML_STRING("ownerRegistrationID", 8), YAML_SIGNED( "uartSampleMode", 2 ), + YAML_PADDING( 5 ), YAML_END }; static const struct YamlNode struct_unsigned_8[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_xlites.cpp b/radio/src/storage/yaml/yaml_datastructs_xlites.cpp index aacd40d2e..81d132563 100644 --- a/radio/src/storage/yaml/yaml_datastructs_xlites.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_xlites.cpp @@ -403,6 +403,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_SIGNED( "gyroMax", 8 ), YAML_SIGNED( "gyroOffset", 8 ), YAML_SIGNED( "uartSampleMode", 2 ), + YAML_PADDING( 5 ), YAML_END }; static const struct YamlNode struct_unsigned_8[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_zorro.cpp b/radio/src/storage/yaml/yaml_datastructs_zorro.cpp index 5f22428df..9df1ea6f9 100644 --- a/radio/src/storage/yaml/yaml_datastructs_zorro.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_zorro.cpp @@ -407,6 +407,7 @@ static const struct YamlNode struct_RadioData[] = { YAML_STRING("bluetoothName", 10), YAML_STRING("ownerRegistrationID", 8), YAML_SIGNED( "uartSampleMode", 2 ), + YAML_PADDING( 5 ), YAML_END }; static const struct YamlNode struct_unsigned_8[] = { diff --git a/radio/src/targets/nv14/CMakeLists.txt b/radio/src/targets/nv14/CMakeLists.txt index 2c3e2b079..8e314b19a 100644 --- a/radio/src/targets/nv14/CMakeLists.txt +++ b/radio/src/targets/nv14/CMakeLists.txt @@ -1,5 +1,6 @@ option(DISK_CACHE "Enable SD card disk cache" ON) option(UNEXPECTED_SHUTDOWN "Enable the Unexpected Shutdown screen" ON) +option(STICKS_DEAD_ZONE "Enable sticks dead zone" YES) option(MULTIMODULE "DIY Multiprotocol TX Module (https://github.com/pascallanger/DIY-Multiprotocol-TX-Module)" ON) option(AFHDS2 "Support for AFHDS2" ON) option(GHOST "Ghost TX Module" ON) @@ -90,6 +91,10 @@ if(NOT UNEXPECTED_SHUTDOWN) add_definitions(-DNO_UNEXPECTED_SHUTDOWN) endif() +if(STICKS_DEAD_ZONE) + add_definitions(-DSTICK_DEAD_ZONE) +endif() + set(AFHDS2 ON) # disable for now as it crashes on radio diff --git a/radio/src/targets/nv14/board.h b/radio/src/targets/nv14/board.h index 33bb94ebe..9b746bb40 100644 --- a/radio/src/targets/nv14/board.h +++ b/radio/src/targets/nv14/board.h @@ -299,6 +299,8 @@ enum Analogs { #define SLIDER_FIRST 0 #define SLIDER_LAST -1 +#define DEFAULT_STICK_DEADZONE 2 + #define DEFAULT_POTS_CONFIG (POT_WITHOUT_DETENT << 0) + (POT_WITHOUT_DETENT << 2) // 2 pots without detent enum CalibratedAnalogs { diff --git a/radio/src/tests/mixer.cpp b/radio/src/tests/mixer.cpp index 1dce97657..c266458c8 100644 --- a/radio/src/tests/mixer.cpp +++ b/radio/src/tests/mixer.cpp @@ -337,7 +337,11 @@ TEST_F(TrimsTest, CopySticksToOffset) anaInValues[ELE_STICK] = -100; evalMixes(1); copySticksToOffset(1); +#if defined(STICK_DEAD_ZONE) + EXPECT_EQ(g_model.limitData[1].offset, -93); +#else EXPECT_EQ(g_model.limitData[1].offset, -97); +#endif } TEST_F(TrimsTest, MoveTrimsToOffsets) @@ -444,7 +448,11 @@ TEST_F(TrimsTest, InstantTrim) { anaInValues[AIL_STICK] = 50; instantTrim(); +#if defined(STICK_DEAD_ZONE) + EXPECT_EQ(23, getTrimValue(0, AIL_STICK)); +#else EXPECT_EQ(25, getTrimValue(0, AIL_STICK)); +#endif } TEST_F(TrimsTest, InstantTrimNegativeCurve) @@ -459,7 +467,11 @@ TEST_F(TrimsTest, InstantTrimNegativeCurve) g_model.points[4] = 0; anaInValues[AIL_STICK] = 512; instantTrim(); +#if defined(STICK_DEAD_ZONE) + EXPECT_EQ(127, getTrimValue(0, AIL_STICK)); +#else EXPECT_EQ(128, getTrimValue(0, AIL_STICK)); +#endif } TEST(Curves, LinearIntpol) diff --git a/radio/src/translations.cpp b/radio/src/translations.cpp index baa8aff82..767a85203 100644 --- a/radio/src/translations.cpp +++ b/radio/src/translations.cpp @@ -765,6 +765,7 @@ const char STR_MENU_DISPLAY[] = TR_MENU_DISPLAY; const char STR_MENU_OTHER[] = TR_MENU_OTHER; const char STR_MENU_INVERT[] = TR_MENU_INVERT; const char STR_JITTER_FILTER[] = TR_JITTER_FILTER; +const char STR_DEAD_ZONE[] = TR_DEAD_ZONE; const char STR_RTC_CHECK[] = TR_RTC_CHECK; const char STR_EXIT[] = TR_EXIT; const char STR_MODULE_RANGE[] = TR_MODULE_RANGE; diff --git a/radio/src/translations.h b/radio/src/translations.h index 4e0282c00..5a1ae773b 100644 --- a/radio/src/translations.h +++ b/radio/src/translations.h @@ -1110,6 +1110,7 @@ extern const char STR_MENU_DISPLAY[]; extern const char STR_MENU_OTHER[]; extern const char STR_MENU_INVERT[]; extern const char STR_JITTER_FILTER[]; +extern const char STR_DEAD_ZONE[]; extern const char STR_RTC_CHECK[]; extern const char STR_SPORT_UPDATE_POWER_MODE[]; extern const char STR_SPORT_UPDATE_POWER_MODES[]; diff --git a/radio/src/translations/cn.h.txt b/radio/src/translations/cn.h.txt index 7a418ef00..49383c0bb 100644 --- a/radio/src/translations/cn.h.txt +++ b/radio/src/translations/cn.h.txt @@ -1154,6 +1154,7 @@ #define TR_MENU_OTHER "其它" #define TR_MENU_INVERT "反向" #define TR_JITTER_FILTER "类比输入滤波" +#define TR_DEAD_ZONE "Dead zone" #define TR_RTC_CHECK TR("Check RTC", "检查时间驱动电池电压") #define TR_AUTH_FAILURE "验证失败" #define TR_RACING_MODE "竞速模式" diff --git a/radio/src/translations/cz.h.txt b/radio/src/translations/cz.h.txt index bae1fd9c1..b1caa1bd3 100644 --- a/radio/src/translations/cz.h.txt +++ b/radio/src/translations/cz.h.txt @@ -1201,6 +1201,7 @@ #define TR_MENU_OTHER "Ostatní" #define TR_MENU_INVERT "Invertovat" #define TR_JITTER_FILTER "ADC Filtr" +#define TR_DEAD_ZONE "Dead zone" #define TR_RTC_CHECK TR("Check RTC", "Check RTC voltage") #define TR_AUTH_FAILURE "Auth-failure" #define TR_RACING_MODE "Racing mode" diff --git a/radio/src/translations/de.h.txt b/radio/src/translations/de.h.txt index dc5f4340c..be37b7ded 100644 --- a/radio/src/translations/de.h.txt +++ b/radio/src/translations/de.h.txt @@ -1207,6 +1207,7 @@ #define TR_MENU_OTHER "Weitere" #define TR_MENU_INVERT "Invertieren" #define TR_JITTER_FILTER "ADC Filter" +#define TR_DEAD_ZONE "Dead zone" #define TR_RTC_CHECK TR("Check RTC", "Check RTC voltage") #define TR_AUTH_FAILURE "Auth-failure" #define TR_RACING_MODE "Racing mode" diff --git a/radio/src/translations/en.h.txt b/radio/src/translations/en.h.txt index 6fc3ae6f4..0f4b4f540 100644 --- a/radio/src/translations/en.h.txt +++ b/radio/src/translations/en.h.txt @@ -1205,6 +1205,7 @@ #define TR_MENU_OTHER "Other" #define TR_MENU_INVERT "Invert" #define TR_JITTER_FILTER "ADC filter" +#define TR_DEAD_ZONE "Dead zone" #define TR_RTC_CHECK TR("Check RTC", "Check RTC voltage") #define TR_AUTH_FAILURE "Auth-failure" #define TR_RACING_MODE "Racing mode" diff --git a/radio/src/translations/es.h.txt b/radio/src/translations/es.h.txt index 92f34fcae..47736f98d 100644 --- a/radio/src/translations/es.h.txt +++ b/radio/src/translations/es.h.txt @@ -1207,6 +1207,7 @@ #define TR_MENU_OTHER "Otros" #define TR_MENU_INVERT "Invertir" #define TR_JITTER_FILTER "Filtro ADC" +#define TR_DEAD_ZONE "Dead zone" #define TR_RTC_CHECK TR("Check RTC", "Check RTC voltaje") #define TR_AUTH_FAILURE "Fallo " LCDW_128_480_LINEBREAK "autentificación" #define TR_RACING_MODE "Racing mode" diff --git a/radio/src/translations/fi.h.txt b/radio/src/translations/fi.h.txt index de3678909..188da3e7a 100644 --- a/radio/src/translations/fi.h.txt +++ b/radio/src/translations/fi.h.txt @@ -1213,6 +1213,7 @@ #define TR_MENU_OTHER "Other" #define TR_MENU_INVERT "Invert" #define TR_JITTER_FILTER "ADC Filter" +#define TR_DEAD_ZONE "Dead zone" #define TR_RTC_CHECK TR("Check RTC", "Check RTC voltage") #define TR_AUTH_FAILURE "Auth-failure" #define TR_RACING_MODE "Racing mode" diff --git a/radio/src/translations/fr.h.txt b/radio/src/translations/fr.h.txt index 59cd70621..be0c484ee 100644 --- a/radio/src/translations/fr.h.txt +++ b/radio/src/translations/fr.h.txt @@ -1230,6 +1230,7 @@ #define TR_MENU_OTHER "Autres" #define TR_MENU_INVERT "Inverser" #define TR_JITTER_FILTER "Filtre ADC" +#define TR_DEAD_ZONE "Dead zone" #define TR_RTC_CHECK TR("Vérif. RTC", "Vérif. pile RTC") #define TR_AUTH_FAILURE "Auth-failure" #define TR_RACING_MODE "Racing mode" diff --git a/radio/src/translations/it.h.txt b/radio/src/translations/it.h.txt index e0f3ae8c9..e5e0d81ac 100644 --- a/radio/src/translations/it.h.txt +++ b/radio/src/translations/it.h.txt @@ -1226,6 +1226,7 @@ #define TR_MENU_OTHER "Altro" #define TR_MENU_INVERT "Inverti" #define TR_JITTER_FILTER "Filtro ADC" +#define TR_DEAD_ZONE "Dead zone" #define TR_RTC_CHECK TR("Controllo RTC", "Controllo volt. RTC") #define TR_AUTH_FAILURE "Auth-failure" #define TR_RACING_MODE "Racing mode" diff --git a/radio/src/translations/nl.h.txt b/radio/src/translations/nl.h.txt index af34962a6..4404d3d1d 100644 --- a/radio/src/translations/nl.h.txt +++ b/radio/src/translations/nl.h.txt @@ -1217,6 +1217,7 @@ #define TR_MENU_OTHER "Verdere" #define TR_MENU_INVERT "Inverteer" #define TR_JITTER_FILTER "ADC Filter" +#define TR_DEAD_ZONE "Dead zone" #define TR_RTC_CHECK TR("Check RTC", "Check RTC voltage") #define TR_AUTH_FAILURE "Auth-failure" #define TR_RACING_MODE "Racing mode" diff --git a/radio/src/translations/pl.h.txt b/radio/src/translations/pl.h.txt index df5c359a8..7736b9b2c 100644 --- a/radio/src/translations/pl.h.txt +++ b/radio/src/translations/pl.h.txt @@ -1222,6 +1222,7 @@ #define TR_MENU_OTHER "Inny " #define TR_MENU_INVERT "Odwróć" #define TR_JITTER_FILTER "ADC Filter" +#define TR_DEAD_ZONE "Dead zone" #define TR_RTC_CHECK TR("Check RTC", "Check RTC voltage") #define TR_AUTH_FAILURE "Auth-failure" #define TR_RACING_MODE "Racing mode" diff --git a/radio/src/translations/pt.h.txt b/radio/src/translations/pt.h.txt index 9589579bf..8e3a8664f 100644 --- a/radio/src/translations/pt.h.txt +++ b/radio/src/translations/pt.h.txt @@ -1229,6 +1229,7 @@ #define TR_MENU_OTHER "Other" #define TR_MENU_INVERT "Invert" #define TR_JITTER_FILTER "ADC Filter" +#define TR_DEAD_ZONE "Dead zone" #define TR_RTC_CHECK TR("Check RTC", "Check RTC voltage") #define TR_AUTH_FAILURE "Auth-failure" #define TR_RACING_MODE "Racing mode" diff --git a/radio/src/translations/se.h.txt b/radio/src/translations/se.h.txt index b91de33f2..a306a4383 100644 --- a/radio/src/translations/se.h.txt +++ b/radio/src/translations/se.h.txt @@ -1230,6 +1230,7 @@ #define TR_MENU_OTHER "Annat" #define TR_MENU_INVERT "Invertera" #define TR_JITTER_FILTER "ADC Filter" +#define TR_DEAD_ZONE "Dead zone" #define TR_RTC_CHECK TR("Check RTC", "Check RTC voltage") #define TR_AUTH_FAILURE "Auth-failure" #define TR_RACING_MODE "Racing mode" diff --git a/radio/src/translations/tw.h.txt b/radio/src/translations/tw.h.txt index 0ea8dd233..44d7f144a 100644 --- a/radio/src/translations/tw.h.txt +++ b/radio/src/translations/tw.h.txt @@ -1154,6 +1154,7 @@ #define TR_MENU_OTHER "其它" #define TR_MENU_INVERT "反向" #define TR_JITTER_FILTER "類比輸入濾波" +#define TR_DEAD_ZONE "Dead zone" #define TR_RTC_CHECK TR("Check RTC", "檢查時間驅動電池電壓") #define TR_AUTH_FAILURE "驗證失敗" #define TR_RACING_MODE "Racing mode"