ph-esp32-mac is a no_std, no_alloc Rust driver for the ESP32 Ethernet MAC (EMAC). It targets ESP32 hardware, provides LAN8720A PHY support, and integrates with smoltcp, embassy-net, and esp-hal.
- Overview
- Status & Scope
- Motivation
- Goal
- Features
- Supported Hardware
- Quick Start (Happy Path)
- Recommended Workflow
- Examples
- Memory & DMA Sizing
- Feature Flags
- MSRV
- Documentation
- License
This crate implements the ESP32 EMAC peripheral using static DMA descriptors and buffers. It is designed for embedded use with explicit initialization, no heap allocation, and predictable memory usage. The public API is optimized for esp-hal consumers while keeping low-level control available.
- Current target: ESP32 (this release only)
- ESP32-P4: Experimental placeholder (not implemented, hidden from docs)
- Happy path: esp-hal synchronous and async bring-up on WT32-ETH01
There was no existing bare-metal, no_std, no_alloc Rust driver for the ESP32 MAC, which created a barrier to using wt32_eth01.rs in the bare-metal ecosystem.
Provide an efficient bare-metal, no_std, no_alloc implementation of the ESP32 MAC to enable use of the LAN8720A Ethernet PHY.
- ESP32 RMII support (MII is available but secondary)
- LAN8720A PHY driver with a generic PHY fallback
- smoltcp integration (
smoltcpfeature) - embassy-net driver integration (
embassy-netfeature) - esp-hal integration helpers (
esp-halfeature) - Async/waker support without allocation (
async+critical-section)
- ESP32 (current release target)
- ESP32-P4 (experimental / not implemented yet, hidden from docs)
These are the recommended esp-hal bring-up paths and match the examples in
apps/examples/.
use esp_hal::delay::Delay;
use ph_esp32_mac::esp_hal::{EmacBuilder, EmacPhyBundle, Wt32Eth01};
ph_esp32_mac::emac_static_sync!(EMAC, 10, 10, 1600);
let mut delay = Delay::new();
EMAC.with(|emac| {
EmacBuilder::wt32_eth01_with_mac(emac, [0x02, 0x00, 0x00, 0x12, 0x34, 0x56])
.init(&mut delay)
.unwrap();
let mut emac_phy = EmacPhyBundle::wt32_eth01_lan8720a(emac, Delay::new());
let _status = emac_phy
.init_and_wait_link_up(&mut delay, 10_000, 200)
.unwrap();
emac.start().unwrap();
});use esp_hal::delay::Delay;
use ph_esp32_mac::esp_hal::{EmacBuilder, EmacPhyBundle, Wt32Eth01};
use ph_esp32_mac::{emac_async_isr, emac_static_async};
emac_static_async!(EMAC, EMAC_STATE, 10, 10, 1600);
emac_async_isr!(EMAC_IRQ, esp_hal::interrupt::Priority::Priority1, &EMAC_STATE);
let mut delay = Delay::new();
let emac_ptr = EMAC.init(ph_esp32_mac::Emac::new()) as *mut _;
unsafe {
EmacBuilder::wt32_eth01_with_mac(&mut *emac_ptr, [0x02, 0x00, 0x00, 0x12, 0x34, 0x56])
.init(&mut delay)
.unwrap();
let mut emac_phy = EmacPhyBundle::wt32_eth01_lan8720a(&mut *emac_ptr, Delay::new());
let _status = emac_phy
.init_and_wait_link_up(&mut delay, 10_000, 200)
.unwrap();
(*emac_ptr).start().unwrap();
}From the repo root, use cargo xtask to build and flash apps:
cargo xtask run ex-esp-hal
cargo xtask run ex-esp-hal-asyncSee xtask/README.md for details.
Examples are provided as a separate crate in this repository and are not packaged with the published library crate. They require the Xtensa toolchain and flashing setup, so they are kept repo-only to avoid pulling those requirements into crates.io consumers.
See apps/examples/README.md for build and run instructions.
Recommended runner (from repo root):
cargo xtask run ex-embassy-netIncluded examples:
smoltcp_echoesp_hal_integrationesp_hal_asyncembassy_net
Hardware QA runner (separate crate):
- apps/qa-runner/README.md
cargo xtask run qa-runner
Default configuration (10 RX/TX buffers, 1600 bytes each):
| Component | Size |
|---|---|
| RX descriptors | 320 bytes |
| TX descriptors | 320 bytes |
| RX buffers | 16,000 bytes |
| TX buffers | 16,000 bytes |
| Total | ~32 KB |
Adjust via the static macros if memory is constrained:
ph_esp32_mac::emac_static_sync!(EMAC, 4, 4, 1600);| Feature | Description |
|---|---|
esp32 |
ESP32 target (default) |
esp32p4 |
Experimental placeholder (not implemented) |
smoltcp |
smoltcp integration |
embassy-net |
embassy-net-driver integration |
esp-hal |
esp-hal integration helpers |
critical-section |
Shared/ISR-safe access wrappers |
async |
Async/waker support (requires critical-section) |
defmt |
defmt formatting support |
log |
log crate support |
- Rust 1.92.0
- docs/README.md (documentation index and TOC)
- CODE_OF_CONDUCT.md
- CONTRIBUTING.md
- SECURITY.md
- CHANGELOG.md
Licensed under the Apache License, Version 2.0. See LICENSE.