Skip to content

Commit b5999a2

Browse files
committed
Add generic wolfHAL Ethernet port with STM32H563ZI Nucleo board support
1 parent d6fe35e commit b5999a2

12 files changed

Lines changed: 1136 additions & 0 deletions

File tree

src/port/wolfHAL/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
build/

src/port/wolfHAL/Makefile

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
ROOT = $(CURDIR)/../../..
2+
PORT_DIR = $(ROOT)/src/port/wolfHAL
3+
4+
BOARD_DIR = $(PORT_DIR)/boards/$(BOARD)
5+
6+
ifeq ($(BOARD),)
7+
ifeq ($(MAKECMDGOALS),clean)
8+
clean:
9+
rm -rf build
10+
.PHONY: clean
11+
else
12+
$(error BOARD is required. Usage: make BOARD=stm32h563zi_nucleo)
13+
endif
14+
else
15+
include $(BOARD_DIR)/board.mk
16+
17+
SOURCE = $(PORT_DIR)/main.c
18+
SOURCE += $(PORT_DIR)/wolfhal_eth.c
19+
SOURCE += $(ROOT)/src/wolfip.c
20+
SOURCE += $(BOARD_SOURCE)
21+
22+
BUILD_DIR = build/$(BOARD)
23+
OBJECTS = $(patsubst %.c,$(BUILD_DIR)/%.o,$(SOURCE))
24+
DEPENDS = $(OBJECTS:.o=.d)
25+
26+
all: $(BUILD_DIR)/app.bin
27+
28+
$(BUILD_DIR)/%.o: %.c Makefile
29+
@mkdir -p $(dir $@)
30+
$(GCC) $(CFLAGS) -c -o $@ $<
31+
32+
.SECONDARY:
33+
$(BUILD_DIR)/%.elf: $(OBJECTS) $(LINKER_SCRIPT)
34+
@mkdir -p $(dir $@)
35+
$(GCC) $(CFLAGS) $(LDFLAGS) -T $(LINKER_SCRIPT) -o $@ $(OBJECTS) $(LDLIBS)
36+
37+
$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf
38+
$(OBJCOPY) $^ -O binary $@
39+
40+
.PHONY: clean size
41+
clean:
42+
rm -rf build
43+
44+
size: $(BUILD_DIR)/app.elf
45+
arm-none-eabi-size $<
46+
47+
-include $(DEPENDS)
48+
49+
endif
Lines changed: 320 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,320 @@
1+
/* board.c
2+
*
3+
* Copyright (C) 2024-2026 wolfSSL Inc.
4+
*
5+
* Minimal board configuration for STM32H563ZI Nucleo-144
6+
* Only sets up what's needed for wolfIP: clocks, GPIO, Ethernet, PHY.
7+
*
8+
* This file is part of wolfIP TCP/IP stack.
9+
*
10+
* wolfIP is free software; you can redistribute it and/or modify
11+
* it under the terms of the GNU General Public License as published by
12+
* the Free Software Foundation; either version 3 of the License, or
13+
* (at your option) any later version.
14+
*
15+
* wolfIP is distributed in the hope that it will be useful,
16+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18+
* GNU General Public License for more details.
19+
*
20+
* You should have received a copy of the GNU General Public License
21+
* along with this program; if not, write to the Free Software
22+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
23+
*/
24+
25+
#include <stdint.h>
26+
#include <stddef.h>
27+
#include "board.h"
28+
#include <wolfHAL/platform/st/stm32h563xx.h>
29+
#include <wolfHAL/eth_phy/lan8742a.h>
30+
31+
/* SysTick timing */
32+
volatile uint32_t g_tick = 0;
33+
34+
void SysTick_Handler(void)
35+
{
36+
g_tick++;
37+
}
38+
39+
uint32_t board_get_tick(void)
40+
{
41+
return g_tick;
42+
}
43+
44+
whal_Timeout g_whalTimeout = {
45+
.timeoutTicks = 1000,
46+
.GetTick = board_get_tick,
47+
};
48+
49+
/* Clock: PLL1 from HSI to 168 MHz */
50+
static whal_Clock clock = {
51+
WHAL_STM32H563_RCC_PLL_DEVICE,
52+
53+
.cfg = &(whal_Stm32h5Rcc_Cfg) {
54+
.sysClkSrc = WHAL_STM32H5_RCC_SYSCLK_SRC_PLL1,
55+
.sysClkCfg = &(whal_Stm32h5Rcc_PllClkCfg) {
56+
.clkSrc = WHAL_STM32H5_RCC_PLLCLK_SRC_HSI,
57+
.m = 8,
58+
.n = 62,
59+
.p = 2,
60+
.q = 2,
61+
.r = 2,
62+
},
63+
},
64+
};
65+
66+
static const whal_Stm32h5Rcc_Clk clocks[] = {
67+
{WHAL_STM32H563_GPIOA_CLOCK},
68+
{WHAL_STM32H563_GPIOB_CLOCK},
69+
{WHAL_STM32H563_GPIOC_CLOCK},
70+
{WHAL_STM32H563_GPIOD_CLOCK},
71+
{WHAL_STM32H563_GPIOG_CLOCK},
72+
{WHAL_STM32H563_USART2_CLOCK},
73+
{WHAL_STM32H563_SBS_CLOCK},
74+
};
75+
#define CLOCK_COUNT (sizeof(clocks) / sizeof(clocks[0]))
76+
77+
static const whal_Stm32h5Rcc_Clk eth_clocks[] = {
78+
{WHAL_STM32H563_ETH_CLOCK},
79+
{WHAL_STM32H563_ETHTX_CLOCK},
80+
{WHAL_STM32H563_ETHRX_CLOCK},
81+
};
82+
#define ETH_CLOCK_COUNT (sizeof(eth_clocks) / sizeof(eth_clocks[0]))
83+
84+
/* GPIO: only RMII pins */
85+
static whal_Gpio gpio = {
86+
WHAL_STM32H563_GPIO_DEVICE,
87+
88+
.cfg = &(whal_Stm32h5Gpio_Cfg) {
89+
.pinCfg = (whal_Stm32h5Gpio_PinCfg[PIN_COUNT]) {
90+
[UART_TX_PIN] = WHAL_STM32H5_GPIO_PIN(
91+
WHAL_STM32H5_GPIO_PORT_D, 5, WHAL_STM32H5_GPIO_MODE_ALTFN,
92+
WHAL_STM32H5_GPIO_OUTTYPE_PUSHPULL, WHAL_STM32H5_GPIO_SPEED_FAST,
93+
WHAL_STM32H5_GPIO_PULL_UP, 7),
94+
[UART_RX_PIN] = WHAL_STM32H5_GPIO_PIN(
95+
WHAL_STM32H5_GPIO_PORT_D, 6, WHAL_STM32H5_GPIO_MODE_ALTFN,
96+
WHAL_STM32H5_GPIO_OUTTYPE_PUSHPULL, WHAL_STM32H5_GPIO_SPEED_FAST,
97+
WHAL_STM32H5_GPIO_PULL_UP, 7),
98+
[ETH_RMII_REF_CLK_PIN] = WHAL_STM32H5_GPIO_PIN(
99+
WHAL_STM32H5_GPIO_PORT_A, 1, WHAL_STM32H5_GPIO_MODE_ALTFN,
100+
0, WHAL_STM32H5_GPIO_SPEED_HIGH,
101+
WHAL_STM32H5_GPIO_PULL_NONE, 11),
102+
[ETH_RMII_MDIO_PIN] = WHAL_STM32H5_GPIO_PIN(
103+
WHAL_STM32H5_GPIO_PORT_A, 2, WHAL_STM32H5_GPIO_MODE_ALTFN,
104+
0, WHAL_STM32H5_GPIO_SPEED_HIGH,
105+
WHAL_STM32H5_GPIO_PULL_NONE, 11),
106+
[ETH_RMII_MDC_PIN] = WHAL_STM32H5_GPIO_PIN(
107+
WHAL_STM32H5_GPIO_PORT_C, 1, WHAL_STM32H5_GPIO_MODE_ALTFN,
108+
0, WHAL_STM32H5_GPIO_SPEED_HIGH,
109+
WHAL_STM32H5_GPIO_PULL_NONE, 11),
110+
[ETH_RMII_CRS_DV_PIN] = WHAL_STM32H5_GPIO_PIN(
111+
WHAL_STM32H5_GPIO_PORT_A, 7, WHAL_STM32H5_GPIO_MODE_ALTFN,
112+
0, WHAL_STM32H5_GPIO_SPEED_HIGH,
113+
WHAL_STM32H5_GPIO_PULL_NONE, 11),
114+
[ETH_RMII_RXD0_PIN] = WHAL_STM32H5_GPIO_PIN(
115+
WHAL_STM32H5_GPIO_PORT_C, 4, WHAL_STM32H5_GPIO_MODE_ALTFN,
116+
0, WHAL_STM32H5_GPIO_SPEED_HIGH,
117+
WHAL_STM32H5_GPIO_PULL_NONE, 11),
118+
[ETH_RMII_RXD1_PIN] = WHAL_STM32H5_GPIO_PIN(
119+
WHAL_STM32H5_GPIO_PORT_C, 5, WHAL_STM32H5_GPIO_MODE_ALTFN,
120+
0, WHAL_STM32H5_GPIO_SPEED_HIGH,
121+
WHAL_STM32H5_GPIO_PULL_NONE, 11),
122+
[ETH_RMII_TX_EN_PIN] = WHAL_STM32H5_GPIO_PIN(
123+
WHAL_STM32H5_GPIO_PORT_G, 11, WHAL_STM32H5_GPIO_MODE_ALTFN,
124+
0, WHAL_STM32H5_GPIO_SPEED_HIGH,
125+
WHAL_STM32H5_GPIO_PULL_NONE, 11),
126+
[ETH_RMII_TXD0_PIN] = WHAL_STM32H5_GPIO_PIN(
127+
WHAL_STM32H5_GPIO_PORT_G, 13, WHAL_STM32H5_GPIO_MODE_ALTFN,
128+
0, WHAL_STM32H5_GPIO_SPEED_HIGH,
129+
WHAL_STM32H5_GPIO_PULL_NONE, 11),
130+
[ETH_RMII_TXD1_PIN] = WHAL_STM32H5_GPIO_PIN(
131+
WHAL_STM32H5_GPIO_PORT_B, 15, WHAL_STM32H5_GPIO_MODE_ALTFN,
132+
0, WHAL_STM32H5_GPIO_SPEED_HIGH,
133+
WHAL_STM32H5_GPIO_PULL_NONE, 11),
134+
},
135+
.pinCount = PIN_COUNT,
136+
},
137+
};
138+
139+
/* Timer: SysTick at 1 ms */
140+
static whal_Timer timer = {
141+
WHAL_CORTEX_M33_SYSTICK_DEVICE,
142+
143+
.cfg = &(whal_SysTick_Cfg) {
144+
.cyclesPerTick = 168000000 / 1000,
145+
.clkSrc = WHAL_SYSTICK_CLKSRC_SYSCLK,
146+
.tickInt = WHAL_SYSTICK_TICKINT_ENABLED,
147+
},
148+
};
149+
150+
/* Ethernet MAC */
151+
#define ETH_TX_DESC_COUNT 4
152+
#define ETH_RX_DESC_COUNT 4
153+
#define ETH_TX_BUF_SIZE 1536
154+
#define ETH_RX_BUF_SIZE 1536
155+
156+
static whal_Stm32h5Eth_TxDesc eth_tx_descs[ETH_TX_DESC_COUNT]
157+
__attribute__((aligned(16)));
158+
static whal_Stm32h5Eth_RxDesc eth_rx_descs[ETH_RX_DESC_COUNT]
159+
__attribute__((aligned(16)));
160+
static uint8_t eth_tx_bufs[ETH_TX_DESC_COUNT * ETH_TX_BUF_SIZE]
161+
__attribute__((aligned(4)));
162+
static uint8_t eth_rx_bufs[ETH_RX_DESC_COUNT * ETH_RX_BUF_SIZE]
163+
__attribute__((aligned(4)));
164+
165+
whal_Eth g_whalEth = {
166+
WHAL_STM32H563_ETH_DEVICE,
167+
168+
.macAddr = {0x00, 0x80, 0xE1, 0x00, 0x00, 0x01},
169+
.cfg = &(whal_Stm32h5Eth_Cfg) {
170+
.txDescs = eth_tx_descs,
171+
.txBufs = eth_tx_bufs,
172+
.txDescCount = ETH_TX_DESC_COUNT,
173+
.txBufSize = ETH_TX_BUF_SIZE,
174+
.rxDescs = eth_rx_descs,
175+
.rxBufs = eth_rx_bufs,
176+
.rxDescCount = ETH_RX_DESC_COUNT,
177+
.rxBufSize = ETH_RX_BUF_SIZE,
178+
.timeout = &g_whalTimeout,
179+
},
180+
};
181+
182+
/* Ethernet PHY (LAN8742A) */
183+
whal_EthPhy g_whalEthPhy = {
184+
.eth = &g_whalEth,
185+
.addr = BOARD_ETH_PHY_ADDR,
186+
.driver = &whal_Lan8742a_Driver,
187+
188+
.cfg = &(whal_Lan8742a_Cfg) {
189+
.timeout = &g_whalTimeout,
190+
},
191+
};
192+
193+
/* UART: USART2 on ST-Link VCP */
194+
whal_Uart g_whalUart = {
195+
WHAL_STM32H563_USART2_DEVICE,
196+
197+
.cfg = &(whal_Stm32h5Uart_Cfg) {
198+
.brr = WHAL_STM32H5_UART_BRR(168000000, 115200),
199+
.timeout = &g_whalTimeout,
200+
},
201+
};
202+
203+
/* Flash: needed for latency configuration before clock increase */
204+
static whal_Flash flash = {
205+
WHAL_STM32H563_FLASH_DEVICE,
206+
207+
.cfg = &(whal_Stm32h5Flash_Cfg) {
208+
.startAddr = 0x08000000,
209+
.size = 0x200000,
210+
.timeout = &g_whalTimeout,
211+
},
212+
};
213+
214+
/* 5 wait states + WRHIGHFREQ=2 for 168 MHz */
215+
#define FLASH_LATENCY_168MHZ ((2 << 4) | 5)
216+
217+
whal_Error board_init(void)
218+
{
219+
whal_Error err;
220+
size_t i;
221+
222+
/* Set flash latency before increasing clock speed */
223+
err = whal_Stm32h5Flash_Ext_SetLatency(&flash, FLASH_LATENCY_168MHZ);
224+
if (err)
225+
return err;
226+
227+
err = whal_Clock_Init(&clock);
228+
if (err)
229+
return err;
230+
231+
for (i = 0; i < CLOCK_COUNT; i++) {
232+
err = whal_Clock_Enable(&clock, &clocks[i]);
233+
if (err)
234+
return err;
235+
}
236+
237+
/* Select RMII mode in SBS_PMCR before enabling ETH clocks */
238+
*(volatile uint32_t *)0x44000500 =
239+
(*(volatile uint32_t *)0x44000500 & ~(7UL << 21)) | (4UL << 21);
240+
241+
for (i = 0; i < ETH_CLOCK_COUNT; i++) {
242+
err = whal_Clock_Enable(&clock, &eth_clocks[i]);
243+
if (err)
244+
return err;
245+
}
246+
247+
err = whal_Gpio_Init(&gpio);
248+
if (err)
249+
return err;
250+
251+
err = whal_Uart_Init(&g_whalUart);
252+
if (err)
253+
return err;
254+
255+
err = whal_Eth_Init(&g_whalEth);
256+
if (err)
257+
return err;
258+
259+
err = whal_EthPhy_Init(&g_whalEthPhy);
260+
if (err)
261+
return err;
262+
263+
err = whal_Timer_Init(&timer);
264+
if (err)
265+
return err;
266+
267+
err = whal_Timer_Start(&timer);
268+
if (err)
269+
return err;
270+
271+
return WHAL_SUCCESS;
272+
}
273+
274+
whal_Error board_deinit(void)
275+
{
276+
whal_Error err;
277+
size_t i;
278+
279+
err = whal_Timer_Stop(&timer);
280+
if (err)
281+
return err;
282+
283+
err = whal_Timer_Deinit(&timer);
284+
if (err)
285+
return err;
286+
287+
err = whal_EthPhy_Deinit(&g_whalEthPhy);
288+
if (err)
289+
return err;
290+
291+
err = whal_Eth_Deinit(&g_whalEth);
292+
if (err)
293+
return err;
294+
295+
err = whal_Uart_Deinit(&g_whalUart);
296+
if (err)
297+
return err;
298+
299+
err = whal_Gpio_Deinit(&gpio);
300+
if (err)
301+
return err;
302+
303+
for (i = 0; i < ETH_CLOCK_COUNT; i++) {
304+
err = whal_Clock_Disable(&clock, &eth_clocks[i]);
305+
if (err)
306+
return err;
307+
}
308+
309+
for (i = 0; i < CLOCK_COUNT; i++) {
310+
err = whal_Clock_Disable(&clock, &clocks[i]);
311+
if (err)
312+
return err;
313+
}
314+
315+
err = whal_Clock_Deinit(&clock);
316+
if (err)
317+
return err;
318+
319+
return WHAL_SUCCESS;
320+
}

0 commit comments

Comments
 (0)