Skip to content

xtensa/esp32s3: cam driver fixes and GC0308 DVP enhancements#18692

Draft
JianyuWang0623 wants to merge 5 commits intoapache:masterfrom
JianyuWang0623:cam-fixes-and-gc0308-enhancements
Draft

xtensa/esp32s3: cam driver fixes and GC0308 DVP enhancements#18692
JianyuWang0623 wants to merge 5 commits intoapache:masterfrom
JianyuWang0623:cam-fixes-and-gc0308-enhancements

Conversation

@JianyuWang0623
Copy link
Copy Markdown
Contributor

Note: Please adhere to Contributing Guidelines.

Summary

Fix several bugs in the ESP32-S3 CAM driver and add features needed for 8-bit DVP camera sensors (e.g. GC0308) with LCD preview.

  1. video/gc0308: report V4L2_PIX_FMT_RGB565X for 8-bit DVP output (f5145188a3b): GC0308 register 0x24 bits[3:0] = 0x06 selects RGB565 output. On an 8-bit DVP bus the high byte is clocked out first, so pixel data arrives in memory in big-endian order. Report V4L2_PIX_FMT_RGB565X so userspace can detect this and byte-swap for LE displays.

  2. video/gc0308: implement V4L2 horizontal flip control (ff1bbe94508): Implement get_supported_value, get_value, set_value callbacks for IMGSENSOR_ID_HFLIP_VIDEO/STILL. Hardware mirror via register 0x14 (CISCTL_MODE1) bit[0] with zero CPU cost.

  3. xtensa/esp32s3: fix esp32s3_cam uninit/stop_capture bugs (7904d712d3f):

    • stop_capture: reset DMA channel, CAM module and AFIFO under spinlock to fully quiesce hardware. Clear pending VSYNC interrupt to prevent stale ISR firing.
    • uninit: reset CAM/AFIFO before releasing DMA to prevent in-flight transfers after channel detach. Use esp_teardown_irq with correct peripheral ID (ESP32S3_PERIPH_LCD_CAM) instead of irq_detach which corrupts the shared IRQ mapping table. Mask interrupts and clear pending flags under spinlock before detaching handler. Preserve XCLK output so the sensor remains accessible via I2C.
    • set_buf/uninit: track driver-allocated vs user-provided frame buffers with fb_allocated flag to prevent double-free in USERPTR mode.
  4. xtensa/esp32s3: cam driver support MMAP buffer allocation (13c7cc8a743): Implement imgdata_ops alloc/free callbacks using kmm_memalign with GDMA-derived alignment, so the V4L2 framework can use V4L2_MEMORY_MMAP. Introduce ESP32S3_CAM_EXT_MEMBLK / ESP32S3_CAM_DMA_ALIGN macros so the block size enum and byte alignment stay in sync.

  5. boards/lckfb-szpi-esp32s3: camera config use landscape LCD (627e20c0377): Remove CONFIG_LCD_PORTRAIT so ST7789 defaults to landscape (320×240), matching GC0308 QVGA output and physical screen mounting.

Companion apps-side PR:

Impact

  • Fixes potential crash/corruption in CAM driver uninit and stop paths (IRQ mapping table corruption, double-free, stale ISR).
  • Adds MMAP support — no breaking change, USERPTR still works.
  • GC0308 format change: userspace that previously assumed RGB565 must now handle the RGB565X fallback (addressed in companion apps PR).
  • Board defconfig change only affects lckfb-szpi-esp32s3:camera.
  • No impact on build process, documentation, or security.

Testing

Host: Ubuntu 22.04 x86_64, xtensa-esp32s3-elf-gcc

Target: ESP32-S3 (lckfb-szpi-esp32s3, ESP32-S3-WROOM-1-N16R8, PSRAM 8MB OCT) with GC0308 DVP camera and ST7789 LCD

Build and flash:

$ cd nuttx
$ make -j$(nproc) flash ESPTOOL_PORT=/dev/ttyUSB0
...
Generated: nuttx.bin
...
Hard resetting via RTS pin...

Runtime test — continuous preview:

nsh> camera 0
nximage_listener: Connected
nximage_initialize: Screen resolution (320,240)
Start video this mode is eternal. (Non stop, non save files.)

Runtime test — mirrored preview:

nsh> camera 0 -m
nximage_listener: Connected
nximage_initialize: Screen resolution (320,240)
Start video this mode is eternal. (Non stop, non save files.)

Verified:

  • LCD preview displays correct colors (RGB565X byte-swap path active)
  • Hardware mirror (-m) works correctly
  • MMAP buffers allocated by driver with GDMA alignment (3 video buffers in RING mode)
  • Repeated start/stop cycles — no crash, no resource leak
  • checkpatch.sh -g apache/master..HEAD passes all checks

GC0308 register 0x24 bits[3:0] = 0x06 selects RGB565 output per
datasheet.  On an 8-bit DVP bus the high byte is clocked out first,
so the pixel data arrives in memory in big-endian order (RGB565X).

Report V4L2_PIX_FMT_RGB565X so that userspace can detect this and
byte-swap if needed for a little-endian display path.

Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
Implement get_supported_value, get_value and set_value callbacks
for IMGSENSOR_ID_HFLIP_VIDEO / IMGSENSOR_ID_HFLIP_STILL.  This
allows applications to mirror the camera preview horizontally at
runtime via VIDIOC_S_CTRL + V4L2_CID_HFLIP.

The hardware mirror is controlled by register 0x14 (CISCTL_MODE1)
bit[0], which reverses the pixel readout order with zero CPU cost.

Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
Fix several issues in the ESP32-S3 CAM driver:

- stop_capture: reset DMA channel, CAM module and AFIFO under
  spinlock to fully quiesce hardware before returning. Clear
  pending VSYNC interrupt to prevent stale ISR firing.

- uninit: reset CAM/AFIFO before releasing DMA to prevent
  in-flight transfers after channel detach. Use esp_teardown_irq
  with correct peripheral ID (ESP32S3_PERIPH_LCD_CAM) instead of
  irq_detach which corrupts the shared IRQ mapping table. Mask
  interrupts and clear pending flags under spinlock before
  detaching handler.

- uninit: preserve XCLK output so the sensor remains accessible
  via I2C for subsequent re-initialization.

- set_buf/uninit: track driver-allocated vs user-provided frame
  buffers with fb_allocated flag to prevent double-free when
  using V4L2 USERPTR mode.

Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
Implement imgdata_ops alloc/free callbacks so the V4L2 framework
can use MMAP mode to allocate frame buffers with proper GDMA
alignment.  This lets applications avoid hardcoding platform-
specific alignment values.

- Add esp32s3_cam_alloc() using kmm_memalign with the alignment
  derived from the GDMA external memory block size setting.
- Add esp32s3_cam_free() wrapper around kmm_free.
- Introduce ESP32S3_CAM_EXT_MEMBLK / ESP32S3_CAM_DMA_ALIGN macros
  so the block size enum and byte alignment are defined in one
  place and stay in sync automatically.

Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
Remove CONFIG_LCD_PORTRAIT so the ST7789 defaults to landscape
orientation (320x240), matching the GC0308 QVGA output and the
physical screen mounting direction.

Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
@github-actions github-actions bot added Arch: xtensa Issues related to the Xtensa architecture Size: M The size of the change in this PR is medium Area: Video Board: xtensa labels Apr 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Arch: xtensa Issues related to the Xtensa architecture Area: Video Board: xtensa Size: M The size of the change in this PR is medium

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant