diff --git a/components/esp_lcd/spi/esp_lcd_panel_io_spi.c b/components/esp_lcd/spi/esp_lcd_panel_io_spi.c index eae42c890de..b74b14710b3 100644 --- a/components/esp_lcd/spi/esp_lcd_panel_io_spi.c +++ b/components/esp_lcd/spi/esp_lcd_panel_io_spi.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -24,6 +24,7 @@ #include "esp_log.h" #include "esp_check.h" #include "esp_lcd_common.h" +#include "esp_memory_utils.h" #include "freertos/FreeRTOS.h" static const char *TAG = "lcd_panel.io.spi"; @@ -347,11 +348,14 @@ static esp_err_t panel_io_spi_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, cons // use 8 lines for transmitting command, address and data lcd_trans->base.flags |= (SPI_TRANS_MULTILINE_CMD | SPI_TRANS_MULTILINE_ADDR | SPI_TRANS_MODE_OCT); } + // command is short, using polling mode ret = spi_device_polling_transmit(spi_panel_io->spi_dev, &lcd_trans->base); ESP_GOTO_ON_ERROR(ret, err, TAG, "spi transmit (polling) command failed"); } + bool color_in_psram = color && color_size && esp_ptr_external_ram(color); + // if the color buffer is big, we want to split it into chunks, and queue the chunks one by one do { size_t chunk_size = color_size; @@ -367,6 +371,10 @@ static esp_err_t panel_io_spi_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, cons spi_panel_io->num_trans_inflight--; } memset(lcd_trans, 0, sizeof(lcd_spi_trans_descriptor_t)); + if (color_in_psram) { + // When the color buffer resides in PSRAM, set the DMA PSRAM flag + lcd_trans->base.flags |= SPI_TRANS_DMA_USE_PSRAM; + } // SPI per-transfer size has its limitation, if the color buffer is too big, we need to split it into multiple chunks if (chunk_size > spi_panel_io->spi_trans_max_bytes) { diff --git a/components/esp_lcd/test_apps/spi_lcd/main/test_spi_lcd_panel.c b/components/esp_lcd/test_apps/spi_lcd/main/test_spi_lcd_panel.c index 6f41b800525..8094037e728 100644 --- a/components/esp_lcd/test_apps/spi_lcd/main/test_spi_lcd_panel.c +++ b/components/esp_lcd/test_apps/spi_lcd/main/test_spi_lcd_panel.c @@ -76,9 +76,9 @@ void test_spi_lcd_common_initialize(esp_lcd_panel_io_handle_t *io_handle, esp_lc #define TEST_IMG_SIZE (200 * 200 * sizeof(uint16_t)) -static void lcd_panel_test(esp_lcd_panel_io_handle_t io_handle, esp_lcd_panel_handle_t panel_handle) +static void lcd_panel_test(esp_lcd_panel_io_handle_t io_handle, esp_lcd_panel_handle_t panel_handle, bool use_psram) { - uint8_t *img = heap_caps_malloc(TEST_IMG_SIZE, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); + uint8_t *img = heap_caps_malloc(TEST_IMG_SIZE, MALLOC_CAP_DMA | (use_psram ? MALLOC_CAP_SPIRAM : MALLOC_CAP_INTERNAL)); TEST_ASSERT_NOT_NULL(img); esp_lcd_panel_reset(panel_handle); @@ -115,10 +115,6 @@ static void lcd_panel_test(esp_lcd_panel_io_handle_t io_handle, esp_lcd_panel_ha printf("turn off the panel\r\n"); esp_lcd_panel_disp_on_off(panel_handle, false); - TEST_ESP_OK(esp_lcd_panel_del(panel_handle)); - TEST_ESP_OK(esp_lcd_panel_io_del(io_handle)); - TEST_ESP_OK(spi_bus_free(TEST_SPI_HOST_ID)); - TEST_ESP_OK(gpio_reset_pin(TEST_LCD_BK_LIGHT_GPIO)); free(img); } @@ -176,7 +172,15 @@ TEST_CASE("lcd_panel_with_8-line_spi_interface_(st7789)", "[lcd]") .bits_per_pixel = 16, }; TEST_ESP_OK(esp_lcd_new_panel_st7789(io_handle, &panel_config, &panel_handle)); - lcd_panel_test(io_handle, panel_handle); + lcd_panel_test(io_handle, panel_handle, false); +#if SOC_PSRAM_DMA_CAPABLE && CONFIG_PSRAM + printf("test with PSRAM\r\n"); + lcd_panel_test(io_handle, panel_handle, true); +#endif + TEST_ESP_OK(esp_lcd_panel_del(panel_handle)); + TEST_ESP_OK(esp_lcd_panel_io_del(io_handle)); + TEST_ESP_OK(spi_bus_free(TEST_SPI_HOST_ID)); + TEST_ESP_OK(gpio_reset_pin(TEST_LCD_BK_LIGHT_GPIO)); } TEST_CASE("lcd_panel_with_8-line_spi_interface_(nt35510)", "[lcd]") @@ -190,7 +194,15 @@ TEST_CASE("lcd_panel_with_8-line_spi_interface_(nt35510)", "[lcd]") .bits_per_pixel = 16, }; TEST_ESP_OK(esp_lcd_new_panel_nt35510(io_handle, &panel_config, &panel_handle)); - lcd_panel_test(io_handle, panel_handle); + lcd_panel_test(io_handle, panel_handle, false); +#if SOC_PSRAM_DMA_CAPABLE && CONFIG_PSRAM + printf("test with PSRAM\r\n"); + lcd_panel_test(io_handle, panel_handle, true); +#endif + TEST_ESP_OK(esp_lcd_panel_del(panel_handle)); + TEST_ESP_OK(esp_lcd_panel_io_del(io_handle)); + TEST_ESP_OK(spi_bus_free(TEST_SPI_HOST_ID)); + TEST_ESP_OK(gpio_reset_pin(TEST_LCD_BK_LIGHT_GPIO)); } #endif // SOC_SPI_SUPPORT_OCT @@ -205,7 +217,15 @@ TEST_CASE("lcd_panel_with_1-line_spi_interface_(st7789)", "[lcd]") .bits_per_pixel = 16, }; TEST_ESP_OK(esp_lcd_new_panel_st7789(io_handle, &panel_config, &panel_handle)); - lcd_panel_test(io_handle, panel_handle); + lcd_panel_test(io_handle, panel_handle, false); +#if SOC_PSRAM_DMA_CAPABLE && CONFIG_PSRAM + printf("test with PSRAM\r\n"); + lcd_panel_test(io_handle, panel_handle, true); +#endif + TEST_ESP_OK(esp_lcd_panel_del(panel_handle)); + TEST_ESP_OK(esp_lcd_panel_io_del(io_handle)); + TEST_ESP_OK(spi_bus_free(TEST_SPI_HOST_ID)); + TEST_ESP_OK(gpio_reset_pin(TEST_LCD_BK_LIGHT_GPIO)); } TEST_CASE("spi_lcd_send_colors_to_fixed_region", "[lcd]") diff --git a/components/esp_lcd/test_apps/spi_lcd/sdkconfig.defaults.esp32p4 b/components/esp_lcd/test_apps/spi_lcd/sdkconfig.defaults.esp32p4 new file mode 100644 index 00000000000..702fac3342d --- /dev/null +++ b/components/esp_lcd/test_apps/spi_lcd/sdkconfig.defaults.esp32p4 @@ -0,0 +1,3 @@ +CONFIG_SPIRAM=y +CONFIG_SPIRAM_MODE_HEX=y +CONFIG_SPIRAM_SPEED_200M=y