mirror of
https://github.com/CTCaer/hekate
synced 2024-12-22 11:21:23 +00:00
Add battery/charge info + bugfixes
This commit is contained in:
parent
3908493cf5
commit
0c5c827d0b
6 changed files with 216 additions and 197 deletions
|
@ -33,7 +33,7 @@ Greetings to: fincs, hexkyz, SciresM, Shiny Quagsire, WinterMute.
|
||||||
Open source and free packages used:
|
Open source and free packages used:
|
||||||
- FatFs R0.13a, Copyright (C) 2017, ChaN
|
- FatFs R0.13a, Copyright (C) 2017, ChaN
|
||||||
- bcl-1.2.0, Copyright (C) 2003-2006, Marcus Geelnard
|
- bcl-1.2.0, Copyright (C) 2003-2006, Marcus Geelnard
|
||||||
- Atmosphére (se_calculate_sha256), Copyright (C) 2018, Atmosphére-NX
|
- Atmosphère (se_calculate_sha256), Copyright (C) 2018, Atmosphère-NX
|
||||||
|
|
||||||
___
|
___
|
||||||
.-' `'.
|
.-' `'.
|
||||||
|
|
|
@ -218,7 +218,8 @@ void gfx_putc(gfx_con_t *con, char c)
|
||||||
con->y = 0;
|
con->y = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
|
default:
|
||||||
if (c >= 32 && c <= 126)
|
if (c >= 32 && c <= 126)
|
||||||
{
|
{
|
||||||
u8 *cbuf = (u8 *)&_gfx_font[8 * (c - 32)];
|
u8 *cbuf = (u8 *)&_gfx_font[8 * (c - 32)];
|
||||||
|
|
146
ipl/main.c
146
ipl/main.c
|
@ -365,6 +365,7 @@ void print_fuseinfo()
|
||||||
if (sd_mount())
|
if (sd_mount())
|
||||||
{
|
{
|
||||||
char fuseFilename[23];
|
char fuseFilename[23];
|
||||||
|
f_mkdir("Backup");
|
||||||
f_mkdir("Backup/Dumps");
|
f_mkdir("Backup/Dumps");
|
||||||
memcpy(fuseFilename, "Backup/Dumps/fuses.bin\0", 23);
|
memcpy(fuseFilename, "Backup/Dumps/fuses.bin\0", 23);
|
||||||
|
|
||||||
|
@ -399,6 +400,7 @@ void print_kfuseinfo()
|
||||||
if (sd_mount())
|
if (sd_mount())
|
||||||
{
|
{
|
||||||
char kfuseFilename[24];
|
char kfuseFilename[24];
|
||||||
|
f_mkdir("Backup");
|
||||||
f_mkdir("Backup/Dumps");
|
f_mkdir("Backup/Dumps");
|
||||||
memcpy(kfuseFilename, "Backup/Dumps/kfuses.bin\0", 24);
|
memcpy(kfuseFilename, "Backup/Dumps/kfuses.bin\0", 24);
|
||||||
|
|
||||||
|
@ -757,6 +759,7 @@ int dump_emmc_verify(sdmmc_storage_t *storage, u32 lba_curr, char* outFilename,
|
||||||
res = memcmp32sparse((u32 *)bufEm, (u32 *)bufSd, num << 9);
|
res = memcmp32sparse((u32 *)bufEm, (u32 *)bufSd, num << 9);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
|
default:
|
||||||
se_calc_sha256(&hashEm, bufEm, num << 9);
|
se_calc_sha256(&hashEm, bufEm, num << 9);
|
||||||
se_calc_sha256(&hashSd, bufSd, num << 9);
|
se_calc_sha256(&hashSd, bufSd, num << 9);
|
||||||
res = memcmp(hashEm, hashSd, 0x20);
|
res = memcmp(hashEm, hashSd, 0x20);
|
||||||
|
@ -1284,6 +1287,7 @@ void dump_package1()
|
||||||
gfx_printf(&gfx_con, "%kWarmboot ofst: %k0x%05X\n\n", 0xFFC7EA46, 0xFFCCCCCC, hdr->wb_off);
|
gfx_printf(&gfx_con, "%kWarmboot ofst: %k0x%05X\n\n", 0xFFC7EA46, 0xFFCCCCCC, hdr->wb_off);
|
||||||
|
|
||||||
// Dump package1.
|
// Dump package1.
|
||||||
|
f_mkdir("Backup");
|
||||||
f_mkdir("Backup/pkg1");
|
f_mkdir("Backup/pkg1");
|
||||||
if (sd_save_to_file(pkg1, 0x40000, "Backup/pkg1/pkg1_decr.bin")) {
|
if (sd_save_to_file(pkg1, 0x40000, "Backup/pkg1/pkg1_decr.bin")) {
|
||||||
EPRINTF("\nFailed to create pkg1_decr.bin");
|
EPRINTF("\nFailed to create pkg1_decr.bin");
|
||||||
|
@ -1510,19 +1514,150 @@ void fix_sd_attr(){
|
||||||
btn_wait();
|
btn_wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_fuel_gauge_regs()
|
void print_fuel_gauge_info()
|
||||||
|
{
|
||||||
|
int value = 0;
|
||||||
|
|
||||||
|
gfx_printf(&gfx_con, "%kFuel Gauge IC Info:\n%k", 0xFF00DDFF, 0xFFCCCCCC);
|
||||||
|
|
||||||
|
max17050_get_property(MAX17050_Age, &value);
|
||||||
|
gfx_printf(&gfx_con, "Age: %3d%\n", value);
|
||||||
|
|
||||||
|
max17050_get_property(MAX17050_Cycles, &value);
|
||||||
|
gfx_printf(&gfx_con, "Charge cycle count: %4d\n", value);
|
||||||
|
|
||||||
|
max17050_get_property(MAX17050_TEMP, &value);
|
||||||
|
if (value >= 0)
|
||||||
|
gfx_printf(&gfx_con, "Battery temperature: %d.%d oC\n", value / 10, value % 10);
|
||||||
|
else
|
||||||
|
gfx_printf(&gfx_con, "Battery temperature: -%d.%d oC\n", ~value / 10, (~value) % 10);
|
||||||
|
|
||||||
|
max17050_get_property(MAX17050_Current, &value);
|
||||||
|
if (value >= 0)
|
||||||
|
gfx_printf(&gfx_con, "Current now: %d mA\n", value / 1000);
|
||||||
|
else
|
||||||
|
gfx_printf(&gfx_con, "Current now: -%d mA\n", ~value / 1000);
|
||||||
|
|
||||||
|
max17050_get_property(MAX17050_AvgCurrent, &value);
|
||||||
|
if (value >= 0)
|
||||||
|
gfx_printf(&gfx_con, "Current average: %d mA\n", value / 1000);
|
||||||
|
else
|
||||||
|
gfx_printf(&gfx_con, "Current average: -%d mA\n", ~value / 1000);
|
||||||
|
|
||||||
|
max17050_get_property(MAX17050_MinVolt, &value);
|
||||||
|
gfx_printf(&gfx_con, "Min voltage reached: %4d mV\n", value);
|
||||||
|
|
||||||
|
max17050_get_property(MAX17050_MaxVolt, &value);
|
||||||
|
gfx_printf(&gfx_con, "Max voltage reached: %4d mV\n", value);
|
||||||
|
|
||||||
|
max17050_get_property(MAX17050_V_empty, &value);
|
||||||
|
gfx_printf(&gfx_con, "Empty voltage (design): %4d mV\n", value);
|
||||||
|
|
||||||
|
max17050_get_property(MAX17050_VCELL, &value);
|
||||||
|
gfx_printf(&gfx_con, "Voltage now: %4d mV\n", value);
|
||||||
|
|
||||||
|
max17050_get_property(MAX17050_OCVInternal, &value);
|
||||||
|
gfx_printf(&gfx_con, "Voltage open-circuit: %4d mV\n", value);
|
||||||
|
|
||||||
|
max17050_get_property(MAX17050_RepSOC, &value);
|
||||||
|
gfx_printf(&gfx_con, "Capacity now: %3d%\n", value >> 8);
|
||||||
|
|
||||||
|
max17050_get_property(MAX17050_RepCap, &value);
|
||||||
|
gfx_printf(&gfx_con, "Capacity now: %4d mAh\n", value);
|
||||||
|
|
||||||
|
max17050_get_property(MAX17050_FullCAP, &value);
|
||||||
|
gfx_printf(&gfx_con, "Capacity full: %4d mAh\n", value);
|
||||||
|
|
||||||
|
max17050_get_property(MAX17050_DesignCap, &value);
|
||||||
|
gfx_printf(&gfx_con, "Capacity (design): %4d mAh\n", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_battery_charger_info()
|
||||||
|
{
|
||||||
|
int value = 0;
|
||||||
|
|
||||||
|
gfx_printf(&gfx_con, "%k\n\nBattery Charger IC Info:\n%k", 0xFF00DDFF, 0xFFCCCCCC);
|
||||||
|
|
||||||
|
bq24193_get_property(BQ24193_InputVoltageLimit, &value);
|
||||||
|
gfx_printf(&gfx_con, "Input voltage limit: %4d mV\n", value);
|
||||||
|
|
||||||
|
bq24193_get_property(BQ24193_InputCurrentLimit, &value);
|
||||||
|
gfx_printf(&gfx_con, "Input current limit: %4d mA\n", value);
|
||||||
|
|
||||||
|
bq24193_get_property(BQ24193_SystemMinimumVoltage, &value);
|
||||||
|
gfx_printf(&gfx_con, "Min voltage limit: %4d mV\n", value);
|
||||||
|
|
||||||
|
bq24193_get_property(BQ24193_FastChargeCurrentLimit, &value);
|
||||||
|
gfx_printf(&gfx_con, "Fast charge current limit: %4d mA\n", value);
|
||||||
|
|
||||||
|
bq24193_get_property(BQ24193_ChargeVoltageLimit, &value);
|
||||||
|
gfx_printf(&gfx_con, "Charge voltage limit: %4d mV\n", value);
|
||||||
|
|
||||||
|
bq24193_get_property(BQ24193_ThermalRegulation, &value);
|
||||||
|
gfx_printf(&gfx_con, "Thermal threshold: %4d oC\n", value);
|
||||||
|
|
||||||
|
bq24193_get_property(BQ24193_ChargeStatus, &value);
|
||||||
|
gfx_printf(&gfx_con, "Charge status: ");
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
gfx_printf(&gfx_con, "Not charging\n");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
gfx_printf(&gfx_con, "Pre-charging\n");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
gfx_printf(&gfx_con, "Fast charging\n");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
gfx_printf(&gfx_con, "Charge terminated\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
gfx_printf(&gfx_con, "Unknown (%d)\n", value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bq24193_get_property(BQ24193_TempStatus, &value);
|
||||||
|
gfx_printf(&gfx_con, "Temperature status: ");
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
gfx_printf(&gfx_con, "Normal\n");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
gfx_printf(&gfx_con, "Warm\n");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
gfx_printf(&gfx_con, "Cool\n");
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
gfx_printf(&gfx_con, "Cold\n");
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
gfx_printf(&gfx_con, "Hot\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
gfx_printf(&gfx_con, "Unknown (%d)\n", value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_battery_info()
|
||||||
{
|
{
|
||||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||||
gfx_con_setpos(&gfx_con, 0, 0);
|
gfx_con_setpos(&gfx_con, 0, 0);
|
||||||
|
|
||||||
|
print_fuel_gauge_info();
|
||||||
|
|
||||||
|
print_battery_charger_info();
|
||||||
|
|
||||||
u8 *buf = (u8 *)malloc(0x100 * 2);
|
u8 *buf = (u8 *)malloc(0x100 * 2);
|
||||||
|
|
||||||
gfx_printf(&gfx_con, "%kBattery Fuel Gauge Registers:\n\n%k", 0xFF00DDFF, 0xFFCCCCCC);
|
gfx_printf(&gfx_con, "%k\n\nBattery Fuel Gauge Registers:\n%k", 0xFF00DDFF, 0xFFCCCCCC);
|
||||||
|
|
||||||
for (int i = 0; i < 0x200; i += 2)
|
for (int i = 0; i < 0x200; i += 2)
|
||||||
{
|
{
|
||||||
i2c_recv_buf_small(buf + i, 2, I2C_1, 0x36, i >> 1);
|
i2c_recv_buf_small(buf + i, 2, I2C_1, 0x36, i >> 1);
|
||||||
sleep(5000);
|
sleep(2500);
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx_hexdump(&gfx_con, 0, (u8 *)buf, 0x200);
|
gfx_hexdump(&gfx_con, 0, (u8 *)buf, 0x200);
|
||||||
|
@ -1536,6 +1671,7 @@ void print_fuel_gauge_regs()
|
||||||
if (sd_mount())
|
if (sd_mount())
|
||||||
{
|
{
|
||||||
char fuelFilename[28];
|
char fuelFilename[28];
|
||||||
|
f_mkdir("Backup");
|
||||||
f_mkdir("Backup/Dumps");
|
f_mkdir("Backup/Dumps");
|
||||||
memcpy(fuelFilename, "Backup/Dumps/fuel_gauge.bin\0", 28);
|
memcpy(fuelFilename, "Backup/Dumps/fuel_gauge.bin\0", 28);
|
||||||
|
|
||||||
|
@ -1714,7 +1850,7 @@ ment_t ment_cinfo[] = {
|
||||||
MDEF_HANDLER("Print SD Card info", print_sdcard_info),
|
MDEF_HANDLER("Print SD Card info", print_sdcard_info),
|
||||||
MDEF_CHGLINE(),
|
MDEF_CHGLINE(),
|
||||||
MDEF_CAPTION("------ Misc ------", 0xFF0AB9E6),
|
MDEF_CAPTION("------ Misc ------", 0xFF0AB9E6),
|
||||||
MDEF_HANDLER("Print fuel gauge info", print_fuel_gauge_regs),
|
MDEF_HANDLER("Print battery info", print_battery_info),
|
||||||
MDEF_END()
|
MDEF_END()
|
||||||
};
|
};
|
||||||
menu_t menu_cinfo = {
|
menu_t menu_cinfo = {
|
||||||
|
@ -1791,7 +1927,7 @@ ment_t ment_tools[] = {
|
||||||
MDEF_HANDLER("Dump package1", dump_package1),
|
MDEF_HANDLER("Dump package1", dump_package1),
|
||||||
MDEF_HANDLER("Fix SD files attributes", fix_sd_attr),
|
MDEF_HANDLER("Fix SD files attributes", fix_sd_attr),
|
||||||
MDEF_HANDLER("Fix battery de-sync", fix_battery_desync),
|
MDEF_HANDLER("Fix battery de-sync", fix_battery_desync),
|
||||||
//MDEF_MENU("Fix fuel gauge configuration", &fix_fuel_gauge_configuration),
|
//MDEF_HANDLER("Fix fuel gauge configuration", fix_fuel_gauge_configuration),
|
||||||
MDEF_CHGLINE(),
|
MDEF_CHGLINE(),
|
||||||
MDEF_CAPTION("------ Dangerous -----", 0xFFFF0000),
|
MDEF_CAPTION("------ Dangerous -----", 0xFFFF0000),
|
||||||
MDEF_MENU("AutoRCM", &menu_autorcm),
|
MDEF_MENU("AutoRCM", &menu_autorcm),
|
||||||
|
|
243
ipl/max17050.c
243
ipl/max17050.c
|
@ -38,190 +38,83 @@
|
||||||
#define STATUS_SMX_BIT (1 << 14)
|
#define STATUS_SMX_BIT (1 << 14)
|
||||||
#define STATUS_BR_BIT (1 << 15)
|
#define STATUS_BR_BIT (1 << 15)
|
||||||
|
|
||||||
/* Interrupt mask bits */
|
|
||||||
#define CONFIG_ALRT_BIT_ENBL (1 << 2)
|
|
||||||
#define STATUS_INTR_SOCMIN_BIT (1 << 10)
|
|
||||||
#define STATUS_INTR_SOCMAX_BIT (1 << 14)
|
|
||||||
|
|
||||||
#define VFSOC0_LOCK 0x0000
|
#define VFSOC0_LOCK 0x0000
|
||||||
#define VFSOC0_UNLOCK 0x0080
|
#define VFSOC0_UNLOCK 0x0080
|
||||||
|
|
||||||
#define dP_ACC_100 0x1900
|
|
||||||
#define dP_ACC_200 0x3200
|
|
||||||
|
|
||||||
#define MAX17050_VMAX_TOLERANCE 50 /* 50 mV */
|
#define MAX17050_VMAX_TOLERANCE 50 /* 50 mV */
|
||||||
|
|
||||||
static int _max17050_get_temperature(int *temp)
|
|
||||||
{
|
|
||||||
u16 data;
|
|
||||||
|
|
||||||
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_TEMP);
|
|
||||||
|
|
||||||
*temp = (s16)data;
|
|
||||||
/* The value is converted into deci-centigrade scale */
|
|
||||||
/* Units of LSB = 1 / 256 degree Celsius */
|
|
||||||
*temp = *temp * 10 / 256;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _max17050_get_status(int *status)
|
|
||||||
{
|
|
||||||
int charge_full, charge_now;
|
|
||||||
int avg_current;
|
|
||||||
u16 data;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The MAX170xx has builtin end-of-charge detection and will update
|
|
||||||
* FullCAP to match RepCap when it detects end of charging.
|
|
||||||
*
|
|
||||||
* When this cycle the battery gets charged to a higher (calculated)
|
|
||||||
* capacity then the previous cycle then FullCAP will get updated
|
|
||||||
* contineously once end-of-charge detection kicks in, so allow the
|
|
||||||
* 2 to differ a bit.
|
|
||||||
*/
|
|
||||||
|
|
||||||
i2c_recv_buf_small((u8 *)&charge_full, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_FullCAP);
|
|
||||||
|
|
||||||
i2c_recv_buf_small((u8 *)&charge_now, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_RepCap);
|
|
||||||
|
|
||||||
if ((charge_full - charge_now) <= MAX17050_FULL_THRESHOLD) {
|
|
||||||
*status = 0xFF; //FULL
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Even though we are supplied, we may still be discharging if the
|
|
||||||
* supply is e.g. only delivering 5V 0.5A. Check current if available.
|
|
||||||
*/
|
|
||||||
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_AvgCurrent);
|
|
||||||
|
|
||||||
avg_current = (s16)data;
|
|
||||||
avg_current *= 1562500 / MAX17050_DEFAULT_SNS_RESISTOR;
|
|
||||||
|
|
||||||
if (avg_current > 0)
|
|
||||||
*status = 0x1; //Charging
|
|
||||||
else
|
|
||||||
*status = 0x0; //Discharging
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _max17050_get_battery_health(int *health)
|
|
||||||
{
|
|
||||||
int temp, vavg, vbatt;
|
|
||||||
u16 val;
|
|
||||||
|
|
||||||
i2c_recv_buf_small((u8 *)&val, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_AvgVCELL);
|
|
||||||
/* bits [0-3] unused */
|
|
||||||
vavg = val * 625 / 8;
|
|
||||||
/* Convert to millivolts */
|
|
||||||
vavg /= 1000;
|
|
||||||
|
|
||||||
i2c_recv_buf_small((u8 *)&val, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_VCELL);
|
|
||||||
/* bits [0-3] unused */
|
|
||||||
vbatt = val * 625 / 8;
|
|
||||||
/* Convert to millivolts */
|
|
||||||
vbatt /= 1000;
|
|
||||||
|
|
||||||
if (vavg < MAX17050_DEFAULT_VMIN) {
|
|
||||||
*health = HEALTH_DEAD;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vbatt > MAX17050_DEFAULT_VMAX + MAX17050_VMAX_TOLERANCE) {
|
|
||||||
*health = HEALTH_OVERVOLTAGE;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
_max17050_get_temperature(&temp);
|
|
||||||
|
|
||||||
if (temp < MAX17050_DEFAULT_TEMP_MIN) {
|
|
||||||
*health = HEALTH_COLD;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (temp > MAX17050_DEFAULT_TEMP_MAX) {
|
|
||||||
*health = HEALTH_OVERHEAT;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
*health = HEALTH_GOOD; // 1
|
|
||||||
|
|
||||||
out:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int max17050_get_property(enum MAX17050_reg reg, int *value)
|
int max17050_get_property(enum MAX17050_reg reg, int *value)
|
||||||
{
|
{
|
||||||
u16 data;
|
u16 data;
|
||||||
|
|
||||||
switch (reg) {
|
switch (reg)
|
||||||
//case 0x101://///////////////////////////FIX
|
{
|
||||||
// _max17050_get_status(value);
|
case MAX17050_Age: //Age (percent). Based on 100% x (FullCAP Register/DesignCap).
|
||||||
// break;
|
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_Age);
|
||||||
case MAX17050_Cycles: //Cycle count.
|
*value = data >> 8; /* Show MSB. 1% increments */
|
||||||
i2c_recv_buf_small((u8 *)value, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_Cycles);
|
break;
|
||||||
break;
|
case MAX17050_Cycles: //Cycle count.
|
||||||
case MAX17050_MinMaxVolt: //Voltage max/min
|
i2c_recv_buf_small((u8 *)value, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_Cycles);
|
||||||
i2c_recv_buf_small((u8 *)value, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_MinMaxVolt);
|
break;
|
||||||
//value = (data >> 8) * 20; /* Voltage MAX. Units of LSB = 20mV */
|
case MAX17050_MinVolt: //Voltage max/min
|
||||||
//value = (data & 0xff) * 20; /* Voltage MIN. Units of 20mV */
|
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_MinMaxVolt);
|
||||||
*value = data;
|
*value = (data & 0xff) * 20; /* Voltage MIN. Units of 20mV */
|
||||||
break;
|
break;
|
||||||
case MAX17050_V_empty: //Voltage min design.
|
case MAX17050_MaxVolt: //Voltage max/min
|
||||||
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_V_empty);
|
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_MinMaxVolt);
|
||||||
*value = (data >> 7) * 10; /* Units of LSB = 10mV */
|
*value = (data >> 8) * 20; /* Voltage MAX. Units of LSB = 20mV */
|
||||||
break;
|
break;
|
||||||
case MAX17050_VCELL: //Voltage now.
|
case MAX17050_V_empty: //Voltage min design.
|
||||||
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_VCELL);
|
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_V_empty);
|
||||||
*value = data * 625 / 8 / 1000;
|
*value = (data >> 7) * 10; /* Units of LSB = 10mV */
|
||||||
break;
|
break;
|
||||||
case MAX17050_AvgVCELL: //Voltage avg.
|
case MAX17050_VCELL: //Voltage now.
|
||||||
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_AvgVCELL);
|
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_VCELL);
|
||||||
*value = data * 625 / 8 / 1000;
|
*value = data * 625 / 8 / 1000;
|
||||||
break;
|
break;
|
||||||
case MAX17050_OCVInternal: //Voltage ocv.
|
case MAX17050_AvgVCELL: //Voltage avg.
|
||||||
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_OCVInternal);
|
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_AvgVCELL);
|
||||||
*value = data * 625 / 8 / 1000;
|
*value = data * 625 / 8 / 1000;
|
||||||
break;
|
break;
|
||||||
case MAX17050_RepSOC: //Capacity %.
|
case MAX17050_OCVInternal: //Voltage ocv.
|
||||||
i2c_recv_buf_small((u8 *)value, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_RepSOC);
|
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_OCVInternal);
|
||||||
break;
|
*value = data * 625 / 8 / 1000;
|
||||||
case MAX17050_DesignCap: //Charge full design.
|
break;
|
||||||
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_DesignCap);
|
case MAX17050_RepSOC: //Capacity %.
|
||||||
data = data * 5 / 10;
|
i2c_recv_buf_small((u8 *)value, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_RepSOC);
|
||||||
*value = data;
|
break;
|
||||||
break;
|
case MAX17050_DesignCap: //Charge full design.
|
||||||
case MAX17050_FullCAP: //Charge full.
|
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_DesignCap);
|
||||||
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_FullCAP);
|
data = data * 5 / 10;
|
||||||
data = data * 5 / 10;
|
*value = data;
|
||||||
*value = data;
|
break;
|
||||||
break;
|
case MAX17050_FullCAP: //Charge full.
|
||||||
case MAX17050_RepCap: //Charge now.
|
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_FullCAP);
|
||||||
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_RepCap);
|
data = data * 5 / 10;
|
||||||
data = data * 5 / 10;
|
*value = data;
|
||||||
*value = data;
|
break;
|
||||||
break;
|
case MAX17050_RepCap: //Charge now.
|
||||||
case MAX17050_TEMP: //Temp.
|
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_RepCap);
|
||||||
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_TEMP);
|
data = data * 5 / 10;
|
||||||
*value = (s16)(data);
|
*value = data;
|
||||||
*value = *value * 10 / 256;
|
break;
|
||||||
break;
|
case MAX17050_TEMP: //Temp.
|
||||||
//case 0x100: //FIX me
|
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_TEMP);
|
||||||
// _max17050_get_battery_health(value);
|
*value = (s16)data;
|
||||||
// break;
|
*value = *value * 10 / 256;
|
||||||
case MAX17050_Current: //Current now.
|
break;
|
||||||
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_Current);
|
case MAX17050_Current: //Current now.
|
||||||
*value = (s16)data;
|
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_Current);
|
||||||
*value *= 1562500 / MAX17050_DEFAULT_SNS_RESISTOR;
|
*value = (s16)data;
|
||||||
break;
|
*value *= 1562500 / MAX17050_DEFAULT_SNS_RESISTOR;
|
||||||
case MAX17050_AvgCurrent: //Current avg.
|
break;
|
||||||
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_AvgCurrent);
|
case MAX17050_AvgCurrent: //Current avg.
|
||||||
*value = (s16)data;
|
i2c_recv_buf_small((u8 *)&data, 2, I2C_1, MAXIM17050_I2C_ADDR, MAX17050_AvgCurrent);
|
||||||
*value *= 1562500 / MAX17050_DEFAULT_SNS_RESISTOR;
|
*value = (s16)data;
|
||||||
break;
|
*value *= 1562500 / MAX17050_DEFAULT_SNS_RESISTOR;
|
||||||
default:
|
break;
|
||||||
return -1;
|
default:
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,12 +25,7 @@
|
||||||
#define __MAX17050_H_
|
#define __MAX17050_H_
|
||||||
|
|
||||||
#define MAX17050_STATUS_BattAbsent (1 << 3)
|
#define MAX17050_STATUS_BattAbsent (1 << 3)
|
||||||
#define MAX17050_BATTERY_FULL 95 /* Recommend. FullSOCThr value */
|
|
||||||
#define MAX17050_DEFAULT_SNS_RESISTOR 10000
|
#define MAX17050_DEFAULT_SNS_RESISTOR 10000
|
||||||
#define MAX17050_DEFAULT_VMIN 3200
|
|
||||||
#define MAX17050_DEFAULT_VMAX 4200 /* LiHV cell max */
|
|
||||||
#define MAX17050_DEFAULT_TEMP_MIN 5 /* For sys without temp sensor */
|
|
||||||
#define MAX17050_DEFAULT_TEMP_MAX 650 /* 65 degrees Celcius */
|
|
||||||
|
|
||||||
/* Consider RepCap which is less then 10 units below FullCAP full */
|
/* Consider RepCap which is less then 10 units below FullCAP full */
|
||||||
#define MAX17050_FULL_THRESHOLD 10
|
#define MAX17050_FULL_THRESHOLD 10
|
||||||
|
@ -112,6 +107,9 @@ enum MAX17050_reg {
|
||||||
MAX17050_QH = 0x4D,
|
MAX17050_QH = 0x4D,
|
||||||
MAX17050_QL = 0x4E,
|
MAX17050_QL = 0x4E,
|
||||||
|
|
||||||
|
MAX17050_MinVolt = 0x50, // Custom ID. Not to be sent to i2c.
|
||||||
|
MAX17050_MaxVolt = 0x51, // Custom ID. Not to be sent to i2c.
|
||||||
|
|
||||||
MAX17050_VFSOC0Enable = 0x60,
|
MAX17050_VFSOC0Enable = 0x60,
|
||||||
|
|
||||||
MAX17050_MODELChrTbl = 0x80,
|
MAX17050_MODELChrTbl = 0x80,
|
||||||
|
@ -123,15 +121,6 @@ enum MAX17050_reg {
|
||||||
MAX17050_VFSOC = 0xFF,
|
MAX17050_VFSOC = 0xFF,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
|
||||||
HEALTH_UNKNOWN = 0,
|
|
||||||
HEALTH_GOOD,
|
|
||||||
HEALTH_OVERHEAT,
|
|
||||||
HEALTH_DEAD,
|
|
||||||
HEALTH_OVERVOLTAGE,
|
|
||||||
HEALTH_COLD,
|
|
||||||
};
|
|
||||||
|
|
||||||
int max17050_get_property(enum MAX17050_reg reg, int *value);
|
int max17050_get_property(enum MAX17050_reg reg, int *value);
|
||||||
int max17050_fix_configuration();
|
int max17050_fix_configuration();
|
||||||
|
|
||||||
|
|
|
@ -121,7 +121,7 @@ void *tui_do_menu(gfx_con_t *con, menu_t *menu)
|
||||||
max17050_get_property(MAX17050_VCELL, &battVoltCurr);
|
max17050_get_property(MAX17050_VCELL, &battVoltCurr);
|
||||||
gfx_printf(con, " (%d mV) ", battVoltCurr);
|
gfx_printf(con, " (%d mV) ", battVoltCurr);
|
||||||
max17050_get_property(MAX17050_AvgCurrent, &battVoltCurr);
|
max17050_get_property(MAX17050_AvgCurrent, &battVoltCurr);
|
||||||
if (battVoltCurr > 0)
|
if (battVoltCurr >= 0)
|
||||||
gfx_printf(con, "\n %kCharging:%k %d mA %k\n",
|
gfx_printf(con, "\n %kCharging:%k %d mA %k\n",
|
||||||
0xFF008000, 0xFF555555, battVoltCurr / 1000, 0xFFCCCCCC);
|
0xFF008000, 0xFF555555, battVoltCurr / 1000, 0xFFCCCCCC);
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in a new issue