summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrobert-hh <robert@hammelrath.com>2024-02-08 17:56:49 +0100
committerDamien George <damien@micropython.org>2024-03-07 17:54:02 +1100
commit185ae18360f47f8d97070689116b398b019e14db (patch)
treea095645c15b38bdc9f0605afa669fb0623df12a1
parentb3c62f31690ba0e6458589d934acd2db5ee92375 (diff)
stm32/network_lan: Allow defining phy_addr in the LAN constructor.
The default value is 0, which is compatible with the existing behaviour. Implementing that required changes to eth.c as well. The value of phy_addr is added to the eth_t data type. Tested with a STM32F767 and a STM32H750 device. Signed-off-by: robert-hh <robert@hammelrath.com>
-rw-r--r--ports/stm32/boards/ARDUINO_PORTENTA_H7/board_init.c2
-rw-r--r--ports/stm32/eth.c37
-rw-r--r--ports/stm32/eth.h2
-rw-r--r--ports/stm32/network_lan.c13
4 files changed, 33 insertions, 21 deletions
diff --git a/ports/stm32/boards/ARDUINO_PORTENTA_H7/board_init.c b/ports/stm32/boards/ARDUINO_PORTENTA_H7/board_init.c
index 39f782877..ad275ef87 100644
--- a/ports/stm32/boards/ARDUINO_PORTENTA_H7/board_init.c
+++ b/ports/stm32/boards/ARDUINO_PORTENTA_H7/board_init.c
@@ -115,7 +115,7 @@ void PORTENTA_board_early_init(void) {
mp_hal_pin_write(pyb_pin_ETH_RST, 1);
// Put Eth in low-power mode
- eth_init(&eth_instance, MP_HAL_MAC_ETH0);
+ eth_init(&eth_instance, MP_HAL_MAC_ETH0, 0);
eth_low_power_mode(&eth_instance, true);
#if MICROPY_HW_USB_HS_ULPI3320
diff --git a/ports/stm32/eth.c b/ports/stm32/eth.c
index 12c29f071..e1e6f074c 100644
--- a/ports/stm32/eth.c
+++ b/ports/stm32/eth.c
@@ -40,8 +40,7 @@
#include "lwip/dhcp.h"
#include "netif/ethernet.h"
-// ETH PHY register definitions (for LAN8742)
-
+// ETH PHY register definitions (for LAN8742 and LAN8720/LAN8710)
#undef PHY_BCR
#define PHY_BCR (0x0000)
#define PHY_BCR_SOFT_RESET (0x8000)
@@ -137,6 +136,7 @@ typedef struct _eth_t {
uint32_t trace_flags;
struct netif netif;
struct dhcp dhcp_struct;
+ uint32_t phy_addr;
} eth_t;
static eth_dma_t eth_dma __attribute__((aligned(16384)));
@@ -146,11 +146,13 @@ eth_t eth_instance;
static void eth_mac_deinit(eth_t *self);
static void eth_process_frame(eth_t *self, size_t len, const uint8_t *buf);
-static void eth_phy_write(uint32_t reg, uint32_t val) {
+static void eth_phy_write(uint32_t phy_addr, uint32_t reg, uint32_t val) {
#if defined(STM32H5) || defined(STM32H7)
while (ETH->MACMDIOAR & ETH_MACMDIOAR_MB) {
}
uint32_t ar = ETH->MACMDIOAR;
+ ar &= ~ETH_MACMDIOAR_PA_Msk;
+ ar |= (phy_addr << ETH_MACMDIOAR_PA_Pos);
ar &= ~ETH_MACMDIOAR_RDA_Msk;
ar |= reg << ETH_MACMDIOAR_RDA_Pos;
ar &= ~ETH_MACMDIOAR_MOC_Msk;
@@ -165,18 +167,20 @@ static void eth_phy_write(uint32_t reg, uint32_t val) {
}
ETH->MACMIIDR = val;
uint32_t ar = ETH->MACMIIAR;
- ar = reg << ETH_MACMIIAR_MR_Pos | (ar & ETH_MACMIIAR_CR_Msk) | ETH_MACMIIAR_MW | ETH_MACMIIAR_MB;
+ ar = (phy_addr << ETH_MACMIIAR_PA_Pos) | (reg << ETH_MACMIIAR_MR_Pos) | (ar & ETH_MACMIIAR_CR_Msk) | ETH_MACMIIAR_MW | ETH_MACMIIAR_MB;
ETH->MACMIIAR = ar;
while (ETH->MACMIIAR & ETH_MACMIIAR_MB) {
}
#endif
}
-static uint32_t eth_phy_read(uint32_t reg) {
+static uint32_t eth_phy_read(uint32_t phy_addr, uint32_t reg) {
#if defined(STM32H5) || defined(STM32H7)
while (ETH->MACMDIOAR & ETH_MACMDIOAR_MB) {
}
uint32_t ar = ETH->MACMDIOAR;
+ ar &= ~ETH_MACMDIOAR_PA_Msk;
+ ar |= (phy_addr << ETH_MACMDIOAR_PA_Pos);
ar &= ~ETH_MACMDIOAR_RDA_Msk;
ar |= reg << ETH_MACMDIOAR_RDA_Pos;
ar &= ~ETH_MACMDIOAR_MOC_Msk;
@@ -190,7 +194,7 @@ static uint32_t eth_phy_read(uint32_t reg) {
while (ETH->MACMIIAR & ETH_MACMIIAR_MB) {
}
uint32_t ar = ETH->MACMIIAR;
- ar = reg << ETH_MACMIIAR_MR_Pos | (ar & ETH_MACMIIAR_CR_Msk) | ETH_MACMIIAR_MB;
+ ar = (phy_addr << ETH_MACMIIAR_PA_Pos) | (reg << ETH_MACMIIAR_MR_Pos) | (ar & ETH_MACMIIAR_CR_Msk) | ETH_MACMIIAR_MB;
ETH->MACMIIAR = ar;
while (ETH->MACMIIAR & ETH_MACMIIAR_MB) {
}
@@ -198,9 +202,10 @@ static uint32_t eth_phy_read(uint32_t reg) {
#endif
}
-void eth_init(eth_t *self, int mac_idx) {
+void eth_init(eth_t *self, int mac_idx, uint32_t phy_addr) {
mp_hal_get_mac(mac_idx, &self->netif.hwaddr[0]);
self->netif.hwaddr_len = 6;
+ self->phy_addr = phy_addr;
// Configure GPIO
mp_hal_pin_config_alt_static(MICROPY_HW_ETH_MDC, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_ETH_MDC);
@@ -362,7 +367,7 @@ static int eth_mac_init(eth_t *self) {
#endif
// Reset the PHY
- eth_phy_write(PHY_BCR, PHY_BCR_SOFT_RESET);
+ eth_phy_write(self->phy_addr, PHY_BCR, PHY_BCR_SOFT_RESET);
mp_hal_delay_ms(50);
// Wait for the PHY link to be established
@@ -373,8 +378,8 @@ static int eth_mac_init(eth_t *self) {
eth_mac_deinit(self);
return -MP_ETIMEDOUT;
}
- uint16_t bcr = eth_phy_read(0);
- uint16_t bsr = eth_phy_read(1);
+ uint16_t bcr = eth_phy_read(self->phy_addr, PHY_BCR);
+ uint16_t bsr = eth_phy_read(self->phy_addr, PHY_BSR);
switch (phy_state) {
case 0:
if (!(bcr & PHY_BCR_SOFT_RESET)) {
@@ -383,7 +388,7 @@ static int eth_mac_init(eth_t *self) {
break;
case 1:
if (bsr & PHY_BSR_LINK_STATUS) {
- eth_phy_write(PHY_BCR, PHY_BCR_AUTONEG_EN);
+ eth_phy_write(self->phy_addr, PHY_BCR, PHY_BCR_AUTONEG_EN);
phy_state = 2;
}
break;
@@ -398,7 +403,7 @@ static int eth_mac_init(eth_t *self) {
}
// Get register with link status
- uint16_t phy_scsr = eth_phy_read(PHY_SCSR);
+ uint16_t phy_scsr = eth_phy_read(self->phy_addr, PHY_SCSR);
// Burst mode configuration
#if defined(STM32H5) || defined(STM32H7)
@@ -845,7 +850,7 @@ int eth_link_status(eth_t *self) {
return 2; // link no-ip;
}
} else {
- if (eth_phy_read(PHY_BSR) & PHY_BSR_LINK_STATUS) {
+ if (eth_phy_read(self->phy_addr, PHY_BSR) & PHY_BSR_LINK_STATUS) {
return 1; // link up
} else {
return 0; // link down
@@ -883,10 +888,10 @@ void eth_low_power_mode(eth_t *self, bool enable) {
__HAL_RCC_ETH_CLK_ENABLE();
#endif
- uint16_t bcr = eth_phy_read(PHY_BCR);
+ uint16_t bcr = eth_phy_read(self->phy_addr, PHY_BCR);
if (enable) {
// Enable low-power mode.
- eth_phy_write(PHY_BCR, bcr | PHY_BCR_POWER_DOWN);
+ eth_phy_write(self->phy_addr, PHY_BCR, bcr | PHY_BCR_POWER_DOWN);
// Disable eth clock.
#if defined(STM32H7)
__HAL_RCC_ETH1MAC_CLK_DISABLE();
@@ -895,7 +900,7 @@ void eth_low_power_mode(eth_t *self, bool enable) {
#endif
} else {
// Disable low-power mode.
- eth_phy_write(PHY_BCR, bcr & (~PHY_BCR_POWER_DOWN));
+ eth_phy_write(self->phy_addr, PHY_BCR, bcr & (~PHY_BCR_POWER_DOWN));
}
}
#endif // defined(MICROPY_HW_ETH_MDC)
diff --git a/ports/stm32/eth.h b/ports/stm32/eth.h
index 47344b952..45c385a25 100644
--- a/ports/stm32/eth.h
+++ b/ports/stm32/eth.h
@@ -29,7 +29,7 @@
typedef struct _eth_t eth_t;
extern eth_t eth_instance;
-void eth_init(eth_t *self, int mac_idx);
+void eth_init(eth_t *self, int mac_idx, uint32_t phy_addr);
void eth_set_trace(eth_t *self, uint32_t value);
struct netif *eth_netif(eth_t *self);
int eth_link_status(eth_t *self);
diff --git a/ports/stm32/network_lan.c b/ports/stm32/network_lan.c
index 2f70caf01..efdd354fb 100644
--- a/ports/stm32/network_lan.c
+++ b/ports/stm32/network_lan.c
@@ -53,10 +53,17 @@ static void network_lan_print(const mp_print_t *print, mp_obj_t self_in, mp_prin
);
}
-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 *args) {
- mp_arg_check_num(n_args, n_kw, 0, 0, false);
+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) {
+ enum { ARG_phy_addr};
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_phy_addr, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
+ };
+ // Parse args.
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
const network_lan_obj_t *self = &network_lan_eth0;
- eth_init(self->eth, MP_HAL_MAC_ETH0);
+ eth_init(self->eth, MP_HAL_MAC_ETH0, args[ARG_phy_addr].u_int);
return MP_OBJ_FROM_PTR(self);
}