This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 6ac28d5526 xtensa/esp32s3: LCD controller driver
6ac28d5526 is described below
commit 6ac28d552629c4cf6fdbc657b22383192372fa64
Author: Dong Heng <[email protected]>
AuthorDate: Fri Aug 25 19:32:02 2023 +0800
xtensa/esp32s3: LCD controller driver
---
arch/xtensa/src/esp32s3/Kconfig | 157 +++
arch/xtensa/src/esp32s3/Make.defs | 4 +
arch/xtensa/src/esp32s3/esp32s3_dma.c | 41 +
arch/xtensa/src/esp32s3/esp32s3_dma.h | 26 +
arch/xtensa/src/esp32s3/esp32s3_idle.c | 31 +-
arch/xtensa/src/esp32s3/esp32s3_lcd.c | 1010 +++++++++++++++
arch/xtensa/src/esp32s3/hardware/esp32s3_lcd_cam.h | 1349 ++++++++++++++++++++
boards/xtensa/esp32s3/common/Kconfig | 11 +
.../esp32s3/common/scripts/esp32s3_aliases.ld | 2 +
.../esp32s3/common/scripts/legacy_sections.ld | 25 +
boards/xtensa/esp32s3/esp32s3-lcd-ev/Kconfig | 26 +
.../esp32s3/esp32s3-lcd-ev/configs/lcd/defconfig | 63 +
.../esp32s3/esp32s3-lcd-ev/configs/lvgl/defconfig | 78 ++
boards/xtensa/esp32s3/esp32s3-lcd-ev/src/Make.defs | 12 +
.../esp32s3/esp32s3-lcd-ev/src/esp32s3-lcd-ev.h | 98 ++
.../esp32s3/esp32s3-lcd-ev/src/esp32s3_bringup.c | 16 +
.../esp32s3-lcd-ev/src/esp32s3_ioexpander.c | 171 +++
.../esp32s3/esp32s3-lcd-ev/src/esp32s3_lcd.c | 683 ++++++++++
.../esp32s3-lcd-ev/src/esp32s3_touchscreen.c | 191 +++
19 files changed, 3984 insertions(+), 10 deletions(-)
diff --git a/arch/xtensa/src/esp32s3/Kconfig b/arch/xtensa/src/esp32s3/Kconfig
index 78c297df52..af41c2da75 100644
--- a/arch/xtensa/src/esp32s3/Kconfig
+++ b/arch/xtensa/src/esp32s3/Kconfig
@@ -715,6 +715,16 @@ config ESP32S3_WCL
select ARCH_USE_MPU
select XTENSA_HAVE_GENERAL_EXCEPTION_HOOKS if BUILD_PROTECTED
+config ESP32S3_LCD
+ bool "LCD"
+ default n
+ select DRIVERS_VIDEO
+ select VIDEO_FB
+ select FB_UPDATE
+ help
+ ---help---
+ LCD controller that outputs parallel data and supports RGB
interface.
+
endmenu # ESP32-S3 Peripheral Selection
menuconfig ESP32S3_WIFI_BT_COEXIST
@@ -1713,6 +1723,153 @@ config ESP32S3_OTG_DEBUG_REGISTER
endmenu # USB OTG Configuration
+menu "LCD Controller Configuration"
+ depends on ESP32S3_LCD
+
+menu "LCD Pin Configuration"
+
+config ESP32S3_LCD_PCLK_PIN
+ int "LCD Pixel Clock Signal Pin"
+ default 9
+
+config ESP32S3_LCD_VSYNC_PIN
+ int "LCD Vertical Synchronization Pin"
+ default 3
+
+config ESP32S3_LCD_HSYNC_PIN
+ int "LCD Horizontal Synchronization Pin"
+ default 46
+
+config ESP32S3_LCD_HE_PIN
+ int "LCD Horizontal Enable Pin"
+ default 17
+
+config ESP32S3_LCD_DATA0_PIN
+ int "LCD Parallel Output Data Bit-0 Pin"
+ default 10
+
+config ESP32S3_LCD_DATA1_PIN
+ int "LCD Parallel Output Data Bit-1 Pin"
+ default 11
+
+config ESP32S3_LCD_DATA2_PIN
+ int "LCD Parallel Output Data Bit-2 Pin"
+ default 12
+
+config ESP32S3_LCD_DATA3_PIN
+ int "LCD Parallel Output Data Bit-3 Pin"
+ default 13
+
+config ESP32S3_LCD_DATA4_PIN
+ int "LCD Parallel Output Data Bit-4 Pin"
+ default 14
+
+config ESP32S3_LCD_DATA5_PIN
+ int "LCD Parallel Output Data Bit-5 Pin"
+ default 21
+
+config ESP32S3_LCD_DATA6_PIN
+ int "LCD Parallel Output Data Bit-6 Pin"
+ default 47
+
+config ESP32S3_LCD_DATA7_PIN
+ int "LCD Parallel Output Data Bit-7 Pin"
+ default 48
+
+config ESP32S3_LCD_DATA8_PIN
+ int "LCD Parallel Output Data Bit-8 Pin"
+ default 45
+
+config ESP32S3_LCD_DATA9_PIN
+ int "LCD Parallel Output Data Bit-9 Pin"
+ default 38
+
+config ESP32S3_LCD_DATA10_PIN
+ int "LCD Parallel Output Data Bit-10 Pin"
+ default 39
+
+config ESP32S3_LCD_DATA11_PIN
+ int "LCD Parallel Output Data Bit-11 Pin"
+ default 40
+
+config ESP32S3_LCD_DATA12_PIN
+ int "LCD Parallel Output Data Bit-12 Pin"
+ default 41
+
+config ESP32S3_LCD_DATA13_PIN
+ int "LCD Parallel Output Data Bit-13 Pin"
+ default 42
+
+config ESP32S3_LCD_DATA14_PIN
+ int "LCD Parallel Output Data Bit-14 Pin"
+ default 2
+
+config ESP32S3_LCD_DATA15_PIN
+ int "LCD Parallel Output Data Bit-15 Pin"
+ default 1
+
+endmenu
+
+menu "LCD Display Configuration"
+ depends on ESP32S3_LCD
+
+config ESP32S3_LCD_VRES
+ int "LCD Vertical Resolution"
+ default 480
+
+config ESP32S3_LCD_HRES
+ int "LCD Horizontal Resolution"
+ default 480
+
+config ESP32S3_LCD_CLOCK_MHZ
+ int "LCD Pixel Clock Frequency in MHz"
+ default 2
+
+config ESP32S3_LCD_VFRONTPORCH
+ int "LCD Vertical Front Porch"
+ default 40
+
+config ESP32S3_LCD_VBACKPORCH
+ int "LCD Vertical Back Porch"
+ default 20
+
+config ESP32S3_LCD_VPULSEWIDTH
+ int "LCD Vertical Pulse Width"
+ default 13
+
+config ESP32S3_LCD_HFRONTPORCH
+ int "LCD Horizontal Front Porch"
+ default 40
+
+config ESP32S3_LCD_HBACKPORCH
+ int "LCD Horizontal Back Porch"
+ default 20
+
+config ESP32S3_LCD_HPULSEWIDTH
+ int "LCD Horizontal Pulse Width"
+ default 15
+
+config ESP32S3_LCD_BUFFER_LAYERS
+ int "LCD Buffer Layer Number"
+ default 1
+
+choice
+ prompt "LCD Data Width"
+ default ESP32S3_LCD_DATA_16BIT
+
+config ESP32S3_LCD_DATA_16BIT
+ bool "16-bit"
+
+endchoice # LCD Data Width
+
+endmenu
+
+config ESP32S3_LCD_REGDEBUG
+ bool "LCD Debug Registers"
+ default n
+
+endmenu
+
menu "Application Image Configuration"
choice
diff --git a/arch/xtensa/src/esp32s3/Make.defs
b/arch/xtensa/src/esp32s3/Make.defs
index 0a9752a8ec..154c2fc675 100644
--- a/arch/xtensa/src/esp32s3/Make.defs
+++ b/arch/xtensa/src/esp32s3/Make.defs
@@ -158,6 +158,10 @@ ifeq ($(CONFIG_RTC_DRIVER),y)
CHIP_CSRCS += esp32s3_rtc_lowerhalf.c
endif
+ifeq ($(CONFIG_ESP32S3_LCD),y)
+CHIP_CSRCS += esp32s3_lcd.c
+endif
+
#############################################################################
# Espressif HAL for 3rd Party Platforms
#############################################################################
diff --git a/arch/xtensa/src/esp32s3/esp32s3_dma.c
b/arch/xtensa/src/esp32s3/esp32s3_dma.c
index bbd3af5e55..203ba7f130 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_dma.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_dma.c
@@ -391,6 +391,47 @@ void esp32s3_dma_wait_idle(int chan, bool tx)
while ((waitbits & regval) == 0);
}
+/****************************************************************************
+ * Name: esp32s3_dma_set_ext_memblk
+ *
+ * Description:
+ * Configure DMA external memory block size.
+ *
+ * Input Parameters:
+ * chan - DMA channel
+ * tx - true: TX mode; false: RX mode
+ * type - block size type
+ *
+ * Returned Value:
+ * None.
+ *
+ ****************************************************************************/
+
+void esp32s3_dma_set_ext_memblk(int chan, bool tx,
+ enum esp32s3_dma_ext_memblk_e type)
+{
+ uint32_t val;
+
+ if (tx)
+ {
+ val = ((uint32_t)type << DMA_OUT_EXT_MEM_BK_SIZE_CH0_S);
+
+ CLR_GDMA_CH_BITS(DMA_OUT_CONF1_CH0_REG,
+ chan,
+ DMA_OUT_EXT_MEM_BK_SIZE_CH0_M);
+ SET_GDMA_CH_BITS(DMA_OUT_CONF1_CH0_REG, chan, val);
+ }
+ else
+ {
+ val = ((uint32_t)type << DMA_IN_EXT_MEM_BK_SIZE_CH0_S);
+
+ CLR_GDMA_CH_BITS(DMA_IN_CONF1_CH0_REG,
+ chan,
+ DMA_IN_EXT_MEM_BK_SIZE_CH0_M);
+ SET_GDMA_CH_BITS(DMA_IN_CONF1_CH0_REG, chan, val);
+ }
+}
+
/****************************************************************************
* Name: esp32s3_dma_init
*
diff --git a/arch/xtensa/src/esp32s3/esp32s3_dma.h
b/arch/xtensa/src/esp32s3/esp32s3_dma.h
index 2200ad72cd..db2c91899d 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_dma.h
+++ b/arch/xtensa/src/esp32s3/esp32s3_dma.h
@@ -104,6 +104,13 @@ enum esp32s3_dma_periph_e
ESP32S3_DMA_PERIPH_NUM,
};
+enum esp32s3_dma_ext_memblk_e
+{
+ ESP32S3_DMA_EXT_MEMBLK_16B = 0,
+ ESP32S3_DMA_EXT_MEMBLK_32B = 1,
+ ESP32S3_DMA_EXT_MEMBLK_64B = 2
+};
+
/* DMA descriptor type */
struct esp32s3_dmadesc_s
@@ -230,6 +237,25 @@ void esp32s3_dma_disable(int chan, bool tx);
void esp32s3_dma_wait_idle(int chan, bool tx);
+/****************************************************************************
+ * Name: esp32s3_dma_set_ext_memblk
+ *
+ * Description:
+ * Configure DMA external memory block size.
+ *
+ * Input Parameters:
+ * chan - DMA channel
+ * tx - true: TX mode; false: RX mode
+ * type - block size type
+ *
+ * Returned Value:
+ * None.
+ *
+ ****************************************************************************/
+
+void esp32s3_dma_set_ext_memblk(int chan, bool tx,
+ enum esp32s3_dma_ext_memblk_e type);
+
/****************************************************************************
* Name: esp32s3_dma_init
*
diff --git a/arch/xtensa/src/esp32s3/esp32s3_idle.c
b/arch/xtensa/src/esp32s3/esp32s3_idle.c
index d3c4167c7b..16b714e6af 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_idle.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_idle.c
@@ -63,21 +63,32 @@
void up_idle(void)
{
+ /* Report loop explanation here */
+
+#ifdef CONFIG_ESP32S3_SPEED_UP_ISR
+ for (; ; )
+ {
+#endif
+
#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS)
- /* If the system is idle and there are no timer interrupts, then process
- * "fake" timer interrupts. Hopefully, something will wake up.
- */
+ /* If the system is idle and there are no timer interrupts, then
+ * process "fake" timer interrupts. Hopefully, something will wake up.
+ */
- nxsched_process_timer();
+ nxsched_process_timer();
#else
- /* This would be an appropriate place to put some MCU-specific logic to
- * sleep in a reduced power mode until an interrupt occurs to save power
- */
+ /* This would be an appropriate place to put some MCU-specific logic
+ * to sleep in a reduced power mode until an interrupt occurs to save
+ * power.
+ */
-#if XCHAL_HAVE_INTERRUPTS
- __asm__ __volatile__ ("waiti 0");
-#endif
+# if XCHAL_HAVE_INTERRUPTS
+ __asm__ __volatile__ ("waiti 0");
+# endif
+#endif /* CONFIG_SUPPRESS_INTERRUPTS || CONFIG_SUPPRESS_TIMER_INTS */
+#ifdef CONFIG_ESP32S3_SPEED_UP_ISR
+ }
#endif
}
diff --git a/arch/xtensa/src/esp32s3/esp32s3_lcd.c
b/arch/xtensa/src/esp32s3/esp32s3_lcd.c
new file mode 100644
index 0000000000..6fd1be2a0f
--- /dev/null
+++ b/arch/xtensa/src/esp32s3/esp32s3_lcd.c
@@ -0,0 +1,1010 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32s3/esp32s3_lcd.c
+ *
+ * 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 <inttypes.h>
+#include <stdint.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/spinlock.h>
+#include <nuttx/video/fb.h>
+#include <nuttx/kmalloc.h>
+
+#include <arch/board/board.h>
+
+#include "esp32s3_clockconfig.h"
+#include "esp32s3_gpio.h"
+#include "esp32s3_dma.h"
+#include "esp32s3_irq.h"
+#include "esp32s3_periph.h"
+
+#include "xtensa.h"
+#include "hardware/esp32s3_system.h"
+#include "hardware/esp32s3_gpio_sigmap.h"
+#include "hardware/esp32s3_lcd_cam.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Configuration ************************************************************/
+
+/* LCD RGB Mapping */
+
+#ifdef CONFIG_FB_CMAP
+# error "RGB color mapping not supported by this driver"
+#endif
+
+/* Cursor Controls */
+
+#ifdef CONFIG_FB_HWCURSOR
+# error "Cursor control not supported by this driver"
+#endif
+
+#ifdef CONFIG_ESP32S3_LCD_DATA_16BIT
+# define ESP32S3_LCD_DATA_WIDTH 2
+# define ESP32S3_LCD_DATA_BPP 16
+#else
+# error "Configure LCD data width is not supported"
+#endif
+
+#if CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240
+# if (CONFIG_ESP32S3_LCD_CLOCK_MHZ % 3) == 0
+ /* Use PLL=240MHz as clock resource */
+# define ESP32S3_LCD_CLK_SEL 2
+# define ESP32S3_LCD_CLK_MHZ 240
+# else
+ /* Use PLL=160MHz as clock resource */
+# define ESP32S3_LCD_CLK_SEL 3
+# define ESP32S3_LCD_CLK_MHZ 160
+# endif
+#else
+ /* Use PLL=160MHz as clock resource */
+# define ESP32S3_LCD_CLK_SEL 3
+# define ESP32S3_LCD_CLK_MHZ 160
+#endif
+
+/* Total Pins */
+
+#define ESP32S3_LCD_PINS 20
+
+/* LCD configuration parameters */
+
+#define ESP32S3_LCD_CLK_N (ESP32S3_LCD_CLK_MHZ / \
+ CONFIG_ESP32S3_LCD_CLOCK_MHZ)
+#define ESP32S3_LCD_CLK_RES (ESP32S3_LCD_CLK_MHZ % \
+ CONFIG_ESP32S3_LCD_CLOCK_MHZ)
+
+#define ESP32S3_LCD_VT_HIGHT (CONFIG_ESP32S3_LCD_VRES + \
+ CONFIG_ESP32S3_LCD_VBACKPORCH + \
+ CONFIG_ESP32S3_LCD_VFRONTPORCH + \
+ CONFIG_ESP32S3_LCD_VPULSEWIDTH - 1)
+
+#define ESP32S3_LCD_HT_WIDTH (CONFIG_ESP32S3_LCD_HRES + \
+ CONFIG_ESP32S3_LCD_HBACKPORCH + \
+ CONFIG_ESP32S3_LCD_HFRONTPORCH + \
+ CONFIG_ESP32S3_LCD_HPULSEWIDTH - 1)
+
+#define ESP32S3_LCD_VA_HIGHT (CONFIG_ESP32S3_LCD_VRES - 1)
+
+#define ESP32S3_LCD_HA_WIDTH (CONFIG_ESP32S3_LCD_HRES - 1)
+
+#define ESP32S3_LCD_VA_FRONT (CONFIG_ESP32S3_LCD_VBACKPORCH + \
+ CONFIG_ESP32S3_LCD_VPULSEWIDTH - 1)
+
+#define ESP32S3_LCD_HB_FRONT (CONFIG_ESP32S3_LCD_HBACKPORCH + \
+ CONFIG_ESP32S3_LCD_HPULSEWIDTH -1)
+
+#define ESP32S3_LCD_HSYNC_WIDTH (CONFIG_ESP32S3_LCD_HPULSEWIDTH - 1)
+
+#define ESP32S3_LCD_VSYNC_WIDTH (CONFIG_ESP32S3_LCD_VPULSEWIDTH - 1)
+
+#define ESP32S3_LCD_COLOR_FMT (FB_FMT_RGB16_565)
+#define ESP32S3_LCD_STRIDE (CONFIG_ESP32S3_LCD_HRES * \
+ ESP32S3_LCD_DATA_WIDTH)
+
+/* Display memory buffer and DMA */
+
+#define ESP32S3_LCD_FB_SIZE (CONFIG_ESP32S3_LCD_HRES * \
+ CONFIG_ESP32S3_LCD_VRES * \
+ ESP32S3_LCD_DATA_WIDTH)
+
+#define ESP32S3_LCD_DMADESC_NUM (ESP32S3_LCD_FB_SIZE / \
+ ESP32S3_DMA_DATALEN_MAX + 1)
+
+#define ESP32S3_LCD_LAYERS CONFIG_ESP32S3_LCD_BUFFER_LAYERS
+
+/* Get current layer pointer */
+
+#define CURRENT_LAYER(p) (&((p)->layer[(p)->cur_layer]))
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Pin Configuration */
+
+struct pin_config_s
+{
+ uint8_t num;
+ uint8_t signal;
+};
+
+/* Hardware Configuration */
+
+struct esp32s3_lcd_config_s
+{
+ struct pin_config_s pins_config[ESP32S3_LCD_PINS];
+};
+
+/* LCD General Layer information */
+
+struct esp32s3_layer_s
+{
+ /* DMA descriptor(s) */
+
+ struct esp32s3_dmadesc_s dmadesc[ESP32S3_LCD_DMADESC_NUM];
+
+ /* DMA framebuffer memory */
+
+ uint8_t *framebuffer;
+};
+
+/* This structure provides the overall state of the LCD */
+
+struct esp32s3_lcd_s
+{
+ int ref;
+
+ /* Layer information */
+
+ struct esp32s3_layer_s layer[ESP32S3_LCD_LAYERS];
+
+ uint8_t cur_layer; /* Current layer number */
+
+ int cpuint; /* CPU interrupt assigned to this LCD */
+ uint8_t cpu; /* CPU ID */
+ int32_t dma_channel; /* DMA channel */
+
+ spinlock_t lock; /* Device specific lock. */
+
+ /* Debug stuff */
+
+#ifdef CONFIG_ESP32S3_LCD_REGDEBUG
+ bool wrlast; /* True: Last access was a write */
+ uintptr_t addrlast; /* Last address accessed */
+ uint32_t vallast; /* Last value read or written */
+ int ntimes; /* Number of consecutive accesses */
+#endif
+};
+
+/****************************************************************************
+ * External Functions
+ ****************************************************************************/
+
+extern void esp_rom_delay_us(uint32_t us);
+extern void cache_writeback_addr(void *addr_ptr, uint32_t size);
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Register operations ******************************************************/
+
+#ifdef CONFIG_ESP32S3_LCD_REGDEBUG
+static bool esp32s3_lcd_checkreg(bool wr,
+ uint32_t regval,
+ uintptr_t address);
+static uint32_t esp32s3_lcd_getreg(uintptr_t addr);
+static void esp32s3_lcd_putreg(uintptr_t addr, uint32_t val);
+#else
+# define esp32s3_lcd_getreg(addr) getreg32(addr)
+# define esp32s3_lcd_putreg(addr,val) putreg32(val,addr)
+#endif
+
+/* Frame buffer interface ***************************************************/
+
+/* Get information about the video controller configuration and the
+ * configuration of each color plane.
+ */
+
+static int esp32s3_lcd_base_getvideoinfo(struct fb_vtable_s *vtable,
+ struct fb_videoinfo_s *vinfo);
+static int esp32s3_lcd_base_getplaneinfo(struct fb_vtable_s *vtable,
+ int planeno,
+ struct fb_planeinfo_s *pinfo);
+#ifdef CONFIG_FB_UPDATE
+static int esp32s3_lcd_base_updatearea(struct fb_vtable_s *vtable,
+ const struct fb_area_s *area);
+#endif
+
+/* Initialization ***********************************************************/
+
+static void esp32s3_lcd_dmasetup(void);
+static void esp32s3_lcd_gpio_config(void);
+static void esp32s3_lcd_disable(void);
+static void esp32s3_lcd_enable(void);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* This structure describes LCD controller configuration */
+
+static const struct esp32s3_lcd_config_s g_lcd_config =
+{
+ .pins_config =
+ {
+ { CONFIG_ESP32S3_LCD_PCLK_PIN, LCD_PCLK_IDX },
+ { CONFIG_ESP32S3_LCD_VSYNC_PIN, LCD_V_SYNC_IDX },
+ { CONFIG_ESP32S3_LCD_HSYNC_PIN, LCD_H_SYNC_IDX },
+ { CONFIG_ESP32S3_LCD_HE_PIN, LCD_H_ENABLE_IDX },
+ { CONFIG_ESP32S3_LCD_DATA0_PIN, LCD_DATA_OUT0_IDX },
+ { CONFIG_ESP32S3_LCD_DATA1_PIN, LCD_DATA_OUT1_IDX },
+ { CONFIG_ESP32S3_LCD_DATA2_PIN, LCD_DATA_OUT2_IDX },
+ { CONFIG_ESP32S3_LCD_DATA3_PIN, LCD_DATA_OUT3_IDX },
+ { CONFIG_ESP32S3_LCD_DATA4_PIN, LCD_DATA_OUT4_IDX },
+ { CONFIG_ESP32S3_LCD_DATA5_PIN, LCD_DATA_OUT5_IDX },
+ { CONFIG_ESP32S3_LCD_DATA6_PIN, LCD_DATA_OUT6_IDX },
+ { CONFIG_ESP32S3_LCD_DATA7_PIN, LCD_DATA_OUT7_IDX },
+ { CONFIG_ESP32S3_LCD_DATA8_PIN, LCD_DATA_OUT8_IDX },
+ { CONFIG_ESP32S3_LCD_DATA9_PIN, LCD_DATA_OUT9_IDX },
+ { CONFIG_ESP32S3_LCD_DATA10_PIN, LCD_DATA_OUT10_IDX },
+ { CONFIG_ESP32S3_LCD_DATA11_PIN, LCD_DATA_OUT11_IDX },
+ { CONFIG_ESP32S3_LCD_DATA12_PIN, LCD_DATA_OUT12_IDX },
+ { CONFIG_ESP32S3_LCD_DATA13_PIN, LCD_DATA_OUT13_IDX },
+ { CONFIG_ESP32S3_LCD_DATA14_PIN, LCD_DATA_OUT14_IDX },
+ { CONFIG_ESP32S3_LCD_DATA15_PIN, LCD_DATA_OUT15_IDX }
+ }
+};
+
+/* This structure provides the overall state of the LCD */
+
+static struct esp32s3_lcd_s g_lcd_priv;
+
+/* This structure describes the simulated video controller */
+
+static const struct fb_videoinfo_s g_base_videoinfo =
+{
+ .fmt = ESP32S3_LCD_COLOR_FMT,
+ .xres = CONFIG_ESP32S3_LCD_VRES,
+ .yres = CONFIG_ESP32S3_LCD_HRES,
+ .nplanes = 1
+};
+
+/* This structure provides the base layer interface */
+
+static const struct fb_vtable_s g_base_vtable =
+{
+ .getvideoinfo = esp32s3_lcd_base_getvideoinfo,
+ .getplaneinfo = esp32s3_lcd_base_getplaneinfo,
+#ifdef CONFIG_FB_UPDATE
+ .updatearea = esp32s3_lcd_base_updatearea,
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: max_common_divisor
+ *
+ * Description:
+ * Calculate maxium common divisor.
+ *
+ * Input Parameters:
+ * a - Calculation parameter a
+ * b - Calculation parameter b
+ *
+ * Returned Value:
+ * Maxium common divisor.
+ *
+ ****************************************************************************/
+
+static inline uint32_t max_common_divisor(uint32_t a, uint32_t b)
+{
+ uint32_t c = a % b;
+
+ while (c)
+ {
+ a = b;
+ b = c;
+ c = a % b;
+ }
+
+ return b;
+}
+
+/****************************************************************************
+ * Name: esp32s3_lcd_checkreg
+ *
+ * Description:
+ * Check if the current register access is a duplicate of the preceding.
+ *
+ * Input Parameters:
+ * wr - true: write operation; false: read operation
+ * regval - The value to be written
+ * address - The address of the register to write to
+ *
+ * Returned Value:
+ * true: This is the first register access of this type.
+ * flase: This is the same as the preceding register access.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32S3_LCD_REGDEBUG
+static bool esp32s3_lcd_checkreg(bool wr,
+ uint32_t regval,
+ uintptr_t address)
+{
+ struct esp32s3_lcd_s *priv = &g_lcd_priv;
+
+ if (wr == priv->wrlast && /* Same kind of access? */
+ regval == priv->vallast && /* Same value? */
+ address == priv->addrlast) /* Same address? */
+ {
+ /* Yes, then just keep a count of the number of times we did this. */
+
+ priv->ntimes++;
+ return false;
+ }
+ else
+ {
+ /* Did we do the previous operation more than once? */
+
+ if (priv->ntimes > 0)
+ {
+ /* Yes... show how many times we did it */
+
+ lcdinfo("...[Repeats %d times]...\n", priv->ntimes);
+ }
+
+ /* Save information about the new access */
+
+ priv->wrlast = wr;
+ priv->vallast = regval;
+ priv->addrlast = address;
+ priv->ntimes = 0;
+ }
+
+ /* Return true if this is the first time that we have done this operation */
+
+ return true;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32s3_lcd_getreg
+ *
+ * Description:
+ * Read any 32-bit register using an absolute
+ *
+ * Input Parameters:
+ * address - Regster address
+ *
+ * Returned Value:
+ * Regster value.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32S3_LCD_REGDEBUG
+static uint32_t esp32s3_lcd_getreg(uintptr_t address)
+{
+ uint32_t regval = getreg32(address);
+
+ if (esp32s3_lcd_checkreg(false, regval, address))
+ {
+ lcdinfo("%" PRIx32 " ->%" PRIx32 "\n", address, regval);
+ }
+
+ return regval;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32s3_lcd_putreg
+ *
+ * Description:
+ * Write to any 32-bit register using an absolute address
+ *
+ * Input Parameters:
+ * address - Regster address
+ * regval - Regster value
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32S3_LCD_REGDEBUG
+static void esp32s3_lcd_putreg(uintptr_t address, uint32_t regval)
+{
+ if (esp32s3_lcd_checkreg(true, regval, address))
+ {
+ lcdinfo("%" PRIx32 " <-%" PRIx32 "\n", address, regval);
+ }
+
+ putreg32(regval, address);
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32s3_lcd_base_getvideoinfo
+ *
+ * Description:
+ * Entrypoint ioctl FBIOGET_VIDEOINFO
+ * Get the videoinfo for the framebuffer
+ *
+ * Input Parameters:
+ * vtable - The framebuffer driver object
+ * vinfo - The videoinfo object
+ *
+ * Returned Value:
+ * Zero is returned on success; a negated errno value is returned on any
+ * failure.
+ *
+ ****************************************************************************/
+
+static int esp32s3_lcd_base_getvideoinfo(struct fb_vtable_s *vtable,
+ struct fb_videoinfo_s *vinfo)
+{
+ lcdinfo("vtable=%p vinfo=%p\n", vtable, vinfo);
+ if (vtable && vinfo)
+ {
+ memcpy(vinfo, &g_base_videoinfo, sizeof(struct fb_videoinfo_s));
+ return OK;
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: esp32s3_lcd_base_getplaneinfo
+ *
+ * Description:
+ * Entrypoint ioctl FBIOGET_PLANEINFO
+ * Get the planeinfo for the framebuffer
+ *
+ * Input Parameters:
+ * vtable - The framebuffer driver object
+ * pinfo - the planeinfo object
+ *
+ * Returned Value:
+ * Zero is returned on success; a negated errno value is returned on any
+ * failure.
+ *
+ ****************************************************************************/
+
+static int esp32s3_lcd_base_getplaneinfo(struct fb_vtable_s *vtable,
+ int planeno,
+ struct fb_planeinfo_s *pinfo)
+{
+ lcdinfo("vtable=%p planeno=%d pinfo=%p\n", vtable, planeno, pinfo);
+ if (vtable && planeno == 0 && pinfo)
+ {
+ struct esp32s3_lcd_s *priv = &g_lcd_priv;
+ struct esp32s3_layer_s *layer = CURRENT_LAYER(priv);
+
+ pinfo->display = 0;
+ pinfo->fbmem = (void *)layer->framebuffer;
+ pinfo->fblen = ESP32S3_LCD_FB_SIZE;
+ pinfo->stride = ESP32S3_LCD_STRIDE;
+ pinfo->bpp = ESP32S3_LCD_DATA_BPP;
+ return OK;
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: esp32s3_lcd_base_updatearea
+ *
+ * Description:
+ * Flush data from cache to PSRAM so that LCD DMA can access it.
+ *
+ * Input Parameters:
+ * vtable - The framebuffer driver object
+ * area - Reference to the overlay area
+ *
+ * Returned Value:
+ * Zero is returned on success; a negated errno value is returned on any
+ * failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_FB_UPDATE
+static int esp32s3_lcd_base_updatearea(struct fb_vtable_s *vtable,
+ const struct fb_area_s *area)
+{
+ struct esp32s3_lcd_s *priv = &g_lcd_priv;
+
+ cache_writeback_addr(CURRENT_LAYER(priv)->framebuffer,
+ ESP32S3_LCD_FB_SIZE);
+
+ return 0;
+}
+#endif
+
+/****************************************************************************
+ * Name: lcd_interrupt
+ *
+ * Description:
+ * Start sending next frame to LCD.
+ *
+ * Input Parameters:
+ * irq - The IRQ number of the interrupt.
+ * context - The register state save array at the time of the interrupt.
+ * arg - Not used
+ *
+ * Returned Value:
+ * Zero on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int IRAM_ATTR lcd_interrupt(int irq, void *context, void *arg)
+{
+ uint32_t regval;
+ struct esp32s3_lcd_s *priv = &g_lcd_priv;
+ uint32_t status = esp32s3_lcd_getreg(LCD_CAM_LC_DMA_INT_ST_REG);
+
+ esp32s3_lcd_putreg(LCD_CAM_LC_DMA_INT_CLR_REG, status);
+ if (status & LCD_CAM_LCD_VSYNC_INT_ST_M)
+ {
+ /* Stop TX */
+
+ regval = esp32s3_lcd_getreg(LCD_CAM_LCD_USER_REG);
+ regval &= ~LCD_CAM_LCD_START_M;
+ esp32s3_lcd_putreg(LCD_CAM_LCD_USER_REG, regval);
+
+ regval = esp32s3_lcd_getreg(LCD_CAM_LCD_USER_REG);
+ regval |= LCD_CAM_LCD_UPDATE_REG_M;
+ esp32s3_lcd_putreg(LCD_CAM_LCD_USER_REG, regval);
+
+ /* Clear TX fifo */
+
+ regval = esp32s3_lcd_getreg(LCD_CAM_LCD_MISC_REG);
+ regval |= LCD_CAM_LCD_AFIFO_RESET_M;
+ esp32s3_lcd_putreg(LCD_CAM_LCD_MISC_REG, regval);
+
+#if ESP32S3_LCD_LAYERS > 1
+ priv->cur_layer = (priv->cur_layer + 1) % ESP32S3_LCD_LAYERS;
+
+ esp32s3_dma_load(CURRENT_LAYER(priv)->dmadesc,
+ priv->dma_channel,
+ true);
+#endif
+
+#ifndef CONFIG_FB_UPDATE
+ /* Write framebuffer data from D-cache to PSRAM */
+
+ cache_writeback_addr(CURRENT_LAYER(priv)->framebuffer,
+ ESP32S3_LCD_FB_SIZE);
+#endif
+
+ /* Enable DMA TX */
+
+ esp32s3_dma_enable(priv->dma_channel, true);
+
+ /* Update LCD parameters and start TX */
+
+ regval = esp32s3_lcd_getreg(LCD_CAM_LCD_USER_REG);
+ regval |= LCD_CAM_LCD_UPDATE_REG_M;
+ esp32s3_lcd_putreg(LCD_CAM_LCD_USER_REG, regval);
+
+ regval = esp32s3_lcd_getreg(LCD_CAM_LCD_USER_REG);
+ regval |= LCD_CAM_LCD_START_M;
+ esp32s3_lcd_putreg(LCD_CAM_LCD_USER_REG, regval);
+ }
+
+ return 0;
+}
+
+/****************************************************************************
+ * Name: esp32s3_lcd_dmasetup
+ *
+ * Description:
+ * Configure the channel DMA
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void esp32s3_lcd_dmasetup(void)
+{
+ struct esp32s3_lcd_s *priv = &g_lcd_priv;
+
+ esp32s3_dma_init();
+
+ priv->dma_channel = esp32s3_dma_request(ESP32S3_DMA_PERIPH_LCDCAM,
+ 10, 1, true);
+ DEBUGASSERT(priv->dma_channel >= 0);
+ esp32s3_dma_set_ext_memblk(priv->dma_channel,
+ true,
+ ESP32S3_DMA_EXT_MEMBLK_64B);
+
+ for (int i = 0; i < ESP32S3_LCD_LAYERS; i++)
+ {
+ struct esp32s3_layer_s *layer = &priv->layer[i];
+
+ layer->framebuffer = memalign(64, ESP32S3_LCD_FB_SIZE);
+ DEBUGASSERT(layer->framebuffer != NULL);
+ memset(layer->framebuffer, 0, ESP32S3_LCD_FB_SIZE);
+
+ esp32s3_dma_setup(layer->dmadesc,
+ ESP32S3_LCD_DMADESC_NUM,
+ layer->framebuffer,
+ ESP32S3_LCD_FB_SIZE,
+ true);
+ }
+}
+
+/****************************************************************************
+ * Name: esp32s3_lcd_gpio_config
+ *
+ * Description:
+ * Configure GPIO pins for use with the LCD
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void esp32s3_lcd_gpio_config(void)
+{
+ const struct esp32s3_lcd_config_s *config = &g_lcd_config;
+
+ lcdinfo("Configuring pins\n");
+
+ /* Configure each pin */
+
+ for (int i = 0; i < ESP32S3_LCD_PINS; i++)
+ {
+ const struct pin_config_s *pins_config = &config->pins_config[i];
+
+ esp32s3_configgpio(pins_config->num, OUTPUT);
+ esp32s3_gpio_matrix_out(pins_config->num, pins_config->signal, 0, 0);
+ }
+}
+
+/****************************************************************************
+ * Name: esp32s3_lcd_enableclk
+ *
+ * Description:
+ * Enable LCD clock
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void esp32s3_lcd_enableclk(void)
+{
+ uint32_t regval;
+ uint32_t clk_a;
+ uint32_t clk_b;
+
+#if ESP32S3_LCD_CLK_RES != 0
+ uint32_t divisor = max_common_divisor(ESP32S3_LCD_CLK_RES,
+ CONFIG_ESP32S3_LCD_CLOCK_MHZ);
+ clk_b = ESP32S3_LCD_CLK_RES / divisor;
+ clk_a = CONFIG_ESP32S3_LCD_CLOCK_MHZ / divisor;
+
+ lcdinfo("divisor=%d\n", divisor);
+#else
+ clk_b = clk_a = 0;
+#endif
+
+ lcdinfo("PCLK=%d/(%d + %d/%d)\n", ESP32S3_LCD_CLK_MHZ,
+ ESP32S3_LCD_CLK_N, clk_b, clk_a);
+
+ esp32s3_periph_module_enable(PERIPH_LCD_CAM_MODULE);
+
+ regval = (1 << LCD_CAM_LCD_CLKCNT_N_S) |
+ LCD_CAM_CLK_EN_M |
+ LCD_CAM_LCD_CLK_EQU_SYSCLK_M |
+ (ESP32S3_LCD_CLK_SEL << LCD_CAM_LCD_CLK_SEL_S) |
+ (ESP32S3_LCD_CLK_N << LCD_CAM_LCD_CLKM_DIV_NUM_S) |
+ (clk_a << LCD_CAM_LCD_CLKM_DIV_A_S) |
+ (clk_b << LCD_CAM_LCD_CLKM_DIV_B_S);
+ esp32s3_lcd_putreg(LCD_CAM_LCD_CLOCK_REG, regval);
+}
+
+/****************************************************************************
+ * Name: esp32s3_lcd_config
+ *
+ * Description:
+ * Configure LCD controller.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void esp32s3_lcd_config(void)
+{
+ uint32_t regval;
+ irqstate_t flags;
+ struct esp32s3_lcd_s *priv = &g_lcd_priv;
+
+ /* Enable TX done interrupt */
+
+ regval = esp32s3_lcd_getreg(LCD_CAM_LC_DMA_INT_ENA_REG);
+ regval |= LCD_CAM_LCD_VSYNC_INT_ENA_M;
+ esp32s3_lcd_putreg(LCD_CAM_LC_DMA_INT_ENA_REG, regval);
+
+ /**
+ * Set LCD screem parameters:
+ * 1. RGB mode, ouput VSYNC/HSYNC/DE signal
+ * 2. VT height
+ * 3. VA height
+ * 4. HB front
+ * 5. HT width
+ * 6. HA width
+ * 7. VB front
+ * 8. VSYNC width
+ * 9. HSYNC width
+ */
+
+ regval = esp32s3_lcd_getreg(LCD_CAM_LCD_CTRL_REG);
+ regval |= LCD_CAM_LCD_RGB_MODE_EN_M |
+ (ESP32S3_LCD_VT_HIGHT << LCD_CAM_LCD_VT_HEIGHT_S) |
+ (ESP32S3_LCD_VA_HIGHT << LCD_CAM_LCD_VA_HEIGHT_S) |
+ (ESP32S3_LCD_HB_FRONT << LCD_CAM_LCD_HB_FRONT_S);
+ esp32s3_lcd_putreg(LCD_CAM_LCD_CTRL_REG, regval);
+
+ regval = (ESP32S3_LCD_HT_WIDTH << LCD_CAM_LCD_HT_WIDTH_S) |
+ (ESP32S3_LCD_HA_WIDTH << LCD_CAM_LCD_HA_WIDTH_S) |
+ (ESP32S3_LCD_VA_FRONT << LCD_CAM_LCD_VB_FRONT_S);
+ esp32s3_lcd_putreg(LCD_CAM_LCD_CTRL1_REG, regval);
+
+ regval = (ESP32S3_LCD_HSYNC_WIDTH << LCD_CAM_LCD_HSYNC_WIDTH_S) |
+ (ESP32S3_LCD_VSYNC_WIDTH << LCD_CAM_LCD_VSYNC_WIDTH_S) |
+ LCD_CAM_LCD_HSYNC_IDLE_POL_M |
+ LCD_CAM_LCD_HS_BLANK_EN_M |
+ LCD_CAM_LCD_VSYNC_IDLE_POL_M;
+ esp32s3_lcd_putreg(LCD_CAM_LCD_CTRL2_REG, regval);
+
+ /**
+ * Configure output mode:
+ * 1. always output
+ * 2. 16-bit word
+ * 3. LCD mode
+ * 4. 3-bit dummy
+ */
+
+ regval = LCD_CAM_LCD_ALWAYS_OUT_EN_M |
+ LCD_CAM_LCD_2BYTE_EN_M |
+ LCD_CAM_LCD_DOUT_M |
+ (3 << LCD_CAM_LCD_DUMMY_CYCLELEN_S);
+ esp32s3_lcd_putreg(LCD_CAM_LCD_USER_REG, regval);
+
+ regval = LCD_CAM_LCD_AFIFO_THRESHOLD_NUM_M |
+ LCD_CAM_LCD_BK_EN_M;
+ esp32s3_lcd_putreg(LCD_CAM_LCD_MISC_REG, regval);
+
+ /* Update registers */
+
+ regval = esp32s3_lcd_getreg(LCD_CAM_LCD_USER_REG);
+ regval |= LCD_CAM_LCD_UPDATE_REG_M;
+ esp32s3_lcd_putreg(LCD_CAM_LCD_USER_REG, regval);
+
+ /* Set GDMA */
+
+ esp32s3_lcd_dmasetup();
+
+ /* Configure interrupt */
+
+ regval = LCD_CAM_LCD_VSYNC_INT_ENA_M;
+ esp32s3_lcd_putreg(LCD_CAM_LC_DMA_INT_ENA_REG, regval);
+
+ flags = spin_lock_irqsave(&priv->lock);
+
+ priv->cpu = up_cpu_index();
+ priv->cpuint = esp32s3_setup_irq(priv->cpu,
+ ESP32S3_PERIPH_LCD_CAM,
+ ESP32S3_INT_PRIO_DEF,
+ ESP32S3_CPUINT_LEVEL);
+ DEBUGASSERT(priv->cpuint >= 0);
+
+ DEBUGASSERT(irq_attach(ESP32S3_IRQ_LCD_CAM, lcd_interrupt, priv) == 0);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ up_enable_irq(ESP32S3_IRQ_LCD_CAM);
+}
+
+/****************************************************************************
+ * Name: esp32s3_lcd_enable
+ *
+ * Description:
+ * Enable LCD display.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void esp32s3_lcd_enable(void)
+{
+ uint32_t regval;
+ struct esp32s3_lcd_s *priv = &g_lcd_priv;
+ struct esp32s3_layer_s *layer = CURRENT_LAYER(priv);
+
+ esp32s3_dma_load(layer->dmadesc, priv->dma_channel, true);
+ esp32s3_dma_enable(priv->dma_channel, true);
+
+ /* Delay 1 microsecond to wait the DMA start */
+
+ esp_rom_delay_us(1);
+
+ /* Update LCD parameters before start */
+
+ regval = esp32s3_lcd_getreg(LCD_CAM_LCD_USER_REG);
+ regval |= LCD_CAM_LCD_UPDATE_REG_M;
+ esp32s3_lcd_putreg(LCD_CAM_LCD_USER_REG, regval);
+
+ regval = esp32s3_lcd_getreg(LCD_CAM_LCD_USER_REG);
+ regval |= LCD_CAM_LCD_START_M;
+ esp32s3_lcd_putreg(LCD_CAM_LCD_USER_REG, regval);
+}
+
+/****************************************************************************
+ * Name: esp32s3_lcd_disable
+ *
+ * Description:
+ * Disable the LCD peripheral
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void esp32s3_lcd_disable(void)
+{
+ uint32_t regval;
+
+ regval = esp32s3_lcd_getreg(LCD_CAM_LCD_USER_REG);
+ regval &= ~LCD_CAM_LCD_START_M;
+ esp32s3_lcd_putreg(LCD_CAM_LCD_USER_REG, regval);
+
+ /* Update LCD parameters before start */
+
+ regval = esp32s3_lcd_getreg(LCD_CAM_LCD_USER_REG);
+ regval |= LCD_CAM_LCD_UPDATE_REG_M;
+ esp32s3_lcd_putreg(LCD_CAM_LCD_USER_REG, regval);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_fbinitialize
+ *
+ * Description:
+ * Initialize the framebuffer video hardware associated with the display.
+ *
+ * Input Parameters:
+ * display - In the case of hardware with multiple displays, this
+ * specifies the display. Normally this is zero.
+ *
+ * Returned Value:
+ * Zero is returned on success; a negated errno value is returned on any
+ * failure.
+ *
+ ****************************************************************************/
+
+int up_fbinitialize(int display)
+{
+ lcdinfo("Entry\n");
+
+ if (g_lcd_priv.ref++ != 0)
+ {
+ return 0;
+ }
+
+ DEBUGASSERT(display == 0);
+
+ /* Disable the LCD */
+
+ esp32s3_lcd_disable();
+
+ /* Configure GPIO pins */
+
+ esp32s3_lcd_gpio_config();
+
+ /* Enable the LCD peripheral clock */
+
+ esp32s3_lcd_enableclk();
+
+ /* Configure LCD controller */
+
+ esp32s3_lcd_config();
+
+ /* And turn the LCD on */
+
+ esp32s3_lcd_enable();
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: up_fbgetvplane
+ *
+ * Description:
+ * Return a a reference to the framebuffer object for the specified video
+ * plane of the specified plane. Many OSDs support multiple planes of
+ * video.
+ *
+ * Input Parameters:
+ * display - In the case of hardware with multiple displays, this
+ * specifies the display. Normally this is zero.
+ * vplane - Identifies the plane being queried.
+ *
+ * Returned Value:
+ * A non-NULL pointer to the frame buffer access structure is returned on
+ * success; NULL is returned on any failure.
+ *
+ ****************************************************************************/
+
+struct fb_vtable_s *up_fbgetvplane(int display, int vplane)
+{
+ DEBUGASSERT(display == 0);
+
+ lcdinfo("vplane: %d\n", vplane);
+ if (vplane == 0)
+ {
+ return (struct fb_vtable_s *)&g_base_vtable;
+ }
+ else
+ {
+ return NULL;
+ }
+}
diff --git a/arch/xtensa/src/esp32s3/hardware/esp32s3_lcd_cam.h
b/arch/xtensa/src/esp32s3/hardware/esp32s3_lcd_cam.h
new file mode 100644
index 0000000000..5865a42d18
--- /dev/null
+++ b/arch/xtensa/src/esp32s3/hardware/esp32s3_lcd_cam.h
@@ -0,0 +1,1349 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32s3/hardware/esp32s3_lcd_cam.h
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_XTENSA_SRC_ESP32S3_HARDWARE_ESP32S3_LCD_CAM_H
+#define __ARCH_XTENSA_SRC_ESP32S3_HARDWARE_ESP32S3_LCD_CAM_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "esp32s3_soc.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* LCD_CAM_LCD_CLOCK_REG register
+ * LCD clock register
+ */
+
+#define LCD_CAM_LCD_CLOCK_REG (DR_REG_LCD_CAM_BASE + 0x0)
+
+/* LCD_CAM_CLK_EN : R/W; bitpos: [31]; default: 0;
+ * Set this bit to enable clk gate
+ */
+
+#define LCD_CAM_CLK_EN (BIT(31))
+#define LCD_CAM_CLK_EN_M (LCD_CAM_CLK_EN_V << LCD_CAM_CLK_EN_S)
+#define LCD_CAM_CLK_EN_V 0x00000001
+#define LCD_CAM_CLK_EN_S 31
+
+/* LCD_CAM_LCD_CLK_SEL : R/W; bitpos: [30:29]; default: 0;
+ * Select LCD module source clock. 0: no clock. 1: APLL. 2: CLK160. 3: no
+ * clock.
+ */
+
+#define LCD_CAM_LCD_CLK_SEL 0x00000003
+#define LCD_CAM_LCD_CLK_SEL_M (LCD_CAM_LCD_CLK_SEL_V << LCD_CAM_LCD_CLK_SEL_S)
+#define LCD_CAM_LCD_CLK_SEL_V 0x00000003
+#define LCD_CAM_LCD_CLK_SEL_S 29
+
+/* LCD_CAM_LCD_CLKM_DIV_A : R/W; bitpos: [28:23]; default: 0;
+ * Fractional clock divider denominator value
+ */
+
+#define LCD_CAM_LCD_CLKM_DIV_A 0x0000003f
+#define LCD_CAM_LCD_CLKM_DIV_A_M (LCD_CAM_LCD_CLKM_DIV_A_V <<
LCD_CAM_LCD_CLKM_DIV_A_S)
+#define LCD_CAM_LCD_CLKM_DIV_A_V 0x0000003f
+#define LCD_CAM_LCD_CLKM_DIV_A_S 23
+
+/* LCD_CAM_LCD_CLKM_DIV_B : R/W; bitpos: [22:17]; default: 0;
+ * Fractional clock divider numerator value
+ */
+
+#define LCD_CAM_LCD_CLKM_DIV_B 0x0000003f
+#define LCD_CAM_LCD_CLKM_DIV_B_M (LCD_CAM_LCD_CLKM_DIV_B_V <<
LCD_CAM_LCD_CLKM_DIV_B_S)
+#define LCD_CAM_LCD_CLKM_DIV_B_V 0x0000003f
+#define LCD_CAM_LCD_CLKM_DIV_B_S 17
+
+/* LCD_CAM_LCD_CLKM_DIV_NUM : R/W; bitpos: [16:9]; default: 4;
+ * Integral LCD clock divider value
+ */
+
+#define LCD_CAM_LCD_CLKM_DIV_NUM 0x000000ff
+#define LCD_CAM_LCD_CLKM_DIV_NUM_M (LCD_CAM_LCD_CLKM_DIV_NUM_V <<
LCD_CAM_LCD_CLKM_DIV_NUM_S)
+#define LCD_CAM_LCD_CLKM_DIV_NUM_V 0x000000ff
+#define LCD_CAM_LCD_CLKM_DIV_NUM_S 9
+
+/* LCD_CAM_LCD_CK_OUT_EDGE : R/W; bitpos: [8]; default: 0;
+ * 1: LCD_PCLK high in first half clock cycle. 0: LCD_PCLK low in first half
+ * clock cycle.
+ */
+
+#define LCD_CAM_LCD_CK_OUT_EDGE (BIT(8))
+#define LCD_CAM_LCD_CK_OUT_EDGE_M (LCD_CAM_LCD_CK_OUT_EDGE_V <<
LCD_CAM_LCD_CK_OUT_EDGE_S)
+#define LCD_CAM_LCD_CK_OUT_EDGE_V 0x00000001
+#define LCD_CAM_LCD_CK_OUT_EDGE_S 8
+
+/* LCD_CAM_LCD_CK_IDLE_EDGE : R/W; bitpos: [7]; default: 0;
+ * 1: LCD_PCLK line is high when idle 0: LCD_PCLK line is low when idle.
+ */
+
+#define LCD_CAM_LCD_CK_IDLE_EDGE (BIT(7))
+#define LCD_CAM_LCD_CK_IDLE_EDGE_M (LCD_CAM_LCD_CK_IDLE_EDGE_V <<
LCD_CAM_LCD_CK_IDLE_EDGE_S)
+#define LCD_CAM_LCD_CK_IDLE_EDGE_V 0x00000001
+#define LCD_CAM_LCD_CK_IDLE_EDGE_S 7
+
+/* LCD_CAM_LCD_CLK_EQU_SYSCLK : R/W; bitpos: [6]; default: 1;
+ * 1: f_LCD_PCLK = f_LCD_CLK. 0: f_LCD_PCLK = f_LCD_CLK / (reg_clkcnt_N + 1).
+ */
+
+#define LCD_CAM_LCD_CLK_EQU_SYSCLK (BIT(6))
+#define LCD_CAM_LCD_CLK_EQU_SYSCLK_M (LCD_CAM_LCD_CLK_EQU_SYSCLK_V <<
LCD_CAM_LCD_CLK_EQU_SYSCLK_S)
+#define LCD_CAM_LCD_CLK_EQU_SYSCLK_V 0x00000001
+#define LCD_CAM_LCD_CLK_EQU_SYSCLK_S 6
+
+/* LCD_CAM_LCD_CLKCNT_N : R/W; bitpos: [5:0]; default: 3;
+ * f_LCD_PCLK = f_LCD_CLK / (reg_clkcnt_N + 1) when reg_clk_equ_sysclk is 0.
+ */
+
+#define LCD_CAM_LCD_CLKCNT_N 0x0000003f
+#define LCD_CAM_LCD_CLKCNT_N_M (LCD_CAM_LCD_CLKCNT_N_V <<
LCD_CAM_LCD_CLKCNT_N_S)
+#define LCD_CAM_LCD_CLKCNT_N_V 0x0000003f
+#define LCD_CAM_LCD_CLKCNT_N_S 0
+
+/* LCD_CAM_CAM_CTRL_REG register
+ * Camera configuration register
+ */
+
+#define LCD_CAM_CAM_CTRL_REG (DR_REG_LCD_CAM_BASE + 0x4)
+
+/* LCD_CAM_CAM_CLK_SEL : R/W; bitpos: [30:29]; default: 0;
+ * Select Camera module source clock. 0: no clock. 1: APLL. 2: CLK160. 3: no
+ * clock.
+ */
+
+#define LCD_CAM_CAM_CLK_SEL 0x00000003
+#define LCD_CAM_CAM_CLK_SEL_M (LCD_CAM_CAM_CLK_SEL_V << LCD_CAM_CAM_CLK_SEL_S)
+#define LCD_CAM_CAM_CLK_SEL_V 0x00000003
+#define LCD_CAM_CAM_CLK_SEL_S 29
+
+/* LCD_CAM_CAM_CLKM_DIV_A : R/W; bitpos: [28:23]; default: 0;
+ * Fractional clock divider denominator value
+ */
+
+#define LCD_CAM_CAM_CLKM_DIV_A 0x0000003f
+#define LCD_CAM_CAM_CLKM_DIV_A_M (LCD_CAM_CAM_CLKM_DIV_A_V <<
LCD_CAM_CAM_CLKM_DIV_A_S)
+#define LCD_CAM_CAM_CLKM_DIV_A_V 0x0000003f
+#define LCD_CAM_CAM_CLKM_DIV_A_S 23
+
+/* LCD_CAM_CAM_CLKM_DIV_B : R/W; bitpos: [22:17]; default: 0;
+ * Fractional clock divider numerator value
+ */
+
+#define LCD_CAM_CAM_CLKM_DIV_B 0x0000003f
+#define LCD_CAM_CAM_CLKM_DIV_B_M (LCD_CAM_CAM_CLKM_DIV_B_V <<
LCD_CAM_CAM_CLKM_DIV_B_S)
+#define LCD_CAM_CAM_CLKM_DIV_B_V 0x0000003f
+#define LCD_CAM_CAM_CLKM_DIV_B_S 17
+
+/* LCD_CAM_CAM_CLKM_DIV_NUM : R/W; bitpos: [16:9]; default: 4;
+ * Integral Camera clock divider value
+ */
+
+#define LCD_CAM_CAM_CLKM_DIV_NUM 0x000000ff
+#define LCD_CAM_CAM_CLKM_DIV_NUM_M (LCD_CAM_CAM_CLKM_DIV_NUM_V <<
LCD_CAM_CAM_CLKM_DIV_NUM_S)
+#define LCD_CAM_CAM_CLKM_DIV_NUM_V 0x000000ff
+#define LCD_CAM_CAM_CLKM_DIV_NUM_S 9
+
+/* LCD_CAM_CAM_VS_EOF_EN : R/W; bitpos: [8]; default: 0;
+ * 1: CAM_VSYNC to generate in_suc_eof. 0: in_suc_eof is controlled by
+ * reg_cam_rec_data_cyclelen.
+ */
+
+#define LCD_CAM_CAM_VS_EOF_EN (BIT(8))
+#define LCD_CAM_CAM_VS_EOF_EN_M (LCD_CAM_CAM_VS_EOF_EN_V <<
LCD_CAM_CAM_VS_EOF_EN_S)
+#define LCD_CAM_CAM_VS_EOF_EN_V 0x00000001
+#define LCD_CAM_CAM_VS_EOF_EN_S 8
+
+/* LCD_CAM_CAM_LINE_INT_EN : R/W; bitpos: [7]; default: 0;
+ * 1: Enable to generate CAM_HS_INT. 0: Disable.
+ */
+
+#define LCD_CAM_CAM_LINE_INT_EN (BIT(7))
+#define LCD_CAM_CAM_LINE_INT_EN_M (LCD_CAM_CAM_LINE_INT_EN_V <<
LCD_CAM_CAM_LINE_INT_EN_S)
+#define LCD_CAM_CAM_LINE_INT_EN_V 0x00000001
+#define LCD_CAM_CAM_LINE_INT_EN_S 7
+
+/* LCD_CAM_CAM_BIT_ORDER : R/W; bitpos: [6]; default: 0;
+ * 1: invert data byte order, only valid in 2 byte mode. 0: Not change.
+ */
+
+#define LCD_CAM_CAM_BIT_ORDER (BIT(6))
+#define LCD_CAM_CAM_BIT_ORDER_M (LCD_CAM_CAM_BIT_ORDER_V <<
LCD_CAM_CAM_BIT_ORDER_S)
+#define LCD_CAM_CAM_BIT_ORDER_V 0x00000001
+#define LCD_CAM_CAM_BIT_ORDER_S 6
+
+/* LCD_CAM_CAM_BYTE_ORDER : R/W; bitpos: [5]; default: 0;
+ * 1: Change data bit order, change CAM_DATA_in[7:0] to CAM_DATA_in[0:7] in
+ * one byte mode, and bits[15:0] to bits[0:15] in two byte mode. 0: Not
+ * change.
+ */
+
+#define LCD_CAM_CAM_BYTE_ORDER (BIT(5))
+#define LCD_CAM_CAM_BYTE_ORDER_M (LCD_CAM_CAM_BYTE_ORDER_V <<
LCD_CAM_CAM_BYTE_ORDER_S)
+#define LCD_CAM_CAM_BYTE_ORDER_V 0x00000001
+#define LCD_CAM_CAM_BYTE_ORDER_S 5
+
+/* LCD_CAM_CAM_UPDATE_REG : R/W; bitpos: [4]; default: 0;
+ * 1: Update Camera registers, will be cleared by hardware. 0 : Not care.
+ */
+
+#define LCD_CAM_CAM_UPDATE_REG (BIT(4))
+#define LCD_CAM_CAM_UPDATE_REG_M (LCD_CAM_CAM_UPDATE_REG_V <<
LCD_CAM_CAM_UPDATE_REG_S)
+#define LCD_CAM_CAM_UPDATE_REG_V 0x00000001
+#define LCD_CAM_CAM_UPDATE_REG_S 4
+
+/* LCD_CAM_CAM_VSYNC_FILTER_THRES : R/W; bitpos: [3:1]; default: 0;
+ * Filter threshold value for CAM_VSYNC signal.
+ */
+
+#define LCD_CAM_CAM_VSYNC_FILTER_THRES 0x00000007
+#define LCD_CAM_CAM_VSYNC_FILTER_THRES_M (LCD_CAM_CAM_VSYNC_FILTER_THRES_V <<
LCD_CAM_CAM_VSYNC_FILTER_THRES_S)
+#define LCD_CAM_CAM_VSYNC_FILTER_THRES_V 0x00000007
+#define LCD_CAM_CAM_VSYNC_FILTER_THRES_S 1
+
+/* LCD_CAM_CAM_STOP_EN : R/W; bitpos: [0]; default: 0;
+ * Camera stop enable signal, 1: camera stops when DMA Rx FIFO is full. 0:
+ * Not stop.
+ */
+
+#define LCD_CAM_CAM_STOP_EN (BIT(0))
+#define LCD_CAM_CAM_STOP_EN_M (LCD_CAM_CAM_STOP_EN_V << LCD_CAM_CAM_STOP_EN_S)
+#define LCD_CAM_CAM_STOP_EN_V 0x00000001
+#define LCD_CAM_CAM_STOP_EN_S 0
+
+/* LCD_CAM_CAM_CTRL1_REG register
+ * Camera configuration register
+ */
+
+#define LCD_CAM_CAM_CTRL1_REG (DR_REG_LCD_CAM_BASE + 0x8)
+
+/* LCD_CAM_CAM_AFIFO_RESET : WO; bitpos: [31]; default: 0;
+ * Camera AFIFO reset signal.
+ */
+
+#define LCD_CAM_CAM_AFIFO_RESET (BIT(31))
+#define LCD_CAM_CAM_AFIFO_RESET_M (LCD_CAM_CAM_AFIFO_RESET_V <<
LCD_CAM_CAM_AFIFO_RESET_S)
+#define LCD_CAM_CAM_AFIFO_RESET_V 0x00000001
+#define LCD_CAM_CAM_AFIFO_RESET_S 31
+
+/* LCD_CAM_CAM_RESET : WO; bitpos: [30]; default: 0;
+ * Camera module reset signal.
+ */
+
+#define LCD_CAM_CAM_RESET (BIT(30))
+#define LCD_CAM_CAM_RESET_M (LCD_CAM_CAM_RESET_V << LCD_CAM_CAM_RESET_S)
+#define LCD_CAM_CAM_RESET_V 0x00000001
+#define LCD_CAM_CAM_RESET_S 30
+
+/* LCD_CAM_CAM_START : R/W; bitpos: [29]; default: 0;
+ * Camera module start signal.
+ */
+
+#define LCD_CAM_CAM_START (BIT(29))
+#define LCD_CAM_CAM_START_M (LCD_CAM_CAM_START_V << LCD_CAM_CAM_START_S)
+#define LCD_CAM_CAM_START_V 0x00000001
+#define LCD_CAM_CAM_START_S 29
+
+/* LCD_CAM_CAM_VH_DE_MODE_EN : R/W; bitpos: [28]; default: 0;
+ * 1: Input control signals are CAM_DE CAM_HSYNC and CAM_VSYNC is 1. 0:
+ * Input control signals are CAM_DE and CAM_VSYNC. CAM_HSYNC and CAM_DE are
+ * all 1 the the same time.
+ */
+
+#define LCD_CAM_CAM_VH_DE_MODE_EN (BIT(28))
+#define LCD_CAM_CAM_VH_DE_MODE_EN_M (LCD_CAM_CAM_VH_DE_MODE_EN_V <<
LCD_CAM_CAM_VH_DE_MODE_EN_S)
+#define LCD_CAM_CAM_VH_DE_MODE_EN_V 0x00000001
+#define LCD_CAM_CAM_VH_DE_MODE_EN_S 28
+
+/* LCD_CAM_CAM_VSYNC_INV : R/W; bitpos: [27]; default: 0;
+ * CAM_VSYNC invert enable signal, valid in high level.
+ */
+
+#define LCD_CAM_CAM_VSYNC_INV (BIT(27))
+#define LCD_CAM_CAM_VSYNC_INV_M (LCD_CAM_CAM_VSYNC_INV_V <<
LCD_CAM_CAM_VSYNC_INV_S)
+#define LCD_CAM_CAM_VSYNC_INV_V 0x00000001
+#define LCD_CAM_CAM_VSYNC_INV_S 27
+
+/* LCD_CAM_CAM_HSYNC_INV : R/W; bitpos: [26]; default: 0;
+ * CAM_HSYNC invert enable signal, valid in high level.
+ */
+
+#define LCD_CAM_CAM_HSYNC_INV (BIT(26))
+#define LCD_CAM_CAM_HSYNC_INV_M (LCD_CAM_CAM_HSYNC_INV_V <<
LCD_CAM_CAM_HSYNC_INV_S)
+#define LCD_CAM_CAM_HSYNC_INV_V 0x00000001
+#define LCD_CAM_CAM_HSYNC_INV_S 26
+
+/* LCD_CAM_CAM_DE_INV : R/W; bitpos: [25]; default: 0;
+ * CAM_DE invert enable signal, valid in high level.
+ */
+
+#define LCD_CAM_CAM_DE_INV (BIT(25))
+#define LCD_CAM_CAM_DE_INV_M (LCD_CAM_CAM_DE_INV_V << LCD_CAM_CAM_DE_INV_S)
+#define LCD_CAM_CAM_DE_INV_V 0x00000001
+#define LCD_CAM_CAM_DE_INV_S 25
+
+/* LCD_CAM_CAM_2BYTE_EN : R/W; bitpos: [24]; default: 0;
+ * 1: The bit number of input data is 9~16. 0: The bit number of input data
+ * is 0~8.
+ */
+
+#define LCD_CAM_CAM_2BYTE_EN (BIT(24))
+#define LCD_CAM_CAM_2BYTE_EN_M (LCD_CAM_CAM_2BYTE_EN_V <<
LCD_CAM_CAM_2BYTE_EN_S)
+#define LCD_CAM_CAM_2BYTE_EN_V 0x00000001
+#define LCD_CAM_CAM_2BYTE_EN_S 24
+
+/* LCD_CAM_CAM_VSYNC_FILTER_EN : R/W; bitpos: [23]; default: 0;
+ * 1: Enable CAM_VSYNC filter function. 0: bypass.
+ */
+
+#define LCD_CAM_CAM_VSYNC_FILTER_EN (BIT(23))
+#define LCD_CAM_CAM_VSYNC_FILTER_EN_M (LCD_CAM_CAM_VSYNC_FILTER_EN_V <<
LCD_CAM_CAM_VSYNC_FILTER_EN_S)
+#define LCD_CAM_CAM_VSYNC_FILTER_EN_V 0x00000001
+#define LCD_CAM_CAM_VSYNC_FILTER_EN_S 23
+
+/* LCD_CAM_CAM_CLK_INV : R/W; bitpos: [22]; default: 0;
+ * 1: Invert the input signal CAM_PCLK. 0: Not invert.
+ */
+
+#define LCD_CAM_CAM_CLK_INV (BIT(22))
+#define LCD_CAM_CAM_CLK_INV_M (LCD_CAM_CAM_CLK_INV_V << LCD_CAM_CAM_CLK_INV_S)
+#define LCD_CAM_CAM_CLK_INV_V 0x00000001
+#define LCD_CAM_CAM_CLK_INV_S 22
+
+/* LCD_CAM_CAM_LINE_INT_NUM : R/W; bitpos: [21:16]; default: 0;
+ * The line number minus 1 to generate cam_hs_int.
+ */
+
+#define LCD_CAM_CAM_LINE_INT_NUM 0x0000003f
+#define LCD_CAM_CAM_LINE_INT_NUM_M (LCD_CAM_CAM_LINE_INT_NUM_V <<
LCD_CAM_CAM_LINE_INT_NUM_S)
+#define LCD_CAM_CAM_LINE_INT_NUM_V 0x0000003f
+#define LCD_CAM_CAM_LINE_INT_NUM_S 16
+
+/* LCD_CAM_CAM_REC_DATA_BYTELEN : R/W; bitpos: [15:0]; default: 0;
+ * Camera receive data byte length minus 1 to set DMA in_suc_eof_int.
+ */
+
+#define LCD_CAM_CAM_REC_DATA_BYTELEN 0x0000ffff
+#define LCD_CAM_CAM_REC_DATA_BYTELEN_M (LCD_CAM_CAM_REC_DATA_BYTELEN_V <<
LCD_CAM_CAM_REC_DATA_BYTELEN_S)
+#define LCD_CAM_CAM_REC_DATA_BYTELEN_V 0x0000ffff
+#define LCD_CAM_CAM_REC_DATA_BYTELEN_S 0
+
+/* LCD_CAM_CAM_RGB_YUV_REG register
+ * Camera configuration register
+ */
+
+#define LCD_CAM_CAM_RGB_YUV_REG (DR_REG_LCD_CAM_BASE + 0xc)
+
+/* LCD_CAM_CAM_CONV_BYPASS : R/W; bitpos: [31]; default: 0;
+ * 0: Bypass converter. 1: Enable converter.
+ */
+
+#define LCD_CAM_CAM_CONV_BYPASS (BIT(31))
+#define LCD_CAM_CAM_CONV_BYPASS_M (LCD_CAM_CAM_CONV_BYPASS_V <<
LCD_CAM_CAM_CONV_BYPASS_S)
+#define LCD_CAM_CAM_CONV_BYPASS_V 0x00000001
+#define LCD_CAM_CAM_CONV_BYPASS_S 31
+
+/* LCD_CAM_CAM_CONV_TRANS_MODE : R/W; bitpos: [30]; default: 0;
+ * 0: YUV to RGB. 1: RGB to YUV.
+ */
+
+#define LCD_CAM_CAM_CONV_TRANS_MODE (BIT(30))
+#define LCD_CAM_CAM_CONV_TRANS_MODE_M (LCD_CAM_CAM_CONV_TRANS_MODE_V <<
LCD_CAM_CAM_CONV_TRANS_MODE_S)
+#define LCD_CAM_CAM_CONV_TRANS_MODE_V 0x00000001
+#define LCD_CAM_CAM_CONV_TRANS_MODE_S 30
+
+/* LCD_CAM_CAM_CONV_MODE_8BITS_ON : R/W; bitpos: [29]; default: 0;
+ * 0: 16bits mode. 1: 8bits mode.
+ */
+
+#define LCD_CAM_CAM_CONV_MODE_8BITS_ON (BIT(29))
+#define LCD_CAM_CAM_CONV_MODE_8BITS_ON_M (LCD_CAM_CAM_CONV_MODE_8BITS_ON_V <<
LCD_CAM_CAM_CONV_MODE_8BITS_ON_S)
+#define LCD_CAM_CAM_CONV_MODE_8BITS_ON_V 0x00000001
+#define LCD_CAM_CAM_CONV_MODE_8BITS_ON_S 29
+
+/* LCD_CAM_CAM_CONV_DATA_IN_MODE : R/W; bitpos: [28]; default: 0;
+ * LIMIT or FULL mode of Data in. 0: limit. 1: full
+ */
+
+#define LCD_CAM_CAM_CONV_DATA_IN_MODE (BIT(28))
+#define LCD_CAM_CAM_CONV_DATA_IN_MODE_M (LCD_CAM_CAM_CONV_DATA_IN_MODE_V <<
LCD_CAM_CAM_CONV_DATA_IN_MODE_S)
+#define LCD_CAM_CAM_CONV_DATA_IN_MODE_V 0x00000001
+#define LCD_CAM_CAM_CONV_DATA_IN_MODE_S 28
+
+/* LCD_CAM_CAM_CONV_DATA_OUT_MODE : R/W; bitpos: [27]; default: 0;
+ * LIMIT or FULL mode of Data out. 0: limit. 1: full
+ */
+
+#define LCD_CAM_CAM_CONV_DATA_OUT_MODE (BIT(27))
+#define LCD_CAM_CAM_CONV_DATA_OUT_MODE_M (LCD_CAM_CAM_CONV_DATA_OUT_MODE_V <<
LCD_CAM_CAM_CONV_DATA_OUT_MODE_S)
+#define LCD_CAM_CAM_CONV_DATA_OUT_MODE_V 0x00000001
+#define LCD_CAM_CAM_CONV_DATA_OUT_MODE_S 27
+
+/* LCD_CAM_CAM_CONV_PROTOCOL_MODE : R/W; bitpos: [26]; default: 0;
+ * 0:BT601. 1:BT709.
+ */
+
+#define LCD_CAM_CAM_CONV_PROTOCOL_MODE (BIT(26))
+#define LCD_CAM_CAM_CONV_PROTOCOL_MODE_M (LCD_CAM_CAM_CONV_PROTOCOL_MODE_V <<
LCD_CAM_CAM_CONV_PROTOCOL_MODE_S)
+#define LCD_CAM_CAM_CONV_PROTOCOL_MODE_V 0x00000001
+#define LCD_CAM_CAM_CONV_PROTOCOL_MODE_S 26
+
+/* LCD_CAM_CAM_CONV_YUV_MODE : R/W; bitpos: [25:24]; default: 0;
+ * 0: yuv422. 1: yuv420. 2: yuv411. When in yuv2yuv mode, yuv_mode decides
+ * the yuv mode of Data_in
+ */
+
+#define LCD_CAM_CAM_CONV_YUV_MODE 0x00000003
+#define LCD_CAM_CAM_CONV_YUV_MODE_M (LCD_CAM_CAM_CONV_YUV_MODE_V <<
LCD_CAM_CAM_CONV_YUV_MODE_S)
+#define LCD_CAM_CAM_CONV_YUV_MODE_V 0x00000003
+#define LCD_CAM_CAM_CONV_YUV_MODE_S 24
+
+/* LCD_CAM_CAM_CONV_YUV2YUV_MODE : R/W; bitpos: [23:22]; default: 3;
+ * 0: to yuv422. 1: to yuv420. 2: to yuv411. 3: disabled. To enable yuv2yuv
+ * mode, trans_mode must be set to 1.
+ */
+
+#define LCD_CAM_CAM_CONV_YUV2YUV_MODE 0x00000003
+#define LCD_CAM_CAM_CONV_YUV2YUV_MODE_M (LCD_CAM_CAM_CONV_YUV2YUV_MODE_V <<
LCD_CAM_CAM_CONV_YUV2YUV_MODE_S)
+#define LCD_CAM_CAM_CONV_YUV2YUV_MODE_V 0x00000003
+#define LCD_CAM_CAM_CONV_YUV2YUV_MODE_S 22
+
+/* LCD_CAM_CAM_CONV_8BITS_DATA_INV : R/W; bitpos: [21]; default: 0;
+ * 1:invert every two 8bits input data. 2. disabled.
+ */
+
+#define LCD_CAM_CAM_CONV_8BITS_DATA_INV (BIT(21))
+#define LCD_CAM_CAM_CONV_8BITS_DATA_INV_M (LCD_CAM_CAM_CONV_8BITS_DATA_INV_V
<< LCD_CAM_CAM_CONV_8BITS_DATA_INV_S)
+#define LCD_CAM_CAM_CONV_8BITS_DATA_INV_V 0x00000001
+#define LCD_CAM_CAM_CONV_8BITS_DATA_INV_S 21
+
+/* LCD_CAM_LCD_RGB_YUV_REG register
+ * LCD configuration register
+ */
+
+#define LCD_CAM_LCD_RGB_YUV_REG (DR_REG_LCD_CAM_BASE + 0x10)
+
+/* LCD_CAM_LCD_CONV_BYPASS : R/W; bitpos: [31]; default: 0;
+ * 0: Bypass converter. 1: Enable converter.
+ */
+
+#define LCD_CAM_LCD_CONV_BYPASS (BIT(31))
+#define LCD_CAM_LCD_CONV_BYPASS_M (LCD_CAM_LCD_CONV_BYPASS_V <<
LCD_CAM_LCD_CONV_BYPASS_S)
+#define LCD_CAM_LCD_CONV_BYPASS_V 0x00000001
+#define LCD_CAM_LCD_CONV_BYPASS_S 31
+
+/* LCD_CAM_LCD_CONV_TRANS_MODE : R/W; bitpos: [30]; default: 0;
+ * 0: YUV to RGB. 1: RGB to YUV.
+ */
+
+#define LCD_CAM_LCD_CONV_TRANS_MODE (BIT(30))
+#define LCD_CAM_LCD_CONV_TRANS_MODE_M (LCD_CAM_LCD_CONV_TRANS_MODE_V <<
LCD_CAM_LCD_CONV_TRANS_MODE_S)
+#define LCD_CAM_LCD_CONV_TRANS_MODE_V 0x00000001
+#define LCD_CAM_LCD_CONV_TRANS_MODE_S 30
+
+/* LCD_CAM_LCD_CONV_MODE_8BITS_ON : R/W; bitpos: [29]; default: 0;
+ * 0: 16bits mode. 1: 8bits mode.
+ */
+
+#define LCD_CAM_LCD_CONV_MODE_8BITS_ON (BIT(29))
+#define LCD_CAM_LCD_CONV_MODE_8BITS_ON_M (LCD_CAM_LCD_CONV_MODE_8BITS_ON_V <<
LCD_CAM_LCD_CONV_MODE_8BITS_ON_S)
+#define LCD_CAM_LCD_CONV_MODE_8BITS_ON_V 0x00000001
+#define LCD_CAM_LCD_CONV_MODE_8BITS_ON_S 29
+
+/* LCD_CAM_LCD_CONV_DATA_IN_MODE : R/W; bitpos: [28]; default: 0;
+ * LIMIT or FULL mode of Data in. 0: limit. 1: full
+ */
+
+#define LCD_CAM_LCD_CONV_DATA_IN_MODE (BIT(28))
+#define LCD_CAM_LCD_CONV_DATA_IN_MODE_M (LCD_CAM_LCD_CONV_DATA_IN_MODE_V <<
LCD_CAM_LCD_CONV_DATA_IN_MODE_S)
+#define LCD_CAM_LCD_CONV_DATA_IN_MODE_V 0x00000001
+#define LCD_CAM_LCD_CONV_DATA_IN_MODE_S 28
+
+/* LCD_CAM_LCD_CONV_DATA_OUT_MODE : R/W; bitpos: [27]; default: 0;
+ * LIMIT or FULL mode of Data out. 0: limit. 1: full
+ */
+
+#define LCD_CAM_LCD_CONV_DATA_OUT_MODE (BIT(27))
+#define LCD_CAM_LCD_CONV_DATA_OUT_MODE_M (LCD_CAM_LCD_CONV_DATA_OUT_MODE_V <<
LCD_CAM_LCD_CONV_DATA_OUT_MODE_S)
+#define LCD_CAM_LCD_CONV_DATA_OUT_MODE_V 0x00000001
+#define LCD_CAM_LCD_CONV_DATA_OUT_MODE_S 27
+
+/* LCD_CAM_LCD_CONV_PROTOCOL_MODE : R/W; bitpos: [26]; default: 0;
+ * 0:BT601. 1:BT709.
+ */
+
+#define LCD_CAM_LCD_CONV_PROTOCOL_MODE (BIT(26))
+#define LCD_CAM_LCD_CONV_PROTOCOL_MODE_M (LCD_CAM_LCD_CONV_PROTOCOL_MODE_V <<
LCD_CAM_LCD_CONV_PROTOCOL_MODE_S)
+#define LCD_CAM_LCD_CONV_PROTOCOL_MODE_V 0x00000001
+#define LCD_CAM_LCD_CONV_PROTOCOL_MODE_S 26
+
+/* LCD_CAM_LCD_CONV_YUV_MODE : R/W; bitpos: [25:24]; default: 0;
+ * 0: yuv422. 1: yuv420. 2: yuv411. When in yuv2yuv mode, yuv_mode decides
+ * the yuv mode of Data_in
+ */
+
+#define LCD_CAM_LCD_CONV_YUV_MODE 0x00000003
+#define LCD_CAM_LCD_CONV_YUV_MODE_M (LCD_CAM_LCD_CONV_YUV_MODE_V <<
LCD_CAM_LCD_CONV_YUV_MODE_S)
+#define LCD_CAM_LCD_CONV_YUV_MODE_V 0x00000003
+#define LCD_CAM_LCD_CONV_YUV_MODE_S 24
+
+/* LCD_CAM_LCD_CONV_YUV2YUV_MODE : R/W; bitpos: [23:22]; default: 3;
+ * 0: to yuv422. 1: to yuv420. 2: to yuv411. 3: disabled. To enable yuv2yuv
+ * mode, trans_mode must be set to 1.
+ */
+
+#define LCD_CAM_LCD_CONV_YUV2YUV_MODE 0x00000003
+#define LCD_CAM_LCD_CONV_YUV2YUV_MODE_M (LCD_CAM_LCD_CONV_YUV2YUV_MODE_V <<
LCD_CAM_LCD_CONV_YUV2YUV_MODE_S)
+#define LCD_CAM_LCD_CONV_YUV2YUV_MODE_V 0x00000003
+#define LCD_CAM_LCD_CONV_YUV2YUV_MODE_S 22
+
+/* LCD_CAM_LCD_CONV_TXTORX : R/W; bitpos: [21]; default: 0;
+ * 0: txtorx mode off. 1: txtorx mode on.
+ */
+
+#define LCD_CAM_LCD_CONV_TXTORX (BIT(21))
+#define LCD_CAM_LCD_CONV_TXTORX_M (LCD_CAM_LCD_CONV_TXTORX_V <<
LCD_CAM_LCD_CONV_TXTORX_S)
+#define LCD_CAM_LCD_CONV_TXTORX_V 0x00000001
+#define LCD_CAM_LCD_CONV_TXTORX_S 21
+
+/* LCD_CAM_LCD_CONV_8BITS_DATA_INV : R/W; bitpos: [20]; default: 0;
+ * 1:invert every two 8bits input data. 2. disabled.
+ */
+
+#define LCD_CAM_LCD_CONV_8BITS_DATA_INV (BIT(20))
+#define LCD_CAM_LCD_CONV_8BITS_DATA_INV_M (LCD_CAM_LCD_CONV_8BITS_DATA_INV_V
<< LCD_CAM_LCD_CONV_8BITS_DATA_INV_S)
+#define LCD_CAM_LCD_CONV_8BITS_DATA_INV_V 0x00000001
+#define LCD_CAM_LCD_CONV_8BITS_DATA_INV_S 20
+
+/* LCD_CAM_LCD_USER_REG register
+ * LCD configuration register
+ */
+
+#define LCD_CAM_LCD_USER_REG (DR_REG_LCD_CAM_BASE + 0x14)
+
+/* LCD_CAM_LCD_CMD_2_CYCLE_EN : R/W; bitpos: [31]; default: 0;
+ * The cycle length of command phase. 1: 2 cycles. 0: 1 cycle.
+ */
+
+#define LCD_CAM_LCD_CMD_2_CYCLE_EN (BIT(31))
+#define LCD_CAM_LCD_CMD_2_CYCLE_EN_M (LCD_CAM_LCD_CMD_2_CYCLE_EN_V <<
LCD_CAM_LCD_CMD_2_CYCLE_EN_S)
+#define LCD_CAM_LCD_CMD_2_CYCLE_EN_V 0x00000001
+#define LCD_CAM_LCD_CMD_2_CYCLE_EN_S 31
+
+/* LCD_CAM_LCD_DUMMY_CYCLELEN : R/W; bitpos: [30:29]; default: 0;
+ * The dummy cycle length minus 1.
+ */
+
+#define LCD_CAM_LCD_DUMMY_CYCLELEN 0x00000003
+#define LCD_CAM_LCD_DUMMY_CYCLELEN_M (LCD_CAM_LCD_DUMMY_CYCLELEN_V <<
LCD_CAM_LCD_DUMMY_CYCLELEN_S)
+#define LCD_CAM_LCD_DUMMY_CYCLELEN_V 0x00000003
+#define LCD_CAM_LCD_DUMMY_CYCLELEN_S 29
+
+/* LCD_CAM_LCD_RESET : WO; bitpos: [28]; default: 0;
+ * The value of command.
+ */
+
+#define LCD_CAM_LCD_RESET (BIT(28))
+#define LCD_CAM_LCD_RESET_M (LCD_CAM_LCD_RESET_V << LCD_CAM_LCD_RESET_S)
+#define LCD_CAM_LCD_RESET_V 0x00000001
+#define LCD_CAM_LCD_RESET_S 28
+
+/* LCD_CAM_LCD_START : R/W; bitpos: [27]; default: 0;
+ * LCD start sending data enable signal, valid in high level.
+ */
+
+#define LCD_CAM_LCD_START (BIT(27))
+#define LCD_CAM_LCD_START_M (LCD_CAM_LCD_START_V << LCD_CAM_LCD_START_S)
+#define LCD_CAM_LCD_START_V 0x00000001
+#define LCD_CAM_LCD_START_S 27
+
+/* LCD_CAM_LCD_CMD : R/W; bitpos: [26]; default: 0;
+ * 1: Be able to send command in LCD sequence when LCD starts. 0: Disable.
+ */
+
+#define LCD_CAM_LCD_CMD (BIT(26))
+#define LCD_CAM_LCD_CMD_M (LCD_CAM_LCD_CMD_V << LCD_CAM_LCD_CMD_S)
+#define LCD_CAM_LCD_CMD_V 0x00000001
+#define LCD_CAM_LCD_CMD_S 26
+
+/* LCD_CAM_LCD_DUMMY : R/W; bitpos: [25]; default: 0;
+ * 1: Enable DUMMY phase in LCD sequence when LCD starts. 0: Disable.
+ */
+
+#define LCD_CAM_LCD_DUMMY (BIT(25))
+#define LCD_CAM_LCD_DUMMY_M (LCD_CAM_LCD_DUMMY_V << LCD_CAM_LCD_DUMMY_S)
+#define LCD_CAM_LCD_DUMMY_V 0x00000001
+#define LCD_CAM_LCD_DUMMY_S 25
+
+/* LCD_CAM_LCD_DOUT : R/W; bitpos: [24]; default: 0;
+ * 1: Be able to send data out in LCD sequence when LCD starts. 0: Disable.
+ */
+
+#define LCD_CAM_LCD_DOUT (BIT(24))
+#define LCD_CAM_LCD_DOUT_M (LCD_CAM_LCD_DOUT_V << LCD_CAM_LCD_DOUT_S)
+#define LCD_CAM_LCD_DOUT_V 0x00000001
+#define LCD_CAM_LCD_DOUT_S 24
+
+/* LCD_CAM_LCD_2BYTE_EN : R/W; bitpos: [23]; default: 0;
+ * 1: The bit number of output LCD data is 9~16. 0: The bit number of
+ * output LCD data is 0~8.
+ */
+
+#define LCD_CAM_LCD_2BYTE_EN (BIT(23))
+#define LCD_CAM_LCD_2BYTE_EN_M (LCD_CAM_LCD_2BYTE_EN_V <<
LCD_CAM_LCD_2BYTE_EN_S)
+#define LCD_CAM_LCD_2BYTE_EN_V 0x00000001
+#define LCD_CAM_LCD_2BYTE_EN_S 23
+
+/* LCD_CAM_LCD_BYTE_ORDER : R/W; bitpos: [22]; default: 0;
+ * 1: invert data byte order, only valid in 2 byte mode. 0: Not change.
+ */
+
+#define LCD_CAM_LCD_BYTE_ORDER (BIT(22))
+#define LCD_CAM_LCD_BYTE_ORDER_M (LCD_CAM_LCD_BYTE_ORDER_V <<
LCD_CAM_LCD_BYTE_ORDER_S)
+#define LCD_CAM_LCD_BYTE_ORDER_V 0x00000001
+#define LCD_CAM_LCD_BYTE_ORDER_S 22
+
+/* LCD_CAM_LCD_BIT_ORDER : R/W; bitpos: [21]; default: 0;
+ * 1: Change data bit order, change LCD_DATA_out[7:0] to LCD_DATA_out[0:7]
+ * in one byte mode, and bits[15:0] to bits[0:15] in two byte mode. 0: Not
+ * change.
+ */
+
+#define LCD_CAM_LCD_BIT_ORDER (BIT(21))
+#define LCD_CAM_LCD_BIT_ORDER_M (LCD_CAM_LCD_BIT_ORDER_V <<
LCD_CAM_LCD_BIT_ORDER_S)
+#define LCD_CAM_LCD_BIT_ORDER_V 0x00000001
+#define LCD_CAM_LCD_BIT_ORDER_S 21
+
+/* LCD_CAM_LCD_UPDATE_REG : R/W; bitpos: [20]; default: 0;
+ * 1: Update LCD registers, will be cleared by hardware. 0 : Not care.
+ */
+
+#define LCD_CAM_LCD_UPDATE_REG (BIT(20))
+#define LCD_CAM_LCD_UPDATE_REG_M (LCD_CAM_LCD_UPDATE_REG_V <<
LCD_CAM_LCD_UPDATE_REG_S)
+#define LCD_CAM_LCD_UPDATE_REG_V 0x00000001
+#define LCD_CAM_LCD_UPDATE_REG_S 20
+
+/* LCD_CAM_LCD_8BITS_ORDER : R/W; bitpos: [19]; default: 0;
+ * 1: invert every two data byte, valid in 1 byte mode. 0: Not change.
+ */
+
+#define LCD_CAM_LCD_8BITS_ORDER (BIT(19))
+#define LCD_CAM_LCD_8BITS_ORDER_M (LCD_CAM_LCD_8BITS_ORDER_V <<
LCD_CAM_LCD_8BITS_ORDER_S)
+#define LCD_CAM_LCD_8BITS_ORDER_V 0x00000001
+#define LCD_CAM_LCD_8BITS_ORDER_S 19
+
+/* LCD_CAM_LCD_ALWAYS_OUT_EN : R/W; bitpos: [13]; default: 0;
+ * LCD always output when LCD is in LCD_DOUT state, unless reg_lcd_start is
+ * cleared or reg_lcd_reset is set.
+ */
+
+#define LCD_CAM_LCD_ALWAYS_OUT_EN (BIT(13))
+#define LCD_CAM_LCD_ALWAYS_OUT_EN_M (LCD_CAM_LCD_ALWAYS_OUT_EN_V <<
LCD_CAM_LCD_ALWAYS_OUT_EN_S)
+#define LCD_CAM_LCD_ALWAYS_OUT_EN_V 0x00000001
+#define LCD_CAM_LCD_ALWAYS_OUT_EN_S 13
+
+/* LCD_CAM_LCD_DOUT_CYCLELEN : R/W; bitpos: [12:0]; default: 1;
+ * The output data cycles minus 1 of LCD module.
+ */
+
+#define LCD_CAM_LCD_DOUT_CYCLELEN 0x00001fff
+#define LCD_CAM_LCD_DOUT_CYCLELEN_M (LCD_CAM_LCD_DOUT_CYCLELEN_V <<
LCD_CAM_LCD_DOUT_CYCLELEN_S)
+#define LCD_CAM_LCD_DOUT_CYCLELEN_V 0x00001fff
+#define LCD_CAM_LCD_DOUT_CYCLELEN_S 0
+
+/* LCD_CAM_LCD_MISC_REG register
+ * LCD configuration register
+ */
+
+#define LCD_CAM_LCD_MISC_REG (DR_REG_LCD_CAM_BASE + 0x18)
+
+/* LCD_CAM_LCD_CD_IDLE_EDGE : R/W; bitpos: [31]; default: 0;
+ * The default value of LCD_CD.
+ */
+
+#define LCD_CAM_LCD_CD_IDLE_EDGE (BIT(31))
+#define LCD_CAM_LCD_CD_IDLE_EDGE_M (LCD_CAM_LCD_CD_IDLE_EDGE_V <<
LCD_CAM_LCD_CD_IDLE_EDGE_S)
+#define LCD_CAM_LCD_CD_IDLE_EDGE_V 0x00000001
+#define LCD_CAM_LCD_CD_IDLE_EDGE_S 31
+
+/* LCD_CAM_LCD_CD_CMD_SET : R/W; bitpos: [30]; default: 0;
+ * 1: LCD_CD = !reg_cd_idle_edge when lcd_st[2:0] is in LCD_CMD state. 0:
+ * LCD_CD = reg_cd_idle_edge.
+ */
+
+#define LCD_CAM_LCD_CD_CMD_SET (BIT(30))
+#define LCD_CAM_LCD_CD_CMD_SET_M (LCD_CAM_LCD_CD_CMD_SET_V <<
LCD_CAM_LCD_CD_CMD_SET_S)
+#define LCD_CAM_LCD_CD_CMD_SET_V 0x00000001
+#define LCD_CAM_LCD_CD_CMD_SET_S 30
+
+/* LCD_CAM_LCD_CD_DUMMY_SET : R/W; bitpos: [29]; default: 0;
+ * 1: LCD_CD = !reg_cd_idle_edge when lcd_st[2:0] is in LCD_DUMMY state. 0:
+ * LCD_CD = reg_cd_idle_edge.
+ */
+
+#define LCD_CAM_LCD_CD_DUMMY_SET (BIT(29))
+#define LCD_CAM_LCD_CD_DUMMY_SET_M (LCD_CAM_LCD_CD_DUMMY_SET_V <<
LCD_CAM_LCD_CD_DUMMY_SET_S)
+#define LCD_CAM_LCD_CD_DUMMY_SET_V 0x00000001
+#define LCD_CAM_LCD_CD_DUMMY_SET_S 29
+
+/* LCD_CAM_LCD_CD_DATA_SET : R/W; bitpos: [28]; default: 0;
+ * 1: LCD_CD = !reg_cd_idle_edge when lcd_st[2:0] is in LCD_DOUT state. 0:
+ * LCD_CD = reg_cd_idle_edge.
+ */
+
+#define LCD_CAM_LCD_CD_DATA_SET (BIT(28))
+#define LCD_CAM_LCD_CD_DATA_SET_M (LCD_CAM_LCD_CD_DATA_SET_V <<
LCD_CAM_LCD_CD_DATA_SET_S)
+#define LCD_CAM_LCD_CD_DATA_SET_V 0x00000001
+#define LCD_CAM_LCD_CD_DATA_SET_S 28
+
+/* LCD_CAM_LCD_AFIFO_RESET : WO; bitpos: [27]; default: 0;
+ * LCD AFIFO reset signal.
+ */
+
+#define LCD_CAM_LCD_AFIFO_RESET (BIT(27))
+#define LCD_CAM_LCD_AFIFO_RESET_M (LCD_CAM_LCD_AFIFO_RESET_V <<
LCD_CAM_LCD_AFIFO_RESET_S)
+#define LCD_CAM_LCD_AFIFO_RESET_V 0x00000001
+#define LCD_CAM_LCD_AFIFO_RESET_S 27
+
+/* LCD_CAM_LCD_BK_EN : R/W; bitpos: [26]; default: 0;
+ * 1: Enable blank region when LCD sends data out. 0: No blank region.
+ */
+
+#define LCD_CAM_LCD_BK_EN (BIT(26))
+#define LCD_CAM_LCD_BK_EN_M (LCD_CAM_LCD_BK_EN_V << LCD_CAM_LCD_BK_EN_S)
+#define LCD_CAM_LCD_BK_EN_V 0x00000001
+#define LCD_CAM_LCD_BK_EN_S 26
+
+/* LCD_CAM_LCD_NEXT_FRAME_EN : R/W; bitpos: [25]; default: 0;
+ * 1: Send the next frame data when the current frame is sent out. 0: LCD
+ * stops when the current frame is sent out.
+ */
+
+#define LCD_CAM_LCD_NEXT_FRAME_EN (BIT(25))
+#define LCD_CAM_LCD_NEXT_FRAME_EN_M (LCD_CAM_LCD_NEXT_FRAME_EN_V <<
LCD_CAM_LCD_NEXT_FRAME_EN_S)
+#define LCD_CAM_LCD_NEXT_FRAME_EN_V 0x00000001
+#define LCD_CAM_LCD_NEXT_FRAME_EN_S 25
+
+/* LCD_CAM_LCD_VBK_CYCLELEN : R/W; bitpos: [24:12]; default: 0;
+ * The vertical back blank region cycle length minus 1 in LCD RGB mode, or
+ * the hold time cycle length in LCD non-RGB mode.
+ */
+
+#define LCD_CAM_LCD_VBK_CYCLELEN 0x00001fff
+#define LCD_CAM_LCD_VBK_CYCLELEN_M (LCD_CAM_LCD_VBK_CYCLELEN_V <<
LCD_CAM_LCD_VBK_CYCLELEN_S)
+#define LCD_CAM_LCD_VBK_CYCLELEN_V 0x00001fff
+#define LCD_CAM_LCD_VBK_CYCLELEN_S 12
+
+/* LCD_CAM_LCD_VFK_CYCLELEN : R/W; bitpos: [11:6]; default: 3;
+ * The setup cycle length minus 1 in LCD non-RGB mode.
+ */
+
+#define LCD_CAM_LCD_VFK_CYCLELEN 0x0000003f
+#define LCD_CAM_LCD_VFK_CYCLELEN_M (LCD_CAM_LCD_VFK_CYCLELEN_V <<
LCD_CAM_LCD_VFK_CYCLELEN_S)
+#define LCD_CAM_LCD_VFK_CYCLELEN_V 0x0000003f
+#define LCD_CAM_LCD_VFK_CYCLELEN_S 6
+
+/* LCD_CAM_LCD_AFIFO_THRESHOLD_NUM : R/W; bitpos: [5:1]; default: 11;
+ * The awfull threshold number of lcd_afifo.
+ */
+
+#define LCD_CAM_LCD_AFIFO_THRESHOLD_NUM 0x0000001f
+#define LCD_CAM_LCD_AFIFO_THRESHOLD_NUM_M (LCD_CAM_LCD_AFIFO_THRESHOLD_NUM_V
<< LCD_CAM_LCD_AFIFO_THRESHOLD_NUM_S)
+#define LCD_CAM_LCD_AFIFO_THRESHOLD_NUM_V 0x0000001f
+#define LCD_CAM_LCD_AFIFO_THRESHOLD_NUM_S 1
+
+/* LCD_CAM_LCD_CTRL_REG register
+ * LCD configuration register
+ */
+
+#define LCD_CAM_LCD_CTRL_REG (DR_REG_LCD_CAM_BASE + 0x1c)
+
+/* LCD_CAM_LCD_RGB_MODE_EN : R/W; bitpos: [31]; default: 0;
+ * 1: Enable reg mode input vsync, hsync, de. 0: Disable.
+ */
+
+#define LCD_CAM_LCD_RGB_MODE_EN (BIT(31))
+#define LCD_CAM_LCD_RGB_MODE_EN_M (LCD_CAM_LCD_RGB_MODE_EN_V <<
LCD_CAM_LCD_RGB_MODE_EN_S)
+#define LCD_CAM_LCD_RGB_MODE_EN_V 0x00000001
+#define LCD_CAM_LCD_RGB_MODE_EN_S 31
+
+/* LCD_CAM_LCD_VT_HEIGHT : R/W; bitpos: [30:21]; default: 0;
+ * It is the vertical total height of a frame.
+ */
+
+#define LCD_CAM_LCD_VT_HEIGHT 0x000003ff
+#define LCD_CAM_LCD_VT_HEIGHT_M (LCD_CAM_LCD_VT_HEIGHT_V <<
LCD_CAM_LCD_VT_HEIGHT_S)
+#define LCD_CAM_LCD_VT_HEIGHT_V 0x000003ff
+#define LCD_CAM_LCD_VT_HEIGHT_S 21
+
+/* LCD_CAM_LCD_VA_HEIGHT : R/W; bitpos: [20:11]; default: 0;
+ * It is the vertical active height of a frame.
+ */
+
+#define LCD_CAM_LCD_VA_HEIGHT 0x000003ff
+#define LCD_CAM_LCD_VA_HEIGHT_M (LCD_CAM_LCD_VA_HEIGHT_V <<
LCD_CAM_LCD_VA_HEIGHT_S)
+#define LCD_CAM_LCD_VA_HEIGHT_V 0x000003ff
+#define LCD_CAM_LCD_VA_HEIGHT_S 11
+
+/* LCD_CAM_LCD_HB_FRONT : R/W; bitpos: [10:0]; default: 0;
+ * It is the horizontal blank front porch of a frame.
+ */
+
+#define LCD_CAM_LCD_HB_FRONT 0x000007ff
+#define LCD_CAM_LCD_HB_FRONT_M (LCD_CAM_LCD_HB_FRONT_V <<
LCD_CAM_LCD_HB_FRONT_S)
+#define LCD_CAM_LCD_HB_FRONT_V 0x000007ff
+#define LCD_CAM_LCD_HB_FRONT_S 0
+
+/* LCD_CAM_LCD_CTRL1_REG register
+ * LCD configuration register
+ */
+
+#define LCD_CAM_LCD_CTRL1_REG (DR_REG_LCD_CAM_BASE + 0x20)
+
+/* LCD_CAM_LCD_HT_WIDTH : R/W; bitpos: [31:20]; default: 0;
+ * It is the horizontal total width of a frame.
+ */
+
+#define LCD_CAM_LCD_HT_WIDTH 0x00000fff
+#define LCD_CAM_LCD_HT_WIDTH_M (LCD_CAM_LCD_HT_WIDTH_V <<
LCD_CAM_LCD_HT_WIDTH_S)
+#define LCD_CAM_LCD_HT_WIDTH_V 0x00000fff
+#define LCD_CAM_LCD_HT_WIDTH_S 20
+
+/* LCD_CAM_LCD_HA_WIDTH : R/W; bitpos: [19:8]; default: 0;
+ * It is the horizontal active width of a frame.
+ */
+
+#define LCD_CAM_LCD_HA_WIDTH 0x00000fff
+#define LCD_CAM_LCD_HA_WIDTH_M (LCD_CAM_LCD_HA_WIDTH_V <<
LCD_CAM_LCD_HA_WIDTH_S)
+#define LCD_CAM_LCD_HA_WIDTH_V 0x00000fff
+#define LCD_CAM_LCD_HA_WIDTH_S 8
+
+/* LCD_CAM_LCD_VB_FRONT : R/W; bitpos: [7:0]; default: 0;
+ * It is the vertical blank front porch of a frame.
+ */
+
+#define LCD_CAM_LCD_VB_FRONT 0x000000ff
+#define LCD_CAM_LCD_VB_FRONT_M (LCD_CAM_LCD_VB_FRONT_V <<
LCD_CAM_LCD_VB_FRONT_S)
+#define LCD_CAM_LCD_VB_FRONT_V 0x000000ff
+#define LCD_CAM_LCD_VB_FRONT_S 0
+
+/* LCD_CAM_LCD_CTRL2_REG register
+ * LCD configuration register
+ */
+
+#define LCD_CAM_LCD_CTRL2_REG (DR_REG_LCD_CAM_BASE + 0x24)
+
+/* LCD_CAM_LCD_HSYNC_POSITION : R/W; bitpos: [31:24]; default: 0;
+ * It is the position of LCD_HSYNC active pulse in a line.
+ */
+
+#define LCD_CAM_LCD_HSYNC_POSITION 0x000000ff
+#define LCD_CAM_LCD_HSYNC_POSITION_M (LCD_CAM_LCD_HSYNC_POSITION_V <<
LCD_CAM_LCD_HSYNC_POSITION_S)
+#define LCD_CAM_LCD_HSYNC_POSITION_V 0x000000ff
+#define LCD_CAM_LCD_HSYNC_POSITION_S 24
+
+/* LCD_CAM_LCD_HSYNC_IDLE_POL : R/W; bitpos: [23]; default: 0;
+ * It is the idle value of LCD_HSYNC.
+ */
+
+#define LCD_CAM_LCD_HSYNC_IDLE_POL (BIT(23))
+#define LCD_CAM_LCD_HSYNC_IDLE_POL_M (LCD_CAM_LCD_HSYNC_IDLE_POL_V <<
LCD_CAM_LCD_HSYNC_IDLE_POL_S)
+#define LCD_CAM_LCD_HSYNC_IDLE_POL_V 0x00000001
+#define LCD_CAM_LCD_HSYNC_IDLE_POL_S 23
+
+/* LCD_CAM_LCD_HSYNC_WIDTH : R/W; bitpos: [22:16]; default: 1;
+ * It is the position of LCD_HSYNC active pulse in a line.
+ */
+
+#define LCD_CAM_LCD_HSYNC_WIDTH 0x0000007f
+#define LCD_CAM_LCD_HSYNC_WIDTH_M (LCD_CAM_LCD_HSYNC_WIDTH_V <<
LCD_CAM_LCD_HSYNC_WIDTH_S)
+#define LCD_CAM_LCD_HSYNC_WIDTH_V 0x0000007f
+#define LCD_CAM_LCD_HSYNC_WIDTH_S 16
+
+/* LCD_CAM_LCD_HS_BLANK_EN : R/W; bitpos: [9]; default: 0;
+ * 1: The pulse of LCD_HSYNC is out in vertical blanking lines RGB mode. 0:
+ * LCD_HSYNC pulse is valid only in active region lines in RGB mode.
+ */
+
+#define LCD_CAM_LCD_HS_BLANK_EN (BIT(9))
+#define LCD_CAM_LCD_HS_BLANK_EN_M (LCD_CAM_LCD_HS_BLANK_EN_V <<
LCD_CAM_LCD_HS_BLANK_EN_S)
+#define LCD_CAM_LCD_HS_BLANK_EN_V 0x00000001
+#define LCD_CAM_LCD_HS_BLANK_EN_S 9
+
+/* LCD_CAM_LCD_DE_IDLE_POL : R/W; bitpos: [8]; default: 0;
+ * It is the idle value of LCD_DE.
+ */
+
+#define LCD_CAM_LCD_DE_IDLE_POL (BIT(8))
+#define LCD_CAM_LCD_DE_IDLE_POL_M (LCD_CAM_LCD_DE_IDLE_POL_V <<
LCD_CAM_LCD_DE_IDLE_POL_S)
+#define LCD_CAM_LCD_DE_IDLE_POL_V 0x00000001
+#define LCD_CAM_LCD_DE_IDLE_POL_S 8
+
+/* LCD_CAM_LCD_VSYNC_IDLE_POL : R/W; bitpos: [7]; default: 0;
+ * It is the idle value of LCD_VSYNC.
+ */
+
+#define LCD_CAM_LCD_VSYNC_IDLE_POL (BIT(7))
+#define LCD_CAM_LCD_VSYNC_IDLE_POL_M (LCD_CAM_LCD_VSYNC_IDLE_POL_V <<
LCD_CAM_LCD_VSYNC_IDLE_POL_S)
+#define LCD_CAM_LCD_VSYNC_IDLE_POL_V 0x00000001
+#define LCD_CAM_LCD_VSYNC_IDLE_POL_S 7
+
+/* LCD_CAM_LCD_VSYNC_WIDTH : R/W; bitpos: [6:0]; default: 1;
+ * It is the position of LCD_VSYNC active pulse in a line.
+ */
+
+#define LCD_CAM_LCD_VSYNC_WIDTH 0x0000007f
+#define LCD_CAM_LCD_VSYNC_WIDTH_M (LCD_CAM_LCD_VSYNC_WIDTH_V <<
LCD_CAM_LCD_VSYNC_WIDTH_S)
+#define LCD_CAM_LCD_VSYNC_WIDTH_V 0x0000007f
+#define LCD_CAM_LCD_VSYNC_WIDTH_S 0
+
+/* LCD_CAM_LCD_CMD_VAL_REG register
+ * LCD configuration register
+ */
+
+#define LCD_CAM_LCD_CMD_VAL_REG (DR_REG_LCD_CAM_BASE + 0x28)
+
+/* LCD_CAM_LCD_CMD_VALUE : R/W; bitpos: [31:0]; default: 0;
+ * The LCD write command value.
+ */
+
+#define LCD_CAM_LCD_CMD_VALUE 0xffffffff
+#define LCD_CAM_LCD_CMD_VALUE_M (LCD_CAM_LCD_CMD_VALUE_V <<
LCD_CAM_LCD_CMD_VALUE_S)
+#define LCD_CAM_LCD_CMD_VALUE_V 0xffffffff
+#define LCD_CAM_LCD_CMD_VALUE_S 0
+
+/* LCD_CAM_LCD_DLY_MODE_REG register
+ * LCD configuration register
+ */
+
+#define LCD_CAM_LCD_DLY_MODE_REG (DR_REG_LCD_CAM_BASE + 0x30)
+
+/* LCD_CAM_LCD_VSYNC_MODE : R/W; bitpos: [7:6]; default: 0;
+ * The output LCD_VSYNC is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_LCD_VSYNC_MODE 0x00000003
+#define LCD_CAM_LCD_VSYNC_MODE_M (LCD_CAM_LCD_VSYNC_MODE_V <<
LCD_CAM_LCD_VSYNC_MODE_S)
+#define LCD_CAM_LCD_VSYNC_MODE_V 0x00000003
+#define LCD_CAM_LCD_VSYNC_MODE_S 6
+
+/* LCD_CAM_LCD_HSYNC_MODE : R/W; bitpos: [5:4]; default: 0;
+ * The output LCD_HSYNC is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_LCD_HSYNC_MODE 0x00000003
+#define LCD_CAM_LCD_HSYNC_MODE_M (LCD_CAM_LCD_HSYNC_MODE_V <<
LCD_CAM_LCD_HSYNC_MODE_S)
+#define LCD_CAM_LCD_HSYNC_MODE_V 0x00000003
+#define LCD_CAM_LCD_HSYNC_MODE_S 4
+
+/* LCD_CAM_LCD_DE_MODE : R/W; bitpos: [3:2]; default: 0;
+ * The output LCD_DE is delayed by module clock LCD_CLK. 0: output without
+ * delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by the
+ * negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_LCD_DE_MODE 0x00000003
+#define LCD_CAM_LCD_DE_MODE_M (LCD_CAM_LCD_DE_MODE_V << LCD_CAM_LCD_DE_MODE_S)
+#define LCD_CAM_LCD_DE_MODE_V 0x00000003
+#define LCD_CAM_LCD_DE_MODE_S 2
+
+/* LCD_CAM_LCD_CD_MODE : R/W; bitpos: [1:0]; default: 0;
+ * The output LCD_CD is delayed by module clock LCD_CLK. 0: output without
+ * delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by the
+ * negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_LCD_CD_MODE 0x00000003
+#define LCD_CAM_LCD_CD_MODE_M (LCD_CAM_LCD_CD_MODE_V << LCD_CAM_LCD_CD_MODE_S)
+#define LCD_CAM_LCD_CD_MODE_V 0x00000003
+#define LCD_CAM_LCD_CD_MODE_S 0
+
+/* LCD_CAM_LCD_DATA_DOUT_MODE_REG register
+ * LCD configuration register
+ */
+
+#define LCD_CAM_LCD_DATA_DOUT_MODE_REG (DR_REG_LCD_CAM_BASE + 0x38)
+
+/* LCD_CAM_DOUT15_MODE : R/W; bitpos: [31:30]; default: 0;
+ * The output data bit $n is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_DOUT15_MODE 0x00000003
+#define LCD_CAM_DOUT15_MODE_M (LCD_CAM_DOUT15_MODE_V << LCD_CAM_DOUT15_MODE_S)
+#define LCD_CAM_DOUT15_MODE_V 0x00000003
+#define LCD_CAM_DOUT15_MODE_S 30
+
+/* LCD_CAM_DOUT14_MODE : R/W; bitpos: [29:28]; default: 0;
+ * The output data bit $n is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_DOUT14_MODE 0x00000003
+#define LCD_CAM_DOUT14_MODE_M (LCD_CAM_DOUT14_MODE_V << LCD_CAM_DOUT14_MODE_S)
+#define LCD_CAM_DOUT14_MODE_V 0x00000003
+#define LCD_CAM_DOUT14_MODE_S 28
+
+/* LCD_CAM_DOUT13_MODE : R/W; bitpos: [27:26]; default: 0;
+ * The output data bit $n is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_DOUT13_MODE 0x00000003
+#define LCD_CAM_DOUT13_MODE_M (LCD_CAM_DOUT13_MODE_V << LCD_CAM_DOUT13_MODE_S)
+#define LCD_CAM_DOUT13_MODE_V 0x00000003
+#define LCD_CAM_DOUT13_MODE_S 26
+
+/* LCD_CAM_DOUT12_MODE : R/W; bitpos: [25:24]; default: 0;
+ * The output data bit $n is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_DOUT12_MODE 0x00000003
+#define LCD_CAM_DOUT12_MODE_M (LCD_CAM_DOUT12_MODE_V << LCD_CAM_DOUT12_MODE_S)
+#define LCD_CAM_DOUT12_MODE_V 0x00000003
+#define LCD_CAM_DOUT12_MODE_S 24
+
+/* LCD_CAM_DOUT11_MODE : R/W; bitpos: [23:22]; default: 0;
+ * The output data bit $n is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_DOUT11_MODE 0x00000003
+#define LCD_CAM_DOUT11_MODE_M (LCD_CAM_DOUT11_MODE_V << LCD_CAM_DOUT11_MODE_S)
+#define LCD_CAM_DOUT11_MODE_V 0x00000003
+#define LCD_CAM_DOUT11_MODE_S 22
+
+/* LCD_CAM_DOUT10_MODE : R/W; bitpos: [21:20]; default: 0;
+ * The output data bit $n is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_DOUT10_MODE 0x00000003
+#define LCD_CAM_DOUT10_MODE_M (LCD_CAM_DOUT10_MODE_V << LCD_CAM_DOUT10_MODE_S)
+#define LCD_CAM_DOUT10_MODE_V 0x00000003
+#define LCD_CAM_DOUT10_MODE_S 20
+
+/* LCD_CAM_DOUT9_MODE : R/W; bitpos: [19:18]; default: 0;
+ * The output data bit $n is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_DOUT9_MODE 0x00000003
+#define LCD_CAM_DOUT9_MODE_M (LCD_CAM_DOUT9_MODE_V << LCD_CAM_DOUT9_MODE_S)
+#define LCD_CAM_DOUT9_MODE_V 0x00000003
+#define LCD_CAM_DOUT9_MODE_S 18
+
+/* LCD_CAM_DOUT8_MODE : R/W; bitpos: [17:16]; default: 0;
+ * The output data bit $n is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_DOUT8_MODE 0x00000003
+#define LCD_CAM_DOUT8_MODE_M (LCD_CAM_DOUT8_MODE_V << LCD_CAM_DOUT8_MODE_S)
+#define LCD_CAM_DOUT8_MODE_V 0x00000003
+#define LCD_CAM_DOUT8_MODE_S 16
+
+/* LCD_CAM_DOUT7_MODE : R/W; bitpos: [15:14]; default: 0;
+ * The output data bit $n is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_DOUT7_MODE 0x00000003
+#define LCD_CAM_DOUT7_MODE_M (LCD_CAM_DOUT7_MODE_V << LCD_CAM_DOUT7_MODE_S)
+#define LCD_CAM_DOUT7_MODE_V 0x00000003
+#define LCD_CAM_DOUT7_MODE_S 14
+
+/* LCD_CAM_DOUT6_MODE : R/W; bitpos: [13:12]; default: 0;
+ * The output data bit $n is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_DOUT6_MODE 0x00000003
+#define LCD_CAM_DOUT6_MODE_M (LCD_CAM_DOUT6_MODE_V << LCD_CAM_DOUT6_MODE_S)
+#define LCD_CAM_DOUT6_MODE_V 0x00000003
+#define LCD_CAM_DOUT6_MODE_S 12
+
+/* LCD_CAM_DOUT5_MODE : R/W; bitpos: [11:10]; default: 0;
+ * The output data bit $n is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_DOUT5_MODE 0x00000003
+#define LCD_CAM_DOUT5_MODE_M (LCD_CAM_DOUT5_MODE_V << LCD_CAM_DOUT5_MODE_S)
+#define LCD_CAM_DOUT5_MODE_V 0x00000003
+#define LCD_CAM_DOUT5_MODE_S 10
+
+/* LCD_CAM_DOUT4_MODE : R/W; bitpos: [9:8]; default: 0;
+ * The output data bit $n is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_DOUT4_MODE 0x00000003
+#define LCD_CAM_DOUT4_MODE_M (LCD_CAM_DOUT4_MODE_V << LCD_CAM_DOUT4_MODE_S)
+#define LCD_CAM_DOUT4_MODE_V 0x00000003
+#define LCD_CAM_DOUT4_MODE_S 8
+
+/* LCD_CAM_DOUT3_MODE : R/W; bitpos: [7:6]; default: 0;
+ * The output data bit $n is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_DOUT3_MODE 0x00000003
+#define LCD_CAM_DOUT3_MODE_M (LCD_CAM_DOUT3_MODE_V << LCD_CAM_DOUT3_MODE_S)
+#define LCD_CAM_DOUT3_MODE_V 0x00000003
+#define LCD_CAM_DOUT3_MODE_S 6
+
+/* LCD_CAM_DOUT2_MODE : R/W; bitpos: [5:4]; default: 0;
+ * The output data bit $n is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_DOUT2_MODE 0x00000003
+#define LCD_CAM_DOUT2_MODE_M (LCD_CAM_DOUT2_MODE_V << LCD_CAM_DOUT2_MODE_S)
+#define LCD_CAM_DOUT2_MODE_V 0x00000003
+#define LCD_CAM_DOUT2_MODE_S 4
+
+/* LCD_CAM_DOUT1_MODE : R/W; bitpos: [3:2]; default: 0;
+ * The output data bit $n is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_DOUT1_MODE 0x00000003
+#define LCD_CAM_DOUT1_MODE_M (LCD_CAM_DOUT1_MODE_V << LCD_CAM_DOUT1_MODE_S)
+#define LCD_CAM_DOUT1_MODE_V 0x00000003
+#define LCD_CAM_DOUT1_MODE_S 2
+
+/* LCD_CAM_DOUT0_MODE : R/W; bitpos: [1:0]; default: 0;
+ * The output data bit $n is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_DOUT0_MODE 0x00000003
+#define LCD_CAM_DOUT0_MODE_M (LCD_CAM_DOUT0_MODE_V << LCD_CAM_DOUT0_MODE_S)
+#define LCD_CAM_DOUT0_MODE_V 0x00000003
+#define LCD_CAM_DOUT0_MODE_S 0
+
+/* LCD_CAM_LC_DMA_INT_ENA_REG register
+ * LCD_camera DMA inturrupt enable register
+ */
+
+#define LCD_CAM_LC_DMA_INT_ENA_REG (DR_REG_LCD_CAM_BASE + 0x64)
+
+/* LCD_CAM_CAM_HS_INT_ENA : R/W; bitpos: [3]; default: 0;
+ * The enable bit for Camera line interrupt.
+ */
+
+#define LCD_CAM_CAM_HS_INT_ENA (BIT(3))
+#define LCD_CAM_CAM_HS_INT_ENA_M (LCD_CAM_CAM_HS_INT_ENA_V <<
LCD_CAM_CAM_HS_INT_ENA_S)
+#define LCD_CAM_CAM_HS_INT_ENA_V 0x00000001
+#define LCD_CAM_CAM_HS_INT_ENA_S 3
+
+/* LCD_CAM_CAM_VSYNC_INT_ENA : R/W; bitpos: [2]; default: 0;
+ * The enable bit for Camera frame end interrupt.
+ */
+
+#define LCD_CAM_CAM_VSYNC_INT_ENA (BIT(2))
+#define LCD_CAM_CAM_VSYNC_INT_ENA_M (LCD_CAM_CAM_VSYNC_INT_ENA_V <<
LCD_CAM_CAM_VSYNC_INT_ENA_S)
+#define LCD_CAM_CAM_VSYNC_INT_ENA_V 0x00000001
+#define LCD_CAM_CAM_VSYNC_INT_ENA_S 2
+
+/* LCD_CAM_LCD_TRANS_DONE_INT_ENA : R/W; bitpos: [1]; default: 0;
+ * The enable bit for lcd transfer end interrupt.
+ */
+
+#define LCD_CAM_LCD_TRANS_DONE_INT_ENA (BIT(1))
+#define LCD_CAM_LCD_TRANS_DONE_INT_ENA_M (LCD_CAM_LCD_TRANS_DONE_INT_ENA_V <<
LCD_CAM_LCD_TRANS_DONE_INT_ENA_S)
+#define LCD_CAM_LCD_TRANS_DONE_INT_ENA_V 0x00000001
+#define LCD_CAM_LCD_TRANS_DONE_INT_ENA_S 1
+
+/* LCD_CAM_LCD_VSYNC_INT_ENA : R/W; bitpos: [0]; default: 0;
+ * The enable bit for LCD frame end interrupt.
+ */
+
+#define LCD_CAM_LCD_VSYNC_INT_ENA (BIT(0))
+#define LCD_CAM_LCD_VSYNC_INT_ENA_M (LCD_CAM_LCD_VSYNC_INT_ENA_V <<
LCD_CAM_LCD_VSYNC_INT_ENA_S)
+#define LCD_CAM_LCD_VSYNC_INT_ENA_V 0x00000001
+#define LCD_CAM_LCD_VSYNC_INT_ENA_S 0
+
+/* LCD_CAM_LC_DMA_INT_RAW_REG register
+ * LCD_camera DMA raw inturrupt status register
+ */
+
+#define LCD_CAM_LC_DMA_INT_RAW_REG (DR_REG_LCD_CAM_BASE + 0x68)
+
+/* LCD_CAM_CAM_HS_INT_RAW : RO; bitpos: [3]; default: 0;
+ * The raw bit for Camera line interrupt.
+ */
+
+#define LCD_CAM_CAM_HS_INT_RAW (BIT(3))
+#define LCD_CAM_CAM_HS_INT_RAW_M (LCD_CAM_CAM_HS_INT_RAW_V <<
LCD_CAM_CAM_HS_INT_RAW_S)
+#define LCD_CAM_CAM_HS_INT_RAW_V 0x00000001
+#define LCD_CAM_CAM_HS_INT_RAW_S 3
+
+/* LCD_CAM_CAM_VSYNC_INT_RAW : RO; bitpos: [2]; default: 0;
+ * The raw bit for Camera frame end interrupt.
+ */
+
+#define LCD_CAM_CAM_VSYNC_INT_RAW (BIT(2))
+#define LCD_CAM_CAM_VSYNC_INT_RAW_M (LCD_CAM_CAM_VSYNC_INT_RAW_V <<
LCD_CAM_CAM_VSYNC_INT_RAW_S)
+#define LCD_CAM_CAM_VSYNC_INT_RAW_V 0x00000001
+#define LCD_CAM_CAM_VSYNC_INT_RAW_S 2
+
+/* LCD_CAM_LCD_TRANS_DONE_INT_RAW : RO; bitpos: [1]; default: 0;
+ * The raw bit for lcd transfer end interrupt.
+ */
+
+#define LCD_CAM_LCD_TRANS_DONE_INT_RAW (BIT(1))
+#define LCD_CAM_LCD_TRANS_DONE_INT_RAW_M (LCD_CAM_LCD_TRANS_DONE_INT_RAW_V <<
LCD_CAM_LCD_TRANS_DONE_INT_RAW_S)
+#define LCD_CAM_LCD_TRANS_DONE_INT_RAW_V 0x00000001
+#define LCD_CAM_LCD_TRANS_DONE_INT_RAW_S 1
+
+/* LCD_CAM_LCD_VSYNC_INT_RAW : RO; bitpos: [0]; default: 0;
+ * The raw bit for LCD frame end interrupt.
+ */
+
+#define LCD_CAM_LCD_VSYNC_INT_RAW (BIT(0))
+#define LCD_CAM_LCD_VSYNC_INT_RAW_M (LCD_CAM_LCD_VSYNC_INT_RAW_V <<
LCD_CAM_LCD_VSYNC_INT_RAW_S)
+#define LCD_CAM_LCD_VSYNC_INT_RAW_V 0x00000001
+#define LCD_CAM_LCD_VSYNC_INT_RAW_S 0
+
+/* LCD_CAM_LC_DMA_INT_ST_REG register
+ * LCD_camera DMA masked inturrupt status register
+ */
+
+#define LCD_CAM_LC_DMA_INT_ST_REG (DR_REG_LCD_CAM_BASE + 0x6c)
+
+/* LCD_CAM_CAM_HS_INT_ST : RO; bitpos: [3]; default: 0;
+ * The status bit for Camera transfer end interrupt.
+ */
+
+#define LCD_CAM_CAM_HS_INT_ST (BIT(3))
+#define LCD_CAM_CAM_HS_INT_ST_M (LCD_CAM_CAM_HS_INT_ST_V <<
LCD_CAM_CAM_HS_INT_ST_S)
+#define LCD_CAM_CAM_HS_INT_ST_V 0x00000001
+#define LCD_CAM_CAM_HS_INT_ST_S 3
+
+/* LCD_CAM_CAM_VSYNC_INT_ST : RO; bitpos: [2]; default: 0;
+ * The status bit for Camera frame end interrupt.
+ */
+
+#define LCD_CAM_CAM_VSYNC_INT_ST (BIT(2))
+#define LCD_CAM_CAM_VSYNC_INT_ST_M (LCD_CAM_CAM_VSYNC_INT_ST_V <<
LCD_CAM_CAM_VSYNC_INT_ST_S)
+#define LCD_CAM_CAM_VSYNC_INT_ST_V 0x00000001
+#define LCD_CAM_CAM_VSYNC_INT_ST_S 2
+
+/* LCD_CAM_LCD_TRANS_DONE_INT_ST : RO; bitpos: [1]; default: 0;
+ * The status bit for lcd transfer end interrupt.
+ */
+
+#define LCD_CAM_LCD_TRANS_DONE_INT_ST (BIT(1))
+#define LCD_CAM_LCD_TRANS_DONE_INT_ST_M (LCD_CAM_LCD_TRANS_DONE_INT_ST_V <<
LCD_CAM_LCD_TRANS_DONE_INT_ST_S)
+#define LCD_CAM_LCD_TRANS_DONE_INT_ST_V 0x00000001
+#define LCD_CAM_LCD_TRANS_DONE_INT_ST_S 1
+
+/* LCD_CAM_LCD_VSYNC_INT_ST : RO; bitpos: [0]; default: 0;
+ * The status bit for LCD frame end interrupt.
+ */
+
+#define LCD_CAM_LCD_VSYNC_INT_ST (BIT(0))
+#define LCD_CAM_LCD_VSYNC_INT_ST_M (LCD_CAM_LCD_VSYNC_INT_ST_V <<
LCD_CAM_LCD_VSYNC_INT_ST_S)
+#define LCD_CAM_LCD_VSYNC_INT_ST_V 0x00000001
+#define LCD_CAM_LCD_VSYNC_INT_ST_S 0
+
+/* LCD_CAM_LC_DMA_INT_CLR_REG register
+ * LCD_camera DMA inturrupt clear register
+ */
+
+#define LCD_CAM_LC_DMA_INT_CLR_REG (DR_REG_LCD_CAM_BASE + 0x70)
+
+/* LCD_CAM_CAM_HS_INT_CLR : WO; bitpos: [3]; default: 0;
+ * The clear bit for Camera line interrupt.
+ */
+
+#define LCD_CAM_CAM_HS_INT_CLR (BIT(3))
+#define LCD_CAM_CAM_HS_INT_CLR_M (LCD_CAM_CAM_HS_INT_CLR_V <<
LCD_CAM_CAM_HS_INT_CLR_S)
+#define LCD_CAM_CAM_HS_INT_CLR_V 0x00000001
+#define LCD_CAM_CAM_HS_INT_CLR_S 3
+
+/* LCD_CAM_CAM_VSYNC_INT_CLR : WO; bitpos: [2]; default: 0;
+ * The clear bit for Camera frame end interrupt.
+ */
+
+#define LCD_CAM_CAM_VSYNC_INT_CLR (BIT(2))
+#define LCD_CAM_CAM_VSYNC_INT_CLR_M (LCD_CAM_CAM_VSYNC_INT_CLR_V <<
LCD_CAM_CAM_VSYNC_INT_CLR_S)
+#define LCD_CAM_CAM_VSYNC_INT_CLR_V 0x00000001
+#define LCD_CAM_CAM_VSYNC_INT_CLR_S 2
+
+/* LCD_CAM_LCD_TRANS_DONE_INT_CLR : WO; bitpos: [1]; default: 0;
+ * The clear bit for lcd transfer end interrupt.
+ */
+
+#define LCD_CAM_LCD_TRANS_DONE_INT_CLR (BIT(1))
+#define LCD_CAM_LCD_TRANS_DONE_INT_CLR_M (LCD_CAM_LCD_TRANS_DONE_INT_CLR_V <<
LCD_CAM_LCD_TRANS_DONE_INT_CLR_S)
+#define LCD_CAM_LCD_TRANS_DONE_INT_CLR_V 0x00000001
+#define LCD_CAM_LCD_TRANS_DONE_INT_CLR_S 1
+
+/* LCD_CAM_LCD_VSYNC_INT_CLR : WO; bitpos: [0]; default: 0;
+ * The clear bit for LCD frame end interrupt.
+ */
+
+#define LCD_CAM_LCD_VSYNC_INT_CLR (BIT(0))
+#define LCD_CAM_LCD_VSYNC_INT_CLR_M (LCD_CAM_LCD_VSYNC_INT_CLR_V <<
LCD_CAM_LCD_VSYNC_INT_CLR_S)
+#define LCD_CAM_LCD_VSYNC_INT_CLR_V 0x00000001
+#define LCD_CAM_LCD_VSYNC_INT_CLR_S 0
+
+/* LCD_CAM_LC_REG_DATE_REG register
+ * Version register
+ */
+
+#define LCD_CAM_LC_REG_DATE_REG (DR_REG_LCD_CAM_BASE + 0xfc)
+
+/* LCD_CAM_LC_DATE : R/W; bitpos: [27:0]; default: 33566752;
+ * LCD_CAM version control register
+ */
+
+#define LCD_CAM_LC_DATE 0x0fffffff
+#define LCD_CAM_LC_DATE_M (LCD_CAM_LC_DATE_V << LCD_CAM_LC_DATE_S)
+#define LCD_CAM_LC_DATE_V 0x0fffffff
+#define LCD_CAM_LC_DATE_S 0
+
+#endif /* __ARCH_XTENSA_SRC_ESP32S3_HARDWARE_ESP32S3_LCD_CAM_H */
diff --git a/boards/xtensa/esp32s3/common/Kconfig
b/boards/xtensa/esp32s3/common/Kconfig
index d22831a996..97c7c69bd0 100644
--- a/boards/xtensa/esp32s3/common/Kconfig
+++ b/boards/xtensa/esp32s3/common/Kconfig
@@ -11,3 +11,14 @@ config ESP32S3_MERGE_BINS
device.
This is only useful when the path to binary files (e.g.
bootloader)
is provided via the ESPTOOL_BINDIR variable.
+
+config ESP32S3_SPEED_UP_ISR
+ bool "Speed up ISR"
+ default n
+ ---help---
+ Move ESP32-S3's interrupt, OS timer tick, and scheduler
functions
+ from Flash to IRAM. This can speed up interrupt service
processing
+ and also reduce reading data from Flash.
+
+ If you run applications that need continue reading data from
PSRAM,
+ such as LCD display, please select this option.
diff --git a/boards/xtensa/esp32s3/common/scripts/esp32s3_aliases.ld
b/boards/xtensa/esp32s3/common/scripts/esp32s3_aliases.ld
index fa3c4e8118..26a937e2d9 100644
--- a/boards/xtensa/esp32s3/common/scripts/esp32s3_aliases.ld
+++ b/boards/xtensa/esp32s3/common/scripts/esp32s3_aliases.ld
@@ -27,3 +27,5 @@
api_vhci_host_send_packet = API_vhci_host_send_packet;
api_vhci_host_register_callback = API_vhci_host_register_callback;
#endif
+
+PROVIDE( cache_writeback_addr = Cache_WriteBack_Addr );
\ No newline at end of file
diff --git a/boards/xtensa/esp32s3/common/scripts/legacy_sections.ld
b/boards/xtensa/esp32s3/common/scripts/legacy_sections.ld
index e565c9b1fe..8745dc1595 100644
--- a/boards/xtensa/esp32s3/common/scripts/legacy_sections.ld
+++ b/boards/xtensa/esp32s3/common/scripts/legacy_sections.ld
@@ -88,6 +88,31 @@ SECTIONS
*libsched.a:sched_thistask.*(.literal .text .literal.* .text.*)
*libsched.a:spinlock.*(.literal .text .literal.* .text.*)
+#ifdef CONFIG_ESP32S3_SPEED_UP_ISR
+ *libarch.a:xtensa_irqdispatch.*(.literal.xtensa_irq_dispatch
.text.xtensa_irq_dispatch)
+ *libarch.a:xtensa_switchcontext.*(.literal.up_switch_context
.text.up_switch_context)
+ *libarch.a:xtensa_modifyreg32.*(.literal.modifyreg32 .text.modifyreg32)
+
+ *libarch.a:esp32s3_irq.*(.literal.xtensa_int_decode
.text.xtensa_int_decode)
+ *libarch.a:esp32s3_timerisr.*(.literal.systimer_isr .text.systimer_isr)
+ *libarch.a:esp32s3_idle.*(.literal.up_idle .text.up_idle)
+ *libarch.a:esp32s3_dma.*(.literal.esp32s3_dma_load .text.esp32s3_dma_load \
+ .literal.esp32s3_dma_enable
.text.esp32s3_dma_enable)
+
+ *libsched.a:sched_processtimer.*(.literal.nxsched_process_timer
.text.nxsched_process_timer)
+ *libsched.a:clock_initialize.*(.literal.clock_timer .text.clock_timer)
+ *libsched.a:wd_start.*(.literal.wd_timer .text.wd_timer)
+ *libsched.a:sched_roundrobin.*(.literal.nxsched_process_roundrobin
.text.nxsched_process_roundrobin)
+ *libsched.a:sched_reprioritizertr.*(.literal.nxsched_reprioritize_rtr
.text.nxsched_reprioritize_rtr)
+ *libsched.a:sched_removereadytorun.*(.literal.nxsched_remove_readytorun
.text.nxsched_remove_readytorun)
+ *libsched.a:sched_addreadytorun.*(.literal.nxsched_add_readytorun
.text.nxsched_add_readytorun)
+ *libsched.a:sched_addprioritized.*(.literal.nxsched_add_prioritized
.text.nxsched_add_prioritized)
+ *libsched.a:sched_mergepending.*(.literal.nxsched_merge_pending
.text.nxsched_merge_pending)
+ *libsched.a:sched_resumescheduler.*(.literal.nxsched_resume_scheduler
.text.nxsched_resume_scheduler)
+
+ *libc.a:bin/sq_remfirst.*(.literal.sq_remfirst .text.sq_remfirst)
+#endif
+
*(.wifirxiram .wifirxiram.*)
*(.wifi0iram .wifi0iram.*)
*(.wifiorslpiram .wifiorslpiram.*)
diff --git a/boards/xtensa/esp32s3/esp32s3-lcd-ev/Kconfig
b/boards/xtensa/esp32s3/esp32s3-lcd-ev/Kconfig
index 015a5a087f..01a4b2e000 100644
--- a/boards/xtensa/esp32s3/esp32s3-lcd-ev/Kconfig
+++ b/boards/xtensa/esp32s3/esp32s3-lcd-ev/Kconfig
@@ -49,4 +49,30 @@ config ESP32S3_SPIFLASH_LITTLEFS
endchoice # ESP32S3_SPIFLASH_FS
+config ESP32S3_BOARD_I2C
+ bool
+ default y if ESP32S3_I2C0 || ESP32S3_I2C1
+
+config ESP32S3_BOARD_IOEXPANDER
+ bool "Enable Board IO Expander"
+ default n
+ depends on ESP32S3_BOARD_I2C
+ ---help---
+ Enable board IO expander support, IC is TC9554.
+
+config ESP32S3_BOARD_LCD
+ bool "Enable Board LCD"
+ default n
+ depends on ESP32S3_LCD
+ select ESP32S3_BOARD_IOEXPANDER
+ ---help---
+ Enable board LCD support, IC is GC9503CV.
+
+config ESP32S3_BOARD_TOUCHPAD
+ bool "Enable Board Touchpad"
+ default n
+ depends on ESP32S3_BOARD_I2C
+ ---help---
+ Enable board touchpad support, IC is FT5X06.
+
endif # ARCH_BOARD_ESP32S3_LCD_EV
diff --git a/boards/xtensa/esp32s3/esp32s3-lcd-ev/configs/lcd/defconfig
b/boards/xtensa/esp32s3/esp32s3-lcd-ev/configs/lcd/defconfig
new file mode 100644
index 0000000000..f3e5bd4731
--- /dev/null
+++ b/boards/xtensa/esp32s3/esp32s3-lcd-ev/configs/lcd/defconfig
@@ -0,0 +1,63 @@
+#
+# 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_NSH_ARGCAT is not set
+# CONFIG_NSH_CMDOPT_HEXDUMP is not set
+CONFIG_ARCH="xtensa"
+CONFIG_ARCH_BOARD="esp32s3-lcd-ev"
+CONFIG_ARCH_BOARD_COMMON=y
+CONFIG_ARCH_BOARD_ESP32S3_LCD_EV=y
+CONFIG_ARCH_CHIP="esp32s3"
+CONFIG_ARCH_CHIP_ESP32S3=y
+CONFIG_ARCH_CHIP_ESP32S3WROOM2=y
+CONFIG_ARCH_INTERRUPTSTACK=2048
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_ARCH_XTENSA=y
+CONFIG_BOARD_LOOPSPERMSEC=16717
+CONFIG_BUILTIN=y
+CONFIG_DEBUG_ASSERTIONS=y
+CONFIG_DEBUG_ASSERTIONS_EXPRESSION=y
+CONFIG_DEBUG_FEATURES=y
+CONFIG_ESP32S3_BOARD_LCD=y
+CONFIG_ESP32S3_DMA=y
+CONFIG_ESP32S3_I2C0=y
+CONFIG_ESP32S3_I2C0_SCLPIN=18
+CONFIG_ESP32S3_I2C0_SDAPIN=8
+CONFIG_ESP32S3_LCD=y
+CONFIG_ESP32S3_LCD_CLOCK_MHZ=3
+CONFIG_ESP32S3_SPEED_UP_ISR=y
+CONFIG_ESP32S3_SPIRAM=y
+CONFIG_ESP32S3_SPIRAM_MODE_OCT=y
+CONFIG_ESP32S3_SPIRAM_SPEED_80M=y
+CONFIG_ESP32S3_UART0=y
+CONFIG_EXAMPLES_FB=y
+CONFIG_FS_PROCFS=y
+CONFIG_HAVE_CXX=y
+CONFIG_HAVE_CXXINITIALIZE=y
+CONFIG_IDLETHREAD_STACKSIZE=3072
+CONFIG_INIT_ENTRYPOINT="nsh_main"
+CONFIG_INIT_STACKSIZE=3072
+CONFIG_INTELHEX_BINARY=y
+CONFIG_MM_REGIONS=2
+CONFIG_NDEBUG=y
+CONFIG_NSH_ARCHINIT=y
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_LINELEN=64
+CONFIG_NSH_READLINE=y
+CONFIG_PREALLOC_TIMERS=4
+CONFIG_RAM_SIZE=114688
+CONFIG_RAM_START=0x20000000
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_WAITPID=y
+CONFIG_START_DAY=6
+CONFIG_START_MONTH=12
+CONFIG_START_YEAR=2011
+CONFIG_SYSLOG_BUFFER=y
+CONFIG_SYSTEM_NSH=y
+CONFIG_UART0_SERIAL_CONSOLE=y
diff --git a/boards/xtensa/esp32s3/esp32s3-lcd-ev/configs/lvgl/defconfig
b/boards/xtensa/esp32s3/esp32s3-lcd-ev/configs/lvgl/defconfig
new file mode 100644
index 0000000000..d23d82c408
--- /dev/null
+++ b/boards/xtensa/esp32s3/esp32s3-lcd-ev/configs/lvgl/defconfig
@@ -0,0 +1,78 @@
+#
+# 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_NSH_ARGCAT is not set
+# CONFIG_NSH_CMDOPT_HEXDUMP is not set
+CONFIG_ARCH="xtensa"
+CONFIG_ARCH_BOARD="esp32s3-lcd-ev"
+CONFIG_ARCH_BOARD_COMMON=y
+CONFIG_ARCH_BOARD_ESP32S3_LCD_EV=y
+CONFIG_ARCH_CHIP="esp32s3"
+CONFIG_ARCH_CHIP_ESP32S3=y
+CONFIG_ARCH_CHIP_ESP32S3WROOM2=y
+CONFIG_ARCH_INTERRUPTSTACK=2048
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_ARCH_XTENSA=y
+CONFIG_BOARD_LOOPSPERMSEC=16717
+CONFIG_BUILTIN=y
+CONFIG_DEBUG_ASSERTIONS=y
+CONFIG_DEBUG_ASSERTIONS_EXPRESSION=y
+CONFIG_DEBUG_FEATURES=y
+CONFIG_ESP32S3_BOARD_LCD=y
+CONFIG_ESP32S3_BOARD_TOUCHPAD=y
+CONFIG_ESP32S3_DMA=y
+CONFIG_ESP32S3_I2C0=y
+CONFIG_ESP32S3_I2C0_SCLPIN=18
+CONFIG_ESP32S3_I2C0_SDAPIN=8
+CONFIG_ESP32S3_LCD=y
+CONFIG_ESP32S3_LCD_CLOCK_MHZ=3
+CONFIG_ESP32S3_SPEED_UP_ISR=y
+CONFIG_ESP32S3_SPIRAM=y
+CONFIG_ESP32S3_SPIRAM_MODE_OCT=y
+CONFIG_ESP32S3_SPIRAM_SPEED_80M=y
+CONFIG_ESP32S3_UART0=y
+CONFIG_EXAMPLES_LVGLDEMO=y
+CONFIG_FS_PROCFS=y
+CONFIG_FT5X06_POLLMODE=y
+CONFIG_FT5X06_SINGLEPOINT=y
+CONFIG_GRAPHICS_LVGL=y
+CONFIG_HAVE_CXX=y
+CONFIG_HAVE_CXXINITIALIZE=y
+CONFIG_IDLETHREAD_STACKSIZE=3072
+CONFIG_INIT_ENTRYPOINT="nsh_main"
+CONFIG_INIT_STACKSIZE=3072
+CONFIG_INPUT=y
+CONFIG_INPUT_FT5X06=y
+CONFIG_INTELHEX_BINARY=y
+CONFIG_LV_FONT_MONTSERRAT_20=y
+CONFIG_LV_MEMCPY_MEMSET_STD=y
+CONFIG_LV_MEM_CUSTOM=y
+CONFIG_LV_PORT_USE_FBDEV=y
+CONFIG_LV_PORT_USE_TOUCHPAD=y
+CONFIG_LV_TICK_CUSTOM=y
+CONFIG_LV_TICK_CUSTOM_INCLUDE="port/lv_port_tick.h"
+CONFIG_LV_USE_DEMO_WIDGETS=y
+CONFIG_MM_REGIONS=2
+CONFIG_NDEBUG=y
+CONFIG_NSH_ARCHINIT=y
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_LINELEN=64
+CONFIG_NSH_READLINE=y
+CONFIG_PREALLOC_TIMERS=4
+CONFIG_RAM_SIZE=114688
+CONFIG_RAM_START=0x20000000
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_LPWORK=y
+CONFIG_SCHED_WAITPID=y
+CONFIG_START_DAY=6
+CONFIG_START_MONTH=12
+CONFIG_START_YEAR=2011
+CONFIG_SYSLOG_BUFFER=y
+CONFIG_SYSTEM_NSH=y
+CONFIG_UART0_SERIAL_CONSOLE=y
diff --git a/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/Make.defs
b/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/Make.defs
index 586a3324e1..a1dcc41aed 100644
--- a/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/Make.defs
+++ b/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/Make.defs
@@ -41,6 +41,18 @@ ifeq ($(CONFIG_WS2812),y)
CSRCS += esp32s3_ws2812.c
endif
+ifeq ($(CONFIG_ESP32S3_BOARD_IOEXPANDER),y)
+CSRCS += esp32s3_ioexpander.c
+endif
+
+ifeq ($(CONFIG_ESP32S3_BOARD_LCD),y)
+CSRCS += esp32s3_lcd.c
+endif
+
+ifeq ($(CONFIG_ESP32S3_BOARD_TOUCHPAD),y)
+CSRCS += esp32s3_touchscreen.c
+endif
+
DEPPATH += --dep-path board
VPATH += :board
CFLAGS +=
${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)board
diff --git a/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3-lcd-ev.h
b/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3-lcd-ev.h
index 138cd63211..cbef32d288 100644
--- a/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3-lcd-ev.h
+++ b/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3-lcd-ev.h
@@ -39,6 +39,10 @@
#define BUTTON_BOOT 0
+/* I2C Port */
+
+#define I2C_PORT 0
+
/****************************************************************************
* Public Types
****************************************************************************/
@@ -94,5 +98,99 @@ int board_spiflash_init(void);
int board_ws2812_initialize(int devno, int spino, uint16_t nleds);
#endif
+/****************************************************************************
+ * Name: board_lcd_initialize
+ *
+ * Description:
+ * Initialize LCD.
+ *
+ * Input Parameters:
+ * None.
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_ESP32S3_LCD) && defined(CONFIG_ESP32S3_BOARD_IOEXPANDER)
+int board_lcd_initialize(void);
+#endif
+
+/****************************************************************************
+ * Name: board_touchscreen_initialize
+ *
+ * Description:
+ * Initialize touchpad.
+ *
+ * Input Parameters:
+ * None.
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32S3_BOARD_TOUCHPAD
+int board_touchscreen_initialize(void);
+#endif
+
+/****************************************************************************
+ * Name: board_ioexpander_set_pin
+ *
+ * Description:
+ * Configure pin mode through the IO expander.
+ *
+ * Input Parameters:
+ * input_mask - pin bit mask which need to be set input, if set pin 0 to
+ * to be input, please make: input_mask = (1 << 0)
+ * output_mask - pin bit mask which need to be set output, if set pin 1 to
+ * to be input, please make: output_mask = (1 << 1)
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32S3_BOARD_IOEXPANDER
+int board_ioexpander_set_pin(uint8_t input_mask, uint8_t output_mask);
+#endif
+
+/****************************************************************************
+ * Name: board_ioexpander_output
+ *
+ * Description:
+ * Set pin output level through the IO expander.
+ *
+ * Input Parameters:
+ * pin - pin number
+ * level - true for high level, false for low.
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32S3_BOARD_IOEXPANDER
+int board_ioexpander_output(int pin, bool level);
+#endif
+
+/****************************************************************************
+ * Name: board_ioexpander_initialize
+ *
+ * Description:
+ * Initialize IO expander driver.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32S3_BOARD_IOEXPANDER
+int board_ioexpander_initialize(void);
+#endif
+
#endif /* __ASSEMBLY__ */
#endif /* __BOARDS_XTENSA_ESP32S3_ESP32S3_LCD_EV_SRC_ESP32S3_LCD_EV_H */
diff --git a/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3_bringup.c
b/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3_bringup.c
index a3427b897c..3f38147e1b 100644
--- a/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3_bringup.c
+++ b/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3_bringup.c
@@ -225,6 +225,22 @@ int esp32s3_bringup(void)
}
#endif
+#ifdef CONFIG_ESP32S3_BOARD_LCD
+ ret = board_lcd_initialize();
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "Failed to initialize LCD driver\n");
+ }
+#endif
+
+#ifdef CONFIG_ESP32S3_BOARD_TOUCHPAD
+ ret = board_touchscreen_initialize();
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "Failed to initialize touchscreen driver\n");
+ }
+#endif
+
/* If we got here then perhaps not all initialization was successful, but
* at least enough succeeded to bring-up NSH with perhaps reduced
* capabilities.
diff --git a/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3_ioexpander.c
b/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3_ioexpander.c
new file mode 100644
index 0000000000..8f606bf189
--- /dev/null
+++ b/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3_ioexpander.c
@@ -0,0 +1,171 @@
+/****************************************************************************
+ * boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3_ioexpander.c
+ *
+ * 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 <unistd.h>
+#include <stdlib.h>
+#include <debug.h>
+#include <assert.h>
+#include <nuttx/arch.h>
+#include <nuttx/board.h>
+
+#include "esp32s3_i2c.h"
+#include "esp32s3-lcd-ev.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define BOARD_IOEXPANDER_I2C_PORT I2C_PORT
+
+#define BOARD_IOEXPANDER_I2C_ADDR (0x20)
+#define BOARD_IOEXPANDER_I2C_CLOCK (400 * 1000)
+
+#define BOARD_IOEXPANDER_SET_DIRECTION (3)
+#define BOARD_IOEXPANDER_SET_OUTPUT (1)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct ioexpander
+{
+ struct i2c_master_s *i2c;
+ uint8_t output_val;
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct i2c_config_s g_i2c_config =
+{
+ .frequency = BOARD_IOEXPANDER_I2C_CLOCK,
+ .address = BOARD_IOEXPANDER_I2C_ADDR,
+ .addrlen = 7
+};
+static struct ioexpander g_ioexpander;
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_ioexpander_set_pin
+ *
+ * Description:
+ * Configure pin mode through the IO expander.
+ *
+ * Input Parameters:
+ * input_mask - pin bit mask which need to be set input, if set pin 0 to
+ * to be input, please make: input_mask = (1 << 0)
+ * output_mask - pin bit mask which need to be set output, if set pin 1 to
+ * to be input, please make: output_mask = (1 << 1)
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int board_ioexpander_set_pin(uint8_t input_mask, uint8_t output_mask)
+{
+ uint8_t data[2] =
+ {
+ BOARD_IOEXPANDER_SET_DIRECTION, 0
+ };
+
+ if (input_mask & output_mask)
+ {
+ return -EINVAL;
+ }
+
+ data[1] |= input_mask;
+ data[1] &= ~output_mask;
+
+ return i2c_write(g_ioexpander.i2c, &g_i2c_config, data, 2);
+}
+
+/****************************************************************************
+ * Name: board_ioexpander_output
+ *
+ * Description:
+ * Set pin output level through the IO expander.
+ *
+ * Input Parameters:
+ * pin - pin number
+ * level - true for high level, false for low.
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int board_ioexpander_output(int pin, bool level)
+{
+ uint8_t data[2] =
+ {
+ BOARD_IOEXPANDER_SET_OUTPUT, 0
+ };
+
+ DEBUGASSERT(pin < 8);
+
+ if (level)
+ {
+ g_ioexpander.output_val |= 1 << pin;
+ }
+ else
+ {
+ g_ioexpander.output_val &= ~(1 << pin);
+ }
+
+ data[1] = g_ioexpander.output_val;
+
+ return i2c_write(g_ioexpander.i2c, &g_i2c_config, data, 2);
+}
+
+/****************************************************************************
+ * Name: board_ioexpander_initialize
+ *
+ * Description:
+ * Initialize IO expander driver.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int board_ioexpander_initialize(void)
+{
+ g_ioexpander.i2c = esp32s3_i2cbus_initialize(BOARD_IOEXPANDER_I2C_PORT);
+ if (!g_ioexpander.i2c)
+ {
+ return -EINVAL;
+ }
+
+ return 0;
+}
diff --git a/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3_lcd.c
b/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3_lcd.c
new file mode 100644
index 0000000000..32b9c454c4
--- /dev/null
+++ b/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3_lcd.c
@@ -0,0 +1,683 @@
+/****************************************************************************
+ * boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3_lcd.c
+ *
+ * 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 <unistd.h>
+#include <stdlib.h>
+#include <debug.h>
+#include <assert.h>
+#include <sys/param.h>
+#include <unistd.h>
+#include <nuttx/arch.h>
+#include <nuttx/board.h>
+#include <nuttx/video/fb.h>
+#include <nuttx/signal.h>
+
+#include "esp32s3_gpio.h"
+#include "esp32s3-lcd-ev.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define CS_PIN 1
+#define SCK_PIN 2
+#define SDO_PIN 3
+
+#define DELAY(us) esp_rom_delay_us(us)
+#define CS(v) DEBUGASSERT(board_ioexpander_output(CS_PIN, v ? 1 : 0) ==
0)
+#define SCK(v) DEBUGASSERT(board_ioexpander_output(SCK_PIN, v ? 1 : 0) ==
0)
+#define SDO(v) DEBUGASSERT(board_ioexpander_output(SDO_PIN, v ? 1 : 0) ==
0)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct lcd_config_data
+{
+ uint8_t cmd;
+ uint8_t data_bytes;
+ uint8_t data[52];
+};
+
+/****************************************************************************
+ * External Functions
+ ****************************************************************************/
+
+extern void esp_rom_delay_us(uint32_t us);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* LCD GC9503CV configuration parameters */
+
+static const struct lcd_config_data g_lcd_config[] =
+{
+ {
+ /* Enable manufacture command set in page 0 */
+
+ 0xf0, 5,
+ {
+ 0x55, 0xaa, 0x52, 0x08, 0x00
+ }
+ },
+ {
+ /* Unknown */
+
+ 0xf6, 2,
+ {
+ 0x5a, 0x87
+ }
+ },
+ {
+ /* Unknown */
+
+ 0xc1, 1,
+ {
+ 0x3f
+ }
+ },
+ {
+ /* Unknown */
+
+ 0xc2, 1,
+ {
+ 0x0e
+ }
+ },
+ {
+ /* Unknown */
+
+ 0xc6, 1,
+ {
+ 0xf8
+ }
+ },
+ {
+ /* Unknown */
+
+ 0xc9, 1,
+ {
+ 0x10
+ }
+ },
+ {
+ /* Unknown */
+
+ 0xcd, 1,
+ {
+ 0x25
+ }
+ },
+ {
+ /* Unknown */
+
+ 0xf8, 1,
+ {
+ 0x8a
+ }
+ },
+ {
+ /* Unknown */
+
+ 0xac, 1,
+ {
+ 0x45
+ }
+ },
+ {
+ /* Set VGH to be 13(15.00) */
+
+ 0xa0, 1,
+ {
+ 0xdd
+ }
+ },
+ {
+ /* Unknown */
+
+ 0xa7, 1,
+ {
+ 0x47
+ }
+ },
+ {
+ /* Unknown */
+
+ 0xfa, 4,
+ {
+ 0x00, 0x00, 0x00, 0x04
+ }
+ },
+ {
+ /* Set VGL to be 5(-10.5) */
+
+ 0x86, 4,
+ {
+ 0x99, 0xa3, 0xa3, 0x51
+ }
+ },
+ {
+ /* Unknown */
+
+ 0xa3, 1,
+ {
+ 0xee
+ }
+ },
+ {
+ /* Unknown */
+
+ 0xfd, 3,
+ {
+ 0x3c, 0x3c, 0x00
+ }
+ },
+ {
+ /* Unknown */
+
+ 0x71, 1,
+ {
+ 0x48
+ }
+ },
+ {
+ /* Unknown */
+
+ 0x72, 1,
+ {
+ 0x48
+ }
+ },
+ {
+ /* Unknown */
+
+ 0x73, 2,
+ {
+ 0x00, 0x44
+ }
+ },
+ {
+ /* Unknown */
+
+ 0x97, 1,
+ {
+ 0xee
+ }
+ },
+ {
+ /* Unknown */
+
+ 0x83, 1,
+ {
+ 0x93
+ }
+ },
+ {
+ /* Set adjustment of VGMP */
+
+ 0x9a, 1,
+ {
+ 0x72
+ }
+ },
+ {
+ /* Set adjustment of VGMN */
+
+ 0x9b, 1,
+ {
+ 0x5a
+ }
+ },
+ {
+ /* Set adjustment of VGSPN */
+
+ 0x82, 2,
+ {
+ 0x2c, 0x2c
+ }
+ },
+ {
+ /* Unknown */
+
+ 0x6d, 32,
+ {
+ 0x00, 0x1f, 0x19, 0x1a, 0x10, 0x0e, 0x0c, 0x0a,
+ 0x02, 0x07, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x08, 0x01,
+ 0x09, 0x0b, 0x0d, 0x0f, 0x1a, 0x19, 0x1f, 0x00
+ }
+ },
+ {
+ /* Unknown */
+
+ 0x64, 16,
+ {
+ 0x38, 0x05, 0x01, 0xdb, 0x03, 0x03, 0x38, 0x04,
+ 0x01, 0xdc, 0x03, 0x03, 0x7a, 0x7a, 0x7a, 0x7a
+ }
+ },
+ {
+ /* Unknown */
+
+ 0x65, 16,
+ {
+ 0x38, 0x03, 0x01, 0xdd, 0x03, 0x03, 0x38, 0x02,
+ 0x01, 0xde, 0x03, 0x03, 0x7a, 0x7a, 0x7a, 0x7a
+ }
+ },
+ {
+ /* Unknown */
+
+ 0x66, 16,
+ {
+ 0x38, 0x01, 0x01, 0xdf, 0x03, 0x03, 0x38, 0x00,
+ 0x01, 0xe0, 0x03, 0x03, 0x7a, 0x7a, 0x7a, 0x7a
+ }
+ },
+ {
+ /* Unknown */
+
+ 0x67, 16,
+ {
+ 0x30, 0x01, 0x01, 0xe1, 0x03, 0x03, 0x30, 0x02,
+ 0x01, 0xe2, 0x03, 0x03, 0x7a, 0x7a, 0x7a, 0x7a
+ }
+ },
+ {
+ /* Unknown */
+
+ 0x68, 13,
+ {
+ 0x00, 0x08, 0x15, 0x08, 0x15, 0x7a, 0x7a, 0x08,
+ 0x15, 0x08, 0x15, 0x7a, 0x7a
+ }
+ },
+ {
+ /* Unknown */
+
+ 0x60, 8,
+ {
+ 0x38, 0x08, 0x7a, 0x7a, 0x38, 0x09, 0x7a, 0x7a
+ }
+ },
+ {
+ /* Unknown */
+
+ 0x63, 8,
+ {
+ 0x31, 0xe4, 0x7a, 0x7a, 0x31, 0xe5, 0x7a, 0x7a
+ }
+ },
+ {
+ /* Unknown */
+
+ 0x69, 7,
+ {
+ 0x04, 0x22, 0x14, 0x22, 0x14, 0x22, 0x08
+ }
+ },
+ {
+ /* Unknown */
+
+ 0x6b, 1,
+ {
+ 0x07
+ }
+ },
+ {
+ /* Unknown */
+
+ 0x7a, 2,
+ {
+ 0x08, 0x13
+ }
+ },
+ {
+ /* Unknown */
+
+ 0x7b, 2,
+ {
+ 0x08, 0x13
+ }
+ },
+ {
+ /* Unknown */
+
+ 0xd1, 52,
+ {
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x18,
+ 0x00, 0x21, 0x00, 0x2a, 0x00, 0x35, 0x00, 0x47,
+ 0x00, 0x56, 0x00, 0x90, 0x00, 0xe5, 0x01, 0x68,
+ 0x01, 0xd5, 0x01, 0xd7, 0x02, 0x36, 0x02, 0xa6,
+ 0x02, 0xee, 0x03, 0x48, 0x03, 0xa0, 0x03, 0xba,
+ 0x03, 0xc5, 0x03, 0xd0, 0x03, 0xe0, 0x03, 0xea,
+ 0x03, 0xfa, 0x03, 0xff
+ }
+ },
+ {
+ /* Unknown */
+
+ 0xd2, 52,
+ {
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x18,
+ 0x00, 0x21, 0x00, 0x2a, 0x00, 0x35, 0x00, 0x47,
+ 0x00, 0x56, 0x00, 0x90, 0x00, 0xe5, 0x01, 0x68,
+ 0x01, 0xd5, 0x01, 0xd7, 0x02, 0x36, 0x02, 0xa6,
+ 0x02, 0xee, 0x03, 0x48, 0x03, 0xa0, 0x03, 0xba,
+ 0x03, 0xc5, 0x03, 0xd0, 0x03, 0xe0, 0x03, 0xea,
+ 0x03, 0xfa, 0x03, 0xff
+ }
+ },
+ {
+ /* Unknown */
+
+ 0xd3, 52,
+ {
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x18,
+ 0x00, 0x21, 0x00, 0x2a, 0x00, 0x35, 0x00, 0x47,
+ 0x00, 0x56, 0x00, 0x90, 0x00, 0xe5, 0x01, 0x68,
+ 0x01, 0xd5, 0x01, 0xd7, 0x02, 0x36, 0x02, 0xa6,
+ 0x02, 0xee, 0x03, 0x48, 0x03, 0xa0, 0x03, 0xba,
+ 0x03, 0xc5, 0x03, 0xd0, 0x03, 0xe0, 0x03, 0xea,
+ 0x03, 0xfa, 0x03, 0xff
+ }
+ },
+ {
+ /* Unknown */
+
+ 0xd4, 52,
+ {
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x18,
+ 0x00, 0x21, 0x00, 0x2a, 0x00, 0x35, 0x00, 0x47,
+ 0x00, 0x56, 0x00, 0x90, 0x00, 0xe5, 0x01, 0x68,
+ 0x01, 0xd5, 0x01, 0xd7, 0x02, 0x36, 0x02, 0xa6,
+ 0x02, 0xee, 0x03, 0x48, 0x03, 0xa0, 0x03, 0xba,
+ 0x03, 0xc5, 0x03, 0xd0, 0x03, 0xe0, 0x03, 0xea,
+ 0x03, 0xfa, 0x03, 0xff
+ }
+ },
+ {
+ /* Unknown */
+
+ 0xd5, 52,
+ {
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x18,
+ 0x00, 0x21, 0x00, 0x2a, 0x00, 0x35, 0x00, 0x47,
+ 0x00, 0x56, 0x00, 0x90, 0x00, 0xe5, 0x01, 0x68,
+ 0x01, 0xd5, 0x01, 0xd7, 0x02, 0x36, 0x02, 0xa6,
+ 0x02, 0xee, 0x03, 0x48, 0x03, 0xa0, 0x03, 0xba,
+ 0x03, 0xc5, 0x03, 0xd0, 0x03, 0xe0, 0x03, 0xea,
+ 0x03, 0xfa, 0x03, 0xff
+ },
+ },
+ {
+ /* Unknown */
+
+ 0xd6, 52,
+ {
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x18,
+ 0x00, 0x21, 0x00, 0x2a, 0x00, 0x35, 0x00, 0x47,
+ 0x00, 0x56, 0x00, 0x90, 0x00, 0xe5, 0x01, 0x68,
+ 0x01, 0xd5, 0x01, 0xd7, 0x02, 0x36, 0x02, 0xa6,
+ 0x02, 0xee, 0x03, 0x48, 0x03, 0xa0, 0x03, 0xba,
+ 0x03, 0xc5, 0x03, 0xd0, 0x03, 0xe0, 0x03, 0xea,
+ 0x03, 0xfa, 0x03, 0xff
+ },
+ },
+ {
+ /* 18-bit Pixel */
+
+ 0x3a, 1,
+ {
+ 0x60
+ }
+ },
+ {
+ /* Enter sleep out mode, no parameters */
+
+ 0x11, 0
+ },
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 9-bit SPI Rising Mode
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: send_byte
+ *
+ * Description:
+ * Send 9-bit data to LCD.
+ *
+ * Input Parameters:
+ * data - TX data
+ *
+ * Returned Value:
+ * None.
+ *
+ ****************************************************************************/
+
+static void send_byte(uint16_t data)
+{
+ for (int n = 0; n < 9; n++)
+ {
+ if (data & 0x0100)
+ {
+ SDO(1);
+ }
+ else
+ {
+ SDO(0);
+ }
+
+ data = data << 1;
+
+ SCK(0);
+ DELAY(10);
+ SCK(1);
+ DELAY(10);
+ }
+}
+
+/****************************************************************************
+ * Name: send_cmd
+ *
+ * Description:
+ * Send command to LCD.
+ *
+ * Input Parameters:
+ * cmd - TX command
+ *
+ * Returned Value:
+ * None.
+ *
+ ****************************************************************************/
+
+static void send_cmd(uint8_t cmd)
+{
+ uint16_t spi_data = cmd;
+
+ CS(0);
+ DELAY(10);
+
+ send_byte(spi_data);
+
+ DELAY(10);
+ CS(1);
+ SCK(0);
+ SDO(0);
+ DELAY(10);
+}
+
+/****************************************************************************
+ * Name: send_data
+ *
+ * Description:
+ * Send data to LCD.
+ *
+ * Input Parameters:
+ * cmd - TX command
+ *
+ * Returned Value:
+ * None.
+ *
+ ****************************************************************************/
+
+static void send_data(uint8_t data)
+{
+ uint16_t spi_data = data;
+
+ CS(0);
+ DELAY(10);
+
+ spi_data &= 0x00ff;
+ spi_data |= 0x0100;
+ send_byte(spi_data);
+
+ DELAY(10);
+ CS(1);
+ SCK(0);
+ SDO(0);
+ DELAY(10);
+}
+
+/****************************************************************************
+ * Name: lcd_initialize_spi
+ *
+ * Description:
+ * Initialize write only SPI interface by IO expander.
+ *
+ * Input Parameters:
+ * None.
+ *
+ * Returned Value:
+ * None.
+ *
+ ****************************************************************************/
+
+static void lcd_initialize_spi(void)
+{
+ uint8_t pin_mask = (1 << CS_PIN) |
+ (1 << SCK_PIN) |
+ (1 << SDO_PIN);
+
+ DEBUGASSERT(board_ioexpander_initialize() == 0);
+ DEBUGASSERT(board_ioexpander_set_pin(0, pin_mask) == 0);
+
+ CS(1);
+ SCK(1);
+ SDO(1);
+}
+
+/****************************************************************************
+ * Name: lcd_configure_display
+ *
+ * Description:
+ * Configure LCD with global configuration parameters.
+ *
+ * Input Parameters:
+ * None.
+ *
+ * Returned Value:
+ * None.
+ *
+ ****************************************************************************/
+
+static void lcd_configure_display(void)
+{
+ /* Pull-up V-SYNC pin to start configurating LCD */
+
+ esp32s3_configgpio(CONFIG_ESP32S3_LCD_VSYNC_PIN, OUTPUT | PULLUP);
+ esp32s3_gpiowrite(CONFIG_ESP32S3_LCD_VSYNC_PIN, 1);
+
+ for (int i = 0; i < nitems(g_lcd_config); i++)
+ {
+ send_cmd(g_lcd_config[i].cmd);
+
+ for (int j = 0; j < g_lcd_config[i].data_bytes; j++)
+ {
+ send_data(g_lcd_config[i].data[j]);
+ }
+ }
+
+ /* Wait until LCD is ready */
+
+ nxsig_usleep(120 * 1000);
+
+ /* Display on */
+
+ send_cmd(0x29);
+
+ /* Wait until LCD is on */
+
+ nxsig_usleep(20 * 1000);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_lcd_initialize
+ *
+ * Description:
+ * Initialize LCD.
+ *
+ * Input Parameters:
+ * None.
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int board_lcd_initialize(void)
+{
+ int ret;
+
+ lcd_initialize_spi();
+ lcd_configure_display();
+
+#ifdef CONFIG_VIDEO_FB
+ /* Initialize and register the framebuffer driver */
+
+ ret = fb_register(0, 0);
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "ERROR: fb_register() failed: %d\n", ret);
+ return ret;
+ }
+#else
+ UNUSED(ret);
+#endif
+
+ return 0;
+}
diff --git a/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3_touchscreen.c
b/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3_touchscreen.c
new file mode 100644
index 0000000000..06e1ffeceb
--- /dev/null
+++ b/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3_touchscreen.c
@@ -0,0 +1,191 @@
+/****************************************************************************
+ * boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3_touchscreen.c
+ *
+ * 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 <syslog.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <nuttx/input/ft5x06.h>
+
+#include "esp32s3_i2c.h"
+#include "esp32s3-lcd-ev.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define BOARD_TOUCHSCREEN_I2C_PORT I2C_PORT
+
+#define BOARD_TOUCHSCREEN_I2C_ADDR (0x38)
+#define BOARD_TOUCHSCREEN_I2C_CLOCK (400 * 1000)
+
+/****************************************************************************
+ * Private Function Ptototypes
+ ****************************************************************************/
+
+#ifndef CONFIG_FT5X06_POLLMODE
+static int esp32s3_ft5x06_attach(const struct ft5x06_config_s *config,
+ xcpt_t isr, void *arg);
+static void esp32s3_ft5x06_enable(const struct ft5x06_config_s *config,
+ bool enable);
+static void esp32s3_ft5x06_clear(const struct ft5x06_config_s *config);
+#endif
+static void esp32s3_ft5x06_wakeup(const struct ft5x06_config_s *config);
+static void esp32s3_ft5x06_nreset(const struct ft5x06_config_s *config,
+ bool state);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct ft5x06_config_s g_ft5x06_config =
+{
+ .address = BOARD_TOUCHSCREEN_I2C_ADDR,
+ .frequency = BOARD_TOUCHSCREEN_I2C_CLOCK,
+#ifndef CONFIG_FT5X06_POLLMODE
+ .attach = esp32s3_ft5x06_attach,
+ .enable = esp32s3_ft5x06_enable,
+ .clear = esp32s3_ft5x06_clear,
+#endif
+ .wakeup = esp32s3_ft5x06_wakeup,
+ .nreset = esp32s3_ft5x06_nreset
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+#ifndef CONFIG_FT5X06_POLLMODE
+
+/****************************************************************************
+ * Name: esp32s3_ft5x06_attach
+ *
+ * Description:
+ * Attach an FT5x06 interrupt handler to a GPIO interrupt
+ *
+ ****************************************************************************/
+
+static int esp32s3_ft5x06_attach(const struct ft5x06_config_s *config,
+ xcpt_t isr, void *arg)
+{
+ /* We do not have interrupt pin in the implementation */
+
+ return 0;
+}
+
+/****************************************************************************
+ * Name: esp32s3_ft5x06_enable
+ *
+ * Description:
+ * Enable or disable a GPIO interrupt
+ *
+ ****************************************************************************/
+
+static void esp32s3_ft5x06_enable(const struct ft5x06_config_s *config,
+ bool enable)
+{
+ /* We do not have interrupt pin in the implementation */
+}
+
+/****************************************************************************
+ * Name: esp32s3_ft5x06_clear
+ *
+ * Description:
+ * Acknowledge/clear any pending GPIO interrupt
+ *
+ ****************************************************************************/
+
+static void esp32s3_ft5x06_clear(const struct ft5x06_config_s *config)
+{
+ /* We do not have interrupt pin in the implementation */
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32s3_ft5x06_wakeup
+ *
+ * Description:
+ * Issue WAKE interrupt to FT5x06 to change the FT5x06 from Hibernate to
+ * Active mode.
+ *
+ ****************************************************************************/
+
+static void esp32s3_ft5x06_wakeup(const struct ft5x06_config_s *config)
+{
+ /* We do not have access to the WAKE pin in the implementation */
+}
+
+/****************************************************************************
+ * Name: esp32s3_ft5x06_nreset
+ *
+ * Description:
+ * Control the chip reset pin
+ *
+ ****************************************************************************/
+
+static void esp32s3_ft5x06_nreset(const struct ft5x06_config_s *config,
+ bool state)
+{
+ /* We do not have access to the RESET pin in the implementation */
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_touchscreen_initialize
+ *
+ * Description:
+ * Initialize touchpad.
+ *
+ * Input Parameters:
+ * None.
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int board_touchscreen_initialize(void)
+{
+ int ret;
+ struct i2c_master_s *i2c;
+
+ i2c = esp32s3_i2cbus_initialize(BOARD_TOUCHSCREEN_I2C_PORT);
+ if (!i2c)
+ {
+ return -EINVAL;
+ }
+
+ ret = ft5x06_register(i2c, &g_ft5x06_config, 0);
+ if (ret != 0)
+ {
+ return ret;
+ }
+
+ return 0;
+}