1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
|
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2026-06-24 ox-horse first version
*/
#ifndef __DRV_ETH_H__
#define __DRV_ETH_H__
#include <rtthread.h>
#include <rthw.h>
#include <rtdevice.h>
#include <board.h>
#if defined(SOC_SERIES_N32H47x_48x)
#include "n32h47x_48x_eth.h"
#elif defined(SOC_SERIES_N32H49x)
#include "n32h49x_eth.h"
#elif defined(SOC_SERIES_N32H7xx)
#include "n32h7xx_eth.h"
#include "n32h7xx_rcc.h"
#include "n32h7xx_pwr.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* ======================= ETH Instance Selection ======================= */
#if defined(SOC_SERIES_N32H47x_48x) || defined(SOC_SERIES_N32H49x)
/* n32h47x_48x / n32h49x have a single ETH instance; ETH pointer & ETH_IRQn come from the device header. */
#define ETH_RCC_ENABLE_AHB_PERIPHEN_CLK RCC_EnableAHBPeriphClk
#define ETH_RCC_AHB_PERIPHEN RCC_AHB_PERIPHEN_ETH
#define ETH_GLOBAL_IRQ ETH_IRQn
#define ETH_GLOBAL_IRQHANDLER ETH_IRQHandler
#elif defined(SOC_SERIES_N32H7xx)
#if defined(BSP_USING_ETH1)
#define ETH ETH1
#define ETH_RCC_ENABLE_AHB_PERIPHEN_CLK RCC_EnableAHB2PeriphClk2
#define ETH_RCC_AHB_PERIPHEN_CLK RCC_AHB2_PERIPHEN_M7_ETH1CLK
#define ETH_RCC_AHB_PERIPHEN (RCC_AHB2_PERIPHEN_M7_ETH1MAC | \
RCC_AHB2_PERIPHEN_M7_ETH1TX | \
RCC_AHB2_PERIPHEN_M7_ETH1RX)
#define ETH_GLOBAL_IRQ ETH1_IRQn
#define ETH_PWR_CTRL HSC1_ETH1_PWRCTRL
#define ETH_GLOBAL_IRQHANDLER ETH1_IRQHandler
#elif defined(BSP_USING_ETH2)
#define ETH ETH2
#define ETH_RCC_ENABLE_AHB_PERIPHEN_CLK RCC_EnableAHB1PeriphClk2
#define ETH_RCC_AHB_PERIPHEN_CLK RCC_AHB1_PERIPHEN_M7_ETH2CLK
#define ETH_RCC_AHB_PERIPHEN (RCC_AHB1_PERIPHEN_M7_ETH2MAC | \
RCC_AHB1_PERIPHEN_M7_ETH2TX | \
RCC_AHB1_PERIPHEN_M7_ETH2RX)
#define ETH_GLOBAL_IRQ ETH2_IRQn
#define ETH_PWR_CTRL HSC2_ETH2_PWRCTRL
#define ETH_GLOBAL_IRQHANDLER ETH2_IRQHandler
#endif /* BSP_USING_ETH1 / BSP_USING_ETH2 */
#endif /* SOC_SERIES_N32H47x_48x / SOC_SERIES_N32H7xx */
/* ======================= Media Interface Selection ======================= */
#if defined(ETH_INTERFACE_USING_GMII)
#define ETH_MEDIA_INTERFACE ETH_GMII_MODE
#elif defined(ETH_INTERFACE_USING_MII)
#define ETH_MEDIA_INTERFACE ETH_MII_MODE
#elif defined(ETH_INTERFACE_USING_RMII)
#define ETH_MEDIA_INTERFACE ETH_RMII_MODE
#else
#error "No ETH media interface selected (define ETH_INTERFACE_USING_GMII/MII/RMII)"
#endif
/* ======================= MACCFG Speed/Duplex Bit Mask ======================= */
#if defined(SOC_SERIES_N32H47x_48x) || defined(SOC_SERIES_N32H49x)
#define ETH_MACCFG_SPEED_DUPLEX_MASK (ETH_SPEED_100M | ETH_FULL_DUPLEX_MODE)
#else
#define ETH_MACCFG_SPEED_DUPLEX_MASK (ETH_MACCFG_PS | ETH_MACCFG_FES | ETH_MACCFG_DM)
#endif
/* ======================= ETH_Init Param Helper ======================= */
#if defined(SOC_SERIES_N32H47x_48x) || defined(SOC_SERIES_N32H49x)
#define ETH_STRUCT_INIT(p) ETH_StructInit(p)
#else
#define ETH_STRUCT_INIT(p) ETH_StructInit(ETH, p)
#endif
/* ======================= Standard IEEE 802.3 PHY Registers ======================= */
#define PHY_BASIC_CONTROL_REG 0x00U
#define PHY_BASIC_STATUS_REG 0x01U
#define PHY_ID1_REG 0x02U
#define PHY_ID2_REG 0x03U
#define PHY_AUTONEG_ADVERTISE_REG 0x04U
#define PHY_AUTONEG_LINK_PARTNER 0x05U
#define PHY_GIGABIT_CONTROL_REG 0x09U /* 1000BASE-T Control Register */
#define PHY_GIGABIT_STATUS_REG 0x0AU /* 1000BASE-T Status Register */
/* Basic Control Register bits */
#define PHY_RESET_MASK (1 << 15)
#define PHY_LOOPBACK_MASK (1 << 14)
#define PHY_AUTO_NEGOTIATION_MASK (1 << 12)
#define PHY_POWER_DOWN_MASK (1 << 11)
#define PHY_RESTART_AUTONEG_MASK (1 << 9)
#define PHY_DUPLEX_MODE_MASK (1 << 8)
/* Basic Status Register bits */
#define PHY_100BASE_T4_MASK (1 << 15)
#define PHY_100BASE_TX_FD_MASK (1 << 14)
#define PHY_100BASE_TX_HD_MASK (1 << 13)
#define PHY_10BASE_T_FD_MASK (1 << 12)
#define PHY_10BASE_T_HD_MASK (1 << 11)
#define PHY_1000BASE_T_FD_MASK (1 << 10)
#define PHY_1000BASE_T_HD_MASK (1 << 9)
#define PHY_LINKED_STATUS_MASK (1 << 2)
#define PHY_AUTONEGO_COMPLETE_MASK (1 << 5)
/* ======================= DM9119INP PHY Specific Registers ======================= */
#ifdef PHY_USING_DM9119INP
/* DM9119INP is a Gigabit PHY supporting GMII/MII/RMII */
#define PHY_DM9119INP_ID1 0x006EU
#define PHY_DM9119INP_ID2 0x3212U
/* DM9119INP PHY Specific Status Register (0x11)
* bit[15:14] = 00 → 10M, 01 → 100M, 10 → 1000M
* bit[13] = 1 → Full-Duplex, 0 → Half-Duplex */
#define PHY_SDSR 0x11U
#define PHY_Status_SPEED_1000M(sr) (((sr) & (1 << 15)) != 0)
#define PHY_Status_SPEED_100M(sr) (((sr) & (1 << 14)) != 0)
#define PHY_Status_SPEED_10M(sr) (!PHY_Status_SPEED_1000M(sr) && !PHY_Status_SPEED_100M(sr))
#define PHY_Status_FULL_DUPLEX(sr) (((sr) & (1 << 13)) != 0)
/* DM9119INP PHY Specific Interrupt Registers
* 0x12 Interrupt Control, 0x13 Interrupt Status */
#define PHY_INTERRUPT_CTRL_REG 0x12U
#define PHY_INTERRUPT_FLAG_REG 0x13U
#define PHY_INTERRUPT_MASK_REG 0x12U
#define PHY_INT_MASK ((1 << 15) | (1 << 14) | (1 << 13) | (1 << 10))
#endif /* PHY_USING_DM9119INP */
/* ======================= YT8522H PHY Specific Registers ======================= */
#ifdef PHY_USING_YT8522H
/* YT8522H is a Fast Ethernet PHY supporting MII/RMII, up to 100M */
#define PHY_YT8522H_ID1 0x4F51U
#define PHY_YT8522H_ID2 0xE928U
/* YT8522H PHY Specific Status Register (0x11)
* bit[15:14] = 00 → 10M, 01 → 100M
* bit[13] = 1 → Full-Duplex, 0 → Half-Duplex */
#define PHY_SDSR 0x11U
#define PHY_Status_SPEED_100M(sr) (((sr) & (1 << 14)) != 0)
#define PHY_Status_SPEED_10M(sr) (!PHY_Status_SPEED_100M(sr))
#define PHY_Status_FULL_DUPLEX(sr) (((sr) & (1 << 13)) != 0)
/* YT8522H PHY Specific Interrupt Registers
* 0x12 Interrupt Control, 0x13 Interrupt Status
* bit15=Auto-Neg Fail, bit14=Speed Change, bit13=Duplex Change,
* bit11=Link Fail, bit10=Link Success */
#define PHY_INTERRUPT_CTRL_REG 0x12U
#define PHY_INTERRUPT_FLAG_REG 0x13U
#define PHY_INTERRUPT_MASK_REG 0x12U
#define PHY_INT_MASK ((1 << 15) | (1 << 14) | (1 << 13) | (1 << 11) | (1 << 10))
#endif /* PHY_USING_YT8522H */
/* ======================= DM9162EP PHY Specific Registers ======================= */
#ifdef PHY_USING_DM9162EP
/* DM9162EP is a Fast Ethernet PHY supporting MII/RMII, up to 100M */
#define PHY_DM9162EP_ID1 0x0181U
#define PHY_DM9162EP_ID2 0xB8A0U
/* DM9162EP PHY Specific Status Register (0x11)
* bit15 = 100M Full-Duplex, bit14 = 100M Half-Duplex,
* bit13 = 10M Full-Duplex, bit12 = 10M Half-Duplex */
#define PHY_SDSR 0x11U
#define PHY_Status_SPEED_100M(sr) (((sr) & ((1 << 15) | (1 << 14))) != 0)
#define PHY_Status_SPEED_10M(sr) (!PHY_Status_SPEED_100M(sr))
#define PHY_Status_FULL_DUPLEX(sr) (((sr) & ((1 << 15) | (1 << 13))) != 0)
/* DM9162EP PHY Specific Interrupt Registers
* 0x15 Interrupt Source Flag / Interrupt Mask */
#define PHY_INTERRUPT_FLAG_REG 0x15U
#define PHY_INTERRUPT_MASK_REG 0x15U
#define PHY_INT_MASK 0U
#endif /* PHY_USING_DM9162EP */
/* ======================= RTL8211EG PHY Specific Registers ======================= */
#ifdef PHY_USING_RTL8211EG
/* RTL8211EG is a Gigabit PHY supporting GMII/MII/RMII */
#define PHY_RTL8211EG_ID1 0x001CU
#define PHY_RTL8211EG_ID2 0xC915U
/* RTL8211EG PHY Specific Status Register (0x11)
* bit[15:14] = 00 → 10M, 01 → 100M, 10 → 1000M
* bit[13] = 1 → Full-Duplex, 0 → Half-Duplex
* No unlock sequence needed — accessible via default register page. */
#define PHY_SDSR 0x11U
#define PHY_Status_SPEED_1000M(sr) (((sr) & (1 << 15)) != 0)
#define PHY_Status_SPEED_100M(sr) (((sr) & (1 << 14)) != 0)
#define PHY_Status_SPEED_10M(sr) (!PHY_Status_SPEED_1000M(sr) && !PHY_Status_SPEED_100M(sr))
#define PHY_Status_FULL_DUPLEX(sr) (((sr) & (1 << 13)) != 0)
/* RTL8211EG Interrupt Registers: 0x12 Control, 0x13 Status
* bit15=Auto-Neg Error, bit11=Auto-Neg Complete, bit10=Link Change */
#define PHY_INTERRUPT_CTRL_REG 0x12U
#define PHY_INTERRUPT_FLAG_REG 0x13U
#define PHY_INTERRUPT_MASK_REG 0x12U
#define PHY_INT_MASK ((1 << 15) | (1 << 11) | (1 << 10))
#endif /* PHY_USING_RTL8211EG */
/* ======================= LAN8720A PHY Specific Registers ======================= */
#ifdef PHY_USING_LAN8720A
/* LAN8720A is a Fast Ethernet PHY supporting MII/RMII, up to 100M */
#define PHY_LAN8720A_ID1 0x0007U
#define PHY_LAN8720A_ID2 0xC0F1U
/* LAN8720A PHY Specific Status Register (0x1F)
* bit4 = Full-Duplex, bit3 = 100M, bit2 = 10M */
#define PHY_SDSR 0x1FU
#define PHY_Status_SPEED_100M(sr) (((sr) & (1 << 3)) != 0)
#define PHY_Status_SPEED_10M(sr) (((sr) & (1 << 2)) != 0)
#define PHY_Status_FULL_DUPLEX(sr) (((sr) & (1 << 4)) != 0)
/* LAN8720A PHY Specific Interrupt Registers
* 0x1D Interrupt Source Flag, 0x1E Interrupt Mask */
#define PHY_INTERRUPT_FLAG_REG 0x1DU
#define PHY_INTERRUPT_MASK_REG 0x1EU
#define PHY_INT_MASK (1 << 4)
#endif /* PHY_USING_LAN8720A */
/* ======================= Buffer & Descriptor Configuration ======================= */
#ifndef ETH_TX_DESC_NUMBER
#define ETH_TX_DESC_NUMBER ((uint32_t)4U)
#endif
#ifndef ETH_RX_DESC_NUMBER
#define ETH_RX_DESC_NUMBER ((uint32_t)4U)
#endif
/* ETH_MAX_PACKET_SIZE is defined in n32h7xx_eth.h (1528U); n32h47x_48x has no such macro. */
#if defined(SOC_SERIES_N32H47x_48x) || defined(SOC_SERIES_N32H49x)
#ifndef ETH_MAX_PACKET_SIZE
#define ETH_MAX_PACKET_SIZE (1528U)
#endif
#endif
#define ETH_TX_BUF_SIZE (ETH_TX_DESC_NUMBER * ETH_MAX_PACKET_SIZE)
#define ETH_RX_BUF_SIZE (ETH_RX_DESC_NUMBER * ETH_MAX_PACKET_SIZE)
/* ======================= PHY Link Status Flags ======================= */
#define PHY_LINK (1 << 0)
#define PHY_10M (1 << 1)
#define PHY_100M (1 << 2)
#define PHY_1000M (1 << 3)
#define PHY_FULL_DUPLEX (1 << 4)
/* ---- test/monitoring accessors (enabled via DO_ETH_TEST) ---- */
#define DO_ETH_TEST 1
#if DO_ETH_TEST
rt_uint32_t n32_eth_get_speed(void);
rt_uint32_t n32_eth_get_duplex(void);
rt_uint8_t n32_eth_get_phy_addr(void);
void n32_eth_get_mac_addr(rt_uint8_t mac[6]);
const char *n32_eth_get_phy_name(void);
#endif /* DO_ETH_TEST */
#ifdef __cplusplus
}
#endif
#endif /* __DRV_ETH_H__ */
|