1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

boards: add WeAct-f411ce board

The WeAct-F411CE is a blackpill-like board with a STM32F411CE.
It can be flashed using the vendor-provided bootloader.
This commit is contained in:
Benjamin Valentin 2019-11-17 01:55:29 +01:00 committed by Benjamin Valentin
parent a3f8a381ab
commit b20ec93991
10 changed files with 590 additions and 0 deletions

View File

@ -0,0 +1,66 @@
/*
* Copyright (C) 2018 Freie Universität Berlin
* 2017 OTA keys S.A.
* 2018 Inria
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup boards_common_stm32
* @{
*
* @file
* @brief Configure STM32F4 clock to 96MHz using PLL
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @author Vincent Dupont <vincent@otakeys.com>
* @author Alexandre Abadie <alexandre.abadie@inria.fr>
*/
#ifndef F4_CFG_CLOCK_96_25_1_H
#define F4_CFG_CLOCK_96_25_1_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @name Clock settings
*
* @note This is auto-generated from
* `cpu/stm32_common/dist/clk_conf/clk_conf.c`
* @{
*/
/* give the target core clock (HCLK) frequency [in Hz],
* maximum: 100MHz */
#define CLOCK_CORECLOCK (96000000U)
/* 0: no external high speed crystal available
* else: actual crystal frequency [in Hz] */
#define CLOCK_HSE (25000000U)
/* 0: no external low speed crystal available,
* 1: external crystal available (always 32.768kHz) */
#define CLOCK_LSE (1U)
/* peripheral clock setup */
#define CLOCK_AHB_DIV RCC_CFGR_HPRE_DIV1
#define CLOCK_AHB (CLOCK_CORECLOCK / 1)
#define CLOCK_APB1_DIV RCC_CFGR_PPRE1_DIV2 /* max 50MHz */
#define CLOCK_APB1 (CLOCK_CORECLOCK / 2)
#define CLOCK_APB2_DIV RCC_CFGR_PPRE2_DIV1 /* max 100MHz */
#define CLOCK_APB2 (CLOCK_CORECLOCK / 1)
/* Main PLL factors */
#define CLOCK_PLL_M (25)
#define CLOCK_PLL_N (384)
#define CLOCK_PLL_P (4)
#define CLOCK_PLL_Q (8)
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* F4_CFG_CLOCK_96_25_1_H */
/** @} */

View File

@ -0,0 +1,3 @@
MODULE = board
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,11 @@
ifneq (,$(filter saul_default,$(USEMODULE)))
USEMODULE += saul_gpio
endif
ifeq (,$(filter stdio_% slipdev_stdio,$(USEMODULE)))
USEMODULE += stdio_cdc_acm
endif
ifneq (,$(filter mtd,$(USEMODULE)))
USEMODULE += mtd_spi_nor
endif

View File

@ -0,0 +1,12 @@
CPU = stm32
CPU_MODEL = stm32f411ceu6
# Put defined MCU peripherals here (in alphabetical order)
FEATURES_PROVIDED += periph_adc
FEATURES_PROVIDED += periph_i2c
FEATURES_PROVIDED += periph_pwm
FEATURES_PROVIDED += periph_rtc
FEATURES_PROVIDED += periph_spi
FEATURES_PROVIDED += periph_timer
FEATURES_PROVIDED += periph_uart
FEATURES_PROVIDED += periph_usbdev

View File

@ -0,0 +1,10 @@
INCLUDES += -I$(RIOTBOARD)/common/stm32/include
# default to flashing over USB
PROGRAMMER ?= dfu-util
DFU_USB_ID ?= 0483:df11
DFU_FLAGS ?= -a 0 -s 0x08000000:leave
ROM_OFFSET ?= 0x0
# Setup of programmer and serial is shared between STM32 based boards
include $(RIOTMAKE)/boards/stm32.inc.mk

View File

@ -0,0 +1,63 @@
/*
* Copyright (C) 2019 Benjamin Valentin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup boards_weact-f411ce
* @{
*
* @file
* @brief Board initialization code for the WeAct-F411CE board.
*
* @author Benjamin Valentin <benpicco@googlemail.com>
*
* @}
*/
#include "board.h"
#include "cpu.h"
#include "mtd.h"
#include "mtd_spi_nor.h"
#include "periph/gpio.h"
#ifdef MODULE_MTD
/* AT25SF041 */
static const mtd_spi_nor_params_t _weact_nor_params = {
.opcode = &mtd_spi_nor_opcode_default,
.wait_chip_erase = 4800LU * US_PER_MS,
.wait_32k_erase = 300LU * US_PER_MS,
.wait_sector_erase = 70LU * US_PER_MS,
.wait_4k_erase = 70LU * US_PER_MS,
.wait_chip_wake_up = 1LU * US_PER_MS,
.clk = WEACT_411CE_NOR_SPI_CLK,
.flag = WEACT_411CE_NOR_FLAGS,
.spi = WEACT_411CE_NOR_SPI_DEV,
.mode = WEACT_411CE_NOR_SPI_MODE,
.cs = WEACT_411CE_NOR_SPI_CS,
.addr_width = 3,
};
static mtd_spi_nor_t weact_nor_dev = {
.base = {
.driver = &mtd_spi_nor_driver,
.page_size = WEACT_411CE_NOR_PAGE_SIZE,
.pages_per_sector = WEACT_411CE_NOR_PAGES_PER_SECTOR,
.sector_count = WEACT_411CE_NOR_SECTOR_COUNT,
},
.params = &_weact_nor_params,
};
mtd_dev_t *mtd0 = (mtd_dev_t *)&weact_nor_dev;
#endif /* MODULE_MTD */
void board_init(void)
{
cpu_init();
gpio_init(LED0_PIN, GPIO_OUT);
LED0_OFF;
}

View File

@ -0,0 +1,66 @@
/**
@defgroup boards_weact-f411ce WeAct-F411CE board
@ingroup boards
@brief Support for the WeAct-F411CE Board
## Overview
WeAct-F411CE is a board with the same form-factor as the blue/blackpill,
but with an STM32F411CEU6 and a USB-C connector.
It is available on sites like AliExpress for less than 4€.
## Hardware
![WeAct-F411CE](https://user-images.githubusercontent.com/1301112/69389644-eb5fb080-0ccc-11ea-8002-67d3db851250.png)
### MCU
| MCU | STM32F411CE |
|:---------------- |:--------------------- |
| Family | ARM Cortex-M4F |
| Vendor | ST Microelectronics |
| RAM | 128KiB |
| Flash | 512KiB |
| Frequency | up to 100MHz |
| FPU | yes |
| Timers | 8 (2x watchdog, 1 SysTick, 6x 16-bit) |
| ADCs | 1x 12-bit |
| UARTs | 3 |
| SPIs | 5 |
| I2Cs | 3 |
| RTC | 1 |
| Vcc | 2.0V - 3.6V |
| Datasheet | [Datasheet](https://www.st.com/resource/en/datasheet/stm32f411ce.pdf) |
| Reference Manual | [Reference Manual](https://www.st.com/content/ccc/resource/technical/document/reference_manual/9b/53/39/1c/f7/01/4a/79/DM00119316.pdf/files/DM00119316.pdf/jcr:content/translations/en.DM00119316.pdf) |
## Flashing the device
The device comes with a bootloader that allows flashing via `dfu-util`.
There are two buttons on the board labeled `BOOT0` and `NRST`.
- Press and hold down `NRST` to reset the CPU
- Press `BOOT0` while keeping `NRST` held down
- Release `NRST`, afterwards release `BOOT0`
The board will now show up as `0483:df11` - `STM32 BOOTLOADER` and will accept
firmware using the DFU protocol.
You can upload your RIOT-firmware by typing
```
make BOARD=weact-f411ce flash
```
*Note:* You need to have write permissions to the device.
On Linux you could add yourself to the `plugdev` group and store the following as `/etc/udev/rules.d/99-weact-f411ce.rules`:
```
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="df11", GROUP="plugdev", MODE="660"
```
## UART
stdio is provided through USB CDC ACM so the board can be used
without any extra hardware, save for a USB-C cable.
*/

View File

@ -0,0 +1,105 @@
/*
* Copyright (C) 2019 Benjamin Valentin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup boards_weact-f411ce
*
* @brief Support for the WeAct-F411CE Board
* @{
*
* @file
* @brief Pin definitions and board configuration options
*
* @author Benjamin Valentin <benpicco@googlemail.com>
*/
#ifndef BOARD_H
#define BOARD_H
#ifdef __cplusplus
extern "C" {
#endif
#include "mtd.h"
#include "periph_cpu.h"
#include "timex.h"
/**
* @name Xtimer configuration
* @{
*/
#define XTIMER_BACKOFF (8)
#define XTIMER_OVERHEAD (6)
/** @} */
/**
* @brief Product & Vendor ID taken from example firmware
* that the board was shipped with.
* @{
*/
#define INTERNAL_PERIPHERAL_VID (0x0483)
#define INTERNAL_PERIPHERAL_PID (0x5740)
/** @} */
/**
* @name LED pin definition and handlers
* @{
*/
#define LED0_PORT GPIOC
#define LED0_PIN GPIO_PIN(PORT_C, 13)
#define LED0_MASK (1 << 13)
#define LED0_ON (LED0_PORT->BSRR = (LED0_MASK << 16))
#define LED0_OFF (LED0_PORT->BSRR = (LED0_MASK << 0))
#define LED0_TOGGLE (LED0_PORT->ODR ^= LED0_MASK)
/** @} */
/**
* @name User button pin definition
* @{
*/
#define BTN0_PIN GPIO_PIN(PORT_A, 0)
#define BTN0_MODE GPIO_IN_PU
/** @} */
/**
* @name WeAct-F411CE NOR flash hardware configuration
*
* The pad for the NOR Flash (U3) is not populated.
* You have to solder a serial flash yourself and adjust the parameters.
* @{
*/
#define WEACT_411CE_NOR_PAGE_SIZE (256)
#define WEACT_411CE_NOR_PAGES_PER_SECTOR (16)
#define WEACT_411CE_NOR_SECTOR_COUNT (128)
#define WEACT_411CE_NOR_FLAGS (SPI_NOR_F_SECT_4K | SPI_NOR_F_SECT_32K)
#define WEACT_411CE_NOR_SPI_DEV SPI_DEV(0)
#define WEACT_411CE_NOR_SPI_CLK SPI_CLK_10MHZ
#define WEACT_411CE_NOR_SPI_CS GPIO_PIN(PORT_A, 4)
#define WEACT_411CE_NOR_SPI_MODE SPI_MODE_0
/** @} */
/**
* @name MTD configuration
* @{
*/
extern mtd_dev_t *mtd0;
#define MTD_0 mtd0
/** @} */
/**
* @brief Initialize board specific hardware, including clock, LEDs and std-IO
*/
void board_init(void);
#ifdef __cplusplus
}
#endif
#endif /* BOARD_H */
/** @} */

View File

@ -0,0 +1,53 @@
/*
* Copyright (C) 2019 Benjamin Valentin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup boards_weact-f411ce
* @{
*
* @file
* @brief Board specific configuration of direct mapped GPIOs
*
* @author Benjamin Valentin <benpicco@googlemail.com>
*/
#ifndef GPIO_PARAMS_H
#define GPIO_PARAMS_H
#include "board.h"
#include "saul/periph.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief GPIO pin configuration
*/
static const saul_gpio_params_t saul_gpio_params[] =
{
{
.name = "LED",
.pin = LED0_PIN,
.mode = GPIO_OUT,
.flags = (SAUL_GPIO_INVERTED | SAUL_GPIO_INIT_CLEAR)
},
{
.name = "KEY",
.pin = BTN0_PIN,
.mode = BTN0_MODE,
.flags = SAUL_GPIO_INVERTED
},
};
#ifdef __cplusplus
}
#endif
#endif /* GPIO_PARAMS_H */
/** @} */

