diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2010-04-07 19:59:26 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2010-04-07 19:59:26 +0000 |
commit | b3d44fcb57173b7995bf67a88aa24aa447f74f52 (patch) | |
tree | ff576a5be237c00eb6ac6f2221d89a7e9909c5bb | |
parent | 94b63c5b19552a31b9f7906eb2ef9ac81b897a4a (diff) | |
download | rockbox-b3d44fcb57173b7995bf67a88aa24aa447f74f52.tar.gz rockbox-b3d44fcb57173b7995bf67a88aa24aa447f74f52.zip |
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
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/powermgmt-imx31.c | 91 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/powermgmt-target.h | 4 |
2 files changed, 72 insertions, 23 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/powermgmt-imx31.c b/firmware/target/arm/imx31/gigabeat-s/powermgmt-imx31.c index 6986a0605d..bb9b8c23af 100644 --- a/firmware/target/arm/imx31/gigabeat-s/powermgmt-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/powermgmt-imx31.c | |||
@@ -379,42 +379,77 @@ static bool adjust_charger_current(void) | |||
379 | 379 | ||
380 | if (charger_setting != 0) | 380 | if (charger_setting != 0) |
381 | { | 381 | { |
382 | charging_set_thread_priority(true); | 382 | if ((charger_setting & MC13783_VCHRG) > BATTERY_VCHARGING || |
383 | (charger_setting & MC13783_ICHRG) > BATTERY_IFAST) | ||
384 | { | ||
385 | /* Table is corrupted somehow. We shouldn't run at all. | ||
386 | * | ||
387 | * Explanation: On two occasions, even though this driver monitors | ||
388 | * the regulator register settings on each step and | ||
389 | * ensures that only valid table indexes are used, | ||
390 | * the current and voltage seem to be misregulated, | ||
391 | * resulting in excessively high battery voltage that | ||
392 | * will trip the battery protection. After careful | ||
393 | * review it seems that two possibilities exist: | ||
394 | * This code or data got trashed at some point or | ||
395 | * there really is a hardware bug of some sort. So | ||
396 | * far the cause is unknown. Voltage is also | ||
397 | * monitored in the CHARGING case for that reason. | ||
398 | * The solution for data or code corruption is to | ||
399 | * just panic and refuse to run the device. The | ||
400 | * solution for overvoltage due to hardware bug is to | ||
401 | * disable the charging. The action taken will reveal | ||
402 | * the true cause, thus _who_ is responsible. | ||
403 | * "Burning lithium is baaaad", so sayeth The Council | ||
404 | * of Seven Ascended Masters. */ | ||
405 | charge_state = CHARGE_STATE_DISABLED; | ||
406 | service_wdt = false; | ||
407 | } | ||
408 | else | ||
409 | { | ||
410 | /* Turn on 5K pulldown. */ | ||
411 | i = mc13783_set(MC13783_CHARGER, MC13783_CHRGRAWPDEN); | ||
383 | 412 | ||
384 | /* Turn regulator logically ON. Hardware may still override. */ | 413 | if (i != MC13783_DATA_ERROR) |
385 | i = mc13783_write_masked(MC13783_CHARGER, | 414 | { |
386 | charger_setting | MC13783_CHRGRAWPDEN, | 415 | charging_set_thread_priority(true); |
387 | MC13783_ICHRG | MC13783_VCHRG | | ||
388 | MC13783_CHRGRAWPDEN); | ||
389 | 416 | ||
390 | if (i != MC13783_DATA_ERROR) | 417 | /* Turn regulator logically ON. Hardware may still override. |
391 | { | 418 | */ |
392 | int icharger; | 419 | i = mc13783_write_masked(MC13783_CHARGER, charger_setting, |
420 | MC13783_ICHRG | MC13783_VCHRG); | ||
393 | 421 | ||
394 | /* Enable charge current conversion */ | 422 | if (i != MC13783_DATA_ERROR) |
395 | adc_enable_channel(ADC_CHARGER_CURRENT, true); | 423 | { |
424 | int icharger; | ||
396 | 425 | ||
397 | /* Charge path regulator turn on takes ~100ms max. */ | 426 | /* Enable charge current conversion */ |
398 | sleep(HZ/10); | 427 | adc_enable_channel(ADC_CHARGER_CURRENT, true); |
399 | 428 | ||
400 | icharger = stat_battery_reading(ADC_CHARGER_CURRENT); | 429 | /* Charge path regulator turn on takes ~100ms max. */ |
430 | sleep(HZ/10); | ||
401 | 431 | ||
402 | if (icharger != INT_MIN) | 432 | icharger = stat_battery_reading(ADC_CHARGER_CURRENT); |
403 | { | 433 | |
404 | icharger_ave = icharger * ICHARGER_AVE_SAMPLES; | 434 | if (icharger != INT_MIN) |
435 | { | ||
436 | icharger_ave = icharger * ICHARGER_AVE_SAMPLES; | ||
405 | 437 | ||
406 | if (update_filtered_battery_voltage()) | 438 | if (update_filtered_battery_voltage()) |
407 | return true; | 439 | return true; |
440 | } | ||
441 | } | ||
408 | } | 442 | } |
409 | } | ||
410 | 443 | ||
411 | /* Force regulator OFF. */ | 444 | /* Force regulator OFF. */ |
412 | charge_state = CHARGE_STATE_ERROR; | 445 | charge_state = CHARGE_STATE_ERROR; |
446 | } | ||
413 | } | 447 | } |
414 | 448 | ||
415 | /* Turn regulator OFF. */ | 449 | /* Turn regulator OFF. */ |
416 | icharger_ave = 0; | 450 | icharger_ave = 0; |
417 | i = mc13783_write_masked(MC13783_CHARGER, charger_bits[0][0], | 451 | i = mc13783_write_masked(MC13783_CHARGER, |
452 | MC13783_ICHRG_0MA | MC13783_VCHRG_4_050V, | ||
418 | MC13783_ICHRG | MC13783_VCHRG | | 453 | MC13783_ICHRG | MC13783_VCHRG | |
419 | MC13783_CHRGRAWPDEN); | 454 | MC13783_CHRGRAWPDEN); |
420 | 455 | ||
@@ -535,6 +570,16 @@ static bool charging_ok(void) | |||
535 | { | 570 | { |
536 | if (ok) | 571 | if (ok) |
537 | { | 572 | { |
573 | /* Protect against any conceivable overcharge/voltage condition | ||
574 | * before hardware protection must intervene. Disable charger | ||
575 | * until reboot. */ | ||
576 | ok = battery_voltage() < BATT_TOO_HIGH; | ||
577 | if (!ok) | ||
578 | charge_state = CHARGE_STATE_DISABLED; | ||
579 | } | ||
580 | |||
581 | if (ok) | ||
582 | { | ||
538 | /* Watch to not overheat FET (nothing should go over about 1012.7mW). | 583 | /* Watch to not overheat FET (nothing should go over about 1012.7mW). |
539 | * Trying a higher voltage AC adapter can work (up to 6.90V) but | 584 | * Trying a higher voltage AC adapter can work (up to 6.90V) but |
540 | * we'll just reject that. Reducing current for adapters that bring | 585 | * we'll just reject that. Reducing current for adapters that bring |
diff --git a/firmware/target/arm/imx31/gigabeat-s/powermgmt-target.h b/firmware/target/arm/imx31/gigabeat-s/powermgmt-target.h index 86278bce73..02d94015a1 100644 --- a/firmware/target/arm/imx31/gigabeat-s/powermgmt-target.h +++ b/firmware/target/arm/imx31/gigabeat-s/powermgmt-target.h | |||
@@ -59,6 +59,10 @@ | |||
59 | #define BATT_USB_VSTOP 4140 /* When to "stop" when USB only */ | 59 | #define BATT_USB_VSTOP 4140 /* When to "stop" when USB only */ |
60 | #define BATT_TOO_LOW 2400 /* No battery? Short? Can't | 60 | #define BATT_TOO_LOW 2400 /* No battery? Short? Can't |
61 | read below 2400mV. */ | 61 | read below 2400mV. */ |
62 | #define BATT_TOO_HIGH 4220 /* Extra care. Don't totally | ||
63 | rely upon battery protection | ||
64 | circutry. Stop it early if too | ||
65 | high. */ | ||
62 | #define CHARGER_TOTAL_TIMER 300 /* minutes */ | 66 | #define CHARGER_TOTAL_TIMER 300 /* minutes */ |
63 | 67 | ||
64 | /* Temperature readings - w/hysteresis */ | 68 | /* Temperature readings - w/hysteresis */ |