This commit is contained in:
01trisha 2026-02-25 17:07:18 +07:00
parent 4e0b3c02fb
commit 53c04ba649
10 changed files with 3411 additions and 22 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@ -36,7 +36,7 @@ else()
endif() endif()
# Main include files of the project # Main include files of the project
include_directories(${PROJECT_SOURCE_DIR}/main/inc) include_directories(${PROJECT_SOURCE_DIR}/src)
# Define options for LVGL with default values (OFF) # Define options for LVGL with default values (OFF)
option(LV_USE_DRAW_SDL "Use SDL draw unit" OFF) option(LV_USE_DRAW_SDL "Use SDL draw unit" OFF)
@ -70,38 +70,25 @@ target_include_directories(lvgl PUBLIC ${PROJECT_SOURCE_DIR} ${SDL2_INCLUDE_DIRS
# Create the main executable, depending on the FreeRTOS option # Create the main executable, depending on the FreeRTOS option
if(USE_FREERTOS) if(USE_FREERTOS)
add_executable(main add_executable(main
${PROJECT_SOURCE_DIR}/main/src/main.c ${PROJECT_SOURCE_DIR}/src/main_sim.c
${PROJECT_SOURCE_DIR}/main/src/freertos_main.cpp ${PROJECT_SOURCE_DIR}/src/freertos_main.cpp
${PROJECT_SOURCE_DIR}/main/src/mouse_cursor_icon.c ${PROJECT_SOURCE_DIR}/src/mouse_cursor_icon.c
${PROJECT_SOURCE_DIR}/main/src/FreeRTOS_Posix_Port.c ${PROJECT_SOURCE_DIR}/src/FreeRTOS_Posix_Port.c
${FREERTOS_SOURCES} # Add only if USE_FREERTOS is enabled ${FREERTOS_SOURCES} # Add only if USE_FREERTOS is enabled
) )
# Link FreeRTOS libraries # Link FreeRTOS libraries
target_link_libraries(main freertos_config FreeRTOS) target_link_libraries(main freertos_config FreeRTOS)
else() else()
add_executable(main add_executable(main
${PROJECT_SOURCE_DIR}/main/src/main.c ${PROJECT_SOURCE_DIR}/src/main_sim.c
${PROJECT_SOURCE_DIR}/main/src/mouse_cursor_icon.c ${PROJECT_SOURCE_DIR}/src/mouse_cursor_icon.c
) )
endif() endif()
# Add sources for custom application # Add sources for custom application
target_sources(main PRIVATE target_sources(main PRIVATE
${PROJECT_SOURCE_DIR}/rec-ui/main.c ${PROJECT_SOURCE_DIR}/src/gui_generated.c
${PROJECT_SOURCE_DIR}/rec-ui/utility_objects.c ${PROJECT_SOURCE_DIR}/assets/montserrat_16_ru_en.c
${PROJECT_SOURCE_DIR}/rec-ui/utility_functions.c
${PROJECT_SOURCE_DIR}/rec-ui/montserrat_16_ru_en.c
${PROJECT_SOURCE_DIR}/rec-ui/montserrat_20_ru_en.c
${PROJECT_SOURCE_DIR}/rec-ui/montserrat_24_ru_en.c
${PROJECT_SOURCE_DIR}/rec-ui/montserrat_28_ru_en.c
${PROJECT_SOURCE_DIR}/rec-ui/montserrat_32_ru_en.c
${PROJECT_SOURCE_DIR}/rec-ui/montserrat_semibold_20_ru_en.c
${PROJECT_SOURCE_DIR}/rec-ui/montserrat_semibold_24_ru_en.c
${PROJECT_SOURCE_DIR}/rec-ui/montserrat_semibold_28_ru_en.c
${PROJECT_SOURCE_DIR}/rec-ui/montserrat_semibold_32_ru_en.c
${PROJECT_SOURCE_DIR}/rec-ui/arrow.c
${PROJECT_SOURCE_DIR}/rec-ui/moon_purple.c
${PROJECT_SOURCE_DIR}/rec-ui/sun_yellow.c
) )
# Define LVGL configuration as a simple include # Define LVGL configuration as a simple include

1188
assets/montserrat_16_ru_en.c Executable file

File diff suppressed because it is too large Load Diff

92
src/FreeRTOS_Posix_Port.c Normal file
View File

@ -0,0 +1,92 @@
/**
* @file Event management with pthreads
* @brief Implementation of an event mechanism using POSIX threads.
* @date 2024-09-03
*/
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
/* Structure representing an event, consisting of a condition variable and a mutex */
typedef struct Event
{
pthread_cond_t cond; /* Condition variable used to signal the event */
pthread_mutex_t mutex; /* Mutex to protect access to the condition variable */
} Event_t;
/**
* @brief Create an event object
*
* Allocates memory for an Event_t structure and initializes its condition variable and mutex.
*
* @param None
* @return Pointer to the created Event_t object, or NULL if memory allocation fails
*/
Event_t *event_create(void)
{
Event_t *event = (Event_t *)malloc(sizeof(Event_t)); /* Allocate memory for the event */
if (event) /* Check if allocation was successful */
{
pthread_cond_init(&event->cond, NULL); /* Initialize the condition variable */
pthread_mutex_init(&event->mutex, NULL); /* Initialize the mutex */
}
return event; /* Return the created event object */
}
// ........................................................................................................
/**
* @brief Delete an event object
*
* Destroys the condition variable and mutex associated with the event, then frees the memory.
*
* @param event Pointer to the Event_t object to be deleted
* @return None
*/
void event_delete(Event_t *event)
{
if (event) /* Check if the event object is valid */
{
pthread_cond_destroy(&event->cond); /* Destroy the condition variable */
pthread_mutex_destroy(&event->mutex); /* Destroy the mutex */
free(event); /* Free the memory allocated for the event object */
}
}
// ........................................................................................................
/**
* @brief Signal an event
*
* Signals the condition variable associated with the event, waking up any waiting threads.
*
* @param event Pointer to the Event_t object to be signaled
* @return None
*/
void event_signal(Event_t *event)
{
if (event) /* Check if the event object is valid */
{
pthread_mutex_lock(&event->mutex); /* Lock the mutex before signaling */
pthread_cond_signal(&event->cond); /* Signal the condition variable */
pthread_mutex_unlock(&event->mutex); /* Unlock the mutex after signaling */
}
}
// ........................................................................................................
/**
* @brief Wait for an event
*
* Waits for the condition variable associated with the event to be signaled.
*
* @param event Pointer to the Event_t object to wait for
* @return None
*/
void event_wait(Event_t *event)
{
if (event) /* Check if the event object is valid */
{
pthread_mutex_lock(&event->mutex); /* Lock the mutex before waiting */
pthread_cond_wait(&event->cond, &event->mutex); /* Wait for the condition variable to be signaled */
pthread_mutex_unlock(&event->mutex); /* Unlock the mutex after waiting */
}
}

179
src/freertos_main.cpp Normal file
View File

@ -0,0 +1,179 @@
/**
* @file Freertos main file
* @author MootSeeker
* @date 2024-09-02
* @brief Main file for FreeRTOS tasks and hooks.
* @license MIT License
*/
#include "lvgl/src/osal/lv_os.h"
#if LV_USE_OS == LV_OS_FREERTOS
#include "lvgl.h"
#include <cstdio> // For printf in C++
// ........................................................................................................
/**
* @brief Malloc failed hook
*
* This function is called when a memory allocation (malloc) fails. It logs the available heap size and enters
* an infinite loop to halt the system.
*
* @param None
* @return None
*/
extern "C" void vApplicationMallocFailedHook(void)
{
printf("Malloc failed! Available heap: %ld bytes\n", xPortGetFreeHeapSize());
for( ;; );
}
// ........................................................................................................
/**
* @brief Idle hook
*
* This function is called when the system is idle. It can be used for low-power mode operations or other
* maintenance tasks that need to run when the CPU is not busy.
*
* @param None
* @return None
*/
extern "C" void vApplicationIdleHook(void) {}
// ........................................................................................................
/**
* @brief Stack overflow hook
*
* This function is called when a stack overflow is detected in a task. It logs the task name and enters
* an infinite loop to halt the system.
*
* @param xTask Handle of the task that caused the stack overflow
* @param pcTaskName Name of the task that caused the stack overflow
* @return None
*/
extern "C" void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName)
{
printf("Stack overflow in task %s\n", pcTaskName);
for(;;);
}
// ........................................................................................................
/**
* @brief Tick hook
*
* This function is called on each tick interrupt. It can be used to execute periodic operations
* that need to occur at a fixed time interval.
*
* @param None
* @return None
*/
extern "C" void vApplicationTickHook(void) {}
// ........................................................................................................
/**
* @brief Create Hello World screen
*
* This function creates a simple LVGL screen with a "Hello, World!" label centered on the screen.
*
* @param None
* @return None
*/
void create_hello_world_screen()
{
/* Create a new screen object */
lv_obj_t *screen = lv_obj_create(NULL);
if (screen == NULL){
printf("Error: Failed to create screen object\n");
/* Return if screen creation fails */
return;
}
/* Create a new label object on the screen */
lv_obj_t *label = lv_label_create(screen);
if (label == NULL){
printf("Error: Failed to create label object\n");
/* Return if label creation fails */
return;
}
/* Set the text of the label to "Hello, World!" */
lv_label_set_text(label, "Hello, World!");
/* Align the label to the center of the screen */
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
/* Load the created screen and make it visible */
lv_scr_load(screen);
}
// ........................................................................................................
/**
* @brief LVGL task
*
* This task initializes LVGL and runs the main loop, periodically calling the LVGL task handler.
* It is responsible for managing the LVGL state and rendering updates.
*
* @param pvParameters Task parameters (not used in this example)
* @return None
*/
void lvgl_task(void *pvParameters)
{
/* Show simple hello world screen */
create_hello_world_screen();
while (true){
lv_timer_handler(); /* Handle LVGL tasks */
vTaskDelay(pdMS_TO_TICKS(5)); /* Short delay for the RTOS scheduler */
}
}
// ........................................................................................................
/**
* @brief Another task
*
* This task simulates some background work by periodically printing a message.
*
* @param pvParameters Task parameters (not used in this example)
* @return None
*/
void another_task(void *pvParameters)
{
/* Create some load in an infinite loop */
while (true){
printf("Second Task is running :)\n");
/* Delay the task for 500 milliseconds */
vTaskDelay(pdMS_TO_TICKS(500));
}
}
// ........................................................................................................
/**
* @brief FreeRTOS main function
*
* This function sets up and starts the FreeRTOS tasks, including the LVGL task and another demo task.
*
* @param None
* @return None
*/
extern "C" void freertos_main()
{
/* Initialize LVGL (Light and Versatile Graphics Library) and other resources */
/* Create the LVGL task */
if (xTaskCreate(lvgl_task, "LVGL Task", 4096, nullptr, 1, nullptr) != pdPASS) {
printf("Error creating LVGL task\n");
/* Error handling */
}
/* Create another task */
if (xTaskCreate(another_task, "Another Task", 1024, nullptr, 1, nullptr) != pdPASS) {
printf("Error creating another task\n");
/* Error handling */
}
/* Start the scheduler */
vTaskStartScheduler();
}
#endif

1654
src/gui_generated.c Normal file

File diff suppressed because it is too large Load Diff

16
src/gui_generated.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef GUI_GENERATED_H
#define GUI_GENERATED_H
#include "lvgl.h"
void gui_init(void);
void gui_update_values(void);
void gui_modbus_init(void);
void gui_modbus_task(void *arg);
extern lv_obj_t *scr_main;
extern lv_obj_t *scr_screen1;
extern lv_obj_t *scr_screen2;
extern lv_obj_t *scr_screen3;
#endif /* GUI_GENERATED_H */

146
src/main.c Normal file
View File

@ -0,0 +1,146 @@
/**
* @file main
*
*/
/*********************
* INCLUDES
*********************/
#ifndef _DEFAULT_SOURCE
#define _DEFAULT_SOURCE /* needed for usleep() */
#endif
#include <stdlib.h>
#include <stdio.h>
#ifdef _MSC_VER
#include <Windows.h>
#else
#include <unistd.h>
#include <pthread.h>
#endif
#include "lvgl/lvgl.h"
#include "lvgl/examples/lv_examples.h"
#include "lvgl/demos/lv_demos.h"
#include <SDL.h>
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static lv_display_t * hal_init(int32_t w, int32_t h);
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
extern void freertos_main(void);
extern void placeWidgets();
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* VARIABLES
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
int main(int argc, char **argv)
{
(void)argc; /*Unused*/
(void)argv; /*Unused*/
/*Initialize LVGL*/
lv_init();
/*Initialize the HAL (display, input devices, tick) for LVGL*/
hal_init(800, 480);
#if LV_USE_OS == LV_OS_NONE
placeWidgets();
while(1) {
/* Periodically call the lv_task handler.
* It could be done in a timer interrupt or an OS task too.*/
lv_timer_handler();
#ifdef _MSC_VER
Sleep(5);
#else
usleep(5 * 1000);
#endif
}
#elif LV_USE_OS == LV_OS_FREERTOS
/* Run FreeRTOS and create lvgl task */
freertos_main();
#endif
return 0;
}
/**********************
* STATIC FUNCTIONS
**********************/
/**
* Initialize the Hardware Abstraction Layer (HAL) for the LVGL graphics
* library
*/
static lv_display_t * hal_init(int32_t w, int32_t h)
{
lv_group_set_default(lv_group_create());
lv_display_t * disp = lv_sdl_window_create(w, h);
lv_indev_t * mouse = lv_sdl_mouse_create();
lv_indev_set_group(mouse, lv_group_get_default());
lv_indev_set_display(mouse, disp);
lv_display_set_default(disp);
LV_IMAGE_DECLARE(mouse_cursor_icon); /*Declare the image file.*/
lv_obj_t * cursor_obj;
cursor_obj = lv_image_create(lv_screen_active()); /*Create an image object for the cursor */
lv_image_set_src(cursor_obj, &mouse_cursor_icon); /*Set the image source*/
lv_indev_set_cursor(mouse, cursor_obj); /*Connect the image object to the driver*/
lv_indev_t * mousewheel = lv_sdl_mousewheel_create();
lv_indev_set_display(mousewheel, disp);
lv_indev_set_group(mousewheel, lv_group_get_default());
lv_indev_t * kb = lv_sdl_keyboard_create();
lv_indev_set_display(kb, disp);
lv_indev_set_group(kb, lv_group_get_default());
return disp;
}

93
src/main_sim.c Normal file
View File

@ -0,0 +1,93 @@
/**
* @file main_sim
* Simulator entry point for GUI Editor design
*/
#ifndef _DEFAULT_SOURCE
#define _DEFAULT_SOURCE /* needed for usleep() */
#endif
#include <stdlib.h>
#include <stdio.h>
#ifdef _MSC_VER
#include <Windows.h>
#else
#include <unistd.h>
#include <pthread.h>
#endif
#include "lvgl/lvgl.h"
#include <SDL.h>
#include "gui_generated.h"
static lv_display_t * hal_init(int32_t w, int32_t h);
extern void freertos_main(void);
int main(int argc, char **argv)
{
(void)argc; /*Unused*/
(void)argv; /*Unused*/
/*Initialize LVGL*/
lv_init();
/*Initialize the HAL (display, input devices, tick) for LVGL*/
hal_init(800, 480);
#if LV_USE_OS == LV_OS_NONE
gui_init();
while(1) {
/* Periodically call the lv_task handler.
* It could be done in a timer interrupt or an OS task too.*/
lv_timer_handler();
#ifdef _MSC_VER
Sleep(5);
#else
usleep(5 * 1000);
#endif
}
#elif LV_USE_OS == LV_OS_FREERTOS
/* Run FreeRTOS and create lvgl task */
freertos_main();
#endif
return 0;
}
/**
* Initialize the Hardware Abstraction Layer (HAL) for the LVGL graphics
* library
*/
static lv_display_t * hal_init(int32_t w, int32_t h)
{
lv_group_set_default(lv_group_create());
lv_display_t * disp = lv_sdl_window_create(w, h);
lv_indev_t * mouse = lv_sdl_mouse_create();
lv_indev_set_group(mouse, lv_group_get_default());
lv_indev_set_display(mouse, disp);
lv_display_set_default(disp);
LV_IMAGE_DECLARE(mouse_cursor_icon); /*Declare the image file.*/
lv_obj_t * cursor_obj;
cursor_obj = lv_image_create(lv_screen_active()); /*Create an image object for the cursor */
lv_image_set_src(cursor_obj, &mouse_cursor_icon); /*Set the image source*/
lv_indev_set_cursor(mouse, cursor_obj); /*Connect the image object to the driver*/
lv_indev_t * mousewheel = lv_sdl_mousewheel_create();
lv_indev_set_display(mousewheel, disp);
lv_indev_set_group(mousewheel, lv_group_get_default());
lv_indev_t * kb = lv_sdl_keyboard_create();
lv_indev_set_display(kb, disp);
lv_indev_set_group(kb, lv_group_get_default());
return disp;
}

34
src/mouse_cursor_icon.c Normal file
View File

@ -0,0 +1,34 @@
#include "lvgl/lvgl.h"
const uint8_t mouse_cursor_icon_map[] = {
0x19, 0x19, 0x19, 0xb8, 0x1e, 0x1e, 0x1e, 0xc8, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x48, 0x48, 0x48, 0xcc, 0xb2, 0xb2, 0xb2, 0xff, 0x3a, 0x3a, 0x3a, 0xcc, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3b, 0x3b, 0x3b, 0xc8, 0xf6, 0xf6, 0xf6, 0xff, 0xdc, 0xdc, 0xdc, 0xff, 0x43, 0x43, 0x43, 0xe0, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3b, 0x3b, 0x3b, 0xcb, 0xe6, 0xe6, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xe5, 0xe5, 0xe5, 0xff, 0x59, 0x59, 0x59, 0xf3, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3c, 0x3c, 0x3c, 0xcb, 0xe9, 0xe9, 0xe9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf5, 0xf5, 0xf5, 0xff, 0x72, 0x72, 0x72, 0xff, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3d, 0x3d, 0x3d, 0xcb, 0xe9, 0xe9, 0xe9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8a, 0x8a, 0x8a, 0xff, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x99, 0x99, 0x00, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3e, 0x3e, 0x3e, 0xcb, 0xe9, 0xe9, 0xe9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa2, 0xa2, 0xa2, 0xff, 0x13, 0x13, 0x13, 0xab, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3f, 0x3f, 0x3f, 0xcb, 0xe9, 0xe9, 0xe9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb7, 0xb7, 0xb7, 0xff, 0x1f, 0x1f, 0x1f, 0xbb, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x41, 0x41, 0x41, 0xcc, 0xea, 0xea, 0xea, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xca, 0xca, 0xca, 0xff, 0x3d, 0x3d, 0x3d, 0xd8, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x41, 0x41, 0x41, 0xcc, 0xea, 0xea, 0xea, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xde, 0xde, 0xde, 0xff, 0x56, 0x56, 0x56, 0xef, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x00,
0x42, 0x42, 0x42, 0xcc, 0xea, 0xea, 0xea, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xf3, 0xf3, 0xff, 0x76, 0x76, 0x76, 0xff, 0x00, 0x00, 0x00, 0x6b,
0x43, 0x43, 0x43, 0xcc, 0xea, 0xea, 0xea, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xce, 0xce, 0xce, 0xff, 0x80, 0x80, 0x80, 0xf7, 0x74, 0x74, 0x74, 0xf8, 0x6d, 0x6d, 0x6d, 0xfb, 0x72, 0x72, 0x72, 0xf8, 0x57, 0x57, 0x57, 0xff, 0x0c, 0x0c, 0x0c, 0xb3,
0x44, 0x44, 0x44, 0xcc, 0xeb, 0xeb, 0xeb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xfb, 0xfb, 0xfb, 0xff, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc9, 0xc9, 0xc9, 0xff, 0x13, 0x13, 0x13, 0xb7, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0c, 0x29, 0x29, 0x29, 0x07,
0x45, 0x45, 0x45, 0xcc, 0xe8, 0xe8, 0xe8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd9, 0xd9, 0xd9, 0xff, 0x5e, 0x5e, 0x5e, 0xff, 0xe2, 0xe2, 0xe2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x62, 0x62, 0x62, 0xf0, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x45, 0x45, 0x45, 0xcc, 0xf9, 0xf9, 0xf9, 0xff, 0xec, 0xec, 0xec, 0xff, 0x4a, 0x4a, 0x4a, 0xd8, 0x00, 0x00, 0x00, 0x78, 0x8a, 0x8a, 0x8a, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x58, 0x58, 0x58, 0xd3, 0xd9, 0xd9, 0xd9, 0xff, 0x5e, 0x5e, 0x5e, 0xef, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x3b, 0x3b, 0xc7, 0xe9, 0xe9, 0xe9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf4, 0xf4, 0xf4, 0xff, 0x54, 0x54, 0x54, 0xdc, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
0x3e, 0x3e, 0x3e, 0xe0, 0x54, 0x54, 0x54, 0xff, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x8e, 0x8e, 0x8e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb0, 0xb0, 0xb0, 0xff, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x4c, 0x4c, 0x4c, 0xd0, 0xec, 0xec, 0xec, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xf4, 0xf4, 0xf4, 0xff, 0x53, 0x53, 0x53, 0xd8, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x1e, 0x1e, 0x00, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xab, 0xab, 0xab, 0xff, 0xf6, 0xf6, 0xf6, 0xff, 0x80, 0x80, 0x80, 0xff, 0x31, 0x31, 0x31, 0xac, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x09, 0x09, 0x09, 0x03, 0x02, 0x02, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x2e, 0x2e, 0x2e, 0xd7, 0x38, 0x38, 0x38, 0xc7, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
lv_img_dsc_t mouse_cursor_icon = {
.header.magic = LV_IMAGE_HEADER_MAGIC,
.header.w = 14,
.header.h = 20,
.data_size = 280 * 4,
.header.cf = LV_COLOR_FORMAT_ARGB8888,
.data = mouse_cursor_icon_map,
};