Skip to content

Commit c2d04bf

Browse files
committed
[stm32f4, stm32f411_blackpill] Initial stm32f4 implementation
1 parent 499626f commit c2d04bf

17 files changed

Lines changed: 2409 additions & 1 deletion

File tree

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
runs-on: ubuntu-latest
2424
strategy:
2525
matrix:
26-
board: [stm32wb55xx_nucleo, pic32cz_curiosity_ultra, stm32h563zi_nucleo]
26+
board: [stm32wb55xx_nucleo, pic32cz_curiosity_ultra, stm32h563zi_nucleo, stm32f411_blackpill]
2727
extra_cflags: ["", "-DWHAL_CFG_NO_TIMEOUT"]
2828
steps:
2929
- uses: actions/checkout@v4
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
_BOARD_DIR := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))
2+
3+
PLATFORM = stm32f4
4+
TESTS ?= clock gpio timer flash
5+
6+
GCC = $(GCC_PATH)arm-none-eabi-gcc
7+
LD = $(GCC_PATH)arm-none-eabi-ld
8+
OBJCOPY = $(GCC_PATH)arm-none-eabi-objcopy
9+
10+
CFLAGS += -Wall -Werror $(INCLUDE) -g3 \
11+
-ffreestanding -nostdlib -mcpu=cortex-m4 -mfloat-abi=hard \
12+
-mfpu=fpv4-sp-d16 -mthumb \
13+
-DPLATFORM_STM32F4 -MMD -MP
14+
LDFLAGS = --omagic -static
15+
16+
LINKER_SCRIPT ?= $(_BOARD_DIR)/linker.ld
17+
18+
INCLUDE += -I$(_BOARD_DIR) -I$(WHAL_DIR)/boards/peripheral
19+
20+
BOARD_SOURCE = $(_BOARD_DIR)/ivt.c
21+
BOARD_SOURCE += $(_BOARD_DIR)/board.c
22+
BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*.c)
23+
BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*/gpio.c)
24+
BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*/clock.c)
25+
BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*/uart.c)
26+
BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*/timer.c)
27+
BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*/supply.c)
28+
BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*/flash.c)
29+
BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*/spi.c)
30+
BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*/rng.c)
31+
BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*/crypto.c)
32+
BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*/block.c)
33+
BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*/stm32f4_*.c)
34+
BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*/systick.c)
35+
36+
# Peripheral devices
37+
include $(WHAL_DIR)/boards/peripheral/Makefile.inc

boards/stm32f411_blackpill/board.c

