These instructions target Waveshare ESP32-S3-Touch-AMOLED-2.16 with 16 MB flash and 8 MB OPI PSRAM. Keep USB at the bottom. Verify the board model before writing firmware, and keep any existing firmware/settings backup private.
Build and identify the device
From the repository root, with PlatformIO on your PATH:
pio run --project-dir firmware
pio device list
Find the Espressif interface and substitute its port for YOUR_PORT. The tested
native USB interface uses VID/PID 303A:1001; the port can change after reconnecting.
On Linux, follow PlatformIO’s USB permissions guidance
if access is denied. Use a USB data cable and close other serial monitors before
flashing.
Normal upload
pio run --project-dir firmware --target upload --upload-port YOUR_PORT
pio device monitor --port YOUR_PORT --baud 115200
Send status followed by a newline. A successful startup reports the example’s
version, ready: true, display/touch/PMIC status and PSRAM size. A missing touch or
power chip can still allow display-only use; inspect each flag separately.
Flashing replaces the installed application. Normal upload does not deliberately perform a full-device erase, and it does not modify eFuses or the chip’s immutable ROM.
Build outputs and offsets
Files are produced under firmware/.pio/build/waveshare_amoled_216/:
| File | Purpose | Flash offset |
|---|---|---|
firmware.factory.bin |
Combined bootloader, partition table, boot metadata and app | 0x0 |
firmware.bin |
Application only, for a matching partition layout | 0x10000 |
bootloader.bin |
ESP32-S3 bootloader | 0x0 |
partitions.bin |
Partition table | 0x8000 |
Use the combined factory image for an initial installation. Do not write the standalone application at address zero. Compiled firmware and device backups are not stored in this source repository.
USB JTAG alternative
Use Espressif’s OpenOCD distribution
with ESP32-S3 support, rather than a generic build without Espressif extensions.
Ensure its bin directory is on PATH and its script directory is available to
OpenOCD (use -s /path/to/openocd/scripts if necessary).
The following command has been tested with OpenOCD v0.12.0-esp32-20260304:
openocd -f board/esp32s3-builtin.cfg \
-c 'adapter speed 20000' \
-c 'gdb port disabled' -c 'tcl port disabled' -c 'telnet port disabled' \
-c 'program_esp firmware/.pio/build/waveshare_amoled_216/firmware.factory.bin 0x0 verify reset exit'
Connect only the intended board, or add -c 'adapter serial YOUR_DEVICE_SERIAL'
using the serial from your device inventory. The 20 MHz clock avoided transfer
CRC errors seen at 40 MHz during development. Confirm Verify OK in the output,
then check startup through the USB console. Do not run a JTAG flash and a serial
upload at the same time.
Enter download mode manually
If automatic entry fails, follow the Waveshare FAQ:
- Fully power the board off. A battery can keep it running after USB is removed.
- Hold BOOT/−, power it on/reconnect USB, and then release BOOT/−.
- Retry upload. Recheck the port if it changed.
- Power-cycle after programming if the application does not start automatically.
Do not assume an unplugged board is off when a battery is attached. The PWR button retains its board power function; use the vendor’s procedure for the fitted battery.
Backups and complete erasure
A full flash read can include Wi-Fi credentials and data left by an earlier app. Store backups privately, outside source control. The example does not require a full erase on each update. If deliberately clearing all stored data, use the vendor’s flashing and erasing guide and verify the target first. Complete erasure destroys settings and files as well as the application; it does not erase eFuses.
After flashing
Select every character and mood, test tap/swipe and the two application buttons,
then check pause, tour and pace. status can report zero FPS for a static picker;
close it and press Play to measure animation. A red display indicates framebuffer
allocation failed: confirm the 8 MB OPI PSRAM configuration and inspect startup logs.