Skip to content

Commit

Permalink
feat: add spi dma support for esp32_s3_eye.
Browse files Browse the repository at this point in the history
  • Loading branch information
100312dog committed Jan 26, 2025
1 parent e2e8054 commit 450d1ec
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 12 deletions.
4 changes: 4 additions & 0 deletions bsp/esp32_s3_eye/esp32_s3_eye.c
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,11 @@ lv_display_t *bsp_display_start(void)
.double_buffer = BSP_LCD_DRAW_BUFF_DOUBLE,
.flags = {
#if (CONFIG_BSP_DISPLAY_LVGL_BUFFER_IN_PSRAM && CONFIG_SPIRAM)
#if CONFIG_SPI_DMA_SUPPORT_PSRAM
.buff_dma = true,
#else
.buff_dma = false,
#endif
.buff_spiram = true,
#else
.buff_dma = true,
Expand Down
5 changes: 5 additions & 0 deletions bsp/esp32_s3_eye/include/bsp/esp32_s3_eye.h
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,12 @@ esp_err_t bsp_sdcard_unmount(void);
*
* If you want to use the display without LVGL, see bsp/display.h API and use BSP version with 'noglib' suffix.
**************************************************************************************************/

#if CONFIG_SPI_DMA_SUPPORT_PSRAM
#define BSP_LCD_PIXEL_CLOCK_HZ (40 * 1000 * 1000)
#else
#define BSP_LCD_PIXEL_CLOCK_HZ (80 * 1000 * 1000)
#endif
#define BSP_LCD_SPI_NUM (SPI3_HOST)

#if (BSP_CONFIG_NO_GRAPHIC_LIB == 0)
Expand Down
3 changes: 2 additions & 1 deletion components/esp_lvgl_port/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ endif()
idf_component_register(
INCLUDE_DIRS "include"
PRIV_INCLUDE_DIRS "priv_include"
REQUIRES "esp_lcd")
REQUIRES "esp_lcd esp_mm")

# Get LVGL version
idf_build_get_property(build_components BUILD_COMPONENTS)
Expand Down Expand Up @@ -116,6 +116,7 @@ target_link_libraries(lvgl_port_lib PUBLIC
)
target_link_libraries(lvgl_port_lib PRIVATE
idf::esp_timer
idf::esp_mm
${ADD_LIBS}
)

Expand Down
2 changes: 1 addition & 1 deletion components/esp_lvgl_port/idf_component.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: "2.4.3"
version: "2.4.4"
description: ESP LVGL port
url: https://github.com/espressif/esp-bsp/tree/master/components/esp_lvgl_port
dependencies:
Expand Down
49 changes: 40 additions & 9 deletions components/esp_lvgl_port/src/lvgl8/esp_lvgl_port_disp.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#if CONFIG_IDF_TARGET_ESP32S3 && CONFIG_SPIRAM && CONFIG_SPI_DMA_SUPPORT_PSRAM
#include "esp_private/esp_cache_private.h"
#endif