Lines changed: 288 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,288 @@
1+
/* Board configuration for the WeAct BlackPill STM32F411CEU6 */
2+
3+
#include <stdint.h>
4+
#include <stddef.h>
5+
#include "board.h"
6+
#include <wolfHAL/platform/st/stm32f411xx.h>
7+
#include "peripheral.h"
8+
9+
/* SysTick timing */
10+
volatile uint32_t g_tick = 0;
11+
volatile uint8_t g_waiting = 0;
12+
volatile uint8_t g_tickOverflow = 0;
13+
14+
void SysTick_Handler()
15+
{
16+
uint32_t tickBefore = g_tick++;
17+
if (g_waiting) {
18+
if (tickBefore > g_tick)
19+
g_tickOverflow = 1;
20+
}
21+
}
22+
23+
uint32_t Board_GetTick(void)
24+
{
25+
return g_tick;
26+
}
27+
28+
whal_Timeout g_whalTimeout = {
29+
.timeoutTicks = 1000, /* 1s timeout */
30+
.GetTick = Board_GetTick,
31+
};
32+
33+
/* STM32F411CE sector layout (512 KB) */
34+
static const whal_Stm32f4Flash_Sector g_flashSectors[] = {
35+
{ .addr = 0x08000000, .size = 0x04000 }, /* Sector 0: 16 KB */
36+
{ .addr = 0x08004000, .size = 0x04000 }, /* Sector 1: 16 KB */
37+
{ .addr = 0x08008000, .size = 0x04000 }, /* Sector 2: 16 KB */
38+
{ .addr = 0x0800C000, .size = 0x04000 }, /* Sector 3: 16 KB */
39+
{ .addr = 0x08010000, .size = 0x10000 }, /* Sector 4: 64 KB */
40+
{ .addr = 0x08020000, .size = 0x20000 }, /* Sector 5: 128 KB */
41+
{ .addr = 0x08040000, .size = 0x20000 }, /* Sector 6: 128 KB */
42+
{ .addr = 0x08060000, .size = 0x20000 }, /* Sector 7: 128 KB */
43+
};
44+
#define FLASH_SECTOR_COUNT (sizeof(g_flashSectors) / sizeof(g_flashSectors[0]))
45+
46+
/* Clock */
47+
whal_Clock g_whalClock = {
48+
WHAL_STM32F411_RCC_PLL_DEVICE,
49+
50+
.cfg = &(whal_Stm32f4Rcc_Cfg) {
51+
.sysClkSrc = WHAL_STM32F4_RCC_SYSCLK_SRC_PLL,
52+
.sysClkCfg = &(whal_Stm32f4Rcc_PllClkCfg) {
53+
.clkSrc = WHAL_STM32F4_RCC_PLLCLK_SRC_HSE,
54+
/* HSE = 25 MHz, PLL: (25 / 25) * 200 / 2 = 100 MHz */
55+
.m = 25,
56+
.n = 200,
57+
.p = 0, /* 0 = div by 2 */
58+
.q = 4, /* USB: 200 / 4 = 50 MHz (close to 48, acceptable) */
59+
},
60+
},
61+
};
62+
63+
static const whal_Stm32f4Rcc_Clk g_clocks[] = {
64+
{WHAL_STM32F411_GPIOA_CLOCK},
65+
{WHAL_STM32F411_GPIOC_CLOCK},
66+
{WHAL_STM32F411_USART2_CLOCK},
67+
{WHAL_STM32F411_SPI1_CLOCK},
68+
};
69+
#define CLOCK_COUNT (sizeof(g_clocks) / sizeof(g_clocks[0]))
70+
71+
/* GPIO */
72+
whal_Gpio g_whalGpio = {
73+
WHAL_STM32F411_GPIO_DEVICE,
74+
75+
.cfg = &(whal_Stm32f4Gpio_Cfg) {
76+
.pinCfg = (whal_Stm32f4Gpio_PinCfg[PIN_COUNT]) {
77+
[LED_PIN] = { /* LED on PC13 (active low) */
78+
.port = WHAL_STM32F4_GPIO_PORT_C,
79+
.pin = 13,
80+
.mode = WHAL_STM32F4_GPIO_MODE_OUT,
81+
.outType = WHAL_STM32F4_GPIO_OUTTYPE_PUSHPULL,
82+
.speed = WHAL_STM32F4_GPIO_SPEED_LOW,
83+
.pull = WHAL_STM32F4_GPIO_PULL_NONE,
84+
.altFn = 0,
85+
},
86+
[UART_TX_PIN] = { /* USART2 TX on PA2 (AF7) */
87+
.port = WHAL_STM32F4_GPIO_PORT_A,
88+
.pin = 2,
89+
.mode = WHAL_STM32F4_GPIO_MODE_ALTFN,
90+
.outType = WHAL_STM32F4_GPIO_OUTTYPE_PUSHPULL,
91+
.speed = WHAL_STM32F4_GPIO_SPEED_FAST,
92+
.pull = WHAL_STM32F4_GPIO_PULL_UP,
93+
.altFn = 7,
94+
},
95+
[UART_RX_PIN] = { /* USART2 RX on PA3 (AF7) */
96+
.port = WHAL_STM32F4_GPIO_PORT_A,
97+
.pin = 3,
98+
.mode = WHAL_STM32F4_GPIO_MODE_ALTFN,
99+
.outType = WHAL_STM32F4_GPIO_OUTTYPE_PUSHPULL,
100+
.speed = WHAL_STM32F4_GPIO_SPEED_FAST,
101+
.pull = WHAL_STM32F4_GPIO_PULL_UP,
102+
.altFn = 7,
103+
},
104+
[SPI_SCK_PIN] = { /* SPI1 SCK on PA5 (AF5) */
105+
.port = WHAL_STM32F4_GPIO_PORT_A,
106+
.pin = 5,
107+
.mode = WHAL_STM32F4_GPIO_MODE_ALTFN,
108+
.outType = WHAL_STM32F4_GPIO_OUTTYPE_PUSHPULL,
109+
.speed = WHAL_STM32F4_GPIO_SPEED_FAST,
110+
.pull = WHAL_STM32F4_GPIO_PULL_NONE,
111+
.altFn = 5,
112+
},
113+
[SPI_MISO_PIN] = { /* SPI1 MISO on PA6 (AF5) */
114+
.port = WHAL_STM32F4_GPIO_PORT_A,
115+
.pin = 6,
116+
.mode = WHAL_STM32F4_GPIO_MODE_ALTFN,
117+
.outType = WHAL_STM32F4_GPIO_OUTTYPE_PUSHPULL,
118+
.speed = WHAL_STM32F4_GPIO_SPEED_FAST,
119+
.pull = WHAL_STM32F4_GPIO_PULL_NONE,
120+
.altFn = 5,
121+
},
122+
[SPI_MOSI_PIN] = { /* SPI1 MOSI on PA7 (AF5) */
123+
.port = WHAL_STM32F4_GPIO_PORT_A,
124+
.pin = 7,
125+
.mode = WHAL_STM32F4_GPIO_MODE_ALTFN,
126+
.outType = WHAL_STM32F4_GPIO_OUTTYPE_PUSHPULL,
127+
.speed = WHAL_STM32F4_GPIO_SPEED_FAST,
128+
.pull = WHAL_STM32F4_GPIO_PULL_NONE,
129+
.altFn = 5,
130+
},
131+
},
132+
.pinCount = PIN_COUNT,
133+
},
134+
};
135+
136+
/* Timer */
137+
whal_Timer g_whalTimer = {
138+
WHAL_CORTEX_M4_SYSTICK_DEVICE,
139+
140+
.cfg = &(whal_SysTick_Cfg) {
141+
.cyclesPerTick = 100000000 / 1000, /* 100 MHz / 1 kHz = 1 ms tick */
142+
.clkSrc = WHAL_SYSTICK_CLKSRC_SYSCLK,
143+
.tickInt = WHAL_SYSTICK_TICKINT_ENABLED,
144+
},
145+
};
146+
147+
/* UART */
148+
whal_Uart g_whalUart = {
149+
WHAL_STM32F411_USART2_DEVICE,
150+
151+
.cfg = &(whal_Stm32f4Uart_Cfg) {
152+
.timeout = &g_whalTimeout,
153+
.brr = WHAL_STM32F4_UART_BRR(50000000, 115200),
154+
},
155+
};
156+
157+
/* SPI */
158+
whal_Spi g_whalSpi = {
159+
WHAL_STM32F411_SPI1_DEVICE,
160+
161+
.cfg = &(whal_Stm32f4Spi_Cfg) {
162+
.pclk = 100000000,
163+
.timeout = &g_whalTimeout,
164+
},
165+
};
166+
167+
/* Flash */
168+
whal_Flash g_whalFlash = {
169+
WHAL_STM32F411_FLASH_DEVICE,
170+
171+
.cfg = &(whal_Stm32f4Flash_Cfg) {
172+
.startAddr = 0x08000000,
173+
.size = 0x80000, /* 512 KB */
174+
.sectors = g_flashSectors,
175+
.sectorCount = FLASH_SECTOR_COUNT,
176+
.timeout = &g_whalTimeout,
177+
},
178+
};
179+
180+
void Board_WaitMs(size_t ms)
181+
{
182+
uint32_t startCount = g_tick;
183+
while ((g_tick - startCount) < ms)
184+
;
185+
}
186+
187+
/*
188+
* Flash latency for 100 MHz at 2.7-3.6V: 3 wait states (Table 5 in RM0383)
189+
*
190+
* RCC_CFGR APB1 prescaler (PPRE1[2:0], bits 12:10):
191+
* 100 = AHB clock divided by 2 => APB1 = 50 MHz
192+
* APB2 prescaler (PPRE2[2:0], bits 15:13):
193+
* 0xx = AHB clock not divided => APB2 = 100 MHz
194+
*/
195+
#define FLASH_ACR_ADDR 0x40023C00
196+
#define FLASH_ACR_LATENCY_100MHZ 3
197+
#define RCC_CFGR_ADDR 0x40023808
198+
#define RCC_CFGR_PPRE1_DIV2 (0x4UL << 10)
199+
200+
whal_Error Board_Init(void)
201+
{
202+
whal_Error err;
203+
204+
/* Set flash latency before increasing clock speed */
205+
*(volatile uint32_t *)FLASH_ACR_ADDR = FLASH_ACR_LATENCY_100MHZ;
206+
207+
err = whal_Clock_Init(&g_whalClock);
208+
if (err)
209+
return err;
210+
211+
/* Set APB1 prescaler to /2 (50 MHz max for APB1) */
212+
*(volatile uint32_t *)RCC_CFGR_ADDR |= RCC_CFGR_PPRE1_DIV2;
213+
214+
/* Enable clocks */
215+
for (size_t i = 0; i < CLOCK_COUNT; i++) {
216+
err = whal_Clock_Enable(&g_whalClock, &g_clocks[i]);
217+
if (err)
218+
return err;
219+
}
220+
221+
err = whal_Gpio_Init(&g_whalGpio);
222+
if (err)
223+
return err;
224+
225+
err = whal_Uart_Init(&g_whalUart);
226+
if (err)
227+
return err;
228+
229+
err = whal_Spi_Init(&g_whalSpi);
230+
if (err)
231+
return err;
232+
233+
err = whal_Timer_Init(&g_whalTimer);
234+
if (err)
235+
return err;
236+
237+
err = whal_Timer_Start(&g_whalTimer);
238+
if (err)
239+
return err;
240+
241+
err = Peripheral_Init();
242+
if (err)
243+
return err;
244+
245+
return WHAL_SUCCESS;
246+
}
247+
248+
whal_Error Board_Deinit(void)
249+
{
250+
whal_Error err;
251+
252+
err = Peripheral_Deinit();
253+
if (err)
254+
return err;
255+
256+
err = whal_Timer_Stop(&g_whalTimer);
257+
if (err)
258+
return err;
259+
260+
err = whal_Timer_Deinit(&g_whalTimer);
261+
if (err)
262+
return err;
263+
264+
err = whal_Spi_Deinit(&g_whalSpi);
265+
if (err)
266+
return err;
267+
268+
err = whal_Uart_Deinit(&g_whalUart);
269+
if (err)
270+
return err;
271+
272+
err = whal_Gpio_Deinit(&g_whalGpio);
273+
if (err)
274+
return err;
275+
276+
/* Disable clocks */
277+
for (size_t i = 0; i < CLOCK_COUNT; i++) {
278+
err = whal_Clock_Disable(&g_whalClock, &g_clocks[i]);
279+
if (err)
280+
return err;
281+
}
282+
283+
err = whal_Clock_Deinit(&g_whalClock);
284+
if (err)
285+
return err;
286+
287+
return WHAL_SUCCESS;
288+
}

