From 5885369f47d1260e58656bfc13bebba6339cf6cc Mon Sep 17 00:00:00 2001 From: nikvoid Date: Wed, 22 Jan 2025 13:23:29 +0200 Subject: [PATCH 1/6] Option to detect Ethernet PHY address automatically --- embassy-stm32/src/eth/generic_smi.rs | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/embassy-stm32/src/eth/generic_smi.rs b/embassy-stm32/src/eth/generic_smi.rs index 3b43051f4..06d01124f 100644 --- a/embassy-stm32/src/eth/generic_smi.rs +++ b/embassy-stm32/src/eth/generic_smi.rs @@ -51,6 +51,8 @@ pub struct GenericSMI { impl GenericSMI { /// Construct the PHY. It assumes the address `phy_addr` in the SMI communication + /// + /// Set `phy_addr` to `0xFF` for automatic detection pub fn new(phy_addr: u8) -> Self { Self { phy_addr, @@ -62,8 +64,24 @@ impl GenericSMI { unsafe impl PHY for GenericSMI { fn phy_reset(&mut self, sm: &mut S) { - sm.smi_write(self.phy_addr, PHY_REG_BCR, PHY_REG_BCR_RESET); - while sm.smi_read(self.phy_addr, PHY_REG_BCR) & PHY_REG_BCR_RESET == PHY_REG_BCR_RESET {} + // Detect SMI address + if self.phy_addr == 0xFF { + for addr in 0..32 { + sm.smi_write(addr, PHY_REG_BCR, PHY_REG_BCR_RESET); + for _ in 0..10 { + if sm.smi_read(addr, PHY_REG_BCR) & PHY_REG_BCR_RESET != PHY_REG_BCR_RESET { + trace!("Found ETH PHY on address {}", addr); + self.phy_addr = addr; + return; + } + cortex_m::asm::delay(1000); + } + } + panic!("PHY did not respond"); + } else { + sm.smi_write(self.phy_addr, PHY_REG_BCR, PHY_REG_BCR_RESET); + while sm.smi_read(self.phy_addr, PHY_REG_BCR) & PHY_REG_BCR_RESET == PHY_REG_BCR_RESET {} + } } fn phy_init(&mut self, sm: &mut S) { From 2d7e0b6e0fe4ee6ee1a7a32401ae3eeea3b08301 Mon Sep 17 00:00:00 2001 From: nikvoid Date: Wed, 22 Jan 2025 13:43:45 +0200 Subject: [PATCH 2/6] use `Delay` from `embassy-time` to wait for PHY response --- embassy-stm32/src/eth/generic_smi.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/embassy-stm32/src/eth/generic_smi.rs b/embassy-stm32/src/eth/generic_smi.rs index 06d01124f..ef673a301 100644 --- a/embassy-stm32/src/eth/generic_smi.rs +++ b/embassy-stm32/src/eth/generic_smi.rs @@ -3,7 +3,7 @@ use core::task::Context; #[cfg(feature = "time")] -use embassy_time::{Duration, Timer}; +use embassy_time::{Duration, Timer, Delay}; #[cfg(feature = "time")] use futures_util::FutureExt; @@ -52,7 +52,7 @@ pub struct GenericSMI { impl GenericSMI { /// Construct the PHY. It assumes the address `phy_addr` in the SMI communication /// - /// Set `phy_addr` to `0xFF` for automatic detection + /// Set `phy_addr` to `0xFF` for automatic detection (only with `time` feature enabled) pub fn new(phy_addr: u8) -> Self { Self { phy_addr, @@ -65,6 +65,7 @@ impl GenericSMI { unsafe impl PHY for GenericSMI { fn phy_reset(&mut self, sm: &mut S) { // Detect SMI address + #[cfg(feature = "time")] if self.phy_addr == 0xFF { for addr in 0..32 { sm.smi_write(addr, PHY_REG_BCR, PHY_REG_BCR_RESET); @@ -74,14 +75,15 @@ unsafe impl PHY for GenericSMI { self.phy_addr = addr; return; } - cortex_m::asm::delay(1000); + embedded_hal_1::delay::DelayNs::delay_us(&mut Delay, 1000); + cortex_m::asm::delay(1000000); } } panic!("PHY did not respond"); - } else { - sm.smi_write(self.phy_addr, PHY_REG_BCR, PHY_REG_BCR_RESET); - while sm.smi_read(self.phy_addr, PHY_REG_BCR) & PHY_REG_BCR_RESET == PHY_REG_BCR_RESET {} } + + sm.smi_write(self.phy_addr, PHY_REG_BCR, PHY_REG_BCR_RESET); + while sm.smi_read(self.phy_addr, PHY_REG_BCR) & PHY_REG_BCR_RESET == PHY_REG_BCR_RESET {} } fn phy_init(&mut self, sm: &mut S) { From 83ccbf48d70859b881f459e9c294acce213ac0d9 Mon Sep 17 00:00:00 2001 From: nikvoid Date: Wed, 22 Jan 2025 18:09:25 +0200 Subject: [PATCH 3/6] remove cortex-m delay --- embassy-stm32/src/eth/generic_smi.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/embassy-stm32/src/eth/generic_smi.rs b/embassy-stm32/src/eth/generic_smi.rs index ef673a301..acd793958 100644 --- a/embassy-stm32/src/eth/generic_smi.rs +++ b/embassy-stm32/src/eth/generic_smi.rs @@ -76,7 +76,6 @@ unsafe impl PHY for GenericSMI { return; } embedded_hal_1::delay::DelayNs::delay_us(&mut Delay, 1000); - cortex_m::asm::delay(1000000); } } panic!("PHY did not respond"); From dff8be9bb6b02c0162bcc595df34b0bc0c3e0e83 Mon Sep 17 00:00:00 2001 From: nikvoid Date: Wed, 22 Jan 2025 18:11:32 +0200 Subject: [PATCH 4/6] run rustfmt --- embassy-stm32/src/eth/generic_smi.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/embassy-stm32/src/eth/generic_smi.rs b/embassy-stm32/src/eth/generic_smi.rs index acd793958..41d19e921 100644 --- a/embassy-stm32/src/eth/generic_smi.rs +++ b/embassy-stm32/src/eth/generic_smi.rs @@ -3,7 +3,7 @@ use core::task::Context; #[cfg(feature = "time")] -use embassy_time::{Duration, Timer, Delay}; +use embassy_time::{Delay, Duration, Timer}; #[cfg(feature = "time")] use futures_util::FutureExt; @@ -80,7 +80,7 @@ unsafe impl PHY for GenericSMI { } panic!("PHY did not respond"); } - + sm.smi_write(self.phy_addr, PHY_REG_BCR, PHY_REG_BCR_RESET); while sm.smi_read(self.phy_addr, PHY_REG_BCR) & PHY_REG_BCR_RESET == PHY_REG_BCR_RESET {} } From afe6b9a192f1434bb024040a20cef9509c307871 Mon Sep 17 00:00:00 2001 From: nikvoid Date: Thu, 23 Jan 2025 13:34:54 +0200 Subject: [PATCH 5/6] split PHY constructor to `new` and `new_auto` --- embassy-stm32/src/eth/generic_smi.rs | 35 ++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/embassy-stm32/src/eth/generic_smi.rs b/embassy-stm32/src/eth/generic_smi.rs index 41d19e921..239c52634 100644 --- a/embassy-stm32/src/eth/generic_smi.rs +++ b/embassy-stm32/src/eth/generic_smi.rs @@ -3,7 +3,7 @@ use core::task::Context; #[cfg(feature = "time")] -use embassy_time::{Delay, Duration, Timer}; +use embassy_time::{Duration, Timer}; #[cfg(feature = "time")] use futures_util::FutureExt; @@ -52,20 +52,46 @@ pub struct GenericSMI { impl GenericSMI { /// Construct the PHY. It assumes the address `phy_addr` in the SMI communication /// - /// Set `phy_addr` to `0xFF` for automatic detection (only with `time` feature enabled) + /// # Panics + /// `phy_addr` must be in range `0..32` pub fn new(phy_addr: u8) -> Self { + assert!(phy_addr < 32); Self { phy_addr, #[cfg(feature = "time")] poll_interval: Duration::from_millis(500), } } + + /// Construct the PHY. Try to probe all addresses from 0 to 31 during initialization + /// + /// # Panics + /// Initialization panics if PHY didn't respond on any address + pub fn new_auto() -> Self { + Self { + phy_addr: 0xFF, + #[cfg(feature = "time")] + poll_interval: Duration::from_millis(500), + } + } +} + +// TODO: Factor out to shared functionality +fn blocking_delay_us(us: u32) { + #[cfg(feature = "time")] + embassy_time::block_for(Duration::from_micros(us as u64)); + #[cfg(not(feature = "time"))] + { + let freq = unsafe { crate::rcc::get_freqs() }.sys.to_hertz().unwrap().0 as u64; + let us = us as u64; + let cycles = freq * us / 1_000_000; + cortex_m::asm::delay(cycles as u32); + } } unsafe impl PHY for GenericSMI { fn phy_reset(&mut self, sm: &mut S) { // Detect SMI address - #[cfg(feature = "time")] if self.phy_addr == 0xFF { for addr in 0..32 { sm.smi_write(addr, PHY_REG_BCR, PHY_REG_BCR_RESET); @@ -75,7 +101,8 @@ unsafe impl PHY for GenericSMI { self.phy_addr = addr; return; } - embedded_hal_1::delay::DelayNs::delay_us(&mut Delay, 1000); + // Give PHY a total of 100ms to respond + blocking_delay_us(10000); } } panic!("PHY did not respond"); From ff52bde787031493ce174cdc1dcc2434fd16aa1b Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Sun, 26 Jan 2025 21:53:00 +0100 Subject: [PATCH 6/6] stm32: change all examples and tests to use GenericSMI::new_auto(). --- examples/stm32f4/src/bin/eth.rs | 2 +- examples/stm32f7/src/bin/eth.rs | 2 +- examples/stm32h5/src/bin/eth.rs | 2 +- examples/stm32h7/src/bin/eth.rs | 2 +- examples/stm32h7/src/bin/eth_client.rs | 2 +- examples/stm32h7/src/bin/eth_client_mii.rs | 2 +- tests/stm32/src/bin/eth.rs | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/stm32f4/src/bin/eth.rs b/examples/stm32f4/src/bin/eth.rs index baed96449..a3af8f75c 100644 --- a/examples/stm32f4/src/bin/eth.rs +++ b/examples/stm32f4/src/bin/eth.rs @@ -76,7 +76,7 @@ async fn main(spawner: Spawner) -> ! { p.PG13, p.PB13, p.PG11, - GenericSMI::new(0), + GenericSMI::new_auto(), mac_addr, ); diff --git a/examples/stm32f7/src/bin/eth.rs b/examples/stm32f7/src/bin/eth.rs index 1f1eadf37..f353af674 100644 --- a/examples/stm32f7/src/bin/eth.rs +++ b/examples/stm32f7/src/bin/eth.rs @@ -77,7 +77,7 @@ async fn main(spawner: Spawner) -> ! { p.PG13, p.PB13, p.PG11, - GenericSMI::new(0), + GenericSMI::new_auto(), mac_addr, ); diff --git a/examples/stm32h5/src/bin/eth.rs b/examples/stm32h5/src/bin/eth.rs index eee1632f5..ead346741 100644 --- a/examples/stm32h5/src/bin/eth.rs +++ b/examples/stm32h5/src/bin/eth.rs @@ -80,7 +80,7 @@ async fn main(spawner: Spawner) -> ! { p.PG13, p.PB15, p.PG11, - GenericSMI::new(0), + GenericSMI::new_auto(), mac_addr, ); diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs index ec3f2c000..6665cd1d0 100644 --- a/examples/stm32h7/src/bin/eth.rs +++ b/examples/stm32h7/src/bin/eth.rs @@ -79,7 +79,7 @@ async fn main(spawner: Spawner) -> ! { p.PG13, // TX_D0: Transmit Bit 0 p.PB13, // TX_D1: Transmit Bit 1 p.PG11, // TX_EN: Transmit Enable - GenericSMI::new(0), + GenericSMI::new_auto(), mac_addr, ); diff --git a/examples/stm32h7/src/bin/eth_client.rs b/examples/stm32h7/src/bin/eth_client.rs index a1558b079..4fbe10f31 100644 --- a/examples/stm32h7/src/bin/eth_client.rs +++ b/examples/stm32h7/src/bin/eth_client.rs @@ -81,7 +81,7 @@ async fn main(spawner: Spawner) -> ! { p.PG13, p.PB13, p.PG11, - GenericSMI::new(0), + GenericSMI::new_auto(), mac_addr, ); diff --git a/examples/stm32h7/src/bin/eth_client_mii.rs b/examples/stm32h7/src/bin/eth_client_mii.rs index a352ef444..53f86ac80 100644 --- a/examples/stm32h7/src/bin/eth_client_mii.rs +++ b/examples/stm32h7/src/bin/eth_client_mii.rs @@ -86,7 +86,7 @@ async fn main(spawner: Spawner) -> ! { p.PC2, p.PE2, p.PG11, - GenericSMI::new(1), + GenericSMI::new_auto(), mac_addr, ); info!("Device created"); diff --git a/tests/stm32/src/bin/eth.rs b/tests/stm32/src/bin/eth.rs index bf1922dde..4ab6e234f 100644 --- a/tests/stm32/src/bin/eth.rs +++ b/tests/stm32/src/bin/eth.rs @@ -87,7 +87,7 @@ async fn main(spawner: Spawner) { #[cfg(feature = "stm32h563zi")] p.PB15, p.PG11, - GenericSMI::new(0), + GenericSMI::new_auto(), mac_addr, );