diff options
| author | xoviat <[email protected]> | 2023-07-15 09:32:36 -0500 |
|---|---|---|
| committer | xoviat <[email protected]> | 2023-07-15 09:32:36 -0500 |
| commit | 48b37aa2bf83b8fccb293fcda7f51149a4ec1a24 (patch) | |
| tree | e0f2491897f7eeca1e3ed078ee0b451c0a0daa22 /embassy-stm32/src/eth | |
| parent | 3bae53306683a57020ba751afaf631ec169deeed (diff) | |
stm32/eth: refactor genericsmi
Diffstat (limited to 'embassy-stm32/src/eth')
| -rw-r--r-- | embassy-stm32/src/eth/generic_smi.rs | 10 | ||||
| -rw-r--r-- | embassy-stm32/src/eth/mod.rs | 10 | ||||
| -rw-r--r-- | embassy-stm32/src/eth/v1/mod.rs | 27 | ||||
| -rw-r--r-- | embassy-stm32/src/eth/v2/mod.rs | 27 |
4 files changed, 47 insertions, 27 deletions
diff --git a/embassy-stm32/src/eth/generic_smi.rs b/embassy-stm32/src/eth/generic_smi.rs index 968256046..1d83cec35 100644 --- a/embassy-stm32/src/eth/generic_smi.rs +++ b/embassy-stm32/src/eth/generic_smi.rs | |||
| @@ -1,5 +1,7 @@ | |||
| 1 | //! Generic SMI Ethernet PHY | 1 | //! Generic SMI Ethernet PHY |
| 2 | 2 | ||
| 3 | use futures::task::Context; | ||
| 4 | |||
| 3 | use super::{StationManagement, PHY}; | 5 | use super::{StationManagement, PHY}; |
| 4 | 6 | ||
| 5 | #[allow(dead_code)] | 7 | #[allow(dead_code)] |
| @@ -40,13 +42,13 @@ pub struct GenericSMI; | |||
| 40 | 42 | ||
| 41 | unsafe impl PHY for GenericSMI { | 43 | unsafe impl PHY for GenericSMI { |
| 42 | /// Reset PHY and wait for it to come out of reset. | 44 | /// Reset PHY and wait for it to come out of reset. |
| 43 | fn phy_reset<S: StationManagement>(sm: &mut S) { | 45 | fn phy_reset<S: StationManagement>(&mut self, sm: &mut S) { |
| 44 | sm.smi_write(PHY_REG_BCR, PHY_REG_BCR_RESET); | 46 | sm.smi_write(PHY_REG_BCR, PHY_REG_BCR_RESET); |
| 45 | while sm.smi_read(PHY_REG_BCR) & PHY_REG_BCR_RESET == PHY_REG_BCR_RESET {} | 47 | while sm.smi_read(PHY_REG_BCR) & PHY_REG_BCR_RESET == PHY_REG_BCR_RESET {} |
| 46 | } | 48 | } |
| 47 | 49 | ||
| 48 | /// PHY initialisation. | 50 | /// PHY initialisation. |
| 49 | fn phy_init<S: StationManagement>(sm: &mut S) { | 51 | fn phy_init<S: StationManagement>(&mut self, sm: &mut S) { |
| 50 | // Clear WU CSR | 52 | // Clear WU CSR |
| 51 | Self::smi_write_ext(sm, PHY_REG_WUCSR, 0); | 53 | Self::smi_write_ext(sm, PHY_REG_WUCSR, 0); |
| 52 | 54 | ||
| @@ -54,7 +56,9 @@ unsafe impl PHY for GenericSMI { | |||
| 54 | sm.smi_write(PHY_REG_BCR, PHY_REG_BCR_AN | PHY_REG_BCR_ANRST | PHY_REG_BCR_100M); | 56 | sm.smi_write(PHY_REG_BCR, PHY_REG_BCR_AN | PHY_REG_BCR_ANRST | PHY_REG_BCR_100M); |
| 55 | } | 57 | } |
| 56 | 58 | ||
| 57 | fn poll_link<S: StationManagement>(sm: &mut S) -> bool { | 59 | fn poll_link<S: StationManagement>(&mut self, sm: &mut S, cx: &mut Context) -> bool { |
| 60 | cx.waker().wake_by_ref(); | ||
| 61 | |||
| 58 | let bsr = sm.smi_read(PHY_REG_BSR); | 62 | let bsr = sm.smi_read(PHY_REG_BSR); |
| 59 | 63 | ||
| 60 | // No link without autonegotiate | 64 | // No link without autonegotiate |
diff --git a/embassy-stm32/src/eth/mod.rs b/embassy-stm32/src/eth/mod.rs index 4989e17c7..1687cb319 100644 --- a/embassy-stm32/src/eth/mod.rs +++ b/embassy-stm32/src/eth/mod.rs | |||
| @@ -81,9 +81,7 @@ impl<'d, T: Instance, P: PHY> embassy_net_driver::Driver for Ethernet<'d, T, P> | |||
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | fn link_state(&mut self, cx: &mut Context) -> LinkState { | 83 | fn link_state(&mut self, cx: &mut Context) -> LinkState { |
| 84 | // TODO: wake cx.waker on link state change | 84 | if self.phy.poll_link(&mut self.station_management, cx) { |
| 85 | cx.waker().wake_by_ref(); | ||
| 86 | if P::poll_link(self) { | ||
| 87 | LinkState::Up | 85 | LinkState::Up |
| 88 | } else { | 86 | } else { |
| 89 | LinkState::Down | 87 | LinkState::Down |
| @@ -148,11 +146,11 @@ pub unsafe trait StationManagement { | |||
| 148 | /// The methods cannot move S | 146 | /// The methods cannot move S |
| 149 | pub unsafe trait PHY { | 147 | pub unsafe trait PHY { |
| 150 | /// Reset PHY and wait for it to come out of reset. | 148 | /// Reset PHY and wait for it to come out of reset. |
| 151 | fn phy_reset<S: StationManagement>(sm: &mut S); | 149 | fn phy_reset<S: StationManagement>(&mut self, sm: &mut S); |
| 152 | /// PHY initialisation. | 150 | /// PHY initialisation. |
| 153 | fn phy_init<S: StationManagement>(sm: &mut S); | 151 | fn phy_init<S: StationManagement>(&mut self, sm: &mut S); |
| 154 | /// Poll link to see if it is up and FD with 100Mbps | 152 | /// Poll link to see if it is up and FD with 100Mbps |
| 155 | fn poll_link<S: StationManagement>(sm: &mut S) -> bool; | 153 | fn poll_link<S: StationManagement>(&mut self, sm: &mut S, cx: &mut Context) -> bool; |
| 156 | } | 154 | } |
| 157 | 155 | ||
| 158 | pub(crate) mod sealed { | 156 | pub(crate) mod sealed { |
diff --git a/embassy-stm32/src/eth/v1/mod.rs b/embassy-stm32/src/eth/v1/mod.rs index b53c2d0fa..2a6ea35ff 100644 --- a/embassy-stm32/src/eth/v1/mod.rs +++ b/embassy-stm32/src/eth/v1/mod.rs | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | mod rx_desc; | 3 | mod rx_desc; |
| 4 | mod tx_desc; | 4 | mod tx_desc; |
| 5 | 5 | ||
| 6 | use core::marker::PhantomData; | ||
| 6 | use core::sync::atomic::{fence, Ordering}; | 7 | use core::sync::atomic::{fence, Ordering}; |
| 7 | 8 | ||
| 8 | use embassy_hal_common::{into_ref, PeripheralRef}; | 9 | use embassy_hal_common::{into_ref, PeripheralRef}; |
| @@ -48,9 +49,8 @@ pub struct Ethernet<'d, T: Instance, P: PHY> { | |||
| 48 | pub(crate) rx: RDesRing<'d>, | 49 | pub(crate) rx: RDesRing<'d>, |
| 49 | 50 | ||
| 50 | pins: [PeripheralRef<'d, AnyPin>; 9], | 51 | pins: [PeripheralRef<'d, AnyPin>; 9], |
| 51 | _phy: P, | 52 | pub(crate) phy: P, |
| 52 | clock_range: Cr, | 53 | pub(crate) station_management: EthernetStationManagement<T>, |
| 53 | phy_addr: u8, | ||
| 54 | pub(crate) mac_addr: [u8; 6], | 54 | pub(crate) mac_addr: [u8; 6], |
| 55 | } | 55 | } |
| 56 | 56 | ||
| @@ -224,9 +224,12 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> { | |||
| 224 | let mut this = Self { | 224 | let mut this = Self { |
| 225 | _peri: peri, | 225 | _peri: peri, |
| 226 | pins, | 226 | pins, |
| 227 | _phy: phy, | 227 | phy: phy, |
| 228 | clock_range, | 228 | station_management: EthernetStationManagement { |
| 229 | phy_addr, | 229 | peri: PhantomData, |
| 230 | clock_range: clock_range, | ||
| 231 | phy_addr: phy_addr, | ||
| 232 | }, | ||
| 230 | mac_addr, | 233 | mac_addr, |
| 231 | tx: TDesRing::new(&mut queue.tx_desc, &mut queue.tx_buf), | 234 | tx: TDesRing::new(&mut queue.tx_desc, &mut queue.tx_buf), |
| 232 | rx: RDesRing::new(&mut queue.rx_desc, &mut queue.rx_buf), | 235 | rx: RDesRing::new(&mut queue.rx_desc, &mut queue.rx_buf), |
| @@ -256,8 +259,8 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> { | |||
| 256 | w.set_tie(true); | 259 | w.set_tie(true); |
| 257 | }); | 260 | }); |
| 258 | 261 | ||
| 259 | P::phy_reset(&mut this); | 262 | this.phy.phy_reset(&mut this.station_management); |
| 260 | P::phy_init(&mut this); | 263 | this.phy.phy_init(&mut this.station_management); |
| 261 | 264 | ||
| 262 | interrupt::ETH.unpend(); | 265 | interrupt::ETH.unpend(); |
| 263 | unsafe { interrupt::ETH.enable() }; | 266 | unsafe { interrupt::ETH.enable() }; |
| @@ -266,7 +269,13 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> { | |||
| 266 | } | 269 | } |
| 267 | } | 270 | } |
| 268 | 271 | ||
| 269 | unsafe impl<'d, T: Instance, P: PHY> StationManagement for Ethernet<'d, T, P> { | 272 | pub struct EthernetStationManagement<T: Instance> { |
| 273 | peri: PhantomData<T>, | ||
| 274 | clock_range: Cr, | ||
| 275 | phy_addr: u8, | ||
| 276 | } | ||
| 277 | |||
| 278 | unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> { | ||
| 270 | fn smi_read(&mut self, reg: u8) -> u16 { | 279 | fn smi_read(&mut self, reg: u8) -> u16 { |
| 271 | let mac = ETH.ethernet_mac(); | 280 | let mac = ETH.ethernet_mac(); |
| 272 | 281 | ||
diff --git a/embassy-stm32/src/eth/v2/mod.rs b/embassy-stm32/src/eth/v2/mod.rs index 600e1d3bc..bb681c42b 100644 --- a/embassy-stm32/src/eth/v2/mod.rs +++ b/embassy-stm32/src/eth/v2/mod.rs | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | mod descriptors; | 1 | mod descriptors; |
| 2 | 2 | ||
| 3 | use core::marker::PhantomData; | ||
| 3 | use core::sync::atomic::{fence, Ordering}; | 4 | use core::sync::atomic::{fence, Ordering}; |
| 4 | 5 | ||
| 5 | use embassy_hal_common::{into_ref, PeripheralRef}; | 6 | use embassy_hal_common::{into_ref, PeripheralRef}; |
| @@ -40,9 +41,8 @@ pub struct Ethernet<'d, T: Instance, P: PHY> { | |||
| 40 | pub(crate) tx: TDesRing<'d>, | 41 | pub(crate) tx: TDesRing<'d>, |
| 41 | pub(crate) rx: RDesRing<'d>, | 42 | pub(crate) rx: RDesRing<'d>, |
| 42 | pins: [PeripheralRef<'d, AnyPin>; 9], | 43 | pins: [PeripheralRef<'d, AnyPin>; 9], |
| 43 | _phy: P, | 44 | pub(crate) phy: P, |
| 44 | clock_range: u8, | 45 | pub(crate) station_management: EthernetStationManagement<T>, |
| 45 | phy_addr: u8, | ||
| 46 | pub(crate) mac_addr: [u8; 6], | 46 | pub(crate) mac_addr: [u8; 6], |
| 47 | } | 47 | } |
| 48 | 48 | ||
| @@ -201,9 +201,12 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> { | |||
| 201 | tx: TDesRing::new(&mut queue.tx_desc, &mut queue.tx_buf), | 201 | tx: TDesRing::new(&mut queue.tx_desc, &mut queue.tx_buf), |
| 202 | rx: RDesRing::new(&mut queue.rx_desc, &mut queue.rx_buf), | 202 | rx: RDesRing::new(&mut queue.rx_desc, &mut queue.rx_buf), |
| 203 | pins, | 203 | pins, |
| 204 | _phy: phy, | 204 | phy: phy, |
| 205 | clock_range, | 205 | station_management: EthernetStationManagement { |
| 206 | phy_addr, | 206 | peri: PhantomData, |
| 207 | clock_range: clock_range, | ||
| 208 | phy_addr: phy_addr, | ||
| 209 | }, | ||
| 207 | mac_addr, | 210 | mac_addr, |
| 208 | }; | 211 | }; |
| 209 | 212 | ||
| @@ -229,8 +232,8 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> { | |||
| 229 | w.set_tie(true); | 232 | w.set_tie(true); |
| 230 | }); | 233 | }); |
| 231 | 234 | ||
| 232 | P::phy_reset(&mut this); | 235 | this.phy.phy_reset(&mut this.station_management); |
| 233 | P::phy_init(&mut this); | 236 | this.phy.phy_init(&mut this.station_management); |
| 234 | 237 | ||
| 235 | interrupt::ETH.unpend(); | 238 | interrupt::ETH.unpend(); |
| 236 | unsafe { interrupt::ETH.enable() }; | 239 | unsafe { interrupt::ETH.enable() }; |
| @@ -239,7 +242,13 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> { | |||
| 239 | } | 242 | } |
| 240 | } | 243 | } |
| 241 | 244 | ||
| 242 | unsafe impl<'d, T: Instance, P: PHY> StationManagement for Ethernet<'d, T, P> { | 245 | pub struct EthernetStationManagement<T: Instance> { |
| 246 | peri: PhantomData<T>, | ||
| 247 | clock_range: u8, | ||
| 248 | phy_addr: u8, | ||
| 249 | } | ||
| 250 | |||
| 251 | unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> { | ||
| 243 | fn smi_read(&mut self, reg: u8) -> u16 { | 252 | fn smi_read(&mut self, reg: u8) -> u16 { |
| 244 | let mac = ETH.ethernet_mac(); | 253 | let mac = ETH.ethernet_mac(); |
| 245 | 254 | ||
