diff --git a/Projects/ESP32-S3-ETH/Rust Dev Environment for Waveshare ESP32-S3-ETH (W5500).md b/Projects/ESP32-S3-ETH/Rust Dev Environment for Waveshare ESP32-S3-ETH (W5500).md new file mode 100644 index 0000000..c927030 --- /dev/null +++ b/Projects/ESP32-S3-ETH/Rust Dev Environment for Waveshare ESP32-S3-ETH (W5500).md @@ -0,0 +1,196 @@ +Working setup, derived from an actual first-time bring-up. Every failure mode below was hit and fixed, in order. Follow this straight through and you skip all of it. (AI generated) + +## Board reference + +Waveshare ESP32-S3-ETH — ESP32-S3 + onboard W5500 ethernet chip over SPI (not RMII — there's no on-chip MAC/PHY involved, W5500 has its own MAC and does everything over SPI). + +Confirmed pin mapping (verify against your board's silkscreen — Waveshare pin assignments have varied slightly across production batches): + +|Signal|GPIO| +|---|---| +|SCLK|13| +|MOSI (SDO)|11| +|MISO (SDI)|12| +|CS|14| +|INT|10| +|RST|9| +|SPI host|SPI2| +|Clock|20–25 MHz| + +W5500 has no burned-in MAC address — you must supply one (a locally-administered address like `02:00:00:12:34:56` works fine). + +## Why std (esp-idf-svc), not no_std (esp-hal) + +`esp-generate` scaffolds `esp-hal` (`no_std`) projects. That toolchain has no W5500/ethernet driver and no full HTTP server story — its focus is Wi-Fi/BLE via `esp-radio` and `embassy`. For ethernet + a standard HTTP server, use the `std` toolchain via `esp-idf-svc`, which wraps ESP-IDF's C ethernet driver and httpd component. + +**Rule of thumb:** if the board has W5500/LAN8720/other wired-ethernet hardware, use `esp-idf-template` (std). Reach for `esp-generate` (no_std) only for pure Wi-Fi/BLE projects. + + + +## 1. Toolchain + +```bash +espup install +. $HOME/export-esp.sh # re-run in every new shell, or add to your shell rc +``` + +Confirm the Xtensa target is present: + +```bash +rustc --print target-list | grep xtensa +``` + + + +## 2. Scaffold the project + +Do **not** use `esp-generate`. Use: + +```bash +cargo install cargo-generate +cargo generate esp-rs/esp-idf-template cargo +``` + +Prompt answers that matter: + +|Prompt|Answer|Why| +|---|---|---| +|MCU|`esp32s3`|matches the board| +|Configure advanced options|Yes|need to reach STD toggle| +|STD support|**Yes**|pulls in `esp-idf-svc`; this is the whole point| +|ESP-IDF version|`v5.3.4`|most mature crates.io compatibility; avoid `master`/newest unless you have a reason| +|Use git esp-idf-* crates|**false**|crates.io releases are stable and documented; git HEAD drifts mid-project| +|Install location|**global**|ESP-IDF toolchain reused across projects, saves re-downloading (~1–2 GB)| +|Dev Containers|false|flashing real hardware over USB is simpler done natively| +|Wokwi simulation|false|Wokwi doesn't model W5500/ethernet peripherals| +|CI files|false|add later if/when you push to GitHub| + + + + +## 3. Known environment issues and fixes + +These hit in this order on a fresh Arch-based system (Omarchy); adjust distro-specific commands as needed, but expect similar issues on any non-Ubuntu-LTS host. + +### a) `esp-clang: error while loading shared libraries: libxml2.so.2` + +Rolling-release distros ship a newer libxml2 soname (`.so.16`+) than the pinned `esp-clang` toolchain expects (`.so.2`). Symlink it: + +```bash +ldconfig -p | grep libxml2 # find your installed version, e.g. libxml2.so.16 +sudo ln -s /usr/lib/libxml2.so.16 /usr/lib/libxml2.so.2 # adjust path/version to match +sudo ldconfig +``` + +Verify against the actual binary, not just `ldconfig -p` (which may not reflect symlinks immediately): + +```bash +/path/to/.embuild/espressif/tools/esp-clang/*/esp-clang/bin/clang --version +``` + +If a failed build already deleted the tool directory during its own error-recovery, just rebuild — `cargo build` reinstalls it. + +### b) `Missing esp-mqtt submodule` / CMake `git_submodule_check` errors + +The managed ESP-IDF checkout under `.embuild/espressif/esp-idf//` needs its git submodules initialized — several ESP-IDF components (mqtt, lwip, mbedtls, wifi/bt libs, etc.) are submodules, and IDF's build requires them present even if your project doesn't use those components. + +```bash +cd .embuild/espressif/esp-idf/ +git submodule update --init --recursive +cd - +cargo build --release +``` + +This is a one-time ~500MB–1GB download. If it's still broken afterward (partial/shallow clone issues), delete and let `embuild` re-clone fresh: + +```bash +rm -rf .embuild/espressif/esp-idf/ +cargo build --release +``` + +### c) Building for host instead of the chip (`Unsupported target 'x86_64-unknown-linux-gnu'`) + +`.cargo/config.toml` must set: + +```toml +[build] +target = "xtensa-esp32s3-espidf" +``` + +`esp-idf-template` generates this correctly — if you hit this, something overwrote or is missing that file, or `espup`'s toolchain isn't active in the current shell (`. $HOME/export-esp.sh`). + +### d) SPI DMA: `check_trans_valid: txdata transfer > host maximum` / w5500 read-write failures + +The default `SpiDriverConfig` has DMA disabled, which caps transfer size below what the W5500 ethernet driver needs to move full frames. Symptom: link never comes up, `wait_netif_up()` hangs, log fills with `w5500_spi_write failed` / `w5500_spi_read failed`. Fix — enable DMA explicitly when constructing the `SpiDriver`: + +```rust +use esp_idf_svc::hal::spi::{config::DriverConfig, Dma, SpiDriver}; + +let spi_driver = SpiDriver::new( + peripherals.spi2, + pins.gpio13, // SCLK + pins.gpio11, // MOSI + Some(pins.gpio12), // MISO + &DriverConfig { + dma: Dma::Auto(4096), + ..Default::default() + }, +)?; +``` + +### e) `esp-idf-svc` API drift across versions + +The `EthDriver::new_spi` signature has changed across `esp-idf-svc` releases — older versions took raw MOSI/MISO/SCLK pins directly; 0.51+ takes a pre-built `SpiDriver` plus INT/CS/RST only (9 args total: `spi, int, cs, rst, chipset, baudrate, mac_addr, phy_addr, sysloop`). If code from an older tutorial/example doesn't compile, check the exact signature for your pinned version: + +```bash +cargo doc --open -p esp-idf-svc +# or browse https://docs.rs/esp-idf-svc//esp_idf_svc/eth/ +``` + +Trust the compiler's error over memory or old examples — it names the exact expected type/arg count. + + + + +## 4. sdkconfig.defaults + +``` +CONFIG_ETH_SPI_ETHERNET_W5500=y +CONFIG_ESP_MAIN_TASK_STACK_SIZE=8000 +CONFIG_HTTPD_MAX_REQ_HDR_LEN=1024 +``` + +Without the first line, the W5500 driver component isn't built into ESP-IDF at all — you'll get a runtime or link failure referencing missing eth symbols. + + + +## 5. Cargo.toml essentials + +```toml +[dependencies] +esp-idf-svc = { version = "0.51", features = ["std"] } +anyhow = "1" +log = "0.4" +``` + + + +## 6. Build / flash / monitor + +```bash +cargo build --release +espflash flash --monitor target/xtensa-esp32s3-espidf/release/ +``` + +Watch the serial log for `Got IP: ...` — that confirms both SPI-to-W5500 link and DHCP succeeded. No `Got IP` line + streaming `w5500.mac` errors = revisit DMA config or pin mapping (item d/a above). + +## Summary: what each fix actually solved + +|Problem|Root cause|Fix| +|---|---|---| +|Config menu had no ethernet option|Wrong scaffolding tool (`esp-generate` = no_std/esp-hal)|Use `esp-idf-template` (std) instead| +|Build targeted host, not chip|Missing/wrong `.cargo/config.toml` target|Ensure `target = "xtensa-esp32s3-espidf"`| +|`esp-clang` failed to load|Host libxml2 soname too new|Symlink `.so.16` → `.so.2`| +|CMake submodule errors|Managed ESP-IDF git checkout incomplete|`git submodule update --init --recursive`| +|`EthDriver::new_spi` type errors|API changed across esp-idf-svc versions|Match compiler-reported signature exactly, don't trust memorized old examples| +|W5500 never links / SPI transfer errors|DMA disabled by default on SPI bus|`Dma::Auto(4096)` in `DriverConfig`| \ No newline at end of file