summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2016-05-02 21:49:13 +0100
committerAmaury Pouly <amaury.pouly@gmail.com>2016-05-28 16:21:03 +0100
commit941ac165d864ccdd4e4ae870366f4e0a6bc30055 (patch)
treed0030c16f10321833f383baafaf3b78610951526
parentd245b7a2a1113b6dbdbfb10f5ee984a00c987844 (diff)
downloadrockbox-941ac165d864ccdd4e4ae870366f4e0a6bc30055.tar.gz
rockbox-941ac165d864ccdd4e4ae870366f4e0a6bc30055.zip
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
-rw-r--r--firmware/target/arm/imx233/debug-imx233.c1
-rw-r--r--firmware/target/arm/imx233/powermgmt-imx233.c45
-rw-r--r--firmware/target/arm/imx233/powermgmt-imx233.h1
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)
407 "<unknown>"); 407 "<unknown>");
408 lcd_putsf(0, 1, "charging tmo: %d", info.charging_timeout); 408 lcd_putsf(0, 1, "charging tmo: %d", info.charging_timeout);
409 lcd_putsf(0, 2, "topoff tmo: %d", info.topoff_timeout); 409 lcd_putsf(0, 2, "topoff tmo: %d", info.topoff_timeout);
410 lcd_putsf(0, 3, "4p2ilimit tmo: %d", info.incr_4p2_ilimit_timeout);
411 410
412 lcd_update(); 411 lcd_update();
413 yield(); 412 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 @@
39/* charger state is maintained in charge_state (see powermgmt.h) */ 39/* charger state is maintained in charge_state (see powermgmt.h) */
40static int timeout_charging; /* timeout before charging will be declared broken */ 40static int timeout_charging; /* timeout before charging will be declared broken */
41static int timeout_topping_off; /* timeout before stopping charging after topping off */ 41static int timeout_topping_off; /* timeout before stopping charging after topping off */
42static int timeout_4p2_ilimit_increase; /* timeout before increasing 4p2 ilimit */
43 42
44/* Returns battery voltage from ADC [millivolts] */ 43/* Returns battery voltage from ADC [millivolts] */
45int _battery_voltage(void) 44int _battery_voltage(void)
@@ -69,9 +68,24 @@ void imx233_powermgmt_init(void)
69#endif 68#endif
70} 69}
71 70
71#define MAX_4P2_ILIMIT 0x3f
72
73/* The code below assumes HZ = 100 so that it runs every 10ms */
74#if HZ != 100
75#warning The ramp_up_4p2_rail() tick task assumes HZ = 100, this may break charging
76#endif
77
78static void ramp_up_4p2_rail(void)
79{
80 /* only ramp up in the TRICKLE state and if we haven't reached the maximum yet */
81 if(charge_state == TRICKLE && BF_RD(POWER_5VCTRL, CHARGE_4P2_ILIMIT) < MAX_4P2_ILIMIT)
82 HW_POWER_5VCTRL += BF_POWER_5VCTRL_CHARGE_4P2_ILIMIT(1);
83}
84
72void powermgmt_init_target(void) 85void powermgmt_init_target(void)
73{ 86{
74 charge_state = DISCHARGING; 87 charge_state = DISCHARGING;
88 tick_add_task(&ramp_up_4p2_rail);
75} 89}
76 90
77void charging_algorithm_step(void) 91void charging_algorithm_step(void)
@@ -84,15 +98,15 @@ void charging_algorithm_step(void)
84 { 98 {
85 logf("pwrmgmt: * -> discharging"); 99 logf("pwrmgmt: * -> discharging");
86 logf("pwrmgmt: disable charger and 4p2"); 100 logf("pwrmgmt: disable charger and 4p2");
101 charge_state = DISCHARGING;
87 /* 5V has been lost: disable 4p2 power rail */ 102 /* 5V has been lost: disable 4p2 power rail */
88 BF_SET(POWER_CHARGE, PWD_BATTCHRG); 103 BF_SET(POWER_CHARGE, PWD_BATTCHRG);
89#if IMX233_SUBTARGET >= 3780 104#if IMX233_SUBTARGET >= 3780
90 BF_WR(POWER_DCDC4P2, ENABLE_DCDC(0)); 105 BF_WR(POWER_DCDC4P2, ENABLE_DCDC(0));
91 BF_WR(POWER_DCDC4P2, ENABLE_4P2(0)); 106 BF_WR(POWER_DCDC4P2, ENABLE_4P2(0));
92 BF_WR(POWER_5VCTRL, CHARGE_4P2_ILIMIT(1)); 107 BF_WR(POWER_5VCTRL, CHARGE_4P2_ILIMIT(0));
93 BF_SET(POWER_5VCTRL, PWD_CHARGE_4P2); 108 BF_SET(POWER_5VCTRL, PWD_CHARGE_4P2);
94#endif 109#endif
95 charge_state = DISCHARGING;
96 } 110 }
97 /* battery -> 5v transition */ 111 /* battery -> 5v transition */
98 else if(is_5v_present && charge_state == DISCHARGING) 112 else if(is_5v_present && charge_state == DISCHARGING)
@@ -108,26 +122,22 @@ void charging_algorithm_step(void)
108 * limit on the 4P2 rail. */ 122 * limit on the 4P2 rail. */
109 BF_WR(POWER_DCDC4P2, ENABLE_4P2(1)); 123 BF_WR(POWER_DCDC4P2, ENABLE_4P2(1));
110 BF_SET(POWER_CHARGE, ENABLE_LOAD); 124 BF_SET(POWER_CHARGE, ENABLE_LOAD);
111 BF_WR(POWER_5VCTRL, CHARGE_4P2_ILIMIT(1)); /* start by drawing 10mA only */ 125 BF_WR(POWER_5VCTRL, CHARGE_4P2_ILIMIT(0)); /* start by drawing 0mA */
112 BF_CLR(POWER_5VCTRL, PWD_CHARGE_4P2);// FIXME: manual error ? 126 BF_CLR(POWER_5VCTRL, PWD_CHARGE_4P2);// FIXME: manual error ?
113 BF_WR(POWER_DCDC4P2, ENABLE_DCDC(1)); 127 BF_WR(POWER_DCDC4P2, ENABLE_DCDC(1));
128 /* the tick task will take care of slowly ramping up the current in the rail
129 * every 10ms (since it runs at HZ and HZ=100) */
114#endif 130#endif
115 timeout_4p2_ilimit_increase = current_tick + HZ / 100;
116 charge_state = TRICKLE; 131 charge_state = TRICKLE;
117 } 132 }
118 else if(charge_state == TRICKLE && TIME_AFTER(current_tick, timeout_4p2_ilimit_increase)) 133 /* trickle -> charging transition */
134 else if(charge_state == TRICKLE)
119 { 135 {
120#if IMX233_SUBTARGET >= 3780 136#if IMX233_SUBTARGET >= 3780
121 /* if 4.2V current limit has not reached 780mA, increase it slowly to 137 /* If 4.2V current limit has not reached 780mA, don't do anything, the
122 * charge the 4.2V capacitance */ 138 * DPC is still running */
123 if(BF_RD(POWER_5VCTRL, CHARGE_4P2_ILIMIT) != 0x3f) 139 /* If we've reached the maximum, take action */
124 { 140 if(BF_RD(POWER_5VCTRL, CHARGE_4P2_ILIMIT) == MAX_4P2_ILIMIT)
125 //logf("pwrmgmt: incr 4.2 ilimit");
126 HW_POWER_5VCTRL += BF_POWER_5VCTRL_CHARGE_4P2_ILIMIT(1);
127 timeout_4p2_ilimit_increase = current_tick + HZ / 100;
128 }
129 /* we've reached the maximum, take action */
130 else
131#endif 141#endif
132 { 142 {
133 logf("pwrmgmt: enable dcdc and charger"); 143 logf("pwrmgmt: enable dcdc and charger");
@@ -181,6 +191,7 @@ void charging_algorithm_step(void)
181 191
182void charging_algorithm_close(void) 192void charging_algorithm_close(void)
183{ 193{
194 tick_remove_task(&ramp_up_4p2_rail);
184} 195}
185 196
186struct imx233_powermgmt_info_t imx233_powermgmt_get_info(void) 197struct imx233_powermgmt_info_t imx233_powermgmt_get_info(void)
@@ -192,7 +203,5 @@ struct imx233_powermgmt_info_t imx233_powermgmt_get_info(void)
192 charge_state == CHARGING ? timeout_charging - current_tick : 0; 203 charge_state == CHARGING ? timeout_charging - current_tick : 0;
193 info.topoff_timeout = 204 info.topoff_timeout =
194 charge_state == TOPOFF ? timeout_topping_off - current_tick : 0; 205 charge_state == TOPOFF ? timeout_topping_off - current_tick : 0;
195 info.incr_4p2_ilimit_timeout =
196 charge_state == TRICKLE ? timeout_4p2_ilimit_increase - current_tick : 0;
197 return info; 206 return info;
198} 207}
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
31 enum charge_state_type state; 31 enum charge_state_type state;
32 int charging_timeout; /* time in tick before timeout, -1 if n/a */ 32 int charging_timeout; /* time in tick before timeout, -1 if n/a */
33 int topoff_timeout; /* ditto */ 33 int topoff_timeout; /* ditto */
34 int incr_4p2_ilimit_timeout; /* ditto */
35}; 34};
36 35
37struct imx233_powermgmt_info_t imx233_powermgmt_get_info(void); 36struct imx233_powermgmt_info_t imx233_powermgmt_get_info(void);