diff options
| author | Dario Nieuwenhuis <[email protected]> | 2025-01-26 21:21:06 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-01-26 21:21:06 +0000 |
| commit | c8d29a1e2cd3f28c3afdd52a679fcb49f67e812c (patch) | |
| tree | 56ef4d76ecb959851ca714f1cff7d7026e2ed845 | |
| parent | 7e0c70b1aa6ac6072e2c98cabb10072e4cd9942d (diff) | |
| parent | ff52bde787031493ce174cdc1dcc2434fd16aa1b (diff) | |
Merge pull request #3795 from nikvoid/stm32-phy-addr-detection
STM32: Option to detect Ethernet PHY address automatically
| -rw-r--r-- | embassy-stm32/src/eth/generic_smi.rs | 46 | ||||
| -rw-r--r-- | examples/stm32f4/src/bin/eth.rs | 2 | ||||
| -rw-r--r-- | examples/stm32f7/src/bin/eth.rs | 2 | ||||
| -rw-r--r-- | examples/stm32h5/src/bin/eth.rs | 2 | ||||
| -rw-r--r-- | examples/stm32h7/src/bin/eth.rs | 2 | ||||
| -rw-r--r-- | examples/stm32h7/src/bin/eth_client.rs | 2 | ||||
| -rw-r--r-- | examples/stm32h7/src/bin/eth_client_mii.rs | 2 | ||||
| -rw-r--r-- | tests/stm32/src/bin/eth.rs | 2 |
8 files changed, 53 insertions, 7 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 | ||
| 52 | impl GenericSMI { | 52 | impl 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 | ||
| 80 | fn 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 | ||
| 63 | unsafe impl PHY for GenericSMI { | 92 | unsafe 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 | } |
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) -> ! { | |||
| 76 | p.PG13, | 76 | p.PG13, |
| 77 | p.PB13, | 77 | p.PB13, |
| 78 | p.PG11, | 78 | p.PG11, |
| 79 | GenericSMI::new(0), | 79 | GenericSMI::new_auto(), |
| 80 | mac_addr, | 80 | mac_addr, |
| 81 | ); | 81 | ); |
| 82 | 82 | ||
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) -> ! { | |||
| 77 | p.PG13, | 77 | p.PG13, |
| 78 | p.PB13, | 78 | p.PB13, |
| 79 | p.PG11, | 79 | p.PG11, |
| 80 | GenericSMI::new(0), | 80 | GenericSMI::new_auto(), |
| 81 | mac_addr, | 81 | mac_addr, |
| 82 | ); | 82 | ); |
| 83 | 83 | ||
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) -> ! { | |||
| 80 | p.PG13, | 80 | p.PG13, |
| 81 | p.PB15, | 81 | p.PB15, |
| 82 | p.PG11, | 82 | p.PG11, |
| 83 | GenericSMI::new(0), | 83 | GenericSMI::new_auto(), |
| 84 | mac_addr, | 84 | mac_addr, |
| 85 | ); | 85 | ); |
| 86 | 86 | ||
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) -> ! { | |||
| 79 | p.PG13, // TX_D0: Transmit Bit 0 | 79 | p.PG13, // TX_D0: Transmit Bit 0 |
| 80 | p.PB13, // TX_D1: Transmit Bit 1 | 80 | p.PB13, // TX_D1: Transmit Bit 1 |
| 81 | p.PG11, // TX_EN: Transmit Enable | 81 | p.PG11, // TX_EN: Transmit Enable |
| 82 | GenericSMI::new(0), | 82 | GenericSMI::new_auto(), |
| 83 | mac_addr, | 83 | mac_addr, |
| 84 | ); | 84 | ); |
| 85 | 85 | ||
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) -> ! { | |||
| 81 | p.PG13, | 81 | p.PG13, |
| 82 | p.PB13, | 82 | p.PB13, |
| 83 | p.PG11, | 83 | p.PG11, |
| 84 | GenericSMI::new(0), | 84 | GenericSMI::new_auto(), |
| 85 | mac_addr, | 85 | mac_addr, |
| 86 | ); | 86 | ); |
| 87 | 87 | ||
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) -> ! { | |||
| 86 | p.PC2, | 86 | p.PC2, |
| 87 | p.PE2, | 87 | p.PE2, |
| 88 | p.PG11, | 88 | p.PG11, |
| 89 | GenericSMI::new(1), | 89 | GenericSMI::new_auto(), |
| 90 | mac_addr, | 90 | mac_addr, |
| 91 | ); | 91 | ); |
| 92 | info!("Device created"); | 92 | 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) { | |||
| 87 | #[cfg(feature = "stm32h563zi")] | 87 | #[cfg(feature = "stm32h563zi")] |
| 88 | p.PB15, | 88 | p.PB15, |
| 89 | p.PG11, | 89 | p.PG11, |
| 90 | GenericSMI::new(0), | 90 | GenericSMI::new_auto(), |
| 91 | mac_addr, | 91 | mac_addr, |
| 92 | ); | 92 | ); |
| 93 | 93 | ||
