diff --git a/components/hal/CMakeLists.txt b/components/hal/CMakeLists.txt index 874cc23f68..86dcdd3edc 100644 --- a/components/hal/CMakeLists.txt +++ b/components/hal/CMakeLists.txt @@ -72,6 +72,7 @@ if(NOT BOOTLOADER_BUILD) list(APPEND srcs "dac_hal.c" "gdma_hal.c" + "lcd_hal.c" "pcnt_hal.c" "spi_flash_hal_gpspi.c" "spi_slave_hd_hal.c" diff --git a/components/hal/component.mk b/components/hal/component.mk index e69da1615b..4c9254ba5f 100644 --- a/components/hal/component.mk +++ b/components/hal/component.mk @@ -2,7 +2,7 @@ COMPONENT_SRCDIRS := . esp32 COMPONENT_ADD_INCLUDEDIRS := esp32/include include COMPONENT_ADD_LDFRAGMENTS += linker.lf -COMPONENT_OBJEXCLUDE += ./spi_slave_hd_hal.o ./spi_flash_hal_gpspi.o ./spi_slave_hd_hal.o ./ds_hal.o ./gdma_hal.o +COMPONENT_OBJEXCLUDE += ./spi_slave_hd_hal.o ./spi_flash_hal_gpspi.o ./spi_slave_hd_hal.o ./ds_hal.o ./gdma_hal.o ./lcd_hal.o ifndef CONFIG_ETH_USE_ESP32_EMAC COMPONENT_OBJEXCLUDE += esp32/emac_hal.o diff --git a/components/hal/esp32s3/include/hal/clk_gate_ll.h b/components/hal/esp32s3/include/hal/clk_gate_ll.h index 77bb5145a6..cb2c514206 100644 --- a/components/hal/esp32s3/include/hal/clk_gate_ll.h +++ b/components/hal/esp32s3/include/hal/clk_gate_ll.h @@ -49,6 +49,8 @@ static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph) return SYSTEM_I2S0_CLK_EN; case PERIPH_I2S1_MODULE: return SYSTEM_I2S1_CLK_EN; + case PERIPH_LCD_CAM_MODULE: + return SYSTEM_LCD_CAM_CLK_EN; case PERIPH_TIMG0_MODULE: return SYSTEM_TIMERGROUP_CLK_EN; case PERIPH_TIMG1_MODULE: @@ -130,6 +132,8 @@ static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool en return SYSTEM_I2S0_RST; case PERIPH_I2S1_MODULE: return SYSTEM_I2S1_RST; + case PERIPH_LCD_CAM_MODULE: + return SYSTEM_LCD_CAM_RST; case PERIPH_TIMG0_MODULE: return SYSTEM_TIMERGROUP_RST; case PERIPH_TIMG1_MODULE: @@ -205,6 +209,7 @@ static uint32_t periph_ll_get_clk_en_reg(periph_module_t periph) return SYSTEM_WIFI_CLK_EN_REG ; case PERIPH_UART2_MODULE: case PERIPH_SDMMC_MODULE: + case PERIPH_LCD_CAM_MODULE: case PERIPH_GDMA_MODULE: case PERIPH_AES_MODULE: case PERIPH_SHA_MODULE: @@ -230,6 +235,7 @@ static uint32_t periph_ll_get_rst_en_reg(periph_module_t periph) case PERIPH_UART2_MODULE: case PERIPH_SDMMC_MODULE: case PERIPH_GDMA_MODULE: + case PERIPH_LCD_CAM_MODULE: case PERIPH_AES_MODULE: case PERIPH_SHA_MODULE: case PERIPH_RSA_MODULE: diff --git a/components/hal/esp32s3/include/hal/lcd_ll.h b/components/hal/esp32s3/include/hal/lcd_ll.h new file mode 100644 index 0000000000..6c6c3ab46a --- /dev/null +++ b/components/hal/esp32s3/include/hal/lcd_ll.h @@ -0,0 +1,253 @@ +// Copyright 2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed 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. +#pragma once + +#include +#include +#include +#include "soc/lcd_cam_reg.h" +#include "soc/lcd_cam_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define LCD_LL_GET_HW(id) (((id) == 0) ? (&LCD_CAM) : NULL) + +// Interrupt event, bit mask +#define LCD_LL_EVENT_VSYNC_END (1 << 0) +#define LCD_LL_EVENT_TRANS_DONE (1 << 1) +#define LCD_LL_EVENT_MASK (LCD_LL_EVENT_VSYNC_END | LCD_LL_EVENT_TRANS_DONE) + +// Clock source ID represented in register +#define LCD_LL_CLOCK_SRC_XTAL (1) +#define LCD_LL_CLOCK_SRC_APLL (2) +#define LCD_LL_CLOCK_SRC_PLL160M (3) + +// Maximum coefficient of clock prescaler +#define LCD_LL_CLOCK_PRESCALE_MAX (64) + +static inline void lcd_ll_enable_clock(lcd_cam_dev_t *dev, bool en) +{ + dev->lcd_clock.clk_en = en; +} + +static inline void lcd_ll_set_group_clock_src(lcd_cam_dev_t *dev, int src, int div_num, int div_a, int div_b) +{ + // lcd_clk = module_clock_src / (div_num + div_b / div_a) + assert(div_num >= 2); + dev->lcd_clock.lcd_clk_sel = src; + dev->lcd_clock.lcd_clkm_div_num = div_num; + dev->lcd_clock.lcd_clkm_div_a = div_a; + dev->lcd_clock.lcd_clkm_div_b = div_b; +} + +static inline void lcd_ll_set_clock_idle_level(lcd_cam_dev_t *dev, bool level) +{ + dev->lcd_clock.lcd_ck_idle_edge = level; +} + +static inline void lcd_ll_set_pixel_clock_edge(lcd_cam_dev_t *dev, bool active_on_neg) +{ + dev->lcd_clock.lcd_clk_equ_sysclk = 0; // if we want to pixel_clk == lcd_clk, just make clkcnt = 0 + dev->lcd_clock.lcd_ck_out_edge = active_on_neg; +} + +static inline void lcd_ll_set_pixel_clock_prescale(lcd_cam_dev_t *dev, uint32_t prescale) +{ + // Formula: pixel_clk = lcd_clk / (1 + clkcnt_n) + dev->lcd_clock.lcd_clkcnt_n = prescale - 1; +} + +static inline void lcd_ll_enable_rgb_yuv_convert(lcd_cam_dev_t *dev, bool en) +{ + dev->lcd_rgb_yuv.lcd_conv_bypass = en; +} + +static inline void lcd_ll_set_phase_cycles(lcd_cam_dev_t *dev, uint32_t cmd_cycles, uint32_t dummy_cycles, uint32_t data_cycles) +{ + assert(cmd_cycles <= 2); + dev->lcd_user.lcd_cmd = (cmd_cycles > 0); + dev->lcd_user.lcd_dummy = (dummy_cycles > 0); + dev->lcd_user.lcd_dout = (data_cycles > 0); + dev->lcd_user.lcd_cmd_2_cycle_en = cmd_cycles > 1; + dev->lcd_user.lcd_dummy_cyclelen = dummy_cycles - 1; + dev->lcd_user.lcd_dout_cyclelen = data_cycles - 1; +} + +static inline void lcd_ll_set_blank_cycles(lcd_cam_dev_t *dev, uint32_t fk_cycles, uint32_t bk_cycles) +{ + dev->lcd_misc.lcd_bk_en = (fk_cycles || bk_cycles); + dev->lcd_misc.lcd_vfk_cyclelen = fk_cycles - 1; + dev->lcd_misc.lcd_vbk_cyclelen = bk_cycles - 1; +} + +static inline void lcd_ll_set_data_width(lcd_cam_dev_t *dev, uint32_t width) +{ + dev->lcd_user.lcd_2byte_en = (width == 16); +} + +static inline uint32_t lcd_ll_get_data_width(lcd_cam_dev_t *dev) +{ + return dev->lcd_user.lcd_2byte_en ? 16 : 8; +} + +static inline void lcd_ll_enable_output_always_on(lcd_cam_dev_t *dev, bool en) +{ + dev->lcd_user.lcd_always_out_en = en; +} + +static inline void lcd_ll_start(lcd_cam_dev_t *dev) +{ + dev->lcd_user.lcd_update = 1; // update parameters before start transaction + dev->lcd_user.lcd_start = 1; +} + +static inline void lcd_ll_stop(lcd_cam_dev_t *dev) +{ + dev->lcd_user.lcd_start = 0; + dev->lcd_user.lcd_update = 1; // self clear +} + +static inline void lcd_ll_reset(lcd_cam_dev_t *dev) +{ + dev->lcd_user.lcd_reset = 1; + dev->lcd_user.lcd_reset = 0; +} + +static inline void lcd_ll_reverse_data_bit_order(lcd_cam_dev_t *dev, bool en) +{ + // whether to change LCD_DATA_out[N:0] to LCD_DATA_out[0:N] + dev->lcd_user.lcd_bit_order = en; +} + +static inline void lcd_ll_reverse_data_byte_order(lcd_cam_dev_t *dev, uint32_t data_width, bool en) +{ + if (data_width == 8) { + dev->lcd_user.lcd_8bits_order = en; // valid in 8bit mode + dev->lcd_user.lcd_byte_order = 0; + } else if (data_width == 16) { + dev->lcd_user.lcd_byte_order = en; // valid in 16bit mode + dev->lcd_user.lcd_8bits_order = 0; + } +} + +static inline void lcd_ll_fifo_reset(lcd_cam_dev_t *dev) +{ + dev->lcd_misc.lcd_afifo_reset = 1; + dev->lcd_misc.lcd_afifo_reset = 0; +} + +static inline void lcd_ll_set_dc_level(lcd_cam_dev_t *dev, bool idle_phase, bool cmd_phase, bool dummy_phase, bool data_phase) +{ + dev->lcd_misc.lcd_cd_idle_edge = idle_phase; + dev->lcd_misc.lcd_cd_cmd_set = (cmd_phase != idle_phase); + dev->lcd_misc.lcd_cd_dummy_set = (dummy_phase != idle_phase); + dev->lcd_misc.lcd_cd_data_set = (data_phase != idle_phase); +} + +static inline void lcd_ll_set_dc_delay_ticks(lcd_cam_dev_t *dev, uint32_t delay) +{ + dev->lcd_dly_mode.lcd_cd_mode = delay; +} + +static inline void lcd_ll_set_command(lcd_cam_dev_t *dev, uint32_t data_width, uint32_t command) +{ + // if command phase has two cycles, in the first cycle, command[15:0] is sent out via lcd_data_out[15:0] + // in the second cycle, command[31:16] is sent out via lcd_data_out[15:0] + // no matter the LCD is in 8bit mode or 16bit mode + // so this is a workaround especially for 8bit mode + if (data_width == 8) { + command = (command & 0xFF) | (command & 0xFF00) << 8; + } + dev->lcd_cmd_val = command; +} + +static inline void lcd_ll_enable_rgb_mode(lcd_cam_dev_t *dev, bool en) +{ + dev->lcd_ctrl.lcd_rgb_mode_en = en; +} + +static inline void lcd_ll_enable_auto_next_frame(lcd_cam_dev_t *dev, bool en) +{ + // in RGB mode, enabling "next frame" means LCD controller keeps sending frame data + dev->lcd_misc.lcd_next_frame_en = en; +} + +static inline void lcd_ll_set_horizontal_timing(lcd_cam_dev_t *dev, uint32_t hsw, uint32_t hbp, uint32_t active_width, uint32_t hfp) +{ + dev->lcd_ctrl2.lcd_hsync_width = hsw; + dev->lcd_ctrl.lcd_hb_front = hbp; + dev->lcd_ctrl1.lcd_ha_width = active_width; + dev->lcd_ctrl1.lcd_ht_width = hsw + hbp + active_width + hfp; +} + +static inline void lcd_ll_set_vertical_timing(lcd_cam_dev_t *dev, uint32_t vsw, uint32_t vbp, uint32_t active_height, uint32_t vfp) +{ + dev->lcd_ctrl2.lcd_vsync_width = vsw; + dev->lcd_ctrl1.lcd_vb_front = vbp; + dev->lcd_ctrl.lcd_va_height = active_height; + dev->lcd_ctrl.lcd_vt_height = vsw + vbp + active_height + vfp; +} + +static inline void lcd_ll_set_idle_level(lcd_cam_dev_t *dev, bool hsync_idle_level, bool vsync_idle_level, bool de_idle_level) +{ + dev->lcd_ctrl2.lcd_hsync_idle_pol = hsync_idle_level; + dev->lcd_ctrl2.lcd_vsync_idle_pol = vsync_idle_level; + dev->lcd_ctrl2.lcd_de_idle_pol = de_idle_level; +} + +static inline void lcd_ll_set_delay_ticks(lcd_cam_dev_t *dev, uint32_t hsync_delay, uint32_t vsync_delay, uint32_t de_delay) +{ + dev->lcd_dly_mode.lcd_hsync_mode = hsync_delay; + dev->lcd_dly_mode.lcd_vsync_mode = vsync_delay; + dev->lcd_dly_mode.lcd_de_mode = de_delay; +} + +static inline void lcd_ll_set_data_delay_ticks(lcd_cam_dev_t *dev, uint32_t delay) +{ + uint32_t reg_val = 0; + for (int i = 0; i < 16; i++) { + reg_val |= (delay & 0x03) << (2 * i); + } + dev->lcd_data_dout_mode.val = reg_val; +} + +static inline void lcd_ll_enable_interrupt(lcd_cam_dev_t *dev, uint32_t mask, bool en) +{ + if (en) { + dev->lc_dma_int_ena.val |= mask & 0x03; + } else { + dev->lc_dma_int_ena.val &= ~(mask & 0x03); + } +} + +static inline uint32_t lcd_ll_get_interrupt_status(lcd_cam_dev_t *dev) +{ + return dev->lc_dma_int_st.val & 0x03; +} + +static inline void lcd_ll_clear_interrupt_status(lcd_cam_dev_t *dev, uint32_t mask) +{ + dev->lc_dma_int_clr.val = mask & 0x03; +} + +static inline uint32_t lcd_ll_get_interrupt_status_reg(lcd_cam_dev_t *dev) +{ + return (uint32_t)(&dev->lc_dma_int_st); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/lcd_hal.h b/components/hal/include/hal/lcd_hal.h new file mode 100644 index 0000000000..a6bcba166c --- /dev/null +++ b/components/hal/include/hal/lcd_hal.h @@ -0,0 +1,37 @@ +// Copyright 2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed 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. + +/******************************************************************************* + * NOTICE + * The HAL is not public api, don't use in application code. + * See readme.md in soc/README.md + ******************************************************************************/ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "soc/lcd_cam_struct.h" + +typedef struct { + lcd_cam_dev_t *dev; +} lcd_hal_context_t; + +void lcd_hal_init(lcd_hal_context_t *hal, int id); + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/lcd_hal.c b/components/hal/lcd_hal.c new file mode 100644 index 0000000000..f08d67ac1b --- /dev/null +++ b/components/hal/lcd_hal.c @@ -0,0 +1,21 @@ +// Copyright 2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed 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. + +#include "hal/lcd_hal.h" +#include "hal/lcd_ll.h" + +void lcd_hal_init(lcd_hal_context_t *hal, int id) +{ + hal->dev = LCD_LL_GET_HW(id); +} diff --git a/components/soc/esp32s3/CMakeLists.txt b/components/soc/esp32s3/CMakeLists.txt index 3a33c3186f..61312030dd 100644 --- a/components/soc/esp32s3/CMakeLists.txt +++ b/components/soc/esp32s3/CMakeLists.txt @@ -7,6 +7,7 @@ set(srcs "i2c_periph.c" "i2s_periph.c" "interrupts.c" + "lcd_periph.c" "ledc_periph.c" "pcnt_periph.c" "rmt_periph.c" diff --git a/components/soc/esp32s3/include/soc/lcd_cam_struct.h b/components/soc/esp32s3/include/soc/lcd_cam_struct.h index 397a896715..56a8bdd8f7 100644 --- a/components/soc/esp32s3/include/soc/lcd_cam_struct.h +++ b/components/soc/esp32s3/include/soc/lcd_cam_struct.h @@ -13,190 +13,190 @@ // limitations under the License. #pragma once +#include + #ifdef __cplusplus extern "C" { #endif -#include - typedef volatile struct { union { struct { - uint32_t lcd_clkcnt_n: 6; /*f_LCD_PCLK = f_LCD_CLK / (reg_clkcnt_N + 1) when reg_clk_equ_sysclk is 0.*/ - uint32_t lcd_clk_equ_sysclk: 1; /*1: f_LCD_PCLK = f_LCD_CLK. 0: f_LCD_PCLK = f_LCD_CLK / (reg_clkcnt_N + 1).*/ - uint32_t lcd_ck_idle_edge: 1; /*1: LCD_PCLK line is high when idle 0: LCD_PCLK line is low when idle.*/ - uint32_t lcd_ck_out_edge: 1; - uint32_t lcd_clkm_div_num: 8; /*Integral LCD clock divider value*/ - uint32_t lcd_clkm_div_b: 6; /*Fractional clock divider numerator value*/ - uint32_t lcd_clkm_div_a: 6; /*Fractional clock divider denominator value*/ - uint32_t lcd_clk_sel: 2; /*Select LCD module source clock. 0: no clock. 1: APLL. 2: CLK160. 3: no clock.*/ - uint32_t clk_en: 1; /*Set this bit to enable clk gate*/ + uint32_t lcd_clkcnt_n: 6; /*f_LCD_PCLK = f_LCD_CLK / (reg_clkcnt_N + 1) when reg_clk_equ_sysclk is 0.*/ + uint32_t lcd_clk_equ_sysclk: 1; /*1: f_LCD_PCLK = f_LCD_CLK. 0: f_LCD_PCLK = f_LCD_CLK / (reg_clkcnt_N + 1).*/ + uint32_t lcd_ck_idle_edge: 1; /*1: LCD_PCLK line is high when idle 0: LCD_PCLK line is low when idle.*/ + uint32_t lcd_ck_out_edge: 1; /*1: LCD_PCLK is high on the first half clock 0: LCD_PCLK is high on the second half clock*/ + uint32_t lcd_clkm_div_num: 8; /*Integral LCD clock divider value*/ + uint32_t lcd_clkm_div_b: 6; /*Fractional clock divider numerator value*/ + uint32_t lcd_clkm_div_a: 6; /*Fractional clock divider denominator value*/ + uint32_t lcd_clk_sel: 2; /*Select LCD module source clock. 0: no clock. 1: APLL. 2: CLK160. 3: no clock.*/ + uint32_t clk_en: 1; /*Set this bit to enable clk gate*/ }; uint32_t val; } lcd_clock; union { struct { - uint32_t cam_stop_en: 1; /*Camera stop enable signal 1: camera stops when DMA Rx FIFO is full. 0: Not stop.*/ - uint32_t cam_vsync_filter_thres: 3; /*Filter threshold value for CAM_VSYNC signal.*/ - uint32_t cam_update: 1; /*1: Update Camera registers will be cleared by hardware. 0 : Not care.*/ - uint32_t cam_byte_order: 1; /*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.*/ - uint32_t cam_bit_order: 1; /*1: invert data byte order only valid in 2 byte mode. 0: Not change.*/ - uint32_t cam_line_int_en: 1; /*1: Enable to generate CAM_HS_INT. 0: Disable.*/ - uint32_t cam_vs_eof_en: 1; /*1: CAM_VSYNC to generate in_suc_eof. 0: in_suc_eof is controlled by reg_cam_rec_data_cyclelen.*/ - uint32_t cam_clkm_div_num: 8; /*Integral Camera clock divider value*/ - uint32_t cam_clkm_div_b: 6; /*Fractional clock divider numerator value*/ - uint32_t cam_clkm_div_a: 6; /*Fractional clock divider denominator value*/ - uint32_t cam_clk_sel: 2; /*Select Camera module source clock. 0: no clock. 1: APLL. 2: CLK160. 3: no clock.*/ - uint32_t reserved31: 1; /*reserved*/ + uint32_t cam_stop_en: 1; /*Camera stop enable signal 1: camera stops when DMA Rx FIFO is full. 0: Not stop.*/ + uint32_t cam_vsync_filter_thres: 3; /*Filter threshold value for CAM_VSYNC signal.*/ + uint32_t cam_update: 1; /*1: Update Camera registers will be cleared by hardware. 0 : Not care.*/ + uint32_t cam_byte_order: 1; /*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.*/ + uint32_t cam_bit_order: 1; /*1: invert data byte order only valid in 2 byte mode. 0: Not change.*/ + uint32_t cam_line_int_en: 1; /*1: Enable to generate CAM_HS_INT. 0: Disable.*/ + uint32_t cam_vs_eof_en: 1; /*1: CAM_VSYNC to generate in_suc_eof. 0: in_suc_eof is controlled by reg_cam_rec_data_cyclelen.*/ + uint32_t cam_clkm_div_num: 8; /*Integral Camera clock divider value*/ + uint32_t cam_clkm_div_b: 6; /*Fractional clock divider numerator value*/ + uint32_t cam_clkm_div_a: 6; /*Fractional clock divider denominator value*/ + uint32_t cam_clk_sel: 2; /*Select Camera module source clock. 0: no clock. 1: APLL. 2: CLK160. 3: no clock.*/ + uint32_t reserved31: 1; /*reserved*/ }; uint32_t val; } cam_ctrl; union { struct { - uint32_t cam_rec_data_bytelen: 14; /*Camera receive data byte length minus 1 to set DMA in_suc_eof_int.*/ - uint32_t cam_line_int_num: 7; /*The line number minus 1 to generate cam_hs_int.*/ - uint32_t cam_clk_inv: 1; /*1: Invert the input signal CAM_PCLK. 0: Not invert.*/ - uint32_t reserved22: 1; - uint32_t cam_vsync_filter_en: 1; /*1: Enable CAM_VSYNC filter function. 0: bypass.*/ - uint32_t cam_2byte_en: 1; /*1: The bit number of input data is 9~16. 0: The bit number of input data is 0~8.*/ - uint32_t cam_de_inv: 1; /*CAM_DE invert enable signal valid in high level.*/ - uint32_t cam_hsync_inv: 1; /*CAM_HSYNC invert enable signal valid in high level.*/ - uint32_t cam_vsync_inv: 1; /*CAM_VSYNC invert enable signal valid in high level.*/ - uint32_t cam_vh_de_mode_en: 1; /*1: Input control signals are CAM_DE CAM_HSYNC and CAM_VSYNC is 1. 0: Input control signals are CAM_DE and CAM_VSYNC*/ - uint32_t cam_start: 1; /*Camera module start signal.*/ - uint32_t cam_reset: 1; /*Camera module reset signal.*/ - uint32_t cam_afifo_reset: 1; /*Camera AFIFO reset signal.*/ + uint32_t cam_rec_data_bytelen: 14; /*Camera receive data byte length minus 1 to set DMA in_suc_eof_int.*/ + uint32_t cam_line_int_num: 7; /*The line number minus 1 to generate cam_hs_int.*/ + uint32_t cam_clk_inv: 1; /*1: Invert the input signal CAM_PCLK. 0: Not invert.*/ + uint32_t reserved22: 1; /*Reserved*/ + uint32_t cam_vsync_filter_en: 1; /*1: Enable CAM_VSYNC filter function. 0: bypass.*/ + uint32_t cam_2byte_en: 1; /*1: The bit number of input data is 9~16. 0: The bit number of input data is 0~8.*/ + uint32_t cam_de_inv: 1; /*CAM_DE invert enable signal valid in high level.*/ + uint32_t cam_hsync_inv: 1; /*CAM_HSYNC invert enable signal valid in high level.*/ + uint32_t cam_vsync_inv: 1; /*CAM_VSYNC invert enable signal valid in high level.*/ + uint32_t cam_vh_de_mode_en: 1; /*1: Input control signals are CAM_DE CAM_HSYNC and CAM_VSYNC is 1. 0: Input control signals are CAM_DE and CAM_VSYNC*/ + uint32_t cam_start: 1; /*Camera module start signal.*/ + uint32_t cam_reset: 1; /*Camera module reset signal.*/ + uint32_t cam_afifo_reset: 1; /*Camera AFIFO reset signal.*/ }; uint32_t val; } cam_ctrl1; union { struct { - uint32_t reserved0: 21; /*reserved*/ - uint32_t cam_conv_8bits_data_inv: 1; /*1:invert every two 8bits input data. 2. disabled.*/ - uint32_t cam_conv_yuv2yuv_mode: 2; /*0: to yuv422. 1: to yuv420. 2: to yuv411. 3: disabled. To enable yuv2yuv mode trans_mode must be set to 1.*/ - uint32_t cam_conv_yuv_mode: 2; /*0: yuv422. 1: yuv420. 2: yuv411. When in yuv2yuv mode yuv_mode decides the yuv mode of Data_in*/ - uint32_t cam_conv_protocol_mode: 1; /*0:BT601. 1:BT709.*/ - uint32_t cam_conv_data_out_mode: 1; /*LIMIT or FULL mode of Data out. 0: limit. 1: full*/ - uint32_t cam_conv_data_in_mode: 1; /*LIMIT or FULL mode of Data in. 0: limit. 1: full*/ - uint32_t cam_conv_mode_8bits_on: 1; /*0: 16bits mode. 1: 8bits mode.*/ - uint32_t cam_conv_trans_mode: 1; /*0: YUV to RGB. 1: RGB to YUV.*/ - uint32_t cam_conv_bypass: 1; /*0: Bypass converter. 1: Enable converter.*/ + uint32_t reserved0: 21; /*reserved*/ + uint32_t cam_conv_8bits_data_inv: 1; /*1:invert every two 8bits input data. 2. disabled.*/ + uint32_t cam_conv_yuv2yuv_mode: 2; /*0: to yuv422. 1: to yuv420. 2: to yuv411. 3: disabled. To enable yuv2yuv mode trans_mode must be set to 1.*/ + uint32_t cam_conv_yuv_mode: 2; /*0: yuv422. 1: yuv420. 2: yuv411. When in yuv2yuv mode yuv_mode decides the yuv mode of Data_in*/ + uint32_t cam_conv_protocol_mode: 1; /*0:BT601. 1:BT709.*/ + uint32_t cam_conv_data_out_mode: 1; /*LIMIT or FULL mode of Data out. 0: limit. 1: full*/ + uint32_t cam_conv_data_in_mode: 1; /*LIMIT or FULL mode of Data in. 0: limit. 1: full*/ + uint32_t cam_conv_mode_8bits_on: 1; /*0: 16bits mode. 1: 8bits mode.*/ + uint32_t cam_conv_trans_mode: 1; /*0: YUV to RGB. 1: RGB to YUV.*/ + uint32_t cam_conv_bypass: 1; /*0: Bypass converter. 1: Enable converter.*/ }; uint32_t val; } cam_rgb_yuv; union { struct { - uint32_t reserved0: 20; /*reserved*/ - uint32_t lcd_conv_8bits_data_inv: 1; /*1:invert every two 8bits input data. 2. disabled.*/ - uint32_t lcd_conv_txtorx: 1; /*0: txtorx mode off. 1: txtorx mode on.*/ - uint32_t lcd_conv_yuv2yuv_mode: 2; /*0: to yuv422. 1: to yuv420. 2: to yuv411. 3: disabled. To enable yuv2yuv mode trans_mode must be set to 1.*/ - uint32_t lcd_conv_yuv_mode: 2; /*0: yuv422. 1: yuv420. 2: yuv411. When in yuv2yuv mode yuv_mode decides the yuv mode of Data_in*/ - uint32_t lcd_conv_protocol_mode: 1; /*0:BT601. 1:BT709.*/ - uint32_t lcd_conv_data_out_mode: 1; /*LIMIT or FULL mode of Data out. 0: limit. 1: full*/ - uint32_t lcd_conv_data_in_mode: 1; /*LIMIT or FULL mode of Data in. 0: limit. 1: full*/ - uint32_t lcd_conv_mode_8bits_on: 1; /*0: 16bits mode. 1: 8bits mode.*/ - uint32_t lcd_conv_trans_mode: 1; /*0: YUV to RGB. 1: RGB to YUV.*/ - uint32_t lcd_conv_bypass: 1; /*0: Bypass converter. 1: Enable converter.*/ + uint32_t reserved0: 20; /*reserved*/ + uint32_t lcd_conv_8bits_data_inv: 1; /*1:invert every two 8bits input data. 2. disabled.*/ + uint32_t lcd_conv_txtorx: 1; /*0: txtorx mode off. 1: txtorx mode on.*/ + uint32_t lcd_conv_yuv2yuv_mode: 2; /*0: to yuv422. 1: to yuv420. 2: to yuv411. 3: disabled. To enable yuv2yuv mode trans_mode must be set to 1.*/ + uint32_t lcd_conv_yuv_mode: 2; /*0: yuv422. 1: yuv420. 2: yuv411. When in yuv2yuv mode yuv_mode decides the yuv mode of Data_in*/ + uint32_t lcd_conv_protocol_mode: 1; /*0:BT601. 1:BT709.*/ + uint32_t lcd_conv_data_out_mode: 1; /*LIMIT or FULL mode of Data out. 0: limit. 1: full*/ + uint32_t lcd_conv_data_in_mode: 1; /*LIMIT or FULL mode of Data in. 0: limit. 1: full*/ + uint32_t lcd_conv_mode_8bits_on: 1; /*0: 16bits mode. 1: 8bits mode.*/ + uint32_t lcd_conv_trans_mode: 1; /*0: YUV to RGB. 1: RGB to YUV.*/ + uint32_t lcd_conv_bypass: 1; /*0: Bypass converter. 1: Enable converter.*/ }; uint32_t val; } lcd_rgb_yuv; union { struct { - uint32_t lcd_dout_cyclelen: 13; /*The output data cycles minus 1 of LCD module.*/ - uint32_t lcd_always_out_en: 1; /*LCD always output when LCD is in LCD_DOUT state unless reg_lcd_start is cleared or reg_lcd_reset is set.*/ - uint32_t reserved14: 5; /*reserved*/ - uint32_t lcd_8bits_order: 1; /*1: invert every two data byte valid in 1 byte mode. 0: Not change.*/ - uint32_t lcd_update: 1; /*1: Update LCD registers will be cleared by hardware. 0 : Not care.*/ - uint32_t lcd_bit_order: 1; /*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.*/ - uint32_t lcd_byte_order: 1; /*1: invert data byte order only valid in 2 byte mode. 0: Not change.*/ - uint32_t lcd_2byte_en: 1; /*1: The bit number of output LCD data is 9~16. 0: The bit number of output LCD data is 0~8.*/ - uint32_t lcd_dout: 1; /*1: Be able to send data out in LCD sequence when LCD starts. 0: Disable.*/ - uint32_t lcd_dummy: 1; /*1: Enable DUMMY phase in LCD sequence when LCD starts. 0: Disable.*/ - uint32_t lcd_cmd: 1; /*1: Be able to send command in LCD sequence when LCD starts. 0: Disable.*/ - uint32_t lcd_start: 1; /*LCD start sending data enable signal valid in high level.*/ - uint32_t lcd_reset: 1; /*The value of command.*/ - uint32_t lcd_dummy_cyclelen: 2; /*The dummy cycle length minus 1.*/ - uint32_t lcd_cmd_2_cycle_en: 1; /*The cycle length of command phase*/ + uint32_t lcd_dout_cyclelen: 13; /*The output data cycles minus 1 of LCD module.*/ + uint32_t lcd_always_out_en: 1; /*LCD always output when LCD is in LCD_DOUT state unless reg_lcd_start is cleared or reg_lcd_reset is set.*/ + uint32_t reserved14: 5; /*reserved*/ + uint32_t lcd_8bits_order: 1; /*1: invert every two data byte valid in 1 byte mode. 0: Not change.*/ + uint32_t lcd_update: 1; /*1: Update LCD registers will be cleared by hardware. 0 : Not care.*/ + uint32_t lcd_bit_order: 1; /*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.*/ + uint32_t lcd_byte_order: 1; /*1: invert data byte order only valid in 2 byte mode. 0: Not change.*/ + uint32_t lcd_2byte_en: 1; /*1: The bit number of output LCD data is 0~15. 0: The bit number of output LCD data is 0~7.*/ + uint32_t lcd_dout: 1; /*1: Be able to send data out in LCD sequence when LCD starts. 0: Disable.*/ + uint32_t lcd_dummy: 1; /*1: Enable DUMMY phase in LCD sequence when LCD starts. 0: Disable.*/ + uint32_t lcd_cmd: 1; /*1: Be able to send command in LCD sequence when LCD starts. 0: Disable.*/ + uint32_t lcd_start: 1; /*LCD start sending data enable signal valid in high level.*/ + uint32_t lcd_reset: 1; /*The value of command.*/ + uint32_t lcd_dummy_cyclelen: 2; /*The dummy cycle length minus 1.*/ + uint32_t lcd_cmd_2_cycle_en: 1; /*The cycle length of command phase*/ }; uint32_t val; } lcd_user; union { struct { - uint32_t reserved0: 1; /*reserved*/ - uint32_t lcd_afifo_threshold_num: 5; /*The awfull threshold number of lcd_afifo.*/ - uint32_t lcd_vfk_cyclelen: 6; /*The setup cycle length minus 1 in LCD non-RGB mode.*/ - uint32_t lcd_vbk_cyclelen: 13; /*The vertical back blank region cycle length minus 1 in LCD RGB mode or the hold time cycle length in LCD non-RGB mode.*/ - uint32_t lcd_next_frame_en: 1; /*1: Send the next frame data when the current frame is sent out. 0: LCD stops when the current frame is sent out.*/ - uint32_t lcd_bk_en: 1; /*1: Enable blank region when LCD sends data out. 0: No blank region.*/ - uint32_t lcd_afifo_reset: 1; /*LCD AFIFO reset signal.*/ - uint32_t lcd_cd_data_set: 1; /*1: LCD_CD = !reg_cd_idle_edge when lcd_st[2:0] is in LCD_DOUT state. 0: LCD_CD = reg_cd_idle_edge.*/ - uint32_t lcd_cd_dummy_set: 1; /*1: LCD_CD = !reg_cd_idle_edge when lcd_st[2:0] is in LCD_DUMMY state. 0: LCD_CD = reg_cd_idle_edge.*/ - uint32_t lcd_cd_cmd_set: 1; /*1: LCD_CD = !reg_cd_idle_edge when lcd_st[2:0] is in LCD_CMD state. 0: LCD_CD = reg_cd_idle_edge.*/ - uint32_t lcd_cd_idle_edge: 1; /*The default value of LCD_CD.*/ + uint32_t reserved0: 1; /*reserved*/ + uint32_t lcd_afifo_threshold_num: 5; /*The awfull threshold number of lcd_afifo.*/ + uint32_t lcd_vfk_cyclelen: 6; /*The setup cycle length minus 1 in LCD non-RGB mode.*/ + uint32_t lcd_vbk_cyclelen: 13; /*The vertical back blank region cycle length minus 1 in LCD RGB mode or the hold time cycle length in LCD non-RGB mode.*/ + uint32_t lcd_next_frame_en: 1; /*1: Send the next frame data when the current frame is sent out. 0: LCD stops when the current frame is sent out.*/ + uint32_t lcd_bk_en: 1; /*1: Enable blank region when LCD sends data out. 0: No blank region.*/ + uint32_t lcd_afifo_reset: 1; /*LCD AFIFO reset signal.*/ + uint32_t lcd_cd_data_set: 1; /*1: LCD_CD = !reg_cd_idle_edge when lcd_st[2:0] is in LCD_DOUT state. 0: LCD_CD = reg_cd_idle_edge.*/ + uint32_t lcd_cd_dummy_set: 1; /*1: LCD_CD = !reg_cd_idle_edge when lcd_st[2:0] is in LCD_DUMMY state. 0: LCD_CD = reg_cd_idle_edge.*/ + uint32_t lcd_cd_cmd_set: 1; /*1: LCD_CD = !reg_cd_idle_edge when lcd_st[2:0] is in LCD_CMD state. 0: LCD_CD = reg_cd_idle_edge.*/ + uint32_t lcd_cd_idle_edge: 1; /*The default value of LCD_CD.*/ }; uint32_t val; } lcd_misc; union { struct { - uint32_t lcd_hb_front: 11; /*It is the horizontal blank front porch of a frame.*/ - uint32_t lcd_va_height: 10; /*It is the vertical active height of a frame.*/ - uint32_t lcd_vt_height: 10; /*It is the vertical total height of a frame.*/ - uint32_t lcd_rgb_mode_en: 1; /*1: Enable reg mode input vsync*/ + uint32_t lcd_hb_front: 11; /*It is the horizontal blank front porch of a frame.*/ + uint32_t lcd_va_height: 10; /*It is the vertical active height of a frame.*/ + uint32_t lcd_vt_height: 10; /*It is the vertical total height of a frame.*/ + uint32_t lcd_rgb_mode_en: 1; /*1: Enable reg mode input vsync*/ }; uint32_t val; } lcd_ctrl; union { struct { - uint32_t lcd_vb_front: 8; /*It is the vertical blank front porch of a frame.*/ - uint32_t lcd_ha_width: 12; /*It is the horizontal active width of a frame.*/ - uint32_t lcd_ht_width: 12; /*It is the horizontal total width of a frame.*/ + uint32_t lcd_vb_front: 8; /*It is the vertical blank front porch of a frame.*/ + uint32_t lcd_ha_width: 12; /*It is the horizontal active width of a frame.*/ + uint32_t lcd_ht_width: 12; /*It is the horizontal total width of a frame.*/ }; uint32_t val; } lcd_ctrl1; union { struct { - uint32_t lcd_vsync_width: 7; /*It is the position of LCD_VSYNC active pulse in a line.*/ - uint32_t lcd_vsync_idle_pol: 1; /*It is the idle value of LCD_VSYNC.*/ - uint32_t lcd_de_idle_pol: 1; /*It is the idle value of LCD_DE.*/ - uint32_t lcd_hs_blank_en: 1; /*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.*/ - uint32_t reserved10: 6; /*reserved*/ - uint32_t lcd_hsync_width: 7; /*It is the position of LCD_HSYNC active pulse in a line.*/ - uint32_t lcd_hsync_idle_pol: 1; /*It is the idle value of LCD_HSYNC.*/ - uint32_t lcd_hsync_position: 8; /*It is the position of LCD_HSYNC active pulse in a line.*/ + uint32_t lcd_vsync_width: 7; /*It is the position of LCD_VSYNC active pulse in a line.*/ + uint32_t lcd_vsync_idle_pol: 1; /*It is the idle value of LCD_VSYNC.*/ + uint32_t lcd_de_idle_pol: 1; /*It is the idle value of LCD_DE.*/ + uint32_t lcd_hs_blank_en: 1; /*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.*/ + uint32_t reserved10: 6; /*reserved*/ + uint32_t lcd_hsync_width: 7; /*It is the position of LCD_HSYNC active pulse in a line.*/ + uint32_t lcd_hsync_idle_pol: 1; /*It is the idle value of LCD_HSYNC.*/ + uint32_t lcd_hsync_position: 8; /*It is the position of LCD_HSYNC active pulse in a line.*/ }; uint32_t val; } lcd_ctrl2; - uint32_t lcd_cmd_val; /*The LCD write command value.*/ + uint32_t lcd_cmd_val; /*The LCD write command value.*/ uint32_t reserved_2c; union { struct { - uint32_t lcd_cd_mode: 2; /*The output LCD_CD is delayed by module clock LCD_CLK*/ - uint32_t lcd_de_mode: 2; /*The output LCD_DE is delayed by module clock LCD_CLK*/ - uint32_t lcd_hsync_mode: 2; /*The output LCD_HSYNC is delayed by module clock LCD_CLK*/ - uint32_t lcd_vsync_mode: 2; /*The output LCD_VSYNC is delayed by module clock LCD_CLK*/ - uint32_t reserved8: 24; /*reserved*/ + uint32_t lcd_cd_mode: 2; /*The output LCD_CD is delayed by module clock LCD_CLK*/ + uint32_t lcd_de_mode: 2; /*The output LCD_DE is delayed by module clock LCD_CLK*/ + uint32_t lcd_hsync_mode: 2; /*The output LCD_HSYNC is delayed by module clock LCD_CLK*/ + uint32_t lcd_vsync_mode: 2; /*The output LCD_VSYNC is delayed by module clock LCD_CLK*/ + uint32_t reserved8: 24; /*reserved*/ }; uint32_t val; } lcd_dly_mode; uint32_t reserved_34; union { struct { - uint32_t dout0_mode: 2; /*The output data bit $n is delayed by module clock LCD_CLK*/ - uint32_t dout1_mode: 2; /*The output data bit $n is delayed by module clock LCD_CLK*/ - uint32_t dout2_mode: 2; /*The output data bit $n is delayed by module clock LCD_CLK*/ - uint32_t dout3_mode: 2; /*The output data bit $n is delayed by module clock LCD_CLK*/ - uint32_t dout4_mode: 2; /*The output data bit $n is delayed by module clock LCD_CLK*/ - uint32_t dout5_mode: 2; /*The output data bit $n is delayed by module clock LCD_CLK*/ - uint32_t dout6_mode: 2; /*The output data bit $n is delayed by module clock LCD_CLK*/ - uint32_t dout7_mode: 2; /*The output data bit $n is delayed by module clock LCD_CLK*/ - uint32_t dout8_mode: 2; /*The output data bit $n is delayed by module clock LCD_CLK*/ - uint32_t dout9_mode: 2; /*The output data bit $n is delayed by module clock LCD_CLK*/ - uint32_t dout10_mode: 2; /*The output data bit $n is delayed by module clock LCD_CLK*/ - uint32_t dout11_mode: 2; /*The output data bit $n is delayed by module clock LCD_CLK*/ - uint32_t dout12_mode: 2; /*The output data bit $n is delayed by module clock LCD_CLK*/ - uint32_t dout13_mode: 2; /*The output data bit $n is delayed by module clock LCD_CLK*/ - uint32_t dout14_mode: 2; /*The output data bit $n is delayed by module clock LCD_CLK*/ - uint32_t dout15_mode: 2; /*The output data bit $n is delayed by module clock LCD_CLK*/ + uint32_t dout0_mode: 2; /*The output data bit $n is delayed by module clock LCD_CLK*/ + uint32_t dout1_mode: 2; /*The output data bit $n is delayed by module clock LCD_CLK*/ + uint32_t dout2_mode: 2; /*The output data bit $n is delayed by module clock LCD_CLK*/ + uint32_t dout3_mode: 2; /*The output data bit $n is delayed by module clock LCD_CLK*/ + uint32_t dout4_mode: 2; /*The output data bit $n is delayed by module clock LCD_CLK*/ + uint32_t dout5_mode: 2; /*The output data bit $n is delayed by module clock LCD_CLK*/ + uint32_t dout6_mode: 2; /*The output data bit $n is delayed by module clock LCD_CLK*/ + uint32_t dout7_mode: 2; /*The output data bit $n is delayed by module clock LCD_CLK*/ + uint32_t dout8_mode: 2; /*The output data bit $n is delayed by module clock LCD_CLK*/ + uint32_t dout9_mode: 2; /*The output data bit $n is delayed by module clock LCD_CLK*/ + uint32_t dout10_mode: 2; /*The output data bit $n is delayed by module clock LCD_CLK*/ + uint32_t dout11_mode: 2; /*The output data bit $n is delayed by module clock LCD_CLK*/ + uint32_t dout12_mode: 2; /*The output data bit $n is delayed by module clock LCD_CLK*/ + uint32_t dout13_mode: 2; /*The output data bit $n is delayed by module clock LCD_CLK*/ + uint32_t dout14_mode: 2; /*The output data bit $n is delayed by module clock LCD_CLK*/ + uint32_t dout15_mode: 2; /*The output data bit $n is delayed by module clock LCD_CLK*/ }; uint32_t val; } lcd_data_dout_mode; @@ -212,41 +212,41 @@ typedef volatile struct { uint32_t reserved_60; union { struct { - uint32_t lcd_vsync: 1; /*The enable bit for LCD frame end interrupt.*/ - uint32_t lcd_trans_done: 1; /*The enable bit for lcd transfer end interrupt.*/ - uint32_t cam_vsync: 1; /*The enable bit for Camera frame end interrupt.*/ - uint32_t cam_hs: 1; /*The enable bit for Camera line interrupt.*/ - uint32_t reserved4: 28; /*reserved*/ + uint32_t lcd_vsync: 1; /*The enable bit for LCD frame end interrupt.*/ + uint32_t lcd_trans_done: 1; /*The enable bit for lcd transfer end interrupt.*/ + uint32_t cam_vsync: 1; /*The enable bit for Camera frame end interrupt.*/ + uint32_t cam_hs: 1; /*The enable bit for Camera line interrupt.*/ + uint32_t reserved4: 28; /*reserved*/ }; uint32_t val; } lc_dma_int_ena; union { struct { - uint32_t lcd_vsync: 1; /*The raw bit for LCD frame end interrupt.*/ - uint32_t lcd_trans_done: 1; /*The raw bit for lcd transfer end interrupt.*/ - uint32_t cam_vsync: 1; /*The raw bit for Camera frame end interrupt.*/ - uint32_t cam_hs: 1; /*The raw bit for Camera line interrupt.*/ - uint32_t reserved4: 28; /*reserved*/ + uint32_t lcd_vsync: 1; /*The raw bit for LCD frame end interrupt.*/ + uint32_t lcd_trans_done: 1; /*The raw bit for lcd transfer end interrupt.*/ + uint32_t cam_vsync: 1; /*The raw bit for Camera frame end interrupt.*/ + uint32_t cam_hs: 1; /*The raw bit for Camera line interrupt.*/ + uint32_t reserved4: 28; /*reserved*/ }; uint32_t val; } lc_dma_int_raw; union { struct { - uint32_t lcd_vsync: 1; /*The status bit for LCD frame end interrupt.*/ - uint32_t lcd_trans_done: 1; /*The status bit for lcd transfer end interrupt.*/ - uint32_t cam_vsync: 1; /*The status bit for Camera frame end interrupt.*/ - uint32_t cam_hs: 1; /*The status bit for Camera transfer end interrupt.*/ - uint32_t reserved4: 28; /*reserved*/ + uint32_t lcd_vsync: 1; /*The status bit for LCD frame end interrupt.*/ + uint32_t lcd_trans_done: 1; /*The status bit for lcd transfer end interrupt.*/ + uint32_t cam_vsync: 1; /*The status bit for Camera frame end interrupt.*/ + uint32_t cam_hs: 1; /*The status bit for Camera transfer end interrupt.*/ + uint32_t reserved4: 28; /*reserved*/ }; uint32_t val; } lc_dma_int_st; union { struct { - uint32_t lcd_vsync: 1; /*The clear bit for LCD frame end interrupt.*/ - uint32_t lcd_trans_done: 1; /*The clear bit for lcd transfer end interrupt.*/ - uint32_t cam_vsync: 1; /*The clear bit for Camera frame end interrupt.*/ - uint32_t cam_hs: 1; /*The clear bit for Camera line interrupt.*/ - uint32_t reserved4: 28; /*reserved*/ + uint32_t lcd_vsync: 1; /*The clear bit for LCD frame end interrupt.*/ + uint32_t lcd_trans_done: 1; /*The clear bit for lcd transfer end interrupt.*/ + uint32_t cam_vsync: 1; /*The clear bit for Camera frame end interrupt.*/ + uint32_t cam_hs: 1; /*The clear bit for Camera line interrupt.*/ + uint32_t reserved4: 28; /*reserved*/ }; uint32_t val; } lc_dma_int_clr; @@ -286,8 +286,8 @@ typedef volatile struct { uint32_t reserved_f8; union { struct { - uint32_t lc_date: 28; /*LCD_CAM version control register*/ - uint32_t reserved28: 4; /*reserved*/ + uint32_t lc_date: 28; /*LCD_CAM version control register*/ + uint32_t reserved28: 4; /*reserved*/ }; uint32_t val; } lc_date; diff --git a/components/soc/esp32s3/include/soc/periph_defs.h b/components/soc/esp32s3/include/soc/periph_defs.h index 33a6517d47..ad53c5e2e8 100644 --- a/components/soc/esp32s3/include/soc/periph_defs.h +++ b/components/soc/esp32s3/include/soc/periph_defs.h @@ -28,6 +28,7 @@ typedef enum { PERIPH_I2C1_MODULE, PERIPH_I2S0_MODULE, PERIPH_I2S1_MODULE, + PERIPH_LCD_CAM_MODULE, PERIPH_TIMG0_MODULE, PERIPH_TIMG1_MODULE, PERIPH_PWM0_MODULE, @@ -149,7 +150,6 @@ typedef enum { ETS_CACHE_CORE0_ACS_INTR_SOURCE, ETS_CACHE_CORE1_ACS_INTR_SOURCE, ETS_MAX_INTR_SOURCE, /**< number of interrupt sources */ - } periph_interrput_t; #ifdef __cplusplus diff --git a/components/soc/esp32s3/include/soc/soc_caps.h b/components/soc/esp32s3/include/soc/soc_caps.h index d3b5eb2c45..f6ceceb8b7 100644 --- a/components/soc/esp32s3/include/soc/soc_caps.h +++ b/components/soc/esp32s3/include/soc/soc_caps.h @@ -9,6 +9,7 @@ #define SOC_PCNT_SUPPORTED 1 #define SOC_TWAI_SUPPORTED 1 #define SOC_GDMA_SUPPORTED 1 +#define SOC_I80_LCD_SUPPORTED 1 #define SOC_DEDICATED_GPIO_SUPPORTED 1 #define SOC_CPU_CORES_NUM 2 #define SOC_CACHE_SUPPORT_WRAP 1 @@ -71,6 +72,12 @@ #define SOC_RMT_SUPPORT_TX_SYNCHRO (1) /*!< Support coordinate a group of TX channels to start simultaneously */ #define SOC_RMT_SUPPORT_XTAL (1) /*!< Support set XTAL clock as the RMT clock source */ + +/*-------------------------- LCD CAPS ----------------------------------------*/ +#define SOC_LCD_I80_BUSES (1) /*!< Has one LCD Intel 8080 bus */ +#define SOC_LCD_RGB_PANELS (1) /*!< Support one RGB LCD panel */ +#define SOC_LCD_MAX_DATA_WIDTH (16) /*!< Maximum number of LCD data lines */ + /*-------------------------- RTCIO CAPS --------------------------------------*/ #include "rtc_io_caps.h" diff --git a/components/soc/esp32s3/lcd_periph.c b/components/soc/esp32s3/lcd_periph.c new file mode 100644 index 0000000000..f59c4886f5 --- /dev/null +++ b/components/soc/esp32s3/lcd_periph.c @@ -0,0 +1,74 @@ +// Copyright 2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed 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. + +#include "soc/lcd_periph.h" +#include "soc/gpio_sig_map.h" + +const lcd_signal_conn_t lcd_periph_signals = { + .buses = { + [0] = { + .module = PERIPH_LCD_CAM_MODULE, + .irq_id = ETS_LCD_CAM_INTR_SOURCE, + .data_sigs = { + LCD_DATA_OUT0_IDX, + LCD_DATA_OUT1_IDX, + LCD_DATA_OUT2_IDX, + LCD_DATA_OUT3_IDX, + LCD_DATA_OUT4_IDX, + LCD_DATA_OUT5_IDX, + LCD_DATA_OUT6_IDX, + LCD_DATA_OUT7_IDX, + LCD_DATA_OUT8_IDX, + LCD_DATA_OUT9_IDX, + LCD_DATA_OUT10_IDX, + LCD_DATA_OUT11_IDX, + LCD_DATA_OUT12_IDX, + LCD_DATA_OUT13_IDX, + LCD_DATA_OUT14_IDX, + LCD_DATA_OUT15_IDX, + }, + .cs_sig = LCD_CS_IDX, + .dc_sig = LCD_DC_IDX, + .wr_sig = LCD_PCLK_IDX + } + }, + .panels = { + [0] = { + .module = PERIPH_LCD_CAM_MODULE, + .irq_id = ETS_LCD_CAM_INTR_SOURCE, + .data_sigs = { + LCD_DATA_OUT0_IDX, + LCD_DATA_OUT1_IDX, + LCD_DATA_OUT2_IDX, + LCD_DATA_OUT3_IDX, + LCD_DATA_OUT4_IDX, + LCD_DATA_OUT5_IDX, + LCD_DATA_OUT6_IDX, + LCD_DATA_OUT7_IDX, + LCD_DATA_OUT8_IDX, + LCD_DATA_OUT9_IDX, + LCD_DATA_OUT10_IDX, + LCD_DATA_OUT11_IDX, + LCD_DATA_OUT12_IDX, + LCD_DATA_OUT13_IDX, + LCD_DATA_OUT14_IDX, + LCD_DATA_OUT15_IDX, + }, + .hsync_sig = LCD_H_SYNC_IDX, + .vsync_sig = LCD_V_SYNC_IDX, + .pclk_sig = LCD_PCLK_IDX, + .de_sig = LCD_H_ENABLE_IDX, + } + } +}; diff --git a/components/soc/include/soc/lcd_periph.h b/components/soc/include/soc/lcd_periph.h new file mode 100644 index 0000000000..fd56a06f27 --- /dev/null +++ b/components/soc/include/soc/lcd_periph.h @@ -0,0 +1,48 @@ +// Copyright 2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed 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. + +#pragma once + +#include "soc/soc_caps.h" +#include "soc/periph_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + struct { + const periph_module_t module; + const int irq_id; + const int data_sigs[SOC_LCD_MAX_DATA_WIDTH]; + const int cs_sig; + const int dc_sig; + const int wr_sig; + } buses[SOC_LCD_I80_BUSES]; + struct { + const periph_module_t module; + const int irq_id; + const int data_sigs[SOC_LCD_MAX_DATA_WIDTH]; + const int hsync_sig; + const int vsync_sig; + const int pclk_sig; + const int de_sig; + } panels[SOC_LCD_RGB_PANELS]; +} lcd_signal_conn_t; + +extern const lcd_signal_conn_t lcd_periph_signals; + +#ifdef __cplusplus +} +#endif