diff --git a/embassy-stm32/src/eth/generic_smi.rs b/embassy-stm32/src/eth/generic_smi.rs index 3b43051f4..239c52634 100644 --- a/embassy-stm32/src/eth/generic_smi.rs +++ b/embassy-stm32/src/eth/generic_smi.rs @@ -51,17 +51,63 @@ pub struct GenericSMI { impl GenericSMI { /// Construct the PHY. It assumes the address `phy_addr` in the SMI communication + /// + /// # 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 + 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; + } + // Give PHY a total of 100ms to respond + blocking_delay_us(10000); + } + } + 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 {} } 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, );