Waveshare ESP32-S3-Touch-LCD-3.5: camera connector support (OV5640/OV2640) - #285
Conversation
3.5" 320x480 IPS sibling of the supported ESP32-S3-Touch-LCD-2: ST7796 display over SPI, FT6336 capacitive touch, QMI8658 IMU, PCF85063 RTC, AXP2101 power management, ES8311 codec, TF slot, and a camera connector (no camera included). The notable hardware difference from the LCD-2: the LCD reset and chip-select lines sit behind a PCA9554 I2C IO expander (EXIO1/EXIO2) instead of ESP32 GPIOs, so the board file pulses reset and parks CS low via the expander before bringing up the SPI display bus (cs=-1; the panel is the only SPI device). - vendor the st7796 display driver from lvgl_micropython (same package glue as the existing st7789) - add a PCA9554 8-bit IO expander driver alongside the existing TCA9555 - battery status via the AXP2101 PMU (t_watch pattern), not an ADC pin - auto-detection: PCA9554@0x20 + FT6336@0x38 on sda=8/scl=7, probed last so existing boards are unaffected Pin map cross-checked between the Waveshare wiki/schematic and two independent community configurations. Not yet verified on hardware: DMA buffer sizing, IMU mounted orientation, rotation, AXP2101 rail defaults, and the EXIO pin roles rest on the schematic + one config. esp32s3 build passes: image 3,618,496 bytes, 51,520 headroom. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Wires the existing drivers/codec/es8311.py into the board: speaker output and microphone input over I2S, with the codec controlled via a small adapter around the shared lcd_bus I2C wrapper (the driver expects machine.I2C-style writeto_mem/readfrom_mem_into). I2S pins from Waveshare's own demo code (01_audio_out / 04_es8311_example): MCLK=12, BCLK=13, LRCK=15, playback data=16, microphone data=14; codec at I2C 0x18 on the shared sda=8/scl=7 bus. No speaker-amp enable pin exists in Waveshare's examples, so pop suppression uses the codec's DAC soft-mute in the AudioManager on_open/on_close hooks (freenove pattern, minus the amp pin). DAC volume defaults to 76%, picked by ear on the physical board with a speaker attached: the driver's 85% default audibly distorts, 70% is clean but quiet, 76% is the loudest clean setting. Verified on hardware: WAV playback through an attached speaker works. Microphone input is registered but untested (no headset to monitor). Known limitation observed while testing: chaining playbacks with short (~400ms) gaps can silently wedge the I2S pipeline with ESP_ERR_INVALID_ARG from stream_wav until reboot — an AudioManager/ stream_wav reopen race worth investigating separately, not specific to this board. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Without INVON the Waveshare ESP32-S3-Touch-LCD-3.5's IPS panel renders the entire UI in negative. This went unnoticed at first because an inverted UI reads as a plausible dark theme; camera preview photos exposed it (inverted photos look like x-rays). Verified on hardware: sending INVON live flips the panel to correct colors, and a rebuilt firmware with this init renders launcher and camera preview correctly. The st7789 driver (used by the ESP32-S3-Touch-LCD-2) already sends INVON for the same reason; the vendored st7796 init was missing it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…2640) Adds the camera section to the 3.5 board file, wired per Waveshare's 03_camera_web_server demo: DVP data [45,47,48,46,42,40,39,21], VSYNC=17, HREF=18, PCLK=41, XCLK=38 @ 20MHz, PWDN/RESET not wired. The SCCB control bus shares the board's main I2C pins (sda=8/scl=7) with touch, codec and IO expander. The camera driver must reuse the existing I2C bus driver (sda_pin=-1, scl_pin=-1, sccb_i2c_port=0) instead of installing its own: with a second driver on the same pins, concurrent FT6336 touch polling garbles SCCB traffic — corrupted sensor config and dead touch buttons during preview. This needs the sccb_i2c_port parameter from the companion micropython-camera-API change. rotation_degrees=-90 tuned on hardware with an OV5640: the sensor is mounted 90 degrees counter-clockwise relative to the landscape UI. Verified on hardware end to end: preview upright with natural colors (after the st7796 INVON fix), touch buttons responsive during preview. Also adds a desktop graphical regression test asserting RGB565 preview color fidelity through the LVGL image blit at 1:1 and scaled sizes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
_270 instead of _90: with the USB cable to the left and the BOOT/RESET buttons at the bottom — the board's natural desk orientation — the UI was upside down. Hardware-verified: display upright, touch aligned. Note the rotation only takes effect at display init; changing it at runtime updates the driver state but not what the panel shows. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
With the display orientation changed from _90 to _270, the camera's mounting offset flips sign: rotation_degrees goes from -90 to 90. Hardware-verified with an OV5640: preview upright in the new orientation, colors natural, touch buttons working. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Updated for the orientation change in #280 ( |
|
Heads-up now that this is merged: the board file passes |
|
Thanks for the heads up! I did the submodule-bump myself so should be good now! |
Stacked on #280 (board support, incl. the new st7796 INVON commit) and #281 (ES8311 audio) — only the last commit is new here. Depends on MicroPythonOS/micropython-camera-API#1 for the
sccb_i2c_portparameter.Adds camera support for the 3.5's DVP connector, pins from Waveshare's 03_camera_web_server demo. Three hardware-debugging findings are baked in:
sda_pin=-1, sccb_i2c_port=0) — with its own second driver on those pins, touch polling garbles SCCB traffic (corrupted sensor config, dead touch buttons during preview).Verified on hardware end to end: preview upright, natural colors, responsive buttons, QR scanning works. Also adds a desktop graphical regression test asserting RGB565 preview color fidelity through the LVGL image blit at 1:1 and scaled sizes (passes on desktop; guards the preview path used by all camera boards).
🤖 Generated with Claude Code