From f02cd18ad027cdb4992a19a16cfbd336ffb63124 Mon Sep 17 00:00:00 2001 From: Aidan MacDonald Date: Tue, 30 Nov 2021 01:26:59 +0000 Subject: powermgmt: Refactor battery current estimation Create a new battery_current() function to report the the battery's charging/discharging current. Move the old runcurrent() implementation into it and clean up some of the related defines. Change-Id: I7dbe5b6532d291fa72add1cb23b30e3cbac8c3ca --- firmware/export/config/iaudiox5.h | 1 + firmware/export/config/ipod6g.h | 1 + firmware/export/config/mrobe500.h | 2 +- firmware/export/config/samsungypr0.h | 1 + firmware/export/config/samsungypr1.h | 1 + firmware/export/powermgmt.h | 19 ++------- firmware/powermgmt.c | 75 ++++++++++++++++++------------------ 7 files changed, 45 insertions(+), 55 deletions(-) diff --git a/firmware/export/config/iaudiox5.h b/firmware/export/config/iaudiox5.h index 0164cd20fa..cae83dd952 100644 --- a/firmware/export/config/iaudiox5.h +++ b/firmware/export/config/iaudiox5.h @@ -151,6 +151,7 @@ #define CURRENT_NORMAL 65 /*2250mah/35h = 65 ma*/ #define CURRENT_BACKLIGHT 25 #define CURRENT_REMOTE 8 /* additional current when remote connected */ +#define CURRENT_RECORD 2 /* FIXME: placeholder value */ /* Define this if your LCD can set contrast */ #define HAVE_LCD_CONTRAST diff --git a/firmware/export/config/ipod6g.h b/firmware/export/config/ipod6g.h index fdf7e8e516..2e4afbdf63 100644 --- a/firmware/export/config/ipod6g.h +++ b/firmware/export/config/ipod6g.h @@ -158,6 +158,7 @@ /* define current usage levels */ #define CURRENT_NORMAL 18 /* playback @48MHz clock, backlight off */ #define CURRENT_BACKLIGHT 23 /* maximum brightness */ +#define CURRENT_RECORD 2 /* FIXME: placeholder value */ /* define this if the unit can be powered or charged via USB */ #define HAVE_USB_POWER diff --git a/firmware/export/config/mrobe500.h b/firmware/export/config/mrobe500.h index a7d72f76ac..ffc8a6bfb8 100644 --- a/firmware/export/config/mrobe500.h +++ b/firmware/export/config/mrobe500.h @@ -198,7 +198,7 @@ /* define current usage levels */ #define CURRENT_NORMAL 85 /* Measured */ #define CURRENT_BACKLIGHT 200 /* Over 200 mA total measured when on */ -#define CURRENT_RECORD 0 /* no recording */ +#define CURRENT_REMOTE 2 /* FIXME: placeholder value */ /* Hardware controlled charging with monitoring */ #define CONFIG_CHARGING CHARGING_MONITOR diff --git a/firmware/export/config/samsungypr0.h b/firmware/export/config/samsungypr0.h index 520eb08d01..88ba96504d 100644 --- a/firmware/export/config/samsungypr0.h +++ b/firmware/export/config/samsungypr0.h @@ -121,6 +121,7 @@ /* Define current usage levels. */ #define CURRENT_NORMAL 24 /* ~25h, on 600mAh that's about 24mA */ #define CURRENT_BACKLIGHT 62 /* ~6,5h -> 92mA. Minus 24mA normal that gives us 68mA */ +#define CURRENT_RECORD 2 /* FIXME: placeholder value */ #endif /* SIMULATOR */ diff --git a/firmware/export/config/samsungypr1.h b/firmware/export/config/samsungypr1.h index 50abfa323e..8ef76d60af 100644 --- a/firmware/export/config/samsungypr1.h +++ b/firmware/export/config/samsungypr1.h @@ -163,5 +163,6 @@ /* Define current usage levels. */ #define CURRENT_NORMAL 24 /* ~25h, on 600mAh that's about 24mA */ #define CURRENT_BACKLIGHT 62 /* ~6,5h -> 92mA. Minus 24mA normal that gives us 68mA */ +#define CURRENT_RECORD 2 /* FIXME: placeholder value */ #endif /* SIMULATOR */ diff --git a/firmware/export/powermgmt.h b/firmware/export/powermgmt.h index a4b924915c..c6fc3d5bdf 100644 --- a/firmware/export/powermgmt.h +++ b/firmware/export/powermgmt.h @@ -81,28 +81,13 @@ void powermgmt_init(void) INIT_ATTR; /* Generic current values that are intentionally meaningless - config header * should define proper numbers.*/ - -#ifndef CURRENT_BACKLIGHT -#define CURRENT_BACKLIGHT 5 /* additional current when backlight always on */ -#endif - -#if defined(HAVE_RECORDING) && !defined(CURRENT_RECORD) -#define CURRENT_RECORD 2 /* additional recording current */ -#endif /* HAVE_RECORDING && !CURRENT_RECORD*/ - #ifndef CURRENT_USB #define CURRENT_USB 2 /* usual current in mA in USB mode */ #endif -#if defined(HAVE_REMOTE_LCD) && !defined(CURRENT_REMOTE) -#define CURRENT_REMOTE 2 /* additional current when remote connected */ -#endif /* CURRENT_REMOTE && !HAVE_REMOTE_LCD */ - -#if CONFIG_CHARGING -#ifndef CURRENT_MAX_CHG +#if CONFIG_CHARGING && !defined(CURRENT_MAX_CHG) #define CURRENT_MAX_CHG 350 /* maximum charging current */ #endif -#endif /* CONFIG_CHARGING */ #ifndef BATT_AVE_SAMPLES /* slw filter constant unless otherwise specified */ @@ -126,6 +111,8 @@ extern const unsigned short percent_to_volt_charge[11]; int battery_level(void); /* percent */ int battery_time(void); /* minutes */ int battery_voltage(void); /* filtered batt. voltage in millivolts */ +int battery_current(void); /* battery current in milliamps + * (may just be a rough estimate) */ /* Implemented by the target, unfiltered */ int _battery_level(void); /* percent */ diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c index 313486889e..13e810e926 100644 --- a/firmware/powermgmt.c +++ b/firmware/powermgmt.c @@ -83,7 +83,7 @@ void handle_auto_poweroff(void); static int poweroff_timeout = 0; static long last_event_tick = 0; -#if (CONFIG_BATTERY_MEASURE & PERCENTAGE_MEASURE) == PERCENTAGE_MEASURE +#if CONFIG_BATTERY_MEASURE & PERCENTAGE_MEASURE #ifdef SIMULATOR int _battery_level(void) { return -1; } #endif @@ -91,7 +91,7 @@ int _battery_level(void) { return -1; } int _battery_level(void) { return -1; } #endif -#if (CONFIG_BATTERY_MEASURE & VOLTAGE_MEASURE) == VOLTAGE_MEASURE +#if CONFIG_BATTERY_MEASURE & VOLTAGE_MEASURE /* * Average battery voltage and charger voltage, filtered via a digital * exponential filter (aka. exponential moving average, scaled): @@ -109,8 +109,12 @@ const unsigned short percent_to_volt_charge[11]; #endif #if !(CONFIG_BATTERY_MEASURE & TIME_MEASURE) +#ifdef CURRENT_NORMAL static int powermgmt_est_runningtime_min; int _battery_time(void) { return powermgmt_est_runningtime_min; } +#else +int _battery_time(void) { return -1; } +#endif #endif /* default value, mAh */ @@ -141,10 +145,6 @@ static const char power_thread_name[] = "power"; static int voltage_to_battery_level(int battery_millivolts); static void battery_status_update(void); -#ifdef CURRENT_NORMAL /*only used if we have run current*/ -static int runcurrent(void); -#endif - #if BATTERY_TYPES_COUNT > 1 void set_battery_type(int type) { @@ -179,19 +179,15 @@ int get_battery_capacity(void) int battery_time(void) { -#if ((CONFIG_BATTERY_MEASURE & TIME_MEASURE) == 0) - -#ifndef CURRENT_NORMAL /* no estimation without current */ - return -1; -#else - if (battery_capacity <= 0) /* nor without capacity */ +#if !(CONFIG_BATTERY_MEASURE & TIME_MEASURE) + /* Note: This should not really be possible but it might occur + * as a degenerate case for targets that don't define any battery + * capacity at all..? */ + if(battery_capacity <= 0) return -1; - return _battery_time(); #endif -#else return _battery_time(); -#endif } /* Returns battery level in percent */ @@ -209,7 +205,7 @@ bool battery_level_safe(void) { #if defined(NO_LOW_BATTERY_SHUTDOWN) return true; -#elif (CONFIG_BATTERY_MEASURE & PERCENTAGE_MEASURE) +#elif CONFIG_BATTERY_MEASURE & PERCENTAGE_MEASURE return (battery_percent > 0); #elif defined(HAVE_BATTERY_SWITCH) /* Cannot rely upon the battery reading to be valid and the @@ -278,40 +274,36 @@ static void battery_status_update(void) if (level < 0) level = voltage_to_battery_level(millivolt); -#ifdef CURRENT_NORMAL /*don't try to estimate run or charge - time without normal current defined*/ - /* calculate estimated remaining running time */ +#ifdef CURRENT_NORMAL + int current = battery_current(); + #if CONFIG_CHARGING >= CHARGING_MONITOR if (charging_state()) { /* charging: remaining charging time */ - powermgmt_est_runningtime_min = (100 - level)*battery_capacity*60 - / 100 / (CURRENT_MAX_CHG - runcurrent()); + if(current > 0) { + powermgmt_est_runningtime_min = + (100 - level) * battery_capacity * 60 / 100 / current; + } } else #endif /* discharging: remaining running time */ - if (level > 0 && (millivolt > percent_to_volt_discharge[battery_type][0] - || millivolt < 0)) { - /* linear extrapolation */ - powermgmt_est_runningtime_min = (level + battery_percent)*60 - * battery_capacity / 200 / runcurrent(); + if (level >= 0 && current > 0) { + powermgmt_est_runningtime_min = + (level + battery_percent) * battery_capacity * 60 / 200 / current; } - if (0 > powermgmt_est_runningtime_min) { + + if (powermgmt_est_runningtime_min < 0 || current <= 0) powermgmt_est_runningtime_min = 0; - } #endif battery_percent = level; send_battery_level_event(); } -#ifdef CURRENT_NORMAL /*check that we have a current defined in a config file*/ - -/* - * Estimate how much current we are drawing just to run. - */ -static int runcurrent(void) +#ifdef CURRENT_NORMAL +int battery_current(void) { int current = CURRENT_NORMAL; @@ -328,7 +320,7 @@ static int runcurrent(void) current = CURRENT_USB; } -#if defined(HAVE_BACKLIGHT) +#if defined(HAVE_BACKLIGHT) && defined(CURRENT_BACKLIGHT) if (backlight_get_current_timeout() == 0) /* LED always on */ current += CURRENT_BACKLIGHT; #endif @@ -338,12 +330,12 @@ static int runcurrent(void) current += CURRENT_RECORD; #endif -#ifdef HAVE_SPDIF_POWER +#if defined(HAVE_SPDIF_POWER) && defined(CURRENT_SPDIF_OUT) if (spdif_powered()) current += CURRENT_SPDIF_OUT; #endif -#ifdef HAVE_REMOTE_LCD +#if defined(HAVE_REMOTE_LCD) && defined(CURRENT_REMOTE) if (remote_detect()) current += CURRENT_REMOTE; #endif @@ -353,11 +345,18 @@ static int runcurrent(void) current += CURRENT_ATA; #endif +#if CONFIG_CHARGING >= CHARGING_MONITOR + /* While charging we must report the charging current. */ + if (charging_state()) { + current = CURRENT_MAX_CHG - current; + current = MIN(current, 1); + } +#endif + #endif /* BOOTLOADER */ return current; } - #endif /* CURRENT_NORMAL */ /* Check to see whether or not we've received an alarm in the last second */ -- cgit v1.2.3