This is a native Linux bring-up port derived from
mrbreaker/why2025-linux. It
targets both Waveshare XC products:
XC_VARIANT |
Product | LCD | DTB |
|---|---|---|---|
3_4c |
ESP32-P4-WIFI6-Touch-LCD-3.4C | 800×800 | esp32p4-waveshare-xc-3_4c.dtb |
4c |
ESP32-P4-WIFI6-Touch-LCD-4C | 720×720 | esp32p4-waveshare-xc-4c.dtb |
The port follows Waveshare's official ESP-IDF BSP for the board wiring and JD9365 command sequence. It keeps the original project's Linux 6.18.35 NOMMU architecture and ESP-IDF boot shim.
This repository is buildable source for board bring-up, not a tested release image. The patch series and both device trees have been checked locally, but the resulting image has not yet been verified on a physical XC board.
| Function | Status | Notes |
|---|---|---|
| P4 boot, UART, 32 MB PSRAM | Ported | Inherited from WHY2025; boot shim selects P4 rev 1+ |
| 32 MB NOR flash | Ported | Uses the capacity stated by Waveshare's product documentation |
| 3.4C / 4C MIPI-DSI LCD | Ported, needs hardware test | JD9365, 2 lanes, 1.5 Gbps/lane, RGB565, 80 MHz DPI |
| Backlight | Ported, needs hardware test | P4 GPIO26, active-low |
| GT911 touch | Ported, needs hardware test | GPIO7/8 bit-banged I²C; polling because TP INT/RST are NC |
| microSD | Mutually exclusive with Wi-Fi/BT | P4 exposes one DW-MMC host; this build selects C6 SDIO slot 1 instead of card slot 0 |
| ESP32-C6 reset/SDIO pins | Ported, needs hardware test | Boot shim routes slot 1 and releases GPIO54 reset before Linux |
| Wi-Fi / Bluetooth | Ported, needs hardware test | ESP-Hosted-NG over 4-bit SDIO; expected interfaces are wlan0 and hci0 |
| ES8311 speaker / ES7210 microphones | Ported, needs hardware test | Fixed 16 kHz S16_LE stereo via lightweight /dev/xc-audio; intentionally not ALSA |
| USB host, camera, Ethernet | Not implemented | Outside this first display/touch boot milestone |
Do not flash the original WHY2025 C6 firmware: that firmware expects the badge's SPI wiring. Build the matching ESP-Hosted SDIO network-adapter image described below.
| Function | P4 GPIO |
|---|---|
| LCD reset / backlight | 27 / 26 |
| Touch I²C SDA / SCL | 7 / 8 |
| microSD D0–D3 / CLK / CMD | 39–42 / 43 / 44 |
| C6 SDIO D0–D3 / CLK / CMD | 14–17 / 18 / 19 |
| C6 reset | 54, active-high |
| I²S MCLK / SCLK / LRCLK / DOUT / DIN | 13 / 12 / 10 / 9 / 11 |
| Audio amplifier enable | 53 |
Buildroot must run on Linux. ESP-IDF can run on Linux or macOS.
-
Prepare Buildroot and repository paths:
git clone -b 2025.02.15 https://gitlab.com/buildroot.org/buildroot for p in patches/buildroot/buildroot-tree/00[0-9][0-9]-*.patch; do patch -p1 -d buildroot -i "$p" done ./setup-paths.sh
-
Build Linux, rootfs, and both DTBs:
cd buildroot cp ../configs/why2025_defconfig .config make olddefconfig make -j"$(nproc)" cd ..
Expected files under
buildroot/output/images/areImage,rootfs.squashfs, and bothesp32p4-waveshare-xc-*.dtbfiles. -
Build the P4 boot shim with ESP-IDF 5.5.x:
. "$IDF_PATH/export.sh" cd linux-native idf.py build cd ..
The first build downloads Espressif's
esp_codec_dev1.4.x component. The shim uses that official component to program ES8311 and ES7210, then releases the shared GPIO7/8 I²C lines before jumping to Linux so the GT911 touch controller remains accessible. -
Build the matching C6 coprocessor firmware. Keep host and slave on the same
release/ng-1.0.6ESP-Hosted tag; the C6 example selects SDIO by default:git clone --depth 1 --branch release/ng-1.0.6 \ https://github.com/espressif/esp-hosted.git . "$IDF_PATH/export.sh" cd esp-hosted/esp_hosted_fg/esp/esp_driver/network_adapter idf.py set-target esp32c6 idf.py build cd -
ESP-IDF 5.5.2 was used for the local compile check. Espressif's tag setup script names IDF 5.4, which is also a conservative choice for rebuilding.
The product page specifies 32 MB flash, while some older Waveshare example
defaults still say 16 MB. Before flashing, run esptool --chip esp32p4 flash-id and confirm the detected capacity. Do not use this partition table
on a board that actually reports 16 MB.
Choose the DTB matching the printed product name:
XC_VARIANT=3_4c # use 4c for the 720×720 product
P4_PORT=/dev/ttyACM0 # adjust for your host
esptool --chip esp32p4 -p "$P4_PORT" -b 460800 \
--before default-reset --after hard-reset \
write-flash --flash-mode dio --flash-size 32MB --flash-freq 80m \
0x2000 linux-native/build/bootloader/bootloader.bin \
0x8000 linux-native/build/partition_table/partition-table.bin \
0x10000 linux-native/build/linux-native.bin \
0x90000 buildroot/output/images/Image \
0x890000 buildroot/output/images/rootfs.squashfs \
0x1890000 "buildroot/output/images/esp32p4-waveshare-xc-${XC_VARIANT}.dtb"Or create both merged images and flash each chip at offset zero:
XC_VARIANT=3_4c tools/mkrelease.sh \
buildroot/output/images linux-native/build \
esp-hosted/esp_hosted_fg/esp/esp_driver/network_adapter/build out
esptool --chip esp32p4 -p "$P4_PORT" write-flash 0x0 out/esp32p4.bin
esptool --chip esp32c6 -p "$C6_PORT" write-flash 0x0 out/esp32c6.binSet C6_PORT to the C6 native USB serial device. Power-cycle the board after
both images are installed. To test manually after boot:
ip link show wlan0
wifi-connect 'your-ssid' 'your-passphrase'
hci_upThe stage-three audio interface is deliberately smaller than ALSA to fit the NOMMU target. It always transfers raw, interleaved, signed 16-bit little-endian stereo PCM at 16000 Hz. Use the bundled smoke-test utility:
# Play a 440 Hz test tone for two seconds.
xc_audio_test tone 2
# Capture five seconds of raw stereo PCM to /tmp/mic.pcm.
xc_audio_test record /tmp/mic.pcm 5
# Capture one block and immediately play it back, repeated for five seconds.
xc_audio_test loop 5Direct writes to /dev/xc-audio play PCM and direct reads capture PCM. Each
system call transfers at most 4080 bytes; normal applications must loop over
short transfers. This stage is intended to establish the codec, I²S, and DMA
path, not to provide gapless playback, sample-rate conversion, mixing, or an
ALSA compatibility layer.
Because the current P4 DW-MMC Linux driver instantiates one physical slot,
this Wi-Fi/BT configuration cannot enumerate the microSD socket at the same
time. Consequently SD-card-backed credential persistence is unavailable;
pass credentials to wifi-connect after boot.
The 32 MB layout is:
| Offset | Size | Content |
|---|---|---|
0x002000 |
24 KiB | ESP-IDF bootloader |
0x008000 |
4 KiB | Partition table |
0x009000 |
24 KiB | NVS |
0x00f000 |
4 KiB | PHY init |
0x010000 |
512 KiB | Linux boot shim |
0x090000 |
8 MiB | Linux Image |
0x890000 |
16 MiB | SquashFS rootfs |
0x1890000 |
64 KiB | Selected DTB |
Use a 115200-baud serial console. A successful stage-three boot additionally
shows an Espressif SDIO function in dmesg, wlan0, and—after hci_up—
/sys/class/bluetooth/hci0. The kernel should also log
/dev/xc-audio: 16000 Hz, 16-bit, 2-channel PCM and create
/dev/xc-audio.
- Applied the complete kernel patch series, including patches
0036–0042, in order against Linux v6.18.35. - Preprocessed and compiled both new DTS files with DTC 1.7.2.
- Cross-compiled the ESP-Hosted SDIO kernel objects for RV32 Linux.
- Cross-compiled the new ESP32-P4 I2S/AHB-GDMA audio object for RV32 Linux.
- Built the P4 boot shim, including official
esp_codec_dev1.4.0, and C6 ESP-Hosted network-adapter firmware with ESP-IDF 5.5.2. - Compiled the fixed-format audio smoke-test utility with strict host warnings enabled.
- Ran whitespace/error checks on the changed source tree.
The remaining required validation is a complete Buildroot cross-build and a physical-board boot/display/touch/SDIO radio/audio test. Audio hardware validation must confirm channel order, microphone gain, speaker polarity, and click-free codec state across the ESP-IDF-to-Linux handoff.