diff --git a/make/source.mk b/make/source.mk
index 9bb812bca1..b28ef2a656 100644
--- a/make/source.mk
+++ b/make/source.mk
@@ -143,6 +143,7 @@ FC_SRC = \
cms/cms_menu_ledstrip.c \
cms/cms_menu_misc.c \
cms/cms_menu_osd.c \
+ cms/cms_menu_power.c \
cms/cms_menu_vtx_rtc6705.c \
cms/cms_menu_vtx_smartaudio.c \
cms/cms_menu_vtx_tramp.c \
@@ -313,6 +314,7 @@ SIZE_OPTIMISED_SRC := $(SIZE_OPTIMISED_SRC) \
cms/cms_menu_ledstrip.c \
cms/cms_menu_misc.c \
cms/cms_menu_osd.c \
+ cms/cms_menu_power.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_menu_builtin.c b/src/main/cms/cms_menu_builtin.c
index 6e6ee3df1d..92a73b366f 100644
--- a/src/main/cms/cms_menu_builtin.c
+++ b/src/main/cms/cms_menu_builtin.c
@@ -43,6 +43,7 @@
#include "cms/cms_menu_osd.h"
#include "cms/cms_menu_ledstrip.h"
#include "cms/cms_menu_misc.h"
+#include "cms/cms_menu_power.h"
// VTX supplied menus
@@ -115,6 +116,7 @@ static OSD_Entry menuFeaturesEntries[] =
#ifdef USE_LED_STRIP
{"LED STRIP", OME_Submenu, cmsMenuChange, &cmsx_menuLedstrip, 0},
#endif // LED_STRIP
+ {"POWER", OME_Submenu, cmsMenuChange, &cmsx_menuPower, 0},
{"BACK", OME_Back, NULL, NULL, 0},
{NULL, OME_END, NULL, NULL, 0}
};
diff --git a/src/main/cms/cms_menu_misc.c b/src/main/cms/cms_menu_misc.c
index dcd63ebe92..7a658b50c4 100644
--- a/src/main/cms/cms_menu_misc.c
+++ b/src/main/cms/cms_menu_misc.c
@@ -93,16 +93,12 @@ CMS_Menu cmsx_menuRcPreview = {
static uint16_t motorConfig_minthrottle;
static uint8_t motorConfig_digitalIdleOffsetValue;
-static uint8_t voltageSensorADCConfig_vbatscale;
-static uint8_t batteryConfig_vbatmaxcellvoltage;
static debugType_e systemConfig_debug_mode;
static long cmsx_menuMiscOnEnter(void)
{
motorConfig_minthrottle = motorConfig()->minthrottle;
motorConfig_digitalIdleOffsetValue = motorConfig()->digitalIdleOffsetValue / 10;
- voltageSensorADCConfig_vbatscale = voltageSensorADCConfig(VOLTAGE_SENSOR_ADC_VBAT)->vbatscale;
- batteryConfig_vbatmaxcellvoltage = batteryConfig()->vbatmaxcellvoltage;
systemConfig_debug_mode = systemConfig()->debug_mode;
return 0;
@@ -114,8 +110,6 @@ static long cmsx_menuMiscOnExit(const OSD_Entry *self)
motorConfigMutable()->minthrottle = motorConfig_minthrottle;
motorConfigMutable()->digitalIdleOffsetValue = 10 * motorConfig_digitalIdleOffsetValue;
- voltageSensorADCConfigMutable(VOLTAGE_SENSOR_ADC_VBAT)->vbatscale = voltageSensorADCConfig_vbatscale;
- batteryConfigMutable()->vbatmaxcellvoltage = batteryConfig_vbatmaxcellvoltage;
systemConfigMutable()->debug_mode = systemConfig_debug_mode;
return 0;
@@ -127,8 +121,6 @@ static OSD_Entry menuMiscEntries[]=
{ "MIN THR", OME_UINT16, NULL, &(OSD_UINT16_t){ &motorConfig_minthrottle, 1000, 2000, 1 }, 0 },
{ "DIGITAL IDLE", OME_UINT8, NULL, &(OSD_UINT8_t) { &motorConfig_digitalIdleOffsetValue, 0, 200, 1 }, 0 },
- { "VBAT SCALE", OME_UINT8, NULL, &(OSD_UINT8_t) { &voltageSensorADCConfig_vbatscale, 1, 250, 1 }, 0 },
- { "VBAT CLMAX", OME_UINT8, NULL, &(OSD_UINT8_t) { &batteryConfig_vbatmaxcellvoltage, 10, 50, 1 }, 0 },
{ "DEBUG MODE", OME_TAB, NULL, &(OSD_TAB_t) { &systemConfig_debug_mode, DEBUG_COUNT - 1, debugModeNames }, 0 },
{ "RC PREV", OME_Submenu, cmsMenuChange, &cmsx_menuRcPreview, 0},
diff --git a/src/main/cms/cms_menu_power.c b/src/main/cms/cms_menu_power.c
new file mode 100644
index 0000000000..a0b0e1a3a0
--- /dev/null
+++ b/src/main/cms/cms_menu_power.c
@@ -0,0 +1,129 @@
+/*
+ * This file is part of Cleanflight.
+ *
+ * Cleanflight is free software: you can redistribute it and/or modify
+ * it 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 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 Cleanflight. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+
+#include "platform.h"
+
+#ifdef USE_CMS
+
+#include "cms/cms.h"
+#include "cms/cms_types.h"
+#include "cms/cms_menu_power.h"
+
+#include "config/feature.h"
+
+#include "sensors/battery.h"
+#include "sensors/current.h"
+#include "sensors/voltage.h"
+
+#include "fc/config.h"
+
+voltageMeterSource_e batteryConfig_voltageMeterSource;
+currentMeterSource_e batteryConfig_currentMeterSource;
+
+uint8_t batteryConfig_vbatmaxcellvoltage;
+
+uint8_t voltageSensorADCConfig_vbatscale;
+
+int16_t currentSensorADCConfig_scale;
+int16_t currentSensorADCConfig_offset;
+
+#ifdef USE_VIRTUAL_CURRENT_METER
+int16_t currentSensorVirtualConfig_scale;
+int16_t currentSensorVirtualConfig_offset;
+#endif
+
+static long cmsx_Power_onEnter(void)
+{
+ batteryConfig_voltageMeterSource = batteryConfig()->voltageMeterSource;
+ batteryConfig_currentMeterSource = batteryConfig()->currentMeterSource;
+
+ batteryConfig_vbatmaxcellvoltage = batteryConfig()->vbatmaxcellvoltage;
+
+ voltageSensorADCConfig_vbatscale = voltageSensorADCConfig(0)->vbatscale;
+
+ currentSensorADCConfig_scale = currentSensorADCConfig()->scale;
+ currentSensorADCConfig_offset = currentSensorADCConfig()->offset;
+
+#ifdef USE_VIRTUAL_CURRENT_METER
+ currentSensorVirtualConfig_scale = currentSensorVirtualConfig()->scale;
+ currentSensorVirtualConfig_offset = currentSensorVirtualConfig()->offset;
+#endif
+
+ return 0;
+}
+
+static long cmsx_Power_onExit(const OSD_Entry *self)
+{
+ UNUSED(self);
+
+ batteryConfigMutable()->voltageMeterSource = batteryConfig_voltageMeterSource;
+ batteryConfigMutable()->currentMeterSource = batteryConfig_currentMeterSource;
+
+ batteryConfigMutable()->vbatmaxcellvoltage = batteryConfig_vbatmaxcellvoltage;
+
+ voltageSensorADCConfigMutable(0)->vbatscale = voltageSensorADCConfig_vbatscale;
+
+ currentSensorADCConfigMutable()->scale = currentSensorADCConfig_scale;
+ currentSensorADCConfigMutable()->offset = currentSensorADCConfig_offset;
+
+#ifdef USE_VIRTUAL_CURRENT_METER
+ currentSensorVirtualConfigMutable()->scale = currentSensorVirtualConfig_scale;
+ currentSensorVirtualConfigMutable()->offset = currentSensorVirtualConfig_offset;
+#endif
+
+ return 0;
+}
+
+static OSD_Entry cmsx_menuPowerEntries[] =
+{
+ { "-- POWER --", OME_Label, NULL, NULL, 0},
+
+ { "V METER", OME_TAB, NULL, &(OSD_TAB_t){ &batteryConfig_voltageMeterSource, VOLTAGE_METER_COUNT - 1, voltageMeterSourceNames }, 0 },
+ { "I METER", OME_TAB, NULL, &(OSD_TAB_t){ &batteryConfig_currentMeterSource, CURRENT_METER_COUNT - 1, currentMeterSourceNames }, 0 },
+
+ { "VBAT CLMAX", OME_UINT8, NULL, &(OSD_UINT8_t) { &batteryConfig_vbatmaxcellvoltage, 10, 50, 1 }, 0 },
+
+ { "VBAT SCALE", OME_UINT8, NULL, &(OSD_UINT8_t){ &voltageSensorADCConfig_vbatscale, VBAT_SCALE_MIN, VBAT_SCALE_MAX, 1 }, 0 },
+
+ { "IBAT SCALE", OME_INT16, NULL, &(OSD_INT16_t){ ¤tSensorADCConfig_scale, -16000, 16000, 5 }, 0 },
+ { "IBAT OFFSET", OME_INT16, NULL, &(OSD_INT16_t){ ¤tSensorADCConfig_offset, -16000, 16000, 5 }, 0 },
+
+#ifdef USE_VIRTUAL_CURRENT_METER
+ { "IBAT VIRT SCALE", OME_INT16, NULL, &(OSD_INT16_t){ ¤tSensorVirtualConfig_scale, -16000, 16000, 5 }, 0 },
+ { "IBAT VIRT OFFSET", OME_INT16, NULL, &(OSD_INT16_t){ ¤tSensorVirtualConfig_offset, -16000, 16000, 5 }, 0 },
+#endif
+
+ { "BACK", OME_Back, NULL, NULL, 0 },
+ { NULL, OME_END, NULL, NULL, 0 }
+};
+
+CMS_Menu cmsx_menuPower = {
+#ifdef CMS_MENU_DEBUG
+ .GUARD_text = "MENUPWR",
+ .GUARD_type = OME_MENU,
+#endif
+ .onEnter = cmsx_Power_onEnter,
+ .onExit = cmsx_Power_onExit,
+ .entries = cmsx_menuPowerEntries
+};
+
+#endif
diff --git a/src/main/cms/cms_menu_power.h b/src/main/cms/cms_menu_power.h
new file mode 100644
index 0000000000..218a74219e
--- /dev/null
+++ b/src/main/cms/cms_menu_power.h
@@ -0,0 +1,20 @@
+/*
+ * This file is part of Cleanflight.
+ *
+ * Cleanflight is free software: you can redistribute it and/or modify
+ * it 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 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 Cleanflight. If not, see .
+ */
+
+#pragma once
+
+extern CMS_Menu cmsx_menuPower;
diff --git a/src/main/interface/settings.c b/src/main/interface/settings.c
index 9c61d17f1b..2eca07a650 100644
--- a/src/main/interface/settings.c
+++ b/src/main/interface/settings.c
@@ -156,14 +156,6 @@ static const char * const lookupTableGPSSBASMode[] = {
};
#endif
-static const char * const lookupTableCurrentSensor[] = {
- "NONE", "ADC", "VIRTUAL", "ESC", "MSP"
-};
-
-static const char * const lookupTableBatterySensor[] = {
- "NONE", "ADC", "ESC"
-};
-
#ifdef USE_SERVOS
static const char * const lookupTableGimbalMode[] = {
"NORMAL", "MIXTILT"
@@ -290,8 +282,8 @@ const lookupTableEntry_t lookupTables[] = {
{ lookupTableBlackboxDevice, sizeof(lookupTableBlackboxDevice) / sizeof(char *) },
{ lookupTableBlackboxMode, sizeof(lookupTableBlackboxMode) / sizeof(char *) },
#endif
- { lookupTableCurrentSensor, sizeof(lookupTableCurrentSensor) / sizeof(char *) },
- { lookupTableBatterySensor, sizeof(lookupTableBatterySensor) / sizeof(char *) },
+ { currentMeterSourceNames, sizeof(currentMeterSourceNames) / sizeof(char *) },
+ { voltageMeterSourceNames, sizeof(voltageMeterSourceNames) / sizeof(char *) },
#ifdef USE_SERVOS
{ lookupTableGimbalMode, sizeof(lookupTableGimbalMode) / sizeof(char *) },
#endif
diff --git a/src/main/sensors/current.c b/src/main/sensors/current.c
index 68705ad7d4..dba09c7eef 100644
--- a/src/main/sensors/current.c
+++ b/src/main/sensors/current.c
@@ -36,6 +36,10 @@
#include "sensors/current.h"
#include "sensors/esc_sensor.h"
+const char * const currentMeterSourceNames[CURRENT_METER_COUNT] = {
+ "NONE", "ADC", "VIRTUAL", "ESC", "MSP"
+};
+
const uint8_t currentMeterIds[] = {
CURRENT_METER_ID_BATTERY_1,
#ifdef USE_VIRTUAL_CURRENT_METER
diff --git a/src/main/sensors/current.h b/src/main/sensors/current.h
index 8996e723ba..4ca3d849cd 100644
--- a/src/main/sensors/current.h
+++ b/src/main/sensors/current.h
@@ -26,9 +26,11 @@ typedef enum {
CURRENT_METER_VIRTUAL,
CURRENT_METER_ESC,
CURRENT_METER_MSP,
- CURRENT_METER_MAX = CURRENT_METER_ESC
+ CURRENT_METER_COUNT
} currentMeterSource_e;
+extern const char * const currentMeterSourceNames[CURRENT_METER_COUNT];
+
typedef struct currentMeter_s {
int32_t amperage; // current read by current sensor in centiampere (1/100th A)
int32_t amperageLatest; // current read by current sensor in centiampere (1/100th A) (unfiltered)
diff --git a/src/main/sensors/voltage.c b/src/main/sensors/voltage.c
index e26b6a55ff..a8e59389f9 100644
--- a/src/main/sensors/voltage.c
+++ b/src/main/sensors/voltage.c
@@ -37,6 +37,10 @@
#include "sensors/voltage.h"
#include "sensors/esc_sensor.h"
+const char * const voltageMeterSourceNames[VOLTAGE_METER_COUNT] = {
+ "NONE", "ADC", "ESC"
+};
+
const uint8_t voltageMeterIds[] = {
VOLTAGE_METER_ID_BATTERY_1,
#ifdef ADC_POWER_12V
diff --git a/src/main/sensors/voltage.h b/src/main/sensors/voltage.h
index e1566fdffa..c144016035 100644
--- a/src/main/sensors/voltage.h
+++ b/src/main/sensors/voltage.h
@@ -26,9 +26,12 @@
typedef enum {
VOLTAGE_METER_NONE = 0,
VOLTAGE_METER_ADC,
- VOLTAGE_METER_ESC
+ VOLTAGE_METER_ESC,
+ VOLTAGE_METER_COUNT
} voltageMeterSource_e;
+extern const char * const voltageMeterSourceNames[VOLTAGE_METER_COUNT];
+
// WARNING - do not mix usage of VOLTAGE_METER_* and VOLTAGE_SENSOR_*, they are separate concerns.
typedef struct voltageMeter_s {