summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx31
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2010-04-07 19:59:26 +0000
committerMichael Sevakis <jethead71@rockbox.org>2010-04-07 19:59:26 +0000
commitb3d44fcb57173b7995bf67a88aa24aa447f74f52 (patch)
treeff576a5be237c00eb6ac6f2221d89a7e9909c5bb /firmware/target/arm/imx31
parent94b63c5b19552a31b9f7906eb2ef9ac81b897a4a (diff)
downloadrockbox-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
Diffstat (limited to 'firmware/target/arm/imx31')
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/powermgmt-imx31.c91
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/powermgmt-target.h4
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 */