Skip to main content

Crate esp_p4_eth

Crate esp_p4_eth 

Source
Expand description

#![no_std] async Ethernet MAC driver for ESP32-P4 RMII designs, plug-in compatible with embassy-net.

See the crate-level README.md for the project status, hardware support matrix, quick-start instructions, and the mandatory build invariants (linker RAM_DMA section below 0x4FF80000, workspace opt-level = 1).

§Architecture

The crate is split into a few narrow layers:

  • regs exposes raw MMIO register addresses and bit fields.
  • clock and pins program the P4 clock tree and IO_MUX for RMII.
  • board groups pin maps, reference-clock pad, and PHY MDIO address into a single BoardConfig; BoardConfig::WAVESHARE_P4_ETH is the built-in default for the Waveshare ESP32-P4-ETH dev board.
  • descriptors owns DMA descriptor/ring state and packet buffers.
  • dma handles cache synchronization, DMA reset/init, and interrupt status.
  • phy provides Clause 22 MDIO access plus an IP101-oriented PHY model.
  • Ethernet composes all of the above into a device that can be driven directly or through ch / embassy-net-driver-channel.

§Bring-up

Two constructor families are provided:

§ESP32-P4 specifics

ESP32-P4 needs a few hardware-specific invariants that are easy to miss:

  • DMA descriptors and packet buffers must stay cache-line aligned. This crate uses 128-byte alignment to match the P4 L2 cache line.
  • DMA-shared statics must live below 0x4FF80000 — the upper 256 KB of HP SRAM is the L2 cache backing region and is not accessible to bus masters.
  • CPU writes must be synchronized to memory before DMA sees them, and DMA writes must be invalidated out of cache before the CPU reads them. The cache sync helpers in dma handle that requirement.
  • DMA_OP_MODE.RSF (Receive Store and Forward) must stay 0 — the P4 RX FIFO is too small to hold a full Ethernet frame and RSF = 1 silently drops everything larger than the FIFO. This crate uses cut-through receive by default; do not re-enable RSF.
  • RMII pin routing is not implicit. The bring-up path applies the supplied BoardConfig through pins::configure_rmii_pin_set, pins::configure_mdio_pin_set, and clock::configure_clock_ext_in.

The examples use StaticDmaResources as the preferred safe way to own the backing DMA memory in 'static storage; #[link_section = ".dma_bss"] places that storage inside the linker’s RAM_DMA region.

Re-exports§

pub use board::BoardConfig;
pub use eth::clock;
pub use eth::descriptors;
pub use eth::dma;
pub use eth::phy;
pub use eth::pins;
pub use eth::regs;
pub use eth::new;
pub use eth::new_from_static_resources;
pub use eth::Device;
pub use eth::Duplex;
pub use eth::Ethernet;
pub use eth::MacError;
pub use eth::Runner;
pub use eth::CHANNEL_RX_COUNT;
pub use eth::CHANNEL_TX_COUNT;
pub use eth::MTU;
pub use clock::configure_clock_ext_in;
pub use clock::configure_clock_mpll_out;
pub use clock::configure_speed_divider;
pub use clock::disable_emac_clock_tree;
pub use clock::MpllClockOutPin;
pub use clock::RefClockPin;
pub use descriptors::zeroed_rx_descriptors;
pub use descriptors::zeroed_tx_descriptors;
pub use descriptors::BufferTooLarge;
pub use descriptors::DescriptorError;
pub use descriptors::DmaBuffers;
pub use descriptors::OwnedBy;
pub use descriptors::RDes;
pub use descriptors::RDesRing;
pub use descriptors::RxRingStats;
pub use descriptors::StaticDmaResources;
pub use descriptors::TDes;
pub use descriptors::TDesRing;
pub use descriptors::TxRingStats;
pub use descriptors::BUF_SIZE;
pub use descriptors::MIN_RX_FRAME_SIZE;
pub use descriptors::RX_DESC_COUNT;
pub use descriptors::TX_DESC_COUNT;
pub use dma::Dma;
pub use dma::DmaError;
pub use dma::DmaInterruptStatus;
pub use phy::anlpar;
pub use phy::bmcr;
pub use phy::bmsr;
pub use phy::mdio_read;
pub use phy::mdio_write;
pub use phy::Ip101;
pub use phy::LinkState;
pub use phy::Phy;
pub use phy::PhyError;
pub use phy::Speed;
pub use phy::ANAR;
pub use phy::ANLPAR;
pub use phy::BMCR;
pub use phy::BMSR;
pub use phy::PHYIDR1;
pub use phy::PHYIDR2;
pub use pins::configure_rmii_pins;
pub use pins::release_phy_reset_pin;
pub use pins::release_waveshare_phy_reset;
pub use pins::PhyResetPinConfig;
pub use embassy_net_driver_channel as ch;

Modules§

board
Board-level configuration grouping pin maps, reference clock pin, and PHY address. A single BoardConfig value is enough to bring up the EMAC on a target hardware without per-call argument plumbing.
clic
ESP32-P4 HP-CPU interrupt routing — INTERRUPT_CORE0 matrix + CLIC.
diag
Diagnostic counters and last-frame snapshots exposed for observability and debugging. The contents of this module are intentionally not part of the crate’s stable API — atomics may be added, removed, or renamed in any release. Build dashboards on top of them at your own risk and pin a specific esp-p4-eth version if you do.
eth
Ethernet implementation modules staged under a future esp-hal/src/eth/ layout.
systimer
ESP32-P4 SYSTIMER — low-level access to the 64-bit free-running counter.
time_driver_irq_logic
Pure-data logic shared with time_driver_irq.rs. Lives in a separate module so it is host-compilable regardless of the p4-time-driver-irq feature flag — the parent module is gated on both the feature and the riscv32 target, which would otherwise hide every helper from host tests.