Skip to content

Commit 3ec76b6

Browse files
committed
stm32/ethernet: Add the phy_type=x keyword option to network.LAN().
With LAN8742, LAN8720, LAN83825 and DP83848 as initial selection and the symbols PHY_LAN8720, PHY_LAN8742, PHY_DP83825 and PHY_DP8348. The default is PHY_LAN8742. The et_init parameters for the Portenta H7 board are set to phy_addr=0 and phy_type=LAN8742, which matches the previous defaults and the schematics. Tested with LAN8720 and DP83848 breakout boards at 10M Duplex and 100M Duplex modes. Signed-off-by: robert-hh <robert@hammelrath.com>
1 parent 81ea035 commit 3ec76b6

File tree

7 files changed

+171
-31
lines changed

7 files changed

+171
-31
lines changed

ports/stm32/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ SRC_C += \
251251
pyb_can.c \
252252
usb.c \
253253
eth.c \
254+
eth_phy.c \
254255
gccollect.c \
255256
help.c \
256257
machine_bitstream.c \

ports/stm32/boards/ARDUINO_PORTENTA_H7/board_init.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ void PORTENTA_board_early_init(void) {
115115
mp_hal_pin_write(pyb_pin_ETH_RST, 1);
116116

117117
// Put Eth in low-power mode
118-
eth_init(&eth_instance, MP_HAL_MAC_ETH0);
118+
eth_init(&eth_instance, MP_HAL_MAC_ETH0, 0, ETH_PHY_LAN8742);
119119
eth_low_power_mode(&eth_instance, true);
120120

121121
#if MICROPY_HW_USB_HS_ULPI3320

ports/stm32/eth.c

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "extmod/modnetwork.h"
3333
#include "mpu.h"
3434
#include "eth.h"
35+
#include "eth_phy.h"
3536

3637
#if defined(MICROPY_HW_ETH_MDC)
3738

@@ -40,26 +41,6 @@
4041
#include "lwip/dhcp.h"
4142
#include "netif/ethernet.h"
4243

43-
// ETH PHY register definitions (for LAN8742 and LAN8720/LAN8710)
44-
#undef PHY_BCR
45-
#define PHY_BCR (0x0000)
46-
#define PHY_BCR_SOFT_RESET (0x8000)
47-
#define PHY_BCR_AUTONEG_EN (0x1000)
48-
#define PHY_BCR_POWER_DOWN (0x0800U)
49-
50-
#undef PHY_BSR
51-
#define PHY_BSR (0x0001)
52-
#define PHY_BSR_LINK_STATUS (0x0004)
53-
#define PHY_BSR_AUTONEG_DONE (0x0020)
54-
55-
#define PHY_SCSR (0x001f)
56-
#define PHY_SCSR_SPEED_Pos (2)
57-
#define PHY_SCSR_SPEED_Msk (7 << PHY_SCSR_SPEED_Pos)
58-
#define PHY_SCSR_SPEED_10HALF (1 << PHY_SCSR_SPEED_Pos)
59-
#define PHY_SCSR_SPEED_10FULL (5 << PHY_SCSR_SPEED_Pos)
60-
#define PHY_SCSR_SPEED_100HALF (2 << PHY_SCSR_SPEED_Pos)
61-
#define PHY_SCSR_SPEED_100FULL (6 << PHY_SCSR_SPEED_Pos)
62-
6344
// ETH DMA RX and TX descriptor definitions
6445
#if defined(STM32H5)
6546
#define RX_DESCR_3_OWN_Pos (31)
@@ -137,6 +118,7 @@ typedef struct _eth_t {
137118
struct netif netif;
138119
struct dhcp dhcp_struct;
139120
uint32_t phy_addr;
121+
int16_t (*phy_get_link_status)(uint32_t phy_addr);
140122
} eth_t;
141123

142124
static eth_dma_t eth_dma __attribute__((aligned(16384)));
@@ -146,7 +128,7 @@ eth_t eth_instance;
146128
STATIC void eth_mac_deinit(eth_t *self);
147129
STATIC void eth_process_frame(eth_t *self, size_t len, const uint8_t *buf);
148130

149-
STATIC void eth_phy_write(uint32_t phy_addr, uint32_t reg, uint32_t val) {
131+
void eth_phy_write(uint32_t phy_addr, uint32_t reg, uint32_t val) {
150132
#if defined(STM32H5) || defined(STM32H7)
151133
while (ETH->MACMDIOAR & ETH_MACMDIOAR_MB) {
152134
}
@@ -174,7 +156,7 @@ STATIC void eth_phy_write(uint32_t phy_addr, uint32_t reg, uint32_t val) {
174156
#endif
175157
}
176158

177-
STATIC uint32_t eth_phy_read(uint32_t phy_addr, uint32_t reg) {
159+
uint32_t eth_phy_read(uint32_t phy_addr, uint32_t reg) {
178160
#if defined(STM32H5) || defined(STM32H7)
179161
while (ETH->MACMDIOAR & ETH_MACMDIOAR_MB) {
180162
}
@@ -202,10 +184,17 @@ STATIC uint32_t eth_phy_read(uint32_t phy_addr, uint32_t reg) {
202184
#endif
203185
}
204186

205-
void eth_init(eth_t *self, int mac_idx, uint32_t phy_addr, int phy_type) {
187+
int eth_init(eth_t *self, int mac_idx, uint32_t phy_addr, int phy_type) {
206188
mp_hal_get_mac(mac_idx, &self->netif.hwaddr[0]);
207189
self->netif.hwaddr_len = 6;
208190
self->phy_addr = phy_addr;
191+
if (phy_type == ETH_PHY_DP83825 || phy_type == ETH_PHY_DP83848) {
192+
self->phy_get_link_status = eth_phy_dp838xx_get_link_status;
193+
} else if (phy_type == ETH_PHY_LAN8720 || phy_type == ETH_PHY_LAN8742) {
194+
self->phy_get_link_status = eth_phy_lan87xx_get_link_status;
195+
} else {
196+
return -1;
197+
}
209198

210199
// Configure GPIO
211200
mp_hal_pin_config_alt_static(MICROPY_HW_ETH_MDC, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_ETH_MDC);
@@ -230,6 +219,7 @@ void eth_init(eth_t *self, int mac_idx, uint32_t phy_addr, int phy_type) {
230219
#else
231220
__HAL_RCC_ETH_CLK_ENABLE();
232221
#endif
222+
return 0;
233223
}
234224

235225
void eth_set_trace(eth_t *self, uint32_t value) {
@@ -381,6 +371,14 @@ STATIC int eth_mac_init(eth_t *self) {
381371
break;
382372
case 1:
383373
if (bsr & PHY_BSR_LINK_STATUS) {
374+
// Announce all modes
375+
eth_phy_write(self->phy_addr, PHY_ANAR,
376+
PHY_ANAR_SPEED_10HALF |
377+
PHY_ANAR_SPEED_10FULL |
378+
PHY_ANAR_SPEED_100HALF |
379+
PHY_ANAR_SPEED_100FULL |
380+
PHY_ANAR_IEEE802_3);
381+
// Start autonegotiate.
384382
eth_phy_write(self->phy_addr, PHY_BCR, PHY_BCR_AUTONEG_EN);
385383
phy_state = 2;
386384
}
@@ -396,7 +394,7 @@ STATIC int eth_mac_init(eth_t *self) {
396394
}
397395

398396
// Get register with link status
399-
uint16_t phy_scsr = eth_phy_read(self->phy_addr, PHY_SCSR);
397+
uint16_t phy_scsr = self->phy_get_link_status(self->phy_addr);
400398

401399
// Burst mode configuration
402400
#if defined(STM32H5) || defined(STM32H7)
@@ -505,9 +503,9 @@ STATIC int eth_mac_init(eth_t *self) {
505503

506504
// Set main MAC control register
507505
ETH->MACCR =
508-
(phy_scsr & PHY_SCSR_SPEED_Msk) == PHY_SCSR_SPEED_10FULL ? ETH_MACCR_DM
509-
: (phy_scsr & PHY_SCSR_SPEED_Msk) == PHY_SCSR_SPEED_100HALF ? ETH_MACCR_FES
510-
: (phy_scsr & PHY_SCSR_SPEED_Msk) == PHY_SCSR_SPEED_100FULL ? (ETH_MACCR_FES | ETH_MACCR_DM)
506+
phy_scsr == PHY_SPEED_10FULL ? ETH_MACCR_DM
507+
: phy_scsr == PHY_SPEED_100HALF ? ETH_MACCR_FES
508+
: phy_scsr == PHY_SPEED_100FULL ? (ETH_MACCR_FES | ETH_MACCR_DM)
511509
: 0
512510
;
513511
mp_hal_delay_ms(2);

ports/stm32/eth.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,17 @@
2626
#ifndef MICROPY_INCLUDED_STM32_ETH_H
2727
#define MICROPY_INCLUDED_STM32_ETH_H
2828

29+
enum {
30+
ETH_PHY_LAN8742 = 0,
31+
ETH_PHY_LAN8720,
32+
ETH_PHY_DP83848,
33+
ETH_PHY_DP83825
34+
};
35+
2936
typedef struct _eth_t eth_t;
3037
extern eth_t eth_instance;
3138

32-
void eth_init(eth_t *self, int mac_idx, uint32_t phy_addr, int phy_type);
39+
int eth_init(eth_t *self, int mac_idx, uint32_t phy_addr, int phy_type);
3340
void eth_set_trace(eth_t *self, uint32_t value);
3441
struct netif *eth_netif(eth_t *self);
3542
int eth_link_status(eth_t *self);

ports/stm32/eth_phy.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2019 Damien P. George
7+
* Copyright (c) 2024 Robert Hammelrath
8+
*
9+
* Permission is hereby granted, free of charge, to any person obtaining a copy
10+
* of this software and associated documentation files (the "Software"), to deal
11+
* in the Software without restriction, including without limitation the rights
12+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
* copies of the Software, and to permit persons to whom the Software is
14+
* furnished to do so, subject to the following conditions:
15+
*
16+
* The above copyright notice and this permission notice shall be included in
17+
* all copies or substantial portions of the Software.
18+
*
19+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
* THE SOFTWARE.
26+
*/
27+
28+
#include "py/mphal.h"
29+
#include "eth_phy.h"
30+
31+
#if defined(MICROPY_HW_ETH_MDC)
32+
33+
#define PHY_SCSR_LAN87XX (0x001f)
34+
#define PHY_SCSR_LAN87XX_SPEED_Pos (2)
35+
#define PHY_SCSR_LAN87XX_SPEED_Msk (7)
36+
37+
#define PHY_SCSR_DP838XX (0x0010)
38+
#define PHY_RECR_DP838XX (0x0015)
39+
#define PHY_SCSR_DP838XX_DUPLEX_Msk (4)
40+
#define PHY_SCSR_DP838XX_10M_Msk (2)
41+
42+
int16_t eth_phy_lan87xx_get_link_status(uint32_t phy_addr) {
43+
// Get the link mode & speed
44+
int16_t scsr = eth_phy_read(phy_addr, PHY_SCSR_LAN87XX);
45+
return (scsr >> PHY_SCSR_LAN87XX_SPEED_Pos) & PHY_SCSR_LAN87XX_SPEED_Msk;
46+
}
47+
48+
int16_t eth_phy_dp838xx_get_link_status(uint32_t phy_addr) {
49+
int16_t scsr = 0;
50+
// Get the link mode & speed
51+
uint16_t temp = eth_phy_read(phy_addr, PHY_SCSR_DP838XX);
52+
scsr = (temp & PHY_SCSR_DP838XX_10M_Msk) ? PHY_SPEED_10HALF : PHY_SPEED_100HALF;
53+
if (temp & PHY_SCSR_DP838XX_DUPLEX_Msk) {
54+
scsr |= PHY_DUPLEX;
55+
}
56+
return scsr;
57+
}
58+
59+
#endif

ports/stm32/eth_phy.h

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2019 Damien P. George
7+
* Copyright (c) 2024 Robert Hammelrath
8+
*
9+
* Permission is hereby granted, free of charge, to any person obtaining a copy
10+
* of this software and associated documentation files (the "Software"), to deal
11+
* in the Software without restriction, including without limitation the rights
12+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
* copies of the Software, and to permit persons to whom the Software is
14+
* furnished to do so, subject to the following conditions:
15+
*
16+
* The above copyright notice and this permission notice shall be included in
17+
* all copies or substantial portions of the Software.
18+
*
19+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
* THE SOFTWARE.
26+
*/
27+
28+
#ifndef MICROPY_INCLUDED_STM32_PHY_H
29+
#define MICROPY_INCLUDED_STM32_PYH_H
30+
31+
#if defined(MICROPY_HW_ETH_MDC)
32+
33+
// Common ETH PHY register definitions
34+
#undef PHY_BCR
35+
#define PHY_BCR (0x0000)
36+
#define PHY_BCR_SOFT_RESET (0x8000)
37+
#define PHY_BCR_AUTONEG_EN (0x1000)
38+
#define PHY_BCR_POWER_DOWN (0x0800U)
39+
40+
#undef PHY_BSR
41+
#define PHY_BSR (0x0001)
42+
#define PHY_BSR_LINK_STATUS (0x0004)
43+
#define PHY_BSR_AUTONEG_DONE (0x0020)
44+
45+
#undef PHY_ANAR
46+
#define PHY_ANAR (0x0004)
47+
#define PHY_ANAR_SPEED_10HALF (0x0020)
48+
#define PHY_ANAR_SPEED_10FULL (0x0040)
49+
#define PHY_ANAR_SPEED_100HALF (0x0080)
50+
#define PHY_ANAR_SPEED_100FULL (0x0100)
51+
#define PHY_ANAR_IEEE802_3 (0x0001)
52+
53+
#define PHY_SPEED_10HALF (1)
54+
#define PHY_SPEED_10FULL (5)
55+
#define PHY_SPEED_100HALF (2)
56+
#define PHY_SPEED_100FULL (6)
57+
#define PHY_DUPLEX (4)
58+
59+
uint32_t eth_phy_read(uint32_t phy_addr, uint32_t reg);
60+
void eth_phy_write(uint32_t phy_addr, uint32_t reg, uint32_t val);
61+
62+
int16_t eth_phy_lan87xx_get_link_status(uint32_t phy_addr);
63+
int16_t eth_phy_dp838xx_get_link_status(uint32_t phy_addr);
64+
65+
#endif
66+
67+
#endif // MICROPY_INCLUDED_STM32_PHY_H

ports/stm32/network_lan.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,19 @@ STATIC void network_lan_print(const mp_print_t *print, mp_obj_t self_in, mp_prin
5454
}
5555

5656
STATIC mp_obj_t network_lan_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
57-
enum { ARG_phy_addr};
57+
enum { ARG_phy_addr, ARG_phy_type};
5858
static const mp_arg_t allowed_args[] = {
5959
{ MP_QSTR_phy_addr, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
60+
{ MP_QSTR_phy_type, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = ETH_PHY_LAN8742} },
6061
};
6162
// Parse args.
6263
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
6364
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
6465

6566
const network_lan_obj_t *self = &network_lan_eth0;
66-
eth_init(self->eth, MP_HAL_MAC_ETH0, args[ARG_phy_addr].u_int);
67+
if (eth_init(self->eth, MP_HAL_MAC_ETH0, args[ARG_phy_addr].u_int, args[ARG_phy_type].u_int) != 0) {
68+
mp_raise_ValueError(MP_ERROR_TEXT("Invalid phy_type"));
69+
}
6770
return MP_OBJ_FROM_PTR(self);
6871
}
6972

@@ -162,6 +165,11 @@ STATIC const mp_rom_map_elem_t network_lan_locals_dict_table[] = {
162165
{ MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&network_lan_ifconfig_obj) },
163166
{ MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&network_lan_status_obj) },
164167
{ MP_ROM_QSTR(MP_QSTR_config), MP_ROM_PTR(&network_lan_config_obj) },
168+
169+
{ MP_ROM_QSTR(MP_QSTR_PHY_LAN8742), MP_ROM_INT(ETH_PHY_LAN8742) },
170+
{ MP_ROM_QSTR(MP_QSTR_PHY_LAN8720), MP_ROM_INT(ETH_PHY_LAN8720) },
171+
{ MP_ROM_QSTR(MP_QSTR_PHY_DP83848), MP_ROM_INT(ETH_PHY_DP83848) },
172+
{ MP_ROM_QSTR(MP_QSTR_PHY_DP83825), MP_ROM_INT(ETH_PHY_DP83825) },
165173
};
166174
STATIC MP_DEFINE_CONST_DICT(network_lan_locals_dict, network_lan_locals_dict_table);
167175

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy