From 51614ce365d4ec683560106d2af56f15d5ff38fa Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sun, 6 Jun 2021 21:42:48 +0200 Subject: [PATCH] stm32/eth: Add low-power mode configuration option. Add low power functionality configurable with: lan.config(low_power=True/False) --- ports/stm32/eth.c | 62 ++++++++++++++++++++++++++++++++------- ports/stm32/eth.h | 1 + ports/stm32/network_lan.c | 4 +++ 3 files changed, 56 insertions(+), 11 deletions(-) diff --git a/ports/stm32/eth.c b/ports/stm32/eth.c index 7a08e8c28c..30f8a1014e 100644 --- a/ports/stm32/eth.c +++ b/ports/stm32/eth.c @@ -46,6 +46,7 @@ #define PHY_BCR (0x0000) #define PHY_BCR_SOFT_RESET (0x8000) #define PHY_BCR_AUTONEG_EN (0x1000) +#define PHY_BCR_POWER_DOWN (0x0800U) #undef PHY_BSR #define PHY_BSR (0x0001) @@ -188,17 +189,6 @@ STATIC uint32_t eth_phy_read(uint32_t reg) { void eth_init(eth_t *self, int mac_idx) { mp_hal_get_mac(mac_idx, &self->netif.hwaddr[0]); self->netif.hwaddr_len = 6; -} - -void eth_set_trace(eth_t *self, uint32_t value) { - self->trace_flags = value; -} - -STATIC int eth_mac_init(eth_t *self) { - // Configure MPU - uint32_t irq_state = mpu_config_start(); - mpu_config_region(MPU_REGION_ETH, (uint32_t)ð_dma, MPU_CONFIG_ETH(MPU_REGION_SIZE_16KB)); - mpu_config_end(irq_state); // 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); @@ -211,6 +201,27 @@ STATIC int eth_mac_init(eth_t *self) { mp_hal_pin_config_alt_static(MICROPY_HW_ETH_RMII_TXD0, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_ETH_RMII_TXD0); mp_hal_pin_config_alt_static(MICROPY_HW_ETH_RMII_TXD1, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_ETH_RMII_TXD1); + // Enable peripheral clock + #if defined(STM32H7) + __HAL_RCC_ETH1MAC_CLK_ENABLE(); + __HAL_RCC_ETH1TX_CLK_ENABLE(); + __HAL_RCC_ETH1RX_CLK_ENABLE(); + #else + __HAL_RCC_ETH_CLK_ENABLE(); + #endif +} + +void eth_set_trace(eth_t *self, uint32_t value) { + self->trace_flags = value; +} + +STATIC int eth_mac_init(eth_t *self) { + // Configure MPU + uint32_t irq_state = mpu_config_start(); + mpu_config_region(MPU_REGION_ETH, (uint32_t)ð_dma, MPU_CONFIG_ETH(MPU_REGION_SIZE_16KB)); + mpu_config_end(irq_state); + + // Enable peripheral clock #if defined(STM32H7) __HAL_RCC_ETH1MAC_CLK_ENABLE(); __HAL_RCC_ETH1TX_CLK_ENABLE(); @@ -791,6 +802,10 @@ int eth_link_status(eth_t *self) { int eth_start(eth_t *self) { eth_lwip_deinit(self); + + // Make sure Eth is Not in low power mode. + eth_low_power_mode(self, false); + int ret = eth_mac_init(self); if (ret < 0) { return ret; @@ -805,4 +820,29 @@ int eth_stop(eth_t *self) { return 0; } +void eth_low_power_mode(eth_t *self, bool enable) { + (void)self; + + // Enable eth clock + #if defined(STM32H7) + __HAL_RCC_ETH1MAC_CLK_ENABLE(); + #else + __HAL_RCC_ETH_CLK_ENABLE(); + #endif + + uint16_t bcr = eth_phy_read(PHY_BCR); + if (enable) { + // Enable low-power mode. + eth_phy_write(PHY_BCR, bcr | PHY_BCR_POWER_DOWN); + // Disable eth clock. + #if defined(STM32H7) + __HAL_RCC_ETH1MAC_CLK_DISABLE(); + #else + __HAL_RCC_ETH_CLK_DISABLE(); + #endif + } else { + // Disable low-power mode. + eth_phy_write(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 fd46c7fa7c..47344b9526 100644 --- a/ports/stm32/eth.h +++ b/ports/stm32/eth.h @@ -35,5 +35,6 @@ struct netif *eth_netif(eth_t *self); int eth_link_status(eth_t *self); int eth_start(eth_t *self); int eth_stop(eth_t *self); +void eth_low_power_mode(eth_t *self, bool enable); #endif // MICROPY_INCLUDED_STM32_ETH_H diff --git a/ports/stm32/network_lan.c b/ports/stm32/network_lan.c index 19b4e786d9..6dd9aadb65 100644 --- a/ports/stm32/network_lan.c +++ b/ports/stm32/network_lan.c @@ -134,6 +134,10 @@ STATIC mp_obj_t network_lan_config(size_t n_args, const mp_obj_t *args, mp_map_t eth_set_trace(self->eth, mp_obj_get_int(e->value)); break; } + case MP_QSTR_low_power: { + eth_low_power_mode(self->eth, mp_obj_get_int(e->value)); + break; + } default: mp_raise_ValueError(MP_ERROR_TEXT("unknown config param")); }