2 * This file is part of Cleanflight.
4 * Cleanflight is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * Cleanflight is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
25 #include "build/version.h"
27 #if defined(USE_CMS) && defined(USE_VTX_CONTROL)
29 #include "common/printf.h"
30 #include "common/utils.h"
33 #include "cms/cms_types.h"
34 #include "cms/cms_menu_vtx.h"
36 #include "drivers/vtx_common.h"
38 #include "fc/config.h"
40 #include "io/vtx_string.h"
44 // Config-time settings
45 static uint8_t vtxBand
= 0;
46 static uint8_t vtxChan
= 0;
47 static uint8_t vtxPower
= 0;
48 static uint8_t vtxPitMode
= 0;
50 static const char * const vtxCmsPitModeNames
[] = {
54 // Menus (these are not const because we update them at run-time )
55 static OSD_TAB_t cms_Vtx_EntBand
= { &vtxBand
, VTX_SETTINGS_BAND_COUNT
, vtx58BandNames
};
56 static OSD_TAB_t cms_Vtx_EntChan
= { &vtxChan
, VTX_SETTINGS_CHANNEL_COUNT
, vtx58ChannelNames
};
57 static OSD_TAB_t cms_Vtx_EntPower
= { &vtxPower
, VTX_SETTINGS_POWER_COUNT
, vtx58DefaultPowerNames
};
58 static const OSD_TAB_t cms_Vtx_EntPitMode
= { &vtxPitMode
, 2, vtxCmsPitModeNames
};
60 static long cms_Vtx_configPitMode(displayPort_t
*pDisp
, const void *self
)
65 if (vtxPitMode
== 0) {
69 // Pit mode changes are immediate, without saving
70 vtxCommonSetPitMode(vtxCommonDevice(), vtxPitMode
>= 2 ? 1 : 0);
75 static long cms_Vtx_configBand(displayPort_t
*pDisp
, const void *self
)
86 static long cms_Vtx_configChan(displayPort_t
*pDisp
, const void *self
)
97 static long cms_Vtx_configPower(displayPort_t
*pDisp
, const void *self
)
108 static void cms_Vtx_initSettings(void)
110 vtxDevice_t
* vtxDevice
= vtxCommonDevice();
111 vtxDeviceCapability_t vtxDeviceCapability
;
113 if (vtxCommonGetDeviceCapability(vtxDevice
, &vtxDeviceCapability
)) {
114 cms_Vtx_EntBand
.max
= vtxDeviceCapability
.bandCount
;
115 cms_Vtx_EntBand
.names
= (const char * const *)vtxDeviceCapability
.bandNames
;
117 cms_Vtx_EntChan
.max
= vtxDeviceCapability
.channelCount
;
118 cms_Vtx_EntChan
.names
= (const char * const *)vtxDeviceCapability
.channelNames
;
120 cms_Vtx_EntPower
.max
= vtxDeviceCapability
.powerCount
;
121 cms_Vtx_EntPower
.names
= (const char * const *)vtxDeviceCapability
.powerNames
;
124 cms_Vtx_EntBand
.max
= VTX_SETTINGS_BAND_COUNT
;
125 cms_Vtx_EntBand
.names
= vtx58BandNames
;
127 cms_Vtx_EntChan
.max
= VTX_SETTINGS_CHANNEL_COUNT
;
128 cms_Vtx_EntChan
.names
= vtx58ChannelNames
;
130 cms_Vtx_EntPower
.max
= VTX_SETTINGS_POWER_COUNT
;
131 cms_Vtx_EntPower
.names
= vtx58DefaultPowerNames
;
134 vtxBand
= vtxSettingsConfig()->band
;
135 vtxChan
= vtxSettingsConfig()->channel
;
136 vtxPower
= vtxSettingsConfig()->power
;
138 // If device is ready - read actual PIT mode
139 if (vtxCommonDeviceIsReady(vtxDevice
)) {
141 vtxCommonGetPitMode(vtxDevice
, &onoff
);
142 vtxPitMode
= onoff
? 2 : 1;
149 static long cms_Vtx_onEnter(const OSD_Entry
*self
)
152 cms_Vtx_initSettings();
156 static long cms_Vtx_Commence(displayPort_t
*pDisp
, const void *self
)
161 vtxCommonSetBandAndChannel(vtxCommonDevice(), vtxBand
, vtxChan
);
162 vtxCommonSetPowerByIndex(vtxCommonDevice(), vtxPower
);
163 vtxCommonSetPitMode(vtxCommonDevice(), vtxPitMode
== 2 ? 1 : 0);
165 vtxSettingsConfigMutable()->band
= vtxBand
;
166 vtxSettingsConfigMutable()->channel
= vtxChan
;
167 vtxSettingsConfigMutable()->power
= vtxPower
;
169 saveConfigAndNotify();
171 return MENU_CHAIN_BACK
;
174 static bool cms_Vtx_drawStatusString(char *buf
, unsigned bufsize
)
176 const char *defaultString
= "-- ---- ----";
180 if (bufsize
< strlen(defaultString
) + 1) {
184 strcpy(buf
, defaultString
);
186 vtxDevice_t
* vtxDevice
= vtxCommonDevice();
187 vtxDeviceOsdInfo_t osdInfo
;
189 if (!vtxDevice
|| !vtxCommonGetOsdInfo(vtxDevice
, &osdInfo
) || !vtxCommonDeviceIsReady(vtxDevice
)) {
193 buf
[0] = osdInfo
.bandLetter
;
194 buf
[1] = osdInfo
.channelName
[0];
197 if (osdInfo
.frequency
)
198 tfp_sprintf(&buf
[3], "%4d", osdInfo
.frequency
);
200 tfp_sprintf(&buf
[3], "----");
202 if (osdInfo
.powerIndex
) {
203 // If OSD driver provides power in milliwatt - display MW, otherwise - power level
204 if (osdInfo
.powerMilliwatt
) {
205 tfp_sprintf(&buf
[7], " %4d", osdInfo
.powerMilliwatt
);
208 tfp_sprintf(&buf
[7], " PL=%c", osdInfo
.powerIndex
);
211 tfp_sprintf(&buf
[7], " ----");
217 static const OSD_Entry cms_menuCommenceEntries
[] =
219 OSD_LABEL_ENTRY("CONFIRM"),
220 OSD_FUNC_CALL_ENTRY("YES", cms_Vtx_Commence
),
222 OSD_BACK_AND_END_ENTRY
,
225 static const CMS_Menu cms_menuCommence
= {
226 #ifdef CMS_MENU_DEBUG
227 .GUARD_text
= "XVTXTRC",
228 .GUARD_type
= OME_MENU
,
232 .onGlobalExit
= NULL
,
233 .entries
= cms_menuCommenceEntries
,
236 static const OSD_Entry cms_menuVtxEntries
[] =
238 OSD_LABEL_ENTRY("--- VTX ---"),
239 OSD_LABEL_FUNC_DYN_ENTRY("", cms_Vtx_drawStatusString
),
240 OSD_TAB_CALLBACK_ENTRY("PIT", cms_Vtx_configPitMode
, &cms_Vtx_EntPitMode
),
241 OSD_TAB_CALLBACK_ENTRY("BAND", cms_Vtx_configBand
, &cms_Vtx_EntBand
),
242 OSD_TAB_CALLBACK_ENTRY("CHAN", cms_Vtx_configChan
, &cms_Vtx_EntChan
),
243 OSD_TAB_CALLBACK_ENTRY("POWER", cms_Vtx_configPower
, &cms_Vtx_EntPower
),
245 OSD_SUBMENU_ENTRY("SET", &cms_menuCommence
),
246 OSD_BACK_AND_END_ENTRY
,
249 const CMS_Menu cmsx_menuVtxControl
= {
250 #ifdef CMS_MENU_DEBUG
251 .GUARD_text
= "MENUVTX",
252 .GUARD_type
= OME_MENU
,
254 .onEnter
= cms_Vtx_onEnter
,
256 .onGlobalExit
= NULL
,
257 .entries
= cms_menuVtxEntries