Skip to content

Commit 7fee50c

Browse files
committed
[eth, eth_phy, stm32h5_eth, lan8742a] Implement ethernet and phy abstraction. Add eth and phy driver
1 parent 499626f commit 7fee50c

16 files changed

Lines changed: 1585 additions & 2 deletions

File tree

boards/stm32h563zi_nucleo/Makefile.inc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
_BOARD_DIR := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))
22

33
PLATFORM = stm32h5
4-
TESTS ?= clock gpio timer flash rng
4+
TESTS ?= clock gpio timer flash rng eth
55

66
GCC = $(GCC_PATH)arm-none-eabi-gcc
77
LD = $(GCC_PATH)arm-none-eabi-ld
@@ -29,6 +29,8 @@ BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*/spi.c)
2929
BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*/rng.c)
3030
BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*/crypto.c)
3131
BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*/block.c)
32+
BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*/eth.c)
33+
BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/eth_phy/*.c)
3234
BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*/stm32h5_*.c)
3335
BOARD_SOURCE += $(wildcard $(WHAL_DIR)/src/*/systick.c)
3436

boards/stm32h563zi_nucleo/board.c

Lines changed: 153 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <stddef.h>
55
#include "board.h"
66
#include <wolfHAL/platform/st/stm32h563xx.h>
7+
#include <wolfHAL/eth_phy/lan8742a.h>
78
#include "peripheral.h"
89

910
/* SysTick timing */
@@ -52,13 +53,22 @@ static const whal_Stm32h5Rcc_Clk g_clocks[] = {
5253
{WHAL_STM32H563_GPIOA_CLOCK},
5354
{WHAL_STM32H563_GPIOB_CLOCK},
5455
{WHAL_STM32H563_GPIOD_CLOCK},
56+
{WHAL_STM32H563_GPIOC_CLOCK},
5557
{WHAL_STM32H563_GPIOG_CLOCK},
5658
{WHAL_STM32H563_USART2_CLOCK},
5759
{WHAL_STM32H563_SPI1_CLOCK},
5860
{WHAL_STM32H563_RNG_CLOCK},
61+
{WHAL_STM32H563_SBS_CLOCK},
5962
};
6063
#define CLOCK_COUNT (sizeof(g_clocks) / sizeof(g_clocks[0]))
6164

65+
static const whal_Stm32h5Rcc_Clk g_ethClocks[] = {
66+
{WHAL_STM32H563_ETH_CLOCK},
67+
{WHAL_STM32H563_ETHTX_CLOCK},
68+
{WHAL_STM32H563_ETHRX_CLOCK},
69+
};
70+
#define ETH_CLOCK_COUNT (sizeof(g_ethClocks) / sizeof(g_ethClocks[0]))
71+
6272
/* GPIO */
6373
whal_Gpio g_whalGpio = {
6474
WHAL_STM32H563_GPIO_DEVICE,
@@ -127,6 +137,78 @@ whal_Gpio g_whalGpio = {
127137
.speed = WHAL_STM32H5_GPIO_SPEED_FAST,
128138
.pull = WHAL_STM32H5_GPIO_PULL_UP,
129139
},
140+
[ETH_RMII_REF_CLK_PIN] = { /* RMII REF_CLK on PA1 */
141+
.port = WHAL_STM32H5_GPIO_PORT_A,
142+
.pin = 1,
143+
.mode = WHAL_STM32H5_GPIO_MODE_ALTFN,
144+
.speed = WHAL_STM32H5_GPIO_SPEED_HIGH,
145+
.pull = WHAL_STM32H5_GPIO_PULL_NONE,
146+
.altFn = 11,
147+
},
148+
[ETH_RMII_MDIO_PIN] = { /* RMII MDIO on PA2 */
149+
.port = WHAL_STM32H5_GPIO_PORT_A,
150+
.pin = 2,
151+
.mode = WHAL_STM32H5_GPIO_MODE_ALTFN,
152+
.speed = WHAL_STM32H5_GPIO_SPEED_HIGH,
153+
.pull = WHAL_STM32H5_GPIO_PULL_NONE,
154+
.altFn = 11,
155+
},
156+
[ETH_RMII_MDC_PIN] = { /* RMII MDC on PC1 */
157+
.port = WHAL_STM32H5_GPIO_PORT_C,
158+
.pin = 1,
159+
.mode = WHAL_STM32H5_GPIO_MODE_ALTFN,
160+
.speed = WHAL_STM32H5_GPIO_SPEED_HIGH,
161+
.pull = WHAL_STM32H5_GPIO_PULL_NONE,
162+
.altFn = 11,
163+
},
164+
[ETH_RMII_CRS_DV_PIN] = { /* RMII CRS_DV on PA7 */
165+
.port = WHAL_STM32H5_GPIO_PORT_A,
166+
.pin = 7,
167+
.mode = WHAL_STM32H5_GPIO_MODE_ALTFN,
168+
.speed = WHAL_STM32H5_GPIO_SPEED_HIGH,
169+
.pull = WHAL_STM32H5_GPIO_PULL_NONE,
170+
.altFn = 11,
171+
},
172+
[ETH_RMII_RXD0_PIN] = { /* RMII RXD0 on PC4 */
173+
.port = WHAL_STM32H5_GPIO_PORT_C,
174+
.pin = 4,
175+
.mode = WHAL_STM32H5_GPIO_MODE_ALTFN,
176+
.speed = WHAL_STM32H5_GPIO_SPEED_HIGH,
177+
.pull = WHAL_STM32H5_GPIO_PULL_NONE,
178+
.altFn = 11,
179+
},
180+
[ETH_RMII_RXD1_PIN] = { /* RMII RXD1 on PC5 */
181+
.port = WHAL_STM32H5_GPIO_PORT_C,
182+
.pin = 5,
183+
.mode = WHAL_STM32H5_GPIO_MODE_ALTFN,
184+
.speed = WHAL_STM32H5_GPIO_SPEED_HIGH,
185+
.pull = WHAL_STM32H5_GPIO_PULL_NONE,
186+
.altFn = 11,
187+
},
188+
[ETH_RMII_TX_EN_PIN] = { /* RMII TX_EN on PG11 */
189+
.port = WHAL_STM32H5_GPIO_PORT_G,
190+
.pin = 11,
191+
.mode = WHAL_STM32H5_GPIO_MODE_ALTFN,
192+
.speed = WHAL_STM32H5_GPIO_SPEED_HIGH,
193+
.pull = WHAL_STM32H5_GPIO_PULL_NONE,
194+
.altFn = 11,
195+
},
196+
[ETH_RMII_TXD0_PIN] = { /* RMII TXD0 on PG13 */
197+
.port = WHAL_STM32H5_GPIO_PORT_G,
198+
.pin = 13,
199+
.mode = WHAL_STM32H5_GPIO_MODE_ALTFN,
200+
.speed = WHAL_STM32H5_GPIO_SPEED_HIGH,
201+
.pull = WHAL_STM32H5_GPIO_PULL_NONE,
202+
.altFn = 11,
203+
},
204+
[ETH_RMII_TXD1_PIN] = { /* RMII TXD1 on PB15 */
205+
.port = WHAL_STM32H5_GPIO_PORT_B,
206+
.pin = 15,
207+
.mode = WHAL_STM32H5_GPIO_MODE_ALTFN,
208+
.speed = WHAL_STM32H5_GPIO_SPEED_HIGH,
209+
.pull = WHAL_STM32H5_GPIO_PULL_NONE,
210+
.altFn = 11,
211+
},
130212
},
131213
.pinCount = PIN_COUNT,
132214
},
@@ -184,6 +266,49 @@ whal_Flash g_whalFlash = {
184266
},
185267
};
186268

