diff --git a/components/driver/gdma.c b/components/driver/gdma.c index 1d0c49a0d5..5250d49eac 100644 --- a/components/driver/gdma.c +++ b/components/driver/gdma.c @@ -26,13 +26,17 @@ static const char *TAG = "gdma"; -#if CONFIG_GDMA_ISR_IRAM_SAFE -#define GDMA_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_INTRDISABLED) +#if CONFIG_GDMA_ISR_IRAM_SAFE || CONFIG_GDMA_CTRL_FUNC_IN_IRAM #define GDMA_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT) #else -#define GDMA_INTR_ALLOC_FLAGS ESP_INTR_FLAG_INTRDISABLED #define GDMA_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT -#endif // CONFIG_GDMA_ISR_IRAM_SAFE +#endif + +#if CONFIG_GDMA_ISR_IRAM_SAFE +#define GDMA_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_INTRDISABLED) +#else +#define GDMA_INTR_ALLOC_FLAGS ESP_INTR_FLAG_INTRDISABLED +#endif #define GDMA_INVALID_PERIPH_TRIG (0x3F) #define SEARCH_REQUEST_RX_CHANNEL (1 << 0) @@ -385,9 +389,7 @@ esp_err_t gdma_register_tx_event_callbacks(gdma_channel_handle_t dma_chan, gdma_ ESP_GOTO_ON_FALSE(esp_ptr_in_iram(cbs->on_trans_eof), ESP_ERR_INVALID_ARG, err, TAG, "on_trans_eof not in IRAM"); } if (user_data) { - ESP_GOTO_ON_FALSE(esp_ptr_in_dram(user_data) || - esp_ptr_in_diram_dram(user_data) || - esp_ptr_in_rtc_dram_fast(user_data), ESP_ERR_INVALID_ARG, err, TAG, "user context not in DRAM"); + ESP_GOTO_ON_FALSE(esp_ptr_internal(user_data), ESP_ERR_INVALID_ARG, err, TAG, "user context not in internal RAM"); } #endif // CONFIG_GDMA_ISR_IRAM_SAFE @@ -423,9 +425,7 @@ esp_err_t gdma_register_rx_event_callbacks(gdma_channel_handle_t dma_chan, gdma_ ESP_GOTO_ON_FALSE(esp_ptr_in_iram(cbs->on_recv_eof), ESP_ERR_INVALID_ARG, err, TAG, "on_recv_eof not in IRAM"); } if (user_data) { - ESP_GOTO_ON_FALSE(esp_ptr_in_dram(user_data) || - esp_ptr_in_diram_dram(user_data) || - esp_ptr_in_rtc_dram_fast(user_data), ESP_ERR_INVALID_ARG, err, TAG, "user context not in DRAM"); + ESP_GOTO_ON_FALSE(esp_ptr_internal(user_data), ESP_ERR_INVALID_ARG, err, TAG, "user context not in internal RAM"); } #endif // CONFIG_GDMA_ISR_IRAM_SAFE diff --git a/components/driver/gptimer.c b/components/driver/gptimer.c index 5ddb46a7de..0c51207eb2 100644 --- a/components/driver/gptimer.c +++ b/components/driver/gptimer.c @@ -31,13 +31,17 @@ // If ISR handler is allowed to run whilst cache is disabled, // Make sure all the code and related variables used by the handler are in the SRAM -#if CONFIG_GPTIMER_ISR_IRAM_SAFE -#define GPTIMER_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_INTRDISABLED) +#if CONFIG_GPTIMER_ISR_IRAM_SAFE || CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM #define GPTIMER_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT) #else -#define GPTIMER_INTR_ALLOC_FLAGS ESP_INTR_FLAG_INTRDISABLED #define GPTIMER_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT -#endif //CONFIG_GPTIMER_ISR_IRAM_SAFE +#endif + +#if CONFIG_GPTIMER_ISR_IRAM_SAFE +#define GPTIMER_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_INTRDISABLED) +#else +#define GPTIMER_INTR_ALLOC_FLAGS ESP_INTR_FLAG_INTRDISABLED +#endif #define GPTIMER_PM_LOCK_NAME_LEN_MAX 16 @@ -240,9 +244,7 @@ esp_err_t gptimer_register_event_callbacks(gptimer_handle_t timer, const gptimer ESP_RETURN_ON_FALSE(esp_ptr_in_iram(cbs->on_alarm), ESP_ERR_INVALID_ARG, TAG, "on_alarm callback not in IRAM"); } if (user_data) { - ESP_RETURN_ON_FALSE(esp_ptr_in_dram(user_data) || - esp_ptr_in_diram_dram(user_data) || - esp_ptr_in_rtc_dram_fast(user_data), ESP_ERR_INVALID_ARG, TAG, "user context not in DRAM"); + ESP_RETURN_ON_FALSE(esp_ptr_internal(user_data), ESP_ERR_INVALID_ARG, TAG, "user context not in internal RAM"); } #endif diff --git a/components/driver/pulse_cnt.c b/components/driver/pulse_cnt.c index 8c72896da1..15a8ebdb16 100644 --- a/components/driver/pulse_cnt.c +++ b/components/driver/pulse_cnt.c @@ -32,13 +32,17 @@ // If ISR handler is allowed to run whilst cache is disabled, // Make sure all the code and related variables used by the handler are in the SRAM -#if CONFIG_PCNT_ISR_IRAM_SAFE -#define PCNT_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_SHARED) +#if CONFIG_PCNT_ISR_IRAM_SAFE || CONFIG_PCNT_CTRL_FUNC_IN_IRAM #define PCNT_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT) #else +#define PCNT_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT +#endif + +#if CONFIG_PCNT_ISR_IRAM_SAFE +#define PCNT_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_SHARED) +#else #define PCNT_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_SHARED) -#define PCNT_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT -#endif //CONFIG_PCNT_ISR_IRAM_SAFE +#endif #define PCNT_PM_LOCK_NAME_LEN_MAX 16 @@ -340,10 +344,7 @@ esp_err_t pcnt_unit_register_event_callbacks(pcnt_unit_handle_t unit, const pcnt ESP_RETURN_ON_FALSE(esp_ptr_in_iram(cbs->on_reach), ESP_ERR_INVALID_ARG, TAG, "on_reach callback not in IRAM"); } if (user_data) { - ESP_RETURN_ON_FALSE(esp_ptr_in_dram(user_data) || - esp_ptr_in_diram_dram(user_data) || - esp_ptr_in_rtc_dram_fast(user_data), - ESP_ERR_INVALID_ARG, TAG, "user context not in DRAM"); + ESP_RETURN_ON_FALSE(esp_ptr_internal(user_data), ESP_ERR_INVALID_ARG, TAG, "user context not in internal RAM"); } #endif diff --git a/components/esp_lcd/CMakeLists.txt b/components/esp_lcd/CMakeLists.txt index ffc0cd5119..81ca044e4e 100644 --- a/components/esp_lcd/CMakeLists.txt +++ b/components/esp_lcd/CMakeLists.txt @@ -1,17 +1,23 @@ set(srcs "src/esp_lcd_common.c" "src/esp_lcd_panel_io.c" "src/esp_lcd_panel_io_i2c.c" - "src/esp_lcd_panel_io_i2s.c" "src/esp_lcd_panel_io_spi.c" - "src/esp_lcd_panel_io_i80.c" "src/esp_lcd_panel_nt35510.c" "src/esp_lcd_panel_ssd1306.c" "src/esp_lcd_panel_st7789.c" - "src/esp_lcd_panel_ops.c" - "src/esp_lcd_rgb_panel.c") + "src/esp_lcd_panel_ops.c") set(includes "include" "interface") set(priv_requires "driver") +if(CONFIG_SOC_I2S_LCD_I80_VARIANT) + list(APPEND srcs "src/esp_lcd_panel_io_i2s.c") +endif() + +if(CONFIG_SOC_LCDCAM_SUPPORTED) + list(APPEND srcs "src/esp_lcd_panel_io_i80.c" "src/esp_lcd_rgb_panel.c") +endif() + idf_component_register(SRCS ${srcs} INCLUDE_DIRS ${includes} - PRIV_REQUIRES ${priv_requires}) + PRIV_REQUIRES ${priv_requires} + LDFRAGMENTS linker.lf) diff --git a/components/esp_lcd/Kconfig b/components/esp_lcd/Kconfig index 95136ff705..5e62153575 100644 --- a/components/esp_lcd/Kconfig +++ b/components/esp_lcd/Kconfig @@ -6,11 +6,24 @@ menu "LCD and Touch Panel" help LCD driver allocates an internal buffer to transform the data into a proper format, because of the endian order mismatch. This option is to set the size of the buffer, in bytes. + config LCD_ENABLE_DEBUG_LOG bool "Enable debug log" default n help Wether to enable the debug log message for LCD driver. Note that, this option only controls the LCD driver log, won't affect other drivers. + + if SOC_LCD_RGB_SUPPORTED + config LCD_RGB_ISR_IRAM_SAFE + bool "RGB LCD ISR IRAM-Safe" + default n + select GDMA_CTRL_FUNC_IN_IRAM # need to restart GDMA in the LCD ISR + help + Ensure the LCD interrupt is IRAM-Safe by allowing the interrupt handler to be + executable when the cache is disabled (e.g. SPI Flash write). + If you want the LCD driver to keep flushing the screen even when cache ops disabled, + you can enable this option. Note, this will also increase the IRAM usage. + endif # SOC_LCD_RGB_SUPPORTED endmenu endmenu diff --git a/components/esp_lcd/linker.lf b/components/esp_lcd/linker.lf new file mode 100644 index 0000000000..51f703659e --- /dev/null +++ b/components/esp_lcd/linker.lf @@ -0,0 +1,6 @@ +[mapping:esp_lcd] +archive: libesp_lcd.a +entries: + if LCD_RGB_ISR_IRAM_SAFE = y: + esp_lcd_common: lcd_com_mount_dma_data (noflash) + esp_lcd_rgb_panel: lcd_rgb_panel_start_transmission (noflash) diff --git a/components/esp_lcd/src/esp_lcd_rgb_panel.c b/components/esp_lcd/src/esp_lcd_rgb_panel.c index d86e48ddd7..b93218bfdf 100644 --- a/components/esp_lcd/src/esp_lcd_rgb_panel.c +++ b/components/esp_lcd/src/esp_lcd_rgb_panel.c @@ -39,6 +39,12 @@ #include "hal/lcd_hal.h" #include "hal/lcd_ll.h" +#if CONFIG_LCD_RGB_ISR_IRAM_SAFE +#define LCD_RGB_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_INTRDISABLED) +#else +#define LCD_RGB_INTR_ALLOC_FLAGS ESP_INTR_FLAG_INTRDISABLED +#endif + static const char *TAG = "lcd_panel.rgb"; typedef struct esp_rgb_panel_t esp_rgb_panel_t; @@ -100,6 +106,16 @@ esp_err_t esp_lcd_new_rgb_panel(const esp_lcd_rgb_panel_config_t *rgb_panel_conf ESP_GOTO_ON_FALSE(rgb_panel_config && ret_panel, ESP_ERR_INVALID_ARG, err, TAG, "invalid parameter"); ESP_GOTO_ON_FALSE(rgb_panel_config->data_width == 16, ESP_ERR_NOT_SUPPORTED, err, TAG, "unsupported data width %d", rgb_panel_config->data_width); + +#if CONFIG_LCD_RGB_ISR_IRAM_SAFE + if (rgb_panel_config->on_frame_trans_done) { + ESP_RETURN_ON_FALSE(esp_ptr_in_iram(rgb_panel_config->on_frame_trans_done), ESP_ERR_INVALID_ARG, TAG, "on_frame_trans_done callback not in IRAM"); + } + if (rgb_panel_config->user_ctx) { + ESP_RETURN_ON_FALSE(esp_ptr_internal(rgb_panel_config->user_ctx), ESP_ERR_INVALID_ARG, TAG, "user context not in internal RAM"); + } +#endif + // calculate the number of DMA descriptors size_t fb_size = rgb_panel_config->timings.h_res * rgb_panel_config->timings.v_res * rgb_panel_config->data_width / 8; size_t num_dma_nodes = fb_size / DMA_DESCRIPTOR_BUFFER_MAX_SIZE; @@ -147,7 +163,7 @@ esp_err_t esp_lcd_new_rgb_panel(const esp_lcd_rgb_panel_config_t *rgb_panel_conf ret = lcd_rgb_panel_select_periph_clock(rgb_panel, rgb_panel_config->clk_src); ESP_GOTO_ON_ERROR(ret, err, TAG, "select periph clock failed"); // install interrupt service, (LCD peripheral shares the interrupt source with Camera by different mask) - int isr_flags = LCD_INTR_ALLOC_FLAGS | ESP_INTR_FLAG_SHARED; + int isr_flags = LCD_RGB_INTR_ALLOC_FLAGS | ESP_INTR_FLAG_SHARED; ret = esp_intr_alloc_intrstatus(lcd_periph_signals.panels[panel_id].irq_id, isr_flags, (uint32_t)lcd_ll_get_interrupt_status_reg(rgb_panel->hal.dev), LCD_LL_EVENT_VSYNC_END, lcd_default_isr_handler, rgb_panel, &rgb_panel->intr); diff --git a/components/esp_lcd/test_apps/rgb_lcd/CMakeLists.txt b/components/esp_lcd/test_apps/rgb_lcd/CMakeLists.txt index e74a9f5358..4852f4edea 100644 --- a/components/esp_lcd/test_apps/rgb_lcd/CMakeLists.txt +++ b/components/esp_lcd/test_apps/rgb_lcd/CMakeLists.txt @@ -3,3 +3,16 @@ cmake_minimum_required(VERSION 3.5) include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(rgb_lcd_panel_test) + +if(CONFIG_COMPILER_DUMP_RTL_FILES) + add_custom_target(check_test_app_sections ALL + COMMAND ${PYTHON} $ENV{IDF_PATH}/tools/ci/check_callgraph.py + --rtl-dir ${CMAKE_BINARY_DIR}/esp-idf/esp_lcd/ + --elf-file ${CMAKE_BINARY_DIR}/rgb_lcd_panel_test.elf + find-refs + --from-sections=.iram0.text + --to-sections=.flash.text,.flash.rodata + --exit-code + DEPENDS ${elf} + ) +endif() diff --git a/components/esp_lcd/test_apps/rgb_lcd/main/CMakeLists.txt b/components/esp_lcd/test_apps/rgb_lcd/main/CMakeLists.txt index 34d2e684ea..ecad51a17c 100644 --- a/components/esp_lcd/test_apps/rgb_lcd/main/CMakeLists.txt +++ b/components/esp_lcd/test_apps/rgb_lcd/main/CMakeLists.txt @@ -1,7 +1,6 @@ set(srcs "test_app_main.c" "test_rgb_panel.c") -idf_component_register(SRCS ${srcs} - PRIV_REQUIRES esp_lcd unity) +idf_component_register(SRCS ${srcs}) target_link_libraries(${COMPONENT_LIB} INTERFACE "-u test_app_include_rgb_lcd") diff --git a/components/esp_lcd/test_apps/rgb_lcd/main/test_app_main.c b/components/esp_lcd/test_apps/rgb_lcd/main/test_app_main.c index 434a50e362..7b7ff5c868 100644 --- a/components/esp_lcd/test_apps/rgb_lcd/main/test_app_main.c +++ b/components/esp_lcd/test_apps/rgb_lcd/main/test_app_main.c @@ -9,7 +9,7 @@ #include "esp_heap_caps.h" // Some resources are lazy allocated in LCD driver, the threadhold is left for that case -#define TEST_MEMORY_LEAK_THRESHOLD (-300) +#define TEST_MEMORY_LEAK_THRESHOLD (-500) static size_t before_free_8bit; static size_t before_free_32bit; diff --git a/components/esp_lcd/test_apps/rgb_lcd/main/test_rgb_panel.c b/components/esp_lcd/test_apps/rgb_lcd/main/test_rgb_panel.c index 12ae23cec5..272897f4cc 100644 --- a/components/esp_lcd/test_apps/rgb_lcd/main/test_rgb_panel.c +++ b/components/esp_lcd/test_apps/rgb_lcd/main/test_rgb_panel.c @@ -5,22 +5,30 @@ */ #include #include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" #include "unity.h" #include "esp_lcd_panel_rgb.h" #include "esp_lcd_panel_ops.h" #include "esp_random.h" +#include "esp_attr.h" +#include "nvs_flash.h" #include "test_rgb_board.h" +#if CONFIG_LCD_RGB_ISR_IRAM_SAFE +#define TEST_LCD_CALLBACK_ATTR IRAM_ATTR +#else +#define TEST_LCD_CALLBACK_ATTR +#endif // CONFIG_LCD_RGB_ISR_IRAM_SAFE + +#define TEST_IMG_SIZE (100 * 100 * sizeof(uint16_t)) + void test_app_include_rgb_lcd(void) { } -TEST_CASE("lcd_rgb_lcd_panel", "[lcd]") +static esp_lcd_panel_handle_t test_rgb_panel_initialization(bool stream_mode, esp_lcd_rgb_panel_frame_trans_done_cb_t cb, void *user_data) { -#define TEST_IMG_SIZE (100 * 100 * sizeof(uint16_t)) - uint8_t *img = malloc(TEST_IMG_SIZE); - TEST_ASSERT_NOT_NULL(img); - esp_lcd_panel_handle_t panel_handle = NULL; esp_lcd_rgb_panel_config_t panel_config = { .data_width = 16, @@ -59,27 +67,117 @@ TEST_CASE("lcd_rgb_lcd_panel", "[lcd]") .vsync_back_porch = 18, .vsync_front_porch = 4, .vsync_pulse_width = 1, - .flags.pclk_active_neg = 1, // RGB data is clocked out on falling edge }, + .on_frame_trans_done = cb, + .user_ctx = user_data, .flags.fb_in_psram = 1, // allocate frame buffer in PSRAM + .flags.relax_on_idle = !stream_mode, }; - // Test stream mode and one-off mode - for (int i = 0; i < 2; i++) { - panel_config.flags.relax_on_idle = i; - TEST_ESP_OK(esp_lcd_new_rgb_panel(&panel_config, &panel_handle)); - TEST_ESP_OK(esp_lcd_panel_reset(panel_handle)); - TEST_ESP_OK(esp_lcd_panel_init(panel_handle)); - for (int i = 0; i < 200; i++) { - uint8_t color_byte = esp_random() & 0xFF; - int x_start = esp_random() % (TEST_LCD_H_RES - 100); - int y_start = esp_random() % (TEST_LCD_V_RES - 100); - memset(img, color_byte, TEST_IMG_SIZE); - esp_lcd_panel_draw_bitmap(panel_handle, x_start, y_start, x_start + 100, y_start + 100, img); - } + TEST_ESP_OK(esp_lcd_new_rgb_panel(&panel_config, &panel_handle)); + TEST_ESP_OK(esp_lcd_panel_reset(panel_handle)); + TEST_ESP_OK(esp_lcd_panel_init(panel_handle)); - TEST_ESP_OK(esp_lcd_panel_del(panel_handle)); - } - free(img); -#undef TEST_IMG_SIZE + return panel_handle; } + +TEST_CASE("lcd_rgb_panel_stream_mode", "[lcd]") +{ + uint8_t *img = malloc(TEST_IMG_SIZE); + TEST_ASSERT_NOT_NULL(img); + + printf("initialize RGB panel with stream mode\r\n"); + esp_lcd_panel_handle_t panel_handle = test_rgb_panel_initialization(true, NULL, NULL); + printf("flush random color block\r\n"); + for (int i = 0; i < 200; i++) { + uint8_t color_byte = esp_random() & 0xFF; + int x_start = esp_random() % (TEST_LCD_H_RES - 100); + int y_start = esp_random() % (TEST_LCD_V_RES - 100); + memset(img, color_byte, TEST_IMG_SIZE); + esp_lcd_panel_draw_bitmap(panel_handle, x_start, y_start, x_start + 100, y_start + 100, img); + } + printf("delete RGB panel\r\n"); + TEST_ESP_OK(esp_lcd_panel_del(panel_handle)); + free(img); +} + +TEST_LCD_CALLBACK_ATTR static bool test_rgb_panel_trans_done(esp_lcd_panel_handle_t panel, esp_lcd_rgb_panel_event_data_t *edata, void *user_ctx) +{ + TaskHandle_t task_to_notify = (TaskHandle_t)user_ctx; + BaseType_t high_task_wakeup; + vTaskNotifyGiveFromISR(task_to_notify, &high_task_wakeup); + return high_task_wakeup == pdTRUE; +} + +TEST_CASE("lcd_rgb_panel_one_shot_mode", "[lcd]") +{ + uint8_t *img = malloc(TEST_IMG_SIZE); + TEST_ASSERT_NOT_NULL(img); + TaskHandle_t cur_task = xTaskGetCurrentTaskHandle(); + + printf("initialize RGB panel with ont-shot mode\r\n"); + esp_lcd_panel_handle_t panel_handle = test_rgb_panel_initialization(false, test_rgb_panel_trans_done, cur_task); + printf("flush random color block\r\n"); + for (int i = 0; i < 200; i++) { + uint8_t color_byte = esp_random() & 0xFF; + int x_start = esp_random() % (TEST_LCD_H_RES - 100); + int y_start = esp_random() % (TEST_LCD_V_RES - 100); + memset(img, color_byte, TEST_IMG_SIZE); + esp_lcd_panel_draw_bitmap(panel_handle, x_start, y_start, x_start + 100, y_start + 100, img); + // wait for flush done + TEST_ASSERT_NOT_EQUAL(0, ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(1000))); + } + + printf("delete RGB panel\r\n"); + TEST_ESP_OK(esp_lcd_panel_del(panel_handle)); + free(img); +} + +#if CONFIG_LCD_RGB_ISR_IRAM_SAFE +TEST_CASE("lcd_rgb_panel_with_nvs_read_write", "[lcd]") +{ + uint8_t *img = malloc(TEST_IMG_SIZE); + TEST_ASSERT_NOT_NULL(img); + + printf("initialize RGB panel with stream mode\r\n"); + esp_lcd_panel_handle_t panel_handle = test_rgb_panel_initialization(true, NULL, NULL); + printf("flush one clock block to the LCD\r\n"); + uint8_t color_byte = esp_random() & 0xFF; + int x_start = esp_random() % (TEST_LCD_H_RES - 100); + int y_start = esp_random() % (TEST_LCD_V_RES - 100); + memset(img, color_byte, TEST_IMG_SIZE); + esp_lcd_panel_draw_bitmap(panel_handle, x_start, y_start, x_start + 100, y_start + 100, img); + printf("The LCD driver should keep flushing the color block in the background (as it's in stream mode)\r\n"); + + // read/write the SPI Flash by NVS APIs, the LCD driver should stay work + printf("initialize NVS flash\r\n"); + esp_err_t err = nvs_flash_init(); + if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) { + // NVS partition was truncated and needs to be erased + TEST_ESP_OK(nvs_flash_erase()); + // Retry nvs_flash_init + err = nvs_flash_init(); + } + TEST_ESP_OK(err); + printf("open NVS storage\r\n"); + nvs_handle_t my_handle; + TEST_ESP_OK(nvs_open("storage", NVS_READWRITE, &my_handle)); + TEST_ESP_OK(nvs_erase_all(my_handle)); + int test_count; + for (int i = 0; i < 50; i++) { + printf("write %d to NVS partition\r\n", i); + TEST_ESP_OK(nvs_set_i32(my_handle, "test_count", i)); + TEST_ESP_OK(nvs_commit(my_handle)); + TEST_ESP_OK(nvs_get_i32(my_handle, "test_count", &test_count)); + TEST_ASSERT_EQUAL(i, test_count); + vTaskDelay(pdMS_TO_TICKS(50)); + } + printf("close NVS storage\r\n"); + nvs_close(my_handle); + TEST_ESP_OK(nvs_flash_deinit()); + + printf("delete RGB panel\r\n"); + TEST_ESP_OK(esp_lcd_panel_del(panel_handle)); + free(img); +} +#endif // CONFIG_LCD_RGB_ISR_IRAM_SAFE diff --git a/components/esp_lcd/test_apps/rgb_lcd/pytest_rgb_lcd.py b/components/esp_lcd/test_apps/rgb_lcd/pytest_rgb_lcd.py index 52c04a369f..99d1b1df70 100644 --- a/components/esp_lcd/test_apps/rgb_lcd/pytest_rgb_lcd.py +++ b/components/esp_lcd/test_apps/rgb_lcd/pytest_rgb_lcd.py @@ -10,6 +10,7 @@ from pytest_embedded import Dut @pytest.mark.parametrize( 'config', [ + 'iram_safe', 'release', ], indirect=True, diff --git a/components/esp_lcd/test_apps/rgb_lcd/sdkconfig.ci.iram_safe b/components/esp_lcd/test_apps/rgb_lcd/sdkconfig.ci.iram_safe new file mode 100644 index 0000000000..8043d59c96 --- /dev/null +++ b/components/esp_lcd/test_apps/rgb_lcd/sdkconfig.ci.iram_safe @@ -0,0 +1,5 @@ +CONFIG_COMPILER_DUMP_RTL_FILES=y +CONFIG_LCD_RGB_ISR_IRAM_SAFE=y + +# silent the error check, as the error string are stored in rodata, causing RTL check failure +CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y diff --git a/components/esp_lcd/test_apps/rgb_lcd/sdkconfig.defaults.esp32s3 b/components/esp_lcd/test_apps/rgb_lcd/sdkconfig.defaults.esp32s3 index 2877855408..aac45bf22e 100644 --- a/components/esp_lcd/test_apps/rgb_lcd/sdkconfig.defaults.esp32s3 +++ b/components/esp_lcd/test_apps/rgb_lcd/sdkconfig.defaults.esp32s3 @@ -1,3 +1,4 @@ CONFIG_ESP32S3_SPIRAM_SUPPORT=y +CONFIG_ESPTOOLPY_OCT_FLASH=y CONFIG_SPIRAM_MODE_OCT=y CONFIG_SPIRAM_SPEED_80M=y