1
0
Fork 0
forked from len0rd/rockbox

Gigabeat S: Add some sanity checks for a strange charging anomaly that I have personally witnessed twice-- no, I don't have photos or a YT video but it did happen. Details are given in a comment in powermgmt-imx31.c. If it happens again, the checks may serve to reveal the true cause.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25524 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Michael Sevakis 2010-04-07 19:59:26 +00:00
parent 94b63c5b19
commit b3d44fcb57
2 changed files with 78 additions and 29 deletions

View file

@ -379,42 +379,77 @@ static bool adjust_charger_current(void)
if (charger_setting != 0) if (charger_setting != 0)
{ {
charging_set_thread_priority(true); if ((charger_setting & MC13783_VCHRG) > BATTERY_VCHARGING ||
(charger_setting & MC13783_ICHRG) > BATTERY_IFAST)
/* Turn regulator logically ON. Hardware may still override. */
i = mc13783_write_masked(MC13783_CHARGER,
charger_setting | MC13783_CHRGRAWPDEN,
MC13783_ICHRG | MC13783_VCHRG |
MC13783_CHRGRAWPDEN);
if (i != MC13783_DATA_ERROR)
{ {
int icharger; /* Table is corrupted somehow. We shouldn't run at all.
*
/* Enable charge current conversion */ * Explanation: On two occasions, even though this driver monitors
adc_enable_channel(ADC_CHARGER_CURRENT, true); * the regulator register settings on each step and
* ensures that only valid table indexes are used,
/* Charge path regulator turn on takes ~100ms max. */ * the current and voltage seem to be misregulated,
sleep(HZ/10); * resulting in excessively high battery voltage that
* will trip the battery protection. After careful
icharger = stat_battery_reading(ADC_CHARGER_CURRENT); * review it seems that two possibilities exist:
* This code or data got trashed at some point or
if (icharger != INT_MIN) * there really is a hardware bug of some sort. So
{ * far the cause is unknown. Voltage is also
icharger_ave = icharger * ICHARGER_AVE_SAMPLES; * monitored in the CHARGING case for that reason.
* The solution for data or code corruption is to
if (update_filtered_battery_voltage()) * just panic and refuse to run the device. The
return true; * solution for overvoltage due to hardware bug is to
} * disable the charging. The action taken will reveal
* the true cause, thus _who_ is responsible.
* "Burning lithium is baaaad", so sayeth The Council
* of Seven Ascended Masters. */
charge_state = CHARGE_STATE_DISABLED;
service_wdt = false;
} }
else
{
/* Turn on 5K pulldown. */
i = mc13783_set(MC13783_CHARGER, MC13783_CHRGRAWPDEN);
/* Force regulator OFF. */ if (i != MC13783_DATA_ERROR)
charge_state = CHARGE_STATE_ERROR; {
charging_set_thread_priority(true);
/* Turn regulator logically ON. Hardware may still override.
*/
i = mc13783_write_masked(MC13783_CHARGER, charger_setting,
MC13783_ICHRG | MC13783_VCHRG);
if (i != MC13783_DATA_ERROR)
{
int icharger;
/* Enable charge current conversion */
adc_enable_channel(ADC_CHARGER_CURRENT, true);
/* Charge path regulator turn on takes ~100ms max. */
sleep(HZ/10);
icharger = stat_battery_reading(ADC_CHARGER_CURRENT);
if (icharger != INT_MIN)
{
icharger_ave = icharger * ICHARGER_AVE_SAMPLES;
if (update_filtered_battery_voltage())
return true;
}
}
}
/* Force regulator OFF. */
charge_state = CHARGE_STATE_ERROR;
}
} }
/* Turn regulator OFF. */ /* Turn regulator OFF. */
icharger_ave = 0; icharger_ave = 0;
i = mc13783_write_masked(MC13783_CHARGER, charger_bits[0][0], i = mc13783_write_masked(MC13783_CHARGER,
MC13783_ICHRG_0MA | MC13783_VCHRG_4_050V,
MC13783_ICHRG | MC13783_VCHRG | MC13783_ICHRG | MC13783_VCHRG |
MC13783_CHRGRAWPDEN); MC13783_CHRGRAWPDEN);
@ -533,6 +568,16 @@ static bool charging_ok(void)
if (charger_setting != 0) if (charger_setting != 0)
{ {
if (ok)
{
/* Protect against any conceivable overcharge/voltage condition
* before hardware protection must intervene. Disable charger
* until reboot. */
ok = battery_voltage() < BATT_TOO_HIGH;
if (!ok)
charge_state = CHARGE_STATE_DISABLED;
}
if (ok) if (ok)
{ {
/* Watch to not overheat FET (nothing should go over about 1012.7mW). /* Watch to not overheat FET (nothing should go over about 1012.7mW).

View file

@ -59,6 +59,10 @@
#define BATT_USB_VSTOP 4140 /* When to "stop" when USB only */ #define BATT_USB_VSTOP 4140 /* When to "stop" when USB only */
#define BATT_TOO_LOW 2400 /* No battery? Short? Can't #define BATT_TOO_LOW 2400 /* No battery? Short? Can't
read below 2400mV. */ read below 2400mV. */
#define BATT_TOO_HIGH 4220 /* Extra care. Don't totally
rely upon battery protection
circutry. Stop it early if too
high. */
#define CHARGER_TOTAL_TIMER 300 /* minutes */ #define CHARGER_TOTAL_TIMER 300 /* minutes */
/* Temperature readings - w/hysteresis */ /* Temperature readings - w/hysteresis */