From b60d19198aaf0af2cbe92e9327e1eb09c52573f1 Mon Sep 17 00:00:00 2001 From: Shawn Nematbakhsh Date: Wed, 11 Nov 2015 13:10:00 -0800 Subject: [PATCH] snoball: Initial board commit BUG=chrome-os-partner:47522 BRANCH=None TEST=Compile only Change-Id: I588733c0f34239a2b3eb36a8810ccfddd8ee98ca Signed-off-by: Shawn Nematbakhsh Reviewed-on: https://chromium-review.googlesource.com/312250 Commit-Ready: Shawn N Tested-by: Shawn N Reviewed-by: Alec Berg --- board/snoball/Makefile | 1 + board/snoball/board.c | 71 +++++++++++++++++ board/snoball/board.h | 88 ++++++++++++++++++++++ board/snoball/build.mk | 14 ++++ board/snoball/ec.tasklist | 25 ++++++ board/snoball/gpio.inc | 77 +++++++++++++++++++ board/snoball/usb_pd_policy.c | 138 ++++++++++++++++++++++++++++++++++ util/flash_ec | 1 + 8 files changed, 415 insertions(+) create mode 120000 board/snoball/Makefile create mode 100644 board/snoball/board.c create mode 100644 board/snoball/board.h create mode 100644 board/snoball/build.mk create mode 100644 board/snoball/ec.tasklist create mode 100644 board/snoball/gpio.inc create mode 100644 board/snoball/usb_pd_policy.c diff --git a/board/snoball/Makefile b/board/snoball/Makefile new file mode 120000 index 0000000000..94aaae2c4d --- /dev/null +++ b/board/snoball/Makefile @@ -0,0 +1 @@ +../../Makefile \ No newline at end of file diff --git a/board/snoball/board.c b/board/snoball/board.c new file mode 100644 index 0000000000..33677d1ca1 --- /dev/null +++ b/board/snoball/board.c @@ -0,0 +1,71 @@ +/* Copyright 2015 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. + */ + +/* Snoball board configuration */ + +#include "adc.h" +#include "adc_chip.h" +#include "common.h" +#include "console.h" +#include "gpio.h" +#include "hooks.h" +#include "host_command.h" +#include "i2c.h" +#include "registers.h" +#include "task.h" +#include "usb_pd.h" +#include "usb_pd_tcpm.h" +#include "util.h" + +void tcpc_alert_event(enum gpio_signal signal) +{ + /* Exchange status with TCPCs */ + host_command_pd_send_status(PD_CHARGE_NO_CHANGE); +} + +#include "gpio_list.h" + +const struct i2c_port_t i2c_ports[] = { + {"tcpc-a", STM32_I2C1_PORT, 1000, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, + {"tcpc-b", STM32_I2C2_PORT, 1000, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, +}; +const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); + +#define FUSB302_I2C_SLAVE_ADDR 0x44 + +const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_COUNT] = { + {STM32_I2C1_PORT, FUSB302_I2C_SLAVE_ADDR}, + {STM32_I2C2_PORT, FUSB302_I2C_SLAVE_ADDR}, + /* TODO: Verify secondary slave addr, or use i2c mux */ + {STM32_I2C2_PORT, FUSB302_I2C_SLAVE_ADDR + 2}, +}; + +/* ADC channels */ +const struct adc_t adc_channels[] = { + /* Current sensing. Converted to mA (6600mV/4096). */ + [ADC_C0_CS] = {"C0_CS", 6600, 4096, 0, STM32_AIN(0)}, + [ADC_C1_CS] = {"C1_CS", 6600, 4096, 0, STM32_AIN(1)}, + [ADC_C2_CS] = {"C2_CS", 6600, 4096, 0, STM32_AIN(2)}, + /* Voltage sensing. Converted to mV (40000mV/4096). */ + [ADC_C0_VS] = {"C0_VS", 40000, 4096, 0, STM32_AIN(3)}, + [ADC_C1_VS] = {"C1_VS", 40000, 4096, 0, STM32_AIN(4)}, + [ADC_C2_VS] = {"C2_VS", 40000, 4096, 0, STM32_AIN(5)}, + [ADC_VBUCK] = {"VBUCK", 40000, 4096, 0, STM32_AIN(8)}, + /* TODO: Check characteristics of thermistor circuit */ + [ADC_TEMP] = {"TEMP", 3300, 4096, 0, STM32_AIN(9)}, +}; +BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); + +static void board_init(void) +{ + gpio_enable_interrupt(GPIO_TCPC1_INT); + gpio_enable_interrupt(GPIO_TCPC2_INT); + gpio_enable_interrupt(GPIO_TCPC3_INT); +} +DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT); + +void board_reset_pd_mcu(void) +{ +} diff --git a/board/snoball/board.h b/board/snoball/board.h new file mode 100644 index 0000000000..2108f9ec77 --- /dev/null +++ b/board/snoball/board.h @@ -0,0 +1,88 @@ +/* Copyright 2015 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. + */ + +/* Snoball board configuration */ + +#ifndef __CROS_EC_BOARD_H +#define __CROS_EC_BOARD_H + +/* 48 MHz SYSCLK clock frequency */ +#define CPU_CLOCK 48000000 + +/* the UART console is on USART1 (PA9/PA10) */ +#define CONFIG_UART_CONSOLE 1 + +#define CONFIG_USB_POWER_DELIVERY +#define CONFIG_USB_PD_ALT_MODE +/* TODO: Consider disabling PD communication in RO */ +#define CONFIG_USB_PD_COMM_ENABLED 1 +#define CONFIG_USB_PD_CUSTOM_VDM +#define CONFIG_USB_PD_DYNAMIC_SRC_CAP +#define CONFIG_USB_PD_LOGGING +#define CONFIG_USB_PD_LOG_SIZE 1024 +#define CONFIG_USB_PD_PORT_COUNT 3 +#define CONFIG_USB_PD_TCPM_FUSB302 + +#define CONFIG_ADC +#define CONFIG_HW_CRC +#define CONFIG_I2C +#define CONFIG_I2C_MASTER +#undef CONFIG_LID_SWITCH +#undef CONFIG_WATCHDOG_HELP + +/* USB configuration */ +#define CONFIG_USB_PID 0x5019 +#define CONFIG_USB_BCD_DEV 0x0001 /* v 0.01 */ + +#define CONFIG_HIBERNATE +#define CONFIG_HIBERNATE_WAKEUP_PINS STM32_PWR_CSR_EWUP6 + +/* + * Allow dangerous commands all the time, since we don't have a write protect + * switch. + */ +#define CONFIG_SYSTEM_UNLOCKED + +#ifndef __ASSEMBLER__ + +/* Timer selection */ +#define TIM_CLOCK_MSB 3 +#define TIM_CLOCK_LSB 14 +#define TIM_ADC 1 + +#include "gpio_signal.h" + +/* ADC signals */ +enum adc_channel { + ADC_C0_CS, + ADC_C1_CS, + ADC_C2_CS, + ADC_C0_VS, + ADC_C1_VS, + ADC_C2_VS, + ADC_VBUCK, + ADC_TEMP, + /* Number of ADC channels */ + ADC_CH_COUNT +}; + +enum board_src_cap { + SRC_CAP_5V = 0, + SRC_CAP_12V, + SRC_CAP_20V, +}; + +#define PD_DEFAULT_STATE PD_STATE_SRC_DISCONNECTED + +/* delay necessary for the voltage transition on the power supply */ +/* TODO: Tune these parameters appropriately for snoball */ +#define PD_POWER_SUPPLY_TURN_ON_DELAY 50000 /* us */ +#define PD_POWER_SUPPLY_TURN_OFF_DELAY 50000 /* us */ + +void board_reset_pd_mcu(void); + +#endif /* !__ASSEMBLER__ */ + +#endif /* __CROS_EC_BOARD_H */ diff --git a/board/snoball/build.mk b/board/snoball/build.mk new file mode 100644 index 0000000000..fc3ff6151f --- /dev/null +++ b/board/snoball/build.mk @@ -0,0 +1,14 @@ +# -*- makefile -*- +# Copyright 2015 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. +# +# Board specific files build + +# the IC is STmicro STM32F070CB +CHIP:=stm32 +CHIP_FAMILY:=stm32f0 +CHIP_VARIANT:=stm32f07x + +board-y=board.o +board-$(CONFIG_USB_POWER_DELIVERY)+=usb_pd_policy.o diff --git a/board/snoball/ec.tasklist b/board/snoball/ec.tasklist new file mode 100644 index 0000000000..e9564d8f68 --- /dev/null +++ b/board/snoball/ec.tasklist @@ -0,0 +1,25 @@ +/* Copyright 2015 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. + */ + +/** + * List of enabled tasks in the priority order + * + * The first one has the lowest priority. + * + * For each task, use the macro TASK_ALWAYS(n, r, d, s) for base tasks and + * TASK_NOTEST(n, r, d, s) for tasks that can be excluded in test binaries, + * where : + * 'n' in the name of the task + * 'r' in the main routine of the task + * 'd' in an opaque parameter passed to the routine at startup + * 's' is the stack size in bytes; must be a multiple of 8 + */ +#define CONFIG_TASK_LIST \ + TASK_ALWAYS(HOOKS, hook_task, NULL, TASK_STACK_SIZE) \ + TASK_NOTEST(PDCMD, pd_command_task, NULL, TASK_STACK_SIZE) \ + TASK_ALWAYS(CONSOLE, console_task, NULL, TASK_STACK_SIZE) \ + TASK_ALWAYS(PD_C0, pd_task, NULL, LARGER_TASK_STACK_SIZE) \ + TASK_ALWAYS(PD_C1, pd_task, NULL, LARGER_TASK_STACK_SIZE) \ + TASK_ALWAYS(PD_C2, pd_task, NULL, LARGER_TASK_STACK_SIZE) diff --git a/board/snoball/gpio.inc b/board/snoball/gpio.inc new file mode 100644 index 0000000000..654e13a5ca --- /dev/null +++ b/board/snoball/gpio.inc @@ -0,0 +1,77 @@ +/* -*- mode:c -*- + * + * Copyright 2015 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. + */ + +/* TCPC alert / interrupt inputs */ +GPIO_INT(TCPC1_INT, PIN(A, 11), GPIO_INT_FALLING, tcpc_alert_event) +GPIO_INT(TCPC2_INT, PIN(A, 12), GPIO_INT_FALLING, tcpc_alert_event) +GPIO_INT(TCPC3_INT, PIN(A, 13), GPIO_INT_FALLING, tcpc_alert_event) + +/* ADCs */ +GPIO(PD1_CURRENT_SENSE, PIN(A, 0), GPIO_ANALOG) +GPIO(PD2_CURRENT_SENSE, PIN(A, 1), GPIO_ANALOG) +GPIO(PD3_CURRENT_SENSE, PIN(A, 2), GPIO_ANALOG) +GPIO(PD1_VOLTAGE_SENSE, PIN(A, 3), GPIO_ANALOG) +GPIO(PD2_VOLTAGE_SENSE, PIN(A, 4), GPIO_ANALOG) +GPIO(PD3_VOLTAGE_SENSE, PIN(A, 5), GPIO_ANALOG) +GPIO(VBUCK_IN_SENSE, PIN(B, 0), GPIO_ANALOG) +GPIO(TEMP_SENSE, PIN(B, 1), GPIO_ANALOG) + +/* + * I2C pins should be configured as inputs until I2C module is + * initialized. This will avoid driving the lines unintentionally. + */ +GPIO(I2C1_SCL, PIN(B, 8), GPIO_INPUT) +GPIO(I2C1_SDA, PIN(B, 9), GPIO_INPUT) +GPIO(I2C2_SCL, PIN(B, 13), GPIO_INPUT) +GPIO(I2C2_SDA, PIN(B, 11), GPIO_INPUT) +/* Mux select for I2C2 TCPCs */ +GPIO(I2C_MUX_SEL, PIN(B, 2), GPIO_OUT_LOW) + +GPIO(BIAS_EN, PIN(B, 10), GPIO_OUT_LOW) +/* Primary-side communication GPIOs */ +GPIO(OPTO_IN, PIN(B, 12), GPIO_INPUT) +GPIO(OPTO_OUT, PIN(A, 8), GPIO_OUT_LOW) + +/* Unimplemented signals which we need to emulate for now */ +UNIMPLEMENTED(ENTERING_RW) +UNIMPLEMENTED(WP_L) +/* TODO(crbug.com/551683): Add support for multiple alert GPIOs */ +UNIMPLEMENTED(PD_MCU_INT) + +/* Alternate functions */ +#if 0 +GPIO(EC_UART_TX, PIN(A, 9), GPIO_OUT_LOW) +GPIO(EC_UART_RX, PIN(A, 10), GPIO_INPUT) +GPIO(DSPIC_UART_TX, PIN(A, 14), GPIO_OUT_LOW) +GPIO(DSPIC_UART_RX, PIN(A, 15), GPIO_INPUT) + +/* WKUP6 */ +GPIO(WAKE, PIN(B, 5), GPIO_INPUT) + +/* PWM outputs w/ negation */ +GPIO(PD1_PWM, PIN(B, 14), GPIO_OUT_LOW) +GPIO(PD1_PWM_CMP, PIN(B, 15), GPIO_OUT_HIGH) +GPIO(PD2_PWM, PIN(A, 6), GPIO_OUT_LOW) +GPIO(PD2_PWM_CMP, PIN(B, 6), GPIO_OUT_HIGH) +GPIO(PD3_PWM, PIN(A, 7), GPIO_OUT_LOW) +GPIO(PD3_PWM_CMP, PIN(B, 7), GPIO_OUT_HIGH) +#endif + +/* PB8 / PB9 / PB11: I2C1_SCL / I2C1_SDA / I2C2_SDA */ +ALTERNATE(PIN_MASK(B, 0x0B00), 1, MODULE_I2C, 0) +/* PB13: I2C2_SCL */ +ALTERNATE(PIN_MASK(B, 0x2000), 5, MODULE_I2C, 0) +/* PA9 / PA10 / PA14 / PA15: USART1 / USART2 */ +ALTERNATE(PIN_MASK(A, 0xC600), 1, MODULE_UART, 0) +/* PA6 / PA7: TIM16_CH1 / TIM17_CH1 */ +ALTERNATE(PIN_MASK(A, 0x00C0), 5, MODULE_EXTPOWER, 0) +/* PB6 / PB7: TIM16_CH1N / TIM17_CH1N */ +ALTERNATE(PIN_MASK(B, 0x00C0), 2, MODULE_EXTPOWER, 0) +/* PB14: TIM15_CH1 */ +ALTERNATE(PIN_MASK(B, 0x4000), 1, MODULE_EXTPOWER, 0) +/* PB15: TIM15_CH1N */ +ALTERNATE(PIN_MASK(B, 0x8000), 3, MODULE_EXTPOWER, 0) diff --git a/board/snoball/usb_pd_policy.c b/board/snoball/usb_pd_policy.c new file mode 100644 index 0000000000..2c65199180 --- /dev/null +++ b/board/snoball/usb_pd_policy.c @@ -0,0 +1,138 @@ +/* Copyright 2015 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. + */ + +#include "common.h" +#include "console.h" +#include "gpio.h" +#include "hooks.h" +#include "registers.h" +#include "system.h" +#include "task.h" +#include "timer.h" +#include "util.h" +#include "usb_pd.h" + +#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) +#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) + +#define PDO_FIXED_FLAGS (PDO_FIXED_EXTERNAL | PDO_FIXED_DATA_SWAP) + +const uint32_t pd_src_pdo[] = { + PDO_FIXED(5000, 3000, PDO_FIXED_FLAGS), + /* TODO: Add additional source modes when tested */ + /* PDO_FIXED(12000, 3000, PDO_FIXED_FLAGS), */ + /* PDO_FIXED(20000, 3000, PDO_FIXED_FLAGS), */ +}; +const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo); + +static const int pd_src_pdo_cnts[3] = { + [SRC_CAP_5V] = 1, + /* [SRC_CAP_12V] = 2, */ + /* [SRC_CAP_20V] = 3, */ +}; + +static int pd_src_pdo_idx; + +int pd_get_source_pdo(const uint32_t **src_pdo) +{ + *src_pdo = pd_src_pdo; + return pd_src_pdo_cnts[pd_src_pdo_idx]; +} + +int pd_is_valid_input_voltage(int mv) +{ + return 1; +} + +void pd_transition_voltage(int idx) +{ + /* No-operation: we are always 5V */ +} + +int pd_set_power_supply_ready(int port) +{ + CPRINTS("Power supply ready/%d", port); + return EC_SUCCESS; /* we are ready */ +} + +void pd_power_supply_reset(int port) +{ + CPRINTS("Power supply reset/%d", port); +} + +int pd_board_checks(void) +{ + return EC_SUCCESS; +} + +void pd_check_dr_role(int port, int dr_role, int flags) +{ + /* If DFP, try to switch to UFP */ + if ((flags & PD_FLAGS_PARTNER_DR_DATA) && dr_role == PD_ROLE_DFP) + pd_request_data_swap(port); +} + +void pd_check_pr_role(int port, int pr_role, int flags) +{ +} + +int pd_check_data_swap(int port, int data_role) +{ + /* Allow data swap if we are a DFP, otherwise don't allow */ + return (data_role == PD_ROLE_DFP) ? 1 : 0; +} + +void pd_execute_data_swap(int port, int data_role) +{ + /* Do nothing */ +} + +/* ----------------- Vendor Defined Messages ------------------ */ +/* TODO: Add identify and GFU modes similar to Zinger */ +const struct svdm_response svdm_rsp = { + .identity = NULL, + .svids = NULL, + .modes = NULL, +}; + +int pd_custom_vdm(int port, int cnt, uint32_t *payload, + uint32_t **rpayload) +{ + int cmd = PD_VDO_CMD(payload[0]); + uint16_t dev_id = 0; + int is_rw; + + /* make sure we have some payload */ + if (cnt == 0) + return 0; + + switch (cmd) { + case VDO_CMD_VERSION: + /* guarantee last byte of payload is null character */ + *(payload + cnt - 1) = 0; + CPRINTF("version: %s\n", (char *)(payload+1)); + break; + case VDO_CMD_READ_INFO: + case VDO_CMD_SEND_INFO: + /* copy hash */ + if (cnt == 7) { + dev_id = VDO_INFO_HW_DEV_ID(payload[6]); + is_rw = VDO_INFO_IS_RW(payload[6]); + + CPRINTF("DevId:%d.%d SW:%d RW:%d\n", + HW_DEV_ID_MAJ(dev_id), + HW_DEV_ID_MIN(dev_id), + VDO_INFO_SW_DBG_VER(payload[6]), + is_rw); + } else if (cnt == 6) { + /* really old devices don't have last byte */ + pd_dev_store_rw_hash(port, dev_id, payload + 1, + SYSTEM_IMAGE_UNKNOWN); + } + break; + } + + return 0; +} diff --git a/util/flash_ec b/util/flash_ec index f97a693bef..be172c616c 100755 --- a/util/flash_ec +++ b/util/flash_ec @@ -70,6 +70,7 @@ BOARDS_STM32=( plankton ryu samus_pd + snoball strago_pd zinger )