powermgmt: Add battery current measurement

This allows targets to report the actual discharging or
charging current if they are able to.

Change-Id: I0b538e6ac94346f1434e45f83c8da8c1260a53a3
This commit is contained in:
Aidan MacDonald 2021-11-30 14:16:13 +00:00
parent 923f92cb12
commit ad05c872fe
4 changed files with 52 additions and 8 deletions

View file

@ -208,6 +208,8 @@
Usually application ports, and only Usually application ports, and only
if the estimation is better that ours if the estimation is better that ours
(which it probably is) */ (which it probably is) */
#define CURRENT_MEASURE 8 /* Target can report battery charge and/or
* discharge current */
/* CONFIG_LCD */ /* CONFIG_LCD */
#define LCD_SSD1815 1 /* as used by Sansa M200 and others */ #define LCD_SSD1815 1 /* as used by Sansa M200 and others */
#define LCD_S1D15E06 3 /* as used by iRiver H100 series */ #define LCD_S1D15E06 3 /* as used by iRiver H100 series */

View file

@ -94,6 +94,11 @@ void powermgmt_init(void) INIT_ATTR;
#define BATT_AVE_SAMPLES 128 #define BATT_AVE_SAMPLES 128
#endif #endif
#ifndef BATT_CURRENT_AVE_SAMPLES
/* TODO may need tweaking */
#define BATT_CURRENT_AVE_SAMPLES 16
#endif
#ifndef POWER_THREAD_STEP_TICKS #ifndef POWER_THREAD_STEP_TICKS
/* 2HZ sample rate unless otherwise specified */ /* 2HZ sample rate unless otherwise specified */
#define POWER_THREAD_STEP_TICKS (HZ/2) #define POWER_THREAD_STEP_TICKS (HZ/2)
@ -118,6 +123,8 @@ int battery_current(void); /* battery current in milliamps
int _battery_level(void); /* percent */ int _battery_level(void); /* percent */
int _battery_time(void); /* minutes */ int _battery_time(void); /* minutes */
int _battery_voltage(void); /* voltage in millivolts */ int _battery_voltage(void); /* voltage in millivolts */
int _battery_current(void); /* (dis)charge current in milliamps */
#if CONFIG_CHARGING >= CHARGING_TARGET #if CONFIG_CHARGING >= CHARGING_TARGET
void powermgmt_init_target(void); void powermgmt_init_target(void);
void charging_algorithm_close(void); void charging_algorithm_close(void);

View file

