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>
This commit is contained in:
Gwendal Grignou
2015-02-13 13:07:14 -08:00
committed by chrome-bot
parent 885c02a92d
commit 7719869dac
8 changed files with 357 additions and 25 deletions

155
board/nucleo-f411re/board.c Normal file
View File

@@ -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

View File

@@ -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 */

View File

@@ -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

View File

@@ -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)

View File

@@ -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 */

View File

@@ -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

View File

@@ -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,

View File

@@ -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
return