summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVic Yang <victoryang@chromium.org>2013-02-19 23:06:55 +0800
committerChromeBot <chrome-bot@google.com>2013-02-20 09:22:40 -0800
commit95253a68dd9ec77388d6556f384299ecb80cfb7e (patch)
tree2ee9a022843caa29c7dca03172d03d46698411e5
parentaab9accfce10e70197729afd07451229ac8a178d (diff)
downloadchrome-ec-95253a68dd9ec77388d6556f384299ecb80cfb7e.tar.gz
spring: Add current limit loop
This monitors input voltage and adjust current limit accordingly to keep voltage in acceptable range. BUG=chrome-os-partner:17881 TEST=Manual on spring BRANCH=none Change-Id: Ie4b44844983f622ef7f648cf022c3c093597246c Signed-off-by: Vic Yang <victoryang@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/43511 Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r--board/spring/board.c4
-rw-r--r--board/spring/usb_charging.c70
2 files changed, 70 insertions, 4 deletions
diff --git a/board/spring/board.c b/board/spring/board.c
index 444dc700b0..9e783d8081 100644
--- a/board/spring/board.c
+++ b/board/spring/board.c
@@ -294,8 +294,8 @@ int board_pmu_init(void)
int board_get_ac(void)
{
- /* use TPSChrome VACG signal to detect AC state */
- return gpio_get_level(GPIO_BCHGR_VACG);
+ /* UVLO is 4.1V. We consider AC bad when its voltage drops below 4.3V */
+ return adc_read_channel(ADC_CH_USB_VBUS_SNS) >= 4300;
}
int board_battery_led(enum charging_state state)
diff --git a/board/spring/usb_charging.c b/board/spring/usb_charging.c
index b56147e61f..61e2b96da3 100644
--- a/board/spring/usb_charging.c
+++ b/board/spring/usb_charging.c
@@ -8,9 +8,12 @@
#include "adc.h"
#include "board.h"
#include "console.h"
+#include "hooks.h"
#include "gpio.h"
#include "lp5562.h"
+#include "pmu_tpschrome.h"
#include "registers.h"
+#include "smart_battery.h"
#include "stm32_adc.h"
#include "task.h"
#include "timer.h"
@@ -35,7 +38,15 @@
#define I_LIMIT_2400MA 25
#define I_LIMIT_3000MA 0
+/* PWM control loop parameters */
+#define PWM_CTRL_BEGIN_OFFSET 30
+#define PWM_CTRL_STEP_DOWN 1
+#define PWM_CTRL_STEP_UP 5
+#define PWM_CTRL_VBUS_LOW 4500
+#define PWM_CTRL_VBUS_HIGH 4700 /* Must be higher than 4.5V */
+
static int current_dev_type = TSU6721_TYPE_NONE;
+static int nominal_pwm_duty;
static int current_pwm_duty;
static enum ilim_config current_ilim_config = ILIM_CONFIG_MANUAL_OFF;
@@ -155,6 +166,43 @@ void board_pwm_duty_cycle(int percent)
current_pwm_duty = percent;
}
+static void board_pwm_tweak(void)
+{
+ int vbus, current;
+
+ if (current_ilim_config != ILIM_CONFIG_PWM)
+ return;
+
+ vbus = adc_read_channel(ADC_CH_USB_VBUS_SNS);
+ if (battery_current(&current))
+ return;
+ /*
+ * If VBUS voltage is too low:
+ * - If battery is discharging, throttling more is going to draw
+ * more current from the battery, so do nothing in this case.
+ * - Otherwise, throttle input current to raise VBUS voltage.
+ * If VBUS voltage is high enough, allow more current until we hit
+ * current limit target.
+ */
+ if (vbus < PWM_CTRL_VBUS_LOW &&
+ current_pwm_duty < 100 &&
+ current >= 0) {
+ board_pwm_duty_cycle(current_pwm_duty + PWM_CTRL_STEP_UP);
+ CPRINTF("[%T PWM duty up %d%%]\n", current_pwm_duty);
+ } else if (vbus > PWM_CTRL_VBUS_HIGH &&
+ current_pwm_duty > nominal_pwm_duty) {
+ board_pwm_duty_cycle(current_pwm_duty - PWM_CTRL_STEP_DOWN);
+ CPRINTF("[%T PWM duty down %d%%]\n", current_pwm_duty);
+ }
+}
+DECLARE_HOOK(HOOK_SECOND, board_pwm_tweak, HOOK_PRIO_DEFAULT);
+
+void board_pwm_nominal_duty_cycle(int percent)
+{
+ board_pwm_duty_cycle(percent + PWM_CTRL_BEGIN_OFFSET);
+ nominal_pwm_duty = percent;
+}
+
void usb_charge_interrupt(enum gpio_signal signal)
{
task_wake(TASK_ID_PMU_TPS65090_CHARGER);
@@ -183,7 +231,7 @@ static void usb_device_change(int dev_type)
(dev_type & TSU6721_TYPE_DCP))
current_limit = I_LIMIT_1500MA;
- board_pwm_duty_cycle(current_limit);
+ board_pwm_nominal_duty_cycle(current_limit);
/* Turns on battery LED */
lp5562_poweron();
@@ -242,7 +290,7 @@ int board_get_usb_current_limit(void)
}
/*
- * Console command for debugging.
+ * Console commands for debugging.
* TODO(victoryang): Remove after charging control is done.
*/
static int command_ilim(int argc, char **argv)
@@ -276,3 +324,21 @@ DECLARE_CONSOLE_COMMAND(ilim, command_ilim,
"[percent | on | off]",
"Set or show ILIM duty cycle/GPIO value",
NULL);
+
+static int command_batdebug(int argc, char **argv)
+{
+ int val;
+ ccprintf("VBUS = %d mV\n", adc_read_channel(ADC_CH_USB_VBUS_SNS));
+ ccprintf("VAC = %d mV\n", pmu_adc_read(ADC_VAC) * 17000 / 1024);
+ ccprintf("IAC = %d mA\n", pmu_adc_read(ADC_IAC) * 20 * 33 / 1024);
+ ccprintf("VBAT = %d mV\n", pmu_adc_read(ADC_VBAT) * 17000 / 1024);
+ ccprintf("IBAT = %d mA\n", pmu_adc_read(ADC_IBAT) * 50 * 40 / 1024);
+ ccprintf("PWM = %d%%\n", STM32_TIM_CCR1(3));
+ battery_current(&val);
+ ccprintf("Battery Current = %d mA\n", val);
+ battery_voltage(&val);
+ ccprintf("Battery Voltage= %d mV\n", val);
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND(batdebug, command_batdebug,
+ NULL, NULL, NULL);