stm32/eth: refactor genericsmi
This commit is contained in:
parent
3bae533066
commit
48b37aa2bf
@ -1,5 +1,7 @@
|
|||||||
//! Generic SMI Ethernet PHY
|
//! Generic SMI Ethernet PHY
|
||||||
|
|
||||||
|
use futures::task::Context;
|
||||||
|
|
||||||
use super::{StationManagement, PHY};
|
use super::{StationManagement, PHY};
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@ -40,13 +42,13 @@ pub struct GenericSMI;
|
|||||||
|
|
||||||
unsafe impl PHY for GenericSMI {
|
unsafe impl PHY for GenericSMI {
|
||||||
/// Reset PHY and wait for it to come out of reset.
|
/// Reset PHY and wait for it to come out of reset.
|
||||||
fn phy_reset<S: StationManagement>(sm: &mut S) {
|
fn phy_reset<S: StationManagement>(&mut self, sm: &mut S) {
|
||||||
sm.smi_write(PHY_REG_BCR, PHY_REG_BCR_RESET);
|
sm.smi_write(PHY_REG_BCR, PHY_REG_BCR_RESET);
|
||||||
while sm.smi_read(PHY_REG_BCR) & PHY_REG_BCR_RESET == PHY_REG_BCR_RESET {}
|
while sm.smi_read(PHY_REG_BCR) & PHY_REG_BCR_RESET == PHY_REG_BCR_RESET {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// PHY initialisation.
|
/// PHY initialisation.
|
||||||
fn phy_init<S: StationManagement>(sm: &mut S) {
|
fn phy_init<S: StationManagement>(&mut self, sm: &mut S) {
|
||||||
// Clear WU CSR
|
// Clear WU CSR
|
||||||
Self::smi_write_ext(sm, PHY_REG_WUCSR, 0);
|
Self::smi_write_ext(sm, PHY_REG_WUCSR, 0);
|
||||||
|
|
||||||
@ -54,7 +56,9 @@ unsafe impl PHY for GenericSMI {
|
|||||||
sm.smi_write(PHY_REG_BCR, PHY_REG_BCR_AN | PHY_REG_BCR_ANRST | PHY_REG_BCR_100M);
|
sm.smi_write(PHY_REG_BCR, PHY_REG_BCR_AN | PHY_REG_BCR_ANRST | PHY_REG_BCR_100M);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn poll_link<S: StationManagement>(sm: &mut S) -> bool {
|
fn poll_link<S: StationManagement>(&mut self, sm: &mut S, cx: &mut Context) -> bool {
|
||||||
|
cx.waker().wake_by_ref();
|
||||||
|
|
||||||
let bsr = sm.smi_read(PHY_REG_BSR);
|
let bsr = sm.smi_read(PHY_REG_BSR);
|
||||||
|
|
||||||
// No link without autonegotiate
|
// No link without autonegotiate
|
||||||
|
@ -81,9 +81,7 @@ impl<'d, T: Instance, P: PHY> embassy_net_driver::Driver for Ethernet<'d, T, P>
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn link_state(&mut self, cx: &mut Context) -> LinkState {
|
fn link_state(&mut self, cx: &mut Context) -> LinkState {
|
||||||
// TODO: wake cx.waker on link state change
|
if self.phy.poll_link(&mut self.station_management, cx) {
|
||||||
cx.waker().wake_by_ref();
|
|
||||||
if P::poll_link(self) {
|
|
||||||
LinkState::Up
|
LinkState::Up
|
||||||
} else {
|
} else {
|
||||||
LinkState::Down
|
LinkState::Down
|
||||||
@ -148,11 +146,11 @@ pub unsafe trait StationManagement {
|
|||||||
/// The methods cannot move S
|
/// The methods cannot move S
|
||||||
pub unsafe trait PHY {
|
pub unsafe trait PHY {
|
||||||
/// Reset PHY and wait for it to come out of reset.
|
/// Reset PHY and wait for it to come out of reset.
|
||||||
fn phy_reset<S: StationManagement>(sm: &mut S);
|
fn phy_reset<S: StationManagement>(&mut self, sm: &mut S);
|
||||||
/// PHY initialisation.
|
/// PHY initialisation.
|
||||||
fn phy_init<S: StationManagement>(sm: &mut S);
|
fn phy_init<S: StationManagement>(&mut self, sm: &mut S);
|
||||||
/// Poll link to see if it is up and FD with 100Mbps
|
/// Poll link to see if it is up and FD with 100Mbps
|
||||||
fn poll_link<S: StationManagement>(sm: &mut S) -> bool;
|
fn poll_link<S: StationManagement>(&mut self, sm: &mut S, cx: &mut Context) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) mod sealed {
|
pub(crate) mod sealed {
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
mod rx_desc;
|
mod rx_desc;
|
||||||
mod tx_desc;
|
mod tx_desc;
|
||||||
|
|
||||||
|
use core::marker::PhantomData;
|
||||||
use core::sync::atomic::{fence, Ordering};
|
use core::sync::atomic::{fence, Ordering};
|
||||||
|
|
||||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||||
@ -48,9 +49,8 @@ pub struct Ethernet<'d, T: Instance, P: PHY> {
|
|||||||
pub(crate) rx: RDesRing<'d>,
|
pub(crate) rx: RDesRing<'d>,
|
||||||
|
|
||||||
pins: [PeripheralRef<'d, AnyPin>; 9],
|
pins: [PeripheralRef<'d, AnyPin>; 9],
|
||||||
_phy: P,
|
pub(crate) phy: P,
|
||||||
clock_range: Cr,
|
pub(crate) station_management: EthernetStationManagement<T>,
|
||||||
phy_addr: u8,
|
|
||||||
pub(crate) mac_addr: [u8; 6],
|
pub(crate) mac_addr: [u8; 6],
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,9 +224,12 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
|
|||||||
let mut this = Self {
|
let mut this = Self {
|
||||||
_peri: peri,
|
_peri: peri,
|
||||||
pins,
|
pins,
|
||||||
_phy: phy,
|
phy: phy,
|
||||||
clock_range,
|
station_management: EthernetStationManagement {
|
||||||
phy_addr,
|
peri: PhantomData,
|
||||||
|
clock_range: clock_range,
|
||||||
|
phy_addr: phy_addr,
|
||||||
|
},
|
||||||
mac_addr,
|
mac_addr,
|
||||||
tx: TDesRing::new(&mut queue.tx_desc, &mut queue.tx_buf),
|
tx: TDesRing::new(&mut queue.tx_desc, &mut queue.tx_buf),
|
||||||
rx: RDesRing::new(&mut queue.rx_desc, &mut queue.rx_buf),
|
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> {
|
|||||||
w.set_tie(true);
|
w.set_tie(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
P::phy_reset(&mut this);
|
this.phy.phy_reset(&mut this.station_management);
|
||||||
P::phy_init(&mut this);
|
this.phy.phy_init(&mut this.station_management);
|
||||||
|
|
||||||
interrupt::ETH.unpend();
|
interrupt::ETH.unpend();
|
||||||
unsafe { interrupt::ETH.enable() };
|
unsafe { interrupt::ETH.enable() };
|
||||||
@ -266,7 +269,13 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<'d, T: Instance, P: PHY> StationManagement for Ethernet<'d, T, P> {
|
pub struct EthernetStationManagement<T: Instance> {
|
||||||
|
peri: PhantomData<T>,
|
||||||
|
clock_range: Cr,
|
||||||
|
phy_addr: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> {
|
||||||
fn smi_read(&mut self, reg: u8) -> u16 {
|
fn smi_read(&mut self, reg: u8) -> u16 {
|
||||||
let mac = ETH.ethernet_mac();
|
let mac = ETH.ethernet_mac();
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
mod descriptors;
|
mod descriptors;
|
||||||
|
|
||||||
|
use core::marker::PhantomData;
|
||||||
use core::sync::atomic::{fence, Ordering};
|
use core::sync::atomic::{fence, Ordering};
|
||||||
|
|
||||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||||
@ -40,9 +41,8 @@ pub struct Ethernet<'d, T: Instance, P: PHY> {
|
|||||||
pub(crate) tx: TDesRing<'d>,
|
pub(crate) tx: TDesRing<'d>,
|
||||||
pub(crate) rx: RDesRing<'d>,
|
pub(crate) rx: RDesRing<'d>,
|
||||||
pins: [PeripheralRef<'d, AnyPin>; 9],
|
pins: [PeripheralRef<'d, AnyPin>; 9],
|
||||||
_phy: P,
|
pub(crate) phy: P,
|
||||||
clock_range: u8,
|
pub(crate) station_management: EthernetStationManagement<T>,
|
||||||
phy_addr: u8,
|
|
||||||
pub(crate) mac_addr: [u8; 6],
|
pub(crate) mac_addr: [u8; 6],
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,9 +201,12 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
|
|||||||
tx: TDesRing::new(&mut queue.tx_desc, &mut queue.tx_buf),
|
tx: TDesRing::new(&mut queue.tx_desc, &mut queue.tx_buf),
|
||||||
rx: RDesRing::new(&mut queue.rx_desc, &mut queue.rx_buf),
|
rx: RDesRing::new(&mut queue.rx_desc, &mut queue.rx_buf),
|
||||||
pins,
|
pins,
|
||||||
_phy: phy,
|
phy: phy,
|
||||||
clock_range,
|
station_management: EthernetStationManagement {
|
||||||
phy_addr,
|
peri: PhantomData,
|
||||||
|
clock_range: clock_range,
|
||||||
|
phy_addr: phy_addr,
|
||||||
|
},
|
||||||
mac_addr,
|
mac_addr,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -229,8 +232,8 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
|
|||||||
w.set_tie(true);
|
w.set_tie(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
P::phy_reset(&mut this);
|
this.phy.phy_reset(&mut this.station_management);
|
||||||
P::phy_init(&mut this);
|
this.phy.phy_init(&mut this.station_management);
|
||||||
|
|
||||||
interrupt::ETH.unpend();
|
interrupt::ETH.unpend();
|
||||||
unsafe { interrupt::ETH.enable() };
|
unsafe { interrupt::ETH.enable() };
|
||||||
@ -239,7 +242,13 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<'d, T: Instance, P: PHY> StationManagement for Ethernet<'d, T, P> {
|
pub struct EthernetStationManagement<T: Instance> {
|
||||||
|
peri: PhantomData<T>,
|
||||||
|
clock_range: u8,
|
||||||
|
phy_addr: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> {
|
||||||
fn smi_read(&mut self, reg: u8) -> u16 {
|
fn smi_read(&mut self, reg: u8) -> u16 {
|
||||||
let mac = ETH.ethernet_mac();
|
let mac = ETH.ethernet_mac();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user