From 95253a68dd9ec77388d6556f384299ecb80cfb7e Mon Sep 17 00:00:00 2001 From: Vic Yang Date: Tue, 19 Feb 2013 23:06:55 +0800 Subject: 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 Reviewed-on: https://gerrit.chromium.org/gerrit/43511 Reviewed-by: Vincent Palatin --- board/spring/board.c | 4 +-- board/spring/usb_charging.c | 70 +++++++++++++++++++++++++++++++++++++++++++-- 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(¤t)) + 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); -- cgit v1.2.1