aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2025-01-26 21:21:06 +0000
committerGitHub <[email protected]>2025-01-26 21:21:06 +0000
commitc8d29a1e2cd3f28c3afdd52a679fcb49f67e812c (patch)
tree56ef4d76ecb959851ca714f1cff7d7026e2ed845 /embassy-stm32
parent7e0c70b1aa6ac6072e2c98cabb10072e4cd9942d (diff)
parentff52bde787031493ce174cdc1dcc2434fd16aa1b (diff)
Merge pull request #3795 from nikvoid/stm32-phy-addr-detection
STM32: Option to detect Ethernet PHY address automatically
Diffstat (limited to 'embassy-stm32')
-rw-r--r--embassy-stm32/src/eth/generic_smi.rs46
1 files changed, 46 insertions, 0 deletions
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 {
51 51
52impl GenericSMI { 52impl GenericSMI {
53 /// Construct the PHY. It assumes the address `phy_addr` in the SMI communication 53 /// Construct the PHY. It assumes the address `phy_addr` in the SMI communication
54 ///
55 /// # Panics
56 /// `phy_addr` must be in range `0..32`
54 pub fn new(phy_addr: u8) -> Self { 57 pub fn new(phy_addr: u8) -> Self {
58 assert!(phy_addr < 32);
55 Self { 59 Self {
56 phy_addr, 60 phy_addr,
57 #[cfg(feature = "time")] 61 #[cfg(feature = "time")]
58 poll_interval: Duration::from_millis(500), 62 poll_interval: Duration::from_millis(500),
59 } 63 }
60 } 64 }
65
66 /// Construct the PHY. Try to probe all addresses from 0 to 31 during initialization
67 ///
68 /// # Panics
69 /// Initialization panics if PHY didn't respond on any address
70 pub fn new_auto() -> Self {
71 Self {
72 phy_addr: 0xFF,
73 #[cfg(feature = "time")]
74 poll_interval: Duration::from_millis(500),
75 }
76 }
77}
78
79// TODO: Factor out to shared functionality
80fn blocking_delay_us(us: u32) {
81 #[cfg(feature = "time")]
82 embassy_time::block_for(Duration::from_micros(us as u64));
83 #[cfg(not(feature = "time"))]
84 {
85 let freq = unsafe { crate::rcc::get_freqs() }.sys.to_hertz().unwrap().0 as u64;
86 let us = us as u64;
87 let cycles = freq * us / 1_000_000;
88 cortex_m::asm::delay(cycles as u32);
89 }
61} 90}
62 91
63unsafe impl PHY for GenericSMI { 92unsafe impl PHY for GenericSMI {
64 fn phy_reset<S: StationManagement>(&mut self, sm: &mut S) { 93 fn phy_reset<S: StationManagement>(&mut self, sm: &mut S) {
94 // Detect SMI address
95 if self.phy_addr == 0xFF {
96 for addr in 0..32 {
97 sm.smi_write(addr, PHY_REG_BCR, PHY_REG_BCR_RESET);
98 for _ in 0..10 {
99 if sm.smi_read(addr, PHY_REG_BCR) & PHY_REG_BCR_RESET != PHY_REG_BCR_RESET {
100 trace!("Found ETH PHY on address {}", addr);
101 self.phy_addr = addr;
102 return;
103 }
104 // Give PHY a total of 100ms to respond
105 blocking_delay_us(10000);
106 }
107 }
108 panic!("PHY did not respond");
109 }
110
65 sm.smi_write(self.phy_addr, PHY_REG_BCR, PHY_REG_BCR_RESET); 111 sm.smi_write(self.phy_addr, PHY_REG_BCR, PHY_REG_BCR_RESET);
66 while sm.smi_read(self.phy_addr, PHY_REG_BCR) & PHY_REG_BCR_RESET == PHY_REG_BCR_RESET {} 112 while sm.smi_read(self.phy_addr, PHY_REG_BCR) & PHY_REG_BCR_RESET == PHY_REG_BCR_RESET {}
67 } 113 }