aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/eth/generic_phy.rs45
-rw-r--r--embassy-stm32/src/eth/mod.rs15
-rw-r--r--embassy-stm32/src/eth/sma/mod.rs13
-rw-r--r--embassy-stm32/src/eth/v1/mod.rs24
-rw-r--r--embassy-stm32/src/eth/v2/mod.rs24
-rw-r--r--tests/stm32/src/bin/eth.rs14
6 files changed, 48 insertions, 87 deletions
diff --git a/embassy-stm32/src/eth/generic_phy.rs b/embassy-stm32/src/eth/generic_phy.rs
index 947874d7f..4e61a83e7 100644
--- a/embassy-stm32/src/eth/generic_phy.rs
+++ b/embassy-stm32/src/eth/generic_phy.rs
@@ -44,21 +44,23 @@ mod phy_consts {
44use self::phy_consts::*; 44use self::phy_consts::*;
45 45
46/// Generic SMI Ethernet PHY implementation 46/// Generic SMI Ethernet PHY implementation
47pub struct GenericPhy { 47pub struct GenericPhy<SM: StationManagement> {
48 phy_addr: u8, 48 phy_addr: u8,
49 sm: SM,
49 #[cfg(feature = "time")] 50 #[cfg(feature = "time")]
50 poll_interval: Duration, 51 poll_interval: Duration,
51} 52}
52 53
53impl GenericPhy { 54impl<SM: StationManagement> GenericPhy<SM> {
54 /// Construct the PHY. It assumes the address `phy_addr` in the SMI communication 55 /// Construct the PHY. It assumes the address `phy_addr` in the SMI communication
55 /// 56 ///
56 /// # Panics 57 /// # Panics
57 /// `phy_addr` must be in range `0..32` 58 /// `phy_addr` must be in range `0..32`
58 pub fn new(phy_addr: u8) -> Self { 59 pub fn new(sm: SM, phy_addr: u8) -> Self {
59 assert!(phy_addr < 32); 60 assert!(phy_addr < 32);
60 Self { 61 Self {
61 phy_addr, 62 phy_addr,
63 sm,
62 #[cfg(feature = "time")] 64 #[cfg(feature = "time")]
63 poll_interval: Duration::from_millis(500), 65 poll_interval: Duration::from_millis(500),
64 } 66 }
@@ -68,8 +70,9 @@ impl GenericPhy {
68 /// 70 ///
69 /// # Panics 71 /// # Panics
70 /// Initialization panics if PHY didn't respond on any address 72 /// Initialization panics if PHY didn't respond on any address
71 pub fn new_auto() -> Self { 73 pub fn new_auto(sm: SM) -> Self {
72 Self { 74 Self {
75 sm,
73 phy_addr: 0xFF, 76 phy_addr: 0xFF,
74 #[cfg(feature = "time")] 77 #[cfg(feature = "time")]
75 poll_interval: Duration::from_millis(500), 78 poll_interval: Duration::from_millis(500),
@@ -77,14 +80,14 @@ impl GenericPhy {
77 } 80 }
78} 81}
79 82
80impl Phy for GenericPhy { 83impl<SM: StationManagement> Phy for GenericPhy<SM> {
81 fn phy_reset<S: StationManagement>(&mut self, sm: &mut S) { 84 fn phy_reset(&mut self) {
82 // Detect SMI address 85 // Detect SMI address
83 if self.phy_addr == 0xFF { 86 if self.phy_addr == 0xFF {
84 for addr in 0..32 { 87 for addr in 0..32 {
85 sm.smi_write(addr, PHY_REG_BCR, PHY_REG_BCR_RESET); 88 self.sm.smi_write(addr, PHY_REG_BCR, PHY_REG_BCR_RESET);
86 for _ in 0..10 { 89 for _ in 0..10 {
87 if sm.smi_read(addr, PHY_REG_BCR) & PHY_REG_BCR_RESET != PHY_REG_BCR_RESET { 90 if self.sm.smi_read(addr, PHY_REG_BCR) & PHY_REG_BCR_RESET != PHY_REG_BCR_RESET {
88 trace!("Found ETH PHY on address {}", addr); 91 trace!("Found ETH PHY on address {}", addr);
89 self.phy_addr = addr; 92 self.phy_addr = addr;
90 return; 93 return;
@@ -96,30 +99,30 @@ impl Phy for GenericPhy {
96 panic!("PHY did not respond"); 99 panic!("PHY did not respond");
97 } 100 }
98 101
99 sm.smi_write(self.phy_addr, PHY_REG_BCR, PHY_REG_BCR_RESET); 102 self.sm.smi_write(self.phy_addr, PHY_REG_BCR, PHY_REG_BCR_RESET);
100 while sm.smi_read(self.phy_addr, PHY_REG_BCR) & PHY_REG_BCR_RESET == PHY_REG_BCR_RESET {} 103 while self.sm.smi_read(self.phy_addr, PHY_REG_BCR) & PHY_REG_BCR_RESET == PHY_REG_BCR_RESET {}
101 } 104 }
102 105
103 fn phy_init<S: StationManagement>(&mut self, sm: &mut S) { 106 fn phy_init(&mut self) {
104 // Clear WU CSR 107 // Clear WU CSR
105 self.smi_write_ext(sm, PHY_REG_WUCSR, 0); 108 self.smi_write_ext(PHY_REG_WUCSR, 0);
106 109
107 // Enable auto-negotiation 110 // Enable auto-negotiation
108 sm.smi_write( 111 self.sm.smi_write(
109 self.phy_addr, 112 self.phy_addr,
110 PHY_REG_BCR, 113 PHY_REG_BCR,
111 PHY_REG_BCR_AN | PHY_REG_BCR_ANRST | PHY_REG_BCR_100M, 114 PHY_REG_BCR_AN | PHY_REG_BCR_ANRST | PHY_REG_BCR_100M,
112 ); 115 );
113 } 116 }
114 117
115 fn poll_link<S: StationManagement>(&mut self, sm: &mut S, cx: &mut Context) -> bool { 118 fn poll_link(&mut self, cx: &mut Context) -> bool {
116 #[cfg(not(feature = "time"))] 119 #[cfg(not(feature = "time"))]
117 cx.waker().wake_by_ref(); 120 cx.waker().wake_by_ref();
118 121
119 #[cfg(feature = "time")] 122 #[cfg(feature = "time")]
120 let _ = Timer::after(self.poll_interval).poll_unpin(cx); 123 let _ = Timer::after(self.poll_interval).poll_unpin(cx);
121 124
122 let bsr = sm.smi_read(self.phy_addr, PHY_REG_BSR); 125 let bsr = self.sm.smi_read(self.phy_addr, PHY_REG_BSR);
123 126
124 // No link without autonegotiate 127 // No link without autonegotiate
125 if bsr & PHY_REG_BSR_ANDONE == 0 { 128 if bsr & PHY_REG_BSR_ANDONE == 0 {
@@ -136,7 +139,7 @@ impl Phy for GenericPhy {
136} 139}
137 140
138/// Public functions for the PHY 141/// Public functions for the PHY
139impl GenericPhy { 142impl<SM: StationManagement> GenericPhy<SM> {
140 /// Set the SMI polling interval. 143 /// Set the SMI polling interval.
141 #[cfg(feature = "time")] 144 #[cfg(feature = "time")]
142 pub fn set_poll_interval(&mut self, poll_interval: Duration) { 145 pub fn set_poll_interval(&mut self, poll_interval: Duration) {
@@ -144,10 +147,10 @@ impl GenericPhy {
144 } 147 }
145 148
146 // Writes a value to an extended PHY register in MMD address space 149 // Writes a value to an extended PHY register in MMD address space
147 fn smi_write_ext<S: StationManagement>(&mut self, sm: &mut S, reg_addr: u16, reg_data: u16) { 150 fn smi_write_ext(&mut self, reg_addr: u16, reg_data: u16) {
148 sm.smi_write(self.phy_addr, PHY_REG_CTL, 0x0003); // set address 151 self.sm.smi_write(self.phy_addr, PHY_REG_CTL, 0x0003); // set address
149 sm.smi_write(self.phy_addr, PHY_REG_ADDAR, reg_addr); 152 self.sm.smi_write(self.phy_addr, PHY_REG_ADDAR, reg_addr);
150 sm.smi_write(self.phy_addr, PHY_REG_CTL, 0x4003); // set data 153 self.sm.smi_write(self.phy_addr, PHY_REG_CTL, 0x4003); // set data
151 sm.smi_write(self.phy_addr, PHY_REG_ADDAR, reg_data); 154 self.sm.smi_write(self.phy_addr, PHY_REG_ADDAR, reg_data);
152 } 155 }
153} 156}
diff --git a/embassy-stm32/src/eth/mod.rs b/embassy-stm32/src/eth/mod.rs
index 448d21f3f..c8bce0e8a 100644
--- a/embassy-stm32/src/eth/mod.rs
+++ b/embassy-stm32/src/eth/mod.rs
@@ -111,7 +111,7 @@ impl<'d, T: Instance, P: Phy> embassy_net_driver::Driver for Ethernet<'d, T, P>
111 } 111 }
112 112
113 fn link_state(&mut self, cx: &mut Context) -> LinkState { 113 fn link_state(&mut self, cx: &mut Context) -> LinkState {
114 if self.phy.poll_link(&mut self.station_management, cx) { 114 if self.phy.poll_link(cx) {
115 LinkState::Up 115 LinkState::Up
116 } else { 116 } else {
117 LinkState::Down 117 LinkState::Down
@@ -162,21 +162,14 @@ impl<'a, 'd> embassy_net_driver::TxToken for TxToken<'a, 'd> {
162/// Trait for an Ethernet PHY 162/// Trait for an Ethernet PHY
163pub trait Phy { 163pub trait Phy {
164 /// Reset PHY and wait for it to come out of reset. 164 /// Reset PHY and wait for it to come out of reset.
165 fn phy_reset<S: StationManagement>(&mut self, sm: &mut S); 165 fn phy_reset(&mut self);
166 /// PHY initialisation. 166 /// PHY initialisation.
167 fn phy_init<S: StationManagement>(&mut self, sm: &mut S); 167 fn phy_init(&mut self);
168 /// Poll link to see if it is up and FD with 100Mbps 168 /// Poll link to see if it is up and FD with 100Mbps
169 fn poll_link<S: StationManagement>(&mut self, sm: &mut S, cx: &mut Context) -> bool; 169 fn poll_link(&mut self, cx: &mut Context) -> bool;
170} 170}
171 171
172impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> { 172impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
173 /// Directly expose the SMI interface used by the Ethernet driver.
174 ///
175 /// This can be used to for example configure special PHY registers for compliance testing.
176 pub fn station_management(&mut self) -> &mut impl StationManagement {
177 &mut self.station_management
178 }
179
180 /// Access the user-supplied `Phy`. 173 /// Access the user-supplied `Phy`.
181 pub fn phy(&self) -> &P { 174 pub fn phy(&self) -> &P {
182 &self.phy 175 &self.phy
diff --git a/embassy-stm32/src/eth/sma/mod.rs b/embassy-stm32/src/eth/sma/mod.rs
index 558107abc..6c851911d 100644
--- a/embassy-stm32/src/eth/sma/mod.rs
+++ b/embassy-stm32/src/eth/sma/mod.rs
@@ -39,17 +39,4 @@ impl SealedInstance for crate::peripherals::ETH_SMA {
39 } 39 }
40} 40}
41 41
42impl<T: crate::eth::Instance> SealedInstance for T {
43 fn regs() -> (Reg<AddressRegister, RW>, Reg<DataRegister, RW>) {
44 let mac = <T as crate::eth::SealedInstance>::regs().ethernet_mac();
45
46 #[cfg(any(eth_v1a, eth_v1b, eth_v1c))]
47 return (mac.macmiiar(), mac.macmiidr());
48
49 #[cfg(eth_v2)]
50 return (mac.macmdioar(), mac.macmdiodr());
51 }
52}
53
54impl Instance for crate::peripherals::ETH_SMA {} 42impl Instance for crate::peripherals::ETH_SMA {}
55impl<T: crate::eth::Instance> Instance for T {}
diff --git a/embassy-stm32/src/eth/v1/mod.rs b/embassy-stm32/src/eth/v1/mod.rs
index d448537c8..45cd33d9a 100644
--- a/embassy-stm32/src/eth/v1/mod.rs
+++ b/embassy-stm32/src/eth/v1/mod.rs
@@ -10,9 +10,7 @@ use stm32_metapac::eth::vals::{Apcs, Dm, DmaomrSr, Fes, Ftf, Ifg, Pbl, Rsf, St,
10 10
11pub(crate) use self::rx_desc::{RDes, RDesRing}; 11pub(crate) use self::rx_desc::{RDes, RDesRing};
12pub(crate) use self::tx_desc::{TDes, TDesRing}; 12pub(crate) use self::tx_desc::{TDes, TDesRing};
13use super::sma::Sma;
14use super::*; 13use super::*;
15use crate::eth::{MDCPin, MDIOPin};
16#[cfg(eth_v1a)] 14#[cfg(eth_v1a)]
17use crate::gpio::Pull; 15use crate::gpio::Pull;
18use crate::gpio::{AfType, AnyPin, OutputType, SealedPin, Speed}; 16use crate::gpio::{AfType, AnyPin, OutputType, SealedPin, Speed};
@@ -53,7 +51,6 @@ pub struct Ethernet<'d, T: Instance, P: Phy> {
53 51
54 pins: Pins<'d>, 52 pins: Pins<'d>,
55 pub(crate) phy: P, 53 pub(crate) phy: P,
56 pub(crate) station_management: Sma<'d, T>,
57 pub(crate) mac_addr: [u8; 6], 54 pub(crate) mac_addr: [u8; 6],
58} 55}
59 56
@@ -104,8 +101,6 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
104 peri: Peri<'d, T>, 101 peri: Peri<'d, T>,
105 irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd, 102 irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd,
106 ref_clk: Peri<'d, if_afio!(impl RefClkPin<T, A>)>, 103 ref_clk: Peri<'d, if_afio!(impl RefClkPin<T, A>)>,
107 mdio: Peri<'d, if_afio!(impl MDIOPin<T, A>)>,
108 mdc: Peri<'d, if_afio!(impl MDCPin<T, A>)>,
109 crs: Peri<'d, if_afio!(impl CRSPin<T, A>)>, 104 crs: Peri<'d, if_afio!(impl CRSPin<T, A>)>,
110 rx_d0: Peri<'d, if_afio!(impl RXD0Pin<T, A>)>, 105 rx_d0: Peri<'d, if_afio!(impl RXD0Pin<T, A>)>,
111 rx_d1: Peri<'d, if_afio!(impl RXD1Pin<T, A>)>, 106 rx_d1: Peri<'d, if_afio!(impl RXD1Pin<T, A>)>,
@@ -165,16 +160,14 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
165 tx_en.into(), 160 tx_en.into(),
166 ]); 161 ]);
167 162
168 Self::new_inner(queue, peri, irq, pins, mdio, mdc, phy, mac_addr) 163 Self::new_inner(queue, peri, irq, pins, phy, mac_addr)
169 } 164 }
170 165
171 fn new_inner<const TX: usize, const RX: usize, #[cfg(afio)] A>( 166 fn new_inner<const TX: usize, const RX: usize>(
172 queue: &'d mut PacketQueue<TX, RX>, 167 queue: &'d mut PacketQueue<TX, RX>,
173 peri: Peri<'d, T>, 168 peri: Peri<'d, T>,
174 _irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd, 169 _irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd,
175 pins: Pins<'d>, 170 pins: Pins<'d>,
176 mdio: Peri<'d, if_afio!(impl MDIOPin<T, A>)>,
177 mdc: Peri<'d, if_afio!(impl MDCPin<T, A>)>,
178 phy: P, 171 phy: P,
179 mac_addr: [u8; 6], 172 mac_addr: [u8; 6],
180 ) -> Self { 173 ) -> Self {
@@ -226,13 +219,10 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
226 219
227 // TODO MTU size setting not found for v1 ethernet, check if correct 220 // TODO MTU size setting not found for v1 ethernet, check if correct
228 221
229 let sma_peri = unsafe { peri.clone_unchecked() };
230
231 let mut this = Self { 222 let mut this = Self {
232 _peri: peri, 223 _peri: peri,
233 pins, 224 pins,
234 phy: phy, 225 phy: phy,
235 station_management: Sma::new(sma_peri, mdio, mdc),
236 mac_addr, 226 mac_addr,
237 tx: TDesRing::new(&mut queue.tx_desc, &mut queue.tx_buf), 227 tx: TDesRing::new(&mut queue.tx_desc, &mut queue.tx_buf),
238 rx: RDesRing::new(&mut queue.rx_desc, &mut queue.rx_buf), 228 rx: RDesRing::new(&mut queue.rx_desc, &mut queue.rx_buf),
@@ -262,8 +252,8 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
262 w.set_tie(true); 252 w.set_tie(true);
263 }); 253 });
264 254
265 this.phy.phy_reset(&mut this.station_management); 255 this.phy.phy_reset();
266 this.phy.phy_init(&mut this.station_management); 256 this.phy.phy_init();
267 257
268 interrupt::ETH.unpend(); 258 interrupt::ETH.unpend();
269 unsafe { interrupt::ETH.enable() }; 259 unsafe { interrupt::ETH.enable() };
@@ -271,15 +261,13 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
271 this 261 this
272 } 262 }
273 263
274 /// Create a new MII ethernet driver using 14 pins. 264 /// Create a new MII ethernet driver using 12 pins.
275 pub fn new_mii<const TX: usize, const RX: usize, #[cfg(afio)] A>( 265 pub fn new_mii<const TX: usize, const RX: usize, #[cfg(afio)] A>(
276 queue: &'d mut PacketQueue<TX, RX>, 266 queue: &'d mut PacketQueue<TX, RX>,
277 peri: Peri<'d, T>, 267 peri: Peri<'d, T>,
278 irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd, 268 irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd,
279 rx_clk: Peri<'d, if_afio!(impl RXClkPin<T, A>)>, 269 rx_clk: Peri<'d, if_afio!(impl RXClkPin<T, A>)>,
280 tx_clk: Peri<'d, if_afio!(impl TXClkPin<T, A>)>, 270 tx_clk: Peri<'d, if_afio!(impl TXClkPin<T, A>)>,
281 mdio: Peri<'d, if_afio!(impl MDIOPin<T, A>)>,
282 mdc: Peri<'d, if_afio!(impl MDCPin<T, A>)>,
283 rxdv: Peri<'d, if_afio!(impl RXDVPin<T, A>)>, 271 rxdv: Peri<'d, if_afio!(impl RXDVPin<T, A>)>,
284 rx_d0: Peri<'d, if_afio!(impl RXD0Pin<T, A>)>, 272 rx_d0: Peri<'d, if_afio!(impl RXD0Pin<T, A>)>,
285 rx_d1: Peri<'d, if_afio!(impl RXD1Pin<T, A>)>, 273 rx_d1: Peri<'d, if_afio!(impl RXD1Pin<T, A>)>,
@@ -352,7 +340,7 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
352 tx_en.into(), 340 tx_en.into(),
353 ]); 341 ]);
354 342
355 Self::new_inner(queue, peri, irq, pins, mdio, mdc, phy, mac_addr) 343 Self::new_inner(queue, peri, irq, pins, phy, mac_addr)
356 } 344 }
357} 345}
358 346
diff --git a/embassy-stm32/src/eth/v2/mod.rs b/embassy-stm32/src/eth/v2/mod.rs
index 0db335a7c..faed7d8e2 100644
--- a/embassy-stm32/src/eth/v2/mod.rs
+++ b/embassy-stm32/src/eth/v2/mod.rs
@@ -6,9 +6,7 @@ use embassy_hal_internal::Peri;
6use stm32_metapac::syscfg::vals::EthSelPhy; 6use stm32_metapac::syscfg::vals::EthSelPhy;
7 7
8pub(crate) use self::descriptors::{RDes, RDesRing, TDes, TDesRing}; 8pub(crate) use self::descriptors::{RDes, RDesRing, TDes, TDesRing};
9use super::sma::Sma;
10use super::*; 9use super::*;
11use crate::eth::{MDCPin, MDIOPin};
12use crate::gpio::{AfType, AnyPin, OutputType, SealedPin as _, Speed}; 10use crate::gpio::{AfType, AnyPin, OutputType, SealedPin as _, Speed};
13use crate::interrupt; 11use crate::interrupt;
14use crate::interrupt::InterruptExt; 12use crate::interrupt::InterruptExt;
@@ -42,7 +40,6 @@ pub struct Ethernet<'d, T: Instance, P: Phy> {
42 pub(crate) rx: RDesRing<'d>, 40 pub(crate) rx: RDesRing<'d>,
43 pins: Pins<'d>, 41 pins: Pins<'d>,
44 pub(crate) phy: P, 42 pub(crate) phy: P,
45 pub(crate) station_management: Sma<'d, T>,
46 pub(crate) mac_addr: [u8; 6], 43 pub(crate) mac_addr: [u8; 6],
47} 44}
48 45
@@ -64,14 +61,12 @@ macro_rules! config_pins {
64} 61}
65 62
66impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> { 63impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
67 /// Create a new RMII ethernet driver using 9 pins. 64 /// Create a new RMII ethernet driver using 7 pins.
68 pub fn new<const TX: usize, const RX: usize>( 65 pub fn new<const TX: usize, const RX: usize>(
69 queue: &'d mut PacketQueue<TX, RX>, 66 queue: &'d mut PacketQueue<TX, RX>,
70 peri: Peri<'d, T>, 67 peri: Peri<'d, T>,
71 irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd, 68 irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd,
72 ref_clk: Peri<'d, impl RefClkPin<T>>, 69 ref_clk: Peri<'d, impl RefClkPin<T>>,
73 mdio: Peri<'d, impl MDIOPin<T>>,
74 mdc: Peri<'d, impl MDCPin<T>>,
75 crs: Peri<'d, impl CRSPin<T>>, 70 crs: Peri<'d, impl CRSPin<T>>,
76 rx_d0: Peri<'d, impl RXD0Pin<T>>, 71 rx_d0: Peri<'d, impl RXD0Pin<T>>,
77 rx_d1: Peri<'d, impl RXD1Pin<T>>, 72 rx_d1: Peri<'d, impl RXD1Pin<T>>,
@@ -104,18 +99,16 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
104 tx_en.into(), 99 tx_en.into(),
105 ]); 100 ]);
106 101
107 Self::new_inner(queue, peri, irq, pins, mdio, mdc, phy, mac_addr) 102 Self::new_inner(queue, peri, irq, pins, phy, mac_addr)
108 } 103 }
109 104
110 /// Create a new MII ethernet driver using 14 pins. 105 /// Create a new MII ethernet driver using 12 pins.
111 pub fn new_mii<const TX: usize, const RX: usize>( 106 pub fn new_mii<const TX: usize, const RX: usize>(
112 queue: &'d mut PacketQueue<TX, RX>, 107 queue: &'d mut PacketQueue<TX, RX>,
113 peri: Peri<'d, T>, 108 peri: Peri<'d, T>,
114 irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd, 109 irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd,
115 rx_clk: Peri<'d, impl RXClkPin<T>>, 110 rx_clk: Peri<'d, impl RXClkPin<T>>,
116 tx_clk: Peri<'d, impl TXClkPin<T>>, 111 tx_clk: Peri<'d, impl TXClkPin<T>>,
117 mdio: Peri<'d, impl MDIOPin<T>>,
118 mdc: Peri<'d, impl MDCPin<T>>,
119 rxdv: Peri<'d, impl RXDVPin<T>>, 112 rxdv: Peri<'d, impl RXDVPin<T>>,
120 rx_d0: Peri<'d, impl RXD0Pin<T>>, 113 rx_d0: Peri<'d, impl RXD0Pin<T>>,
121 rx_d1: Peri<'d, impl RXD1Pin<T>>, 114 rx_d1: Peri<'d, impl RXD1Pin<T>>,
@@ -161,7 +154,7 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
161 tx_en.into(), 154 tx_en.into(),
162 ]); 155 ]);
163 156
164 Self::new_inner(queue, peri, irq, pins, mdio, mdc, phy, mac_addr) 157 Self::new_inner(queue, peri, irq, pins, phy, mac_addr)
165 } 158 }
166 159
167 fn new_inner<const TX: usize, const RX: usize>( 160 fn new_inner<const TX: usize, const RX: usize>(
@@ -169,8 +162,6 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
169 peri: Peri<'d, T>, 162 peri: Peri<'d, T>,
170 _irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd, 163 _irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd,
171 pins: Pins<'d>, 164 pins: Pins<'d>,
172 mdio: Peri<'d, impl MDIOPin<T>>,
173 mdc: Peri<'d, impl MDCPin<T>>,
174 phy: P, 165 phy: P,
175 mac_addr: [u8; 6], 166 mac_addr: [u8; 6],
176 ) -> Self { 167 ) -> Self {
@@ -235,15 +226,12 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
235 w.set_rbsz(RX_BUFFER_SIZE as u16); 226 w.set_rbsz(RX_BUFFER_SIZE as u16);
236 }); 227 });
237 228
238 let sma_peri = unsafe { peri.clone_unchecked() };
239
240 let mut this = Self { 229 let mut this = Self {
241 _peri: peri, 230 _peri: peri,
242 tx: TDesRing::new(&mut queue.tx_desc, &mut queue.tx_buf), 231 tx: TDesRing::new(&mut queue.tx_desc, &mut queue.tx_buf),
243 rx: RDesRing::new(&mut queue.rx_desc, &mut queue.rx_buf), 232 rx: RDesRing::new(&mut queue.rx_desc, &mut queue.rx_buf),
244 pins, 233 pins,
245 phy, 234 phy,
246 station_management: Sma::new(sma_peri, mdio, mdc),
247 mac_addr, 235 mac_addr,
248 }; 236 };
249 237
@@ -269,8 +257,8 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
269 w.set_tie(true); 257 w.set_tie(true);
270 }); 258 });
271 259
272 this.phy.phy_reset(&mut this.station_management); 260 this.phy.phy_reset();
273 this.phy.phy_init(&mut this.station_management); 261 this.phy.phy_init();
274 262
275 interrupt::ETH.unpend(); 263 interrupt::ETH.unpend();
276 unsafe { interrupt::ETH.enable() }; 264 unsafe { interrupt::ETH.enable() };
diff --git a/tests/stm32/src/bin/eth.rs b/tests/stm32/src/bin/eth.rs
index a65682a02..95789ffc5 100644
--- a/tests/stm32/src/bin/eth.rs
+++ b/tests/stm32/src/bin/eth.rs
@@ -7,8 +7,8 @@ mod common;
7use common::*; 7use common::*;
8use embassy_executor::Spawner; 8use embassy_executor::Spawner;
9use embassy_net::StackResources; 9use embassy_net::StackResources;
10use embassy_stm32::eth::{Ethernet, GenericPhy, PacketQueue}; 10use embassy_stm32::eth::{Ethernet, GenericPhy, PacketQueue, Sma};
11use embassy_stm32::peripherals::ETH; 11use embassy_stm32::peripherals::{ETH, ETH_SMA};
12use embassy_stm32::rng::Rng; 12use embassy_stm32::rng::Rng;
13use embassy_stm32::{bind_interrupts, eth, peripherals, rng}; 13use embassy_stm32::{bind_interrupts, eth, peripherals, rng};
14use static_cell::StaticCell; 14use static_cell::StaticCell;
@@ -27,7 +27,7 @@ bind_interrupts!(struct Irqs {
27 RNG => rng::InterruptHandler<peripherals::RNG>; 27 RNG => rng::InterruptHandler<peripherals::RNG>;
28}); 28});
29 29
30type Device = Ethernet<'static, ETH, GenericPhy>; 30type Device = Ethernet<'static, ETH, GenericPhy<Sma<'static, ETH_SMA>>>;
31 31
32#[embassy_executor::task] 32#[embassy_executor::task]
33async fn net_task(mut runner: embassy_net::Runner<'static, Device>) -> ! { 33async fn net_task(mut runner: embassy_net::Runner<'static, Device>) -> ! {
@@ -69,13 +69,15 @@ async fn main(spawner: Spawner) {
69 const PACKET_QUEUE_SIZE: usize = 4; 69 const PACKET_QUEUE_SIZE: usize = 4;
70 70
71 static PACKETS: StaticCell<PacketQueue<PACKET_QUEUE_SIZE, PACKET_QUEUE_SIZE>> = StaticCell::new(); 71 static PACKETS: StaticCell<PacketQueue<PACKET_QUEUE_SIZE, PACKET_QUEUE_SIZE>> = StaticCell::new();
72
73 let sma = Sma::new(p.ETH_SMA, p.PA2, p.PC1);
74 let phy = GenericPhy::new_auto(sma);
75
72 let device = Ethernet::new( 76 let device = Ethernet::new(
73 PACKETS.init(PacketQueue::<PACKET_QUEUE_SIZE, PACKET_QUEUE_SIZE>::new()), 77 PACKETS.init(PacketQueue::<PACKET_QUEUE_SIZE, PACKET_QUEUE_SIZE>::new()),
74 p.ETH, 78 p.ETH,
75 Irqs, 79 Irqs,
76 p.PA1, 80 p.PA1,
77 p.PA2,
78 p.PC1,
79 p.PA7, 81 p.PA7,
80 p.PC4, 82 p.PC4,
81 p.PC5, 83 p.PC5,
@@ -85,7 +87,7 @@ async fn main(spawner: Spawner) {
85 #[cfg(feature = "stm32h563zi")] 87 #[cfg(feature = "stm32h563zi")]
86 p.PB15, 88 p.PB15,
87 p.PG11, 89 p.PG11,
88 GenericPhy::new_auto(), 90 phy,
89 mac_addr, 91 mac_addr,
90 ); 92 );
91 93