269+
/* Ethernet */
270+
#define ETH_TX_DESC_COUNT 4
271+
#define ETH_RX_DESC_COUNT 4
272+
#define ETH_TX_BUF_SIZE 1536
273+
#define ETH_RX_BUF_SIZE 1536
274+
275+
static whal_Stm32h5Eth_TxDesc ethTxDescs[ETH_TX_DESC_COUNT]
276+
__attribute__((aligned(16)));
277+
static whal_Stm32h5Eth_RxDesc ethRxDescs[ETH_RX_DESC_COUNT]
278+
__attribute__((aligned(16)));
279+
static uint8_t ethTxBufs[ETH_TX_DESC_COUNT * ETH_TX_BUF_SIZE]
280+
__attribute__((aligned(4)));
281+
static uint8_t ethRxBufs[ETH_RX_DESC_COUNT * ETH_RX_BUF_SIZE]
282+
__attribute__((aligned(4)));
283+
284+
whal_Eth g_whalEth = {
285+
WHAL_STM32H563_ETH_DEVICE,
286+
287+
.cfg = &(whal_Stm32h5Eth_Cfg) {
288+
.macAddr = {0x00, 0x80, 0xE1, 0x00, 0x00, 0x01},
289+
.txDescs = ethTxDescs,
290+
.txBufs = ethTxBufs,
291+
.txDescCount = ETH_TX_DESC_COUNT,
292+
.txBufSize = ETH_TX_BUF_SIZE,
293+
.rxDescs = ethRxDescs,
294+
.rxBufs = ethRxBufs,
295+
.rxDescCount = ETH_RX_DESC_COUNT,
296+
.rxBufSize = ETH_RX_BUF_SIZE,
297+
.timeout = &g_whalTimeout,
298+
},
299+
};
300+
301+
/* Ethernet PHY (LAN8742A) */
302+
whal_EthPhy g_whalEthPhy = {
303+
.eth = &g_whalEth,
304+
.addr = BOARD_ETH_PHY_ADDR,
305+
.driver = &whal_Lan8742a_Driver,
306+
307+
.cfg = &(whal_Lan8742a_Cfg) {
308+
.timeout = &g_whalTimeout,
309+
},
310+
};
311+
187312
void Board_WaitMs(size_t ms)
188313
{
189314
uint32_t startCount = g_tick;
@@ -210,13 +335,24 @@ whal_Error Board_Init(void)
210335
if (err)
211336
return err;
212337

213-
/* Enable clocks */
338+
/* Enable clocks (excludes ETH — needs SBS RMII config first) */
214339
for (size_t i = 0; i < CLOCK_COUNT; i++) {
215340
err = whal_Clock_Enable(&g_whalClock, &g_clocks[i]);
216341
if (err)
217342
return err;
218343
}
219344

345+
/* Select RMII mode in SBS_PMCR (SBS base 0x44000400 + 0x100) bits [23:21] = 0b100 */
346+
*(volatile uint32_t *)0x44000500 =
347+
(*(volatile uint32_t *)0x44000500 & ~(7UL << 21)) | (4UL << 21);
348+
349+
/* Enable ETH clocks after RMII mode is selected */
350+
for (size_t i = 0; i < ETH_CLOCK_COUNT; i++) {
351+
err = whal_Clock_Enable(&g_whalClock, &g_ethClocks[i]);
352+
if (err)
353+
return err;
354+
}
355+
220356
/* Enable HSI48 for RNG kernel clock */
221357
err = whal_Stm32h5Rcc_Ext_EnableHsi48(&g_whalClock, 1);
222358
if (err)
@@ -238,6 +374,14 @@ whal_Error Board_Init(void)
238374
if (err)
239375
return err;
240376

377+
err = whal_Eth_Init(&g_whalEth);
378+
if (err)
379+
return err;
380+
381+
err = whal_EthPhy_Init(&g_whalEthPhy);
382+
if (err)
383+
return err;
384+
241385
err = whal_Timer_Init(&g_whalTimer);
242386
if (err)
243387
return err;
@@ -269,6 +413,14 @@ whal_Error Board_Deinit(void)
269413
if (err)
270414
return err;
271415

416+
err = whal_EthPhy_Deinit(&g_whalEthPhy);
417+
if (err)
418+
return err;
419+
420+
err = whal_Eth_Deinit(&g_whalEth);
421+
if (err)
422+
return err;
423+
272424
err = whal_Rng_Deinit(&g_whalRng);
273425
if (err)
274426
return err;

boards/stm32h563zi_nucleo/board.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ extern whal_Uart g_whalUart;
1212
extern whal_Spi g_whalSpi;
1313
extern whal_Rng g_whalRng;
1414
extern whal_Flash g_whalFlash;
15+
extern whal_Eth g_whalEth;
16+
extern whal_EthPhy g_whalEthPhy;
1517

1618
extern whal_Timeout g_whalTimeout;
1719
extern volatile uint32_t g_tick;
@@ -24,6 +26,15 @@ enum {
2426
SPI_MISO_PIN,
2527
SPI_MOSI_PIN,
2628
SPI_CS_PIN,
29+
ETH_RMII_REF_CLK_PIN,
30+
ETH_RMII_MDIO_PIN,
31+
ETH_RMII_MDC_PIN,
32+
ETH_RMII_CRS_DV_PIN,
33+
ETH_RMII_RXD0_PIN,
34+
ETH_RMII_RXD1_PIN,
35+
ETH_RMII_TX_EN_PIN,
36+
ETH_RMII_TXD0_PIN,
37+
ETH_RMII_TXD1_PIN,
2738
PIN_COUNT,
2839
};
2940

@@ -33,6 +44,11 @@ enum {
3344
#define BOARD_FLASH_TEST_ADDR 0x081FE000
3445
#define BOARD_FLASH_SECTOR_SZ 0x2000
3546

47+
/* Ethernet PHY: LAN8742A on MDIO address 0 */
48+
#define BOARD_ETH_PHY_ADDR 0
49+
#define BOARD_ETH_PHY_ID1 0x0007
50+
#define BOARD_ETH_PHY_ID2 0xC131
51+
3652
whal_Error Board_Init(void);
3753
whal_Error Board_Deinit(void);
3854
void Board_WaitMs(size_t ms);

src/eth/eth.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#include <wolfHAL/eth/eth.h>
2+
#include <wolfHAL/error.h>
3+
4+
whal_Error whal_Eth_Init(whal_Eth *ethDev)
5+
{
6+
if (!ethDev || !ethDev->driver || !ethDev->driver->Init)
7+
return WHAL_EINVAL;
8+
return ethDev->driver->Init(ethDev);
9+
}
10+
11+
whal_Error whal_Eth_Deinit(whal_Eth *ethDev)
12+
{
13+
if (!ethDev || !ethDev->driver || !ethDev->driver->Deinit)
14+
return WHAL_EINVAL;
15+
return ethDev->driver->Deinit(ethDev);
16+
}
17+
18+
whal_Error whal_Eth_Start(whal_Eth *ethDev, uint8_t speed,
19+
uint8_t duplex)
20+
{
21+
if (!ethDev || !ethDev->driver || !ethDev->driver->Start)
22+
return WHAL_EINVAL;
23+
return ethDev->driver->Start(ethDev, speed, duplex);
24+
}
25+
26+
whal_Error whal_Eth_Stop(whal_Eth *ethDev)
27+
{
28+
if (!ethDev || !ethDev->driver || !ethDev->driver->Stop)
29+
return WHAL_EINVAL;
30+
return ethDev->driver->Stop(ethDev);
31+
}
32+
33+
whal_Error whal_Eth_Send(whal_Eth *ethDev, const uint8_t *frame,
34+
size_t len)
35+
{
36+
if (!ethDev || !ethDev->driver || !ethDev->driver->Send || !frame)
37+
return WHAL_EINVAL;
38+
return ethDev->driver->Send(ethDev, frame, len);
39+
}
40+
41+
whal_Error whal_Eth_Recv(whal_Eth *ethDev, uint8_t *frame, size_t *len)
42+
{
43+
if (!ethDev || !ethDev->driver || !ethDev->driver->Recv || !frame || !len)
44+
return WHAL_EINVAL;
45+
return ethDev->driver->Recv(ethDev, frame, len);
46+
}
47+
48+
whal_Error whal_Eth_MdioRead(whal_Eth *ethDev, uint8_t phyAddr,
49+
uint8_t reg, uint16_t *val)
50+
{
51+
if (!ethDev || !ethDev->driver || !ethDev->driver->MdioRead || !val)
52+
return WHAL_EINVAL;
53+
return ethDev->driver->MdioRead(ethDev, phyAddr, reg, val);
54+
}
55+
56+
whal_Error whal_Eth_MdioWrite(whal_Eth *ethDev, uint8_t phyAddr,
57+
uint8_t reg, uint16_t val)
58+
{
59+
if (!ethDev || !ethDev->driver || !ethDev->driver->MdioWrite)
60+
return WHAL_EINVAL;
61+
return ethDev->driver->MdioWrite(ethDev, phyAddr, reg, val);
62+
}

0 commit comments

Comments
 (0)