mirror of
https://github.com/espressif/esp-idf.git
synced 2025-09-19 08:03:59 +00:00
feat(lcd): pre-support rgb and i80 lcd driver on esp32p4
added LL functions for LCD_CAM module, only the LCD part
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -29,6 +29,42 @@ extern "C" {
|
||||
#define LCD_LL_CLK_FRAC_DIV_AB_MAX 64 // LCD_CLK = LCD_CLK_S / (N + b/a), the a/b register is 6 bit-width
|
||||
#define LCD_LL_PCLK_DIV_MAX 64 // LCD_PCLK = LCD_CLK / MO, the MO register is 6 bit-width
|
||||
|
||||
/**
|
||||
* @brief LCD data byte swizzle mode
|
||||
*/
|
||||
typedef enum {
|
||||
LCD_LL_SWIZZLE_AB2BA, /*!< AB -> BA */
|
||||
} lcd_ll_swizzle_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Enable or disable the bus clock for the LCD module
|
||||
*
|
||||
* @param set_bit True to set bit, false to clear bit
|
||||
*/
|
||||
static inline void lcd_ll_enable_bus_clock(int group_id, bool enable)
|
||||
{
|
||||
(void)group_id;
|
||||
SYSTEM.perip_clk_en1.lcd_cam_clk_en = enable;
|
||||
}
|
||||
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
/// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance
|
||||
#define lcd_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; lcd_ll_enable_bus_clock(__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @brief Reset the LCD module
|
||||
*/
|
||||
static inline void lcd_ll_reset_register(int group_id)
|
||||
{
|
||||
(void)group_id;
|
||||
SYSTEM.perip_rst_en1.lcd_cam_rst = 0x01;
|
||||
SYSTEM.perip_rst_en1.lcd_cam_rst = 0x00;
|
||||
}
|
||||
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
/// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance
|
||||
#define lcd_ll_reset_register(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; lcd_ll_reset_register(__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @brief Enable clock gating
|
||||
*
|
||||
@@ -326,15 +362,35 @@ static inline void lcd_ll_set_blank_cycles(lcd_cam_dev_t *dev, uint32_t fk_cycle
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set data line width
|
||||
* @brief Set data read stride, i.e., number of bytes the LCD reads from the DMA in each step
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param width data line width (8 or 16)
|
||||
* @param stride data stride size
|
||||
*/
|
||||
static inline void lcd_ll_set_data_width(lcd_cam_dev_t *dev, uint32_t width)
|
||||
static inline void lcd_ll_set_dma_read_stride(lcd_cam_dev_t *dev, uint32_t stride)
|
||||
{
|
||||
HAL_ASSERT(width == 8 || width == 16);
|
||||
dev->lcd_user.lcd_2byte_en = (width == 16);
|
||||
switch (stride) {
|
||||
case 8:
|
||||
dev->lcd_user.lcd_2byte_en = 0;
|
||||
break;
|
||||
case 16:
|
||||
dev->lcd_user.lcd_2byte_en = 1;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the wire width of LCD output
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param width LCD output wire width
|
||||
*/
|
||||
static inline void lcd_ll_set_data_wire_width(lcd_cam_dev_t *dev, uint32_t width)
|
||||
{
|
||||
// data line width is same as data stride that set in `lcd_ll_set_dma_read_stride`
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -386,36 +442,69 @@ static inline void lcd_ll_reset(lcd_cam_dev_t *dev)
|
||||
/**
|
||||
* @brief Whether to reverse the data bit order
|
||||
*
|
||||
* @note It acts before the YUV-RGB converter
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param en True to reverse, False to not reverse
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void lcd_ll_reverse_bit_order(lcd_cam_dev_t *dev, bool en)
|
||||
static inline void lcd_ll_reverse_dma_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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Whether to reverse the output data bit order
|
||||
*
|
||||
* @note ESP32S3 doesn't support to reverse the data bit after the YUV-RGB converter
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param en True to reverse, False to not reverse
|
||||
*/
|
||||
static inline void lcd_ll_reverse_wire_bit_order(lcd_cam_dev_t *dev, bool en)
|
||||
{
|
||||
(void)dev;
|
||||
(void)en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Whether to swap adjacent two bytes
|
||||
*
|
||||
* @note This acts before the YUV-RGB converter, mainly to change the data endian.
|
||||
* {B1,B0},{B3,B2} => {B0,B1}{B2,B3}
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param width Bus width
|
||||
* @param en True to swap the byte order, False to not swap
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void lcd_ll_swap_byte_order(lcd_cam_dev_t *dev, uint32_t width, bool en)
|
||||
static inline void lcd_ll_swap_dma_data_byte_order(lcd_cam_dev_t *dev, bool en)
|
||||
{
|
||||
HAL_ASSERT(width == 8 || width == 16);
|
||||
if (width == 8) {
|
||||
// {B0}{B1}{B2}{B3} => {B1}{B0}{B3}{B2}
|
||||
dev->lcd_user.lcd_8bits_order = en;
|
||||
dev->lcd_user.lcd_byte_order = 0;
|
||||
} else if (width == 16) {
|
||||
// {B1,B0},{B3,B2} => {B0,B1}{B2,B3}
|
||||
dev->lcd_user.lcd_byte_order = en;
|
||||
dev->lcd_user.lcd_8bits_order = 0;
|
||||
}
|
||||
dev->lcd_user.lcd_byte_order = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the byte swizzle
|
||||
*
|
||||
* @note The swizzle module acts after the YUV-RGB converter, used to reorder the data bytes before the data wire
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param en True to enable, False to disable
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void lcd_ll_enable_swizzle(lcd_cam_dev_t *dev, bool en)
|
||||
{
|
||||
dev->lcd_user.lcd_8bits_order = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set data byte swizzle mode
|
||||
*
|
||||
* @param dev LCD register base address
|
||||
* @param mode Swizzle mode
|
||||
*/
|
||||
static inline void lcd_ll_set_swizzle_mode(lcd_cam_dev_t *dev, lcd_ll_swizzle_mode_t mode)
|
||||
{
|
||||
HAL_ASSERT(mode == LCD_LL_SWIZZLE_AB2BA);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -652,35 +741,6 @@ static inline volatile void *lcd_ll_get_interrupt_status_reg(lcd_cam_dev_t *dev)
|
||||
return &dev->lc_dma_int_st;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable or disable the bus clock for the LCD module
|
||||
*
|
||||
* @param set_bit True to set bit, false to clear bit
|
||||
*/
|
||||
static inline void lcd_ll_enable_bus_clock(int group_id, bool enable)
|
||||
{
|
||||
(void)group_id;
|
||||
SYSTEM.perip_clk_en1.lcd_cam_clk_en = enable;
|
||||
}
|
||||
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
/// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance
|
||||
#define lcd_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; lcd_ll_enable_bus_clock(__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @brief Reset the LCD module
|
||||
*/
|
||||
static inline void lcd_ll_reset_register(int group_id)
|
||||
{
|
||||
(void)group_id;
|
||||
SYSTEM.perip_rst_en1.lcd_cam_rst = 0x01;
|
||||
SYSTEM.perip_rst_en1.lcd_cam_rst = 0x00;
|
||||
}
|
||||
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
/// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance
|
||||
#define lcd_ll_reset_register(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; lcd_ll_reset_register(__VA_ARGS__)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user