From e22087126a7a08a556cb4ce7374c34a2e93cd948 Mon Sep 17 00:00:00 2001 From: Vic Yang Date: Wed, 12 Dec 2012 14:31:00 +0800 Subject: spring: Implement PWM control on ILIM_500 This adds init code to configure PWM and a console command to adjust duty cycle. Also rename ILIM_1500 to BOOST_EN. BUG=chrome-os-partner:14319 TEST=Adjust PWM duty cycle and measure voltage. BRANCH=none Change-Id: I23856416da19ed523d46af39e6cbc3129ac25525 Signed-off-by: Vic Yang Reviewed-on: https://gerrit.chromium.org/gerrit/39587 --- board/spring/board.c | 10 ++++-- board/spring/board.h | 9 +++-- board/spring/build.mk | 2 +- board/spring/usb_charging.c | 86 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 102 insertions(+), 5 deletions(-) create mode 100644 board/spring/usb_charging.c diff --git a/board/spring/board.c b/board/spring/board.c index 9316aaad52..4e4ddd1395 100644 --- a/board/spring/board.c +++ b/board/spring/board.c @@ -92,8 +92,7 @@ const struct gpio_info gpio_list[GPIO_COUNT] = { {"KB_OUT10", GPIO_C, (1<<5), GPIO_KB_OUTPUT, NULL}, {"KB_OUT11", GPIO_C, (1<<6), GPIO_KB_OUTPUT, NULL}, {"KB_OUT12", GPIO_C, (1<<7), GPIO_KB_OUTPUT, NULL}, - {"ILIM_1500", GPIO_B, (1<<3), GPIO_OUT_HIGH, NULL}, - {"ILIM_500", GPIO_B, (1<<4), GPIO_OUT_LOW, NULL}, + {"BOOST_EN", GPIO_B, (1<<3), GPIO_OUT_HIGH, NULL}, }; /* ADC channels */ @@ -127,6 +126,13 @@ void configure_board(void) STM32_GPIO_AFIO_MAPR = (STM32_GPIO_AFIO_MAPR & ~(0x7 << 24)) | (4 << 24); + /* remap TIM3_CH1 to PB4 */ + STM32_GPIO_AFIO_MAPR = (STM32_GPIO_AFIO_MAPR & ~(0x3 << 10)) + | (2 << 10); + + /* Set up PWM on TIM3 */ + board_configure_pwm(); + /* * Set alternate function for USART1. For alt. function input * the port is configured in either floating or pull-up/down diff --git a/board/spring/board.h b/board/spring/board.h index e4c0e27e64..6b99e9c5cb 100644 --- a/board/spring/board.h +++ b/board/spring/board.h @@ -121,8 +121,7 @@ enum gpio_signal { GPIO_KB_OUT10, GPIO_KB_OUT11, GPIO_KB_OUT12, - GPIO_ILIM_1500, /* max charging current : 1500 mA */ - GPIO_ILIM_500, /* max charging current : 500 mA */ + GPIO_BOOST_EN, /* Number of GPIOs; not an actual GPIO */ GPIO_COUNT }; @@ -140,6 +139,12 @@ int board_pmu_init(void); /* Force the pmu to reset everything on the board */ void board_hard_reset(void); +/* Set up PWM for ILIM */ +void board_configure_pwm(void); + +/* Set PWM duty cycle */ +void board_pwm_duty_cycle(int percent); + #endif /* !__ASSEMBLER__ */ #endif /* __BOARD_H */ diff --git a/board/spring/build.mk b/board/spring/build.mk index ae15fbe081..bb6f4ae234 100644 --- a/board/spring/build.mk +++ b/board/spring/build.mk @@ -8,4 +8,4 @@ CHIP:=stm32 CHIP_VARIANT:=stm32f100 -board-y=board.o +board-y=board.o usb_charging.o diff --git a/board/spring/usb_charging.c b/board/spring/usb_charging.c new file mode 100644 index 0000000000..3f93fe6e72 --- /dev/null +++ b/board/spring/usb_charging.c @@ -0,0 +1,86 @@ +/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* USB charging control for spring board */ + +#include "board.h" +#include "console.h" +#include "registers.h" +#include "util.h" + +#define PWM_FREQUENCY 100 /* Hz */ + +void board_configure_pwm(void) +{ + uint32_t val; + + /* Config alt. function (TIM3/PWM) */ + val = STM32_GPIO_CRL_OFF(GPIO_B) & ~0x000f0000; + val |= 0x00090000; + STM32_GPIO_CRL_OFF(GPIO_B) = val; + + /* Enable TIM3 clock */ + STM32_RCC_APB1ENR |= 0x2; + + /* Disable counter during setup */ + STM32_TIM_CR1(3) = 0x0000; + + /* + * CPU_CLOCK / PSC determines how fast the counter operates. + * ARR determines the wave period, CCRn determines duty cycle. + * Thus, frequency = CPU_CLOCK / PSC / ARR. + * + * Assuming 16MHz clock and ARR=100, PSC needed to achieve PWM_FREQUENCY + * is: PSC = CPU_CLOCK / PWM_FREQUENCY / ARR + */ + STM32_TIM_PSC(3) = CPU_CLOCK / PWM_FREQUENCY / 100; /* pre-scaler */ + STM32_TIM_ARR(3) = 100; /* auto-reload value */ + STM32_TIM_CCR1(3) = 100; /* duty cycle */ + + /* CC1 configured as output, PWM mode 1, preload enable */ + STM32_TIM_CCMR1(3) = (6 << 4) | (1 << 3); + + /* CC1 output enable, active high */ + STM32_TIM_CCER(3) = (1 << 0); + + /* Generate update event to force loading of shadow registers */ + STM32_TIM_EGR(3) |= 1; + + /* Enable auto-reload preload, start counting */ + STM32_TIM_CR1(3) |= (1 << 7) | (1 << 0); +} + +void board_pwm_duty_cycle(int percent) +{ + if (percent < 0) + percent = 0; + if (percent > 100) + percent = 100; + STM32_TIM_CCR1(3) = (percent * STM32_TIM_ARR(3)) / 100; +} + +/* + * Console command for debugging. + * TODO(victoryang): Remove after charging control is done. + */ +static int command_ilim(int argc, char **argv) +{ + char *e; + int percent; + + if (argc >= 2) { + percent = strtoi(argv[1], &e, 0); + if (*e) + return EC_ERROR_PARAM1; + board_pwm_duty_cycle(percent); + } + ccprintf("PWM duty cycle set to %d%%\n", STM32_TIM_CCR1(3)); + + return EC_SUCCESS; +} +DECLARE_CONSOLE_COMMAND(ilim, command_ilim, + "[percent]", + "Set or show ILIM duty cycle", + NULL); -- cgit v1.2.1