Skip to main content

Crate esp_emac

Crate esp_emac 

Source
Expand description

Native ESP32 Ethernet MAC driver for #![no_std] Rust.

Owns the DMA engine and brings the EMAC peripheral up directly via memory-mapped register helpers — no ph-esp32-mac, no esp-idf-svc, no esp-eth.

Pairs with eth-phy-lan87xx (or any eth_mdio_phy::PhyDriver implementation) for the PHY side, and with embassy-net for the TCP/IP stack.

See the crate README for an installation guide, embassy-net example, ISR setup, and troubleshooting checklist.

§Quick start (embassy-net + LAN8720A)

use esp_emac::config::{ClkGpio, EmacConfig, RmiiClockConfig, RmiiPins, XtalFreq};
use esp_emac::EmacDefault;
use esp_emac::embassy::EmacDriverState;

// `Emac::new` (and therefore `EmacDefault::new`) is a `const fn`.
// Storing the EMAC in a `static mut` gives compile-time BSS init
// — no runtime stack temporary, deterministic on cold boot.
//
// The default ring sizing is currently 10 RX / 10 TX / 1600-byte
// buffers (~32 KiB), sourced from `DEFAULT_RX` / `DEFAULT_TX` /
// `DEFAULT_BUF`. At that size a `StaticCell::init(EmacDefault::new(..))`
// pattern would risk materialising the full struct on the caller's
// stack before moving it into static storage; `static mut` avoids
// that path entirely.
static mut EMAC: EmacDefault = EmacDefault::new(EmacConfig {
    clock: RmiiClockConfig::InternalApll {
        gpio: ClkGpio::Gpio17,
        xtal: XtalFreq::Mhz40,
    },
    pins: RmiiPins { mdc: 23, mdio: 18 },
});
static EMAC_STATE: EmacDriverState = EmacDriverState::new();

// In `main`, take the `&'static mut` once. SAFETY: `EMAC` is touched
// only here — single owner — so there is no aliasing.
let _emac: &'static mut EmacDefault =
    unsafe { &mut *core::ptr::addr_of_mut!(EMAC) };

Full bring-up (PHY init, link wait, embassy-net plumbing, DHCP) is shown in examples/embassy_net_lan8720a.rs.

§Crate features

FeatureDefaultWhen to enable
esp-haloffAlways for hardware bring-up — pulls in [esp_hal::interrupt] for ISR binding.
mdio-phyoffWhen using a PhyDriver-based PHY driver via mdio::EspMdio.
embassy-netoffWhen using [embassy-net] — exposes embassy::EmacDriver.
asyncoffWhen using reset::async_impl::AsyncResetController.
defmtoffAdds defmt::Format derives on public types.

§Compatibility

  • Target: xtensa-esp32-none-elf (original ESP32, Xtensa LX6)
  • MSRV: 1.88 (constrained by esp-hal = "1.1"’s declared rust-version)
  • esp-hal: 1.1.x
  • embassy-net: 0.9.x
  • embassy-executor: 0.10.x

Other ESP variants (S2/S3/C-series/H2) have no built-in EMAC. ESP32-P4 has a newer Synopsys GMAC revision and is not yet supported (planned through a chip-feature split in regs/*).

Pure register-arithmetic unit tests build and run on the host (cargo test --target $HOST_TARGET), which is how regs/* is exercised in CI.

Re-exports§

pub use config::ClkGpio;
pub use config::EmacConfig;
pub use config::RmiiClockConfig;
pub use config::RmiiPins;
pub use config::XtalFreq;
pub use emac::Emac;
pub use emac::EmacDefault;
pub use emac::EmacSmall;
pub use emac::EmacState;
pub use error::EmacError;
pub use interrupt::InterruptStatus;
pub use mdio::EspMdio;
pub use mdio::MdcClockDivider;

Modules§

clock
APLL 50 MHz clock configuration and GPIO clock output/input setup.
config
EMAC configuration types.
dma
DMA descriptor management for the ESP32 EMAC.
emac
Native ESP32 EMAC driver.
embassy
Native embassy-net driver for the ESP32 EMAC.
error
EMAC error types.
interrupt
Interrupt status parsing for the ESP32 EMAC DMA controller.
mdio
MDIO (Management Data Input/Output) controller.
regs
ESP32 EMAC register definitions.
reset
DMA software reset state machine.

Enums§

Duplex
Ethernet duplex mode.
Speed
Ethernet link speed.