1 /*
2  * Copyright (c) 2019 Jan Van Winkel <jan.van_winkel@dxplore.eu>
3  * Copyright (c) 2024 STMicroelectronics
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include "img.h"
9 
10 #include <zephyr/kernel.h>
11 #include <zephyr/device.h>
12 #include <zephyr/drivers/display.h>
13 #include <zephyr/fs/fs.h>
14 #include <zephyr/fs/littlefs.h>
15 #include <zephyr/ztest.h>
16 #include <lvgl_zephyr.h>
17 
18 #include <lvgl.h>
19 
20 #ifdef CONFIG_FS_LITTLEFS_BLK_DEV
21 
22 #ifdef CONFIG_DISK_DRIVER_SDMMC
23 #define DISK_NAME "SD"
24 #elif defined(CONFIG_DISK_DRIVER_MMC)
25 #define DISK_NAME "SD2"
26 #else
27 #error "No disk device defined, is your board supported?"
28 #endif /* CONFIG_DISK_DRIVER_SDMMC */
29 
30 #define IMG_FILE_PATH "/"DISK_NAME":/img.bin"
31 
32 struct fs_littlefs lfsfs;
33 
34 static struct fs_mount_t mnt = {
35 	.type = FS_LITTLEFS,
36 	.fs_data = &lfsfs,
37 	.storage_dev = (void *)DISK_NAME,
38 	.mnt_point = "/"DISK_NAME":",
39 	.flags = FS_MOUNT_FLAG_USE_DISK_ACCESS,
40 };
41 
42 #else /* CONFIG_FS_LITTLEFS_BLK_DEV */
43 
44 #define IMG_FILE_PATH "/mnt/img.bin"
45 
46 #define LVGL_PARTITION		storage_partition
47 #define LVGL_PARTITION_ID	FIXED_PARTITION_ID(LVGL_PARTITION)
48 
49 FS_LITTLEFS_DECLARE_DEFAULT_CONFIG(cstorage);
50 
51 static struct fs_mount_t mnt = {
52 	.type = FS_LITTLEFS,
53 	.fs_data = &cstorage,
54 	.storage_dev = (void *)LVGL_PARTITION_ID,
55 	.mnt_point = "/mnt"
56 };
57 #endif /* CONFIG_FS_LITTLEFS_BLK_DEV */
58 
59 static const struct device *display_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display));
60 
ZTEST(lvgl_screen,test_get_default_screen)61 ZTEST(lvgl_screen, test_get_default_screen)
62 {
63 	zassert_not_null(lv_scr_act(), "No default screen");
64 }
65 
ZTEST(lvgl_screen,test_add_delete_screen)66 ZTEST(lvgl_screen, test_add_delete_screen)
67 {
68 	lv_obj_t *default_screen = lv_scr_act();
69 
70 	zassert_not_null(default_screen, "No default screen");
71 
72 	lv_obj_t *new_screen = lv_obj_create(NULL);
73 
74 	zassert_not_null(new_screen, "Failed to create new screen");
75 
76 	lv_scr_load(new_screen);
77 
78 	lv_obj_t *act_screen = lv_scr_act();
79 
80 	zassert_equal_ptr(act_screen, new_screen, "New screen not active");
81 
82 	lv_scr_load(default_screen);
83 
84 	lv_obj_del(new_screen);
85 
86 	act_screen = lv_scr_act();
87 	zassert_equal_ptr(act_screen, default_screen,
88 			"Default screen not active");
89 
90 }
ZTEST_USER(lvgl_fs,test_add_img)91 ZTEST_USER(lvgl_fs, test_add_img)
92 {
93 	lv_obj_t *img = lv_img_create(lv_scr_act());
94 
95 	zassert_not_null(img, "Failed to create image");
96 
97 	lv_img_set_src(img, IMG_FILE_PATH);
98 	lv_obj_align(img, LV_ALIGN_CENTER, 0, 0);
99 }
100 
setup_lvgl(void)101 void *setup_lvgl(void)
102 {
103 	int ret;
104 
105 #if CONFIG_LV_COLOR_DEPTH_1 == 1
106 	display_set_pixel_format(display_dev, PIXEL_FORMAT_MONO10);
107 #elif CONFIG_LV_COLOR_DEPTH_8 == 1
108 	display_set_pixel_format(display_dev, PIXEL_FORMAT_L_8);
109 #elif CONFIG_LV_COLOR_DEPTH_24 == 1
110 	display_set_pixel_format(display_dev, PIXEL_FORMAT_RGB_888);
111 #elif CONFIG_LV_COLOR_DEPTH_16 == 1
112 	display_set_pixel_format(display_dev, PIXEL_FORMAT_RGB_565);
113 #elif CONFIG_LV_COLOR_DEPTH_32 == 1
114 	display_set_pixel_format(display_dev, PIXEL_FORMAT_ARGB_8888);
115 #else
116 #error "No display pixel format defined, is your board supported?"
117 #endif
118 
119 	ret = lvgl_init();
120 	zassert_equal(ret, 0, "Failed to initialize lvgl");
121 
122 	return NULL;
123 }
124 
setup_fs(void)125 void *setup_fs(void)
126 {
127 	struct fs_file_t img;
128 	struct fs_dirent info;
129 	int ret;
130 	const lv_image_dsc_t *c_img = get_lvgl_img();
131 
132 	setup_lvgl();
133 
134 	ret = fs_mount(&mnt);
135 	if (ret < 0) {
136 		TC_PRINT("Failed to mount file system: %d\n", ret);
137 		ztest_test_fail();
138 		return NULL;
139 	}
140 
141 	ret = fs_stat(IMG_FILE_PATH, &info);
142 	if ((ret == 0) && (info.type == FS_DIR_ENTRY_FILE)) {
143 		return NULL;
144 	}
145 
146 	fs_file_t_init(&img);
147 	ret = fs_open(&img, IMG_FILE_PATH, FS_O_CREATE | FS_O_WRITE);
148 	if (ret < 0) {
149 		TC_PRINT("Failed to open image file: %d\n", ret);
150 		ztest_test_fail();
151 		return NULL;
152 	}
153 
154 	ret = fs_write(&img, &c_img->header, sizeof(lv_image_header_t));
155 	if (ret < 0) {
156 		TC_PRINT("Failed to write image file header: %d\n", ret);
157 		ztest_test_fail();
158 		return NULL;
159 	}
160 
161 	ret = fs_write(&img, c_img->data, c_img->data_size);
162 	if (ret < 0) {
163 		TC_PRINT("Failed to write image file data: %d\n", ret);
164 		ztest_test_fail();
165 		return NULL;
166 	}
167 
168 	ret = fs_close(&img);
169 	if (ret < 0) {
170 		TC_PRINT("Failed to close image file: %d\n", ret);
171 		ztest_test_fail();
172 		return NULL;
173 	}
174 	return NULL;
175 }
176 
teardown_lvgl(void * data)177 void teardown_lvgl(void *data)
178 {
179 	lv_deinit();
180 }
181 
182 ZTEST_SUITE(lvgl_screen, NULL, setup_lvgl, NULL, NULL, teardown_lvgl);
183 ZTEST_SUITE(lvgl_fs, NULL, setup_fs, NULL, NULL, teardown_lvgl);
184