View File

@ -0,0 +1,201 @@
/*
* Copyright (C) 2019 Benjamin Valentin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup boards_weact-f411ce
* @{
*
* @file
* @brief Peripheral MCU configuration for the WeAct-F411CE Board
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @author José Ignacio Alamos <jialamos@uc.cl>
* @author Alexandre Abadie <alexandre.abadie@inria.fr>
* @author Benjamin Valentin <benpicco@googlemail.com>
*/
#ifndef PERIPH_CONF_H
#define PERIPH_CONF_H
#include "periph_cpu.h"
#include "f4/cfg_clock_96_25_1.h"
#include "cfg_i2c1_pb8_pb9.h"
#include "cfg_timer_tim5.h"
#include "cfg_usb_otg_fs.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @name UART configuration
* @{
*/
static const uart_conf_t uart_config[] = {
{
.dev = USART2,
.rcc_mask = RCC_APB1ENR_USART2EN,
.rx_pin = GPIO_PIN(PORT_A, 3),
.tx_pin = GPIO_PIN(PORT_A, 2),
.rx_af = GPIO_AF7,
.tx_af = GPIO_AF7,
.bus = APB1,
.irqn = USART2_IRQn,
#ifdef MODULE_PERIPH_DMA
.dma = DMA_STREAM_UNDEF,
.dma_chan = UINT8_MAX,
#endif
},
{
.dev = USART1,
.rcc_mask = RCC_APB2ENR_USART1EN,
.rx_pin = GPIO_PIN(PORT_A, 10),
.tx_pin = GPIO_PIN(PORT_A, 9),
.rx_af = GPIO_AF7,
.tx_af = GPIO_AF7,
.bus = APB2,
.irqn = USART1_IRQn,
#ifdef MODULE_PERIPH_DMA
.dma = DMA_STREAM_UNDEF,
.dma_chan = UINT8_MAX,
#endif
},
};
/* assign ISR vector names */
#define UART_0_ISR isr_usart2
#define UART_1_ISR isr_usart1
/* deduct number of defined UART interfaces */
#define UART_NUMOF ARRAY_SIZE(uart_config)
/** @} */
/** @name PWM configuration
* @{
*/
static const pwm_conf_t pwm_config[] = {
{
.dev = TIM2,
.rcc_mask = RCC_APB1ENR_TIM2EN,
.chan = { { .pin = GPIO_PIN(PORT_A, 15), .cc_chan = 0 },
{ .pin = GPIO_PIN(PORT_B, 3), /* D3 */ .cc_chan = 1 },
{ .pin = GPIO_PIN(PORT_B, 10), /* D6 */ .cc_chan = 2 },
{ .pin = GPIO_UNDEF, .cc_chan = 0 } },
.af = GPIO_AF1,
.bus = APB1
},
{
.dev = TIM3,
.rcc_mask = RCC_APB1ENR_TIM3EN,
.chan = { { .pin = GPIO_PIN(PORT_B, 4), /* D5 */ .cc_chan = 0 },
{ .pin = GPIO_PIN(PORT_C, 7), /* D9 */ .cc_chan = 1 },
{ .pin = GPIO_PIN(PORT_C, 8), .cc_chan = 2 },
{ .pin = GPIO_PIN(PORT_C, 9), .cc_chan = 3 } },
.af = GPIO_AF2,
.bus = APB1
},
};
#define PWM_NUMOF ARRAY_SIZE(pwm_config)
/** @} */
/**
* @name SPI configuration
*
* @note The spi_divtable is auto-generated from
* `cpu/stm32_common/dist/spi_divtable/spi_divtable.c`
* @{
*/
static const uint8_t spi_divtable[2][5] = {
{ /* for APB1 @ 48000000Hz */
7, /* -> 187500Hz */
6, /* -> 375000Hz */
5, /* -> 750000Hz */
2, /* -> 6000000Hz */
1 /* -> 12000000Hz */
},
{ /* for APB2 @ 96000000Hz */
7, /* -> 375000Hz */
7, /* -> 375000Hz */
6, /* -> 750000Hz */
3, /* -> 6000000Hz */
2 /* -> 12000000Hz */
}
};
static const spi_conf_t spi_config[] = {
{ /* U3 - SPI flash */
.dev = SPI1,
.mosi_pin = GPIO_PIN(PORT_A, 7),
.miso_pin = GPIO_PIN(PORT_A, 6),
.sclk_pin = GPIO_PIN(PORT_A, 5),
.cs_pin = GPIO_PIN(PORT_A, 4),
.mosi_af = GPIO_AF5,
.miso_af = GPIO_AF5,
.sclk_af = GPIO_AF5,
.cs_af = GPIO_AF5,
.rccmask = RCC_APB2ENR_SPI1EN,
.apbbus = APB2
},
{
.dev = SPI2,
.mosi_pin = GPIO_PIN(PORT_B, 15),
.miso_pin = GPIO_PIN(PORT_B, 14),
.sclk_pin = GPIO_PIN(PORT_B, 13),
.cs_pin = GPIO_PIN(PORT_B, 12),
.mosi_af = GPIO_AF5,
.miso_af = GPIO_AF5,
.sclk_af = GPIO_AF5,
.cs_af = GPIO_AF5,
.rccmask = RCC_APB1ENR_SPI2EN,
.apbbus = APB1
},
{
.dev = SPI3,
.mosi_pin = GPIO_PIN(PORT_B, 5),
.miso_pin = GPIO_PIN(PORT_B, 4),
.sclk_pin = GPIO_PIN(PORT_B, 3),
.cs_pin = GPIO_PIN(PORT_A, 15),
.mosi_af = GPIO_AF6,
.miso_af = GPIO_AF6,
.sclk_af = GPIO_AF6,
.cs_af = GPIO_AF6,
.rccmask = RCC_APB1ENR_SPI3EN,
.apbbus = APB1
},
};
#define SPI_NUMOF ARRAY_SIZE(spi_config)
/** @} */
/**
* @name ADC configuration
*
* Note that we do not configure all ADC channels,
* and not in the STM32F411 order.
* Feel free to add more if needed.
*
* @{
*/
#define ADC_CONFIG { \
{GPIO_PIN(PORT_A, 0), 0, 0}, \
{GPIO_PIN(PORT_A, 1), 0, 1}, \
{GPIO_PIN(PORT_A, 4), 0, 4}, \
{GPIO_PIN(PORT_B, 0), 0, 8}, \
}
#define ADC_NUMOF (4)
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* PERIPH_CONF_H */
/** @} */