#if CONFIG_IDF_TARGET_ESP32S3 && ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
#include "esp_lcd_panel_rgb.h"
Expand Down Expand Up @@ -244,6 +247,21 @@ static lv_disp_t *lvgl_port_add_disp_priv(const lvgl_port_display_cfg_t *disp_cf
disp_ctx->trans_size = disp_cfg->trans_size;

buffer_size = disp_cfg->buffer_size;
uint32_t buff_caps = 0;
#if SOC_PSRAM_DMA_CAPABLE == 0
if (disp_cfg->flags.buff_dma && disp_cfg->flags.buff_spiram) {
ESP_GOTO_ON_FALSE(false, ESP_ERR_NOT_SUPPORTED, err, TAG, "Alloc DMA capable buffer in SPIRAM is not supported!");
}
#endif
if (disp_cfg->flags.buff_dma) {
buff_caps |= MALLOC_CAP_DMA;
}
if (disp_cfg->flags.buff_spiram) {
buff_caps |= MALLOC_CAP_SPIRAM;
}
if (buff_caps == 0) {
buff_caps |= MALLOC_CAP_DEFAULT;
}

/* Use RGB internal buffers for avoid tearing effect */
if (priv_cfg && priv_cfg->avoid_tearing) {
Expand All @@ -259,15 +277,6 @@ static lv_disp_t *lvgl_port_add_disp_priv(const lvgl_port_display_cfg_t *disp_cf
ESP_GOTO_ON_FALSE(trans_sem, ESP_ERR_NO_MEM, err, TAG, "Failed to create transport counting Semaphore");
disp_ctx->trans_sem = trans_sem;
} else {
uint32_t buff_caps = MALLOC_CAP_DEFAULT;
if (disp_cfg->flags.buff_dma && disp_cfg->flags.buff_spiram && (0 == disp_cfg->trans_size)) {
ESP_GOTO_ON_FALSE(false, ESP_ERR_NOT_SUPPORTED, err, TAG, "Alloc DMA capable buffer in SPIRAM is not supported!");
} else if (disp_cfg->flags.buff_dma) {
buff_caps = MALLOC_CAP_DMA;
} else if (disp_cfg->flags.buff_spiram) {
buff_caps = MALLOC_CAP_SPIRAM;
}

if (disp_cfg->trans_size) {
buf3 = heap_caps_malloc(disp_cfg->trans_size * sizeof(lv_color_t), MALLOC_CAP_DMA);
ESP_GOTO_ON_FALSE(buf3, ESP_ERR_NO_MEM, err, TAG, "Not enough memory for buffer(transport) allocation!");
Expand All @@ -280,12 +289,34 @@ static lv_disp_t *lvgl_port_add_disp_priv(const lvgl_port_display_cfg_t *disp_cf

/* alloc draw buffers used by LVGL */
/* it's recommended to choose the size of the draw buffer(s) to be at least 1/10 screen sized */
#if CONFIG_IDF_TARGET_ESP32S3 && CONFIG_SPIRAM && CONFIG_SPI_DMA_SUPPORT_PSRAM
if (disp_cfg->flags.buff_dma && disp_cfg->flags.buff_spiram) {
size_t cache_line_size;
ESP_ERROR_CHECK(esp_cache_get_alignment(MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA, &cache_line_size));
uint32_t buffer_size_align_bytes = buffer_size * sizeof(lv_color_t);
buffer_size_align_bytes = (buffer_size_align_bytes + cache_line_size - 1) & ~(cache_line_size - 1);
buf1 = heap_caps_aligned_alloc(cache_line_size, buffer_size_align_bytes, buff_caps);
ESP_GOTO_ON_FALSE(buf1, ESP_ERR_NO_MEM, err, TAG, "Not enough memory for LVGL buffer (buf1) allocation!");
if (disp_cfg->double_buffer) {
buf2 = heap_caps_aligned_alloc(cache_line_size, buffer_size_align_bytes, buff_caps);
ESP_GOTO_ON_FALSE(buf2, ESP_ERR_NO_MEM, err, TAG, "Not enough memory for LVGL buffer (buf2) allocation!");
}
} else {
buf1 = heap_caps_malloc(buffer_size * sizeof(lv_color_t), buff_caps);
ESP_GOTO_ON_FALSE(buf1, ESP_ERR_NO_MEM, err, TAG, "Not enough memory for LVGL buffer (buf1) allocation!");
if (disp_cfg->double_buffer) {
buf2 = heap_caps_malloc(buffer_size * sizeof(lv_color_t), buff_caps);
ESP_GOTO_ON_FALSE(buf2, ESP_ERR_NO_MEM, err, TAG, "Not enough memory for LVGL buffer (buf2) allocation!");
}
}
#else
buf1 = heap_caps_malloc(buffer_size * sizeof(lv_color_t), buff_caps);
ESP_GOTO_ON_FALSE(buf1, ESP_ERR_NO_MEM, err, TAG, "Not enough memory for LVGL buffer (buf1) allocation!");
if (disp_cfg->double_buffer) {
buf2 = heap_caps_malloc(buffer_size * sizeof(lv_color_t), buff_caps);
ESP_GOTO_ON_FALSE(buf2, ESP_ERR_NO_MEM, err, TAG, "Not enough memory for LVGL buffer (buf2) allocation!");
}
#endif
}

lv_disp_draw_buf_t *disp_buf = malloc(sizeof(lv_disp_draw_buf_t));
Expand Down
27 changes: 26 additions & 1 deletion components/esp_lvgl_port/src/lvgl9/esp_lvgl_port_disp.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
#include "esp_lcd_panel_ops.h"
#include "esp_lvgl_port.h"
#include "esp_lvgl_port_priv.h"
#if CONFIG_IDF_TARGET_ESP32S3 && CONFIG_SPIRAM && CONFIG_SPI_DMA_SUPPORT_PSRAM
#include "esp_private/esp_cache_private.h"
#endif

#if CONFIG_IDF_TARGET_ESP32S3 && ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
#include "esp_lcd_panel_rgb.h"
Expand Down Expand Up @@ -308,13 +311,35 @@ static lv_display_t *lvgl_port_add_disp_priv(const lvgl_port_display_cfg_t *disp
} else {
/* alloc draw buffers used by LVGL */
/* it's recommended to choose the size of the draw buffer(s) to be at least 1/10 screen sized */
#if CONFIG_IDF_TARGET_ESP32S3 && CONFIG_SPIRAM && CONFIG_SPI_DMA_SUPPORT_PSRAM
if (disp_cfg->flags.buff_dma && disp_cfg->flags.buff_spiram) {
// the data buffer address and transaction length should both aligned to cache length
size_t cache_line_size;
ESP_ERROR_CHECK(esp_cache_get_alignment(MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA, &cache_line_size));
uint32_t buffer_size_align_bytes = buffer_size * color_bytes;
buffer_size_align_bytes = (buffer_size_align_bytes + cache_line_size - 1) & ~(cache_line_size - 1);
buf1 = heap_caps_aligned_alloc(cache_line_size, buffer_size_align_bytes, buff_caps);
ESP_GOTO_ON_FALSE(buf1, ESP_ERR_NO_MEM, err, TAG, "Not enough memory for LVGL buffer (buf1) allocation!");
if (disp_cfg->double_buffer) {
buf2 = heap_caps_aligned_alloc(cache_line_size, buffer_size_align_bytes, buff_caps);
ESP_GOTO_ON_FALSE(buf2, ESP_ERR_NO_MEM, err, TAG, "Not enough memory for LVGL buffer (buf2) allocation!");
}
} else {
buf1 = heap_caps_malloc(buffer_size * color_bytes, buff_caps);
ESP_GOTO_ON_FALSE(buf1, ESP_ERR_NO_MEM, err, TAG, "Not enough memory for LVGL buffer (buf1) allocation!");
if (disp_cfg->double_buffer) {
buf2 = heap_caps_malloc(buffer_size * color_bytes, buff_caps);
ESP_GOTO_ON_FALSE(buf2, ESP_ERR_NO_MEM, err, TAG, "Not enough memory for LVGL buffer (buf2) allocation!");
}
}
#else
buf1 = heap_caps_malloc(buffer_size * color_bytes, buff_caps);
ESP_GOTO_ON_FALSE(buf1, ESP_ERR_NO_MEM, err, TAG, "Not enough memory for LVGL buffer (buf1) allocation!");
if (disp_cfg->double_buffer) {
buf2 = heap_caps_malloc(buffer_size * color_bytes, buff_caps);
ESP_GOTO_ON_FALSE(buf2, ESP_ERR_NO_MEM, err, TAG, "Not enough memory for LVGL buffer (buf2) allocation!");
}

#endif
disp_ctx->draw_buffs[0] = buf1;
disp_ctx->draw_buffs[1] = buf2;
}
Expand Down

0 comments on commit 450d1ec

Please sign in to comment.