diff --git a/make/source.mk b/make/source.mk
index d168e7f306..e3c93b87f2 100644
--- a/make/source.mk
+++ b/make/source.mk
@@ -153,6 +153,7 @@ COMMON_SRC = \
cms/cms_menu_vtx_rtc6705.c \
cms/cms_menu_vtx_smartaudio.c \
cms/cms_menu_vtx_tramp.c \
+ cms/cms_menu_persistent_stats.c \
drivers/display_ug2864hsweg01.c \
drivers/light_ws2811strip.c \
drivers/rangefinder/rangefinder_hcsr04.c \
@@ -344,6 +345,7 @@ SIZE_OPTIMISED_SRC := $(SIZE_OPTIMISED_SRC) \
cms/cms_menu_vtx_rtc6705.c \
cms/cms_menu_vtx_smartaudio.c \
cms/cms_menu_vtx_tramp.c \
+ cms/cms_menu_persistent_stats.c \
io/vtx.c \
io/vtx_rtc6705.c \
io/vtx_smartaudio.c \
diff --git a/src/main/cms/cms.c b/src/main/cms/cms.c
index e23eac5909..e188413603 100644
--- a/src/main/cms/cms.c
+++ b/src/main/cms/cms.c
@@ -555,6 +555,24 @@ static int cmsDrawMenuEntry(displayPort_t *pDisplay, const OSD_Entry *p, uint8_t
}
break;
+ case OME_UINT32:
+ if (IS_PRINTVALUE(*flags) && p->data) {
+ OSD_UINT32_t *ptr = p->data;
+ itoa(*ptr->val, buff, 10);
+ cnt = cmsDrawMenuItemValue(pDisplay, buff, row, CMS_NUM_FIELD_LEN);
+ CLR_PRINTVALUE(*flags);
+ }
+ break;
+
+ case OME_INT32:
+ if (IS_PRINTVALUE(*flags) && p->data) {
+ OSD_INT32_t *ptr = p->data;
+ itoa(*ptr->val, buff, 10);
+ cnt = cmsDrawMenuItemValue(pDisplay, buff, row, CMS_NUM_FIELD_LEN);
+ CLR_PRINTVALUE(*flags);
+ }
+ break;
+
case OME_FLOAT:
if (IS_PRINTVALUE(*flags) && p->data) {
OSD_FLOAT_t *ptr = p->data;
@@ -1017,6 +1035,9 @@ STATIC_UNIT_TESTED uint16_t cmsHandleKey(displayPort_t *pDisplay, cms_key_e key)
if (retval == MENU_CHAIN_BACK) {
cmsMenuBack(pDisplay);
}
+ if ((p->flags & REBOOT_REQUIRED)) {
+ setRebootRequired();
+ }
res = BUTTON_PAUSE;
}
break;
@@ -1202,6 +1223,52 @@ STATIC_UNIT_TESTED uint16_t cmsHandleKey(displayPort_t *pDisplay, cms_key_e key)
}
break;
+ case OME_UINT32:
+ if (p->data) {
+ OSD_UINT32_t *ptr = p->data;
+ const uint32_t previousValue = *ptr->val;
+ if (key == CMS_KEY_RIGHT) {
+ if (*ptr->val < ptr->max) {
+ *ptr->val += ptr->step;
+ }
+ } else {
+ if (*ptr->val > ptr->min) {
+ *ptr->val -= ptr->step;
+ }
+ }
+ SET_PRINTVALUE(runtimeEntryFlags[currentCtx.cursorRow]);
+ if ((p->flags & REBOOT_REQUIRED) && (*ptr->val != previousValue)) {
+ setRebootRequired();
+ }
+ if (p->func) {
+ p->func(pDisplay, p);
+ }
+ }
+ break;
+
+ case OME_INT32:
+ if (p->data) {
+ OSD_INT32_t *ptr = p->data;
+ const int32_t previousValue = *ptr->val;
+ if (key == CMS_KEY_RIGHT) {
+ if (*ptr->val < ptr->max) {
+ *ptr->val += ptr->step;
+ }
+ } else {
+ if (*ptr->val > ptr->min) {
+ *ptr->val -= ptr->step;
+ }
+ }
+ SET_PRINTVALUE(runtimeEntryFlags[currentCtx.cursorRow]);
+ if ((p->flags & REBOOT_REQUIRED) && (*ptr->val != previousValue)) {
+ setRebootRequired();
+ }
+ if (p->func) {
+ p->func(pDisplay, p);
+ }
+ }
+ break;
+
case OME_String:
break;
diff --git a/src/main/cms/cms_menu_main.c b/src/main/cms/cms_menu_main.c
index 89d5070906..185f8bf21b 100644
--- a/src/main/cms/cms_menu_main.c
+++ b/src/main/cms/cms_menu_main.c
@@ -43,6 +43,10 @@
#include "cms/cms_menu_power.h"
#include "cms/cms_menu_saveexit.h"
+#ifdef USE_PERSISTENT_STATS
+#include "cms/cms_menu_persistent_stats.h"
+#endif
+
// VTX supplied menus
#include "cms/cms_menu_vtx_common.h"
@@ -88,6 +92,9 @@ static const OSD_Entry menuFeaturesEntries[] =
{"POWER", OME_Submenu, cmsMenuChange, &cmsx_menuPower, 0},
#ifdef USE_CMS_FAILSAFE_MENU
{"FAILSAFE", OME_Submenu, cmsMenuChange, &cmsx_menuFailsafe, 0},
+#endif
+#ifdef USE_PERSISTENT_STATS
+ {"PERSISTENT STATS", OME_Submenu, cmsMenuChange, &cmsx_menuPersistentStats, 0},
#endif
{"BACK", OME_Back, NULL, NULL, 0},
{NULL, OME_END, NULL, NULL, 0}
diff --git a/src/main/cms/cms_menu_persistent_stats.c b/src/main/cms/cms_menu_persistent_stats.c
new file mode 100644
index 0000000000..e45b248873
--- /dev/null
+++ b/src/main/cms/cms_menu_persistent_stats.c
@@ -0,0 +1,108 @@
+/*
+ * 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
+
+#include "platform.h"
+
+#ifdef USE_CMS
+#ifdef USE_PERSISTENT_STATS
+
+#include "cms/cms.h"
+#include "cms/cms_types.h"
+#include "cms/cms_menu_persistent_stats.h"
+
+#include "config/config.h"
+#include "pg/stats.h"
+
+uint32_t stats_total_flights;
+uint32_t stats_total_time_s;
+uint32_t stats_total_dist_m;
+int8_t stats_min_armed_time_s;
+
+static const void *cmsx_PersistentStats_onEnter(displayPort_t *pDisp)
+{
+ UNUSED(pDisp);
+
+ stats_total_flights = statsConfig()->stats_total_flights;
+ stats_total_time_s = statsConfig()->stats_total_time_s;
+ stats_total_dist_m = statsConfig()->stats_total_dist_m;
+ stats_min_armed_time_s = statsConfig()->stats_min_armed_time_s;
+
+ return NULL;
+}
+
+static const void *cmsx_PersistentStats_onExit(displayPort_t *pDisp, const OSD_Entry *self)
+{
+ UNUSED(pDisp);
+ UNUSED(self);
+
+ statsConfigMutable()->stats_total_flights = stats_total_flights;
+ statsConfigMutable()->stats_total_time_s = stats_total_time_s;
+ statsConfigMutable()->stats_total_dist_m = stats_total_dist_m;
+ statsConfigMutable()->stats_min_armed_time_s = stats_min_armed_time_s;
+
+ return NULL;
+}
+
+static const void *cmsx_ResetStats(displayPort_t *pDisplay, const void *ptr)
+{
+ UNUSED(ptr);
+
+ stats_total_flights = 0;
+ stats_total_time_s = 0;
+ stats_total_dist_m = 0;
+
+ displayClearScreen(pDisplay);
+ displayRedraw(pDisplay);
+
+ return NULL;
+}
+
+static const OSD_Entry cmsx_menuPersistentStatsEntries[] =
+{
+ {"-- PERSISTENT STATS --", OME_Label, NULL, NULL, 0},
+ {"FLIGHTS", OME_UINT32, NULL, &(OSD_UINT32_t){ &stats_total_flights, 0, UINT32_MAX, 1}, 0},
+ {"TIME(sec)", OME_UINT32, NULL, &(OSD_UINT32_t){ &stats_total_time_s, 0, UINT32_MAX, 1}, 0},
+ {"DIST(m)", OME_UINT32, NULL, &(OSD_UINT32_t){ &stats_total_dist_m, 0, UINT32_MAX, 1}, 0},
+ {"RESET STATS", OME_Funcall, cmsx_ResetStats, NULL, 0},
+ {"--- SETTINGS ---", OME_Label, NULL, NULL, 0},
+ {"MIN ARMED TIME(sec)", OME_INT8, NULL, &(OSD_INT8_t){ &stats_min_armed_time_s, -1, INT8_MAX, 1}, 0},
+
+ {"BACK", OME_Back, NULL, NULL, 0},
+ { NULL, OME_END, NULL, NULL, 0}
+};
+
+CMS_Menu cmsx_menuPersistentStats = {
+#ifdef CMS_MENU_DEBUG
+ .GUARD_text = "PRESSTATS",
+ .GUARD_type = OME_MENU,
+#endif
+ .onEnter = cmsx_PersistentStats_onEnter,
+ .onExit = cmsx_PersistentStats_onExit,
+ .onDisplayUpdate = NULL,
+ .entries = cmsx_menuPersistentStatsEntries
+};
+
+#endif
+#endif
diff --git a/src/main/cms/cms_menu_persistent_stats.h b/src/main/cms/cms_menu_persistent_stats.h
new file mode 100644
index 0000000000..c53c6b3857
--- /dev/null
+++ b/src/main/cms/cms_menu_persistent_stats.h
@@ -0,0 +1,23 @@
+/*
+ * 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
+
+extern CMS_Menu cmsx_menuPersistentStats;
diff --git a/src/main/cms/cms_types.h b/src/main/cms/cms_types.h
index f4965036ff..66d7b933fc 100644
--- a/src/main/cms/cms_types.h
+++ b/src/main/cms/cms_types.h
@@ -39,6 +39,8 @@ typedef enum
OME_UINT8,
OME_UINT16,
OME_INT16,
+ OME_UINT32,
+ OME_INT32,
OME_String,
OME_FLOAT, //only up to 255 value and cant be 2.55 or 25.5, just for PID's
//wlasciwosci elementow
@@ -149,6 +151,22 @@ typedef struct
uint16_t step;
} OSD_UINT16_t;
+typedef struct
+{
+ int32_t *val;
+ int32_t min;
+ int32_t max;
+ int32_t step;
+} OSD_INT32_t;
+
+typedef struct
+{
+ uint32_t *val;
+ uint32_t min;
+ uint32_t max;
+ uint32_t step;
+} OSD_UINT32_t;
+
typedef struct
{
uint8_t *val;