boards/stm32f411_blackpill/board.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#ifndef BOARD_H
2+
#define BOARD_H
3+
4+
#include <stdint.h>
5+
#include <stddef.h>
6+
#include <wolfHAL/wolfHAL.h>
7+
8+
extern whal_Clock g_whalClock;
9+
extern whal_Gpio g_whalGpio;
10+
extern whal_Timer g_whalTimer;
11+
extern whal_Uart g_whalUart;
12+
extern whal_Spi g_whalSpi;
13+
extern whal_Flash g_whalFlash;
14+
15+
extern whal_Timeout g_whalTimeout;
16+
extern volatile uint32_t g_tick;
17+
18+
enum {
19+
LED_PIN,
20+
UART_TX_PIN,
21+
UART_RX_PIN,
22+
SPI_SCK_PIN,
23+
SPI_MISO_PIN,
24+
SPI_MOSI_PIN,
25+
PIN_COUNT,
26+
};
27+
28+
#define BOARD_LED_PIN 0
29+
30+
/* Flash test address: last sector (sector 7, 128KB at 0x08060000) */
31+
#define BOARD_FLASH_TEST_ADDR 0x08060000
32+
#define BOARD_FLASH_SECTOR_SZ 0x20000
33+
#define BOARD_FLASH_WRITE_SZ 4
34+
35+
whal_Error Board_Init(void);
36+
whal_Error Board_Deinit(void);
37+
void Board_WaitMs(size_t ms);
38+
39+
#endif /* BOARD_H */

0 commit comments

Comments
 (0)