Skip to content

Commit af6f1e0

Browse files
committed
feat(test_apps): add lcd mip_dsi
1 parent af89b71 commit af6f1e0

File tree

7 files changed

+328
-0
lines changed

7 files changed

+328
-0
lines changed

test_apps/lcd/mipi_dsi/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# The following lines of boilerplate have to be in your project's CMakeLists
2+
# in this exact order for cmake to work correctly
3+
cmake_minimum_required(VERSION 3.5)
4+
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
5+
project(mipi_dsi_lcd_test)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
idf_component_register(
2+
SRCS "test_app_main.c" "test_mipi_dsi_lcd.cpp"
3+
PRIV_REQUIRES esp_lcd driver esp_timer
4+
WHOLE_ARCHIVE
5+
)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
## IDF Component Manager Manifest File
2+
dependencies:
3+
test_utils:
4+
path: ${IDF_PATH}/tools/unit-test-app/components/test_utils
5+
test_driver_utils:
6+
path: ${IDF_PATH}/components/driver/test_apps/components/test_driver_utils
7+
ESP32_Display_Panel:
8+
version: "*"
9+
override_path: "../../../../../ESP32_Display_Panel"
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: CC0-1.0
5+
*/
6+
#include <inttypes.h>
7+
#include "freertos/FreeRTOS.h"
8+
#include "freertos/task.h"
9+
#include "esp_heap_caps.h"
10+
#include "unity.h"
11+
#include "unity_test_runner.h"
12+
13+
// Some resources are lazy allocated in the LCD driver, the threadhold is left for that case
14+
#define TEST_MEMORY_LEAK_THRESHOLD (-300)
15+
16+
static size_t before_free_8bit;
17+
static size_t before_free_32bit;
18+
19+
static void check_leak(size_t before_free, size_t after_free, const char *type)
20+
{
21+
ssize_t delta = after_free - before_free;
22+
printf("MALLOC_CAP_%s: Before %u bytes free, After %u bytes free (delta %d)\n", type, before_free, after_free, delta);
23+
TEST_ASSERT_MESSAGE(delta >= TEST_MEMORY_LEAK_THRESHOLD, "memory leak");
24+
}
25+
26+
void setUp(void)
27+
{
28+
before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
29+
before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
30+
}
31+
32+
void tearDown(void)
33+
{
34+
size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
35+
size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
36+
check_leak(before_free_8bit, after_free_8bit, "8BIT");
37+
check_leak(before_free_32bit, after_free_32bit, "32BIT");
38+
}
39+
40+
void app_main(void)
41+
{
42+
/**
43+
* __ __ ______ _______ ______ _______ ______ ______ __ ______ _______
44+
* | \ / \| \| \| \ | \ / \ | \ | \ / \ | \
45+
* | $$\ / $$ \$$$$$$| $$$$$$$\\$$$$$$ | $$$$$$$\| $$$$$$\ \$$$$$$ | $$ | $$$$$$\| $$$$$$$\
46+
* | $$$\ / $$$ | $$ | $$__/ $$ | $$ ______ | $$ | $$| $$___\$$ | $$ | $$ | $$ \$$| $$ | $$
47+
* | $$$$\ $$$$ | $$ | $$ $$ | $$| \| $$ | $$ \$$ \ | $$ | $$ | $$ | $$ | $$
48+
* | $$\$$ $$ $$ | $$ | $$$$$$$ | $$ \$$$$$$| $$ | $$ _\$$$$$$\ | $$ | $$ | $$ __ | $$ | $$
49+
* | $$ \$$$| $$ _| $$_ | $$ _| $$_ | $$__/ $$| \__| $$ _| $$_ | $$_____| $$__/ \| $$__/ $$
50+
* | $$ \$ | $$| $$ \| $$ | $$ \ | $$ $$ \$$ $$| $$ \ | $$ \\$$ $$| $$ $$
51+
* \$$ \$$ \$$$$$$ \$$ \$$$$$$ \$$$$$$$ \$$$$$$ \$$$$$$ \$$$$$$$$ \$$$$$$ \$$$$$$$
52+
*/
53+
printf(" __ __ ______ _______ ______ _______ ______ ______ __ ______ _______\r\n");
54+
printf("| \\ / \\| \\| \\| \\ | \\ / \\ | \\ | \\ / \\ | \\\r\n");
55+
printf("| $$\\ / $$ \\$$$$$$| $$$$$$$\\\\$$$$$$ | $$$$$$$\\| $$$$$$\\ \\$$$$$$ | $$ | $$$$$$\\| $$$$$$$\\\r\n");
56+
printf("| $$$\\ / $$$ | $$ | $$__/ $$ | $$ ______ | $$ | $$| $$___\\$$ | $$ | $$ | $$ \\$$| $$ | $$\r\n");
57+
printf("| $$$$\\ $$$$ | $$ | $$ $$ | $$| \\| $$ | $$ \\$$ \\ | $$ | $$ | $$ | $$ | $$\r\n");
58+
printf("| $$\\$$ $$ $$ | $$ | $$$$$$$ | $$ \\$$$$$$| $$ | $$ _\\$$$$$$\\ | $$ | $$ | $$ __ | $$ | $$\r\n");
59+
printf("| $$ \\$$$| $$ _| $$_ | $$ _| $$_ | $$__/ $$| \\__| $$ _| $$_ | $$_____| $$__/ \\| $$__/ $$\r\n");
60+
printf("| $$ \\$ | $$| $$ \\| $$ | $$ \\ | $$ $$ \\$$ $$| $$ \\ | $$ \\\\$$ $$| $$ $$\r\n");
61+
printf(" \\$$ \\$$ \\$$$$$$ \\$$ \\$$$$$$ \\$$$$$$$ \\$$$$$$ \\$$$$$$ \\$$$$$$$$ \\$$$$$$ \\$$$$$$$\r\n");
62+
unity_run_menu();
63+
}
Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: CC0-1.0
5+
*/
6+
#include <memory>
7+
#include "freertos/FreeRTOS.h"
8+
#include "freertos/task.h"
9+
#include "esp_heap_caps.h"
10+
#include "esp_log.h"
11+
#include "esp_timer.h"
12+
#include "unity.h"
13+
#include "unity_test_runner.h"
14+
#include "ESP_Panel_Library.h"
15+
16+
using namespace std;
17+
18+
/* The following default configurations are for the board 'Espressif: ESP32-P4-Function-EV-Board, EK79007' */
19+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
20+
//////////////////// Please update the following configuration according to your LCD spec //////////////////////////////
21+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
22+
#define TEST_LCD_WIDTH (1024)
23+
#define TEST_LCD_HEIGHT (600)
24+
#define TEST_LCD_COLOR_BITS (ESP_PANEL_LCD_RGB888_COLOR_BITS_24)
25+
#define TEST_LCD_DSI_PHY_LDO_ID (3)
26+
#define TEST_LCD_DSI_LANE_NUM (2)
27+
#define TEST_LCD_DSI_LANE_RATE_MBPS (1000)
28+
#define TEST_LCD_DPI_CLK_MHZ (52)
29+
#define TEST_LCD_DPI_COLOR_BITS (ESP_PANEL_LCD_RGB888_COLOR_BITS_24)
30+
#define TEST_LCD_DPI_HPW (10)
31+
#define TEST_LCD_DPI_HBP (160)
32+
#define TEST_LCD_DPI_HFP (160)
33+
#define TEST_LCD_DPI_VPW (1)
34+
#define TEST_LCD_DPI_VBP (23)
35+
#define TEST_LCD_DPI_VFP (12)
36+
#define TEST_LCD_USE_EXTERNAL_CMD (0)
37+
#if TEST_LCD_USE_EXTERNAL_CMD
38+
/**
39+
* LCD initialization commands.
40+
*
41+
* Vendor specific initialization can be different between manufacturers, should consult the LCD supplier for
42+
* initialization sequence code.
43+
*
44+
* Please uncomment and change the following macro definitions, then use `configVendorCommands()` to pass them in the
45+
* same format if needed. Otherwise, the LCD driver will use the default initialization sequence code.
46+
*
47+
* There are two formats for the sequence code:
48+
* 1. Raw data: {command, (uint8_t []){ data0, data1, ... }, data_size, delay_ms}
49+
* 2. Formatter: ESP_PANEL_LCD_CMD_WITH_8BIT_PARAM(delay_ms, command, { data0, data1, ... }) and
50+
* ESP_PANEL_LCD_CMD_WITH_NONE_PARAM(delay_ms, command)
51+
*/
52+
const esp_lcd_panel_vendor_init_cmd_t lcd_init_cmd[] = {
53+
// {0xFF, (uint8_t []){0x77, 0x01, 0x00, 0x00, 0x10}, 5, 0},
54+
// {0xC0, (uint8_t []){0x3B, 0x00}, 2, 0},
55+
// {0xC1, (uint8_t []){0x0D, 0x02}, 2, 0},
56+
// {0x29, (uint8_t []){0x00}, 0, 120},
57+
// // or
58+
ESP_PANEL_LCD_CMD_WITH_8BIT_PARAM(0, 0xFF, {0x77, 0x01, 0x00, 0x00, 0x10}),
59+
ESP_PANEL_LCD_CMD_WITH_8BIT_PARAM(0, 0xC0, {0x3B, 0x00}),
60+
ESP_PANEL_LCD_CMD_WITH_8BIT_PARAM(0, 0xC1, {0x0D, 0x02}),
61+
ESP_PANEL_LCD_CMD_WITH_NONE_PARAM(120, 0x29),
62+
};
63+
#endif
64+
65+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
66+
//////////////////// Please update the following configuration according to your board spec ////////////////////////////
67+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
68+
#define TEST_LCD_PIN_NUM_RST (27) // Set to -1 if not used
69+
#define TEST_LCD_PIN_NUM_BK_LIGHT (26) // Set to -1 if not used
70+
#define TEST_LCD_BK_LIGHT_ON_LEVEL (1)
71+
#define TEST_LCD_BK_LIGHT_OFF_LEVEL !TEST_LCD_BK_LIGHT_ON_LEVEL
72+
73+
/* Enable or disable pattern test */
74+
#define TEST_ENABLE_PATTERN_TEST (1)
75+
/* Enable or disable printing LCD refresh rate */
76+
#define TEST_ENABLE_PRINT_LCD_FPS (1)
77+
#define TEST_PRINT_LCD_FPS_PERIOD_MS (1000)
78+
/* Enable or disable the attachment of a callback function that is called after each bitmap drawing is completed */
79+
#define TEST_ENABLE_ATTACH_CALLBACK (1)
80+
#define TEST_COLOR_BAR_SHOW_TIME_MS (5000)
81+
82+
#define delay(ms) vTaskDelay(pdMS_TO_TICKS(ms))
83+
84+
static const char *TAG = "test_spi_lcd";
85+
86+
static shared_ptr<ESP_PanelBacklight> init_backlight(void)
87+
{
88+
#if TEST_LCD_PIN_NUM_BK_LIGHT >= 0
89+
ESP_LOGI(TAG, "Initialize backlight control pin and turn it on");
90+
shared_ptr<ESP_PanelBacklight> backlight = make_shared<ESP_PanelBacklight>(
91+
TEST_LCD_PIN_NUM_BK_LIGHT, TEST_LCD_BK_LIGHT_ON_LEVEL, true
92+
);
93+
TEST_ASSERT_NOT_NULL_MESSAGE(backlight, "Create backlight object failed");
94+
95+
TEST_ASSERT_TRUE_MESSAGE(backlight->begin(), "Backlight begin failed");
96+
TEST_ASSERT_TRUE_MESSAGE(backlight->on(), "Backlight on failed");
97+
98+
return backlight;
99+
#else
100+
return nullptr;
101+
#endif
102+
}
103+
104+
static shared_ptr<ESP_PanelBus_DSI> init_panel_bus(void)
105+
{
106+
ESP_LOGI(TAG, "Create LCD bus");
107+
shared_ptr<ESP_PanelBus_DSI> panel_bus = make_shared<ESP_PanelBus_DSI>(
108+
TEST_LCD_DSI_LANE_NUM, TEST_LCD_DSI_LANE_RATE_MBPS,
109+
TEST_LCD_DPI_CLK_MHZ, TEST_LCD_DPI_COLOR_BITS, TEST_LCD_WIDTH, TEST_LCD_HEIGHT,
110+
TEST_LCD_DPI_HPW, TEST_LCD_DPI_HBP, TEST_LCD_DPI_HFP,
111+
TEST_LCD_DPI_VPW, TEST_LCD_DPI_VBP, TEST_LCD_DPI_VFP,
112+
TEST_LCD_DSI_PHY_LDO_ID
113+
);
114+
TEST_ASSERT_NOT_NULL_MESSAGE(panel_bus, "Create panel bus object failed");
115+
116+
TEST_ASSERT_TRUE_MESSAGE(panel_bus->begin(), "Panel bus begin failed");
117+
118+
return panel_bus;
119+
}
120+
121+
#if TEST_ENABLE_ATTACH_CALLBACK
122+
IRAM_ATTR static bool onDrawBitmapFinishCallback(void *user_data)
123+
{
124+
esp_rom_printf("Draw bitmap finish callback\n");
125+
126+
return false;
127+
}
128+
#endif
129+
130+
#if TEST_ENABLE_PRINT_LCD_FPS
131+
#define TEST_LCD_FPS_COUNT_MAX (100)
132+
#ifndef millis
133+
#define millis() (esp_timer_get_time() / 1000)
134+
#endif
135+
136+
DRAM_ATTR int frame_count = 0;
137+
DRAM_ATTR int fps = 0;
138+
DRAM_ATTR long start_time = 0;
139+
140+
IRAM_ATTR bool onVsyncEndCallback(void *user_data)
141+
{
142+
long frame_start_time = *(long *)user_data;
143+
if (frame_start_time == 0) {
144+
(*(long *)user_data) = millis();
145+
146+
return false;
147+
}
148+
149+
frame_count++;
150+
if (frame_count >= TEST_LCD_FPS_COUNT_MAX) {
151+
fps = TEST_LCD_FPS_COUNT_MAX * 1000 / (millis() - frame_start_time);
152+
frame_count = 0;
153+
(*(long *)user_data) = millis();
154+
}
155+
156+
return false;
157+
}
158+
#endif
159+
160+
static void run_test(shared_ptr<ESP_PanelLcd> lcd)
161+
{
162+
frame_count = 0;
163+
fps = 0;
164+
start_time = 0;
165+
166+
#if TEST_LCD_USE_EXTERNAL_CMD
167+
// Configure external initialization commands, should called before `init()`
168+
lcd->configVendorCommands(lcd_init_cmd, sizeof(lcd_init_cmd) / sizeof(lcd_init_cmd[0]));
169+
#endif
170+
TEST_ASSERT_TRUE_MESSAGE(lcd->init(), "LCD init failed");
171+
TEST_ASSERT_TRUE_MESSAGE(lcd->reset(), "LCD reset failed");
172+
TEST_ASSERT_TRUE_MESSAGE(lcd->begin(), "LCD begin failed");
173+
TEST_ASSERT_TRUE_MESSAGE(lcd->displayOn(), "LCD display on failed");
174+
175+
#if TEST_ENABLE_PATTERN_TEST
176+
ESP_LOGI(TAG, "Show MIPI-DSI patterns");
177+
TEST_ASSERT_TRUE_MESSAGE(
178+
lcd->showDsiPattern(ESP_PanelLcd::DsiPatternType::BAR_HORIZONTAL), "MIPI DPI bar horizontal pattern test failed"
179+
);
180+
delay(1000);
181+
TEST_ASSERT_TRUE_MESSAGE(
182+
lcd->showDsiPattern(ESP_PanelLcd::DsiPatternType::BAR_VERTICAL), "MIPI DPI bar vertical pattern test failed"
183+
);
184+
delay(1000);
185+
TEST_ASSERT_TRUE_MESSAGE(
186+
lcd->showDsiPattern(ESP_PanelLcd::DsiPatternType::BER_VERTICAL), "MIPI DPI ber vertical pattern test failed"
187+
);
188+
delay(1000);
189+
TEST_ASSERT_TRUE_MESSAGE(
190+
lcd->showDsiPattern(ESP_PanelLcd::DsiPatternType::NONE), "MIPI DPI none pattern test failed"
191+
);
192+
#endif
193+
#if TEST_ENABLE_ATTACH_CALLBACK
194+
TEST_ASSERT_TRUE_MESSAGE(
195+
lcd->attachDrawBitmapFinishCallback(onDrawBitmapFinishCallback, nullptr), "Attach callback failed"
196+
);
197+
#endif
198+
#if TEST_ENABLE_PRINT_LCD_FPS
199+
TEST_ASSERT_TRUE_MESSAGE(
200+
lcd->attachRefreshFinishCallback(onVsyncEndCallback, (void *)&start_time), "Attach refresh callback failed"
201+
);
202+
#endif
203+
204+
ESP_LOGI(TAG, "Draw color bar from top left to bottom right, the order is B - G - R");
205+
TEST_ASSERT_TRUE_MESSAGE(lcd->colorBarTest(TEST_LCD_WIDTH, TEST_LCD_HEIGHT), "LCD color bar test failed");
206+
207+
ESP_LOGI(TAG, "Wait for %d ms to show the color bar", TEST_COLOR_BAR_SHOW_TIME_MS);
208+
#if TEST_ENABLE_PRINT_LCD_FPS
209+
int i = 0;
210+
while (i++ < TEST_COLOR_BAR_SHOW_TIME_MS / TEST_PRINT_LCD_FPS_PERIOD_MS) {
211+
ESP_LOGI(TAG, "FPS: %d", fps);
212+
vTaskDelay(pdMS_TO_TICKS(TEST_PRINT_LCD_FPS_PERIOD_MS));
213+
}
214+
#else
215+
vTaskDelay(pdMS_TO_TICKS(TEST_COLOR_BAR_SHOW_TIME_MS));
216+
#endif
217+
}
218+
219+
#define CREATE_LCD(name, panel_bus) \
220+
({ \
221+
ESP_LOGI(TAG, "Create LCD device: " #name); \
222+
shared_ptr<ESP_PanelLcd> lcd = make_shared<ESP_PanelLcd_##name>(panel_bus, TEST_LCD_COLOR_BITS, TEST_LCD_PIN_NUM_RST); \
223+
TEST_ASSERT_NOT_NULL_MESSAGE(lcd, "Create LCD object failed"); \
224+
lcd; \
225+
})
226+
#define CREATE_TEST_CASE(name) \
227+
TEST_CASE("Test LCD (" #name ") to draw color bar", "[spi_lcd][" #name "]") \
228+
{ \
229+
shared_ptr<ESP_PanelBacklight> backlight = init_backlight(); \
230+
shared_ptr<ESP_PanelBus_DSI> panel_bus = init_panel_bus(); \
231+
shared_ptr<ESP_PanelLcd> lcd = CREATE_LCD(name, panel_bus.get()); \
232+
run_test(lcd); \
233+
}
234+
235+
/**
236+
* Here to create test cases for different LCDs
237+
*
238+
*/
239+
CREATE_TEST_CASE(EK79007)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
CONFIG_ESP_TASK_WDT_INIT=n
2+
CONFIG_FREERTOS_HZ=1000
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
CONFIG_SPIRAM=y
2+
CONFIG_SPIRAM_MODE_HEX=y
3+
CONFIG_SPIRAM_SPEED_200M=y
4+
CONFIG_SPIRAM_XIP_FROM_PSRAM=y
5+
CONFIG_IDF_EXPERIMENTAL_FEATURES=y

0 commit comments

Comments
 (0)