diff --git a/src/dma/mod.rs b/src/dma/mod.rs index 3f3d3be9..d7a311bb 100644 --- a/src/dma/mod.rs +++ b/src/dma/mod.rs @@ -6,12 +6,6 @@ use cortex_m::peripheral::NVIC; use crate::{peripherals::ETHERNET_DMA, stm32::Interrupt}; -#[cfg(feature = "f-series")] -type ETHERNET_MTL = (); - -#[cfg(feature = "stm32h7xx-hal")] -use crate::stm32::ETHERNET_MTL; - #[cfg(feature = "smoltcp-phy")] mod smoltcp_phy; #[cfg(feature = "smoltcp-phy")] @@ -77,7 +71,7 @@ pub struct EthernetDMA<'rx, 'tx> { pub(crate) struct DmaParts { pub eth_dma: ETHERNET_DMA, #[cfg(feature = "stm32h7xx-hal")] - pub eth_mtl: ETHERNET_MTL, + pub eth_mtl: crate::stm32::ETHERNET_MTL, } impl<'rx, 'tx> EthernetDMA<'rx, 'tx> { diff --git a/src/dma/rx/f_series_desc.rs b/src/dma/rx/f_series_desc.rs index f33f90b7..70cf85d9 100644 --- a/src/dma/rx/f_series_desc.rs +++ b/src/dma/rx/f_series_desc.rs @@ -59,8 +59,7 @@ impl RxDescriptor { } pub(super) fn setup(&mut self, buffer: &mut [u8]) { - self.set_buffer(buffer); - self.set_owned(); + self.set_owned(buffer); } /// Is owned by the DMA engine? @@ -71,7 +70,9 @@ impl RxDescriptor { /// Pass ownership to the DMA engine /// /// Overrides old timestamp data - pub(super) fn set_owned(&mut self) { + pub(super) fn set_owned(&mut self, buffer: &mut [u8]) { + self.set_buffer(buffer); + // "Preceding reads and writes cannot be moved past subsequent writes." #[cfg(feature = "fence")] atomic::fence(Ordering::Release); @@ -125,11 +126,15 @@ impl RxDescriptor { ((self.inner_raw.read(0) >> RXDESC_0_FL_SHIFT) & RXDESC_0_FL_MASK) as usize } - pub(super) fn take_received(&mut self, packet_id: Option) -> Result<(), RxError> { + pub(super) fn take_received( + &mut self, + packet_id: Option, + buffer: &mut [u8], + ) -> Result<(), RxError> { if self.is_owned() { Err(RxError::WouldBlock) } else if self.has_error() { - self.set_owned(); + self.set_owned(buffer); Err(RxError::DmaError) } else if self.is_first() && self.is_last() { // "Subsequent reads and writes cannot be moved ahead of preceding reads." @@ -143,7 +148,7 @@ impl RxDescriptor { Ok(()) } else { - self.set_owned(); + self.set_owned(buffer); Err(RxError::Truncated) } } @@ -151,14 +156,14 @@ impl RxDescriptor { pub(super) fn set_end_of_ring(&mut self) { unsafe { self.inner_raw.modify(1, |w| w | RXDESC_1_RER) } } +} +#[cfg(feature = "ptp")] +impl RxDescriptor { pub(super) fn packet_id(&self) -> Option<&PacketId> { self.packet_id.as_ref() } -} -#[cfg(feature = "ptp")] -impl RxDescriptor { /// Get PTP timestamps if available pub(super) fn read_timestamp(&self) -> Option { #[cfg(not(feature = "stm32f1xx-hal"))] diff --git a/src/dma/rx/h_desc.rs b/src/dma/rx/h_desc.rs index 0a4898a7..567e17aa 100644 --- a/src/dma/rx/h_desc.rs +++ b/src/dma/rx/h_desc.rs @@ -136,11 +136,12 @@ impl RxDescriptor { } pub(super) fn setup(&mut self, buffer: &[u8]) { - self.set_owned(buffer.as_ptr()); + self.set_owned(buffer); } /// Pass ownership to the DMA engine - pub(super) fn set_owned(&mut self, buffer: *const u8) { + pub(super) fn set_owned(&mut self, buffer: &[u8]) { + let buffer = buffer.as_ptr(); self.set_buffer(buffer); // "Preceding reads and writes cannot be moved past subsequent writes." @@ -205,7 +206,7 @@ impl RxDescriptor { Ok(()) } else { - self.set_owned(buffer.as_ptr()); + self.set_owned(buffer); Err(RxError::Truncated) } } diff --git a/src/dma/rx/mod.rs b/src/dma/rx/mod.rs index cabbb8e8..1cea58de 100644 --- a/src/dma/rx/mod.rs +++ b/src/dma/rx/mod.rs @@ -280,7 +280,7 @@ impl<'a> core::ops::DerefMut for RxPacket<'a> { impl<'a> Drop for RxPacket<'a> { fn drop(&mut self) { - self.entry.set_owned(self.buffer.as_ptr()); + self.entry.set_owned(self.buffer); } } diff --git a/src/dma/tx/f_series_desc.rs b/src/dma/tx/f_series_desc.rs index 2e3e86aa..2e5debe0 100644 --- a/src/dma/tx/f_series_desc.rs +++ b/src/dma/tx/f_series_desc.rs @@ -144,14 +144,14 @@ impl TxDescriptor { pub(super) fn set_end_of_ring(&mut self) { unsafe { self.inner_raw.modify(0, |w| w | TXDESC_0_TER) }; } +} +#[cfg(feature = "ptp")] +impl TxDescriptor { pub(super) fn packet_id(&self) -> Option<&PacketId> { self.packet_id.as_ref() } -} -#[cfg(feature = "ptp")] -impl TxDescriptor { fn read_timestamp(&mut self) -> Option { let tdes0 = self.inner_raw.read(0); diff --git a/src/dma/tx/mod.rs b/src/dma/tx/mod.rs index 6fe8ecc7..5e0db780 100644 --- a/src/dma/tx/mod.rs +++ b/src/dma/tx/mod.rs @@ -41,7 +41,7 @@ pub(crate) struct TxRing<'data, STATE> { impl<'data, STATE> TxRing<'data, STATE> { pub fn running_state(&self, eth_dma: ÐERNET_DMA) -> RunningState { #[cfg(feature = "f-series")] - let tx_status = eth_dma.dmasr().read().tps().bits(); + let tx_status = eth_dma.dmasr.read().tps().bits(); #[cfg(feature = "stm32h7xx-hal")] let tx_status = eth_dma.dmadsr.read().tps0().bits(); @@ -97,7 +97,7 @@ impl<'data> TxRing<'data, NotRunning> { #[cfg(feature = "f-series")] // Set end of ring register - self.ring.last_descriptor().set_end_of_ring(); + self.ring.last_descriptor_mut().set_end_of_ring(); let ring_ptr = self.ring.descriptors_start_address(); @@ -235,7 +235,7 @@ impl<'data> TxRing<'data, Running> { impl<'data> TxRing<'data, Running> { pub(crate) fn collect_timestamps(&mut self) { for descriptor in self.ring.descriptors_mut() { - f_descriptor.attach_timestamp(); + descriptor.attach_timestamp(); } } @@ -243,12 +243,12 @@ impl<'data> TxRing<'data, Running> { let descriptor = if let Some(descriptor) = self.ring.descriptors().find(|d| d.packet_id() == Some(&id)) { - f_descriptor + descriptor } else { return Err(TimestampError::IdNotFound); }; - f_descriptor + descriptor .timestamp() .map(|t| *t) .ok_or(TimestampError::NotYetTimestamped) diff --git a/src/lib.rs b/src/lib.rs index ef19fee3..1514b6a2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -111,7 +111,7 @@ where // Congfigure and start up the ethernet DMA. let dma = EthernetDMA::new( DmaParts { - eth_dma: parts.dma, + eth_dma: parts.dma.into(), #[cfg(feature = "stm32h7xx-hal")] eth_mtl: parts.mtl, }, @@ -195,7 +195,13 @@ where let eth_mac = parts.mac.into(); // Congfigure and start up the ethernet DMA. - let dma = EthernetDMA::new(parts.dma.into(), rx_buffer, tx_buffer); + let dma = EthernetDMA::new( + DmaParts { + eth_dma: parts.dma.into(), + }, + rx_buffer, + tx_buffer, + ); // Configure the ethernet PTP #[cfg(feature = "ptp")] @@ -203,7 +209,10 @@ where // Configure the ethernet MAC let mac = EthernetMAC::new( - MacParts { eth_mac, eth_mmc }, + MacParts { + eth_mac, + eth_mmc: parts.mmc, + }, clocks, Speed::FullDuplexBase100Tx, &dma, diff --git a/src/mac/miim.rs b/src/mac/miim.rs index e6cb0f0e..fdf3c590 100644 --- a/src/mac/miim.rs +++ b/src/mac/miim.rs @@ -1,7 +1,8 @@ pub use ieee802_3_miim::Miim; - pub use ieee802_3_miim::*; +use core::ops::{Deref, DerefMut}; + use crate::{peripherals::ETHERNET_MAC, stm32::ethernet_mac::MACMIIAR}; use super::EthernetMAC; @@ -157,7 +158,7 @@ where MDIO: MdioPin, MDC: MdcPin, { - pub(crate) eth_mac: EthernetMAC, + eth_mac: EthernetMAC, mdio: MDIO, mdc: MDC, } @@ -226,7 +227,7 @@ where } } -impl miim::Miim for EthernetMACWithMii +impl Miim for EthernetMACWithMii where MDIO: MdioPin, MDC: MdcPin, diff --git a/src/mac/mod.rs b/src/mac/mod.rs index aa6fe9f3..3a5d6bfb 100644 --- a/src/mac/mod.rs +++ b/src/mac/mod.rs @@ -10,7 +10,7 @@ pub use miim::*; pub(crate) struct MacParts { pub eth_mac: ETHERNET_MAC, #[cfg(feature = "f-series")] - pub eth_mmc: ETHERNET_MMC, + pub eth_mmc: crate::stm32::ETHERNET_MMC, } impl MacParts { @@ -18,7 +18,7 @@ impl MacParts { let Self { eth_mac, .. } = self; #[cfg(feature = "f-series")] - let (mac_filter_reg, flow_control) = (ð_mac.macffr, ð_mac.macfcr); + let (mac_filter, flow_control) = (ð_mac.macffr, ð_mac.macfcr); #[cfg(feature = "stm32h7xx-hal")] let (mac_filter, flow_control) = (ð_mac.macpfr, ð_mac.macqtx_fcr); @@ -42,14 +42,9 @@ impl MacParts { } fn disable_mmc_interrupts(&self) { - let Self { - eth_mac, - #[cfg(feature = "f-series")] - eth_mmc, - } = self; - #[cfg(feature = "f-series")] { + let eth_mmc = &self.eth_mmc; // Disable all MMC RX interrupts eth_mmc .mmcrimr @@ -69,6 +64,8 @@ impl MacParts { #[cfg(feature = "stm32h7xx-hal")] { + let eth_mac = &self.eth_mac; + // Disable all MMC RX interrupts eth_mac.mmc_rx_interrupt_mask.write(|w| { w.rxlpitrcim() @@ -163,11 +160,7 @@ impl EthernetMAC { // it doesn't work. _dma: &EthernetDMA, ) -> Result { - let MacParts { - eth_mac, - #[cfg(feature = "f-series")] - eth_mmc, - } = &parts; + let eth_mac = &parts.eth_mac; // TODO: configure MDIOS #[cfg(feature = "f-series")] @@ -218,12 +211,7 @@ impl EthernetMAC { .dr() .set_bit(); - // Fast Ethernet speed - w.fes() - .set_bit() - // Duplex mode - .dm() - .set_bit() + w // Receiver enable .re() .set_bit() @@ -244,6 +232,31 @@ impl EthernetMAC { Ok(me) } + /// Set the Ethernet Speed at which the MAC communicates + /// + /// Note that this does _not_ affect the PHY in any way. To + /// configure the PHY, use [`EthernetMACWithMii`] (see: [`Self::with_mii`]) + /// or [`Stm32Mii`] (see: [`Self::mii`]) + pub fn set_speed(&mut self, speed: Speed) { + self.eth_mac.maccr.modify(|_, w| match speed { + Speed::HalfDuplexBase10T => w.fes().clear_bit().dm().clear_bit(), + Speed::FullDuplexBase10T => w.fes().clear_bit().dm().set_bit(), + Speed::HalfDuplexBase100Tx => w.fes().set_bit().dm().clear_bit(), + Speed::FullDuplexBase100Tx => w.fes().set_bit().dm().set_bit(), + }); + } + + /// Get the Ethernet Speed at which the MAC communicates + pub fn get_speed(&self) -> Speed { + let cr = self.eth_mac.maccr.read(); + match (cr.fes().bit_is_set(), cr.dm().bit_is_set()) { + (false, false) => Speed::HalfDuplexBase10T, + (false, true) => Speed::FullDuplexBase10T, + (true, false) => Speed::HalfDuplexBase100Tx, + (true, true) => Speed::FullDuplexBase100Tx, + } + } + /// Borrow access to the MAC's SMI. /// /// Allows for controlling and monitoring any PHYs that may be accessible via the MDIO/MDC @@ -271,36 +284,7 @@ impl EthernetMAC { MDIO: MdioPin, MDC: MdcPin, { - EthernetMACWithMii { - eth_mac: self, - mdio, - mdc, - } - } - - /// Set the Ethernet Speed at which the MAC communicates - /// - /// Note that this does _not_ affect the PHY in any way. To - /// configure the PHY, use [`EthernetMACWithMii`] (see: [`Self::with_mii`]) - /// or [`Stm32Mii`] (see: [`Self::mii`]) - pub fn set_speed(&mut self, speed: Speed) { - self.eth_mac.maccr.modify(|_, w| match speed { - Speed::HalfDuplexBase10T => w.fes().clear_bit().dm().clear_bit(), - Speed::FullDuplexBase10T => w.fes().clear_bit().dm().set_bit(), - Speed::HalfDuplexBase100Tx => w.fes().set_bit().dm().clear_bit(), - Speed::FullDuplexBase100Tx => w.fes().set_bit().dm().set_bit(), - }); - } - - /// Get the Ethernet Speed at which the MAC communicates - pub fn get_speed(&self) -> Speed { - let cr = self.eth_mac.maccr.read(); - match (cr.fes().bit_is_set(), cr.dm().bit_is_set()) { - (false, false) => Speed::HalfDuplexBase10T, - (false, true) => Speed::FullDuplexBase10T, - (true, false) => Speed::HalfDuplexBase100Tx, - (true, true) => Speed::FullDuplexBase100Tx, - } + EthernetMACWithMii::new(self, mdio, mdc) } #[cfg(feature = "ptp")]