diff --git a/apps/lang/english.lang b/apps/lang/english.lang index 795bde69f8..6ef4d40390 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang @@ -2925,3 +2925,21 @@ desc: ID3 virtual folder name eng: "Found %d matches" voice: "" new: + +id: LANG_BATTERY_TYPE +desc: in battery settings +eng: "Battery type" +voice: "Battery type" +new: + +id: LANG_BATTERY_TYPE_ALKALINE +desc: in battery settings +eng: "Alkaline" +voice: "Alkaline" +new: + +id: LANG_BATTERY_TYPE_NIMH +desc: in battery settings +eng: "NiMH" +voice: "Nickel metal hydride" +new: diff --git a/apps/settings.c b/apps/settings.c index de4254edad..e16d546bb6 100644 --- a/apps/settings.c +++ b/apps/settings.c @@ -235,6 +235,10 @@ static const struct bit_entry rtc_bits[] = /* new stuff to be added here */ /* If values are just added to the end, no need to bump the version. */ +#if BATTERY_TYPES_COUNT > 1 + {1, S_O(battery_type), 0, "battery type", "alkaline,nimh" }, +#endif + /* Current sum of bits: 259 (worst case) */ /* Sum of all bit sizes must not grow beyond 288! */ }; @@ -759,6 +763,9 @@ void settings_apply(void) #endif set_battery_capacity(global_settings.battery_capacity); +#if BATTERY_TYPES_COUNT > 1 + set_battery_type(global_settings.battery_type); +#endif #ifdef HAVE_LCD_BITMAP lcd_set_invert_display(global_settings.invert); diff --git a/apps/settings.h b/apps/settings.h index b28f4cedea..8a12b2623c 100644 --- a/apps/settings.h +++ b/apps/settings.h @@ -185,6 +185,7 @@ struct user_settings bool discharge; /* maintain charge of at least: false = 85%, true = 10% */ bool trickle_charge; /* do trickle charging: 0=off, 1=on */ int battery_capacity; /* in mAh */ + int battery_type; /* for units which can take multiple types (Ondio). */ /* resume settings */ diff --git a/apps/settings_menu.c b/apps/settings_menu.c index 63f1415af8..b19f2eda3c 100644 --- a/apps/settings_menu.c +++ b/apps/settings_menu.c @@ -707,6 +707,19 @@ static bool battery_capacity(void) &set_battery_capacity, 50, BATTERY_CAPACITY_MIN, BATTERY_CAPACITY_MAX ); } + +#if BATTERY_TYPES_COUNT > 1 +static bool battery_type(void) +{ + static const struct opt_items names[] = { + { STR(LANG_BATTERY_TYPE_ALKALINE) }, + { STR(LANG_BATTERY_TYPE_NIMH) } + }; + + return set_option(str(LANG_BATTERY_TYPE), &global_settings.battery_type, + INT, names, 2, set_battery_type); +} +#endif #endif #ifdef HAVE_CHARGE_CTRL @@ -1250,6 +1263,9 @@ static bool battery_settings_menu(void) #endif #ifndef SIMULATOR { ID2P(LANG_BATTERY_CAPACITY), battery_capacity }, +#if BATTERY_TYPES_COUNT > 1 + { ID2P(LANG_BATTERY_TYPE), battery_type }, +#endif #else #ifndef HAVE_CHARGE_CTRL { "Dummy", NULL }, /* to have an entry at all, in the simulator */ diff --git a/firmware/export/config-ondiofm.h b/firmware/export/config-ondiofm.h index 99d4c483ea..79e7adbe58 100644 --- a/firmware/export/config-ondiofm.h +++ b/firmware/export/config-ondiofm.h @@ -26,7 +26,7 @@ #define CONFIG_I2C I2C_ONDIO /* Type of mobile power */ -#define CONFIG_BATTERY BATT_3AAA_ALKALINE +#define CONFIG_BATTERY BATT_3AAA /* Battery scale factor (average from 3 Ondios) */ #define BATTERY_SCALE_FACTOR 4735 diff --git a/firmware/export/config-ondiosp.h b/firmware/export/config-ondiosp.h index 41bc83bf60..bda078a792 100644 --- a/firmware/export/config-ondiosp.h +++ b/firmware/export/config-ondiosp.h @@ -20,7 +20,7 @@ #define CPU_FREQ 12000000 /* Type of mobile power */ -#define CONFIG_BATTERY BATT_3AAA_ALKALINE +#define CONFIG_BATTERY BATT_3AAA /* Battery scale factor (average from 3 Ondios) */ #define BATTERY_SCALE_FACTOR 4735 diff --git a/firmware/export/config.h b/firmware/export/config.h index 4a55fbc622..64694af794 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h @@ -45,9 +45,9 @@ #define GMINI100_PAD 4 /* CONFIG_BATTERY */ -#define BATT_LIION2200 2200 /* FM/V2 recorder type */ -#define BATT_4AA_NIMH 1500 -#define BATT_3AAA_ALKALINE 1000 +#define BATT_LIION2200 2200 /* FM/V2 recorder type */ +#define BATT_4AA_NIMH 1500 +#define BATT_3AAA 1000 /* Ondio */ /* CONFIG_LCD */ #define LCD_GMINI100 0 diff --git a/firmware/export/powermgmt.h b/firmware/export/powermgmt.h index 2847156f46..ce006e9145 100644 --- a/firmware/export/powermgmt.h +++ b/firmware/export/powermgmt.h @@ -26,13 +26,15 @@ #define BATTERY_LEVEL_FULL 400 /* 4.00V */ #define BATTERY_CAPACITY_MIN 2200 #define BATTERY_CAPACITY_MAX 3200 /* max. capacity selectable in settings */ -#elif CONFIG_BATTERY == BATT_3AAA_ALKALINE /* Ondio, Alkalines */ +#define BATTERY_TYPES_COUNT 1 +#elif CONFIG_BATTERY == BATT_3AAA /* Ondio */ #define BATTERY_LEVEL_SHUTDOWN 260 /* 2.60V */ #define BATTERY_LEVEL_EMPTY 270 /* 2.70V */ #define BATTERY_LEVEL_DANGEROUS 280 /* 2.80V */ -#define BATTERY_LEVEL_FULL 450 /* 4.50V */ +#define BATTERY_LEVEL_FULL 475 /* 4.75V */ #define BATTERY_CAPACITY_MIN 500 #define BATTERY_CAPACITY_MAX 1500 /* max. capacity selectable in settings */ +#define BATTERY_TYPES_COUNT 2 /* Alkalines or NiMH */ #else /* Recorder, NiMH */ #define BATTERY_LEVEL_SHUTDOWN 450 /* 4.50V */ #define BATTERY_LEVEL_EMPTY 465 /* 4.65V */ @@ -40,6 +42,7 @@ #define BATTERY_LEVEL_FULL 585 /* 5.85V */ #define BATTERY_CAPACITY_MIN 1500 #define BATTERY_CAPACITY_MAX 3200 /* max. capacity selectable in settings */ +#define BATTERY_TYPES_COUNT 1 #endif #define BATTERY_RANGE (BATTERY_LEVEL_FULL - BATTERY_LEVEL_EMPTY) @@ -111,6 +114,7 @@ bool battery_level_safe(void); void set_poweroff_timeout(int timeout); void set_battery_capacity(int capacity); /* set local battery capacity value */ +void set_battery_type(int type); /* set local battery type */ void set_sleep_timer(int seconds); int get_sleep_timer(void); diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c index 26759b647d..08f0be7d5f 100644 --- a/firmware/powermgmt.c +++ b/firmware/powermgmt.c @@ -89,20 +89,21 @@ static const int poweroff_idle_timeout_value[15] = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 30, 45, 60 }; -static const int percent_to_volt_decharge[11] = +static const short percent_to_volt_decharge[BATTERY_TYPES_COUNT][11] = /* voltages (centivolt) of 0%, 10%, ... 100% when charging disabled */ { #if CONFIG_BATTERY == BATT_LIION2200 /* measured values */ - 260, 285, 295, 303, 311, 320, 330, 345, 360, 380, 400 -#elif CONFIG_BATTERY == BATT_3AAA_ALKALINE - /* taken from a textbook alkaline discharge graph, not measured */ - 270, 303, 324, 336, 348, 357, 366, 378, 390, 408, 450 + { 260, 285, 295, 303, 311, 320, 330, 345, 360, 380, 400 } +#elif CONFIG_BATTERY == BATT_3AAA + /* measured values */ + { 280, 325, 341, 353, 364, 374, 385, 395, 409, 427, 475 }, /* alkaline */ + { 310, 355, 363, 369, 372, 374, 376, 378, 380, 386, 405 } /* NiMH */ #else /* NiMH */ /* original values were taken directly after charging, but it should show 100% after turning off the device for some hours, too */ - 450, 481, 491, 497, 503, 507, 512, 514, 517, 525, 540 /* orig. values: - ...,528,560 */ + { 450, 481, 491, 497, 503, 507, 512, 514, 517, 525, 540 } + /* orig. values: ...,528,560 */ #endif }; @@ -115,6 +116,16 @@ void set_battery_capacity(int capacity) battery_capacity = BATTERY_CAPACITY_MIN; } +#if BATTERY_TYPES_COUNT > 1 +static int battery_type = 0; + +void set_battery_type(int type) +{ + battery_type = type; + battery_level_cached = -1; /* reset on type change */ +} +#endif + #if defined(HAVE_CHARGE_CTRL) || CONFIG_BATTERY == BATT_LIION2200 int charge_state = 0; /* at the beginning, the charger does nothing */ @@ -136,7 +147,7 @@ int trickle_sec = 0; /* how many seconds should the charger be enabled per minute for trickle charging? */ -static const int percent_to_volt_charge[11] = +static const short percent_to_volt_charge[11] = /* voltages (centivolt) of 0%, 10%, ... 100% when charging enabled */ { /* values guessed, see @@ -170,7 +181,7 @@ int battery_time(void) /* look into the percent_to_volt_* table and get a realistic battery level percentage */ -int voltage_to_percent(int voltage, const int* table) +int voltage_to_percent(int voltage, const short* table) { if (voltage <= table[0]) return 0; @@ -195,6 +206,9 @@ void battery_level_update(void) int level = 0; int c = 0; int i; +#if BATTERY_TYPES_COUNT == 1 /* single type */ + const int battery_type = 0; +#endif /* calculate maximum over last 3 minutes (skip empty samples) */ for (i = 0; i < 3; i++) @@ -214,7 +228,8 @@ void battery_level_update(void) #ifdef HAVE_CHARGE_CTRL if (charge_state == 0) { /* decharge */ - level = voltage_to_percent(level, percent_to_volt_decharge); + level = voltage_to_percent(level, + percent_to_volt_decharge[battery_type]); } else if (charge_state == 1) { /* charge */ level = voltage_to_percent(level, percent_to_volt_charge); @@ -223,7 +238,8 @@ void battery_level_update(void) battery_level_cached = level = 100; } #else - level = voltage_to_percent(level, percent_to_volt_decharge); + level = voltage_to_percent(level, + percent_to_volt_decharge[battery_type]); /* always use the decharge table */ #endif