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");