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