Skip to content

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

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

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>
@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
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>
@JianyuWang0623 JianyuWang0623 force-pushed the cam-fixes-and-gc0308-enhancements branch from 627e20c to f32b545 Compare April 9, 2026 12:58
@JianyuWang0623 JianyuWang0623 marked this pull request as ready for review April 10, 2026 01:44
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed for this PR but let me add it for information. After the latest Espressif's common layer update, it is possible to use Espressif common layer drivers for camera and lcd interfaces. For more information please check these files:

S3 cam_ll.h
S3 cam_hal.c
S3 lcd_ll.h

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.

3 participants