Merge branch 'feature/lcd_isr_in_iram' into 'master'

refactor LCD unit tests into test apps

Closes IDF-4666

See merge request espressif/esp-idf!14980
This commit is contained in:
morris
2022-02-25 08:21:15 +00:00
64 changed files with 732 additions and 399 deletions

View File

@@ -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

View File

@@ -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
*/

View File

@@ -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 <stddef.h>
#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

View File

@@ -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 *));

View File

@@ -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;

View File

@@ -1,3 +0,0 @@
idf_component_register(SRC_DIRS .
PRIV_INCLUDE_DIRS .
PRIV_REQUIRES cmock test_utils esp_lcd)

View File

@@ -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);

View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View File

@@ -0,0 +1 @@
This test app is used to test LCDs with I2C interface.

View File

@@ -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")

View File

@@ -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();
}

View File

@@ -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

View File

@@ -1,24 +1,24 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <string.h>
#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,

View File

@@ -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()

View File

@@ -0,0 +1,3 @@
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y

View File

@@ -0,0 +1,2 @@
CONFIG_FREERTOS_HZ=1000
CONFIG_ESP_TASK_WDT=n

View File

@@ -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)

View File

@@ -0,0 +1,4 @@
| Supported Targets | ESP32 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- |
This test app is used to test LCDs with intel 8080 interface.

View File

@@ -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")

View File

@@ -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();
}

View File

@@ -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

View File

@@ -1,7 +1,14 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/
#include <stdio.h>
#include <string.h>
#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

View File

@@ -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()

View File

@@ -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

View File

@@ -0,0 +1,2 @@
CONFIG_FREERTOS_HZ=1000
CONFIG_ESP_TASK_WDT=n

View File

@@ -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)

View File

@@ -0,0 +1,4 @@
| Supported Targets | ESP32-S3 |
| ----------------- | -------- |
This test app is used to test RGB565 interfaced LCDs.

View File

@@ -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")

View File

@@ -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();
}

View File

@@ -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

View File

@@ -1,40 +1,21 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <string.h>
#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

View File

@@ -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()

View File

@@ -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

View File

@@ -0,0 +1,2 @@
CONFIG_FREERTOS_HZ=1000
CONFIG_ESP_TASK_WDT=n

View File

@@ -0,0 +1,3 @@
CONFIG_ESP32S3_SPIRAM_SUPPORT=y
CONFIG_SPIRAM_MODE_OCT=y
CONFIG_SPIRAM_SPEED_80M=y

View File

@@ -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)

View File

@@ -0,0 +1 @@
This test app is used to test LCDs with SPI interface.

View File

@@ -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")

View File

@@ -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();
}

View File

@@ -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

View File

@@ -1,8 +1,12 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <string.h>
#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

View File

@@ -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()

View File

@@ -0,0 +1,3 @@
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y

View File

@@ -0,0 +1,2 @@
CONFIG_FREERTOS_HZ=1000
CONFIG_ESP_TASK_WDT=n

View File

@@ -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")

View File

@@ -1,3 +1,3 @@
dependencies:
idf: ">=4.4"
lvgl/lvgl: "~8.0.2"
lvgl/lvgl: "~8.2.0"

View File

@@ -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")

View File

@@ -1,3 +1,3 @@
dependencies:
idf: ">=4.4"
lvgl/lvgl: "~8.0.2"
lvgl/lvgl: "~8.2.0"

View File

@@ -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")

View File

@@ -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 <target-name>` 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.

View File

@@ -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

View File

@@ -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);

View File

@@ -1,3 +1,3 @@
dependencies:
idf: ">=4.4"
lvgl/lvgl: "~8.0.2"
lvgl/lvgl: "~8.2.0"

View File

@@ -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")

View File

@@ -1,3 +1,3 @@
dependencies:
idf: ">=4.4"
lvgl/lvgl: "~8.0.2"
lvgl/lvgl: "~8.2.0"

View File

@@ -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

View File

@@ -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 <stdint.h>

View File

@@ -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 <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

View File

@@ -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 <math.h>
#include "pretty_effect.h"

View File

@@ -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 <stdint.h>

View File

@@ -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

View File

@@ -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