Skip to content

Commit 74c8f74

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. Tested with LAN8720 and DP83848 breakout boards at 10M Duplex and 100M Duplex modes. Signed-off-by: robert-hh <robert@hammelrath.com>
1 parent 7297c7d commit 74c8f74

File tree

6 files changed

+168
-30
lines changed

6 files changed

+168
-30
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+
phy.c \
254255
gccollect.c \
255256
help.c \
256257
machine_bitstream.c \

ports/stm32/eth.c

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,14 @@
2626

2727
#include <string.h>
2828
#include "py/mphal.h"
29+
#include "py/runtime.h"
2930
#include "py/mperrno.h"
3031
#include "shared/netutils/netutils.h"
3132
#include "pin_static_af.h"
3233
#include "extmod/modnetwork.h"
3334
#include "mpu.h"
3435
#include "eth.h"
36+
#include "phy.h"
3537

3638
#if defined(MICROPY_HW_ETH_MDC)
3739

@@ -40,26 +42,6 @@
4042
#include "lwip/dhcp.h"
4143
#include "netif/ethernet.h"
4244

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-
6345
// ETH DMA RX and TX descriptor definitions
6446
#if defined(STM32H5)
6547
#define RX_DESCR_3_OWN_Pos (31)
@@ -137,6 +119,7 @@ typedef struct _eth_t {
137119
struct netif netif;
138120
struct dhcp dhcp_struct;
139121
uint32_t phy_addr;
122+
int16_t (*phy_get_link_status)(uint32_t phy_addr);
140123
} eth_t;
141124

142125
static eth_dma_t eth_dma __attribute__((aligned(16384)));
@@ -146,7 +129,7 @@ eth_t eth_instance;
146129
STATIC void eth_mac_deinit(eth_t *self);
147130
STATIC void eth_process_frame(eth_t *self, size_t len, const uint8_t *buf);
148131

149-
STATIC void eth_phy_write(uint32_t phy_addr, uint32_t reg, uint32_t val) {
132+
void eth_phy_write(uint32_t phy_addr, uint32_t reg, uint32_t val) {
150133
#if defined(STM32H5) || defined(STM32H7)
151134
while (ETH->MACMDIOAR & ETH_MACMDIOAR_MB) {
152135
}
@@ -174,7 +157,7 @@ STATIC void eth_phy_write(uint32_t phy_addr, uint32_t reg, uint32_t val) {
174157
#endif
175158
}
176159

177-
STATIC uint32_t eth_phy_read(uint32_t phy_addr, uint32_t reg) {
160+
uint32_t eth_phy_read(uint32_t phy_addr, uint32_t reg) {
178161
#if defined(STM32H5) || defined(STM32H7)
179162
while (ETH->MACMDIOAR & ETH_MACMDIOAR_MB) {
180163
}
@@ -202,10 +185,17 @@ STATIC uint32_t eth_phy_read(uint32_t phy_addr, uint32_t reg) {
202185
#endif
203186
}
204187

205-
void eth_init(eth_t *self, int mac_idx, int phy_addr) {
188+
void eth_init(eth_t *self, int mac_idx, int phy_addr, int phy_type) {
206189
mp_hal_get_mac(mac_idx, &self->netif.hwaddr[0]);
207190
self->netif.hwaddr_len = 6;
208191
self->phy_addr = phy_addr;
192+
if (phy_type == PHY_DP83825 || phy_type == PHY_DP83848) {
193+
self->phy_get_link_status = phy_dp838xx_get_link_status;
194+
} else if (phy_type == PHY_LAN8720 || phy_type == PHY_LAN8742) {
195+
self->phy_get_link_status = phy_lan87xx_get_link_status;
196+
} else {
197+
mp_raise_ValueError(MP_ERROR_TEXT("Invalid phy_type"));
198+
}
209199

210200
// Configure GPIO
211201
mp_hal_pin_config_alt_static(MICROPY_HW_ETH_MDC, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_ETH_MDC);
@@ -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
@@ -29,12 +29,19 @@
2929
typedef struct _eth_t eth_t;
3030
extern eth_t eth_instance;
3131

32-
void eth_init(eth_t *self, int mac_idx, int phy_addr);
32+
void eth_init(eth_t *self, int mac_idx, int phy_addr, int phy_type);
3333
void eth_set_trace(eth_t *self, uint32_t value);
3434
struct netif *eth_netif(eth_t *self);
3535
int eth_link_status(eth_t *self);
3636
int eth_start(eth_t *self);
3737
int eth_stop(eth_t *self);
3838
void eth_low_power_mode(eth_t *self, bool enable);
3939

40+
enum {
41+
PHY_LAN8742 = 0,
42+
PHY_LAN8720,
43+
PHY_DP83848,
44+
PHY_DP83825
45+
};
46+
4047
#endif // MICROPY_INCLUDED_STM32_ETH_H

ports/stm32/network_lan.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,17 @@ 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 = 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+
eth_init(self->eth, MP_HAL_MAC_ETH0, args[ARG_phy_addr].u_int, args[ARG_phy_type].u_int);
6768
return MP_OBJ_FROM_PTR(self);
6869
}
6970

@@ -162,6 +163,11 @@ STATIC const mp_rom_map_elem_t network_lan_locals_dict_table[] = {
162163
{ MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&network_lan_ifconfig_obj) },
163164
{ MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&network_lan_status_obj) },
164165
{ MP_ROM_QSTR(MP_QSTR_config), MP_ROM_PTR(&network_lan_config_obj) },
166+
167+
{ MP_ROM_QSTR(MP_QSTR_PHY_LAN8742), MP_ROM_INT(PHY_LAN8742) },
168+
{ MP_ROM_QSTR(MP_QSTR_PHY_LAN8720), MP_ROM_INT(PHY_LAN8720) },
169+
{ MP_ROM_QSTR(MP_QSTR_PHY_DP83848), MP_ROM_INT(PHY_DP83848) },
170+
{ MP_ROM_QSTR(MP_QSTR_PHY_DP83825), MP_ROM_INT(PHY_DP83825) },
165171
};
166172
STATIC MP_DEFINE_CONST_DICT(network_lan_locals_dict, network_lan_locals_dict_table);
167173

ports/stm32/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 "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 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 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/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 phy_lan87xx_get_link_status(uint32_t phy_addr);
63+
int16_t phy_dp838xx_get_link_status(uint32_t phy_addr);
64+
65+
#endif
66+
67+
#endif // MICROPY_INCLUDED_STM32_PHY_H

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