diff --git a/make/source.mk b/make/source.mk
index c248b3b36a..c9326c255e 100644
--- a/make/source.mk
+++ b/make/source.mk
@@ -138,6 +138,7 @@ COMMON_SRC = \
cms/cms_menu_osd.c \
cms/cms_menu_power.c \
cms/cms_menu_saveexit.c \
+ cms/cms_menu_vtx_common.c \
cms/cms_menu_vtx_rtc6705.c \
cms/cms_menu_vtx_smartaudio.c \
cms/cms_menu_vtx_tramp.c \
@@ -327,6 +328,7 @@ SIZE_OPTIMISED_SRC := $(SIZE_OPTIMISED_SRC) \
cms/cms_menu_osd.c \
cms/cms_menu_power.c \
cms/cms_menu_saveexit.c \
+ cms/cms_menu_vtx_common.c \
cms/cms_menu_vtx_rtc6705.c \
cms/cms_menu_vtx_smartaudio.c \
cms/cms_menu_vtx_tramp.c \
diff --git a/src/main/cms/cms.c b/src/main/cms/cms.c
index d0e83a6e1e..ee355b162e 100644
--- a/src/main/cms/cms.c
+++ b/src/main/cms/cms.c
@@ -654,6 +654,13 @@ long cmsMenuChange(displayPort_t *pDisplay, const void *ptr)
return 0;
}
+ if (pMenu->checkRedirect) {
+ const CMS_Menu *pRedirectMenu = (const CMS_Menu *)pMenu->checkRedirect();
+ if (pRedirectMenu) {
+ return cmsMenuChange(pDisplay, pRedirectMenu);
+ }
+ }
+
menuStack[menuStackIdx++] = currentCtx;
currentCtx.menu = pMenu;
diff --git a/src/main/cms/cms_menu_blackbox.c b/src/main/cms/cms_menu_blackbox.c
index 66235e8a04..1332cfa4bb 100644
--- a/src/main/cms/cms_menu_blackbox.c
+++ b/src/main/cms/cms_menu_blackbox.c
@@ -221,6 +221,7 @@ CMS_Menu cmsx_menuBlackbox = {
#endif
.onEnter = cmsx_Blackbox_onEnter,
.onExit = cmsx_Blackbox_onExit,
+ .checkRedirect = NULL,
.entries = cmsx_menuBlackboxEntries
};
diff --git a/src/main/cms/cms_menu_builtin.c b/src/main/cms/cms_menu_builtin.c
index db9aa01632..b5c151baba 100644
--- a/src/main/cms/cms_menu_builtin.c
+++ b/src/main/cms/cms_menu_builtin.c
@@ -49,9 +49,7 @@
// VTX supplied menus
-#include "cms/cms_menu_vtx_rtc6705.h"
-#include "cms/cms_menu_vtx_smartaudio.h"
-#include "cms/cms_menu_vtx_tramp.h"
+#include "cms/cms_menu_vtx_common.h"
#include "drivers/system.h"
@@ -98,6 +96,7 @@ static CMS_Menu menuInfo = {
#endif
.onEnter = cmsx_InfoInit,
.onExit = NULL,
+ .checkRedirect = NULL,
.entries = menuInfoEntries
};
@@ -111,14 +110,8 @@ static const OSD_Entry menuFeaturesEntries[] =
{"BLACKBOX", OME_Submenu, cmsMenuChange, &cmsx_menuBlackbox, 0},
#endif
#if defined(USE_VTX_CONTROL)
-#if defined(USE_VTX_RTC6705)
- {"VTX", OME_Submenu, cmsMenuChange, &cmsx_menuVtxRTC6705, 0},
-#endif // VTX_RTC6705
-#if defined(USE_VTX_SMARTAUDIO)
- {"VTX SA", OME_Submenu, cmsMenuChange, &cmsx_menuVtxSmartAudio, 0},
-#endif
-#if defined(USE_VTX_TRAMP)
- {"VTX TR", OME_Submenu, cmsMenuChange, &cmsx_menuVtxTramp, 0},
+#if defined(USE_VTX_RTC6705) || defined(USE_VTX_SMARTAUDIO) || defined(USE_VTX_TRAMP)
+ {"VTX", OME_Submenu, cmsMenuChange, &cmsx_menuVtxRedirect, 0},
#endif
#endif // VTX_CONTROL
#ifdef USE_LED_STRIP
@@ -139,6 +132,7 @@ static CMS_Menu menuFeatures = {
#endif
.onEnter = NULL,
.onExit = NULL,
+ .checkRedirect = NULL,
.entries = menuFeaturesEntries,
};
@@ -182,6 +176,7 @@ CMS_Menu menuMain = {
#endif
.onEnter = NULL,
.onExit = NULL,
+ .checkRedirect = NULL,
.entries = menuMainEntries,
};
#endif
diff --git a/src/main/cms/cms_menu_failsafe.c b/src/main/cms/cms_menu_failsafe.c
index 1e5ed46d9c..b7c60f4f47 100644
--- a/src/main/cms/cms_menu_failsafe.c
+++ b/src/main/cms/cms_menu_failsafe.c
@@ -91,6 +91,7 @@ CMS_Menu cmsx_menuFailsafe = {
#endif
.onEnter = cmsx_Failsafe_onEnter,
.onExit = cmsx_Failsafe_onExit,
+ .checkRedirect = NULL,
.entries = cmsx_menuFailsafeEntries
};
diff --git a/src/main/cms/cms_menu_gps_rescue.c b/src/main/cms/cms_menu_gps_rescue.c
index b4fb56d5e3..b5406029c4 100644
--- a/src/main/cms/cms_menu_gps_rescue.c
+++ b/src/main/cms/cms_menu_gps_rescue.c
@@ -117,6 +117,7 @@ CMS_Menu cms_menuGpsRescuePid = {
#endif
.onEnter = cms_menuGpsRescuePidOnEnter,
.onExit = cms_menuGpsRescuePidOnExit,
+ .checkRedirect = NULL,
.entries = cms_menuGpsRescuePidEntries,
};
@@ -198,6 +199,7 @@ CMS_Menu cmsx_menuGpsRescue = {
#endif
.onEnter = cmsx_menuGpsRescueOnEnter,
.onExit = cmsx_menuGpsRescueOnExit,
+ .checkRedirect = NULL,
.entries = cmsx_menuGpsRescueEntries,
};
diff --git a/src/main/cms/cms_menu_imu.c b/src/main/cms/cms_menu_imu.c
index 13d089c1fb..50077bd185 100644
--- a/src/main/cms/cms_menu_imu.c
+++ b/src/main/cms/cms_menu_imu.c
@@ -223,6 +223,7 @@ static CMS_Menu cmsx_menuPid = {
#endif
.onEnter = cmsx_PidOnEnter,
.onExit = cmsx_PidWriteback,
+ .checkRedirect = NULL,
.entries = cmsx_menuPidEntries
};
@@ -289,6 +290,7 @@ static CMS_Menu cmsx_menuRateProfile = {
#endif
.onEnter = cmsx_RateProfileOnEnter,
.onExit = cmsx_RateProfileWriteback,
+ .checkRedirect = NULL,
.entries = cmsx_menuRateProfileEntries
};
@@ -347,6 +349,7 @@ static CMS_Menu cmsx_menuLaunchControl = {
#endif
.onEnter = cmsx_launchControlOnEnter,
.onExit = cmsx_launchControlOnExit,
+ .checkRedirect = NULL,
.entries = cmsx_menuLaunchControlEntries,
};
#endif
@@ -492,6 +495,7 @@ static CMS_Menu cmsx_menuProfileOther = {
#endif
.onEnter = cmsx_profileOtherOnEnter,
.onExit = cmsx_profileOtherOnExit,
+ .checkRedirect = NULL,
.entries = cmsx_menuProfileOtherEntries,
};
@@ -559,6 +563,7 @@ static CMS_Menu cmsx_menuFilterGlobal = {
#endif
.onEnter = cmsx_menuGyro_onEnter,
.onExit = cmsx_menuGyro_onExit,
+ .checkRedirect = NULL,
.entries = cmsx_menuFilterGlobalEntries,
};
@@ -646,6 +651,7 @@ static CMS_Menu cmsx_menuDynFilt = {
#endif
.onEnter = cmsx_menuDynFilt_onEnter,
.onExit = cmsx_menuDynFilt_onExit,
+ .checkRedirect = NULL,
.entries = cmsx_menuDynFiltEntries,
};
@@ -706,6 +712,7 @@ static CMS_Menu cmsx_menuFilterPerProfile = {
#endif
.onEnter = cmsx_FilterPerProfileRead,
.onExit = cmsx_FilterPerProfileWriteback,
+ .checkRedirect = NULL,
.entries = cmsx_menuFilterPerProfileEntries,
};
@@ -776,6 +783,7 @@ CMS_Menu cmsx_menuCopyProfile = {
#endif
.onEnter = cmsx_menuCopyProfile_onEnter,
.onExit = NULL,
+ .checkRedirect = NULL,
.entries = cmsx_menuCopyProfileEntries,
};
@@ -813,6 +821,7 @@ CMS_Menu cmsx_menuImu = {
#endif
.onEnter = cmsx_menuImu_onEnter,
.onExit = cmsx_menuImu_onExit,
+ .checkRedirect = NULL,
.entries = cmsx_menuImuEntries,
};
diff --git a/src/main/cms/cms_menu_ledstrip.c b/src/main/cms/cms_menu_ledstrip.c
index 7d1845db42..72f2ede1bd 100644
--- a/src/main/cms/cms_menu_ledstrip.c
+++ b/src/main/cms/cms_menu_ledstrip.c
@@ -127,6 +127,7 @@ CMS_Menu cmsx_menuLedstrip = {
#endif
.onEnter = cmsx_Ledstrip_OnEnter,
.onExit = cmsx_Ledstrip_OnExit,
+ .checkRedirect = NULL,
.entries = cmsx_menuLedstripEntries
};
#endif // LED_STRIP
diff --git a/src/main/cms/cms_menu_misc.c b/src/main/cms/cms_menu_misc.c
index 4826e715fa..6e2b647ae5 100644
--- a/src/main/cms/cms_menu_misc.c
+++ b/src/main/cms/cms_menu_misc.c
@@ -93,6 +93,7 @@ CMS_Menu cmsx_menuRcPreview = {
#endif
.onEnter = NULL,
.onExit = cmsx_menuRcConfirmBack,
+ .checkRedirect = NULL,
.entries = cmsx_menuRcEntries
};
@@ -144,6 +145,7 @@ CMS_Menu cmsx_menuMisc = {
#endif
.onEnter = cmsx_menuMiscOnEnter,
.onExit = cmsx_menuMiscOnExit,
+ .checkRedirect = NULL,
.entries = menuMiscEntries
};
diff --git a/src/main/cms/cms_menu_osd.c b/src/main/cms/cms_menu_osd.c
index 24f11b4861..4fb8504478 100644
--- a/src/main/cms/cms_menu_osd.c
+++ b/src/main/cms/cms_menu_osd.c
@@ -158,6 +158,7 @@ CMS_Menu menuOsdActiveElems = {
#endif
.onEnter = menuOsdActiveElemsOnEnter,
.onExit = menuOsdActiveElemsOnExit,
+ .checkRedirect = NULL,
.entries = menuOsdActiveElemsEntries
};
@@ -218,6 +219,7 @@ CMS_Menu menuAlarms = {
#endif
.onEnter = menuAlarmsOnEnter,
.onExit = menuAlarmsOnExit,
+ .checkRedirect = NULL,
.entries = menuAlarmsEntries,
};
@@ -270,6 +272,7 @@ CMS_Menu menuTimers = {
#endif
.onEnter = menuTimersOnEnter,
.onExit = menuTimersOnExit,
+ .checkRedirect = NULL,
.entries = menuTimersEntries,
};
#endif /* USE_EXTENDED_CMS_MENUS */
@@ -343,6 +346,7 @@ CMS_Menu cmsx_menuOsd = {
#endif
.onEnter = cmsx_menuOsdOnEnter,
.onExit = cmsx_menuOsdOnExit,
+ .checkRedirect = NULL,
.entries = cmsx_menuOsdEntries
};
#endif // CMS
diff --git a/src/main/cms/cms_menu_power.c b/src/main/cms/cms_menu_power.c
index 111611f6d4..47a66ffa63 100644
--- a/src/main/cms/cms_menu_power.c
+++ b/src/main/cms/cms_menu_power.c
@@ -126,6 +126,7 @@ CMS_Menu cmsx_menuPower = {
#endif
.onEnter = cmsx_Power_onEnter,
.onExit = cmsx_Power_onExit,
+ .checkRedirect = NULL,
.entries = cmsx_menuPowerEntries
};
diff --git a/src/main/cms/cms_menu_saveexit.c b/src/main/cms/cms_menu_saveexit.c
index f8b860f375..2cafea32ba 100644
--- a/src/main/cms/cms_menu_saveexit.c
+++ b/src/main/cms/cms_menu_saveexit.c
@@ -49,6 +49,9 @@ CMS_Menu cmsx_menuSaveExit = {
.GUARD_text = "MENUSAVE",
.GUARD_type = OME_MENU,
#endif
+ .onEnter = NULL,
+ .onExit = NULL,
+ .checkRedirect = NULL,
.entries = cmsx_menuSaveExitEntries
};
@@ -66,6 +69,9 @@ CMS_Menu cmsx_menuSaveExitReboot = {
.GUARD_text = "MENUSAVE",
.GUARD_type = OME_MENU,
#endif
+ .onEnter = NULL,
+ .onExit = NULL,
+ .checkRedirect = NULL,
.entries = cmsx_menuSaveExitRebootEntries
};
diff --git a/src/main/cms/cms_menu_vtx_common.c b/src/main/cms/cms_menu_vtx_common.c
new file mode 100644
index 0000000000..9ea05c519b
--- /dev/null
+++ b/src/main/cms/cms_menu_vtx_common.c
@@ -0,0 +1,120 @@
+/*
+ * This file is part of Cleanflight and Betaflight.
+ *
+ * Cleanflight and Betaflight are 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.
+ *
+ * Cleanflight and Betaflight are distributed in the hope that they
+ * 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 "platform.h"
+
+#if defined(USE_CMS) && defined(USE_VTX_CONTROL) && (defined(USE_VTX_TRAMP) || defined(USE_VTX_SMARTAUDIO) || defined(USE_VTX_RTC6705))
+
+#include "common/printf.h"
+
+#include "cms/cms.h"
+#include "cms/cms_menu_vtx_rtc6705.h"
+#include "cms/cms_menu_vtx_smartaudio.h"
+#include "cms/cms_menu_vtx_tramp.h"
+#include "cms/cms_types.h"
+
+#include "drivers/vtx_common.h"
+
+#include "cms_menu_vtx_common.h"
+
+#define MAX_STATUS_LINE_LENGTH 21
+
+static char statusLine1[MAX_STATUS_LINE_LENGTH] = "";
+static char statusLine2[MAX_STATUS_LINE_LENGTH] = "";
+
+static long setStatusMessage(void)
+{
+ vtxDevice_t *device = vtxCommonDevice();
+
+ statusLine1[0] = 0;
+ statusLine2[0] = 0;
+
+ if (!device) {
+ tfp_sprintf(&statusLine1[0], "VTX NOT RESPONDING");
+ tfp_sprintf(&statusLine2[0], "OR NOT CONFIGURED");
+ } else {
+ vtxDevType_e vtxType = vtxCommonGetDeviceType(device);
+ if (vtxType == VTXDEV_UNSUPPORTED) {
+ tfp_sprintf(&statusLine1[0], "UNSUPPORTED VTX TYPE");
+ } else {
+ tfp_sprintf(&statusLine1[0], "UNKNOWN VTX TYPE");
+ }
+ }
+ return 0;
+}
+
+// Redirect to the proper menu based on the vtx device type
+// If device isn't valid or not a supported type then don't
+// redirect and instead display a local informational menu.
+static const void *vtxMenuRedirect(void)
+{
+ vtxDevice_t *device = vtxCommonDevice();
+
+ if (device) {
+ vtxDevType_e vtxType = vtxCommonGetDeviceType(device);
+
+ switch (vtxType) {
+
+#if defined(USE_VTX_RTC6705)
+ case VTXDEV_RTC6705:
+ return &cmsx_menuVtxRTC6705;
+#endif
+#if defined(USE_VTX_SMARTAUDIO)
+ case VTXDEV_SMARTAUDIO:
+ return &cmsx_menuVtxSmartAudio;
+#endif
+#if defined(USE_VTX_TRAMP)
+ case VTXDEV_TRAMP:
+ return &cmsx_menuVtxTramp;
+#endif
+
+ default:
+ return NULL;
+ }
+ }
+
+ return NULL;
+}
+
+static const OSD_Entry vtxRedirectMenuEntries[] =
+{
+ { "", OME_Label, NULL, statusLine1, DYNAMIC },
+ { "", OME_Label, NULL, statusLine2, DYNAMIC },
+ { "", OME_Label, NULL, NULL, 0 },
+ { "BACK", OME_Back, NULL, NULL, 0 },
+ { NULL, OME_END, NULL, NULL, 0 }
+};
+
+CMS_Menu cmsx_menuVtxRedirect = {
+#ifdef CMS_MENU_DEBUG
+ .GUARD_text = "XVTXREDIRECT",
+ .GUARD_type = OME_MENU,
+#endif
+ .onEnter = setStatusMessage,
+ .onExit = NULL,
+ .checkRedirect = vtxMenuRedirect,
+ .entries = vtxRedirectMenuEntries,
+};
+
+#endif
diff --git a/src/main/cms/cms_menu_vtx_common.h b/src/main/cms/cms_menu_vtx_common.h
new file mode 100644
index 0000000000..6e7b9641bc
--- /dev/null
+++ b/src/main/cms/cms_menu_vtx_common.h
@@ -0,0 +1,26 @@
+/*
+ * This file is part of Cleanflight and Betaflight.
+ *
+ * Cleanflight and Betaflight are 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.
+ *
+ * Cleanflight and Betaflight are distributed in the hope that they
+ * 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.h"
+#include "cms/cms_types.h"
+
+extern CMS_Menu cmsx_menuVtxRedirect;
diff --git a/src/main/cms/cms_menu_vtx_rtc6705.c b/src/main/cms/cms_menu_vtx_rtc6705.c
index 4c124ea497..16d7c9d571 100644
--- a/src/main/cms/cms_menu_vtx_rtc6705.c
+++ b/src/main/cms/cms_menu_vtx_rtc6705.c
@@ -139,6 +139,7 @@ CMS_Menu cmsx_menuVtxRTC6705 = {
#endif
.onEnter = cmsx_Vtx_onEnter,
.onExit = cmsx_Vtx_onExit,
+ .checkRedirect = NULL,
.entries = cmsx_menuVtxEntries
};
diff --git a/src/main/cms/cms_menu_vtx_smartaudio.c b/src/main/cms/cms_menu_vtx_smartaudio.c
index e6fa661979..02371767c0 100644
--- a/src/main/cms/cms_menu_vtx_smartaudio.c
+++ b/src/main/cms/cms_menu_vtx_smartaudio.c
@@ -416,6 +416,7 @@ static CMS_Menu saCmsMenuStats = {
#endif
.onEnter = NULL,
.onExit = NULL,
+ .checkRedirect = NULL,
.entries = saCmsMenuStatsEntries
};
#endif /* USE_EXTENDED_CMS_MENUS */
@@ -613,6 +614,7 @@ static CMS_Menu saCmsMenuPORFreq =
#endif
.onEnter = saCmsSetPORFreqOnEnter,
.onExit = NULL,
+ .checkRedirect = NULL,
.entries = saCmsMenuPORFreqEntries,
};
@@ -635,6 +637,7 @@ static CMS_Menu saCmsMenuUserFreq =
#endif
.onEnter = saCmsSetUserFreqOnEnter,
.onExit = NULL,
+ .checkRedirect = NULL,
.entries = saCmsMenuUserFreqEntries,
};
@@ -662,6 +665,7 @@ static CMS_Menu saCmsMenuConfig = {
#endif
.onEnter = NULL,
.onExit = NULL,
+ .checkRedirect = NULL,
.entries = saCmsMenuConfigEntries
};
@@ -681,6 +685,7 @@ static CMS_Menu saCmsMenuCommence = {
#endif
.onEnter = NULL,
.onExit = NULL,
+ .checkRedirect = NULL,
.entries = saCmsMenuCommenceEntries,
};
@@ -753,6 +758,7 @@ CMS_Menu cmsx_menuVtxSmartAudio = {
#endif
.onEnter = sacms_SetupTopMenu,
.onExit = NULL,
+ .checkRedirect = NULL,
.entries = saCmsMenuOfflineEntries,
};
diff --git a/src/main/cms/cms_menu_vtx_tramp.c b/src/main/cms/cms_menu_vtx_tramp.c
index 657cd66bd2..ea0e3a792f 100644
--- a/src/main/cms/cms_menu_vtx_tramp.c
+++ b/src/main/cms/cms_menu_vtx_tramp.c
@@ -243,6 +243,7 @@ static CMS_Menu trampCmsMenuCommence = {
#endif
.onEnter = NULL,
.onExit = NULL,
+ .checkRedirect = NULL,
.entries = trampCmsMenuCommenceEntries,
};
@@ -270,6 +271,7 @@ CMS_Menu cmsx_menuVtxTramp = {
#endif
.onEnter = trampCmsOnEnter,
.onExit = NULL,
+ .checkRedirect = NULL,
.entries = trampMenuEntries,
};
#endif
diff --git a/src/main/cms/cms_types.h b/src/main/cms/cms_types.h
index 1e6b8e06ca..1e659d472b 100644
--- a/src/main/cms/cms_types.h
+++ b/src/main/cms/cms_types.h
@@ -96,6 +96,8 @@ onExit function is called with self:
typedef long (*CMSMenuOnExitPtr)(const OSD_Entry *self);
+typedef const void * (*CMSMenuCheckRedirectPtr)(void);
+
typedef struct
{
#ifdef CMS_MENU_DEBUG
@@ -105,6 +107,7 @@ typedef struct
#endif
const CMSMenuFuncPtr onEnter;
const CMSMenuOnExitPtr onExit;
+ const CMSMenuCheckRedirectPtr checkRedirect;
const OSD_Entry *entries;
} CMS_Menu;
diff --git a/src/test/unit/cms_unittest.cc b/src/test/unit/cms_unittest.cc
index b2bedaa67c..348139e666 100644
--- a/src/test/unit/cms_unittest.cc
+++ b/src/test/unit/cms_unittest.cc
@@ -127,12 +127,13 @@ static OSD_Entry menuMainEntries[] =
};
CMS_Menu menuMain = {
#ifdef CMS_MENU_DEBUG
- "MENUMAIN",
- OME_MENU,
+ .GUARD_text = "MENUMAIN",
+ .GUARD_type = OME_MENU,
#endif
- NULL,
- NULL,
- menuMainEntries,
+ .onEnter = NULL,
+ .onExit = NULL,
+ .checkRedirect = NULL,
+ .entries = menuMainEntries,
};
uint8_t armingFlags;
int16_t debug[4];