Skip to content

Commit

Permalink
Merge branch 'feature/esp_lcd_st7789_rgb_data_endian_config' into 'ma…
Browse files Browse the repository at this point in the history
…ster'

feat(st7789): add data endian config

Closes IDFGH-10145

See merge request espressif/esp-idf!25475
  • Loading branch information
suda-morris committed Sep 6, 2023
2 parents cd9eeff + 6f55f76 commit 01f3c93
Show file tree
Hide file tree
Showing 13 changed files with 62 additions and 30 deletions.
6 changes: 4 additions & 2 deletions components/esp_lcd/include/esp_lcd_panel_vendor.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ extern "C" {
typedef struct {
int reset_gpio_num; /*!< GPIO used to reset the LCD panel, set to -1 if it's not used */
union {
lcd_color_rgb_endian_t color_space; /*!< @deprecated Set RGB color space, please use rgb_endian instead */
lcd_color_rgb_endian_t rgb_endian; /*!< Set RGB data endian: RGB or BGR */
lcd_rgb_element_order_t color_space; /*!< @deprecated Set RGB color space, please use rgb_ele_order instead */
lcd_rgb_element_order_t rgb_endian; /*!< @deprecated Set RGB data endian, please use rgb_ele_order instead */
lcd_rgb_element_order_t rgb_ele_order; /*!< Set RGB element order, RGB or BGR */
};
lcd_rgb_data_endian_t data_endian; /*!< Set the data endian for color data larger than 1 byte */
unsigned int bits_per_pixel; /*!< Color depth, in bpp */
struct {
unsigned int reset_active_high: 1; /*!< Setting this if the panel reset is high level active */
Expand Down
4 changes: 2 additions & 2 deletions components/esp_lcd/include/esp_lcd_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ typedef enum {
} esp_lcd_color_space_t __attribute__((deprecated));

// Ensure binary compatibility with lcd_color_rgb_endian_t
ESP_STATIC_ASSERT((lcd_color_rgb_endian_t)ESP_LCD_COLOR_SPACE_RGB == LCD_RGB_ENDIAN_RGB, "ESP_LCD_COLOR_SPACE_RGB is not compatible with LCD_RGB_ENDIAN_RGB");
ESP_STATIC_ASSERT((lcd_color_rgb_endian_t)ESP_LCD_COLOR_SPACE_BGR == LCD_RGB_ENDIAN_BGR, "ESP_LCD_COLOR_SPACE_BGR is not compatible with LCD_RGB_ENDIAN_BGR");
ESP_STATIC_ASSERT((lcd_rgb_element_order_t)ESP_LCD_COLOR_SPACE_RGB == LCD_RGB_ELEMENT_ORDER_RGB, "ESP_LCD_COLOR_SPACE_RGB is not compatible with LCD_RGB_ORDER_RGB");
ESP_STATIC_ASSERT((lcd_rgb_element_order_t)ESP_LCD_COLOR_SPACE_BGR == LCD_RGB_ELEMENT_ORDER_BGR, "ESP_LCD_COLOR_SPACE_BGR is not compatible with LCD_RGB_ORDER_BGR");
/** @endcond */

#ifdef __cplusplus
Expand Down
6 changes: 3 additions & 3 deletions components/esp_lcd/src/esp_lcd_panel_nt35510.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,11 @@ esp_lcd_new_panel_nt35510(const esp_lcd_panel_io_handle_t io, const esp_lcd_pane
ESP_GOTO_ON_ERROR(gpio_config(&io_conf), err, TAG, "configure GPIO for RST line failed");
}

switch (panel_dev_config->rgb_endian) {
case LCD_RGB_ENDIAN_RGB:
switch (panel_dev_config->rgb_ele_order) {
case LCD_RGB_ELEMENT_ORDER_RGB:
nt35510->madctl_val = 0;
break;
case LCD_RGB_ENDIAN_BGR:
case LCD_RGB_ELEMENT_ORDER_BGR:
nt35510->madctl_val |= LCD_CMD_BGR_BIT;
break;
default:
Expand Down
19 changes: 17 additions & 2 deletions components/esp_lcd/src/esp_lcd_panel_st7789.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
#include "esp_log.h"
#include "esp_check.h"

#define ST7789_CMD_RAMCTRL 0xb0
#define ST7789_DATA_LITTLE_ENDIAN_BIT (1 << 3)

static const char *TAG = "lcd_panel.st7789";

static esp_err_t panel_st7789_del(esp_lcd_panel_t *panel);
Expand All @@ -46,8 +49,10 @@ typedef struct {
int x_gap;
int y_gap;
uint8_t fb_bits_per_pixel;
uint8_t madctl_val; // save current value of LCD_CMD_MADCTL register
uint8_t colmod_cal; // save surrent value of LCD_CMD_COLMOD register
uint8_t madctl_val; // save current value of LCD_CMD_MADCTL register
uint8_t colmod_cal; // save surrent value of LCD_CMD_COLMOD register
uint8_t ramctl_val_1;
uint8_t ramctl_val_2;
} st7789_panel_t;

esp_err_t
Expand Down Expand Up @@ -99,6 +104,13 @@ esp_lcd_new_panel_st7789(const esp_lcd_panel_io_handle_t io, const esp_lcd_panel
break;
}

st7789->ramctl_val_1 = 0x00;
st7789->ramctl_val_2 = 0xf0; // Use big endian by default
if((panel_dev_config->data_endian) == LCD_RGB_DATA_ENDIAN_LITTLE) {
// Use little endian
st7789->ramctl_val_2 |= ST7789_DATA_LITTLE_ENDIAN_BIT;
}

st7789->io = io;
st7789->fb_bits_per_pixel = fb_bits_per_pixel;
st7789->reset_gpio_num = panel_dev_config->reset_gpio_num;
Expand Down Expand Up @@ -173,6 +185,9 @@ static esp_err_t panel_st7789_init(esp_lcd_panel_t *panel)
ESP_RETURN_ON_ERROR(esp_lcd_panel_io_tx_param(io, LCD_CMD_COLMOD, (uint8_t[]) {
st7789->colmod_cal,
}, 1), TAG, "io tx param LCD_CMD_COLMOD failed");
ESP_RETURN_ON_ERROR(esp_lcd_panel_io_tx_param(io, ST7789_CMD_RAMCTRL, (uint8_t[]) {
st7789->ramctl_val_1, st7789->ramctl_val_2
}, 2), TAG, "io tx param RAMCTRL failed");

return ESP_OK;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ TEST_CASE("lcd_panel_i80_io_test", "[lcd]")
esp_lcd_panel_handle_t panel_handle = NULL;
esp_lcd_panel_dev_config_t panel_config = {
.reset_gpio_num = TEST_LCD_RST_GPIO,
.rgb_endian = LCD_RGB_ENDIAN_RGB,
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB,
.bits_per_pixel = 16,
};

Expand Down Expand Up @@ -420,7 +420,7 @@ TEST_CASE("lcd_panel_with_i80_interface_(st7789, 8bits)", "[lcd]")
esp_lcd_panel_handle_t panel_handle = NULL;
esp_lcd_panel_dev_config_t panel_config = {
.reset_gpio_num = TEST_LCD_RST_GPIO,
.rgb_endian = LCD_RGB_ENDIAN_RGB,
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB,
.bits_per_pixel = 16,
};
TEST_ESP_OK(esp_lcd_new_panel_st7789(io_handle, &panel_config, &panel_handle));
Expand Down Expand Up @@ -509,7 +509,7 @@ TEST_CASE("i80_lcd_send_colors_to_fixed_region", "[lcd]")
esp_lcd_panel_handle_t panel_handle = NULL;
esp_lcd_panel_dev_config_t panel_config = {
.reset_gpio_num = TEST_LCD_RST_GPIO,
.rgb_endian = LCD_RGB_ENDIAN_RGB,
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB,
.bits_per_pixel = 16,
};
TEST_ESP_OK(esp_lcd_new_panel_st7789(io_handle, &panel_config, &panel_handle));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ TEST_CASE("lcd_panel_with_8-line_spi_interface_(st7789)", "[lcd]")
test_spi_lcd_common_initialize(&io_handle, NULL, NULL, 8, 8, true);
esp_lcd_panel_dev_config_t panel_config = {
.reset_gpio_num = TEST_LCD_RST_GPIO,
.rgb_endian = LCD_RGB_ENDIAN_RGB,
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB,
.bits_per_pixel = 16,
};
TEST_ESP_OK(esp_lcd_new_panel_st7789(io_handle, &panel_config, &panel_handle));
Expand All @@ -171,7 +171,7 @@ TEST_CASE("lcd_panel_with_8-line_spi_interface_(nt35510)", "[lcd]")
test_spi_lcd_common_initialize(&io_handle, NULL, NULL, 16, 16, true);
esp_lcd_panel_dev_config_t panel_config = {
.reset_gpio_num = TEST_LCD_RST_GPIO,
.rgb_endian = LCD_RGB_ENDIAN_RGB,
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB,
.bits_per_pixel = 16,
};
TEST_ESP_OK(esp_lcd_new_panel_nt35510(io_handle, &panel_config, &panel_handle));
Expand All @@ -186,7 +186,7 @@ TEST_CASE("lcd_panel_with_1-line_spi_interface_(st7789)", "[lcd]")
test_spi_lcd_common_initialize(&io_handle, NULL, NULL, 8, 8, false);
esp_lcd_panel_dev_config_t panel_config = {
.reset_gpio_num = TEST_LCD_RST_GPIO,
.rgb_endian = LCD_RGB_ENDIAN_RGB,
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB,
.bits_per_pixel = 16,
};
TEST_ESP_OK(esp_lcd_new_panel_st7789(io_handle, &panel_config, &panel_handle));
Expand All @@ -212,7 +212,7 @@ TEST_CASE("spi_lcd_send_colors_to_fixed_region", "[lcd]")
// we don't use the panel handle in this test, creating the panel just for a quick initialization
esp_lcd_panel_dev_config_t panel_config = {
.reset_gpio_num = TEST_LCD_RST_GPIO,
.rgb_endian = LCD_RGB_ENDIAN_RGB,
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB,
.bits_per_pixel = 16,
};
TEST_ESP_OK(esp_lcd_new_panel_st7789(io_handle, &panel_config, &panel_handle));
Expand Down
19 changes: 16 additions & 3 deletions components/hal/include/hal/lcd_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,22 @@ typedef soc_periph_lcd_clk_src_t lcd_clock_source_t;
* @brief RGB color endian
*/
typedef enum {
LCD_RGB_ENDIAN_RGB, /*!< RGB data endian: RGB */
LCD_RGB_ENDIAN_BGR, /*!< RGB data endian: BGR */
} lcd_color_rgb_endian_t;
LCD_RGB_ELEMENT_ORDER_RGB, /*!< RGB element order: RGB */
LCD_RGB_ELEMENT_ORDER_BGR, /*!< RGB element order: BGR */
} lcd_rgb_element_order_t;

/// for backward compatible
typedef lcd_rgb_element_order_t lcd_color_rgb_endian_t;
#define LCD_RGB_ENDIAN_RGB LCD_RGB_ELEMENT_ORDER_RGB
#define LCD_RGB_ENDIAN_BGR LCD_RGB_ELEMENT_ORDER_BGR

/**
* @brief RGB data endian
*/
typedef enum {
LCD_RGB_DATA_ENDIAN_BIG = 0, /*!< RGB data endian: MSB first */
LCD_RGB_DATA_ENDIAN_LITTLE, /*!< RGB data endian: LSB first */
} lcd_rgb_data_endian_t;

/**
* @brief LCD color space
Expand Down
9 changes: 5 additions & 4 deletions docs/en/api-reference/peripherals/lcd.rst
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,16 @@ SPI Interfaced LCD
#. Install the LCD controller driver. The LCD controller driver is responsible for sending the commands and parameters to the LCD controller chip. In this step, you need to specify the SPI IO device handle that allocated in the last step, and some panel specific configurations:

- :cpp:member:`esp_lcd_panel_dev_config_t::reset_gpio_num` sets the LCD's hardware reset GPIO number. If the LCD does not have a hardware reset pin, set this to ``-1``.
- :cpp:member:`esp_lcd_panel_dev_config_t::rgb_endian` sets the endian of the RGB color data.
- :cpp:member:`esp_lcd_panel_dev_config_t::rgb_ele_order` sets the R-G-B element order of each color data.
- :cpp:member:`esp_lcd_panel_dev_config_t::bits_per_pixel` sets the bit width of the pixel color data. The LCD driver uses this value to calculate the number of bytes to send to the LCD controller chip.
- :cpp:member:`esp_lcd_panel_dev_config_t::data_endian` specifies the data endian to be transmitted to the screen. No need to specify for color data within 1 byte, like RGB232. For drivers that do not support specifying data endian, this field would be ignored.

.. code-block:: c
esp_lcd_panel_handle_t panel_handle = NULL;
esp_lcd_panel_dev_config_t panel_config = {
.reset_gpio_num = EXAMPLE_PIN_NUM_RST,
.rgb_endian = LCD_RGB_ENDIAN_BGR,
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_BGR,
.bits_per_pixel = 16,
};
// Create LCD panel handle for ST7789, with the SPI IO device handle
Expand Down Expand Up @@ -200,13 +201,13 @@ I2C Interfaced LCD

- :cpp:member:`esp_lcd_panel_dev_config_t::bits_per_pixel` sets the bit width of the pixel color data. The LCD driver uses this value to calculate the number of bytes to send to the LCD controller chip.
- :cpp:member:`esp_lcd_panel_dev_config_t::reset_gpio_num` sets the GPIO number of the reset pin. If the LCD controller chip does not have a reset pin, you can set this value to ``-1``.
- :cpp:member:`esp_lcd_panel_dev_config_t::rgb_endian` sets the endian of the pixel color data.
- :cpp:member:`esp_lcd_panel_dev_config_t::rgb_ele_order` sets the color order the pixel color data.

.. code-block:: c
esp_lcd_panel_dev_config_t panel_config = {
.reset_gpio_num = EXAMPLE_PIN_NUM_RST,
.rgb_endian = LCD_RGB_ENDIAN_RGB,
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB,
.bits_per_pixel = 16,
};
ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(io_handle, &panel_config, &panel_handle));
Expand Down
2 changes: 1 addition & 1 deletion docs/en/migration-guides/release-5.x/5.0/peripherals.rst
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ LCD
- The way to register RGB panel event callbacks has been moved from the :cpp:type:`esp_lcd_rgb_panel_config_t` into a separate API :cpp:func:`esp_lcd_rgb_panel_register_event_callbacks`. However, the event callback signature is not changed.
- Previous ``relax_on_idle`` flag in :cpp:type:`esp_lcd_rgb_panel_config_t` has been renamed into :cpp:member:`esp_lcd_rgb_panel_config_t::refresh_on_demand`, which expresses the same meaning but with a clear name.
- If the RGB LCD is created with the ``refresh_on_demand`` flag enabled, the driver will not start a refresh in the :cpp:func:`esp_lcd_panel_draw_bitmap`. Now users have to call :cpp:func:`esp_lcd_rgb_panel_refresh` to refresh the screen by themselves.
- :cpp:type:`esp_lcd_color_space_t` is deprecated, please use :cpp:type:`lcd_color_space_t` to describe the color space, and use :cpp:type:`lcd_color_rgb_endian_t` to describe the data order of RGB color.
- :cpp:type:`esp_lcd_color_space_t` is deprecated, please use :cpp:type:`lcd_color_space_t` to describe the color space, and use :cpp:type:`lcd_rgb_element_order_t` to describe the data order of RGB color.

.. only:: SOC_MCPWM_SUPPORTED

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ LCD
- 更新后,用于注册 RGB 面板的事件回调函数已从 :cpp:type:`esp_lcd_rgb_panel_config_t` 更新为单独的 API :cpp:func:`esp_lcd_rgb_panel_register_event_callbacks`。但是,事件回调签名仍保持不变。
- 更新后, :cpp:type:`esp_lcd_rgb_panel_config_t` 中的标志位 ``relax_on_idle`` 被重命名为 :cpp:member:`esp_lcd_rgb_panel_config_t::refresh_on_demand`,后者虽表达了同样的含义,但是其命名更有意义。
- 更新后,如果创建 RGB LCD 时,标志位 ``refresh_on_demand`` 使能,驱动不会在 :cpp:func:`esp_lcd_panel_draw_bitmap` 中进行刷新,用户需要调用 :cpp:func:`esp_lcd_rgb_panel_refresh` 来刷新屏幕。
- 更新后,:cpp:type:`esp_lcd_color_space_t` 已被弃用,请使用 :cpp:type:`lcd_color_space_t` 来描述色彩空间,使用 :cpp:type:`lcd_color_rgb_endian_t` 来描述 RGB 颜色的排列顺序。
- 更新后,:cpp:type:`esp_lcd_color_space_t` 已被弃用,请使用 :cpp:type:`lcd_color_space_t` 来描述色彩空间,使用 :cpp:type:`lcd_rgb_element_order_t` 来描述 RGB 颜色的排列顺序。

.. only:: SOC_MCPWM_SUPPORTED

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ void app_main(void)
ESP_LOGI(TAG, "Install LCD driver of st7789");
esp_lcd_panel_dev_config_t panel_config = {
.reset_gpio_num = EXAMPLE_PIN_NUM_RST,
.rgb_endian = LCD_RGB_ENDIAN_RGB,
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB,
.bits_per_pixel = 16,
};
ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(io_handle, &panel_config, &panel_handle));
Expand All @@ -226,7 +226,7 @@ void app_main(void)
ESP_LOGI(TAG, "Install LCD driver of nt35510");
esp_lcd_panel_dev_config_t panel_config = {
.reset_gpio_num = EXAMPLE_PIN_NUM_RST,
.rgb_endian = LCD_RGB_ENDIAN_BGR,
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_BGR,
.bits_per_pixel = 16,
};
ESP_ERROR_CHECK(esp_lcd_new_panel_nt35510(io_handle, &panel_config, &panel_handle));
Expand All @@ -244,7 +244,7 @@ void app_main(void)
ESP_LOGI(TAG, "Install LCD driver of ili9341 (st7789 compatible)");
esp_lcd_panel_dev_config_t panel_config = {
.reset_gpio_num = EXAMPLE_PIN_NUM_RST,
.rgb_endian = LCD_RGB_ENDIAN_BGR,
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_BGR,
.bits_per_pixel = 16,
};
ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(io_handle, &panel_config, &panel_handle));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ void app_main(void)
esp_lcd_panel_handle_t panel_handle = NULL;
esp_lcd_panel_dev_config_t panel_config = {
.reset_gpio_num = EXAMPLE_PIN_NUM_LCD_RST,
.rgb_endian = LCD_RGB_ENDIAN_BGR,
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_BGR,
.bits_per_pixel = 16,
};
#if CONFIG_EXAMPLE_LCD_CONTROLLER_ILI9341
Expand Down
3 changes: 2 additions & 1 deletion examples/peripherals/lcd/tjpgd/main/lcd_tjpgd_example_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ void app_main(void)
esp_lcd_panel_handle_t panel_handle = NULL;
esp_lcd_panel_dev_config_t panel_config = {
.reset_gpio_num = EXAMPLE_PIN_NUM_RST,
.rgb_endian = LCD_RGB_ENDIAN_BGR,
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB,
.bits_per_pixel = 16,
};
// Initialize the LCD configuration
Expand All @@ -148,6 +148,7 @@ void app_main(void)

// Turn on the screen
ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel_handle, true));
ESP_ERROR_CHECK(esp_lcd_panel_invert_color(panel_handle, true));

// Swap x and y axis (Different LCD screens may need different options)
ESP_ERROR_CHECK(esp_lcd_panel_swap_xy(panel_handle, true));
Expand Down

0 comments on commit 01f3c93

Please sign in to comment.