diff --git a/.gitlab/ci/target-test.yml b/.gitlab/ci/target-test.yml index db1622a7db..7926974c6c 100644 --- a/.gitlab/ci/target-test.yml +++ b/.gitlab/ci/target-test.yml @@ -154,6 +154,19 @@ component_ut_pytest_esp32s3_generic: - ESP32S3 - COMPONENT_UT_GENERIC +component_ut_pytest_esp32s3_octal_psram: + extends: + - .pytest_components_dir_template + - .rules:test:component_ut-esp32s3 + needs: + - build_pytest_components_esp32s3 + variables: + TARGET: esp32s3 + ENV_MARKER: octal_psram + tags: + - ESP32S3 + - MSPI_F8R8 + component_ut_pytest_esp32c3_generic: extends: - .pytest_components_dir_template diff --git a/components/esp_lcd/src/esp_lcd_common.c b/components/esp_lcd/src/esp_lcd_common.c index 8aa364ac8c..f9716b7854 100644 --- a/components/esp_lcd/src/esp_lcd_common.c +++ b/components/esp_lcd/src/esp_lcd_common.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/esp_lcd/src/esp_lcd_common.h b/components/esp_lcd/src/esp_lcd_common.h index a6e97ba70b..6c534bc9f9 100644 --- a/components/esp_lcd/src/esp_lcd_common.h +++ b/components/esp_lcd/src/esp_lcd_common.h @@ -1,13 +1,16 @@ /* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once #include +#include "sdkconfig.h" #include "soc/soc_caps.h" #include "hal/dma_types.h" +#include "esp_intr_alloc.h" +#include "esp_heap_caps.h" #if SOC_LCDCAM_SUPPORTED #include "hal/lcd_hal.h" #endif @@ -16,6 +19,9 @@ extern "C" { #endif +#define LCD_INTR_ALLOC_FLAGS ESP_INTR_FLAG_INTRDISABLED +#define LCD_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT + #define LCD_PERIPH_CLOCK_PRE_SCALE (2) // This is the minimum divider that can be applied to LCD peripheral #if SOC_LCDCAM_SUPPORTED diff --git a/components/esp_lcd/src/esp_lcd_panel_io_i80.c b/components/esp_lcd/src/esp_lcd_panel_io_i80.c index 13cdf697b4..f745b96a28 100644 --- a/components/esp_lcd/src/esp_lcd_panel_io_i80.c +++ b/components/esp_lcd/src/esp_lcd_panel_io_i80.c @@ -16,8 +16,6 @@ #include "freertos/queue.h" #include "esp_attr.h" #include "esp_check.h" -#include "esp_intr_alloc.h" -#include "esp_heap_caps.h" #include "esp_pm.h" #include "esp_lcd_panel_io_interface.h" #include "esp_lcd_panel_io.h" @@ -149,7 +147,7 @@ esp_err_t esp_lcd_new_i80_bus(const esp_lcd_i80_bus_config_t *bus_config, esp_lc ESP_GOTO_ON_ERROR(ret, err, TAG, "select periph clock %d failed", bus_config->clk_src); // install interrupt service, (LCD peripheral shares the same interrupt source with Camera peripheral with different mask) // interrupt is disabled by default - int isr_flags = ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_SHARED; + int isr_flags = LCD_INTR_ALLOC_FLAGS | ESP_INTR_FLAG_SHARED; ret = esp_intr_alloc_intrstatus(lcd_periph_signals.buses[bus_id].irq_id, isr_flags, (uint32_t)lcd_ll_get_interrupt_status_reg(bus->hal.dev), LCD_LL_EVENT_TRANS_DONE, lcd_default_isr_handler, bus, &bus->intr); @@ -246,7 +244,7 @@ esp_err_t esp_lcd_new_panel_io_i80(esp_lcd_i80_bus_handle_t bus, const esp_lcd_p uint32_t pclk_prescale = bus->resolution_hz / io_config->pclk_hz; ESP_GOTO_ON_FALSE(pclk_prescale > 0 && pclk_prescale <= LCD_LL_CLOCK_PRESCALE_MAX, ESP_ERR_NOT_SUPPORTED, err, TAG, "prescaler can't satisfy PCLK clock %u", io_config->pclk_hz); - i80_device = calloc(1, sizeof(lcd_panel_io_i80_t) + io_config->trans_queue_depth * sizeof(lcd_i80_trans_descriptor_t)); + i80_device = heap_caps_calloc(1, sizeof(lcd_panel_io_i80_t) + io_config->trans_queue_depth * sizeof(lcd_i80_trans_descriptor_t), LCD_MEM_ALLOC_CAPS); ESP_GOTO_ON_FALSE(i80_device, ESP_ERR_NO_MEM, err, TAG, "no mem for i80 panel io"); // create two queues for i80 device i80_device->trans_queue = xQueueCreate(io_config->trans_queue_depth, sizeof(lcd_i80_trans_descriptor_t *)); diff --git a/components/esp_lcd/src/esp_lcd_rgb_panel.c b/components/esp_lcd/src/esp_lcd_rgb_panel.c index 37e6d2c220..969f603867 100644 --- a/components/esp_lcd/src/esp_lcd_rgb_panel.c +++ b/components/esp_lcd/src/esp_lcd_rgb_panel.c @@ -16,8 +16,6 @@ #include "freertos/semphr.h" #include "esp_attr.h" #include "esp_check.h" -#include "esp_intr_alloc.h" -#include "esp_heap_caps.h" #include "esp_pm.h" #include "esp_lcd_panel_interface.h" #include "esp_lcd_panel_rgb.h" @@ -107,7 +105,7 @@ esp_err_t esp_lcd_new_rgb_panel(const esp_lcd_rgb_panel_config_t *rgb_panel_conf num_dma_nodes++; } // DMA descriptors must be placed in internal SRAM (requested by DMA) - rgb_panel = heap_caps_calloc(1, sizeof(esp_rgb_panel_t) + num_dma_nodes * sizeof(dma_descriptor_t), MALLOC_CAP_DMA); + rgb_panel = heap_caps_calloc(1, sizeof(esp_rgb_panel_t) + num_dma_nodes * sizeof(dma_descriptor_t), MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); ESP_GOTO_ON_FALSE(rgb_panel, ESP_ERR_NO_MEM, err, TAG, "no mem for rgb panel"); rgb_panel->num_dma_nodes = num_dma_nodes; rgb_panel->panel_id = -1; @@ -150,7 +148,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 = ESP_INTR_FLAG_SHARED; + int isr_flags = LCD_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); @@ -284,6 +282,8 @@ static esp_err_t rgb_panel_init(esp_lcd_panel_t *panel) lcd_ll_enable_auto_next_frame(rgb_panel->hal.dev, rgb_panel->flags.stream_mode); // trigger interrupt on the end of frame lcd_ll_enable_interrupt(rgb_panel->hal.dev, LCD_LL_EVENT_VSYNC_END, true); + // enable intr + esp_intr_enable(rgb_panel->intr); ESP_LOGD(TAG, "rgb panel(%d) start, pclk=%uHz", rgb_panel->panel_id, rgb_panel->timings.pclk_hz); err: return ret; diff --git a/components/esp_lcd/test/CMakeLists.txt b/components/esp_lcd/test/CMakeLists.txt deleted file mode 100644 index f845f124fd..0000000000 --- a/components/esp_lcd/test/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -idf_component_register(SRC_DIRS . - PRIV_INCLUDE_DIRS . - PRIV_REQUIRES cmock test_utils esp_lcd) diff --git a/components/esp_lcd/test/test_lvgl_port.h b/components/esp_lcd/test/test_lvgl_port.h deleted file mode 100644 index 872644b7e8..0000000000 --- a/components/esp_lcd/test/test_lvgl_port.h +++ /dev/null @@ -1,4 +0,0 @@ -#include "esp_lcd_panel_ops.h" -#include "lvgl.h" - -void test_lvgl_task_loop(esp_lcd_panel_handle_t panel_handle, int h_res, int v_res, lv_disp_t **disp); diff --git a/components/esp_lcd/test/test_lvgl_port_v7.c b/components/esp_lcd/test/test_lvgl_port_v7.c deleted file mode 100644 index 535897c059..0000000000 --- a/components/esp_lcd/test/test_lvgl_port_v7.c +++ /dev/null @@ -1,86 +0,0 @@ -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "unity.h" -#include "test_utils.h" -#include "esp_freertos_hooks.h" -#include "soc/soc_caps.h" -#if CONFIG_LV_USE_USER_DATA -#include "test_lvgl_port.h" - -static void my_lvgl_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map) -{ - esp_lcd_panel_handle_t panel_handle = (esp_lcd_panel_handle_t) drv->user_data; - - int offsetx1 = area->x1; - int offsetx2 = area->x2; - int offsety1 = area->y1; - int offsety2 = area->y2; - - esp_lcd_panel_draw_bitmap(panel_handle, offsetx1, offsety1, offsetx2 + 1, offsety2 + 1, color_map); -} - -static void increase_lvgl_tick(void) -{ - lv_tick_inc(portTICK_PERIOD_MS); -} - -static void create_demo_application(lv_disp_t *disp) -{ - // Get the current screen - lv_obj_t *scr = lv_disp_get_scr_act(disp); - // Create a Label on the currently active screen - lv_obj_t *label = lv_label_create(scr, NULL); - // Modify the Label's text - lv_label_set_text(label, "Hello World"); - // Align the Label to the center - lv_obj_align(label, NULL, LV_ALIGN_IN_TOP_MID, 0, 0); - - // new screen_spinner - lv_obj_t *screen_spinner = lv_spinner_create(scr, NULL); - lv_obj_align(screen_spinner, label, LV_ALIGN_OUT_BOTTOM_MID, 15, 20); - lv_obj_set_size(screen_spinner, 100, 100); - lv_spinner_set_arc_length(screen_spinner, 60); - lv_spinner_set_spin_time(screen_spinner, 1000); - lv_spinner_set_type(screen_spinner, LV_SPINNER_TYPE_SPINNING_ARC); - lv_spinner_set_dir(screen_spinner, LV_SPINNER_DIR_FORWARD); - - lv_obj_t *bar = lv_bar_create(scr, NULL); - lv_obj_set_size(bar, 100, 20); - lv_obj_align(bar, screen_spinner, LV_ALIGN_OUT_BOTTOM_MID, 0, 0); - lv_bar_set_anim_time(bar, 2000); - lv_bar_set_value(bar, 100, LV_ANIM_ON); -} - -void test_lvgl_task_loop(esp_lcd_panel_handle_t panel_handle, int h_res, int v_res, lv_disp_t **disp) -{ - static lv_disp_buf_t disp_buf; - // alloc frame buffer used by LVGL - lv_color_t *buf1 = heap_caps_malloc(h_res * 20 * sizeof(lv_color_t), MALLOC_CAP_DMA); - TEST_ASSERT_NOT_NULL(buf1); - lv_color_t *buf2 = heap_caps_malloc(h_res * 20 * sizeof(lv_color_t), MALLOC_CAP_DMA); - TEST_ASSERT_NOT_NULL(buf2); - lv_disp_buf_init(&disp_buf, buf1, buf2, h_res * 20); - // register display driver - lv_disp_drv_t disp_drv; - lv_disp_drv_init(&disp_drv); - disp_drv.hor_res = h_res; - disp_drv.ver_res = v_res; - disp_drv.flush_cb = my_lvgl_flush; - - disp_drv.buffer = &disp_buf; - disp_drv.user_data = panel_handle; // LV_USE_USER_DATA is disabled by default, need to enable it in menuconfig - *disp = lv_disp_drv_register(&disp_drv); - - // Tick interface for LVGL - esp_register_freertos_tick_hook(increase_lvgl_tick); - - // create a demo UI on that screen - create_demo_application(*disp); - - while (1) { - vTaskDelay(pdMS_TO_TICKS(10)); - lv_task_handler(); // The task running lv_task_handler should have lower priority than that running `lv_tick_inc` - } -} - -#endif // CONFIG_LV_USE_USER_DATA diff --git a/components/esp_lcd/test/test_spi_board.h b/components/esp_lcd/test/test_spi_board.h deleted file mode 100644 index b862683db9..0000000000 --- a/components/esp_lcd/test/test_spi_board.h +++ /dev/null @@ -1,18 +0,0 @@ -#include "sdkconfig.h" - -#define TEST_LCD_H_RES (240) -#define TEST_LCD_V_RES (280) - -#define TEST_LCD_BK_LIGHT_GPIO (18) -#define TEST_LCD_RST_GPIO (5) -#define TEST_LCD_CS_GPIO (0) -#define TEST_LCD_DC_GPIO (19) -#define TEST_LCD_PCLK_GPIO (2) -#define TEST_LCD_DATA0_GPIO (4) -#define TEST_LCD_DATA1_GPIO (7) -#define TEST_LCD_DATA2_GPIO (8) -#define TEST_LCD_DATA3_GPIO (9) -#define TEST_LCD_DATA4_GPIO (10) -#define TEST_LCD_DATA5_GPIO (11) -#define TEST_LCD_DATA6_GPIO (12) -#define TEST_LCD_DATA7_GPIO (13) diff --git a/components/esp_lcd/test_apps/i2c_lcd/CMakeLists.txt b/components/esp_lcd/test_apps/i2c_lcd/CMakeLists.txt new file mode 100644 index 0000000000..9f5761fc27 --- /dev/null +++ b/components/esp_lcd/test_apps/i2c_lcd/CMakeLists.txt @@ -0,0 +1,5 @@ +# This is the project CMakeLists.txt file for the test subproject +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(i2c_lcd_panel_test) diff --git a/components/esp_lcd/test_apps/i2c_lcd/README.md b/components/esp_lcd/test_apps/i2c_lcd/README.md new file mode 100644 index 0000000000..c1bf68ceb4 --- /dev/null +++ b/components/esp_lcd/test_apps/i2c_lcd/README.md @@ -0,0 +1 @@ +This test app is used to test LCDs with I2C interface. diff --git a/components/esp_lcd/test_apps/i2c_lcd/main/CMakeLists.txt b/components/esp_lcd/test_apps/i2c_lcd/main/CMakeLists.txt new file mode 100644 index 0000000000..dfec558f2d --- /dev/null +++ b/components/esp_lcd/test_apps/i2c_lcd/main/CMakeLists.txt @@ -0,0 +1,7 @@ +set(srcs "test_app_main.c" + "test_i2c_lcd_panel.c") + +idf_component_register(SRCS ${srcs} + PRIV_REQUIRES esp_lcd unity) + +target_link_libraries(${COMPONENT_LIB} INTERFACE "-u test_app_include_i2c_lcd") diff --git a/components/esp_lcd/test_apps/i2c_lcd/main/test_app_main.c b/components/esp_lcd/test_apps/i2c_lcd/main/test_app_main.c new file mode 100644 index 0000000000..2c2aa076d6 --- /dev/null +++ b/components/esp_lcd/test_apps/i2c_lcd/main/test_app_main.c @@ -0,0 +1,51 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ + +#include "unity.h" +#include "unity_test_runner.h" +#include "esp_heap_caps.h" + +// Some resources are lazy allocated in the LCD driver, the threadhold is left for that case +#define TEST_MEMORY_LEAK_THRESHOLD (-300) + +static size_t before_free_8bit; +static size_t before_free_32bit; + +static void check_leak(size_t before_free, size_t after_free, const char *type) +{ + ssize_t delta = after_free - before_free; + printf("MALLOC_CAP_%s: Before %u bytes free, After %u bytes free (delta %d)\n", type, before_free, after_free, delta); + TEST_ASSERT_MESSAGE(delta >= TEST_MEMORY_LEAK_THRESHOLD, "memory leak"); +} + +void setUp(void) +{ + before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); + before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); +} + +void tearDown(void) +{ + size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); + size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); + check_leak(before_free_8bit, after_free_8bit, "8BIT"); + check_leak(before_free_32bit, after_free_32bit, "32BIT"); +} + +void app_main(void) +{ + // ___ ____ ____ _ ____ ____ _____ _ + // |_ _|___ \ / ___| | | / ___| _ \ |_ _|__ ___| |_ + // | | __) | | | | | | | | | | | |/ _ \/ __| __| + // | | / __/| |___ | |__| |___| |_| | | | __/\__ \ |_ + // |___|_____|\____| |_____\____|____/ |_|\___||___/\__| + printf(" ___ ____ ____ _ ____ ____ _____ _\r\n"); + printf("|_ _|___ \\ / ___| | | / ___| _ \\ |_ _|__ ___| |_\r\n"); + printf(" | | __) | | | | | | | | | | | |/ _ \\/ __| __|\r\n"); + printf(" | | / __/| |___ | |__| |___| |_| | | | __/\\__ \\ |_\r\n"); + printf("|___|_____|\\____| |_____\\____|____/ |_|\\___||___/\\__|\r\n"); + unity_run_menu(); +} diff --git a/components/esp_lcd/test_apps/i2c_lcd/main/test_i2c_board.h b/components/esp_lcd/test_apps/i2c_lcd/main/test_i2c_board.h new file mode 100644 index 0000000000..c8f4150a0e --- /dev/null +++ b/components/esp_lcd/test_apps/i2c_lcd/main/test_i2c_board.h @@ -0,0 +1,26 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#define TEST_LCD_H_RES 128 +#define TEST_LCD_V_RES 64 + +#define TEST_I2C_SDA_GPIO 0 +#define TEST_I2C_SCL_GPIO 2 + +#define TEST_I2C_HOST_ID 0 + +#define TEST_I2C_DEV_ADDR 0x3C + +#define TEST_LCD_PIXEL_CLOCK_HZ (400 * 1000) + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_lcd/test/test_i2c_lcd_panel.c b/components/esp_lcd/test_apps/i2c_lcd/main/test_i2c_lcd_panel.c similarity index 86% rename from components/esp_lcd/test/test_i2c_lcd_panel.c rename to components/esp_lcd/test_apps/i2c_lcd/main/test_i2c_lcd_panel.c index a62af2666d..83ee5590d2 100644 --- a/components/esp_lcd/test/test_i2c_lcd_panel.c +++ b/components/esp_lcd/test_apps/i2c_lcd/main/test_i2c_lcd_panel.c @@ -1,24 +1,24 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include -#include "sdkconfig.h" #include "unity.h" -#include "test_utils.h" #include "driver/i2c.h" #include "driver/gpio.h" #include "esp_lcd_panel_io.h" #include "esp_lcd_panel_vendor.h" #include "esp_lcd_panel_ops.h" #include "esp_system.h" +#include "test_i2c_board.h" -#define TEST_LCD_H_RES (128) -#define TEST_LCD_V_RES (64) -#define TEST_I2C_SDA_GPIO (3) -#define TEST_I2C_SCL_GPIO (4) -#define TEST_I2C_HOST_ID (0) -#define TEST_I2C_DEV_ADDR (0x3C) -#define TEST_LCD_PIXEL_CLOCK_HZ (400 * 1000) +void test_app_include_i2c_lcd(void) +{ +} -TEST_CASE("lcd panel with i2c interface (ssd1306)", "[lcd]") +TEST_CASE("lcd_panel_with_i2c_interface_(ssd1306)", "[lcd]") { const uint8_t pattern[][16] = {{ 0x00, 0x7E, 0x42, 0x42, 0x42, 0x42, 0x7E, 0x00, diff --git a/components/esp_lcd/test_apps/i2c_lcd/pytest_i2c_lcd.py b/components/esp_lcd/test_apps/i2c_lcd/pytest_i2c_lcd.py new file mode 100644 index 0000000000..9a131d00a7 --- /dev/null +++ b/components/esp_lcd/test_apps/i2c_lcd/pytest_i2c_lcd.py @@ -0,0 +1,20 @@ +# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 + +import pytest +from pytest_embedded import Dut + + +@pytest.mark.supported_targets +@pytest.mark.generic +@pytest.mark.parametrize( + 'config', + [ + 'release', + ], + indirect=True, +) +def test_i2c_lcd(dut: Dut) -> None: + dut.expect_exact('Press ENTER to see the list of tests') + dut.write('*') + dut.expect_unity_test_output() diff --git a/components/esp_lcd/test_apps/i2c_lcd/sdkconfig.ci.release b/components/esp_lcd/test_apps/i2c_lcd/sdkconfig.ci.release new file mode 100644 index 0000000000..3cff15d49e --- /dev/null +++ b/components/esp_lcd/test_apps/i2c_lcd/sdkconfig.ci.release @@ -0,0 +1,3 @@ +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y diff --git a/components/esp_lcd/test_apps/i2c_lcd/sdkconfig.defaults b/components/esp_lcd/test_apps/i2c_lcd/sdkconfig.defaults new file mode 100644 index 0000000000..b308cb2ddd --- /dev/null +++ b/components/esp_lcd/test_apps/i2c_lcd/sdkconfig.defaults @@ -0,0 +1,2 @@ +CONFIG_FREERTOS_HZ=1000 +CONFIG_ESP_TASK_WDT=n diff --git a/components/esp_lcd/test_apps/i80_lcd/CMakeLists.txt b/components/esp_lcd/test_apps/i80_lcd/CMakeLists.txt new file mode 100644 index 0000000000..5bc0952c87 --- /dev/null +++ b/components/esp_lcd/test_apps/i80_lcd/CMakeLists.txt @@ -0,0 +1,5 @@ +# This is the project CMakeLists.txt file for the test subproject +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(i80_lcd_panel_test) diff --git a/components/esp_lcd/test_apps/i80_lcd/README.md b/components/esp_lcd/test_apps/i80_lcd/README.md new file mode 100644 index 0000000000..c6425abb4e --- /dev/null +++ b/components/esp_lcd/test_apps/i80_lcd/README.md @@ -0,0 +1,4 @@ +| Supported Targets | ESP32 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | + +This test app is used to test LCDs with intel 8080 interface. diff --git a/components/esp_lcd/test_apps/i80_lcd/main/CMakeLists.txt b/components/esp_lcd/test_apps/i80_lcd/main/CMakeLists.txt new file mode 100644 index 0000000000..d8421978f1 --- /dev/null +++ b/components/esp_lcd/test_apps/i80_lcd/main/CMakeLists.txt @@ -0,0 +1,7 @@ +set(srcs "test_app_main.c" + "test_i80_lcd_panel.c") + +idf_component_register(SRCS ${srcs} + PRIV_REQUIRES esp_lcd unity) + +target_link_libraries(${COMPONENT_LIB} INTERFACE "-u test_app_include_i80_lcd") diff --git a/components/esp_lcd/test_apps/i80_lcd/main/test_app_main.c b/components/esp_lcd/test_apps/i80_lcd/main/test_app_main.c new file mode 100644 index 0000000000..c4d721ce37 --- /dev/null +++ b/components/esp_lcd/test_apps/i80_lcd/main/test_app_main.c @@ -0,0 +1,51 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ + +#include "unity.h" +#include "unity_test_runner.h" +#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) + +static size_t before_free_8bit; +static size_t before_free_32bit; + +static void check_leak(size_t before_free, size_t after_free, const char *type) +{ + ssize_t delta = after_free - before_free; + printf("MALLOC_CAP_%s: Before %u bytes free, After %u bytes free (delta %d)\n", type, before_free, after_free, delta); + TEST_ASSERT_MESSAGE(delta >= TEST_MEMORY_LEAK_THRESHOLD, "memory leak"); +} + +void setUp(void) +{ + before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); + before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); +} + +void tearDown(void) +{ + size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); + size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); + check_leak(before_free_8bit, after_free_8bit, "8BIT"); + check_leak(before_free_32bit, after_free_32bit, "32BIT"); +} + +void app_main(void) +{ + // _ ___ ___ _ ____ ____ _____ _ + // (_)( _ ) / _ \ | | / ___| _ \ |_ _|__ ___| |_ + // | |/ _ \| | | | | | | | | | | | | |/ _ \/ __| __| + // | | (_) | |_| | | |__| |___| |_| | | | __/\__ \ |_ + // |_|\___/ \___/ |_____\____|____/ |_|\___||___/\__| + printf(" _ ___ ___ _ ____ ____ _____ _\r\n"); + printf("(_)( _ ) / _ \\ | | / ___| _ \\ |_ _|__ ___| |_r\n"); + printf("| |/ _ \\| | | | | | | | | | | | | |/ _ \\/ __| __|\r\n"); + printf("| | (_) | |_| | | |__| |___| |_| | | | __/\\__ \\ |_\r\n"); + printf("|_|\\___/ \\___/ |_____\\____|____/ |_|\\___||___/\\__|\r\n"); + unity_run_menu(); +} diff --git a/components/esp_lcd/test/test_i80_board.h b/components/esp_lcd/test_apps/i80_lcd/main/test_i80_board.h similarity index 92% rename from components/esp_lcd/test/test_i80_board.h rename to components/esp_lcd/test_apps/i80_lcd/main/test_i80_board.h index 088adad2f8..0e44ac9a10 100644 --- a/components/esp_lcd/test/test_i80_board.h +++ b/components/esp_lcd/test_apps/i80_lcd/main/test_i80_board.h @@ -1,5 +1,14 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include "sdkconfig.h" +#ifdef __cplusplus +extern "C" { +#endif + #define TEST_LCD_H_RES (240) #define TEST_LCD_V_RES (280) @@ -70,3 +79,7 @@ #define TEST_LCD_DATA14_GPIO (16) #define TEST_LCD_DATA15_GPIO (17) #endif + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_lcd/test/test_i80_lcd_panel.c b/components/esp_lcd/test_apps/i80_lcd/main/test_i80_lcd_panel.c similarity index 95% rename from components/esp_lcd/test/test_i80_lcd_panel.c rename to components/esp_lcd/test_apps/i80_lcd/main/test_i80_lcd_panel.c index a70a1ea992..50f7a87c10 100644 --- a/components/esp_lcd/test/test_i80_lcd_panel.c +++ b/components/esp_lcd/test_apps/i80_lcd/main/test_i80_lcd_panel.c @@ -1,7 +1,14 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ + #include #include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" #include "unity.h" -#include "test_utils.h" #include "esp_lcd_panel_io.h" #include "esp_lcd_panel_vendor.h" #include "esp_lcd_panel_ops.h" @@ -9,8 +16,51 @@ #include "driver/gpio.h" #include "test_i80_board.h" +void test_app_include_i80_lcd(void) +{ +} + +#if SOC_I2S_LCD_I80_VARIANT +#include "driver/i2s.h" + +TEST_CASE("i80_and_i2s_driver_co-existence", "[lcd][i2s]") +{ + esp_lcd_i80_bus_handle_t i80_bus = NULL; + esp_lcd_i80_bus_config_t bus_config = { + .dc_gpio_num = TEST_LCD_DC_GPIO, + .wr_gpio_num = TEST_LCD_PCLK_GPIO, + .data_gpio_nums = { + TEST_LCD_DATA0_GPIO, + TEST_LCD_DATA1_GPIO, + TEST_LCD_DATA2_GPIO, + TEST_LCD_DATA3_GPIO, + TEST_LCD_DATA4_GPIO, + TEST_LCD_DATA5_GPIO, + TEST_LCD_DATA6_GPIO, + TEST_LCD_DATA7_GPIO, + }, + .bus_width = 8, + .max_transfer_bytes = 20, + }; + TEST_ESP_OK(esp_lcd_new_i80_bus(&bus_config, &i80_bus)); + + i2s_config_t i2s_config = { + .mode = I2S_MODE_MASTER | I2S_MODE_TX, + .sample_rate = 36000, + .bits_per_sample = 16, + .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, + .communication_format = I2S_COMM_FORMAT_STAND_I2S, + .dma_desc_num = 6, + .dma_frame_num = 60, + }; + // I2S driver won't be installed as the same I2S port has been used by LCD + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, i2s_driver_install(0, &i2s_config, 0, NULL)); + TEST_ESP_OK(esp_lcd_del_i80_bus(i80_bus)); +} +#endif // SOC_I2S_LCD_I80_VARIANT + #if SOC_LCDCAM_SUPPORTED -TEST_CASE("lcd i80 device swap color bytes", "[lcd]") +TEST_CASE("lcd_i80_device_swap_color_bytes", "[lcd]") { esp_lcd_i80_bus_handle_t i80_bus = NULL; esp_lcd_i80_bus_config_t bus_config = { @@ -72,7 +122,7 @@ TEST_CASE("lcd i80 device swap color bytes", "[lcd]") TEST_ESP_OK(esp_lcd_del_i80_bus(i80_bus)); } -TEST_CASE("lcd i80 device clock mode", "[lcd]") +TEST_CASE("lcd_i80_device_clock_mode", "[lcd]") { esp_lcd_i80_bus_handle_t i80_bus = NULL; esp_lcd_i80_bus_config_t bus_config = { @@ -131,8 +181,7 @@ TEST_CASE("lcd i80 device clock mode", "[lcd]") } #endif // SOC_LCDCAM_SUPPORTED -#if SOC_LCD_I80_SUPPORTED -TEST_CASE("lcd i80 bus and device allocation", "[lcd]") +TEST_CASE("lcd_i80_bus_and_device_allocation", "[lcd]") { esp_lcd_i80_bus_handle_t i80_buses[SOC_LCD_I80_BUSES] = {}; esp_lcd_i80_bus_config_t bus_config = { @@ -176,7 +225,7 @@ TEST_CASE("lcd i80 bus and device allocation", "[lcd]") } } -TEST_CASE("lcd i80 bus exclusively owned by one device", "[lcd]") +TEST_CASE("lcd_i80_bus_exclusively_owned_by_one_device", "[lcd]") { esp_lcd_i80_bus_handle_t i80_bus_handle = NULL; esp_lcd_i80_bus_config_t bus_config = { @@ -211,7 +260,7 @@ TEST_CASE("lcd i80 bus exclusively owned by one device", "[lcd]") TEST_ESP_OK(esp_lcd_del_i80_bus(i80_bus_handle)); } -TEST_CASE("lcd panel i80 io test", "[lcd]") +TEST_CASE("lcd_panel_i80_io_test", "[lcd]") { esp_lcd_i80_bus_handle_t i80_bus = NULL; esp_lcd_i80_bus_config_t bus_config = { @@ -257,9 +306,6 @@ TEST_CASE("lcd panel i80 io test", "[lcd]") .bits_per_pixel = 16, }; -// On esp32, GPIO16 and GPIO17 are connected to PSRAM, and we don't have other spare GPIOs can be used in the test -// so we skip the 16bit test on esp32 when PSRAM is enabled -#if !CONFIG_ESP32_SPIRAM_SUPPORT printf("testing bus-width=16bit, cmd/param bit-width=8bit\r\n"); bus_config.bus_width = 16; TEST_ESP_OK(esp_lcd_new_i80_bus(&bus_config, &i80_bus)); @@ -292,7 +338,6 @@ TEST_CASE("lcd panel i80 io test", "[lcd]") TEST_ESP_OK(esp_lcd_panel_del(panel_handle)); TEST_ESP_OK(esp_lcd_panel_io_del(io_handle)); TEST_ESP_OK(esp_lcd_del_i80_bus(i80_bus)); -#endif printf("testing bus-width=8bit, cmd/param bit-width=8bit\r\n"); bus_config.bus_width = 8; @@ -327,7 +372,7 @@ TEST_CASE("lcd panel i80 io test", "[lcd]") TEST_ESP_OK(esp_lcd_del_i80_bus(i80_bus)); } -TEST_CASE("lcd panel with i80 interface (st7789, 8bits)", "[lcd]") +TEST_CASE("lcd_panel_with_i80_interface_(st7789, 8bits)", "[lcd]") { #define TEST_IMG_SIZE (100 * 100 * sizeof(uint16_t)) uint8_t *img = heap_caps_malloc(TEST_IMG_SIZE, MALLOC_CAP_DMA); @@ -407,44 +452,3 @@ TEST_CASE("lcd panel with i80 interface (st7789, 8bits)", "[lcd]") free(img); #undef TEST_IMG_SIZE } - -#endif // SOC_LCD_I80_SUPPORTED - -#if SOC_I2S_LCD_I80_VARIANT -#include "driver/i2s.h" - -TEST_CASE("i80 and i2s driver coexistance", "[lcd][i2s]") -{ - esp_lcd_i80_bus_handle_t i80_bus = NULL; - esp_lcd_i80_bus_config_t bus_config = { - .dc_gpio_num = TEST_LCD_DC_GPIO, - .wr_gpio_num = TEST_LCD_PCLK_GPIO, - .data_gpio_nums = { - TEST_LCD_DATA0_GPIO, - TEST_LCD_DATA1_GPIO, - TEST_LCD_DATA2_GPIO, - TEST_LCD_DATA3_GPIO, - TEST_LCD_DATA4_GPIO, - TEST_LCD_DATA5_GPIO, - TEST_LCD_DATA6_GPIO, - TEST_LCD_DATA7_GPIO, - }, - .bus_width = 8, - .max_transfer_bytes = 20, - }; - TEST_ESP_OK(esp_lcd_new_i80_bus(&bus_config, &i80_bus)); - - i2s_config_t i2s_config = { - .mode = I2S_MODE_MASTER | I2S_MODE_TX, - .sample_rate = 36000, - .bits_per_sample = 16, - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, - .communication_format = I2S_COMM_FORMAT_STAND_I2S, - .dma_desc_num = 6, - .dma_frame_num = 60, - }; - // I2S driver won't be installed as the same I2S port has been used by LCD - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, i2s_driver_install(0, &i2s_config, 0, NULL)); - TEST_ESP_OK(esp_lcd_del_i80_bus(i80_bus)); -} -#endif // SOC_I2S_LCD_I80_VARIANT diff --git a/components/esp_lcd/test_apps/i80_lcd/pytest_i80_lcd.py b/components/esp_lcd/test_apps/i80_lcd/pytest_i80_lcd.py new file mode 100644 index 0000000000..721d615b97 --- /dev/null +++ b/components/esp_lcd/test_apps/i80_lcd/pytest_i80_lcd.py @@ -0,0 +1,22 @@ +# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 + +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32 +@pytest.mark.esp32s2 +@pytest.mark.esp32s3 +@pytest.mark.generic +@pytest.mark.parametrize( + 'config', + [ + 'release', + ], + indirect=True, +) +def test_i80_lcd(dut: Dut) -> None: + dut.expect_exact('Press ENTER to see the list of tests') + dut.write('*') + dut.expect_unity_test_output() diff --git a/components/esp_lcd/test_apps/i80_lcd/sdkconfig.ci.release b/components/esp_lcd/test_apps/i80_lcd/sdkconfig.ci.release new file mode 100644 index 0000000000..91d93f163e --- /dev/null +++ b/components/esp_lcd/test_apps/i80_lcd/sdkconfig.ci.release @@ -0,0 +1,5 @@ +CONFIG_PM_ENABLE=y +CONFIG_FREERTOS_USE_TICKLESS_IDLE=y +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y diff --git a/components/esp_lcd/test_apps/i80_lcd/sdkconfig.defaults b/components/esp_lcd/test_apps/i80_lcd/sdkconfig.defaults new file mode 100644 index 0000000000..b308cb2ddd --- /dev/null +++ b/components/esp_lcd/test_apps/i80_lcd/sdkconfig.defaults @@ -0,0 +1,2 @@ +CONFIG_FREERTOS_HZ=1000 +CONFIG_ESP_TASK_WDT=n diff --git a/components/esp_lcd/test_apps/rgb_lcd/CMakeLists.txt b/components/esp_lcd/test_apps/rgb_lcd/CMakeLists.txt new file mode 100644 index 0000000000..e74a9f5358 --- /dev/null +++ b/components/esp_lcd/test_apps/rgb_lcd/CMakeLists.txt @@ -0,0 +1,5 @@ +# This is the project CMakeLists.txt file for the test subproject +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(rgb_lcd_panel_test) diff --git a/components/esp_lcd/test_apps/rgb_lcd/README.md b/components/esp_lcd/test_apps/rgb_lcd/README.md new file mode 100644 index 0000000000..47ecb029fc --- /dev/null +++ b/components/esp_lcd/test_apps/rgb_lcd/README.md @@ -0,0 +1,4 @@ +| Supported Targets | ESP32-S3 | +| ----------------- | -------- | + +This test app is used to test RGB565 interfaced LCDs. diff --git a/components/esp_lcd/test_apps/rgb_lcd/main/CMakeLists.txt b/components/esp_lcd/test_apps/rgb_lcd/main/CMakeLists.txt new file mode 100644 index 0000000000..34d2e684ea --- /dev/null +++ b/components/esp_lcd/test_apps/rgb_lcd/main/CMakeLists.txt @@ -0,0 +1,7 @@ +set(srcs "test_app_main.c" + "test_rgb_panel.c") + +idf_component_register(SRCS ${srcs} + PRIV_REQUIRES esp_lcd unity) + +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 new file mode 100644 index 0000000000..434a50e362 --- /dev/null +++ b/components/esp_lcd/test_apps/rgb_lcd/main/test_app_main.c @@ -0,0 +1,51 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ + +#include "unity.h" +#include "unity_test_runner.h" +#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) + +static size_t before_free_8bit; +static size_t before_free_32bit; + +static void check_leak(size_t before_free, size_t after_free, const char *type) +{ + ssize_t delta = after_free - before_free; + printf("MALLOC_CAP_%s: Before %u bytes free, After %u bytes free (delta %d)\n", type, before_free, after_free, delta); + TEST_ASSERT_MESSAGE(delta >= TEST_MEMORY_LEAK_THRESHOLD, "memory leak"); +} + +void setUp(void) +{ + before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); + before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); +} + +void tearDown(void) +{ + size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); + size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); + check_leak(before_free_8bit, after_free_8bit, "8BIT"); + check_leak(before_free_32bit, after_free_32bit, "32BIT"); +} + +void app_main(void) +{ + // ____ ____ ____ _ ____ ____ _____ _ + // | _ \ / ___| __ ) | | / ___| _ \ |_ _|__ ___| |_ + // | |_) | | _| _ \ | | | | | | | | | |/ _ \/ __| __| + // | _ <| |_| | |_) | | |__| |___| |_| | | | __/\__ \ |_ + // |_| \_\\____|____/ |_____\____|____/ |_|\___||___/\__| + printf(" ____ ____ ____ _ ____ ____ _____ _\r\n"); + printf("| _ \\ / ___| __ ) | | / ___| _ \\ |_ _|__ ___| |_\r\n"); + printf("| |_) | | _| _ \\ | | | | | | | | | |/ _ \\/ __| __|\r\n"); + printf("| _ <| |_| | |_) | | |__| |___| |_| | | | __/\\__ \\ |_\r\n"); + printf("|_| \\_\\\\____|____/ |_____\\____|____/ |_|\\___||___/\\__|\r\n"); + unity_run_menu(); +} diff --git a/components/esp_lcd/test_apps/rgb_lcd/main/test_rgb_board.h b/components/esp_lcd/test_apps/rgb_lcd/main/test_rgb_board.h new file mode 100644 index 0000000000..280feefdbc --- /dev/null +++ b/components/esp_lcd/test_apps/rgb_lcd/main/test_rgb_board.h @@ -0,0 +1,41 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#define TEST_LCD_H_RES 480 +#define TEST_LCD_V_RES 272 + +#define TEST_LCD_VSYNC_GPIO 48 +#define TEST_LCD_HSYNC_GPIO 47 +#define TEST_LCD_DE_GPIO 45 +#define TEST_LCD_PCLK_GPIO 21 +#define TEST_LCD_DATA0_GPIO 3 // B0 +#define TEST_LCD_DATA1_GPIO 4 // B1 +#define TEST_LCD_DATA2_GPIO 5 // B2 +#define TEST_LCD_DATA3_GPIO 6 // B3 +#define TEST_LCD_DATA4_GPIO 7 // B4 +#define TEST_LCD_DATA5_GPIO 8 // G0 +#define TEST_LCD_DATA6_GPIO 9 // G1 +#define TEST_LCD_DATA7_GPIO 10 // G2 +#define TEST_LCD_DATA8_GPIO 11 // G3 +#define TEST_LCD_DATA9_GPIO 12 // G4 +#define TEST_LCD_DATA10_GPIO 13 // G5 +#define TEST_LCD_DATA11_GPIO 14 // R0 +#define TEST_LCD_DATA12_GPIO 15 // R1 +#define TEST_LCD_DATA13_GPIO 16 // R2 +#define TEST_LCD_DATA14_GPIO 17 // R3 +#define TEST_LCD_DATA15_GPIO 18 // R4 +#define TEST_LCD_DISP_EN_GPIO -1 + +#define TEST_LCD_PIXEL_CLOCK_HZ (10 * 1000 * 1000) + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_lcd/test/test_rgb_panel.c b/components/esp_lcd/test_apps/rgb_lcd/main/test_rgb_panel.c similarity index 58% rename from components/esp_lcd/test/test_rgb_panel.c rename to components/esp_lcd/test_apps/rgb_lcd/main/test_rgb_panel.c index d606549980..12053097d2 100644 --- a/components/esp_lcd/test/test_rgb_panel.c +++ b/components/esp_lcd/test_apps/rgb_lcd/main/test_rgb_panel.c @@ -1,40 +1,21 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include #include "unity.h" -#include "test_utils.h" #include "esp_lcd_panel_rgb.h" #include "esp_lcd_panel_ops.h" -#include "soc/soc_caps.h" +#include "esp_system.h" +#include "test_rgb_board.h" -#define TEST_LCD_H_RES (480) -#define TEST_LCD_V_RES (272) +void test_app_include_rgb_lcd(void) +{ +} -#define TEST_LCD_VSYNC_GPIO (48) -#define TEST_LCD_HSYNC_GPIO (47) -#define TEST_LCD_DE_GPIO (45) -#define TEST_LCD_PCLK_GPIO (21) -#define TEST_LCD_DATA0_GPIO (3) // B0 -#define TEST_LCD_DATA1_GPIO (4) // B1 -#define TEST_LCD_DATA2_GPIO (5) // B2 -#define TEST_LCD_DATA3_GPIO (6) // B3 -#define TEST_LCD_DATA4_GPIO (7) // B4 -#define TEST_LCD_DATA5_GPIO (8) // G0 -#define TEST_LCD_DATA6_GPIO (9) // G1 -#define TEST_LCD_DATA7_GPIO (10) // G2 -#define TEST_LCD_DATA8_GPIO (11) // G3 -#define TEST_LCD_DATA9_GPIO (12) // G4 -#define TEST_LCD_DATA10_GPIO (13) // G5 -#define TEST_LCD_DATA11_GPIO (14) // R0 -#define TEST_LCD_DATA12_GPIO (15) // R1 -#define TEST_LCD_DATA13_GPIO (16) // R2 -#define TEST_LCD_DATA14_GPIO (17) // R3 -#define TEST_LCD_DATA15_GPIO (18) // R4 -#define TEST_LCD_DISP_EN_GPIO (39) - -#if SOC_LCD_RGB_SUPPORTED -// RGB driver consumes a huge memory to save frame buffer, only test it with PSRAM enabled -#if CONFIG_SPIRAM_USE_MALLOC -TEST_CASE("lcd rgb lcd panel", "[lcd]") +TEST_CASE("lcd_rgb_lcd_panel", "[lcd]") { #define TEST_IMG_SIZE (100 * 100 * sizeof(uint16_t)) uint8_t *img = malloc(TEST_IMG_SIZE); @@ -43,6 +24,8 @@ TEST_CASE("lcd rgb lcd panel", "[lcd]") esp_lcd_panel_handle_t panel_handle = NULL; esp_lcd_rgb_panel_config_t panel_config = { .data_width = 16, + .psram_trans_align = 64, + .clk_src = LCD_CLK_SRC_PLL160M, .disp_gpio_num = TEST_LCD_DISP_EN_GPIO, .pclk_gpio_num = TEST_LCD_PCLK_GPIO, .vsync_gpio_num = TEST_LCD_VSYNC_GPIO, @@ -67,17 +50,18 @@ TEST_CASE("lcd rgb lcd panel", "[lcd]") TEST_LCD_DATA15_GPIO, }, .timings = { - .pclk_hz = 12000000, + .pclk_hz = TEST_LCD_PIXEL_CLOCK_HZ, .h_res = TEST_LCD_H_RES, .v_res = TEST_LCD_V_RES, - .hsync_back_porch = 43, - .hsync_front_porch = 2, - .hsync_pulse_width = 1, - .vsync_back_porch = 12, - .vsync_front_porch = 1, + .hsync_back_porch = 68, + .hsync_front_porch = 20, + .hsync_pulse_width = 5, + .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 }, - .flags.fb_in_psram = 1, + .flags.fb_in_psram = 1, // allocate frame buffer in PSRAM }; // Test stream mode and one-off mode for (int i = 0; i < 2; i++) { @@ -99,6 +83,3 @@ TEST_CASE("lcd rgb lcd panel", "[lcd]") free(img); #undef TEST_IMG_SIZE } - -#endif // CONFIG_SPIRAM_USE_MALLOC -#endif // SOC_LCD_RGB_SUPPORTED 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 new file mode 100644 index 0000000000..52c04a369f --- /dev/null +++ b/components/esp_lcd/test_apps/rgb_lcd/pytest_rgb_lcd.py @@ -0,0 +1,20 @@ +# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 + +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32s3 +@pytest.mark.octal_psram +@pytest.mark.parametrize( + 'config', + [ + 'release', + ], + indirect=True, +) +def test_rgb_lcd(dut: Dut) -> None: + dut.expect_exact('Press ENTER to see the list of tests') + dut.write('*') + dut.expect_unity_test_output() diff --git a/components/esp_lcd/test_apps/rgb_lcd/sdkconfig.ci.release b/components/esp_lcd/test_apps/rgb_lcd/sdkconfig.ci.release new file mode 100644 index 0000000000..91d93f163e --- /dev/null +++ b/components/esp_lcd/test_apps/rgb_lcd/sdkconfig.ci.release @@ -0,0 +1,5 @@ +CONFIG_PM_ENABLE=y +CONFIG_FREERTOS_USE_TICKLESS_IDLE=y +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y diff --git a/components/esp_lcd/test_apps/rgb_lcd/sdkconfig.defaults b/components/esp_lcd/test_apps/rgb_lcd/sdkconfig.defaults new file mode 100644 index 0000000000..b308cb2ddd --- /dev/null +++ b/components/esp_lcd/test_apps/rgb_lcd/sdkconfig.defaults @@ -0,0 +1,2 @@ +CONFIG_FREERTOS_HZ=1000 +CONFIG_ESP_TASK_WDT=n diff --git a/components/esp_lcd/test_apps/rgb_lcd/sdkconfig.defaults.esp32s3 b/components/esp_lcd/test_apps/rgb_lcd/sdkconfig.defaults.esp32s3 new file mode 100644 index 0000000000..2877855408 --- /dev/null +++ b/components/esp_lcd/test_apps/rgb_lcd/sdkconfig.defaults.esp32s3 @@ -0,0 +1,3 @@ +CONFIG_ESP32S3_SPIRAM_SUPPORT=y +CONFIG_SPIRAM_MODE_OCT=y +CONFIG_SPIRAM_SPEED_80M=y diff --git a/components/esp_lcd/test_apps/spi_lcd/CMakeLists.txt b/components/esp_lcd/test_apps/spi_lcd/CMakeLists.txt new file mode 100644 index 0000000000..46462997a7 --- /dev/null +++ b/components/esp_lcd/test_apps/spi_lcd/CMakeLists.txt @@ -0,0 +1,5 @@ +# This is the project CMakeLists.txt file for the test subproject +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(spi_lcd_panel_test) diff --git a/components/esp_lcd/test_apps/spi_lcd/README.md b/components/esp_lcd/test_apps/spi_lcd/README.md new file mode 100644 index 0000000000..b7b1010107 --- /dev/null +++ b/components/esp_lcd/test_apps/spi_lcd/README.md @@ -0,0 +1 @@ +This test app is used to test LCDs with SPI interface. diff --git a/components/esp_lcd/test_apps/spi_lcd/main/CMakeLists.txt b/components/esp_lcd/test_apps/spi_lcd/main/CMakeLists.txt new file mode 100644 index 0000000000..d3fff0f65b --- /dev/null +++ b/components/esp_lcd/test_apps/spi_lcd/main/CMakeLists.txt @@ -0,0 +1,7 @@ +set(srcs "test_app_main.c" + "test_spi_lcd_panel.c") + +idf_component_register(SRCS ${srcs} + PRIV_REQUIRES esp_lcd unity) + +target_link_libraries(${COMPONENT_LIB} INTERFACE "-u test_app_include_spi_lcd") diff --git a/components/esp_lcd/test_apps/spi_lcd/main/test_app_main.c b/components/esp_lcd/test_apps/spi_lcd/main/test_app_main.c new file mode 100644 index 0000000000..5c978d553b --- /dev/null +++ b/components/esp_lcd/test_apps/spi_lcd/main/test_app_main.c @@ -0,0 +1,51 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ + +#include "unity.h" +#include "unity_test_runner.h" +#include "esp_heap_caps.h" + +// Some resources are lazy allocated in the LCD driver, the threadhold is left for that case +#define TEST_MEMORY_LEAK_THRESHOLD (-300) + +static size_t before_free_8bit; +static size_t before_free_32bit; + +static void check_leak(size_t before_free, size_t after_free, const char *type) +{ + ssize_t delta = after_free - before_free; + printf("MALLOC_CAP_%s: Before %u bytes free, After %u bytes free (delta %d)\n", type, before_free, after_free, delta); + TEST_ASSERT_MESSAGE(delta >= TEST_MEMORY_LEAK_THRESHOLD, "memory leak"); +} + +void setUp(void) +{ + before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); + before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); +} + +void tearDown(void) +{ + size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); + size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); + check_leak(before_free_8bit, after_free_8bit, "8BIT"); + check_leak(before_free_32bit, after_free_32bit, "32BIT"); +} + +void app_main(void) +{ + // ____ ____ ___ _ ____ ____ _____ _ + // / ___|| _ \_ _| | | / ___| _ \ |_ _|__ ___| |_ + // \___ \| |_) | | | | | | | | | | | |/ _ \/ __| __| + // ___) | __/| | | |__| |___| |_| | | | __/\__ \ |_ + // |____/|_| |___| |_____\____|____/ |_|\___||___/\__| + printf(" ____ ____ ___ _ ____ ____ _____ _\r\n"); + printf("/ ___|| _ \\_ _| | | / ___| _ \\ |_ _|__ ___| |_\r\n"); + printf("\\___ \\| |_) | | | | | | | | | | | |/ _ \\/ __| __|\r\n"); + printf(" ___) | __/| | | |__| |___| |_| | | | __/\\__ \\ |_\r\n"); + printf("|____/|_| |___| |_____\\____|____/ |_|\\___||___/\\__|\r\n"); + unity_run_menu(); +} diff --git a/components/esp_lcd/test_apps/spi_lcd/main/test_spi_board.h b/components/esp_lcd/test_apps/spi_lcd/main/test_spi_board.h new file mode 100644 index 0000000000..2bb9c8a755 --- /dev/null +++ b/components/esp_lcd/test_apps/spi_lcd/main/test_spi_board.h @@ -0,0 +1,33 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#define TEST_LCD_H_RES 240 +#define TEST_LCD_V_RES 280 + +#define TEST_LCD_BK_LIGHT_GPIO 18 +#define TEST_LCD_RST_GPIO 5 +#define TEST_LCD_CS_GPIO 0 +#define TEST_LCD_DC_GPIO 19 +#define TEST_LCD_PCLK_GPIO 2 +#define TEST_LCD_DATA0_GPIO 4 +#define TEST_LCD_DATA1_GPIO 7 +#define TEST_LCD_DATA2_GPIO 8 +#define TEST_LCD_DATA3_GPIO 9 +#define TEST_LCD_DATA4_GPIO 10 +#define TEST_LCD_DATA5_GPIO 11 +#define TEST_LCD_DATA6_GPIO 12 +#define TEST_LCD_DATA7_GPIO 13 + +#define TEST_LCD_PIXEL_CLOCK_HZ (20 * 1000 * 1000) + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_lcd/test/test_spi_lcd_panel.c b/components/esp_lcd/test_apps/spi_lcd/main/test_spi_lcd_panel.c similarity index 59% rename from components/esp_lcd/test/test_spi_lcd_panel.c rename to components/esp_lcd/test_apps/spi_lcd/main/test_spi_lcd_panel.c index 4a92833e69..1dd8a930b4 100644 --- a/components/esp_lcd/test/test_spi_lcd_panel.c +++ b/components/esp_lcd/test_apps/spi_lcd/main/test_spi_lcd_panel.c @@ -1,8 +1,12 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include #include "sdkconfig.h" #include "unity.h" -#include "test_utils.h" #include "driver/spi_master.h" #include "driver/gpio.h" #include "esp_lcd_panel_io.h" @@ -12,16 +16,22 @@ #include "soc/soc_caps.h" #include "test_spi_board.h" -#define TEST_SPI_HOST_ID (1) -#define TEST_LCD_PIXEL_CLOCK_HZ (20 * 1000 * 1000) // 20MHz +#define TEST_SPI_HOST_ID SPI2_HOST -static void lcd_initialize_spi(esp_lcd_panel_io_handle_t *io_handle, esp_lcd_panel_io_color_trans_done_cb_t on_color_trans_done, void *user_ctx, int cmd_bits, int param_bits, bool oct_mode) +void test_app_include_spi_lcd(void) { +} + +void test_spi_lcd_common_initialize(esp_lcd_panel_io_handle_t *io_handle, esp_lcd_panel_io_color_trans_done_cb_t on_color_trans_done, + void *user_data, int cmd_bits, int param_bits, bool oct_mode) +{ + // turn off backlight gpio_config_t bk_gpio_config = { .mode = GPIO_MODE_OUTPUT, .pin_bit_mask = 1ULL << TEST_LCD_BK_LIGHT_GPIO }; TEST_ESP_OK(gpio_config(&bk_gpio_config)); + gpio_set_level(TEST_LCD_BK_LIGHT_GPIO, 0); spi_bus_config_t buscfg = { .sclk_io_num = TEST_LCD_PCLK_GPIO, @@ -52,7 +62,7 @@ static void lcd_initialize_spi(esp_lcd_panel_io_handle_t *io_handle, esp_lcd_pan .lcd_cmd_bits = cmd_bits, .lcd_param_bits = param_bits, .on_color_trans_done = on_color_trans_done, - .user_ctx = user_ctx + .user_ctx = user_data, }; if (oct_mode) { io_config.flags.octal_mode = 1; @@ -67,8 +77,6 @@ static void lcd_panel_test(esp_lcd_panel_io_handle_t io_handle, esp_lcd_panel_ha uint8_t *img = heap_caps_malloc(TEST_IMG_SIZE, MALLOC_CAP_DMA); TEST_ASSERT_NOT_NULL(img); - // turn off backlight - gpio_set_level(TEST_LCD_BK_LIGHT_GPIO, 0); esp_lcd_panel_reset(panel_handle); esp_lcd_panel_init(panel_handle); esp_lcd_panel_invert_color(panel_handle, true); @@ -94,10 +102,10 @@ static void lcd_panel_test(esp_lcd_panel_io_handle_t io_handle, esp_lcd_panel_ha #undef TEST_IMG_SIZE } -TEST_CASE("lcd panel spi io test", "[lcd]") +TEST_CASE("lcd_panel_spi_io_test", "[lcd]") { esp_lcd_panel_io_handle_t io_handle = NULL; - lcd_initialize_spi(&io_handle, NULL, NULL, 8, 8, false); + test_spi_lcd_common_initialize(&io_handle, NULL, NULL, 8, 8, false); esp_lcd_panel_io_tx_param(io_handle, 0x1A, NULL, 0); esp_lcd_panel_io_tx_param(io_handle, 0x1B, (uint8_t[]) { 0x11, 0x22, 0x33 @@ -106,7 +114,7 @@ TEST_CASE("lcd panel spi io test", "[lcd]") TEST_ESP_OK(esp_lcd_panel_io_del(io_handle)); TEST_ESP_OK(spi_bus_free(TEST_SPI_HOST_ID)); - lcd_initialize_spi(&io_handle, NULL, NULL, 16, 16, false); + test_spi_lcd_common_initialize(&io_handle, NULL, NULL, 16, 16, false); esp_lcd_panel_io_tx_param(io_handle, 0x1A01, NULL, 0); esp_lcd_panel_io_tx_param(io_handle, 0x1B02, (uint16_t[]) { 0x11, 0x22, 0x33 @@ -116,7 +124,7 @@ TEST_CASE("lcd panel spi io test", "[lcd]") TEST_ESP_OK(spi_bus_free(TEST_SPI_HOST_ID)); #if SOC_SPI_SUPPORT_OCT - lcd_initialize_spi(&io_handle, NULL, NULL, 8, 8, true); + test_spi_lcd_common_initialize(&io_handle, NULL, NULL, 8, 8, true); esp_lcd_panel_io_tx_param(io_handle, 0x1A, NULL, 0); esp_lcd_panel_io_tx_param(io_handle, 0x1B, (uint8_t[]) { 0x11, 0x22, 0x33 @@ -125,7 +133,7 @@ TEST_CASE("lcd panel spi io test", "[lcd]") TEST_ESP_OK(esp_lcd_panel_io_del(io_handle)); TEST_ESP_OK(spi_bus_free(TEST_SPI_HOST_ID)); - lcd_initialize_spi(&io_handle, NULL, NULL, 16, 16, true); + test_spi_lcd_common_initialize(&io_handle, NULL, NULL, 16, 16, true); esp_lcd_panel_io_tx_param(io_handle, 0x1A01, NULL, 0); esp_lcd_panel_io_tx_param(io_handle, 0x1B02, (uint16_t[]) { 0x11, 0x22, 0x33 @@ -137,11 +145,11 @@ TEST_CASE("lcd panel spi io test", "[lcd]") } #if SOC_SPI_SUPPORT_OCT -TEST_CASE("lcd panel with 8-line spi interface (st7789)", "[lcd]") +TEST_CASE("lcd_panel_with_8-line_spi_interface_(st7789)", "[lcd]") { esp_lcd_panel_io_handle_t io_handle = NULL; esp_lcd_panel_handle_t panel_handle = NULL; - lcd_initialize_spi(&io_handle, NULL, NULL, 8, 8, true); + 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, .color_space = ESP_LCD_COLOR_SPACE_RGB, @@ -151,11 +159,11 @@ TEST_CASE("lcd panel with 8-line spi interface (st7789)", "[lcd]") lcd_panel_test(io_handle, panel_handle); } -TEST_CASE("lcd panel with 8-line spi interface (nt35510)", "[lcd]") +TEST_CASE("lcd_panel_with_8-line_spi_interface_(nt35510)", "[lcd]") { esp_lcd_panel_io_handle_t io_handle = NULL; esp_lcd_panel_handle_t panel_handle = NULL; - lcd_initialize_spi(&io_handle, NULL, NULL, 16, 16, true); + 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, .color_space = ESP_LCD_COLOR_SPACE_RGB, @@ -166,11 +174,11 @@ TEST_CASE("lcd panel with 8-line spi interface (nt35510)", "[lcd]") } #endif // SOC_SPI_SUPPORT_OCT -TEST_CASE("lcd panel with 1-line spi interface (st7789)", "[lcd]") +TEST_CASE("lcd_panel_with_1-line_spi_interface_(st7789)", "[lcd]") { esp_lcd_panel_io_handle_t io_handle = NULL; esp_lcd_panel_handle_t panel_handle = NULL; - lcd_initialize_spi(&io_handle, NULL, NULL, 8, 8, false); + 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, .color_space = ESP_LCD_COLOR_SPACE_RGB, @@ -179,81 +187,3 @@ TEST_CASE("lcd panel with 1-line spi interface (st7789)", "[lcd]") TEST_ESP_OK(esp_lcd_new_panel_st7789(io_handle, &panel_config, &panel_handle)); lcd_panel_test(io_handle, panel_handle); } - -// The following test shows a porting example of LVGL GUI library -// To run the LVGL tests, you need to clone the LVGL library into components directory firstly -#if CONFIG_LV_USE_USER_DATA -#include "test_lvgl_port.h" - -static bool notify_lvgl_ready_to_flush(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_io_event_data_t *edata, void *user_ctx) -{ - lv_disp_t *disp = *(lv_disp_t **)user_ctx; - lv_disp_flush_ready(&disp->driver); - return false; -} - -static void lvgl_gui_test(esp_lcd_panel_io_handle_t io_handle, esp_lcd_panel_handle_t panel_handle, lv_disp_t **disp) -{ - // initialize LVGL graphics library - lv_init(); - // turn off backlight - gpio_set_level(TEST_LCD_BK_LIGHT_GPIO, 0); - esp_lcd_panel_reset(panel_handle); - esp_lcd_panel_init(panel_handle); - esp_lcd_panel_invert_color(panel_handle, true); - // the gap is LCD panel specific, even panels with the same driver IC, can have different gap value - esp_lcd_panel_set_gap(panel_handle, 0, 20); - // turn on backlight - gpio_set_level(TEST_LCD_BK_LIGHT_GPIO, 1); - - test_lvgl_task_loop(panel_handle, TEST_LCD_H_RES, TEST_LCD_V_RES, disp); -} - -#if SOC_SPI_SUPPORT_OCT -TEST_CASE("lvgl gui with 8-line spi interface (st7789)", "[lcd][lvgl][ignore]") -{ - lv_disp_t *disp = NULL; - esp_lcd_panel_io_handle_t io_handle = NULL; - esp_lcd_panel_handle_t panel_handle = NULL; - lcd_initialize_spi(&io_handle, notify_lvgl_ready_to_flush, &disp, 8, 8, true); - esp_lcd_panel_dev_config_t panel_config = { - .reset_gpio_num = TEST_LCD_RST_GPIO, - .color_space = ESP_LCD_COLOR_SPACE_RGB, - .bits_per_pixel = 16, - }; - TEST_ESP_OK(esp_lcd_new_panel_st7789(io_handle, &panel_config, &panel_handle)); - lvgl_gui_test(io_handle, panel_handle, &disp); -} - -TEST_CASE("lvgl gui with 8-line spi interface (nt35510)", "[lcd][lvgl][ignore]") -{ - lv_disp_t *disp = NULL; - esp_lcd_panel_io_handle_t io_handle = NULL; - esp_lcd_panel_handle_t panel_handle = NULL; - lcd_initialize_spi(&io_handle, notify_lvgl_ready_to_flush, &disp, 16, 16, true); - esp_lcd_panel_dev_config_t panel_config = { - .reset_gpio_num = TEST_LCD_RST_GPIO, - .color_space = ESP_LCD_COLOR_SPACE_RGB, - .bits_per_pixel = 16, - }; - TEST_ESP_OK(esp_lcd_new_panel_nt35510(io_handle, &panel_config, &panel_handle)); - lvgl_gui_test(io_handle, panel_handle, &disp); -} -#endif // SOC_SPI_SUPPORT_OCT - -TEST_CASE("lvgl gui with 1-line spi interface (st7789)", "[lcd][lvgl][ignore]") -{ - lv_disp_t *disp = NULL; - esp_lcd_panel_io_handle_t io_handle = NULL; - esp_lcd_panel_handle_t panel_handle = NULL; - lcd_initialize_spi(&io_handle, notify_lvgl_ready_to_flush, &disp, 8, 8, false); - esp_lcd_panel_dev_config_t panel_config = { - .reset_gpio_num = TEST_LCD_RST_GPIO, - .color_space = ESP_LCD_COLOR_SPACE_RGB, - .bits_per_pixel = 16, - }; - TEST_ESP_OK(esp_lcd_new_panel_st7789(io_handle, &panel_config, &panel_handle)); - lvgl_gui_test(io_handle, panel_handle, &disp); -} - -#endif // CONFIG_LV_USE_USER_DATA diff --git a/components/esp_lcd/test_apps/spi_lcd/pytest_spi_lcd.py b/components/esp_lcd/test_apps/spi_lcd/pytest_spi_lcd.py new file mode 100644 index 0000000000..fcae4961e1 --- /dev/null +++ b/components/esp_lcd/test_apps/spi_lcd/pytest_spi_lcd.py @@ -0,0 +1,20 @@ +# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 + +import pytest +from pytest_embedded import Dut + + +@pytest.mark.supported_targets +@pytest.mark.generic +@pytest.mark.parametrize( + 'config', + [ + 'release', + ], + indirect=True, +) +def test_spi_lcd(dut: Dut) -> None: + dut.expect_exact('Press ENTER to see the list of tests') + dut.write('*') + dut.expect_unity_test_output() diff --git a/components/esp_lcd/test_apps/spi_lcd/sdkconfig.ci.release b/components/esp_lcd/test_apps/spi_lcd/sdkconfig.ci.release new file mode 100644 index 0000000000..3cff15d49e --- /dev/null +++ b/components/esp_lcd/test_apps/spi_lcd/sdkconfig.ci.release @@ -0,0 +1,3 @@ +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y diff --git a/components/esp_lcd/test_apps/spi_lcd/sdkconfig.defaults b/components/esp_lcd/test_apps/spi_lcd/sdkconfig.defaults new file mode 100644 index 0000000000..b308cb2ddd --- /dev/null +++ b/components/esp_lcd/test_apps/spi_lcd/sdkconfig.defaults @@ -0,0 +1,2 @@ +CONFIG_FREERTOS_HZ=1000 +CONFIG_ESP_TASK_WDT=n diff --git a/examples/peripherals/lcd/gc9a01/CMakeLists.txt b/examples/peripherals/lcd/gc9a01/CMakeLists.txt index 50065c7404..43af9216fc 100644 --- a/examples/peripherals/lcd/gc9a01/CMakeLists.txt +++ b/examples/peripherals/lcd/gc9a01/CMakeLists.txt @@ -2,8 +2,3 @@ cmake_minimum_required(VERSION 3.5) include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(lcd_gc9a01) - -# As the upstream LVGL library has build warnings in esp-idf build system, this is only for temporarily workaround -# Will remove this workaround when upstream LVGL fixes the warnings in the next release -idf_component_get_property(lvgl_lib lvgl__lvgl COMPONENT_LIB) -target_compile_options(${lvgl_lib} PRIVATE "-Wno-empty-body" "-Wno-strict-prototypes") diff --git a/examples/peripherals/lcd/gc9a01/main/idf_component.yml b/examples/peripherals/lcd/gc9a01/main/idf_component.yml index eedaf75ade..84e851db81 100644 --- a/examples/peripherals/lcd/gc9a01/main/idf_component.yml +++ b/examples/peripherals/lcd/gc9a01/main/idf_component.yml @@ -1,3 +1,3 @@ dependencies: idf: ">=4.4" - lvgl/lvgl: "~8.0.2" + lvgl/lvgl: "~8.2.0" diff --git a/examples/peripherals/lcd/i2c_oled/CMakeLists.txt b/examples/peripherals/lcd/i2c_oled/CMakeLists.txt index d1180c30fa..3c9d979191 100644 --- a/examples/peripherals/lcd/i2c_oled/CMakeLists.txt +++ b/examples/peripherals/lcd/i2c_oled/CMakeLists.txt @@ -2,8 +2,3 @@ cmake_minimum_required(VERSION 3.5) include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(i2c_oled) - -# As the upstream LVGL library has build warnings in esp-idf build system, this is only for temporarily workaround -# Will remove this workaround when upstream LVGL fixes the warnings in the next release -idf_component_get_property(lvgl_lib lvgl__lvgl COMPONENT_LIB) -target_compile_options(${lvgl_lib} PRIVATE "-Wno-empty-body" "-Wno-strict-prototypes") diff --git a/examples/peripherals/lcd/i2c_oled/main/idf_component.yml b/examples/peripherals/lcd/i2c_oled/main/idf_component.yml index eedaf75ade..84e851db81 100644 --- a/examples/peripherals/lcd/i2c_oled/main/idf_component.yml +++ b/examples/peripherals/lcd/i2c_oled/main/idf_component.yml @@ -1,3 +1,3 @@ dependencies: idf: ">=4.4" - lvgl/lvgl: "~8.0.2" + lvgl/lvgl: "~8.2.0" diff --git a/examples/peripherals/lcd/i80_controller/CMakeLists.txt b/examples/peripherals/lcd/i80_controller/CMakeLists.txt index 00a14efea6..a132259f6f 100644 --- a/examples/peripherals/lcd/i80_controller/CMakeLists.txt +++ b/examples/peripherals/lcd/i80_controller/CMakeLists.txt @@ -2,8 +2,3 @@ cmake_minimum_required(VERSION 3.5) include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(i80_controller) - -# As the upstream LVGL library has build warnings in esp-idf build system, this is only for temporarily workaround -# Will remove this workaround when upstream LVGL fixes the warnings in the next release -idf_component_get_property(lvgl_lib lvgl__lvgl COMPONENT_LIB) -target_compile_options(${lvgl_lib} PRIVATE "-Wno-empty-body" "-Wno-strict-prototypes") diff --git a/examples/peripherals/lcd/i80_controller/README.md b/examples/peripherals/lcd/i80_controller/README.md index fbe77e0d1f..c8934f226f 100644 --- a/examples/peripherals/lcd/i80_controller/README.md +++ b/examples/peripherals/lcd/i80_controller/README.md @@ -19,7 +19,7 @@ This example uses the [esp_timer](https://docs.espressif.com/projects/esp-idf/en ### Hardware Required * An ESP development board -* An Intel 8080 interfaced (so called MCU interface or parallel interface) LCD +* An Intel 8080 interfaced (so called MCU interface or parallel interface) LCD (this example can use ST7789 or NT35510) * An USB cable for power supply and programming ### Hardware Connection @@ -58,6 +58,8 @@ Run `idf.py set-target ` to select one supported target that can ru Run `idf.py menuconfig` to open a terminal UI where you can tune specific configuration for this example in the `Example Configuration` menu. +* `i80 LCD controller model`: Choose the LCD model to use by the example. If you choose `NT35510`, there will be another relevant configuration `NT35510 Data Width`, to choose the data line width for your NT35510 LCD module. + * `Allocate color data from PSRAM`: Select this option if you want to allocate the LVGL draw buffers from PSRAM. Run `idf.py -p PORT build flash monitor` to build, flash and monitor the project. A fancy animation will show up on the LCD as expected. diff --git a/examples/peripherals/lcd/i80_controller/main/Kconfig.projbuild b/examples/peripherals/lcd/i80_controller/main/Kconfig.projbuild index 208bd16277..def347cc95 100644 --- a/examples/peripherals/lcd/i80_controller/main/Kconfig.projbuild +++ b/examples/peripherals/lcd/i80_controller/main/Kconfig.projbuild @@ -8,4 +8,38 @@ menu "Example Configuration" Enable this option if you wish to allocate the color buffer used by LVGL from PSRAM. Unmatched PSRAM band width with LCD requirement can lead to blurred image display. + choice EXAMPLE_LCD_I80_CONTROLLER_MODEL + prompt "i80 LCD controller model" + default EXAMPLE_LCD_I80_CONTROLLER_ST7789 + help + Select LCD controller model + + config EXAMPLE_LCD_I80_CONTROLLER_ST7789 + bool "ST7789" + + config EXAMPLE_LCD_I80_CONTROLLER_NT35510 + bool "NT35510" + endchoice + + if EXAMPLE_LCD_I80_CONTROLLER_NT35510 + choice EXAMPLE_LCD_NT35510_DATA_WIDTH + prompt "NT35510 Data Width" + default EXAMPLE_LCD_NT35510_DATA_WIDTH_8 + help + Select NT35510 Data Width (8 or 16), a.k.a, the number of data lines. + + config EXAMPLE_LCD_NT35510_DATA_WIDTH_8 + bool "8" + + config EXAMPLE_LCD_NT35510_DATA_WIDTH_16 + bool "16" + endchoice + + endif + + config EXAMPLE_LCD_I80_BUS_WIDTH + int + default 16 if EXAMPLE_LCD_NT35510_DATA_WIDTH_16 + default 8 + endmenu diff --git a/examples/peripherals/lcd/i80_controller/main/i80_controller_example_main.c b/examples/peripherals/lcd/i80_controller/main/i80_controller_example_main.c index 02e8873887..b337680e96 100644 --- a/examples/peripherals/lcd/i80_controller/main/i80_controller_example_main.c +++ b/examples/peripherals/lcd/i80_controller/main/i80_controller_example_main.c @@ -38,6 +38,16 @@ static const char *TAG = "example"; #define EXAMPLE_PIN_NUM_DATA5 11 #define EXAMPLE_PIN_NUM_DATA6 12 #define EXAMPLE_PIN_NUM_DATA7 13 +#if CONFIG_EXAMPLE_LCD_I80_BUS_WIDTH > 8 +#define EXAMPLE_PIN_NUM_DATA8 14 +#define EXAMPLE_PIN_NUM_DATA9 15 +#define EXAMPLE_PIN_NUM_DATA10 16 +#define EXAMPLE_PIN_NUM_DATA11 17 +#define EXAMPLE_PIN_NUM_DATA12 18 +#define EXAMPLE_PIN_NUM_DATA13 19 +#define EXAMPLE_PIN_NUM_DATA14 20 +#define EXAMPLE_PIN_NUM_DATA15 21 +#endif #define EXAMPLE_PIN_NUM_PCLK 5 #define EXAMPLE_PIN_NUM_CS 3 #define EXAMPLE_PIN_NUM_DC 4 @@ -48,8 +58,13 @@ static const char *TAG = "example"; #define EXAMPLE_LCD_H_RES 240 #define EXAMPLE_LCD_V_RES 280 // Bit number used to represent command and parameter +#if CONFIG_EXAMPLE_LCD_I80_CONTROLLER_ST7789 #define EXAMPLE_LCD_CMD_BITS 8 #define EXAMPLE_LCD_PARAM_BITS 8 +#elif CONFIG_EXAMPLE_LCD_I80_CONTROLLER_NT35510 +#define EXAMPLE_LCD_CMD_BITS 16 +#define EXAMPLE_LCD_PARAM_BITS 16 +#endif #define EXAMPLE_LVGL_TICK_PERIOD_MS 2 @@ -110,8 +125,18 @@ void app_main(void) EXAMPLE_PIN_NUM_DATA5, EXAMPLE_PIN_NUM_DATA6, EXAMPLE_PIN_NUM_DATA7, +#if CONFIG_EXAMPLE_LCD_I80_BUS_WIDTH > 8 + EXAMPLE_PIN_NUM_DATA8, + EXAMPLE_PIN_NUM_DATA9, + EXAMPLE_PIN_NUM_DATA10, + EXAMPLE_PIN_NUM_DATA11, + EXAMPLE_PIN_NUM_DATA12, + EXAMPLE_PIN_NUM_DATA13, + EXAMPLE_PIN_NUM_DATA14, + EXAMPLE_PIN_NUM_DATA15, +#endif }, - .bus_width = 8, + .bus_width = CONFIG_EXAMPLE_LCD_I80_BUS_WIDTH, .max_transfer_bytes = EXAMPLE_LCD_H_RES * 100 * sizeof(uint16_t), .psram_trans_align = EXAMPLE_PSRAM_DATA_ALIGNMENT, .sram_trans_align = 4, @@ -135,18 +160,34 @@ void app_main(void) }; ESP_ERROR_CHECK(esp_lcd_new_panel_io_i80(i80_bus, &io_config, &io_handle)); - ESP_LOGI(TAG, "Install LCD driver of st7789"); esp_lcd_panel_handle_t panel_handle = NULL; +#if CONFIG_EXAMPLE_LCD_I80_CONTROLLER_ST7789 + ESP_LOGI(TAG, "Install LCD driver of st7789"); esp_lcd_panel_dev_config_t panel_config = { .reset_gpio_num = EXAMPLE_PIN_NUM_RST, .color_space = ESP_LCD_COLOR_SPACE_RGB, .bits_per_pixel = 16, }; ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(io_handle, &panel_config, &panel_handle)); +#elif CONFIG_EXAMPLE_LCD_I80_CONTROLLER_NT35510 + ESP_LOGI(TAG, "Install LCD driver of nt35510"); + esp_lcd_panel_dev_config_t panel_config = { + .reset_gpio_num = EXAMPLE_PIN_NUM_RST, + .color_space = ESP_LCD_COLOR_SPACE_BGR, + .bits_per_pixel = 16, + }; + ESP_ERROR_CHECK(esp_lcd_new_panel_nt35510(io_handle, &panel_config, &panel_handle)); +#endif esp_lcd_panel_reset(panel_handle); esp_lcd_panel_init(panel_handle); + // Set inversion, x/y coordinate order, x/y mirror according to your LCD module spec +#if CONFIG_EXAMPLE_LCD_I80_CONTROLLER_ST7789 esp_lcd_panel_invert_color(panel_handle, true); +#elif CONFIG_EXAMPLE_LCD_I80_CONTROLLER_NT35510 + esp_lcd_panel_swap_xy(panel_handle, true); + esp_lcd_panel_mirror(panel_handle, true, false); +#endif // the gap is LCD panel specific, even panels with the same driver IC, can have different gap value esp_lcd_panel_set_gap(panel_handle, 0, 20); diff --git a/examples/peripherals/lcd/i80_controller/main/idf_component.yml b/examples/peripherals/lcd/i80_controller/main/idf_component.yml index eedaf75ade..84e851db81 100644 --- a/examples/peripherals/lcd/i80_controller/main/idf_component.yml +++ b/examples/peripherals/lcd/i80_controller/main/idf_component.yml @@ -1,3 +1,3 @@ dependencies: idf: ">=4.4" - lvgl/lvgl: "~8.0.2" + lvgl/lvgl: "~8.2.0" diff --git a/examples/peripherals/lcd/rgb_panel/CMakeLists.txt b/examples/peripherals/lcd/rgb_panel/CMakeLists.txt index 867e9f3eb4..aa002ecfa1 100644 --- a/examples/peripherals/lcd/rgb_panel/CMakeLists.txt +++ b/examples/peripherals/lcd/rgb_panel/CMakeLists.txt @@ -2,8 +2,3 @@ cmake_minimum_required(VERSION 3.5) include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(rgb_panel) - -# As the upstream LVGL library has build warnings in esp-idf build system, this is only for temporarily workaround -# Will remove this workaround when upstream LVGL fixes the warnings in the next release -idf_component_get_property(lvgl_lib lvgl__lvgl COMPONENT_LIB) -target_compile_options(${lvgl_lib} PRIVATE "-Wno-empty-body" "-Wno-strict-prototypes") diff --git a/examples/peripherals/lcd/rgb_panel/main/idf_component.yml b/examples/peripherals/lcd/rgb_panel/main/idf_component.yml index eedaf75ade..84e851db81 100644 --- a/examples/peripherals/lcd/rgb_panel/main/idf_component.yml +++ b/examples/peripherals/lcd/rgb_panel/main/idf_component.yml @@ -1,3 +1,3 @@ dependencies: idf: ">=4.4" - lvgl/lvgl: "~8.0.2" + lvgl/lvgl: "~8.2.0" diff --git a/examples/peripherals/lcd/tjpgd/main/decode_image.c b/examples/peripherals/lcd/tjpgd/main/decode_image.c index a9a460bc39..f7182a32cb 100644 --- a/examples/peripherals/lcd/tjpgd/main/decode_image.c +++ b/examples/peripherals/lcd/tjpgd/main/decode_image.c @@ -1,11 +1,8 @@ -/* SPI Master example: jpeg decoder. - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ /* The image used for the effect on the LCD in the SPI master example is stored in flash diff --git a/examples/peripherals/lcd/tjpgd/main/decode_image.h b/examples/peripherals/lcd/tjpgd/main/decode_image.h index 223db59d6f..8fa1155005 100644 --- a/examples/peripherals/lcd/tjpgd/main/decode_image.h +++ b/examples/peripherals/lcd/tjpgd/main/decode_image.h @@ -1,10 +1,8 @@ /* - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ #pragma once #include diff --git a/examples/peripherals/lcd/tjpgd/main/lcd_tjpgd_example_main.c b/examples/peripherals/lcd/tjpgd/main/lcd_tjpgd_example_main.c index f327a5d660..d9faab0372 100644 --- a/examples/peripherals/lcd/tjpgd/main/lcd_tjpgd_example_main.c +++ b/examples/peripherals/lcd/tjpgd/main/lcd_tjpgd_example_main.c @@ -1,11 +1,9 @@ -/* LCD tjpgd example +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" diff --git a/examples/peripherals/lcd/tjpgd/main/pretty_effect.c b/examples/peripherals/lcd/tjpgd/main/pretty_effect.c index 89fea666b4..3aa8ac03c9 100644 --- a/examples/peripherals/lcd/tjpgd/main/pretty_effect.c +++ b/examples/peripherals/lcd/tjpgd/main/pretty_effect.c @@ -1,13 +1,8 @@ /* - This code generates an effect that should pass the 'fancy graphics' qualification - as set in the comment in the spi_master code. - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ #include #include "pretty_effect.h" diff --git a/examples/peripherals/lcd/tjpgd/main/pretty_effect.h b/examples/peripherals/lcd/tjpgd/main/pretty_effect.h index f4fbe70fbe..6ed8bb83fb 100644 --- a/examples/peripherals/lcd/tjpgd/main/pretty_effect.h +++ b/examples/peripherals/lcd/tjpgd/main/pretty_effect.h @@ -1,10 +1,8 @@ /* - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ #pragma once #include diff --git a/pytest.ini b/pytest.ini index 7386f2fba8..7e3c8ac276 100644 --- a/pytest.ini +++ b/pytest.ini @@ -22,6 +22,7 @@ markers = flash_suspend: support flash suspend feature ip101: connected via wired 10/100M ethernet lan8720: connected via LAN8720 ethernet transceiver + octal_psram: runners with octal psram # log related log_cli = True diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index 27545daf26..e95d15a877 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -485,17 +485,6 @@ components/esp_hid/test/test_esp_hid.c components/esp_hw_support/include/esp_clk.h components/esp_hw_support/include/soc/esp_himem.h components/esp_hw_support/include/soc/esp_spiram.h -components/esp_ipc/include/esp_ipc.h -components/esp_ipc/test/test_ipc.c -components/esp_ipc/test/test_ipc_isr.c -components/esp_lcd/test/test_i2c_lcd_panel.c -components/esp_lcd/test/test_i80_board.h -components/esp_lcd/test/test_i80_lcd_panel.c -components/esp_lcd/test/test_lvgl_port.h -components/esp_lcd/test/test_lvgl_port_v7.c -components/esp_lcd/test/test_rgb_panel.c -components/esp_lcd/test/test_spi_board.h -components/esp_lcd/test/test_spi_lcd_panel.c components/esp_local_ctrl/include/esp_local_ctrl.h components/esp_local_ctrl/proto-c/esp_local_ctrl.pb-c.c components/esp_local_ctrl/proto-c/esp_local_ctrl.pb-c.h @@ -2301,11 +2290,6 @@ examples/peripherals/i2s/i2s_adc_dac/main/audio_example_file.h examples/peripherals/i2s/i2s_adc_dac/tools/generate_audio_file.py examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/i2s_recorder_main.c examples/peripherals/i2s/i2s_basic/main/i2s_example_main.c -examples/peripherals/lcd/tjpgd/main/decode_image.c -examples/peripherals/lcd/tjpgd/main/decode_image.h -examples/peripherals/lcd/tjpgd/main/lcd_tjpgd_example_main.c -examples/peripherals/lcd/tjpgd/main/pretty_effect.c -examples/peripherals/lcd/tjpgd/main/pretty_effect.h examples/peripherals/ledc/ledc_basic/main/ledc_basic_example_main.c examples/peripherals/ledc/ledc_fade/main/ledc_fade_example_main.c examples/peripherals/mcpwm/mcpwm_bldc_hall_control/main/mcpwm_bldc_hall_control_example_main.c