@ -110,7 +110,8 @@ static int percent_now; /* Cached to avoid polling too often */
#if !(CONFIG_BATTERY_MEASURE & TIME_MEASURE) #if !(CONFIG_BATTERY_MEASURE & TIME_MEASURE)
int _battery_time(void) { return -1; } int _battery_time(void) { return -1; }
#endif #endif
#if (CONFIG_BATTERY_MEASURE & TIME_MEASURE) || defined(CURRENT_NORMAL) #if (CONFIG_BATTERY_MEASURE & TIME_MEASURE) || \
defined(CURRENT_NORMAL) || (CONFIG_BATTERY_MEASURE & CURRENT_MEASURE)
static int time_now; /* Cached to avoid polling too often */ static int time_now; /* Cached to avoid polling too often */
#endif #endif
@ -121,6 +122,12 @@ int _battery_voltage(void) { return -1; }
static int voltage_avg, voltage_now; static int voltage_avg, voltage_now;
#endif #endif
#if !(CONFIG_BATTERY_MEASURE & CURRENT_MEASURE)
int _battery_current(void) { return -1; }
#else
static int current_avg, current_now;
#endif
/* The battery level can be obtained in two ways. If the target reports /* The battery level can be obtained in two ways. If the target reports
* voltage, the battery level can be estminated using percent_to_volt_* * voltage, the battery level can be estminated using percent_to_volt_*
* curves. If the target can report the percentage directly, then that * curves. If the target can report the percentage directly, then that
@ -142,7 +149,8 @@ int battery_level(void)
* on the battery level and the actual current usage. */ * on the battery level and the actual current usage. */
int battery_time(void) int battery_time(void)
{ {
#if (CONFIG_BATTERY_MEASURE & TIME_MEASURE) || defined(CURRENT_NORMAL) #if (CONFIG_BATTERY_MEASURE & TIME_MEASURE) || \
defined(CURRENT_NORMAL) || (CONFIG_BATTERY_MEASURE & CURRENT_MEASURE)
return time_now; return time_now;
#else #else
return -1; return -1;
@ -166,7 +174,9 @@ int battery_voltage(void)
* the power consumed by the backlight, remote display, SPDIF, etc. */ * the power consumed by the backlight, remote display, SPDIF, etc. */
int battery_current(void) int battery_current(void)
{ {
#if defined(CURRENT_NORMAL) #if CONFIG_BATTERY_MEASURE & CURRENT_MEASURE
return current_now;
#elif defined(CURRENT_NORMAL)
int current = CURRENT_NORMAL; int current = CURRENT_NORMAL;
#ifndef BOOTLOADER #ifndef BOOTLOADER
@ -223,8 +233,8 @@ int battery_current(void)
#endif #endif
} }
/* Initialize the battery voltage filter. This is called once /* Initialize the battery voltage/current filters. This is called
* by the power thread before entering the main polling loop. */ * once by the power thread before entering the main polling loop. */
static void average_init(void) static void average_init(void)
{ {
#if CONFIG_BATTERY_MEASURE & VOLTAGE_MEASURE #if CONFIG_BATTERY_MEASURE & VOLTAGE_MEASURE
@ -244,9 +254,14 @@ static void average_init(void)
voltage_avg = voltage_now * BATT_AVE_SAMPLES; voltage_avg = voltage_now * BATT_AVE_SAMPLES;
#endif /* CONFIG_BATTERY_MEASURE & VOLTAGE_MEASURE */ #endif /* CONFIG_BATTERY_MEASURE & VOLTAGE_MEASURE */
#if CONFIG_BATTERY_MEASURE & CURRENT_MEASURE
current_now = _battery_current();
current_avg = current_now * BATT_CURRENT_AVE_SAMPLES;
#endif
} }
/* Sample the battery voltage and update the filter. /* Sample the battery voltage/current and update the filters.
* Updated once every POWER_THREAD_STEP_TICKS. */ * Updated once every POWER_THREAD_STEP_TICKS. */
static void average_step(bool low_battery) static void average_step(bool low_battery)
{ {
@ -262,6 +277,11 @@ static void average_step(bool low_battery)
#else #else
(void)low_battery; (void)low_battery;
#endif #endif
#if CONFIG_BATTERY_MEASURE & CURRENT_MEASURE
current_avg += _battery_current() - current_avg / BATT_CURRENT_AVE_SAMPLES;
current_now = current_avg / BATT_CURRENT_AVE_SAMPLES;
#endif
} }
/* Send system battery level update events on reaching certain significant /* Send system battery level update events on reaching certain significant
@ -353,7 +373,7 @@ static void battery_status_update(void)
#if CONFIG_BATTERY_MEASURE & TIME_MEASURE #if CONFIG_BATTERY_MEASURE & TIME_MEASURE
time_now = _battery_time(); time_now = _battery_time();
#elif defined(CURRENT_NORMAL) #elif defined(CURRENT_NORMAL) || (CONFIG_BATTERY_MEASURE & CURRENT_MEASURE)
int current = battery_current(); int current = battery_current();
if(level >= 0 && current > 0 && battery_capacity > 0) { if(level >= 0 && current > 0 && battery_capacity > 0) {
#if CONFIG_CHARGING >= CHARGING_MONITOR #if CONFIG_CHARGING >= CHARGING_MONITOR
@ -455,6 +475,11 @@ void reset_battery_filter(int millivolts)
{ {
voltage_avg = millivolts * BATT_AVE_SAMPLES; voltage_avg = millivolts * BATT_AVE_SAMPLES;
voltage_now = millivolts; voltage_now = millivolts;
#if CONFIG_BATTERY_MEASURE & CURRENT_MEASURE
/* current would probably be inaccurate too */
current_now = _battery_current();
current_avg = current_now * BATT_CURRENT_AVE_SAMPLES;
#endif
battery_status_update(); battery_status_update();
} }
#endif /* HAVE_BATTERY_SWITCH */ #endif /* HAVE_BATTERY_SWITCH */
@ -589,7 +614,6 @@ static inline bool detect_charger(unsigned int pwr)
} }
#endif /* CONFIG_CHARGING */ #endif /* CONFIG_CHARGING */
#if CONFIG_BATTERY_MEASURE & VOLTAGE_MEASURE #if CONFIG_BATTERY_MEASURE & VOLTAGE_MEASURE
static int power_hist_item(void) static int power_hist_item(void)
{ {

View file

@ -43,6 +43,7 @@ static bool charging = false;
static unsigned int batt_millivolts = BATT_MAXMVOLT; static unsigned int batt_millivolts = BATT_MAXMVOLT;
static unsigned int batt_percent = 100; static unsigned int batt_percent = 100;
static unsigned int batt_runtime = BATT_MAXRUNTIME; static unsigned int batt_runtime = BATT_MAXRUNTIME;
static unsigned int batt_current = 0;
void powermgmt_init_target(void) {} void powermgmt_init_target(void) {}
@ -97,6 +98,8 @@ static void battery_status_update(void)
batt_percent = (batt_millivolts - BATT_MINMVOLT) / (BATT_MAXMVOLT - BATT_MINMVOLT); batt_percent = (batt_millivolts - BATT_MINMVOLT) / (BATT_MAXMVOLT - BATT_MINMVOLT);
batt_runtime = batt_percent * BATT_MAXRUNTIME; batt_runtime = batt_percent * BATT_MAXRUNTIME;
/* current is completely bogus... */
batt_current = charging ? BATT_CHARGE_STEP : BATT_DISCHARGE_STEP;
} }
const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = { 3200 }; const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = { 3200 };
@ -132,6 +135,14 @@ int _battery_time(void)
} }
#endif #endif
#if (CONFIG_BATTERY_MEASURE & CURRENT_MEASURE)
int _battery_current(void)
{
battery_status_update();
return batt_current;
}
#endif
#if CONFIG_CHARGING #if CONFIG_CHARGING
unsigned int power_input_status(void) unsigned int power_input_status(void)
{ {