STM32 Nucleo-F401RE¶
Support for the STM32 Nucleo-F401RE.
Overview¶
The Nucleo-F401 is a board from ST’s Nucleo family supporting a ARM Cortex-M4 STM32F401RE microcontroller with 96Kb of SRAM and 512Kb of ROM Flash.
Hardware¶
MCU¶
MCU | STM32F401RE |
---|---|
Family | ARM Cortex-M4 |
Vendor | ST Microelectronics |
RAM | 96Kb |
Flash | 512Kb |
Frequency | up to 84MHz |
FPU | yes |
Timers | 11 (2x watchdog, 1 SysTick, 6x 16-bit, 2x 32-bit [TIM2]) |
ADCs | 1x 12-bit |
UARTs | 3 |
SPIs | 4 |
I2Cs | 3 |
RTC | 1 |
Vcc | 2.0V - 3.6V |
Datasheet | Datasheet |
Reference Manual | Reference Manual |
Programming Manual | Programming Manual |
Board Manual | Board Manual |
MCU¶
MCU | STM32F401RE |
---|---|
Family | ARM Cortex-M4 |
Vendor | ST Microelectronics |
RAM | 96Kb |
Flash | 512Kb |
Frequency | up to 84MHz |
FPU | yes |
Timers | 11 (2x watchdog, 1 SysTick, 6x 16-bit, 2x 32-bit [TIM2]) |
ADCs | 1x 12-bit |
UARTs | 3 |
SPIs | 4 |
I2Cs | 3 |
RTC | 1 |
Vcc | 2.0V - 3.6V |
Datasheet | Datasheet |
Reference Manual | Reference Manual |
Programming Manual | Programming Manual |
Board Manual | Board Manual |
Implementation Status¶
Device | ID | Supported | Comments |
---|---|---|---|
MCU | STM32F401RE | partly | Energy saving modes not fully utilized |
Low-level driver | GPIO | yes | |
PWM | yes (7 pins available)) | ||
UART | 2 UARTs | USART2 via STLink/USB or D0(RX)/D1(TX) and USART6 on PA12(RX)/PA11(TX) | |
I2C | 1 I2C | ||
SPI | 1 SPI | ||
USB | no | ||
Timer | 2 32 bit timers |
Flashing the device¶
The ST Nucleo-F401RE board includes an on-board ST-LINK V2 programmer. The easiest way to program the board is to use OpenOCD. Once you have installed OpenOCD (look here for installation instructions), you can flash the board simply by typing
1 | make BOARD=nucleo-f401 flash
|
1 | make BOARD=nucleo-f401 debug
|
Supported Toolchains¶
For using the ST Nucleo-F401 board we strongly recommend the usage of the GNU Tools for ARM Embedded Processors toolchain.
Issues with old Hardware Revisions¶
Some Nucleo 64 Boards come in different hardware revisions, which is located on a sticker at the backside of the board. As discussed in issue #6721, there are some issues with the external clock sources in revisions smaller than C-03
. (This would also be true for all boards with board ID MB1136
). The revision C-01
has a different configuration for the high speed external clock (HSE), which is used in RIOT. This could be fixed by reconfiguring some solder bridges as mentioned in the user manual, section 6.7.1. The other issue is, that revision C-01
also has no 32kHz oscillator, so the RTC module of RIOT cannot be used.
-
CLOCK_CORECLOCK
¶ 1
(84000000U)
-
CLOCK_HSE
¶ 1
(8000000U)
-
CLOCK_LSE
¶ 1
(1)
-
CLOCK_AHB_DIV
¶ 1
RCC_CFGR_HPRE_DIV1
-
CLOCK_AHB
¶ 1
(CLOCK_CORECLOCK / 1)
-
CLOCK_APB1_DIV
¶ 1
RCC_CFGR_PPRE1_DIV2 /* max 42MHz */
-
CLOCK_APB1
¶ 1
(CLOCK_CORECLOCK / 2)
-
CLOCK_APB2_DIV
¶ 1
RCC_CFGR_PPRE2_DIV1 /* max 84MHz */
-
CLOCK_APB2
¶ 1
(CLOCK_CORECLOCK / 1)
-
CLOCK_PLL_M
¶ 1
(4)
-
CLOCK_PLL_N
¶ 1
(168)
-
CLOCK_PLL_P
¶ 1
(4)
-
CLOCK_PLL_Q
¶ 1
(7)
-
const timer_conf_t
timer_config
()¶ 1 2 3 4 5 6 7 8 9
= { { .dev = TIM5, .max = 0xffffffff, .rcc_mask = RCC_APB1ENR_TIM5EN, .bus = APB1, .irqn = TIM5_IRQn } }
-
TIMER_0_ISR
¶ 1
isr_tim5
-
TIMER_NUMOF
¶ 1
(sizeof(timer_config) / sizeof(timer_config[0]))
-
const uart_conf_t
uart_config
()¶
-
UART_0_ISR
¶ 1
(isr_usart2)
-
UART_0_DMA_ISR
¶ 1
(isr_dma1_stream6)
-
UART_1_ISR
¶ 1
(isr_usart1)
-
UART_1_DMA_ISR
¶ 1
(isr_dma1_stream6)
-
UART_2_ISR
¶ 1
(isr_usart6)
-
UART_2_DMA_ISR
¶ 1
(isr_dma1_stream6)
-
UART_NUMOF
¶ 1
(sizeof(uart_config) / sizeof(uart_config[0]))
-
const pwm_conf_t
pwm_config
()¶ 1 2 3 4 5 6 7 8 9 10 11 12
= { { .dev = TIM2, .rcc_mask = RCC_APB1ENR_TIM2EN, .chan = { { .pin = GPIO_PIN(PORT_A, 15) , .cc_chan = 0 }, { .pin = GPIO_PIN(PORT_B, 3) , .cc_chan = 1 }, { .pin = GPIO_PIN(PORT_B, 10) , .cc_chan = 2 }, { .pin = GPIO_UNDEF, .cc_chan = 0 } }, .af = GPIO_AF1, .bus = APB1 }, }
-
PWM_NUMOF
¶ 1
(sizeof(pwm_config) / sizeof(pwm_config[0]))
-
const qdec_conf_t
qdec_config
()¶ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
= { { .dev = TIM3, .max = 0xffffffff, .rcc_mask = RCC_APB1ENR_TIM3EN, .chan = { { .pin = GPIO_PIN(PORT_A, 6), .cc_chan = 0 }, { .pin = GPIO_PIN(PORT_A, 7), .cc_chan = 1 } }, .af = GPIO_AF2, .bus = APB1, .irqn = TIM3_IRQn }, { .dev = TIM4, .max = 0xffffffff, .rcc_mask = RCC_APB1ENR_TIM4EN, .chan = { { .pin = GPIO_PIN(PORT_B, 6), .cc_chan = 0 }, { .pin = GPIO_PIN(PORT_B, 7), .cc_chan = 1 } }, .af = GPIO_AF2, .bus = APB1, .irqn = TIM4_IRQn }, }
-
QDEC_0_ISR
¶ 1
isr_tim3
-
QDEC_1_ISR
¶ 1
isr_tim4
-
QDEC_NUMOF
¶ 1
(sizeof(qdec_config) / sizeof(qdec_config[0]))
-
const uint8_t
spi_divtable
()¶ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
= { { 7, 6, 4, 2, 1 }, { 7, 7, 5, 3, 2 } }
-
const spi_conf_t
spi_config
()¶
-
SPI_NUMOF
¶ 1
(sizeof(spi_config) / sizeof(spi_config[0]))
-
const i2c_conf_t
i2c_config
()¶ 1 2 3 4 5 6 7 8 9 10 11 12 13 14
= { { .dev = I2C1, .speed = I2C_SPEED_NORMAL, .scl_pin = GPIO_PIN(PORT_B, 8), .sda_pin = GPIO_PIN(PORT_B, 9), .scl_af = GPIO_AF4, .sda_af = GPIO_AF4, .bus = APB1, .rcc_mask = RCC_APB1ENR_I2C1EN, .clk = CLOCK_APB1, .irqn = I2C1_EV_IRQn } }
-
I2C_0_ISR
¶ 1
isr_i2c1_ev
-
I2C_NUMOF
¶ 1
(sizeof(i2c_config) / sizeof(i2c_config[0]))
-
ADC_NUMOF
¶ 1
(6U)
-
ADC_CONFIG
¶ 1 2 3 4 5 6 7 8
{ \ {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}, \ {GPIO_PIN(PORT_C, 1), 0, 11}, \ {GPIO_PIN(PORT_C, 0), 0, 10}, \ }
-
RTC_NUMOF
¶ 1
(1)