diff --git a/mk/source.mk b/mk/source.mk
index 65286356953..caefe30e0a6 100644
--- a/mk/source.mk
+++ b/mk/source.mk
@@ -150,6 +150,8 @@ COMMON_SRC = \
cms/cms_menu_vtx_smartaudio.c \
cms/cms_menu_vtx_tramp.c \
cms/cms_menu_persistent_stats.c \
+ cms/cms_menu_rpm_limit.c \
+ cms/cms_menu_quick.c \
drivers/display_ug2864hsweg01.c \
drivers/light_ws2811strip.c \
drivers/rangefinder/rangefinder_hcsr04.c \
@@ -410,6 +412,8 @@ SIZE_OPTIMISED_SRC := $(SIZE_OPTIMISED_SRC) \
cms/cms_menu_vtx_smartaudio.c \
cms/cms_menu_vtx_tramp.c \
cms/cms_menu_persistent_stats.c \
+ cms/cms_menu_rpm_limit.c \
+ cms/cms_menu_quick.c \
io/vtx.c \
io/vtx_rtc6705.c \
io/vtx_smartaudio.c \
diff --git a/src/main/cli/settings.c b/src/main/cli/settings.c
index 99b1b367e2d..90d0f5793f7 100644
--- a/src/main/cli/settings.c
+++ b/src/main/cli/settings.c
@@ -1367,7 +1367,9 @@ const clivalue_t valueTable[] = {
{ "osd_ah_invert", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_OSD_CONFIG, offsetof(osdConfig_t, ahInvert) },
{ "osd_logo_on_arming", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OSD_LOGO_ON_ARMING }, PG_OSD_CONFIG, offsetof(osdConfig_t, logo_on_arming) },
{ "osd_logo_on_arming_duration",VAR_UINT8 | MASTER_VALUE, .config.minmaxUnsigned = { 5, 50 }, PG_OSD_CONFIG, offsetof(osdConfig_t, logo_on_arming_duration) },
-
+#ifdef USE_QUICK_OSD_MENU
+ { "osd_use_quick_menu", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_OSD_CONFIG, offsetof(osdConfig_t, osd_use_quick_menu) },
+#endif // USE_QUICK_OSD_MENU
{ "osd_tim1", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, INT16_MAX }, PG_OSD_CONFIG, offsetof(osdConfig_t, timers[OSD_TIMER_1]) },
{ "osd_tim2", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, INT16_MAX }, PG_OSD_CONFIG, offsetof(osdConfig_t, timers[OSD_TIMER_2]) },
diff --git a/src/main/cms/cms.c b/src/main/cms/cms.c
index c4578ffd303..bc853fe0327 100644
--- a/src/main/cms/cms.c
+++ b/src/main/cms/cms.c
@@ -43,6 +43,7 @@
#include "cms/cms.h"
#include "cms/cms_menu_main.h"
#include "cms/cms_menu_saveexit.h"
+#include "cms/cms_menu_quick.h"
#include "cms/cms_types.h"
#include "common/maths.h"
@@ -845,7 +846,7 @@ const void *cmsMenuChange(displayPort_t *pDisplay, const void *ptr)
if (pMenu != currentCtx.menu) {
saveMenuInhibited = false;
- if (currentCtx.menu) {
+ if (currentCtx.menu && pMenu != &cmsx_menuMain) {
// If we are opening the initial top-level menu, then currentCtx.menu will be NULL and nothing to do.
// Otherwise stack the current menu before moving to the selected menu.
if (menuStackIdx >= CMS_MENU_STACK_LIMIT - 1) {
@@ -896,6 +897,13 @@ void cmsMenuOpen(void)
cmsInMenu = true;
currentCtx = (cmsCtx_t){ NULL, 0, 0 };
startMenu = &cmsx_menuMain;
+
+#ifdef USE_QUICK_OSD_MENU
+ if (osdConfig()->osd_use_quick_menu) {
+ startMenu = &cmsx_menuQuick;
+ }
+#endif // USE_QUICK_OSD_MENU
+
menuStackIdx = 0;
setArmingDisabled(ARMING_DISABLED_CMS_MENU);
displayLayerSelect(pCurrentDisplay, DISPLAYPORT_LAYER_FOREGROUND); // make sure the foreground layer is active
diff --git a/src/main/cms/cms_menu_quick.c b/src/main/cms/cms_menu_quick.c
new file mode 100644
index 00000000000..aad64601756
--- /dev/null
+++ b/src/main/cms/cms_menu_quick.c
@@ -0,0 +1,127 @@
+/*
+ * This file is part of Betaflight.
+ *
+ * Betaflight is free software. You can redistribute this software
+ * and/or modify this software under the terms of the GNU General
+ * Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * Betaflight 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.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this software.
+ *
+ * If not, see .
+ */
+
+#include
+#include
+
+#include "platform.h"
+
+#ifdef USE_CMS
+#ifdef USE_QUICK_OSD_MENU
+
+#include "cms/cms.h"
+#include "cms/cms_types.h"
+#include "cms/cms_menu_main.h"
+#include "cms/cms_menu_vtx_common.h"
+#include "cms/cms_menu_rpm_limit.h"
+#include "common/printf.h"
+#include "config/config.h"
+
+#include "drivers/pwm_output.h"
+
+#include "fc/controlrate_profile.h"
+#include "fc/core.h"
+#include "fc/runtime_config.h"
+#include "flight/pid.h"
+#include "flight/pid_init.h"
+
+#include "sensors/battery.h"
+
+#include "cms_menu_quick.h"
+
+static controlRateConfig_t rateProfile;
+static uint8_t rateProfileIndex;
+static batteryConfig_t batteryProfile;
+static uint8_t cmsx_motorOutputLimit;
+static uint8_t pidProfileIndex;
+static pidProfile_t *pidProfile;
+
+static const void *quickMenuOnEnter(displayPort_t *pDisp)
+{
+ UNUSED(pDisp);
+ pidProfileIndex = getCurrentPidProfileIndex();
+ pidProfile = pidProfilesMutable(pidProfileIndex);
+
+ rateProfileIndex = getCurrentControlRateProfileIndex();
+ memcpy(&rateProfile, controlRateProfiles(rateProfileIndex), sizeof(controlRateConfig_t));
+ memcpy(&batteryProfile, batteryConfigMutable(), sizeof(batteryConfig_t));
+
+ cmsx_motorOutputLimit = pidProfile->motor_output_limit;
+
+ return NULL;
+}
+
+static const void *cmsx_RateProfileWriteback(displayPort_t *pDisp, const OSD_Entry *self)
+{
+ UNUSED(pDisp);
+ UNUSED(self);
+
+ memcpy(controlRateProfilesMutable(rateProfileIndex), &rateProfile, sizeof(controlRateConfig_t));
+ memcpy(batteryConfigMutable(), &batteryProfile, sizeof(batteryConfig_t));
+
+ pidProfile_t *pidProfile = pidProfilesMutable(pidProfileIndex);
+ pidProfile->motor_output_limit = cmsx_motorOutputLimit;
+
+ pidInitConfig(currentPidProfile);
+
+ return NULL;
+}
+
+
+static const char * const osdTableThrottleLimitType[] = {
+ "OFF", "SCALE", "CLIP"
+};
+
+static const OSD_Entry menuMainEntries[] =
+{
+ { "-- QUICK --", OME_Label, NULL, NULL },
+
+#if defined(USE_RPM_LIMIT)
+ { "RPM LIM", OME_Submenu, cmsMenuChange, &cmsx_menuRpmLimit },
+#endif
+ { "THR LIM TYPE",OME_TAB, NULL, &(OSD_TAB_t) { &rateProfile.throttle_limit_type, THROTTLE_LIMIT_TYPE_COUNT - 1, osdTableThrottleLimitType} },
+ { "THR LIM %", OME_UINT8, NULL, &(OSD_UINT8_t) { &rateProfile.throttle_limit_percent, 25, 100, 1} },
+ { "MTR OUT LIM %",OME_UINT8, NULL, &(OSD_UINT8_t) { &cmsx_motorOutputLimit, MOTOR_OUTPUT_LIMIT_PERCENT_MIN, MOTOR_OUTPUT_LIMIT_PERCENT_MAX, 1} },
+ { "FORCE CELLS", OME_UINT8, NULL, &(OSD_UINT8_t) { &batteryProfile.forceBatteryCellCount, 0, 24, 1} },
+#if defined(USE_VTX_CONTROL)
+#if defined(USE_VTX_RTC6705) || defined(USE_VTX_SMARTAUDIO) || defined(USE_VTX_TRAMP)
+ {"VTX", OME_Funcall, cmsSelectVtx, NULL},
+#endif
+#endif // VTX_CONTROL
+ { "MAIN", OME_Submenu, NULL, &cmsx_menuMain },
+ { "EXIT", OME_OSD_Exit, cmsMenuExit, (void *)CMS_EXIT},
+ { "SAVE&REBOOT", OME_OSD_Exit, cmsMenuExit, (void *)CMS_POPUP_SAVEREBOOT},
+ {NULL, OME_END, NULL, NULL},
+};
+
+CMS_Menu cmsx_menuQuick = {
+#ifdef CMS_MENU_DEBUG
+ .GUARD_text = "MENUQUICK",
+ .GUARD_type = OME_MENU,
+#endif
+ .onEnter = quickMenuOnEnter,
+ .onExit = cmsx_RateProfileWriteback,
+ .onDisplayUpdate = NULL,
+ .entries = menuMainEntries,
+};
+
+#endif // USE_QUICK_OSD_MENU
+#endif // USE_CMS
diff --git a/src/main/cms/cms_menu_quick.h b/src/main/cms/cms_menu_quick.h
new file mode 100644
index 00000000000..49782f5b920
--- /dev/null
+++ b/src/main/cms/cms_menu_quick.h
@@ -0,0 +1,26 @@
+/*
+ * This file is part of Betaflight.
+ *
+ * Betaflight is free software. You can redistribute this software
+ * and/or modify this software under the terms of the GNU General
+ * Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * Betaflight 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.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this software.
+ *
+ * If not, see .
+ */
+
+#pragma once
+
+#include "cms/cms_types.h"
+
+extern CMS_Menu cmsx_menuQuick;
diff --git a/src/main/cms/cms_menu_rpm_limit.c b/src/main/cms/cms_menu_rpm_limit.c
new file mode 100644
index 00000000000..eaff55d87d9
--- /dev/null
+++ b/src/main/cms/cms_menu_rpm_limit.c
@@ -0,0 +1,91 @@
+/*
+ * This file is part of Betaflight.
+ *
+ * Betaflight is free software. You can redistribute this software
+ * and/or modify this software under the terms of the GNU General
+ * Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * Betaflight 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.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this software.
+ *
+ * If not, see .
+ */
+
+#include
+#include
+#include
+#include
+
+#include "platform.h"
+
+#ifdef USE_CMS
+#ifdef USE_RPM_LIMIT
+
+#include "cms/cms.h"
+#include "cms/cms_types.h"
+#include "config/config.h"
+#include "pg/stats.h"
+#include "flight/mixer.h"
+
+#include "cms/cms_menu_rpm_limit.h"
+
+uint16_t rpm_limit_value;
+uint16_t kv;
+bool rpm_limit;
+
+static const void *cmsx_RpmLimit_onEnter(displayPort_t *pDisp)
+{
+ UNUSED(pDisp);
+
+ rpm_limit_value = mixerConfig()->rpm_limit_value;
+ kv = motorConfig()->kv;
+ rpm_limit = mixerConfig()->rpm_limit;
+
+ return NULL;
+}
+
+static const void *cmsx_RpmLimit_onExit(displayPort_t *pDisp, const OSD_Entry *self)
+{
+ UNUSED(pDisp);
+ UNUSED(self);
+
+ mixerConfigMutable()->rpm_limit_value = rpm_limit_value;
+ motorConfigMutable()->kv = kv;
+ mixerConfigMutable()->rpm_limit = rpm_limit;
+
+ return NULL;
+}
+
+static const OSD_Entry cmsx_menuRpmLimitEntries[] =
+{
+ { "-- RPM LIMIT --", OME_Label, NULL, NULL },
+ { "ACTIVE", OME_Bool | REBOOT_REQUIRED, NULL, &rpm_limit },
+ { "MAX RPM", OME_UINT16, NULL, &(OSD_UINT16_t){ &rpm_limit_value, 0, UINT16_MAX, 100} },
+ { "KV", OME_UINT16, NULL, &(OSD_UINT16_t){ &kv, 0, UINT16_MAX, 1} },
+
+ { "SAVE&REBOOT", OME_OSD_Exit, cmsMenuExit, (void *)CMS_POPUP_SAVEREBOOT },
+ { "BACK", OME_Back, NULL, NULL },
+ { NULL, OME_END, NULL, NULL}
+};
+
+CMS_Menu cmsx_menuRpmLimit = {
+#ifdef CMS_MENU_DEBUG
+ .GUARD_text = "RPMLIMIT",
+ .GUARD_type = OME_MENU,
+#endif
+ .onEnter = cmsx_RpmLimit_onEnter,
+ .onExit = cmsx_RpmLimit_onExit,
+ .onDisplayUpdate = NULL,
+ .entries = cmsx_menuRpmLimitEntries
+};
+
+#endif
+#endif // USE_RPM_LIMIT
diff --git a/src/main/cms/cms_menu_rpm_limit.h b/src/main/cms/cms_menu_rpm_limit.h
new file mode 100644
index 00000000000..0dc0538a323
--- /dev/null
+++ b/src/main/cms/cms_menu_rpm_limit.h
@@ -0,0 +1,24 @@
+/*
+ * This file is part of Betaflight.
+ *
+ * Betaflight is free software. You can redistribute this software
+ * and/or modify this software under the terms of the GNU General
+ * Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * Betaflight 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.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this software.
+ *
+ * If not, see .
+ */
+
+#pragma once
+
+extern CMS_Menu cmsx_menuRpmLimit;
diff --git a/src/main/cms/cms_menu_vtx_smartaudio.c b/src/main/cms/cms_menu_vtx_smartaudio.c
index 520b2fb9d6c..bebeec645e8 100644
--- a/src/main/cms/cms_menu_vtx_smartaudio.c
+++ b/src/main/cms/cms_menu_vtx_smartaudio.c
@@ -491,9 +491,6 @@ static const void *saCmsConfigFreqModeByGvar(displayPort_t *pDisp, const void *s
static const void *saCmsCommence(displayPort_t *pDisp, const void *self)
{
- UNUSED(pDisp);
- UNUSED(self);
-
const vtxSettingsConfig_t prevSettings = {
.band = vtxSettingsConfig()->band,
.channel = vtxSettingsConfig()->channel,
@@ -537,6 +534,8 @@ static const void *saCmsCommence(displayPort_t *pDisp, const void *self)
saveConfigAndNotify();
}
+ cmsMenuExit(pDisp, self);
+
return MENU_CHAIN_BACK;
}
@@ -682,7 +681,7 @@ static CMS_Menu saCmsMenuConfig = {
static const OSD_Entry saCmsMenuCommenceEntries[] = {
{ "CONFIRM", OME_Label, NULL, NULL },
- { "YES", OME_Funcall, saCmsCommence, NULL },
+ { "YES", OME_OSD_Exit, saCmsCommence, (void *)CMS_EXIT },
{ "NO", OME_Back, NULL, NULL },
{ NULL, OME_END, NULL, NULL }
@@ -706,7 +705,7 @@ static const OSD_Entry saCmsMenuFreqModeEntries[] = {
{ "FREQ", OME_Submenu | OPTSTRING, (CMSEntryFuncPtr)saCmsUserFreqGetString, &saCmsMenuUserFreq },
{ "POWER", OME_TAB | DYNAMIC, saCmsConfigPowerByGvar, &saCmsEntPower },
{ "PIT", OME_TAB | DYNAMIC, saCmsConfigPitByGvar, &saCmsEntPit },
- { "SAVE", OME_Submenu, cmsMenuChange, &saCmsMenuCommence },
+ { "SAVE&EXIT", OME_Submenu, cmsMenuChange, &saCmsMenuCommence },
{ "CONFIG", OME_Submenu, cmsMenuChange, &saCmsMenuConfig },
{ "BACK", OME_Back, NULL, NULL },
@@ -723,7 +722,7 @@ static const OSD_Entry saCmsMenuChanModeEntries[] =
{ "(FREQ)", OME_UINT16 | DYNAMIC, NULL, &saCmsEntFreqRef },
{ "POWER", OME_TAB | DYNAMIC, saCmsConfigPowerByGvar, &saCmsEntPower },
{ "PIT", OME_TAB | DYNAMIC, saCmsConfigPitByGvar, &saCmsEntPit },
- { "SAVE", OME_Submenu, cmsMenuChange, &saCmsMenuCommence },
+ { "SAVE&EXIT", OME_Submenu, cmsMenuChange, &saCmsMenuCommence },
{ "CONFIG", OME_Submenu, cmsMenuChange, &saCmsMenuConfig },
{ "BACK", OME_Back, NULL, NULL },
diff --git a/src/main/cms/cms_menu_vtx_tramp.c b/src/main/cms/cms_menu_vtx_tramp.c
index 9ef7f418e50..c3a1f3a3858 100644
--- a/src/main/cms/cms_menu_vtx_tramp.c
+++ b/src/main/cms/cms_menu_vtx_tramp.c
@@ -195,6 +195,7 @@ static const void *trampCmsCommence(displayPort_t *pDisp, const void *self)
vtxSettingsConfigMutable()->freq = vtxCommonLookupFrequency(vtxCommonDevice(), trampCmsBand, trampCmsChan);
saveConfigAndNotify();
+ cmsMenuExit(pDisp, self);
return MENU_CHAIN_BACK;
}
@@ -249,7 +250,7 @@ static const void *trampCmsOnEnter(displayPort_t *pDisp)
static const OSD_Entry trampCmsMenuCommenceEntries[] = {
{ "CONFIRM", OME_Label, NULL, NULL },
- { "YES", OME_Funcall, trampCmsCommence, NULL },
+ { "YES", OME_OSD_Exit, trampCmsCommence, (void *)CMS_EXIT },
{ "NO", OME_Back, NULL, NULL },
{ NULL, OME_END, NULL, NULL }
};
@@ -276,7 +277,7 @@ static const OSD_Entry trampMenuEntries[] =
{ "(FREQ)", OME_UINT16 | DYNAMIC, NULL, &trampCmsEntFreqRef },
{ "POWER", OME_TAB, trampCmsConfigPower, &trampCmsEntPower },
{ "T(C)", OME_INT16 | DYNAMIC, NULL, &trampCmsEntTemp },
- { "SAVE", OME_Submenu, cmsMenuChange, &trampCmsMenuCommence },
+ { "SAVE&EXIT", OME_Submenu, cmsMenuChange, &trampCmsMenuCommence },
{ "BACK", OME_Back, NULL, NULL },
{ NULL, OME_END, NULL, NULL }
diff --git a/src/main/osd/osd.c b/src/main/osd/osd.c
index 860b1e59f73..4b2b537a6d1 100644
--- a/src/main/osd/osd.c
+++ b/src/main/osd/osd.c
@@ -413,6 +413,10 @@ void pgResetFn_osdConfig(osdConfig_t *osdConfig)
osdConfig->canvas_cols = OSD_SD_COLS;
osdConfig->canvas_rows = OSD_SD_ROWS;
#endif
+
+#ifdef USE_QUICK_OSD_MENU
+ osdConfig->osd_use_quick_menu = true;
+#endif // USE_QUICK_OSD_MENU
}
void pgResetFn_osdElementConfig(osdElementConfig_t *osdElementConfig)
diff --git a/src/main/osd/osd.h b/src/main/osd/osd.h
index 788296e0db9..aefc2400ca1 100644
--- a/src/main/osd/osd.h
+++ b/src/main/osd/osd.h
@@ -345,6 +345,9 @@ typedef struct osdConfig_s {
uint8_t aux_symbol;
uint8_t canvas_cols; // Canvas dimensions for HD display
uint8_t canvas_rows;
+ #ifdef USE_QUICK_OSD_MENU
+ uint8_t osd_use_quick_menu; // use QUICK menu YES/NO
+ #endif // USE_QUICK_OSD_MENU
} osdConfig_t;
PG_DECLARE(osdConfig_t, osdConfig);
diff --git a/src/test/unit/cms_unittest.cc b/src/test/unit/cms_unittest.cc
index ba7a00dceb1..330baf61c12 100644
--- a/src/test/unit/cms_unittest.cc
+++ b/src/test/unit/cms_unittest.cc
@@ -29,6 +29,7 @@ extern "C" {
#include "platform.h"
#include "target.h"
#include "cms/cms.h"
+ #include "cms/cms_menu_quick.h"
#include "cms/cms_types.h"
#include "fc/rc_modes.h"
#include "fc/runtime_config.h"
@@ -47,6 +48,14 @@ extern "C" {
#include "unittest_displayport.h"
#include "gtest/gtest.h"
+CMS_Menu cmsx_menuQuick = {
+ .onEnter = NULL,
+ .onExit = NULL,
+ .onDisplayUpdate = NULL,
+ .entries = NULL,
+};
+
+
TEST(CMSUnittest, TestCmsDisplayPortRegister)
{
cmsInit();