kopia lustrzana https://github.com/espressif/esp-idf
lcd: improve LL driver according to TRM
rodzic
1938d7c006
commit
2ab7d92785
|
@ -164,7 +164,7 @@ esp_err_t esp_lcd_new_i80_bus(const esp_lcd_i80_bus_config_t *bus_config, esp_lc
|
|||
// enable 8080 mode and set bus width
|
||||
lcd_ll_enable_rgb_mode(bus->hal.dev, false);
|
||||
lcd_ll_set_data_width(bus->hal.dev, bus_config->bus_width);
|
||||
bus->bus_width = lcd_ll_get_data_width(bus->hal.dev);
|
||||
bus->bus_width = bus_config->bus_width;
|
||||
// number of data cycles is controlled by DMA buffer size
|
||||
lcd_ll_enable_output_always_on(bus->hal.dev, true);
|
||||
// enable trans done interrupt
|
||||
|
@ -389,7 +389,7 @@ static esp_err_t panel_io_i80_tx_param(esp_lcd_panel_io_t *io, int lcd_cmd, cons
|
|||
// switch devices if necessary
|
||||
lcd_i80_switch_devices(cur_device, next_device);
|
||||
// set data format
|
||||
lcd_ll_reverse_data_byte_order(bus->hal.dev, false);
|
||||
lcd_ll_swap_data_byte_order(bus->hal.dev, false);
|
||||
lcd_ll_reverse_data_bit_order(bus->hal.dev, false);
|
||||
lcd_ll_reverse_data_8bits_order(bus->hal.dev, next_device->lcd_param_bits > bus->bus_width);
|
||||
bus->cur_trans = NULL;
|
||||
|
@ -462,7 +462,8 @@ static esp_err_t panel_io_i80_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, cons
|
|||
static esp_err_t lcd_i80_select_periph_clock(esp_lcd_i80_bus_handle_t bus, lcd_clock_source_t clk_src)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
lcd_ll_set_group_clock_src(bus->hal.dev, clk_src, LCD_PERIPH_CLOCK_PRE_SCALE, 1, 0);
|
||||
// force to use integer division, as fractional division might lead to clock jitter
|
||||
lcd_ll_set_group_clock_src(bus->hal.dev, clk_src, LCD_PERIPH_CLOCK_PRE_SCALE, 0, 0);
|
||||
switch (clk_src) {
|
||||
case LCD_CLK_SRC_PLL160M:
|
||||
bus->resolution_hz = 160000000 / LCD_PERIPH_CLOCK_PRE_SCALE;
|
||||
|
@ -639,7 +640,7 @@ IRAM_ATTR static void lcd_default_isr_handler(void *args)
|
|||
lcd_i80_switch_devices(cur_device, next_device);
|
||||
// only reverse data bit/bytes for color data
|
||||
lcd_ll_reverse_data_bit_order(bus->hal.dev, next_device->flags.reverse_color_bits);
|
||||
lcd_ll_reverse_data_byte_order(bus->hal.dev, next_device->flags.swap_color_bytes);
|
||||
lcd_ll_swap_data_byte_order(bus->hal.dev, next_device->flags.swap_color_bytes);
|
||||
lcd_ll_reverse_data_8bits_order(bus->hal.dev, false);
|
||||
bus->cur_trans = trans_desc;
|
||||
bus->cur_device = next_device;
|
||||
|
|
|
@ -439,7 +439,8 @@ static esp_err_t lcd_rgb_panel_configure_gpio(esp_rgb_panel_t *panel, const esp_
|
|||
static esp_err_t lcd_rgb_panel_select_periph_clock(esp_rgb_panel_t *panel, lcd_clock_source_t clk_src)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
lcd_ll_set_group_clock_src(panel->hal.dev, clk_src, LCD_PERIPH_CLOCK_PRE_SCALE, 1, 0);
|
||||
// force to use integer division, as fractional division might lead to clock jitter
|
||||
lcd_ll_set_group_clock_src(panel->hal.dev, clk_src, LCD_PERIPH_CLOCK_PRE_SCALE, 0, 0);
|
||||
switch (clk_src) {
|
||||
case LCD_CLK_SRC_PLL160M:
|
||||
panel->resolution_hz = 160000000 / LCD_PERIPH_CLOCK_PRE_SCALE;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
@ -26,15 +26,34 @@ extern "C" {
|
|||
// Maximum coefficient of clock prescaler
|
||||
#define LCD_LL_CLOCK_PRESCALE_MAX (64)
|
||||
|
||||
/**
|
||||
* @brief Enable clock gating
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param en True to enable, False to disable
|
||||
*/
|
||||
static inline void lcd_ll_enable_clock(lcd_cam_dev_t *dev, bool en)
|
||||
{
|
||||
dev->lcd_clock.clk_en = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set clock source for LCD peripheral
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param src Clock source
|
||||
* @param div_num Integer part of the divider
|
||||
* @param div_a denominator of the divider
|
||||
* @param div_b numerator of the divider
|
||||
*/
|
||||
static inline void lcd_ll_set_group_clock_src(lcd_cam_dev_t *dev, lcd_clock_source_t src, int div_num, int div_a, int div_b)
|
||||
{
|
||||
// lcd_clk = module_clock_src / (div_num + div_b / div_a)
|
||||
HAL_ASSERT(div_num >= 2);
|
||||
HAL_ASSERT(div_num >= 2 && div_num <= 256);
|
||||
// dic_num == 0 means 256 divider in hardware
|
||||
if (div_num >= 256) {
|
||||
div_num = 0;
|
||||
}
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(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;
|
||||
|
@ -42,40 +61,85 @@ static inline void lcd_ll_set_group_clock_src(lcd_cam_dev_t *dev, lcd_clock_sour
|
|||
case LCD_CLK_SRC_PLL160M:
|
||||
dev->lcd_clock.lcd_clk_sel = 3;
|
||||
break;
|
||||
case LCD_CLK_SRC_PLL240M:
|
||||
dev->lcd_clock.lcd_clk_sel = 2;
|
||||
break;
|
||||
case LCD_CLK_SRC_XTAL:
|
||||
dev->lcd_clock.lcd_clk_sel = 1;
|
||||
break;
|
||||
default:
|
||||
// disble LCD clock source
|
||||
dev->lcd_clock.lcd_clk_sel = 0;
|
||||
HAL_ASSERT(false && "unsupported clock source");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set the PCLK clock level state when there's no transaction undergoing
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param level 1 is high level, 0 is low level
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void lcd_ll_set_clock_idle_level(lcd_cam_dev_t *dev, bool level)
|
||||
{
|
||||
dev->lcd_clock.lcd_ck_idle_edge = level;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the PCLK sample edge
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param active_on_neg True: sample on negedge, False: sample on posedge
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set PCLK prescale
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param prescale Prescale value, PCLK = LCD_CLK / prescale
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
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;
|
||||
// clkcnt_n can't be zero
|
||||
uint32_t scale = 1;
|
||||
if (prescale == 1) {
|
||||
dev->lcd_clock.lcd_clk_equ_sysclk = 1;
|
||||
} else {
|
||||
dev->lcd_clock.lcd_clk_equ_sysclk = 0;
|
||||
scale = prescale - 1;
|
||||
}
|
||||
dev->lcd_clock.lcd_clkcnt_n = scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable YUV-RGB converter
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param en True to enable converter, False to disable converter
|
||||
*/
|
||||
static inline void lcd_ll_enable_rgb_yuv_convert(lcd_cam_dev_t *dev, bool en)
|
||||
{
|
||||
dev->lcd_rgb_yuv.lcd_conv_bypass = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set clock cycles of each transaction phases
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param cmd_cycles Clock cycles of CMD phase
|
||||
* @param dummy_cycles Clock cycles of DUMMY phase
|
||||
* @param data_cycles Clock cycles of DATA phase
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
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)
|
||||
{
|
||||
|
@ -88,6 +152,13 @@ static inline void lcd_ll_set_phase_cycles(lcd_cam_dev_t *dev, uint32_t cmd_cycl
|
|||
dev->lcd_user.lcd_dout_cyclelen = data_cycles - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set clock cycles of blank phases
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param fk_cycles Clock cycles of front blank
|
||||
* @param bk_cycles Clock cycles of back blank
|
||||
*/
|
||||
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);
|
||||
|
@ -95,21 +166,35 @@ static inline void lcd_ll_set_blank_cycles(lcd_cam_dev_t *dev, uint32_t fk_cycle
|
|||
dev->lcd_misc.lcd_vbk_cyclelen = bk_cycles - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set data line width
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param width data line width (8 or 16)
|
||||
*/
|
||||
static inline void lcd_ll_set_data_width(lcd_cam_dev_t *dev, uint32_t width)
|
||||
{
|
||||
HAL_ASSERT(width == 8 || width == 16);
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Whether to continue the data phase when the DMA has content to send
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param en True: The number of data cycles will be controller by DMA buffer size, instead of lcd_dout_cyclelen
|
||||
* False: The number of data cycles will be controlled by lcd_dout_cyclelen
|
||||
*/
|
||||
static inline void lcd_ll_enable_output_always_on(lcd_cam_dev_t *dev, bool en)
|
||||
{
|
||||
dev->lcd_user.lcd_always_out_en = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start the LCD transaction
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void lcd_ll_start(lcd_cam_dev_t *dev)
|
||||
{
|
||||
|
@ -117,18 +202,33 @@ static inline void lcd_ll_start(lcd_cam_dev_t *dev)
|
|||
dev->lcd_user.lcd_start = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stop the LCD transaction
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
*/
|
||||
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
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset LCD TX controller and RGB/YUV converter
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
*/
|
||||
static inline void lcd_ll_reset(lcd_cam_dev_t *dev)
|
||||
{
|
||||
dev->lcd_user.lcd_reset = 1;
|
||||
dev->lcd_user.lcd_reset = 0;
|
||||
dev->lcd_user.lcd_reset = 1; // self clear
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Whether to reverse the data bit order
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param en True to reverse, False to not reverse
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void lcd_ll_reverse_data_bit_order(lcd_cam_dev_t *dev, bool en)
|
||||
{
|
||||
|
@ -136,24 +236,49 @@ static inline void lcd_ll_reverse_data_bit_order(lcd_cam_dev_t *dev, bool en)
|
|||
dev->lcd_user.lcd_bit_order = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Whether to swap data byte order, i.e. data[15:0] -> data[7:0][15:8]
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param en True to swap the byte order, False to not swap
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void lcd_ll_reverse_data_byte_order(lcd_cam_dev_t *dev, bool en)
|
||||
static inline void lcd_ll_swap_data_byte_order(lcd_cam_dev_t *dev, bool en)
|
||||
{
|
||||
dev->lcd_user.lcd_byte_order = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Whether to reverse the 8bits order
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param en True to reverse, False to not reverse
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void lcd_ll_reverse_data_8bits_order(lcd_cam_dev_t *dev, bool en)
|
||||
{
|
||||
dev->lcd_user.lcd_8bits_order = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset Async TX FIFO
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
*/
|
||||
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;
|
||||
dev->lcd_misc.lcd_afifo_reset = 1; // self clear
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the level state of DC line, on different transaction phases
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param idle_phase Level state of DC line on IDLE phase
|
||||
* @param cmd_phase Level state of DC line on CMD phase
|
||||
* @param dummy_phase Level state of DC line on DUMMY phase
|
||||
* @param data_phase Level state of DC line on DATA phase
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
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)
|
||||
{
|
||||
|
@ -163,14 +288,28 @@ static inline void lcd_ll_set_dc_level(lcd_cam_dev_t *dev, bool idle_phase, bool
|
|||
dev->lcd_misc.lcd_cd_data_set = (data_phase != idle_phase);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set cycle of delay for DC line
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param delay Ticks of delay
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the LCD command (the data at CMD phase)
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param data_width Data line width
|
||||
* @param command command value
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void lcd_ll_set_command(lcd_cam_dev_t *dev, uint32_t data_width, uint32_t command)
|
||||
{
|
||||
HAL_ASSERT(data_width == 8 || data_width == 16);
|
||||
// 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]
|
||||
if (data_width == 8) {
|
||||
|
@ -179,27 +318,60 @@ static inline void lcd_ll_set_command(lcd_cam_dev_t *dev, uint32_t data_width, u
|
|||
dev->lcd_cmd_val.lcd_cmd_value = command;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wether to enable RGB interface
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param en True to enable RGB interface, False to disable RGB interface
|
||||
*/
|
||||
static inline void lcd_ll_enable_rgb_mode(lcd_cam_dev_t *dev, bool en)
|
||||
{
|
||||
dev->lcd_ctrl.lcd_rgb_mode_en = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Whether to send the next frame automatically
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param en True to enable, False to disable
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wether to output HSYNC signal in porch resion
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param en True to enable, False to disable
|
||||
*/
|
||||
static inline void lcd_ll_enable_output_hsync_in_porch_region(lcd_cam_dev_t *dev, bool en)
|
||||
{
|
||||
dev->lcd_ctrl2.lcd_hs_blank_en = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set HSYNC signal offset in the line
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param offset_in_line Offset value
|
||||
*/
|
||||
static inline void lcd_ll_set_hsync_position(lcd_cam_dev_t *dev, uint32_t offset_in_line)
|
||||
{
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->lcd_ctrl2, lcd_hsync_position, offset_in_line);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set RGB LCD horizontal timing
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param hsw Horizontal sync width
|
||||
* @param hbp Horizontal back porch
|
||||
* @param active_width Horizontal active width
|
||||
* @param hfp Horizontal front porch
|
||||
*/
|
||||
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 - 1;
|
||||
|
@ -208,6 +380,15 @@ static inline void lcd_ll_set_horizontal_timing(lcd_cam_dev_t *dev, uint32_t hsw
|
|||
dev->lcd_ctrl1.lcd_ht_width = hsw + hbp + active_width + hfp - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set RGB vertical timing
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param vsw Vertical sync width
|
||||
* @param vbp Vertical back porch
|
||||
* @param active_height Vertical active height
|
||||
* @param vfp Vertical front porch
|
||||
*/
|
||||
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 - 1;
|
||||
|
@ -216,6 +397,14 @@ static inline void lcd_ll_set_vertical_timing(lcd_cam_dev_t *dev, uint32_t vsw,
|
|||
dev->lcd_ctrl.lcd_vt_height = vsw + vbp + active_height + vfp - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set level state for hsync, vsync, de at IDLE phase
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param hsync_idle_level HSYNC level on IDLE phase
|
||||
* @param vsync_idle_level VSYNC level on IDLE phase
|
||||
* @param de_idle_level DE level on IDLE phase
|
||||
*/
|
||||
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;
|
||||
|
@ -223,6 +412,14 @@ static inline void lcd_ll_set_idle_level(lcd_cam_dev_t *dev, bool hsync_idle_lev
|
|||
dev->lcd_ctrl2.lcd_de_idle_pol = de_idle_level;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set extra delay for HSYNC, VSYNC, and DE signals
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param hsync_delay HSYNC delay
|
||||
* @param vsync_delay VSYNC delay
|
||||
* @param de_delay DE delay
|
||||
*/
|
||||
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;
|
||||
|
@ -230,6 +427,12 @@ static inline void lcd_ll_set_delay_ticks(lcd_cam_dev_t *dev, uint32_t hsync_del
|
|||
dev->lcd_dly_mode.lcd_de_mode = de_delay;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set extra delay for data lines
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param delay Data line delay
|
||||
*/
|
||||
static inline void lcd_ll_set_data_delay_ticks(lcd_cam_dev_t *dev, uint32_t delay)
|
||||
{
|
||||
uint32_t reg_val = 0;
|
||||
|
@ -239,6 +442,13 @@ static inline void lcd_ll_set_data_delay_ticks(lcd_cam_dev_t *dev, uint32_t dela
|
|||
dev->lcd_data_dout_mode.val = reg_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable/disable interrupt by mask
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param mask Interrupt mask
|
||||
* @param en True to enable interrupt, False to disable interrupt
|
||||
*/
|
||||
static inline void lcd_ll_enable_interrupt(lcd_cam_dev_t *dev, uint32_t mask, bool en)
|
||||
{
|
||||
if (en) {
|
||||
|
@ -248,18 +458,36 @@ static inline void lcd_ll_enable_interrupt(lcd_cam_dev_t *dev, uint32_t mask, bo
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get interrupt status value
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @return Interrupt status value
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t lcd_ll_get_interrupt_status(lcd_cam_dev_t *dev)
|
||||
{
|
||||
return dev->lc_dma_int_st.val & 0x03;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear interrupt status by mask
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param mask Interupt status mask
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void lcd_ll_clear_interrupt_status(lcd_cam_dev_t *dev, uint32_t mask)
|
||||
{
|
||||
dev->lc_dma_int_clr.val = mask & 0x03;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get address of interrupt status register address
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @return Interrupt status register address
|
||||
*/
|
||||
static inline volatile void *lcd_ll_get_interrupt_status_reg(lcd_cam_dev_t *dev)
|
||||
{
|
||||
return &dev->lc_dma_int_st;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
@ -19,6 +19,8 @@ extern "C" {
|
|||
* +=====================+=========================+============================+
|
||||
* | LCD_CLK_SRC_PLL160M | High resolution | ESP_PM_APB_FREQ_MAX lock |
|
||||
* +---------------------+-------------------------+----------------------------+
|
||||
* | LCD_CLK_SRC_PLL240M | High resolution | ESP_PM_APB_FREQ_MAX lock |
|
||||
* +---------------------+-------------------------+----------------------------+
|
||||
* | LCD_CLK_SRC_APLL | Configurable resolution | ESP_PM_NO_LIGHT_SLEEP lock |
|
||||
* +---------------------+-------------------------+----------------------------+
|
||||
* | LCD_CLK_SRC_XTAL | Medium resolution | No PM lock |
|
||||
|
@ -27,6 +29,7 @@ extern "C" {
|
|||
*/
|
||||
typedef enum {
|
||||
LCD_CLK_SRC_PLL160M, /*!< Select PLL160M as the source clock */
|
||||
LCD_CLK_SRC_PLL240M, /*!< Select PLL240M as the source clock */
|
||||
LCD_CLK_SRC_APLL, /*!< Select APLL as the source clock */
|
||||
LCD_CLK_SRC_XTAL, /*!< Select XTAL as the source clock */
|
||||
} lcd_clock_source_t;
|
||||
|
|
|
@ -18,5 +18,4 @@
|
|||
#define SOC_GDMA_TRIG_PERIPH_AES0 (6)
|
||||
#define SOC_GDMA_TRIG_PERIPH_SHA0 (7)
|
||||
#define SOC_GDMA_TRIG_PERIPH_ADC0 (8)
|
||||
#define SOC_GDMA_TRIG_PERIPH_DAC0 (8)
|
||||
#define SOC_GDMA_TRIG_PERIPH_RMT0 (9)
|
||||
|
|
Ładowanie…
Reference in New Issue