Implement Stopwatch (#12623)
[betaflight.git] / src / main / cms / cms_menu_osd.c
blob0724c2e9b1df8d6ad4ed77df288322e42cdac799
1 /*
2 * This file is part of Cleanflight and Betaflight.
4 * Cleanflight and Betaflight are free software. You can redistribute
5 * this software and/or modify this software under the terms of the
6 * GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option)
8 * any later version.
10 * Cleanflight and Betaflight are distributed in the hope that they
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software.
18 * If not, see <http://www.gnu.org/licenses/>.
21 #include <stdbool.h>
22 #include <stdint.h>
23 #include <string.h>
24 #include <ctype.h>
26 #include "platform.h"
28 #if defined(USE_OSD) && defined(USE_CMS)
30 #include "build/version.h"
32 #include "cli/settings.h"
34 #include "cms/cms.h"
35 #include "cms/cms_types.h"
36 #include "cms/cms_menu_osd.h"
38 #include "common/utils.h"
40 #include "config/feature.h"
42 #include "drivers/display.h"
44 #include "io/displayport_max7456.h"
46 #include "osd/osd.h"
47 #include "osd/osd_elements.h"
49 #include "pg/pg.h"
50 #include "pg/pg_ids.h"
52 #include "rx/crsf.h"
54 #include "sensors/battery.h"
56 #ifdef USE_EXTENDED_CMS_MENUS
57 static uint16_t osdConfig_item_pos[OSD_ITEM_COUNT];
59 static const void *menuOsdActiveElemsOnEnter(displayPort_t *pDisp)
61 UNUSED(pDisp);
63 memcpy(&osdConfig_item_pos[0], &osdElementConfig()->item_pos[0], sizeof(uint16_t) * OSD_ITEM_COUNT);
64 return NULL;
67 static const void *menuOsdActiveElemsOnExit(displayPort_t *pDisp, const OSD_Entry *self)
69 UNUSED(pDisp);
70 UNUSED(self);
72 memcpy(&osdElementConfigMutable()->item_pos[0], &osdConfig_item_pos[0], sizeof(uint16_t) * OSD_ITEM_COUNT);
73 osdAnalyzeActiveElements();
74 return NULL;
77 const OSD_Entry menuOsdActiveElemsEntries[] =
79 {"--- ACTIV ELEM ---", OME_Label, NULL, NULL},
80 {"RSSI", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_RSSI_VALUE]},
81 #ifdef USE_RX_RSSI_DBM
82 {"RSSI DBM", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_RSSI_DBM_VALUE]},
83 #endif
84 #ifdef USE_RX_RSNR
85 {"RSNR", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_RSNR_VALUE]},
86 #endif
87 {"BATTERY VOLTAGE", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_MAIN_BATT_VOLTAGE]},
88 {"BATTERY USAGE", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_MAIN_BATT_USAGE]},
89 {"AVG CELL VOLTAGE", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_AVG_CELL_VOLTAGE]},
90 #ifdef USE_GPS
91 {"BATTERY EFFICIENCY", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_EFFICIENCY]},
92 #endif // GPS
93 {"CROSSHAIRS", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_CROSSHAIRS]},
94 {"HORIZON", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_ARTIFICIAL_HORIZON]},
95 {"HORIZON SIDEBARS", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_HORIZON_SIDEBARS]},
96 {"UP/DOWN REFERENCE", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_UP_DOWN_REFERENCE]},
97 {"TIMER 1", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_ITEM_TIMER_1]},
98 {"TIMER 2", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_ITEM_TIMER_2]},
99 {"REMAINING TIME ESTIMATE", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_REMAINING_TIME_ESTIMATE]},
100 #ifdef USE_RTC_TIME
101 {"RTC DATETIME", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_RTC_DATETIME]},
102 #endif
103 #ifdef USE_OSD_ADJUSTMENTS
104 {"ADJUSTMENT RANGE", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_ADJUSTMENT_RANGE]},
105 #endif
106 #ifdef USE_ADC_INTERNAL
107 {"CORE TEMPERATURE", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_CORE_TEMPERATURE]},
108 #endif
109 {"ANTI GRAVITY", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_ANTI_GRAVITY]},
110 {"FLY MODE", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_FLYMODE]},
111 {"CRAFT NAME", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_CRAFT_NAME]},
112 {"THROTTLE", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_THROTTLE_POS]},
113 #ifdef USE_VTX_CONTROL
114 {"VTX CHAN", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_VTX_CHANNEL]},
115 #endif // VTX
116 {"CURRENT (A)", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_CURRENT_DRAW]},
117 {"USED MAH", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_MAH_DRAWN]},
118 #ifdef USE_GPS
119 {"GPS SPEED", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_GPS_SPEED]},
120 {"GPS SATS", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_GPS_SATS]},
121 {"GPS LAT", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_GPS_LAT]},
122 {"GPS LON", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_GPS_LON]},
123 {"HOME DIR", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_HOME_DIR]},
124 {"HOME DIST", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_HOME_DIST]},
125 {"FLIGHT DIST", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_FLIGHT_DIST]},
126 #endif // GPS
127 {"COMPASS BAR", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_COMPASS_BAR]},
128 #ifdef USE_ESC_SENSOR
129 {"ESC TEMPERATURE", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_ESC_TMP]},
130 {"ESC RPM", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_ESC_RPM]},
131 #endif
132 {"ALTITUDE", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_ALTITUDE]},
133 {"POWER", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_POWER]},
134 {"ROLL PID", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_ROLL_PIDS]},
135 {"PITCH PID", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_PITCH_PIDS]},
136 {"YAW PID", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_YAW_PIDS]},
137 {"PROFILES", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_PIDRATE_PROFILE]},
138 #ifdef USE_PROFILE_NAMES
139 {"PID PROFILE NAME", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_PID_PROFILE_NAME]},
140 {"RATE PROFILE NAME", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_RATE_PROFILE_NAME]},
141 #endif
142 #ifdef USE_OSD_PROFILES
143 {"OSD PROFILE NAME", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_PROFILE_NAME]},
144 #endif
145 {"DEBUG", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_DEBUG]},
146 {"WARNINGS", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_WARNINGS]},
147 {"DISARMED", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_DISARMED]},
148 {"PIT ANG", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_PITCH_ANGLE]},
149 {"ROL ANG", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_ROLL_ANGLE]},
150 {"HEADING", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_NUMERICAL_HEADING]},
151 #ifdef USE_VARIO
152 {"VARIO", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_NUMERICAL_VARIO]},
153 #endif
154 {"G-FORCE", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_G_FORCE]},
155 {"MOTOR DIAGNOSTIC", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_MOTOR_DIAG]},
156 #ifdef USE_BLACKBOX
157 {"LOG STATUS", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_LOG_STATUS]},
158 #endif
159 {"FLIP ARROW", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_FLIP_ARROW]},
160 #ifdef USE_RX_LINK_QUALITY_INFO
161 {"LINK QUALITY", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_LINK_QUALITY]},
162 #endif
163 #ifdef USE_OSD_STICK_OVERLAY
164 {"STICK OVERLAY LEFT", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_STICK_OVERLAY_LEFT]},
165 {"STICK OVERLAY RIGHT",OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_STICK_OVERLAY_RIGHT]},
166 #endif
167 {"PILOT NAME", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_PILOT_NAME]},
168 {"RC CHANNELS", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_RC_CHANNELS]},
169 {"CAMERA FRAME", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_CAMERA_FRAME]},
170 {"TOTAL FLIGHTS", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_TOTAL_FLIGHTS]},
171 {"AUX VALUE", OME_VISIBLE | DYNAMIC, NULL, &osdConfig_item_pos[OSD_AUX_VALUE]},
172 {"BACK", OME_Back, NULL, NULL},
173 {NULL, OME_END, NULL, NULL}
176 static CMS_Menu menuOsdActiveElems = {
177 #ifdef CMS_MENU_DEBUG
178 .GUARD_text = "MENUOSDACT",
179 .GUARD_type = OME_MENU,
180 #endif
181 .onEnter = menuOsdActiveElemsOnEnter,
182 .onExit = menuOsdActiveElemsOnExit,
183 .onDisplayUpdate = NULL,
184 .entries = menuOsdActiveElemsEntries
187 static uint8_t osdConfig_rssi_alarm;
188 static uint16_t osdConfig_link_quality_alarm;
189 static int16_t osdConfig_rssi_dbm_alarm;
190 static int16_t osdConfig_rsnr_alarm;
191 static uint16_t osdConfig_cap_alarm;
192 static uint16_t osdConfig_alt_alarm;
193 static uint16_t osdConfig_distance_alarm;
194 static uint8_t batteryConfig_vbatDurationForWarning;
195 static uint8_t batteryConfig_vbatDurationForCritical;
197 static const void *menuAlarmsOnEnter(displayPort_t *pDisp)
199 UNUSED(pDisp);
201 osdConfig_rssi_alarm = osdConfig()->rssi_alarm;
202 osdConfig_link_quality_alarm = osdConfig()->link_quality_alarm;
203 osdConfig_rssi_dbm_alarm = osdConfig()->rssi_dbm_alarm;
204 osdConfig_rsnr_alarm = osdConfig()->rsnr_alarm;
205 osdConfig_cap_alarm = osdConfig()->cap_alarm;
206 osdConfig_alt_alarm = osdConfig()->alt_alarm;
207 osdConfig_distance_alarm = osdConfig()->distance_alarm;
208 batteryConfig_vbatDurationForWarning = batteryConfig()->vbatDurationForWarning;
209 batteryConfig_vbatDurationForCritical = batteryConfig()->vbatDurationForCritical;
211 return NULL;
214 static const void *menuAlarmsOnExit(displayPort_t *pDisp, const OSD_Entry *self)
216 UNUSED(pDisp);
217 UNUSED(self);
219 osdConfigMutable()->rssi_alarm = osdConfig_rssi_alarm;
220 osdConfigMutable()->link_quality_alarm = osdConfig_link_quality_alarm;
221 osdConfigMutable()->rssi_dbm_alarm = osdConfig_rssi_dbm_alarm;
222 osdConfigMutable()->rsnr_alarm = osdConfig_rsnr_alarm;
223 osdConfigMutable()->cap_alarm = osdConfig_cap_alarm;
224 osdConfigMutable()->alt_alarm = osdConfig_alt_alarm;
225 osdConfigMutable()->distance_alarm = osdConfig_distance_alarm;
226 batteryConfigMutable()->vbatDurationForWarning = batteryConfig_vbatDurationForWarning;
227 batteryConfigMutable()->vbatDurationForCritical = batteryConfig_vbatDurationForCritical;
229 return NULL;
232 const OSD_Entry menuAlarmsEntries[] =
234 {"--- ALARMS ---", OME_Label, NULL, NULL},
235 {"RSSI", OME_UINT8, NULL, &(OSD_UINT8_t){&osdConfig_rssi_alarm, 5, 90, 5}},
236 {"LINK QUALITY", OME_UINT16, NULL, &(OSD_UINT16_t){&osdConfig_link_quality_alarm, 5, 300, 5}},
237 {"RSSI DBM", OME_INT16, NULL, &(OSD_INT16_t){&osdConfig_rssi_dbm_alarm, CRSF_RSSI_MIN, CRSF_SNR_MAX, 5}},
238 {"RSNR", OME_INT16, NULL, &(OSD_INT16_t){&osdConfig_rsnr_alarm, CRSF_SNR_MIN, CRSF_SNR_MAX, 5}},
239 {"MAIN BAT", OME_UINT16, NULL, &(OSD_UINT16_t){&osdConfig_cap_alarm, 50, 30000, 50}},
240 {"MAX ALT", OME_UINT16, NULL, &(OSD_UINT16_t){&osdConfig_alt_alarm, 1, 200, 1}},
241 {"MAX DISTANCE", OME_UINT16, NULL, &(OSD_UINT16_t){&osdConfig_distance_alarm, 0, UINT16_MAX, 10}},
242 {"VBAT WARN DUR", OME_UINT8, NULL, &(OSD_UINT8_t){ &batteryConfig_vbatDurationForWarning, 0, 200, 1 } },
243 {"VBAT CRIT DUR", OME_UINT8, NULL, &(OSD_UINT8_t){ &batteryConfig_vbatDurationForCritical, 0, 200, 1 } },
244 {"BACK", OME_Back, NULL, NULL},
245 {NULL, OME_END, NULL, NULL,}
248 static CMS_Menu menuAlarms = {
249 #ifdef CMS_MENU_DEBUG
250 .GUARD_text = "MENUALARMS",
251 .GUARD_type = OME_MENU,
252 #endif
253 .onEnter = menuAlarmsOnEnter,
254 .onExit = menuAlarmsOnExit,
255 .onDisplayUpdate = NULL,
256 .entries = menuAlarmsEntries,
259 osd_timer_source_e timerSource[OSD_TIMER_COUNT];
260 osd_timer_precision_e timerPrecision[OSD_TIMER_COUNT];
261 uint8_t timerAlarm[OSD_TIMER_COUNT];
263 static const void *menuTimersOnEnter(displayPort_t *pDisp)
265 UNUSED(pDisp);
267 for (int i = 0; i < OSD_TIMER_COUNT; i++) {
268 const uint16_t timer = osdConfig()->timers[i];
269 timerSource[i] = OSD_TIMER_SRC(timer);
270 timerPrecision[i] = OSD_TIMER_PRECISION(timer);
271 timerAlarm[i] = OSD_TIMER_ALARM(timer);
274 return NULL;
277 static const void *menuTimersOnExit(displayPort_t *pDisp, const OSD_Entry *self)
279 UNUSED(pDisp);
280 UNUSED(self);
282 for (int i = 0; i < OSD_TIMER_COUNT; i++) {
283 osdConfigMutable()->timers[i] = OSD_TIMER(timerSource[i], timerPrecision[i], timerAlarm[i]);
286 return NULL;
289 static const char * osdTimerPrecisionNames[] = {"SCND", "HDTH"};
291 const OSD_Entry menuTimersEntries[] =
293 {"--- TIMERS ---", OME_Label, NULL, NULL},
294 {"1 SRC", OME_TAB, NULL, &(OSD_TAB_t){&timerSource[OSD_TIMER_1], OSD_TIMER_SRC_COUNT - 1, osdTimerSourceNames} },
295 {"1 PREC", OME_TAB, NULL, &(OSD_TAB_t){&timerPrecision[OSD_TIMER_1], OSD_TIMER_PREC_COUNT - 1, osdTimerPrecisionNames}},
296 {"1 ALARM", OME_UINT8, NULL, &(OSD_UINT8_t){&timerAlarm[OSD_TIMER_1], 0, 0xFF, 1}},
297 {"2 SRC", OME_TAB, NULL, &(OSD_TAB_t){&timerSource[OSD_TIMER_2], OSD_TIMER_SRC_COUNT - 1, osdTimerSourceNames} },
298 {"2 PREC", OME_TAB, NULL, &(OSD_TAB_t){&timerPrecision[OSD_TIMER_2], OSD_TIMER_PREC_COUNT - 1, osdTimerPrecisionNames}},
299 {"2 ALARM", OME_UINT8, NULL, &(OSD_UINT8_t){&timerAlarm[OSD_TIMER_2], 0, 0xFF, 1}},
300 {"BACK", OME_Back, NULL, NULL},
301 {NULL, OME_END, NULL, NULL}
304 static CMS_Menu menuTimers = {
305 #ifdef CMS_MENU_DEBUG
306 .GUARD_text = "MENUTIMERS",
307 .GUARD_type = OME_MENU,
308 #endif
309 .onEnter = menuTimersOnEnter,
310 .onExit = menuTimersOnExit,
311 .onDisplayUpdate = NULL,
312 .entries = menuTimersEntries,
314 #endif /* USE_EXTENDED_CMS_MENUS */
316 #ifdef USE_MAX7456
317 static bool displayPortProfileMax7456_invert;
318 static uint8_t displayPortProfileMax7456_blackBrightness;
319 static uint8_t displayPortProfileMax7456_whiteBrightness;
320 #endif
322 #ifdef USE_OSD_PROFILES
323 static uint8_t osdConfig_osdProfileIndex;
324 #endif
326 static displayPortBackground_e osdMenuBackgroundType;
328 static const void *cmsx_menuOsdOnEnter(displayPort_t *pDisp)
330 UNUSED(pDisp);
332 #ifdef USE_OSD_PROFILES
333 osdConfig_osdProfileIndex = osdConfig()->osdProfileIndex;
334 #endif
336 #ifdef USE_MAX7456
337 displayPortProfileMax7456_invert = displayPortProfileMax7456()->invert;
338 displayPortProfileMax7456_blackBrightness = displayPortProfileMax7456()->blackBrightness;
339 displayPortProfileMax7456_whiteBrightness = displayPortProfileMax7456()->whiteBrightness;
340 osdMenuBackgroundType = osdConfig()->cms_background_type;
341 #endif
343 return NULL;
346 static const void *cmsx_menuOsdOnExit(displayPort_t *pDisp, const OSD_Entry *self)
348 UNUSED(pDisp);
349 UNUSED(self);
351 #ifdef USE_OSD_PROFILES
352 changeOsdProfileIndex(osdConfig_osdProfileIndex);
353 #endif
355 return NULL;
358 #ifdef USE_MAX7456
359 static const void *cmsx_max7456Update(displayPort_t *pDisp, const void *self)
361 UNUSED(self);
363 displayPortProfileMax7456Mutable()->invert = displayPortProfileMax7456_invert;
364 displayPortProfileMax7456Mutable()->blackBrightness = displayPortProfileMax7456_blackBrightness;
365 displayPortProfileMax7456Mutable()->whiteBrightness = displayPortProfileMax7456_whiteBrightness;
367 displayClearScreen(pDisp, DISPLAY_CLEAR_WAIT);
369 return NULL;
371 #endif // USE_MAX7456
373 static const void *cmsx_osdBackgroundUpdate(displayPort_t *pDisp, const void *self)
375 UNUSED(self);
376 osdConfigMutable()->cms_background_type = osdMenuBackgroundType;
377 displaySetBackgroundType(pDisp, osdMenuBackgroundType);
378 return NULL;
381 const OSD_Entry cmsx_menuOsdEntries[] =
383 {"---OSD---", OME_Label, NULL, NULL},
384 #ifdef USE_OSD_PROFILES
385 {"OSD PROFILE", OME_UINT8, NULL, &(OSD_UINT8_t){&osdConfig_osdProfileIndex, 1, 3, 1}},
386 #endif
387 #ifdef USE_EXTENDED_CMS_MENUS
388 {"ACTIVE ELEM", OME_Submenu, cmsMenuChange, &menuOsdActiveElems},
389 {"TIMERS", OME_Submenu, cmsMenuChange, &menuTimers},
390 {"ALARMS", OME_Submenu, cmsMenuChange, &menuAlarms},
391 #endif
392 #ifdef USE_MAX7456
393 {"INVERT", OME_Bool, cmsx_max7456Update, &displayPortProfileMax7456_invert},
394 {"BRT BLACK", OME_UINT8, cmsx_max7456Update, &(OSD_UINT8_t){&displayPortProfileMax7456_blackBrightness, 0, 3, 1}},
395 {"BRT WHITE", OME_UINT8, cmsx_max7456Update, &(OSD_UINT8_t){&displayPortProfileMax7456_whiteBrightness, 0, 3, 1}},
396 #endif
397 {"BACKGROUND",OME_TAB, cmsx_osdBackgroundUpdate, &(OSD_TAB_t){&osdMenuBackgroundType, DISPLAY_BACKGROUND_COUNT - 1, lookupTableCMSMenuBackgroundType}},
398 {"BACK", OME_Back, NULL, NULL},
399 {NULL, OME_END, NULL, NULL}
402 CMS_Menu cmsx_menuOsd = {
403 #ifdef CMS_MENU_DEBUG
404 .GUARD_text = "MENUOSD",
405 .GUARD_type = OME_MENU,
406 #endif
407 .onEnter = cmsx_menuOsdOnEnter,
408 .onExit = cmsx_menuOsdOnExit,
409 .onDisplayUpdate = NULL,
410 .entries = cmsx_menuOsdEntries
412 #endif // CMS