summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDana Conrad <dconrad@fastmail.com>2024-12-30 03:16:20 +0000
committerSolomon Peachy <pizza@shaftnet.org>2025-01-01 20:49:07 -0500
commitf2dd48912045f09a44df7d6b058624d3a1d3d676 (patch)
tree2d195507e125ff58816820b2166a4f38683e299a
parentd038aa47fef0238f4a4c24d0f533982fa0944f98 (diff)
downloadrockbox-f2dd489120.tar.gz
rockbox-f2dd489120.zip
FS#13535: AXP2101: ADC / reporting improvements
Improve ADC behavior, add correct conversion for die temperature, add readout of EGauge to debug screen. Add delay to give ADC time to get a good reading. Initial reading may still be 1-3% optimistic, which is probably ok. EGauge appears to be pretty good, but no great need to convert to using it either. Change-Id: Iab9d50e2427f656ad0875f9a623b03545fc69881
-rw-r--r--firmware/drivers/axp-2101.c45
-rw-r--r--firmware/target/mips/ingenic_x1000/erosqnative/power-erosqnative.c11
2 files changed, 36 insertions, 20 deletions
diff --git a/firmware/drivers/axp-2101.c b/firmware/drivers/axp-2101.c
index 74a302f1b7..b2187d3274 100644
--- a/firmware/drivers/axp-2101.c
+++ b/firmware/drivers/axp-2101.c
@@ -57,17 +57,16 @@ struct axp_supply_info {
};
static const struct axp_adc_info axp_adc_info[AXP2101_NUM_ADC_CHANNELS] = {
- // TODO: Datasheet ADC conversion table doesn't seem to make any sense...
- // 0x000 0x001 0x002 ... 0xFFF
+ // 0x000 0x001 0x002 ... 0x1FFF
// 0mV 1mV 2mV ... 8.192V
[AXP2101_ADC_VBAT_VOLTAGE] = {AXP2101_REG_ADC_VBAT_H, AXP2101_REG_ADCCHNENABLE, 1 << 0, 1, 1},
// 0mV 1mV 2mV ... 8.192V
[AXP2101_ADC_VBUS_VOLTAGE] = {AXP2101_REG_ADC_VBUS_H, AXP2101_REG_ADCCHNENABLE, 1 << 2, 1, 1},
// 0mV 1mV 2mV ... 8.192V
[AXP2101_ADC_VSYS_VOLTAGE] = {AXP2101_REG_ADC_VSYS_H, AXP2101_REG_ADCCHNENABLE, 1 << 3, 1, 1},
- // 0mV 0.5mV 1mV ... 4.096V
- [AXP2101_ADC_TS_VOLTAGE] = {AXP2101_REG_ADC_TS_H, AXP2101_REG_ADCCHNENABLE, 1 << 1, 1, 1},
- // 0mV 0.1mV 2mV ... 0.8192V
+ // 0mV 0.5mV 0.1mV ... 4.096V
+ [AXP2101_ADC_TS_VOLTAGE] = {AXP2101_REG_ADC_TS_H, AXP2101_REG_ADCCHNENABLE, 1 << 1, 1, 2},
+ // see axp2101_adc_conv_raw() for conversion
[AXP2101_ADC_DIE_TEMPERATURE] = {AXP2101_REG_ADC_TDIE_H, AXP2101_REG_ADCCHNENABLE, 1 << 4, 1, 1},
};
@@ -309,7 +308,7 @@ void axp2101_supply_set_voltage(int supply, int voltage)
if(voltage > 0 && info->step_mV != 0) {
if(voltage < info->min_mV)
return;
-
+
int regval;
// there's probably a more elegant way to do this...
@@ -446,11 +445,20 @@ int axp2101_adc_read_raw(int adc)
return INT_MIN;
/* Parse the value */
- return ((buf[0] & 0x3f) << 8) | (buf[1] & 0xff);
+ return ((int)(buf[0] & 0x3f) << 8) | (buf[1] & 0xff);
}
int axp2101_adc_conv_raw(int adc, int value)
{
+ if (adc == AXP2101_ADC_DIE_TEMPERATURE)
+ return 22 + ((7274 - value) / 20);
+
+ // seems to be a signed 14-bit value, but
+ // let's clamp it to zero. Seems to give sane results
+ // on v_bus and v_ts channels
+ if (value & 0x2000)
+ return 0;
+
return axp_adc_info[adc].num * value / axp_adc_info[adc].den;
}
@@ -472,12 +480,12 @@ void axp2101_adc_set_enabled(int adc_bits)
i2c_reg_write(AXP_PMU_BUS, AXP_PMU_ADDR, AXP2101_REG_ADCCHNENABLE, 1, &xfer[0]);
}
-// TODO: See if we can figure out "optimum" battery chemistry-type settings
-// like constant-current charging, charge curves... that stuff is all configurable
-// as far as I can tell! Probably important to at least figure out if the defaults
-// are clearly wrong or not!
-
-// TODO: what are DATA_BUFFER 0-3 for????
+int axp2101_egauge_read(void)
+{
+ uint8_t buf;
+ i2c_reg_read(AXP_PMU_BUS, AXP_PMU_ADDR, AXP2101_REG_BATT_PERCENTAGE, 1, &buf);
+ return (int)buf;
+}
// there are many current settings:
// Reg 16: Input current limit control
@@ -534,6 +542,7 @@ enum {
AXP_DEBUG_BATTERY_STATUS,
AXP_DEBUG_INPUT_STATUS,
AXP_DEBUG_CHARGE_CURRENT,
+ AXP_DEBUG_EGAUGE_VALUE,
AXP_DEBUG_FIRST_ADC,
AXP_DEBUG_FIRST_SUPPLY = AXP_DEBUG_FIRST_ADC + AXP2101_NUM_ADC_CHANNELS,
AXP_DEBUG_NUM_ENTRIES = AXP_DEBUG_FIRST_SUPPLY + AXP2101_NUM_SUPPLIES,
@@ -555,11 +564,11 @@ static const char* axp2101_debug_menu_get_name(int item, void* data,
(void)data;
static const char* const adc_names[] = {
- "V_bat", "V_bus", "V_sys", "V_ts", "V_die",
+ "V_bat", "V_bus", "V_sys", "V_ts", "T_die",
};
static const char* const adc_units[] = {
- "mV", "mV", "mV", "mV", "C*100",
+ "mV", "mV", "mV", "mV", "C",
};
static const char* const supply_names[] = {
@@ -625,6 +634,12 @@ static const char* axp2101_debug_menu_get_name(int item, void* data,
return buf;
} break;
+ case AXP_DEBUG_EGAUGE_VALUE: {
+ int percent = axp2101_egauge_read();
+ snprintf(buf, buflen, "EGauge percent: %d", percent);
+ return buf;
+ } break;
+
default:
return "---";
}
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/power-erosqnative.c b/firmware/target/mips/ingenic_x1000/erosqnative/power-erosqnative.c
index 5dad78392e..0f9eb3fcd0 100644
--- a/firmware/target/mips/ingenic_x1000/erosqnative/power-erosqnative.c
+++ b/firmware/target/mips/ingenic_x1000/erosqnative/power-erosqnative.c
@@ -97,10 +97,6 @@ void power_init(void)
}
// These match the OF as far as I can discern
- // TODO: These values are set in EFUSE apparently, could
- // do a "check then set if necessary"...
- // Also if we had a fresh device we could verify what
- // the OF sets.
axp2101_supply_set_voltage(AXP2101_SUPPLY_DCDC1, 3300);
axp2101_supply_set_voltage(AXP2101_SUPPLY_DCDC2, 1200);
axp2101_supply_set_voltage(AXP2101_SUPPLY_DCDC3, 2800);
@@ -123,6 +119,12 @@ void power_init(void)
/* Set the default charging current. This is the same as the
* OF's setting, although it's not strictly within the USB spec. */
axp2101_set_charge_current(780);
+
+ /* delay to allow ADC to get a good sample -
+ * may give bogus (high) readings otherwise. */
+#ifndef BOOTLOADER
+ mdelay(150);
+#endif
} else {
axp_init();
/* Set lowest sample rate */
@@ -138,7 +140,6 @@ void power_init(void)
(1 << ADC_INTERNAL_TEMP) |
(1 << ADC_APS_VOLTAGE));
- /* TODO: Set Output Voltages! */
i2c_reg_modify1(AXP_PMU_BUS, AXP_PMU_ADDR,
AXP_REG_PWROUTPUTCTRL2, 0, 0x5f, NULL);
i2c_reg_modify1(AXP_PMU_BUS, AXP_PMU_ADDR,