diff --git a/examples/ethernet-nucleo-h743zi2.rs b/examples/ethernet-nucleo-h743zi2.rs index c0b52fd9..e2db4852 100644 --- a/examples/ethernet-nucleo-h743zi2.rs +++ b/examples/ethernet-nucleo-h743zi2.rs @@ -160,6 +160,7 @@ fn main() -> ! { ) }; + #[cfg(feature = "ptp")] let ethernet::Parts { dma: eth_dma, mac: eth_mac, @@ -176,6 +177,21 @@ fn main() -> ! { &ccdr.clocks, ); + #[cfg(not(feature = "ptp"))] + let ethernet::Parts { + dma: eth_dma, + mac: eth_mac, + } = ethernet::new( + dp.ETHERNET_MAC, + dp.ETHERNET_MTL, + dp.ETHERNET_DMA, + rmii_pins, + rx_ring, + tx_ring, + mac_addr, + ccdr.peripheral.ETH1MAC, + &ccdr.clocks, + ); // let start_addend = ptp.addend(); eth_dma.enable_interrupt(); diff --git a/examples/ethernet-rtic-stm32h735g-dk.rs b/examples/ethernet-rtic-stm32h735g-dk.rs index b5124383..8814c385 100644 --- a/examples/ethernet-rtic-stm32h735g-dk.rs +++ b/examples/ethernet-rtic-stm32h735g-dk.rs @@ -23,7 +23,12 @@ use smoltcp::iface::{Config, Interface, SocketSet, SocketStorage}; use smoltcp::time::Instant; use smoltcp::wire::{HardwareAddress, IpAddress, IpCidr}; -use stm32h7xx_hal::{ethernet, rcc::CoreClocks, stm32}; +use stm32h7xx_hal::{rcc::CoreClocks, stm32}; +use stm32h7xx_hal::{ethernet, + ethernet::{ + RxDescriptor, RxDescriptorRing, TxDescriptor, TxDescriptorRing, MTU, + }, +}; /// Configure SYSTICK for 1ms timebase fn systick_init(mut syst: stm32::SYST, clocks: CoreClocks) { @@ -73,13 +78,13 @@ static mut STORE: MaybeUninit = MaybeUninit::uninit(); pub struct Net<'a> { iface: Interface, - ethdev: ethernet::EthernetDMA<4, 4>, + ethdev: ethernet::EthernetDMA<'a, 'a>, sockets: SocketSet<'a>, } impl<'a> Net<'a> { pub fn new( store: &'a mut NetStorageStatic<'a>, - mut ethdev: ethernet::EthernetDMA<4, 4>, + mut ethdev: ethernet::EthernetDMA<'a, 'a>, ethernet_addr: HardwareAddress, now: Instant, ) -> Self { @@ -165,6 +170,18 @@ mod app { let rmii_txd0 = gpiob.pb12.into_alternate(); let rmii_txd1 = gpiob.pb13.into_alternate(); + let rmii_pins = ( + rmii_ref_clk, + rmii_mdio, + rmii_mdc, + rmii_crs_dv, + rmii_rxd0, + rmii_rxd1, + rmii_tx_en, + rmii_txd0, + rmii_txd1, + ); + // Initialise ethernet... assert_eq!(ccdr.clocks.hclk().raw(), 200_000_000); // HCLK 200MHz assert_eq!(ccdr.clocks.pclk1().raw(), 100_000_000); // PCLK 100MHz @@ -189,32 +206,39 @@ mod app { ) }; + #[cfg(feature = "ptp")] let ethernet::Parts { - dma: mut eth_dma, - mac: mut eth_mac, - ptp, + dma: eth_dma, + mac: eth_mac, + ptp: _ptp, } = ethernet::new( - dp.ETHERNET_MAC, - dp.ETHERNET_MTL, - dp.ETHERNET_DMA, - ( - rmii_ref_clk, - rmii_mdio, - rmii_mdc, - rmii_crs_dv, - rmii_rxd0, - rmii_rxd1, - rmii_tx_en, - rmii_txd0, - rmii_txd1, - ), + ctx.device.ETHERNET_MAC, + ctx.device.ETHERNET_MTL, + ctx.device.ETHERNET_DMA, + rmii_pins, + rx_ring, + tx_ring, + mac_addr, + ccdr.peripheral.ETH1MAC, + &ccdr.clocks, + ); + + #[cfg(not(feature = "ptp"))] + let ethernet::Parts { + dma: eth_dma, + mac: eth_mac, + } = ethernet::new( + ctx.device.ETHERNET_MAC, + ctx.device.ETHERNET_MTL, + ctx.device.ETHERNET_DMA, + rmii_pins, rx_ring, tx_ring, mac_addr, ccdr.peripheral.ETH1MAC, &ccdr.clocks, ); - let start_addend = ptp.addend(); + // let start_addend = ptp.addend(); eth_dma.enable_interrupt(); // Initialise ethernet PHY... @@ -267,7 +291,7 @@ mod app { #[task(binds = ETH, local = [net])] fn ethernet_event(ctx: ethernet_event::Context) { - unsafe { ethernet::interrupt_handler() } + ethernet::eth_interrupt_handler(); let time = TIME.load(Ordering::Relaxed); ctx.local.net.poll(time as i64); diff --git a/examples/ethernet-rtic-stm32h747i-disco.rs b/examples/ethernet-rtic-stm32h747i-disco.rs index 7d6525d7..afa34ed8 100644 --- a/examples/ethernet-rtic-stm32h747i-disco.rs +++ b/examples/ethernet-rtic-stm32h747i-disco.rs @@ -30,7 +30,13 @@ use smoltcp::iface::{Config, Interface, SocketSet, SocketStorage}; use smoltcp::time::Instant; use smoltcp::wire::{HardwareAddress, IpAddress, IpCidr}; -use stm32h7xx_hal::{ethernet, rcc::CoreClocks, stm32}; +use stm32h7xx_hal::{rcc::CoreClocks, stm32}; + +use stm32h7xx_hal::{ethernet, + ethernet::{ + RxDescriptor, RxDescriptorRing, TxDescriptor, TxDescriptorRing, MTU, + }, +}; /// Configure SYSTICK for 1ms timebase fn systick_init(mut syst: stm32::SYST, clocks: CoreClocks) { @@ -50,9 +56,25 @@ static TIME: AtomicU32 = AtomicU32::new(0); /// Locally administered MAC address const MAC_ADDRESS: [u8; 6] = [0x02, 0x00, 0x11, 0x22, 0x33, 0x44]; +/// DesRing TD +const NUM_DESCRIPTORS: usize = 8; /// Ethernet descriptor rings are a global singleton #[link_section = ".sram3.eth"] -static mut DES_RING: ethernet::DesRing<4, 4> = ethernet::DesRing::new(); +/// Doc +static mut TX_DESCRIPTORS: [TxDescriptor; NUM_DESCRIPTORS] = + [TxDescriptor::new(); NUM_DESCRIPTORS]; +#[link_section = ".sram3.eth"] +/// Doc +static mut TX_BUFFERS: [[u8; MTU + 2]; NUM_DESCRIPTORS] = + [[0u8; MTU + 2]; NUM_DESCRIPTORS]; +#[link_section = ".sram3.eth"] +/// Doc +static mut RX_DESCRIPTORS: [RxDescriptor; NUM_DESCRIPTORS] = + [RxDescriptor::new(); NUM_DESCRIPTORS]; +#[link_section = ".sram3.eth"] +/// Doc +static mut RX_BUFFERS: [[u8; MTU + 2]; NUM_DESCRIPTORS] = + [[0u8; MTU + 2]; NUM_DESCRIPTORS]; // This data will be held by Net through a mutable reference pub struct NetStorageStatic<'a> { @@ -64,13 +86,13 @@ static mut STORE: MaybeUninit = MaybeUninit::uninit(); pub struct Net<'a> { iface: Interface, - ethdev: ethernet::EthernetDMA<4, 4>, + ethdev: ethernet::EthernetDMA<'a, 'a>, sockets: SocketSet<'a>, } impl<'a> Net<'a> { pub fn new( store: &'a mut NetStorageStatic<'a>, - mut ethdev: ethernet::EthernetDMA<4, 4>, + mut ethdev: ethernet::EthernetDMA<'a, 'a>, ethernet_addr: HardwareAddress, now: Instant, ) -> Self { @@ -159,6 +181,17 @@ mod app { let rmii_txd0 = gpiog.pg13.into_alternate(); let rmii_txd1 = gpiog.pg12.into_alternate(); // STM32H747I-DISCO + let rmii_pins = ( + rmii_ref_clk, + rmii_mdio, + rmii_mdc, + rmii_crs_dv, + rmii_rxd0, + rmii_rxd1, + rmii_tx_en, + rmii_txd0, + rmii_txd1, + ); // Initialise ethernet... assert_eq!(ccdr.clocks.hclk().raw(), 200_000_000); // HCLK 200MHz assert_eq!(ccdr.clocks.pclk1().raw(), 100_000_000); // PCLK 100MHz @@ -166,37 +199,64 @@ mod app { assert_eq!(ccdr.clocks.pclk4().raw(), 100_000_000); // PCLK 100MHz let mac_addr = smoltcp::wire::EthernetAddress::from_bytes(&MAC_ADDRESS); - let (eth_dma, eth_mac) = unsafe { - ethernet::new( - ctx.device.ETHERNET_MAC, - ctx.device.ETHERNET_MTL, - ctx.device.ETHERNET_DMA, - ( - rmii_ref_clk, - rmii_mdio, - rmii_mdc, - rmii_crs_dv, - rmii_rxd0, - rmii_rxd1, - rmii_tx_en, - rmii_txd0, - rmii_txd1, - ), - &mut DES_RING, - mac_addr, - ccdr.peripheral.ETH1MAC, - &ccdr.clocks, + let (rx_ring, tx_ring) = { + // let tx_desc = unsafe { TX_DESCRIPTORS.write([TxDescriptor::new(); NUM_DESCRIPTORS]) }; + // let tx_buf = unsafe { TX_BUFFERS.write([[0u8; MTU + 2]; NUM_DESCRIPTORS]) }; + + // let rx_desc = unsafe { RX_DESCRIPTORS.write([RxDescriptor::new(); NUM_DESCRIPTORS]) }; + // let rx_buf = unsafe { RX_BUFFERS.write([[0u8; MTU + 2]; NUM_DESCRIPTORS]) }; + + ( + RxDescriptorRing::new(unsafe { &mut RX_DESCRIPTORS }, unsafe { + &mut RX_BUFFERS + }), + TxDescriptorRing::new(unsafe { &mut TX_DESCRIPTORS }, unsafe { + &mut TX_BUFFERS + }), ) }; + #[cfg(feature = "ptp")] + let ethernet::Parts { + dma: eth_dma, + mac: eth_mac, + ptp: _ptp, + } = ethernet::new( + ctx.device.ETHERNET_MAC, + ctx.device.ETHERNET_MTL, + ctx.device.ETHERNET_DMA, + rmii_pins, + rx_ring, + tx_ring, + mac_addr, + ccdr.peripheral.ETH1MAC, + &ccdr.clocks, + ); + + #[cfg(not(feature = "ptp"))] + let ethernet::Parts { + dma: eth_dma, + mac: eth_mac, + } = ethernet::new( + ctx.device.ETHERNET_MAC, + ctx.device.ETHERNET_MTL, + ctx.device.ETHERNET_DMA, + rmii_pins, + rx_ring, + tx_ring, + mac_addr, + ccdr.peripheral.ETH1MAC, + &ccdr.clocks, + ); + // let start_addend = ptp.addend(); + eth_dma.enable_interrupt(); + // Initialise ethernet PHY... let mut lan8742a = ethernet::phy::LAN8742A::new(eth_mac); lan8742a.phy_reset(); lan8742a.phy_init(); // The eth_dma should not be used until the PHY reports the link is up - unsafe { ethernet::enable_interrupt() }; - // unsafe: mutable reference to static storage, we only do this once let store = unsafe { let store_ptr = STORE.as_mut_ptr(); @@ -241,7 +301,7 @@ mod app { #[task(binds = ETH, local = [net])] fn ethernet_event(ctx: ethernet_event::Context) { - unsafe { ethernet::interrupt_handler() } + ethernet::eth_interrupt_handler(); let time = TIME.load(Ordering::Relaxed); ctx.local.net.poll(time as i64); diff --git a/examples/ethernet-stm32h747i-disco.rs b/examples/ethernet-stm32h747i-disco.rs index 206c4e43..06159f86 100644 --- a/examples/ethernet-stm32h747i-disco.rs +++ b/examples/ethernet-stm32h747i-disco.rs @@ -20,15 +20,37 @@ mod utilities; use log::info; -use stm32h7xx_hal::{ethernet, ethernet::PHY}; +use stm32h7xx_hal::{ethernet, + ethernet::{ + RxDescriptor, RxDescriptorRing, TxDescriptor, TxDescriptorRing, MTU, + PHY, + }, +}; use stm32h7xx_hal::{prelude::*, stm32, stm32::interrupt}; /// Locally administered MAC address const MAC_ADDRESS: [u8; 6] = [0x02, 0x00, 0x11, 0x22, 0x33, 0x44]; +/// DesRing TD +const NUM_DESCRIPTORS: usize = 8; /// Ethernet descriptor rings are a global singleton #[link_section = ".sram3.eth"] -static mut DES_RING: ethernet::DesRing<4, 4> = ethernet::DesRing::new(); +/// Doc +static mut TX_DESCRIPTORS: [TxDescriptor; NUM_DESCRIPTORS] = + [TxDescriptor::new(); NUM_DESCRIPTORS]; +#[link_section = ".sram3.eth"] +/// Doc +static mut TX_BUFFERS: [[u8; MTU + 2]; NUM_DESCRIPTORS] = + [[0u8; MTU + 2]; NUM_DESCRIPTORS]; +#[link_section = ".sram3.eth"] +/// Doc +static mut RX_DESCRIPTORS: [RxDescriptor; NUM_DESCRIPTORS] = + [RxDescriptor::new(); NUM_DESCRIPTORS]; +#[link_section = ".sram3.eth"] +/// Doc +static mut RX_BUFFERS: [[u8; MTU + 2]; NUM_DESCRIPTORS] = + [[0u8; MTU + 2]; NUM_DESCRIPTORS]; + // the program entry point #[entry] @@ -77,6 +99,17 @@ fn main() -> ! { let rmii_txd0 = gpiog.pg13.into_alternate(); let rmii_txd1 = gpiog.pg12.into_alternate(); + let rmii_pins = ( + rmii_ref_clk, + rmii_mdio, + rmii_mdc, + rmii_crs_dv, + rmii_rxd0, + rmii_rxd1, + rmii_tx_en, + rmii_txd0, + rmii_txd1, + ); // Initialise ethernet... assert_eq!(ccdr.clocks.hclk().raw(), 200_000_000); // HCLK 200MHz assert_eq!(ccdr.clocks.pclk1().raw(), 100_000_000); // PCLK 100MHz @@ -84,36 +117,64 @@ fn main() -> ! { assert_eq!(ccdr.clocks.pclk4().raw(), 100_000_000); // PCLK 100MHz let mac_addr = smoltcp::wire::EthernetAddress::from_bytes(&MAC_ADDRESS); - let (_eth_dma, eth_mac) = unsafe { - ethernet::new( - dp.ETHERNET_MAC, - dp.ETHERNET_MTL, - dp.ETHERNET_DMA, - ( - rmii_ref_clk, - rmii_mdio, - rmii_mdc, - rmii_crs_dv, - rmii_rxd0, - rmii_rxd1, - rmii_tx_en, - rmii_txd0, - rmii_txd1, - ), - &mut DES_RING, - mac_addr, - ccdr.peripheral.ETH1MAC, - &ccdr.clocks, + let (rx_ring, tx_ring) = { + // let tx_desc = unsafe { TX_DESCRIPTORS.write([TxDescriptor::new(); NUM_DESCRIPTORS]) }; + // let tx_buf = unsafe { TX_BUFFERS.write([[0u8; MTU + 2]; NUM_DESCRIPTORS]) }; + + // let rx_desc = unsafe { RX_DESCRIPTORS.write([RxDescriptor::new(); NUM_DESCRIPTORS]) }; + // let rx_buf = unsafe { RX_BUFFERS.write([[0u8; MTU + 2]; NUM_DESCRIPTORS]) }; + + ( + RxDescriptorRing::new(unsafe { &mut RX_DESCRIPTORS }, unsafe { + &mut RX_BUFFERS + }), + TxDescriptorRing::new(unsafe { &mut TX_DESCRIPTORS }, unsafe { + &mut TX_BUFFERS + }), ) }; + #[cfg(feature = "ptp")] + let ethernet::Parts { + dma: eth_dma, + mac: eth_mac, + ptp: _ptp, + } = ethernet::new( + dp.ETHERNET_MAC, + dp.ETHERNET_MTL, + dp.ETHERNET_DMA, + rmii_pins, + rx_ring, + tx_ring, + mac_addr, + ccdr.peripheral.ETH1MAC, + &ccdr.clocks, + ); + + #[cfg(not(feature = "ptp"))] + let ethernet::Parts { + dma: eth_dma, + mac: eth_mac, + } = ethernet::new( + dp.ETHERNET_MAC, + dp.ETHERNET_MTL, + dp.ETHERNET_DMA, + rmii_pins, + rx_ring, + tx_ring, + mac_addr, + ccdr.peripheral.ETH1MAC, + &ccdr.clocks, + ); + // let start_addend = ptp.addend(); + eth_dma.enable_interrupt(); + // Initialise ethernet PHY... let mut lan8742a = ethernet::phy::LAN8742A::new(eth_mac.set_phy_addr(0)); lan8742a.phy_reset(); lan8742a.phy_init(); unsafe { - ethernet::enable_interrupt(); cp.NVIC.set_priority(stm32::Interrupt::ETH, 196); // Mid prio cortex_m::peripheral::NVIC::unmask(stm32::Interrupt::ETH); } @@ -143,7 +204,7 @@ fn main() -> ! { #[interrupt] fn ETH() { - unsafe { ethernet::interrupt_handler() } + ethernet::eth_interrupt_handler(); } #[exception] diff --git a/src/ethernet/eth.rs b/src/ethernet/eth.rs index 2d9302c3..5a3e1c71 100644 --- a/src/ethernet/eth.rs +++ b/src/ethernet/eth.rs @@ -758,6 +758,7 @@ impl<'a, 'rx, 'tx> phy::Device for &'a mut EthernetDMA<'rx, 'tx> { fn transmit(&mut self, _timestamp: Instant) -> Option> { if self.tx_available() { + #[cfg(feature = "ptp")] let tx_packet_id = self.next_packet_id(); let EthernetDMA { tx_ring, .. } = self; @@ -823,6 +824,7 @@ impl<'rx, 'tx> phy::Device for EthernetDMA<'rx, 'tx> { fn transmit(&mut self, _timestamp: Instant) -> Option> { if self.tx_available() { + #[cfg(feature = "ptp")] let tx_packet_id = self.next_packet_id(); let EthernetDMA { tx_ring, .. } = self; diff --git a/src/lib.rs b/src/lib.rs index bca57f9f..08cc68f3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -142,7 +142,12 @@ pub use crate::stm32 as device; #[cfg_attr(docsrs, doc(cfg(feature = "rt")))] pub use crate::stm32::interrupt; -#[cfg(feature = "device-selected")] +#[cfg(all( + feature = "device-selected", + feature = "ethernet", + not(feature = "rm0455") +))] +#[cfg_attr(docsrs, doc(cfg(feature = "ethernet")))] pub mod ptp; #[cfg(feature = "device-selected")]