diff options
author | Gwendal Grignou <gwendal@chromium.org> | 2015-02-13 13:07:14 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-06-06 17:09:28 -0700 |
commit | 7719869dace6785e72db53c909fbea3315533b3d (patch) | |
tree | 6e75f937a4dc09bdda70d7efd5c345adc899161e | |
parent | 885c02a92d35607bf410e27f27c0b35e67827cf5 (diff) | |
download | chrome-ec-7719869dace6785e72db53c909fbea3315533b3d.tar.gz |
board: Add support for nucleo-f411re
Add nucleo-f411re for testing STM32F411.
Fix registers.h to include F411 specific features.
TEST=Check uart,gpio works. Check BMI160 accel/gyro sensor works over
i2c
Install firmware with "make BOARD=nucleo-f411re flash"
BUG=b:38018926
BRANCH=none
Change-Id: I8514d1aa48e06708053e72f8d4be15738eda6cf4
Signed-off-by: Gwendal Grignou <gwendal@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/249994
Reviewed-by: Alexandru M Stan <amstan@chromium.org>
-rw-r--r-- | board/nucleo-f411re/board.c | 155 | ||||
-rw-r--r-- | board/nucleo-f411re/board.h | 76 | ||||
-rw-r--r-- | board/nucleo-f411re/build.mk | 12 | ||||
-rw-r--r-- | board/nucleo-f411re/ec.tasklist | 23 | ||||
-rw-r--r-- | board/nucleo-f411re/gpio.inc | 31 | ||||
-rw-r--r-- | board/nucleo-f411re/openocd-flash.cfg | 19 | ||||
-rw-r--r-- | chip/stm32/registers.h | 62 | ||||
-rw-r--r-- | cts/common/board.py | 4 |
8 files changed, 357 insertions, 25 deletions
diff --git a/board/nucleo-f411re/board.c b/board/nucleo-f411re/board.c new file mode 100644 index 0000000000..6a8fc8e50c --- /dev/null +++ b/board/nucleo-f411re/board.c @@ -0,0 +1,155 @@ +/* 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. + */ +/* nucleo-f411re development board configuration */ + +#include "adc.h" +#include "adc_chip.h" +#include "common.h" +#include "console.h" +#include "driver/accelgyro_bmi160.h" +#include "ec_version.h" +#include "gpio.h" +#include "hooks.h" +#include "i2c.h" +#include "motion_sense.h" + +#include "gpio.h" +#include "registers.h" +#include "task.h" +#include "util.h" + +void user_button_evt(enum gpio_signal signal) +{ + ccprintf("Button %d, %d!\n", signal, gpio_get_level(signal)); +} + +#include "gpio_list.h" + +/* Initialize board. */ +static void board_init(void) +{ + gpio_enable_interrupt(GPIO_USER_BUTTON_L); + + /* No power control yet */ + /* Go to S3 state */ + hook_notify(HOOK_CHIPSET_STARTUP); + + /* Go to S0 state */ + hook_notify(HOOK_CHIPSET_RESUME); +} +DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT); + +/* ADC channels */ +const struct adc_t adc_channels[] = { + /* Arduino connectors analog pins */ + [ADC1_0] = {"ADC1_0", 3000, 4096, 0, STM32_AIN(0)}, + [ADC1_1] = {"ADC1_1", 3000, 4096, 0, STM32_AIN(1)}, + [ADC1_4] = {"ADC1_4", 3000, 4096, 0, STM32_AIN(4)}, + [ADC1_8] = {"ADC1_8", 3000, 4096, 0, STM32_AIN(8)}, +}; +BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); + +/* I2C ports */ +const struct i2c_port_t i2c_ports[] = { + {"master", I2C_PORT_MASTER, 100, + GPIO_MASTER_I2C_SCL, GPIO_MASTER_I2C_SDA}, +}; + +const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); + +/* Base Sensor mutex */ +static struct mutex g_base_mutex; + +struct bmi160_drv_data_t g_bmi160_data; + +struct motion_sensor_t motion_sensors[] = { + [BASE_ACCEL] = { + .name = "Base Accel", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_BMI160, + .type = MOTIONSENSE_TYPE_ACCEL, + .location = MOTIONSENSE_LOC_BASE, + .drv = &bmi160_drv, + .mutex = &g_base_mutex, + .drv_data = &g_bmi160_data, + .port = I2C_PORT_ACCEL, + .addr = BMI160_ADDR0, + .rot_standard_ref = NULL, + .default_range = 2, /* g, enough for laptop. */ + .config = { + /* AP: by default use EC settings */ + [SENSOR_CONFIG_AP] = { + .odr = 0, + .ec_rate = 0, + }, + /* EC use accel for angle detection */ + [SENSOR_CONFIG_EC_S0] = { + .odr = 10000 | ROUND_UP_FLAG, + .ec_rate = 100 * MSEC, + }, + /* Sensor on for lid angle detection */ + [SENSOR_CONFIG_EC_S3] = { + .odr = 10000 | ROUND_UP_FLAG, + .ec_rate = 100 * MSEC, + }, + /* Sensor off in S5 */ + [SENSOR_CONFIG_EC_S5] = { + .odr = 0, + .ec_rate = 0 + }, + }, + }, + + [BASE_GYRO] = { + .name = "Base Gyro", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_BMI160, + .type = MOTIONSENSE_TYPE_GYRO, + .location = MOTIONSENSE_LOC_BASE, + .drv = &bmi160_drv, + .mutex = &g_base_mutex, + .drv_data = &g_bmi160_data, + .port = I2C_PORT_ACCEL, + .addr = BMI160_ADDR0, + .default_range = 1000, /* dps */ + .rot_standard_ref = NULL, + .config = { + /* AP: by default shutdown all sensors */ + [SENSOR_CONFIG_AP] = { + .odr = 0, + .ec_rate = 0, + }, + /* EC does not need in S0 */ + [SENSOR_CONFIG_EC_S0] = { + .odr = 0, + .ec_rate = 0, + }, + /* Sensor off in S3/S5 */ + [SENSOR_CONFIG_EC_S3] = { + .odr = 0, + .ec_rate = 0, + }, + /* Sensor off in S3/S5 */ + [SENSOR_CONFIG_EC_S5] = { + .odr = 0, + .ec_rate = 0, + }, + }, + }, +}; +const unsigned int motion_sensor_count = ARRAY_SIZE(motion_sensors); + +#ifdef CONFIG_DMA_HELP +#include "dma.h" +int command_dma_help(int argc, char **argv) +{ + dma_dump(STM32_DMA2_STREAM0); + dma_test(STM32_DMA2_STREAM0); + dma_dump(STM32_DMA2_STREAM0); + return EC_SUCCESS; +} +DECLARE_CONSOLE_COMMAND(dmahelp, command_dma_help, + NULL, "Run DMA test"); +#endif diff --git a/board/nucleo-f411re/board.h b/board/nucleo-f411re/board.h new file mode 100644 index 0000000000..0a8dcc6ba8 --- /dev/null +++ b/board/nucleo-f411re/board.h @@ -0,0 +1,76 @@ +/* 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. + */ + +/* Nucleo-F411RE development board configuration */ + +#ifndef __BOARD_H +#define __BOARD_H + +/* 84 MHz CPU/AHB/APB2 clock frequency (APB1 = 42 Mhz) */ +#define CPU_CLOCK 84000000 +#define CONFIG_FLASH_WRITE_SIZE STM32_FLASH_WRITE_SIZE_3300 + + +/* the UART console is on USART2 (PA2/PA3) */ +#undef CONFIG_UART_CONSOLE +#define CONFIG_UART_CONSOLE 2 + +/* Optional features */ +#undef CONFIG_LID_SWITCH +#undef CONFIG_HIBERNATE +#define CONFIG_STM_HWTIMER32 +#define CONFIG_WATCHDOG_HELP +#define CONFIG_TASK_PROFILING + +#undef CONFIG_ADC +#define CONFIG_DMA_HELP +#define CONFIG_I2C + +#undef CONFIG_UART_RX_DMA +#define CONFIG_UART_TX_DMA_CH STM32_DMAS_USART2_TX +#define CONFIG_UART_RX_DMA_CH STM32_DMAS_USART2_RX +#define CONFIG_UART_TX_REQ_CH STM32_REQ_USART2_TX +#define CONFIG_UART_RX_REQ_CH STM32_REQ_USART2_RX + +#define CONFIG_ACCELGYRO_BMI160 +#define CONFIG_CMD_ACCELS +#define CONFIG_CMD_ACCEL_INFO +#define CONFIG_CMD_FLASH + +/* I2C ports configuration */ +#define CONFIG_I2C_MASTER +#define CONFIG_I2C_DEBUG +#define I2C_PORT_MASTER 1 +#define I2C_PORT_SLAVE 0 /* needed for DMAC macros (ugh) */ +#define I2C_PORT_ACCEL I2C_PORT_MASTER + +#ifndef __ASSEMBLER__ + +/* Timer selection */ +#define TIM_CLOCK32 2 +#define TIM_WATCHDOG 11 + +#define CONFIG_WP_ALWAYS + +/* ADC signal */ +enum adc_channel { + ADC1_0 = 0, + ADC1_1, + ADC1_4, + ADC1_8, + /* Number of ADC channels */ + ADC_CH_COUNT +}; + +enum sensor_id { + BASE_ACCEL = 0, + BASE_GYRO, +}; + +#include "gpio_signal.h" + +#endif /* !__ASSEMBLER__ */ + +#endif /* __BOARD_H */ diff --git a/board/nucleo-f411re/build.mk b/board/nucleo-f411re/build.mk new file mode 100644 index 0000000000..3a5fc28558 --- /dev/null +++ b/board/nucleo-f411re/build.mk @@ -0,0 +1,12 @@ +# 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 STM32F411RE +CHIP:=stm32 +CHIP_FAMILY:=stm32f4 +CHIP_VARIANT:=stm32f411 + +board-y=board.o diff --git a/board/nucleo-f411re/ec.tasklist b/board/nucleo-f411re/ec.tasklist new file mode 100644 index 0000000000..52135d97f8 --- /dev/null +++ b/board/nucleo-f411re/ec.tasklist @@ -0,0 +1,23 @@ +/* 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, LARGER_TASK_STACK_SIZE) \ + TASK_NOTEST(HOSTCMD, host_command_task, NULL, TASK_STACK_SIZE) \ + TASK_NOTEST(MOTIONSENSE, motion_sense_task, NULL, TASK_STACK_SIZE) \ + TASK_ALWAYS(CONSOLE, console_task, NULL, LARGER_TASK_STACK_SIZE) diff --git a/board/nucleo-f411re/gpio.inc b/board/nucleo-f411re/gpio.inc new file mode 100644 index 0000000000..83a9e51a08 --- /dev/null +++ b/board/nucleo-f411re/gpio.inc @@ -0,0 +1,31 @@ +/* -*- 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. + */ + +/* Interrupts */ +GPIO_INT(USER_BUTTON_L, PIN(C, 13), GPIO_INT_BOTH, user_button_evt) + +/* User LED */ +GPIO(USER_LED, PIN(A, 5), GPIO_OUT_LOW) + +GPIO(BMI160_INT2_L, PIN(C, 10), GPIO_OUT_LOW) +/* + * I2C pins should be configured as inputs until I2C module is + * initialized. This will avoid driving the lines unintentionally. + */ +GPIO(MASTER_I2C_SCL, PIN(B, 10), GPIO_INPUT) +GPIO(MASTER_I2C_SDA, PIN(B, 3), GPIO_INPUT) +GPIO(SLAVE_I2C_SCL, PIN(B, 8), GPIO_INPUT) +GPIO(SLAVE_I2C_SDA, PIN(B, 9), GPIO_INPUT) + +UNIMPLEMENTED(ENTERING_RW) +UNIMPLEMENTED(WP_L) + +ALTERNATE(PIN_MASK(A, 0x000C), GPIO_ALT_USART, MODULE_UART, GPIO_PULL_UP) /* USART2: PA2/PA3 */ +ALTERNATE(PIN_MASK(B, 0x0400), GPIO_ALT_I2C, MODULE_I2C, 0) /* I2C MASTER:PB10 */ +ALTERNATE(PIN_MASK(B, 0x0008), GPIO_ALT_I2C_23, MODULE_I2C, 0) /* I2C MASTER:PB3 */ +ALTERNATE(PIN_MASK(B, 0x0200), GPIO_ALT_I2C, MODULE_I2C, 0) /* I2C SLAVE:PB9 */ +ALTERNATE(PIN_MASK(B, 0x0100), GPIO_ALT_I2C, MODULE_I2C, 0) /* I2C SLAVE:PB8 */ diff --git a/board/nucleo-f411re/openocd-flash.cfg b/board/nucleo-f411re/openocd-flash.cfg new file mode 100644 index 0000000000..7a6ea6316c --- /dev/null +++ b/board/nucleo-f411re/openocd-flash.cfg @@ -0,0 +1,19 @@ +# Copyright 2016 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. + +source [find board/st_nucleo_f4.cfg] + +# For flashing, force the board into reset on connect, this ensures that +# code running on the core can't interfere with programming. +reset_config connect_assert_srst + +gdb_port 0 +tcl_port 0 +telnet_port 0 +init +reset init +flash write_image erase unlock $BUILD_DIR/ec.bin 0x08000000 +reset halt +resume +shutdown diff --git a/chip/stm32/registers.h b/chip/stm32/registers.h index edc94b1b7d..3655251be7 100644 --- a/chip/stm32/registers.h +++ b/chip/stm32/registers.h @@ -293,6 +293,10 @@ #define STM32_TIM9_BASE 0x40010800 /* STM32L15X only */ #define STM32_TIM10_BASE 0x40010C00 /* STM32L15X only */ #define STM32_TIM11_BASE 0x40011000 /* STM32L15X only */ +#elif defined(CHIP_FAMILY_STM32F4) +#define STM32_TIM9_BASE 0x40014000 /* STM32F411 only */ +#define STM32_TIM10_BASE 0x40014400 /* STM32F411 only */ +#define STM32_TIM11_BASE 0x40014800 /* STM32F411 only */ #endif /* TIM9-11 */ #define STM32_TIM12_BASE 0x40001800 /* STM32F373 */ #define STM32_TIM13_BASE 0x40001c00 /* STM32F373 */ @@ -382,12 +386,14 @@ typedef volatile struct timer_ctlr timer_ctlr_t; #define DUMMY_GPIO_BANK GPIO_A -#if defined(CHIP_FAMILY_STM32L) +#if defined(CHIP_FAMILY_STM32L) || defined(CHIP_FAMILY_STM32F4) #define STM32_GPIOA_BASE 0x40020000 #define STM32_GPIOB_BASE 0x40020400 #define STM32_GPIOC_BASE 0x40020800 #define STM32_GPIOD_BASE 0x40020C00 #define STM32_GPIOE_BASE 0x40021000 +#define STM32_GPIOF_BASE 0x40021400 +#define STM32_GPIOG_BASE 0x40021800 #define STM32_GPIOH_BASE 0x40021400 #define STM32_GPIO_MODER(b) REG32((b) + 0x00) @@ -408,6 +414,7 @@ typedef volatile struct timer_ctlr timer_ctlr_t; #define GPIO_ALT_I2C 0x4 #define GPIO_ALT_SPI 0x5 #define GPIO_ALT_USART 0x7 +#define GPIO_ALT_I2C_23 0x9 #define GPIO_ALT_USB 0xA #define GPIO_ALT_LCD 0xB #define GPIO_ALT_RI 0xE @@ -453,29 +460,6 @@ typedef volatile struct timer_ctlr timer_ctlr_t; #define GPIO_ALT_FD 0xD #define GPIO_ALT_FE 0xE #define GPIO_ALT_FF 0xF - -#elif defined(CHIP_FAMILY_STM32F4) - -#define STM32_GPIOA_BASE 0x40020000 -#define STM32_GPIOB_BASE 0x40020400 -#define STM32_GPIOC_BASE 0x40020800 -#define STM32_GPIOD_BASE 0x40020C00 -#define STM32_GPIOE_BASE 0x40021000 -#define STM32_GPIOF_BASE 0x40021400 -#define STM32_GPIOG_BASE 0x40021800 -#define STM32_GPIOH_BASE 0x40021C00 - -#define STM32_GPIO_MODER(b) REG32((b) + 0x00) -#define STM32_GPIO_OTYPER(b) REG16((b) + 0x04) -#define STM32_GPIO_OSPEEDR(b) REG32((b) + 0x08) -#define STM32_GPIO_PUPDR(b) REG32((b) + 0x0C) -#define STM32_GPIO_IDR(b) REG16((b) + 0x10) -#define STM32_GPIO_ODR(b) REG16((b) + 0x14) -#define STM32_GPIO_BSRR(b) REG32((b) + 0x18) -#define STM32_GPIO_LCKR(b) REG32((b) + 0x1C) -#define STM32_GPIO_AFRL(b) REG32((b) + 0x20) -#define STM32_GPIO_AFRH(b) REG32((b) + 0x24) - #else #error Unsupported chip variant #endif @@ -984,6 +968,16 @@ typedef volatile struct timer_ctlr timer_ctlr_t; #define STM32F4_HSI_CLOCK 16000000 #define STM32F4_LSI_CLOCK 32000 +#elif defined(CHIP_VARIANT_STM32F411) +/* Required or recommended clocks for stm32f411 */ +#define STM32F4_PLL_REQ 2000000 +#define STM32F4_RTC_REQ 1000000 +#define STM32F4_IO_CLOCK 48000000 +#define STM32F4_USB_REQ 48000000 +#define STM32F4_VCO_CLOCK 384000000 +#define STM32F4_HSI_CLOCK 16000000 +#define STM32F4_LSI_CLOCK 32000 + #else #error "No valid clocks defined" #endif @@ -1841,10 +1835,29 @@ enum dma_channel { STM32_DMAS_USART1_TX = STM32_DMA2_STREAM7, STM32_DMAS_USART1_RX = STM32_DMA2_STREAM5, + /* Legacy naming for uart.c */ STM32_DMAC_USART1_TX = STM32_DMAS_USART1_TX, STM32_DMAC_USART1_RX = STM32_DMAS_USART1_RX, +#if defined(CHIP_VARIANT_STM32F411) + STM32_DMAS_USART2_TX = STM32_DMA1_STREAM6, + STM32_DMAS_USART2_RX = STM32_DMA1_STREAM5, + /* Legacy naming for uart.c */ + STM32_DMAC_USART2_TX = STM32_DMAS_USART2_TX, + STM32_DMAC_USART2_RX = STM32_DMAS_USART2_RX, +#endif + +#if defined(CHIP_VARIANT_STM32F411) + STM32_DMAC_I2C1_TX = STM32_DMA1_STREAM1, + STM32_DMAC_I2C1_RX = STM32_DMA1_STREAM0, + + STM32_DMAC_I2C2_TX = STM32_DMA1_STREAM7, + STM32_DMAC_I2C2_RX = STM32_DMA1_STREAM3, + + STM32_DMAC_I2C3_TX = STM32_DMA1_STREAM4, + STM32_DMAC_I2C3_RX = STM32_DMA1_STREAM2, +#else STM32_DMAC_I2C1_TX = STM32_DMA1_STREAM6, STM32_DMAC_I2C1_RX = STM32_DMA1_STREAM0, @@ -1853,6 +1866,7 @@ enum dma_channel { STM32_DMAC_I2C3_TX = STM32_DMA1_STREAM4, STM32_DMAC_I2C3_RX = STM32_DMA1_STREAM1, +#endif STM32_DMAC_FMPI2C4_TX = STM32_DMA1_STREAM5, STM32_DMAC_FMPI2C4_RX = STM32_DMA1_STREAM2, diff --git a/cts/common/board.py b/cts/common/board.py index 42479e6de3..dd730087ec 100644 --- a/cts/common/board.py +++ b/cts/common/board.py @@ -14,10 +14,12 @@ OCD_SCRIPT_DIR = '/usr/local/share/openocd/scripts' OPENOCD_CONFIGS = { 'stm32l476g-eval': 'board/stm32l4discovery.cfg', 'nucleo-f072rb': 'board/st_nucleo_f0.cfg', + 'nucleo-f411re': 'board/st_nucleo_f4.cfg', } FLASH_OFFSETS = { 'stm32l476g-eval': '0x08000000', 'nucleo-f072rb': '0x08000000', + 'nucleo-f411re': '0x08000000', } @@ -314,4 +316,4 @@ class DeviceUnderTest(Board): # Found your other st-link device serial! self.hla_serial = dut[0] - return
\ No newline at end of file + return |