diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2016-05-02 21:49:13 +0100 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2016-05-28 16:21:03 +0100 |
commit | 941ac165d864ccdd4e4ae870366f4e0a6bc30055 (patch) | |
tree | d0030c16f10321833f383baafaf3b78610951526 /firmware | |
parent | d245b7a2a1113b6dbdbfb10f5ee984a00c987844 (diff) |
imx233: speedup charging trickle phase
Per Freescale recommandation, we need to ramp up the 4.2V rail before enabling
charging. Ramping should be done at 1 step/10ms, but the old code did 1 step/1s
because the powermgmt_step() function is called once every second. Use a tick
task to ramp up much faster.
Change-Id: I9a52bdd0c2ba5426d83ed42db8db7ecce2fea1f7
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/target/arm/imx233/debug-imx233.c | 1 | ||||
-rw-r--r-- | firmware/target/arm/imx233/powermgmt-imx233.c | 45 | ||||
-rw-r--r-- | firmware/target/arm/imx233/powermgmt-imx233.h | 1 |
3 files changed, 27 insertions, 20 deletions
diff --git a/firmware/target/arm/imx233/debug-imx233.c b/firmware/target/arm/imx233/debug-imx233.c index fa913a9532..c1820c8fe2 100644 --- a/firmware/target/arm/imx233/debug-imx233.c +++ b/firmware/target/arm/imx233/debug-imx233.c @@ -407,7 +407,6 @@ bool dbg_hw_info_powermgmt(void) "<unknown>"); lcd_putsf(0, 1, "charging tmo: %d", info.charging_timeout); lcd_putsf(0, 2, "topoff tmo: %d", info.topoff_timeout); - lcd_putsf(0, 3, "4p2ilimit tmo: %d", info.incr_4p2_ilimit_timeout); lcd_update(); yield(); diff --git a/firmware/target/arm/imx233/powermgmt-imx233.c b/firmware/target/arm/imx233/powermgmt-imx233.c index 50ab8451bb..2706ee99fa 100644 --- a/firmware/target/arm/imx233/powermgmt-imx233.c +++ b/firmware/target/arm/imx233/powermgmt-imx233.c @@ -39,7 +39,6 @@ /* charger state is maintained in charge_state (see powermgmt.h) */ static int timeout_charging; /* timeout before charging will be declared broken */ static int timeout_topping_off; /* timeout before stopping charging after topping off */ -static int timeout_4p2_ilimit_increase; /* timeout before increasing 4p2 ilimit */ /* Returns battery voltage from ADC [millivolts] */ int _battery_voltage(void) @@ -69,9 +68,24 @@ void imx233_powermgmt_init(void) #endif } +#define MAX_4P2_ILIMIT 0x3f + +/* The code below assumes HZ = 100 so that it runs every 10ms */ +#if HZ != 100 +#warning The ramp_up_4p2_rail() tick task assumes HZ = 100, this may break charging +#endif + +static void ramp_up_4p2_rail(void) +{ + /* only ramp up in the TRICKLE state and if we haven't reached the maximum yet */ + if(charge_state == TRICKLE && BF_RD(POWER_5VCTRL, CHARGE_4P2_ILIMIT) < MAX_4P2_ILIMIT) + HW_POWER_5VCTRL += BF_POWER_5VCTRL_CHARGE_4P2_ILIMIT(1); +} + void powermgmt_init_target(void) { charge_state = DISCHARGING; + tick_add_task(&ramp_up_4p2_rail); } void charging_algorithm_step(void) @@ -84,15 +98,15 @@ void charging_algorithm_step(void) { logf("pwrmgmt: * -> discharging"); logf("pwrmgmt: disable charger and 4p2"); + charge_state = DISCHARGING; /* 5V has been lost: disable 4p2 power rail */ BF_SET(POWER_CHARGE, PWD_BATTCHRG); #if IMX233_SUBTARGET >= 3780 BF_WR(POWER_DCDC4P2, ENABLE_DCDC(0)); BF_WR(POWER_DCDC4P2, ENABLE_4P2(0)); - BF_WR(POWER_5VCTRL, CHARGE_4P2_ILIMIT(1)); + BF_WR(POWER_5VCTRL, CHARGE_4P2_ILIMIT(0)); BF_SET(POWER_5VCTRL, PWD_CHARGE_4P2); #endif - charge_state = DISCHARGING; } /* battery -> 5v transition */ else if(is_5v_present && charge_state == DISCHARGING) @@ -108,26 +122,22 @@ void charging_algorithm_step(void) * limit on the 4P2 rail. */ BF_WR(POWER_DCDC4P2, ENABLE_4P2(1)); BF_SET(POWER_CHARGE, ENABLE_LOAD); - BF_WR(POWER_5VCTRL, CHARGE_4P2_ILIMIT(1)); /* start by drawing 10mA only */ + BF_WR(POWER_5VCTRL, CHARGE_4P2_ILIMIT(0)); /* start by drawing 0mA */ BF_CLR(POWER_5VCTRL, PWD_CHARGE_4P2);// FIXME: manual error ? BF_WR(POWER_DCDC4P2, ENABLE_DCDC(1)); + /* the tick task will take care of slowly ramping up the current in the rail + * every 10ms (since it runs at HZ and HZ=100) */ #endif - timeout_4p2_ilimit_increase = current_tick + HZ / 100; charge_state = TRICKLE; } - else if(charge_state == TRICKLE && TIME_AFTER(current_tick, timeout_4p2_ilimit_increase)) + /* trickle -> charging transition */ + else if(charge_state == TRICKLE) { #if IMX233_SUBTARGET >= 3780 - /* if 4.2V current limit has not reached 780mA, increase it slowly to - * charge the 4.2V capacitance */ - if(BF_RD(POWER_5VCTRL, CHARGE_4P2_ILIMIT) != 0x3f) - { - //logf("pwrmgmt: incr 4.2 ilimit"); - HW_POWER_5VCTRL += BF_POWER_5VCTRL_CHARGE_4P2_ILIMIT(1); - timeout_4p2_ilimit_increase = current_tick + HZ / 100; - } - /* we've reached the maximum, take action */ - else + /* If 4.2V current limit has not reached 780mA, don't do anything, the + * DPC is still running */ + /* If we've reached the maximum, take action */ + if(BF_RD(POWER_5VCTRL, CHARGE_4P2_ILIMIT) == MAX_4P2_ILIMIT) #endif { logf("pwrmgmt: enable dcdc and charger"); @@ -181,6 +191,7 @@ void charging_algorithm_step(void) void charging_algorithm_close(void) { + tick_remove_task(&ramp_up_4p2_rail); } struct imx233_powermgmt_info_t imx233_powermgmt_get_info(void) @@ -192,7 +203,5 @@ struct imx233_powermgmt_info_t imx233_powermgmt_get_info(void) charge_state == CHARGING ? timeout_charging - current_tick : 0; info.topoff_timeout = charge_state == TOPOFF ? timeout_topping_off - current_tick : 0; - info.incr_4p2_ilimit_timeout = - charge_state == TRICKLE ? timeout_4p2_ilimit_increase - current_tick : 0; return info; } diff --git a/firmware/target/arm/imx233/powermgmt-imx233.h b/firmware/target/arm/imx233/powermgmt-imx233.h index 4cbe0072e7..640a8e3740 100644 --- a/firmware/target/arm/imx233/powermgmt-imx233.h +++ b/firmware/target/arm/imx233/powermgmt-imx233.h @@ -31,7 +31,6 @@ struct imx233_powermgmt_info_t enum charge_state_type state; int charging_timeout; /* time in tick before timeout, -1 if n/a */ int topoff_timeout; /* ditto */ - int incr_4p2_ilimit_timeout; /* ditto */ }; struct imx233_powermgmt_info_t imx233_powermgmt_get_info(void); |