From 3578a9e646ab1803ca49662f938b5cfdf09e09dd Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Wed, 10 Jan 2024 18:11:49 +0900 Subject: [PATCH] tests: drivers: display: add read() and write() test Add test for `display_read()` and `display_write()` api. Note: The CI environment has no display device, which makes it fail the tests. So, I make this test case `build_only`. But it can run in a display device available environment. Signed-off-by: TOKITA Hiroshi --- .../display/display_read_write/CMakeLists.txt | 9 + .../display/display_read_write/prj.conf | 9 + .../display/display_read_write/src/main.c | 268 ++++++++++++++++++ .../display/display_read_write/testcase.yaml | 52 ++++ 4 files changed, 338 insertions(+) create mode 100644 tests/drivers/display/display_read_write/CMakeLists.txt create mode 100644 tests/drivers/display/display_read_write/prj.conf create mode 100644 tests/drivers/display/display_read_write/src/main.c create mode 100644 tests/drivers/display/display_read_write/testcase.yaml diff --git a/tests/drivers/display/display_read_write/CMakeLists.txt b/tests/drivers/display/display_read_write/CMakeLists.txt new file mode 100644 index 0000000000..3c88f23c18 --- /dev/null +++ b/tests/drivers/display/display_read_write/CMakeLists.txt @@ -0,0 +1,9 @@ +# Copyright 2024 (c) TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) + +project(display_read_write) + +target_sources(app PRIVATE src/main.c) diff --git a/tests/drivers/display/display_read_write/prj.conf b/tests/drivers/display/display_read_write/prj.conf new file mode 100644 index 0000000000..c18b5f93da --- /dev/null +++ b/tests/drivers/display/display_read_write/prj.conf @@ -0,0 +1,9 @@ +# Copyright 2024 (c) TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ZTEST=y +CONFIG_DISPLAY=y + +CONFIG_HEAP_MEM_POOL_SIZE=16384 + +CONFIG_LOG=y diff --git a/tests/drivers/display/display_read_write/src/main.c b/tests/drivers/display/display_read_write/src/main.c new file mode 100644 index 0000000000..2ae246e4fb --- /dev/null +++ b/tests/drivers/display/display_read_write/src/main.c @@ -0,0 +1,268 @@ +/* + * Copyright 2024 (c) TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +LOG_MODULE_DECLARE(display_api, CONFIG_DISPLAY_LOG_LEVEL); + +static const struct device *dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display)); +static const uint32_t display_width = DT_PROP(DT_CHOSEN(zephyr_display), width); +static const uint32_t display_height = DT_PROP(DT_CHOSEN(zephyr_display), height); +static uint8_t disp_buffer[DT_PROP(DT_CHOSEN(zephyr_display), width) * + DT_PROP(DT_CHOSEN(zephyr_display), height) * 4]; +static struct display_capabilities cfg; +static uint8_t bpp; +static bool is_tiled; + +static inline uint8_t bytes_per_pixel(enum display_pixel_format pixel_format) +{ + switch (pixel_format) { + case PIXEL_FORMAT_ARGB_8888: + return 4; + case PIXEL_FORMAT_RGB_888: + return 3; + case PIXEL_FORMAT_RGB_565: + case PIXEL_FORMAT_BGR_565: + return 2; + case PIXEL_FORMAT_MONO01: + case PIXEL_FORMAT_MONO10: + default: + return 1; + } + + return 0; +} + +static void verify_bytes_of_area(uint8_t *data, int cmp_x, int cmp_y, size_t width, size_t height) +{ + struct display_buffer_descriptor desc = { + .height = height, + .pitch = width, + .width = width, + .buf_size = height * width * bpp, + }; + + int err = display_read(dev, cmp_x, cmp_y, &desc, disp_buffer); + + zassert_ok(err, "display_read failed"); + + if (is_tiled) { + zassert_mem_equal(data, disp_buffer, width * height / 8, NULL); + } else { + zassert_mem_equal(data, disp_buffer, width * height * bpp, NULL); + } +} + +static void verify_background_color(int x, int y, size_t width, size_t height, uint32_t color) +{ + size_t buf_size = is_tiled ? (height * width / 8) : (height * width * bpp); + struct display_buffer_descriptor desc = { + .height = height, + .pitch = width, + .width = width, + .buf_size = buf_size, + }; + uint32_t *buf32 = (void *)disp_buffer; + uint16_t *buf16 = (void *)disp_buffer; + uint8_t *buf8 = disp_buffer; + int err; + + err = display_read(dev, x, y, &desc, disp_buffer); + zassert_ok(err, "display_read failed"); + + for (size_t i = 0; i < width * height; i++) { + switch (bpp) { + case 4: + zassert_equal(buf32[i], color, "@%d", i); + break; + case 2: + zassert_equal(buf16[i], (uint16_t)color, "@%d", i); + break; + case 1: + if (is_tiled) { + uint16_t x = i % (width); + uint16_t line = (i - x) / width; + uint16_t tile = line / 8; + uint16_t y = line % 8; + + uint8_t *tptr = disp_buffer + (tile * width + x); + + zassert_equal(!!(*tptr & BIT(y)), !!(color), "@%d", i); + } else { + zassert_equal(buf8[i], (uint8_t)color, "@%d", i); + } + break; + } + } +} + +/** + * Fill the buffer with 0 before running tests. + */ +static void display_before(void *text_fixture) +{ + display_get_capabilities(dev, &cfg); + bpp = bytes_per_pixel(cfg.current_pixel_format); + is_tiled = ((bpp == 1) && (cfg.screen_info & SCREEN_INFO_MONO_VTILED)); + + struct display_buffer_descriptor desc = { + .height = display_height, + .pitch = display_width, + .width = display_width, + .buf_size = display_height * display_width * bpp, + }; + + memset(disp_buffer, 0, sizeof(disp_buffer)); + display_write(dev, 0, 0, &desc, disp_buffer); +} + +/* + * Verify that we can get a color of '0' from all pixels + * when after zeroing the buffer. + */ +ZTEST(display_read_write, test_clear) +{ + verify_background_color(0, 0, display_width, display_height, 0); +} + +/* + * Write to the head of the buffer and check that + * the same value can be read. + */ +ZTEST(display_read_write, test_write_to_buffer_head) +{ + uint8_t data[4] = {0xFA, 0xAF, 0x9F, 0xFA}; + uint8_t height = (is_tiled ? 8 : 1); + uint16_t width = sizeof(data) / bpp; + uint16_t buf_size = width * bpp; + struct display_buffer_descriptor desc = { + .height = height, + .pitch = width, + .width = width, + .buf_size = buf_size, + }; + + /* write data to head of buffer */ + display_write(dev, 0, 0, &desc, data); + + /* check write data and read data are same */ + verify_bytes_of_area(data, 0, 0, width, height); + + /* check remaining region still black */ + verify_background_color(0, height, display_width, display_height - height, 0); + verify_background_color(width, 0, display_width - width, display_height, 0); +} + +/* + * Write to the tail of the buffer and check that + * the same value can be read. + */ +ZTEST(display_read_write, test_write_to_buffer_tail) +{ + uint8_t data[4] = {0xFA, 0xAF, 0x9F, 0xFA}; + uint16_t height = (is_tiled ? 8 : 1); + uint16_t width = sizeof(data) / bpp; + uint16_t buf_size = width * bpp; + struct display_buffer_descriptor desc = { + .height = height, + .pitch = width, + .width = width, + .buf_size = buf_size, + }; + struct display_buffer_descriptor desc_whole = { + .height = display_height, + .pitch = display_width, + .width = display_width, + .buf_size = display_height * display_width * bpp / height, + }; + int err; + + /* write data to tail of buffer */ + display_write(dev, display_width - width, display_height - height, &desc, data); + + /* read entire displayed data */ + err = display_read(dev, 0, 0, &desc_whole, disp_buffer); + zassert_ok(err, "display_read failed"); + + /* check write data and read data are same */ + if (is_tiled) { + zassert_mem_equal(data, + disp_buffer + (display_width * display_height / 8 - buf_size), + buf_size, NULL); + } else { + zassert_mem_equal(data, + disp_buffer + (display_width * display_height * bpp - buf_size), + buf_size, NULL); + } + + /* check remaining region still black */ + verify_background_color(0, 0, display_width, display_height - height, 0); + verify_background_color(0, display_height - height, display_width - width, height, 0); +} + +/* + * Verify that it will keep the drawn content even if display_read is executed + */ +ZTEST(display_read_write, test_read_does_not_clear_existing_buffer) +{ + uint8_t data[4] = {0xFA, 0xAF, 0x9F, 0xFA}; + uint8_t height = (is_tiled ? 8 : 1); + uint16_t width = sizeof(data) / bpp; + uint16_t buf_size = width * bpp; + struct display_buffer_descriptor desc = { + .height = height, + .pitch = width, + .width = width, + .buf_size = buf_size, + }; + struct display_buffer_descriptor desc_whole = { + .height = display_height, + .pitch = display_width, + .width = display_width, + .buf_size = display_height * display_width * bpp / height, + }; + int err; + + /* write data to head of buffer */ + display_write(dev, 0, 0, &desc, data); + + /* check write data and read data are same */ + verify_bytes_of_area(data, 0, 0, width, height); + + /* check remaining region still black */ + verify_background_color(0, height, display_width, display_height - height, 0); + verify_background_color(width, 0, display_width - width, display_height, 0); + + /* write data to tail of buffer */ + display_write(dev, display_width - width, display_height - height, &desc, data); + + /* read entire displayed data */ + err = display_read(dev, 0, 0, &desc_whole, disp_buffer); + zassert_ok(err, "display_read failed"); + + /* checking correctly write to the tail of buffer */ + if (is_tiled) { + zassert_mem_equal(data, + disp_buffer + (display_width * display_height / 8 - buf_size), + buf_size, NULL); + } else { + zassert_mem_equal(data, + disp_buffer + (display_width * display_height * bpp - buf_size), + buf_size, NULL); + } + + /* checking if the content written before reading is kept */ + verify_bytes_of_area(data, 0, 0, width, height); + + /* checking remaining region is still black */ + verify_background_color(width, 0, display_width - width, display_height - height, 0); + verify_background_color(0, height, display_width - width, display_height - height, 0); +} + +ZTEST_SUITE(display_read_write, NULL, NULL, display_before, NULL, NULL); diff --git a/tests/drivers/display/display_read_write/testcase.yaml b/tests/drivers/display/display_read_write/testcase.yaml new file mode 100644 index 0000000000..e991a022d4 --- /dev/null +++ b/tests/drivers/display/display_read_write/testcase.yaml @@ -0,0 +1,52 @@ +# Copyright 2024 (c) TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +common: + tags: + - drivers + - display + filter: dt_chosen_enabled("zephyr,display") + build_only: true # The CI environment has no display device +tests: + drivers.display.read_write.sdl.argb8888: + filter: dt_compat_enabled("zephyr,sdl-dc") + extra_configs: + - CONFIG_SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_ARGB_8888=y + - CONFIG_SDL_DISPLAY_USE_HARDWARE_ACCELERATOR=n + drivers.display.read_write.sdl.rgb888: + filter: dt_compat_enabled("zephyr,sdl-dc") + extra_configs: + - CONFIG_SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_RGB_888=y + - CONFIG_SDL_DISPLAY_USE_HARDWARE_ACCELERATOR=n + drivers.display.read_write.sdl.mono01: + filter: dt_compat_enabled("zephyr,sdl-dc") + extra_configs: + - CONFIG_SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_MONO01=y + - CONFIG_SDL_DISPLAY_USE_HARDWARE_ACCELERATOR=n + drivers.display.read_write.sdl.mono10: + filter: dt_compat_enabled("zephyr,sdl-dc") + extra_configs: + - CONFIG_SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_MONO10=y + - CONFIG_SDL_DISPLAY_USE_HARDWARE_ACCELERATOR=n + drivers.display.read_write.sdl.mono01.lsbfirst: + filter: dt_compat_enabled("zephyr,sdl-dc") + extra_configs: + - CONFIG_SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_MONO01=y + - CONFIG_SDL_DISPLAY_USE_HARDWARE_ACCELERATOR=n + - CONFIG_SDL_DISPLAY_MONO_MSB_FIRST=n + drivers.display.read_write.sdl.mono10.lsbfirst: + filter: dt_compat_enabled("zephyr,sdl-dc") + extra_configs: + - CONFIG_SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_MONO10=y + - CONFIG_SDL_DISPLAY_USE_HARDWARE_ACCELERATOR=n + - CONFIG_SDL_DISPLAY_MONO_MSB_FIRST=n + drivers.display.read_write.sdl.rgb565: + filter: dt_compat_enabled("zephyr,sdl-dc") + extra_configs: + - CONFIG_SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_RGB_565=y + - CONFIG_SDL_DISPLAY_USE_HARDWARE_ACCELERATOR=n + drivers.display.read_write.sdl.bgr565: + filter: dt_compat_enabled("zephyr,sdl-dc") + extra_configs: + - CONFIG_SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_BGR_565=y + - CONFIG_SDL_DISPLAY_USE_HARDWARE_ACCELERATOR=n