mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
Merge branch 'fix/fix_i2s_i80_color_size_check_v5.5' into 'release/v5.5'
fix(lcd): add color size check for i80 and boundary check for rgb (v5.5) See merge request espressif/esp-idf!50965
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -475,6 +475,25 @@ static void i2s_lcd_prepare_param_buffer(lcd_i80_trans_descriptor_t *trans_desc,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool i2s_lcd_get_color_buffer_size(const esp_lcd_i80_bus_t *bus, size_t color_size, size_t *buffer_size)
|
||||||
|
{
|
||||||
|
#if SOC_I2S_TRANS_SIZE_ALIGN_WORD
|
||||||
|
size_t input_bytes_per_word = bus->bus_width / 4;
|
||||||
|
if (color_size % input_bytes_per_word) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
size_t word_num = color_size / input_bytes_per_word;
|
||||||
|
if (word_num > (size_t) -1 / 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*buffer_size = word_num * 4;
|
||||||
|
#else
|
||||||
|
(void)bus;
|
||||||
|
*buffer_size = color_size;
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static void i2s_lcd_prepare_color_buffer(lcd_i80_trans_descriptor_t *trans_desc, const void *color, size_t color_size)
|
static void i2s_lcd_prepare_color_buffer(lcd_i80_trans_descriptor_t *trans_desc, const void *color, size_t color_size)
|
||||||
{
|
{
|
||||||
#if SOC_I2S_TRANS_SIZE_ALIGN_WORD
|
#if SOC_I2S_TRANS_SIZE_ALIGN_WORD
|
||||||
@@ -510,8 +529,8 @@ static esp_err_t panel_io_i80_tx_param(esp_lcd_panel_io_t *io, int lcd_cmd, cons
|
|||||||
esp_lcd_i80_bus_t *bus = next_device->bus;
|
esp_lcd_i80_bus_t *bus = next_device->bus;
|
||||||
lcd_panel_io_i80_t *cur_device = bus->cur_device;
|
lcd_panel_io_i80_t *cur_device = bus->cur_device;
|
||||||
lcd_i80_trans_descriptor_t *trans_desc = NULL;
|
lcd_i80_trans_descriptor_t *trans_desc = NULL;
|
||||||
assert(param_size <= bus->max_transfer_bytes && "parameter bytes too long, enlarge max_transfer_bytes");
|
ESP_RETURN_ON_FALSE(param_size <= bus->max_transfer_bytes, ESP_ERR_INVALID_ARG, TAG, "parameter bytes too long, enlarge max_transfer_bytes");
|
||||||
assert(param_size <= LCD_I80_IO_FORMAT_BUF_SIZE && "format buffer too small, increase LCD_I80_IO_FORMAT_BUF_SIZE");
|
ESP_RETURN_ON_FALSE(param_size <= LCD_I80_IO_FORMAT_BUF_SIZE, ESP_ERR_INVALID_ARG, TAG, "format buffer too small, increase LCD_I80_IO_FORMAT_BUF_SIZE");
|
||||||
size_t num_trans_inflight = next_device->num_trans_inflight;
|
size_t num_trans_inflight = next_device->num_trans_inflight;
|
||||||
// before issue a polling transaction, need to wait queued transactions finished
|
// before issue a polling transaction, need to wait queued transactions finished
|
||||||
for (size_t i = 0; i < num_trans_inflight; i++) {
|
for (size_t i = 0; i < num_trans_inflight; i++) {
|
||||||
@@ -587,7 +606,10 @@ static esp_err_t panel_io_i80_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, cons
|
|||||||
esp_lcd_i80_bus_t *bus = next_device->bus;
|
esp_lcd_i80_bus_t *bus = next_device->bus;
|
||||||
lcd_panel_io_i80_t *cur_device = bus->cur_device;
|
lcd_panel_io_i80_t *cur_device = bus->cur_device;
|
||||||
lcd_i80_trans_descriptor_t *trans_desc = NULL;
|
lcd_i80_trans_descriptor_t *trans_desc = NULL;
|
||||||
assert(color_size <= bus->max_transfer_bytes && "color bytes too long, enlarge max_transfer_bytes");
|
size_t color_buffer_size = 0;
|
||||||
|
bool valid_color_buffer_size = i2s_lcd_get_color_buffer_size(bus, color_size, &color_buffer_size);
|
||||||
|
ESP_RETURN_ON_FALSE(valid_color_buffer_size && color_buffer_size <= bus->max_transfer_bytes, ESP_ERR_INVALID_ARG, TAG,
|
||||||
|
"color bytes too long, enlarge max_transfer_bytes");
|
||||||
size_t num_trans_inflight = next_device->num_trans_inflight;
|
size_t num_trans_inflight = next_device->num_trans_inflight;
|
||||||
// before issue a polling transaction, need to wait queued transactions finished
|
// before issue a polling transaction, need to wait queued transactions finished
|
||||||
for (size_t i = 0; i < num_trans_inflight; i++) {
|
for (size_t i = 0; i < num_trans_inflight; i++) {
|
||||||
|
|||||||
@@ -498,8 +498,10 @@ static esp_err_t panel_io_i80_tx_param(esp_lcd_panel_io_t *io, int lcd_cmd, cons
|
|||||||
esp_lcd_i80_bus_t *bus = next_device->bus;
|
esp_lcd_i80_bus_t *bus = next_device->bus;
|
||||||
lcd_panel_io_i80_t *cur_device = bus->cur_device;
|
lcd_panel_io_i80_t *cur_device = bus->cur_device;
|
||||||
lcd_i80_trans_descriptor_t *trans_desc = NULL;
|
lcd_i80_trans_descriptor_t *trans_desc = NULL;
|
||||||
assert(param_size <= bus->max_transfer_bytes && "parameter bytes too long, enlarge max_transfer_bytes");
|
ESP_RETURN_ON_FALSE(param_size <= bus->max_transfer_bytes, ESP_ERR_INVALID_ARG, TAG,
|
||||||
assert(param_size <= LCD_I80_IO_FORMAT_BUF_SIZE && "format buffer too small, increase LCD_I80_IO_FORMAT_BUF_SIZE");
|
"parameter bytes too long, enlarge max_transfer_bytes");
|
||||||
|
ESP_RETURN_ON_FALSE(param_size <= LCD_I80_IO_FORMAT_BUF_SIZE, ESP_ERR_INVALID_ARG, TAG,
|
||||||
|
"format buffer too small, increase LCD_I80_IO_FORMAT_BUF_SIZE");
|
||||||
uint32_t cmd_cycles = next_device->lcd_cmd_bits / bus->bus_width;
|
uint32_t cmd_cycles = next_device->lcd_cmd_bits / bus->bus_width;
|
||||||
// in case bus_width=16 and cmd_bits=8, we still need 1 cmd_cycle
|
// in case bus_width=16 and cmd_bits=8, we still need 1 cmd_cycle
|
||||||
if (cmd_cycles * bus->bus_width < next_device->lcd_cmd_bits) {
|
if (cmd_cycles * bus->bus_width < next_device->lcd_cmd_bits) {
|
||||||
@@ -566,7 +568,8 @@ static esp_err_t panel_io_i80_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, cons
|
|||||||
lcd_panel_io_i80_t *i80_device = __containerof(io, lcd_panel_io_i80_t, base);
|
lcd_panel_io_i80_t *i80_device = __containerof(io, lcd_panel_io_i80_t, base);
|
||||||
esp_lcd_i80_bus_t *bus = i80_device->bus;
|
esp_lcd_i80_bus_t *bus = i80_device->bus;
|
||||||
lcd_i80_trans_descriptor_t *trans_desc = NULL;
|
lcd_i80_trans_descriptor_t *trans_desc = NULL;
|
||||||
assert(color_size <= bus->max_transfer_bytes && "color bytes too long, enlarge max_transfer_bytes");
|
ESP_RETURN_ON_FALSE(color_size <= bus->max_transfer_bytes, ESP_ERR_INVALID_ARG, TAG,
|
||||||
|
"color bytes too long, enlarge max_transfer_bytes");
|
||||||
uint32_t cache_line_size = 0;
|
uint32_t cache_line_size = 0;
|
||||||
if (esp_ptr_external_ram(color)) {
|
if (esp_ptr_external_ram(color)) {
|
||||||
// check alignment
|
// check alignment
|
||||||
|
|||||||
@@ -651,6 +651,13 @@ static esp_err_t rgb_panel_draw_bitmap(esp_lcd_panel_t *panel, int x_start, int
|
|||||||
y_start = MAX(y_start, 0);
|
y_start = MAX(y_start, 0);
|
||||||
y_end = MIN(y_end, v_res);
|
y_end = MIN(y_end, v_res);
|
||||||
}
|
}
|
||||||
|
if (x_start >= x_end || y_start >= y_end) {
|
||||||
|
// no valid region to draw, skip
|
||||||
|
if (cb) {
|
||||||
|
cb(&rgb_panel->base, NULL, rgb_panel->user_ctx);
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// check if we want to copy the draw buffer to the internal frame buffer
|
// check if we want to copy the draw buffer to the internal frame buffer
|
||||||
bool draw_buf_copy_to_fb = true;
|
bool draw_buf_copy_to_fb = true;
|
||||||
|
|||||||
Reference in New Issue
Block a user