boards/lckfb-szpi-esp32s3: add camera defconfig

Add camera configuration for lckfb-szpi-esp32s3 board with GC0308
sensor on DVP interface. Includes board-level camera initialization,
DVP GPIO pin mapping, and V4L2 video pipeline setup.

Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
This commit is contained in:
wangjianyu3
2026-03-16 11:50:04 +08:00
committed by Alan C. Assis
parent 370921aeba
commit ebfacd3bb8
6 changed files with 334 additions and 0 deletions
@@ -525,3 +525,41 @@ Then format and mount the SD card::
nsh> echo "hello" > /mnt/sd/test.txt
nsh> cat /mnt/sd/test.txt
hello
camera
------
Basic NuttShell configuration console and DVP camera enabled via the
ESP32-S3 CAM controller with a GC0308 VGA CMOS image sensor. The camera
outputs RGB565X (big-endian RGB565) at QVGA (320x240) resolution by default.
Console is accessible over USB ADB.
The DVP camera pin mapping is as follows:
======= ======
Signal GPIO
======= ======
XCLK GPIO15
PCLK GPIO13
VSYNC GPIO6
HREF GPIO7
D0 GPIO5
D1 GPIO4
D2 GPIO16
D3 GPIO14
D4 GPIO1
D5 GPIO2
D6 GPIO42
D7 GPIO41
PWDN GPIO38 (active low, directly connected to PCA9557 I/O expander)
======= ======
You can run the configuration and compilation procedure::
$ ./tools/configure.sh lckfb-szpi-esp32s3:camera
$ make flash -j$(nproc) ESPTOOL_PORT=/dev/ttyUSB0
Then use the camera example to capture a frame::
$ adb -s 1234 shell
nsh> camera
@@ -0,0 +1,136 @@
#
# This file is autogenerated: PLEASE DO NOT EDIT IT.
#
# You can use "make menuconfig" to make any modifications to the installed .config file.
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
# modifications.
#
# CONFIG_ARCH_LEDS is not set
# CONFIG_NDEBUG is not set
# CONFIG_NSH_ARGCAT is not set
# CONFIG_NSH_CMDOPT_HEXDUMP is not set
# CONFIG_NXFONTS_DISABLE_16BPP is not set
# CONFIG_NX_DISABLE_16BPP is not set
CONFIG_ADBD_FILE_SERVICE=y
CONFIG_ADBD_SHELL_SERVICE=y
CONFIG_ADBD_STACKSIZE=8192
CONFIG_ADBD_USB_BOARDCTL=y
CONFIG_ADBD_USB_SERVER=y
CONFIG_ARCH="xtensa"
CONFIG_ARCH_BOARD="lckfb-szpi-esp32s3"
CONFIG_ARCH_BOARD_COMMON=y
CONFIG_ARCH_BOARD_ESP32S3_LCKFB_SZPI=y
CONFIG_ARCH_CHIP="esp32s3"
CONFIG_ARCH_CHIP_ESP32S3=y
CONFIG_ARCH_CHIP_ESP32S3WROOM1N16R8=y
CONFIG_ARCH_INTERRUPTSTACK=2048
CONFIG_ARCH_STACKDUMP=y
CONFIG_ARCH_XTENSA=y
CONFIG_BOARD_LOOPSPERMSEC=16717
CONFIG_BUILTIN=y
CONFIG_DEBUG_FEATURES=y
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_GPIO=y
CONFIG_DEBUG_GPIO_ERROR=y
CONFIG_DEBUG_I2C=y
CONFIG_DEBUG_I2C_ERROR=y
CONFIG_DEBUG_MM=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_DEV_GPIO=y
CONFIG_ESP32S3_CAM=y
CONFIG_ESP32S3_GPIO_IRQ=y
CONFIG_ESP32S3_I2C0=y
CONFIG_ESP32S3_OTG=y
CONFIG_ESP32S3_OTG_ENDPOINT_NUM=2
CONFIG_ESP32S3_SDMMC=y
CONFIG_ESP32S3_SDMMC_CLK=47
CONFIG_ESP32S3_SDMMC_CMD=48
CONFIG_ESP32S3_SDMMC_D0=21
CONFIG_ESP32S3_SPI2=y
CONFIG_ESP32S3_SPI2_CLKPIN=41
CONFIG_ESP32S3_SPI2_CSPIN=-1
CONFIG_ESP32S3_SPI2_MISOPIN=-1
CONFIG_ESP32S3_SPI2_MOSIPIN=40
CONFIG_ESP32S3_SPIRAM=y
CONFIG_ESP32S3_SPIRAM_MODE_OCT=y
CONFIG_ESP32S3_SPI_SWCS=y
CONFIG_ESP32S3_SPI_UDCS=y
CONFIG_ESP32S3_UART0=y
CONFIG_ESPRESSIF_LEDC=y
CONFIG_ESPRESSIF_LEDC_CHANNEL0_PIN=42
CONFIG_ESPRESSIF_LEDC_TIMER0=y
CONFIG_ETC_ROMFS=y
CONFIG_EXAMPLES_CAMERA=y
CONFIG_EXAMPLES_CAMERA_OUTPUT_LCD=y
CONFIG_EXAMPLES_CAMERA_STACKSIZE=8192
CONFIG_EXAMPLES_FB=y
CONFIG_EXAMPLES_PWM=y
CONFIG_FAT_LFN=y
CONFIG_FS_FAT=y
CONFIG_FS_PROCFS=y
CONFIG_FS_ROMFS=y
CONFIG_FS_TMPFS=y
CONFIG_GPIO_LOWER_HALF=y
CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=3072
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INIT_STACKSIZE=4096
CONFIG_INTELHEX_BINARY=y
CONFIG_IOEXPANDER=y
CONFIG_IOEXPANDER_PCA9557=y
CONFIG_LCD=y
CONFIG_LCD_DEV=y
CONFIG_LCD_FRAMEBUFFER=y
CONFIG_LCD_PORTRAIT=y
CONFIG_LCD_ST7789=y
CONFIG_LCD_ST7789_DATA_ENDIAN_LITTLE=y
CONFIG_LCD_ST7789_FREQUENCY=40000000
CONFIG_LIBC_EXECFUNCS=y
CONFIG_LIBUV=y
CONFIG_LINE_MAX=64
CONFIG_MMCSD_CHECK_READY_STATUS_WITHOUT_SLEEP=y
CONFIG_MMCSD_MULTIBLOCK_LIMIT=128
CONFIG_MM_BACKTRACE=0
CONFIG_MM_REGIONS=2
CONFIG_MQ_MAXMSGSIZE=64
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_READLINE=y
CONFIG_NX=y
CONFIG_NXFONT_SANS23X27=y
CONFIG_NX_BLOCKING=y
CONFIG_POSIX_SPAWN_DEFAULT_STACKSIZE=4096
CONFIG_PREALLOC_TIMERS=4
CONFIG_PSEUDOTERM=y
CONFIG_PTHREAD_MUTEX_TYPES=y
CONFIG_RAM_SIZE=114688
CONFIG_RAM_START=0x20000000
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_BACKTRACE=y
CONFIG_SCHED_CHILD_STATUS=y
CONFIG_SCHED_HAVE_PARENT=y
CONFIG_SCHED_HPWORKSTACKSIZE=8192
CONFIG_SCHED_WAITPID=y
CONFIG_SDIO_WIDTH_D1_ONLY=y
CONFIG_SPI_CMDDATA=y
CONFIG_STACK_COLORATION=y
CONFIG_STACK_USAGE=y
CONFIG_START_DAY=6
CONFIG_START_MONTH=12
CONFIG_START_YEAR=2011
CONFIG_SYSLOG_BUFFER=y
CONFIG_SYSLOG_CHARDEV=y
CONFIG_SYSTEM_ADBD=y
CONFIG_SYSTEM_I2CTOOL=y
CONFIG_SYSTEM_NSH=y
CONFIG_TLS_NCLEANUP=4
CONFIG_TLS_NELEM=4
CONFIG_TLS_TASK_NELEM=4
CONFIG_UART0_SERIAL_CONSOLE=y
CONFIG_USBADB=y
CONFIG_VIDEO=y
CONFIG_VIDEO_FB=y
CONFIG_VIDEO_GC0308=y
CONFIG_VIDEO_STREAM=y
@@ -56,3 +56,7 @@ endif
ifeq ($(CONFIG_SENSORS_QMI8658),y)
CSRCS += esp32s3_qmi8658.c
endif
ifeq ($(CONFIG_ESP32S3_CAM),y)
CSRCS += esp32s3_board_camera.c
endif
@@ -163,5 +163,9 @@ int esp32s3_ft5x06_initialize(void);
int esp32s3_qmi8658_initialize(void);
#endif
#ifdef CONFIG_ESP32S3_CAM
int esp32s3_camera_initialize(void);
#endif
#endif /* __ASSEMBLY__ */
#endif /* __BOARDS_XTENSA_ESP32S3_LCKFB_SZPI_ESP32S3_SRC_ESP32S3_DEVKIT_H */
@@ -0,0 +1,140 @@
/****************************************************************************
* boards/xtensa/esp32s3/lckfb-szpi-esp32s3/src/esp32s3_board_camera.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <debug.h>
#include <sys/ioctl.h>
#include <nuttx/arch.h>
#include <nuttx/ioexpander/gpio.h>
#include <nuttx/i2c/i2c_master.h>
#include <nuttx/video/imgsensor.h>
#include <nuttx/video/imgdata.h>
#include <nuttx/video/v4l2_cap.h>
#include <nuttx/video/gc0308.h>
#include "esp32s3_i2c.h"
#include "esp32s3_cam.h"
#include "esp32s3-szpi.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* PCA9557 DVP_PWDN is registered as /dev/gpio2 */
#define DVP_PWDN_PATH "/dev/gpio2"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: esp32s3_camera_initialize
*
* Description:
* Initialize the camera subsystem:
* 1. Power on camera via PCA9557 DVP_PWDN
* 2. Register GC0308 imgsensor
* 3. Register ESP32-S3 CAM imgdata
* 4. Register V4L2 capture device
*
****************************************************************************/
int esp32s3_camera_initialize(void)
{
struct imgdata_s *imgdata;
struct imgsensor_s *imgsensor;
struct i2c_master_s *i2c;
int fd;
int ret;
/* Step 1: Power on camera by driving DVP_PWDN low via PCA9557 GPIO */
fd = open(DVP_PWDN_PATH, O_RDWR);
if (fd >= 0)
{
/* Write 0 to deassert PWDN (active high) */
ioctl(fd, GPIOC_WRITE, 0);
close(fd);
up_mdelay(10); /* Wait for sensor power-up */
}
else
{
snerr("ERROR: Failed to open %s: %d\n", DVP_PWDN_PATH, errno);
return -errno;
}
/* Step 2: Register ESP32-S3 CAM imgdata driver.
* This also starts XCLK output — GC0308 needs clock before I2C.
*/
imgdata = esp32s3_cam_initialize();
if (!imgdata)
{
snerr("ERROR: Failed to register CAM imgdata\n");
return -ENODEV;
}
up_mdelay(10); /* Wait for XCLK to stabilize */
/* Step 3: Initialize GC0308 sensor via I2C */
i2c = esp32s3_i2cbus_initialize(0);
if (!i2c)
{
snerr("ERROR: Failed to initialize I2C bus\n");
return -ENODEV;
}
imgsensor = gc0308_initialize(i2c, 320, 240);
if (!imgsensor)
{
snerr("ERROR: Failed to initialize GC0308\n");
return -ENODEV;
}
/* Step 4: Register imgdata and imgsensor globally.
* capture_initialize() in the camera app will create /dev/video.
*/
imgdata_register(imgdata);
ret = imgsensor_register(imgsensor);
if (ret < 0)
{
snerr("ERROR: Failed to register imgsensor: %d\n", ret);
return ret;
}
sninfo("Camera drivers registered\n");
return OK;
}
@@ -117,6 +117,10 @@
# include <nuttx/sensors/qmi8658.h>
#endif
#ifdef CONFIG_ESP32S3_CAM
# include <nuttx/video/v4l2_cap.h>
#endif
#ifdef CONFIG_ESP32S3_ADC
#include "esp32s3_board_adc.h"
#endif
@@ -456,6 +460,14 @@ int esp32s3_bringup(void)
}
#endif
#ifdef CONFIG_ESP32S3_CAM
ret = esp32s3_camera_initialize();
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: Failed to initialize camera: %d\n", ret);
}
#endif
#ifdef CONFIG_ESP32S3_AES_ACCELERATOR
ret = esp32s3_aes_init();
if (ret < 0)