diff --git a/10-OBD-Display-2024/_archive/lvgl9_broken/ST77916_LVGL_DEMO.ino b/10-OBD-Display-2024/_archive/lvgl9_broken/ST77916_LVGL_DEMO.ino deleted file mode 100644 index 87ad540..0000000 --- a/10-OBD-Display-2024/_archive/lvgl9_broken/ST77916_LVGL_DEMO.ino +++ /dev/null @@ -1,179 +0,0 @@ -#include "scr_st77916.h" -#include "SD_MMC.h" - -// https://randomnerdtutorials.com/esp32-client-server-wi-fi/ -#include -#include - -const char* ssid = "ESP32-Access-Point"; -const char* password = "123456789"; - - -void my_print(const char* buf) { - Serial.println(buf); // Print logs to the serial monitor -} - -void display_animation() { - lv_obj_t* img; - - img = lv_gif_create(lv_scr_act()); - - Serial.print("Available Heap before: "); - Serial.println(esp_get_free_heap_size()); - - lv_mem_monitor_t mem_mon; - lv_mem_monitor(&mem_mon); - printf("Free memory: %d bytes\n", mem_mon.free_size); - - lv_fs_file_t file; - if (lv_fs_open(&file, "A:wallpaper.gif", LV_FS_MODE_RD) == LV_FS_RES_OK) { - lv_fs_close(&file); // File exists, proceed with loading - lv_gif_set_src(img, "A:wallpaper.gif"); - Serial.println("GIF Loaded Successfully"); - } else { - Serial.println("Failed to Load GIF: File not found or inaccessible"); - } - - Serial.print("Available Heap after: "); - Serial.println(esp_get_free_heap_size()); - - lv_mem_monitor(&mem_mon); - printf("Free memory: %d bytes\n", mem_mon.free_size); - - lv_obj_align(img, LV_ALIGN_CENTER, 0, 0); -} - -lv_obj_t* label1; - -void display_text() { - // Create a style for the text - static lv_style_t style_text; - lv_style_init(&style_text); - - // Set the text color to white - lv_style_set_text_color(&style_text, lv_color_white()); - - // // Set the shadow color to black (this will simulate the outline) - // lv_style_set_shadow_color(&style_text, lv_color_black()); - - // // Set the shadow width to create the outline effect - // lv_style_set_shadow_width(&style_text, 2); // Adjust for desired outline thickness - - // // Set the shadow offset to 0 so it surrounds the text evenly - // lv_style_set_shadow_ofs_x(&style_text, 0); - // lv_style_set_shadow_ofs_y(&style_text, 0); - - label1 = lv_label_create(lv_scr_act()); - - // Apply the style to the label - lv_obj_add_style(label1, &style_text, LV_PART_MAIN); - - // lv_style_set_text_font(&label1, &Montserrat); /*Set a larger font*/ - lv_label_set_long_mode(label1, LV_LABEL_LONG_WRAP); /*Break the long lines*/ - lv_label_set_text(label1, "0"); - lv_obj_set_width(label1, 150); /*Set smaller width to make the lines wrap*/ - lv_obj_set_style_text_align(label1, LV_TEXT_ALIGN_CENTER, 0); - lv_obj_align(label1, LV_ALIGN_CENTER, 0, 0); - // lv_obj_set_style_transform_zoom(label1, 256 * 2, 0); // Zoom: 256 = 1x scale (default) -} - -void connectToWifi() { - WiFi.begin(ssid, password); - Serial.println("Connecting"); - while (WiFi.status() != WL_CONNECTED) { - delay(500); - Serial.print("."); - } - Serial.println(""); - Serial.print("Connected to WiFi network with IP Address: "); - Serial.println(WiFi.localIP()); -} - -void setup() { - delay(200); - Serial.begin(115200); - scr_lvgl_init(); - - //lv_log_register_print_cb(my_print); // Register print function for LVGL logs - - // Get the active screen (root object for the display) - lv_obj_t* screen = lv_scr_act(); - - // Set the background color of the entire screen to black - lv_obj_set_style_bg_color(screen, lv_color_black(), 0); // 0 is the part ID for the main part - lv_obj_set_style_bg_opa(screen, LV_OPA_COVER, 0); // Set opacity to fully opaque - - // Configure the SDMMC host - SD_MMC.setPins(SD_MMC_CLK_PIN, SD_MMC_CMD_PIN, SD_MMC_D0_PIN, SD_MMC_D1_PIN, SD_MMC_D2_PIN, SD_MMC_D3_PIN); - - if (!SD_MMC.begin()) { - Serial.println("Card Mount Failed"); - return; - } - - uint8_t cardType = SD_MMC.cardType(); - if (cardType == CARD_NONE) { - Serial.println("No SD card attached"); - return; - } - - Serial.println("SD Card initialized successfully."); - - connectToWifi(); - - // display_animation(); - - display_text(); -} - -void loop() { - lv_timer_handler(); - vTaskDelay(5); - - lv_mem_monitor_t mem_mon; - lv_mem_monitor(&mem_mon); - printf("Free memory: %d bytes\n", mem_mon.free_size); - - Serial.print("Available Heap: "); - Serial.println(esp_get_free_heap_size()); - - - if (WiFi.status() == WL_CONNECTED) { - String speed = httpGETRequest("http://192.168.4.1/speed"); - - Serial.print("Speed: "); - Serial.println(speed); - - lv_label_set_text(label1, speed.c_str()); - } else { - Serial.println("WiFi Disconnected"); - connectToWifi(); - } -} - - -String httpGETRequest(const char* serverName) { - WiFiClient client; - HTTPClient http; - - // Your Domain name with URL path or IP address with path - http.begin(client, serverName); - - // Send HTTP POST request - int httpResponseCode = http.GET(); - - String payload = "--"; - - if (httpResponseCode > 0) { - Serial.print("HTTP Response code: "); - Serial.println(httpResponseCode); - payload = http.getString(); - } else { - Serial.print("Error code: "); - Serial.println(httpResponseCode); - } - // Free resources - http.end(); - - return payload; -} \ No newline at end of file diff --git a/10-OBD-Display-2024/_archive/lvgl9_broken/lv_conf.h b/10-OBD-Display-2024/_archive/lvgl9_broken/lv_conf.h deleted file mode 100644 index 480ebd1..0000000 --- a/10-OBD-Display-2024/_archive/lvgl9_broken/lv_conf.h +++ /dev/null @@ -1,988 +0,0 @@ -/** - * @file lv_conf.h - * Configuration file for v9.1.0 - */ - -/* - * Copy this file as `lv_conf.h` - * 1. simply next to the `lvgl` folder - * 2. or any other places and - * - define `LV_CONF_INCLUDE_SIMPLE` - * - add the path as include path - */ - -/* clang-format off */ -#if 1 /*Set it to "1" to enable content*/ - -#ifndef LV_CONF_H -#define LV_CONF_H - -/*If you need to include anything here, do it inside the `__ASSEMBLY__` guard */ -#if 0 && defined(__ASSEMBLY__) -#include "my_include.h" -#endif - -/*==================== - COLOR SETTINGS - *====================*/ - -/*Color depth: 8 (A8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888)*/ -#define LV_COLOR_DEPTH 16 - -/*========================= - STDLIB WRAPPER SETTINGS - *=========================*/ - -/* Possible values - * - LV_STDLIB_BUILTIN: LVGL's built in implementation - * - LV_STDLIB_CLIB: Standard C functions, like malloc, strlen, etc - * - LV_STDLIB_MICROPYTHON: MicroPython implementation - * - LV_STDLIB_RTTHREAD: RT-Thread implementation - * - LV_STDLIB_CUSTOM: Implement the functions externally - */ -#define LV_USE_STDLIB_MALLOC LV_STDLIB_BUILTIN -#define LV_USE_STDLIB_STRING LV_STDLIB_BUILTIN -#define LV_USE_STDLIB_SPRINTF LV_STDLIB_BUILTIN - - -#if LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN - /*Size of the memory available for `lv_malloc()` in bytes (>= 2kB)*/ - #define LV_MEM_SIZE (64 * 1024U) /*[bytes]*/ - - /*Size of the memory expand for `lv_malloc()` in bytes*/ - #define LV_MEM_POOL_EXPAND_SIZE 0 - - /*Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too.*/ - #define LV_MEM_ADR 0 /*0: unused*/ - /*Instead of an address give a memory allocator that will be called to get a memory pool for LVGL. E.g. my_malloc*/ - #if LV_MEM_ADR == 0 - #undef LV_MEM_POOL_INCLUDE - #undef LV_MEM_POOL_ALLOC - #endif -#endif /*LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN*/ - -/*==================== - HAL SETTINGS - *====================*/ - -/*Default display refresh, input device read and animation step period.*/ -#define LV_DEF_REFR_PERIOD 33 /*[ms]*/ - -/*Default Dot Per Inch. Used to initialize default sizes such as widgets sized, style paddings. - *(Not so important, you can adjust it to modify default sizes and spaces)*/ -#define LV_DPI_DEF 130 /*[px/inch]*/ - -/*================= - * OPERATING SYSTEM - *=================*/ -/*Select an operating system to use. Possible options: - * - LV_OS_NONE - * - LV_OS_PTHREAD - * - LV_OS_FREERTOS - * - LV_OS_CMSIS_RTOS2 - * - LV_OS_RTTHREAD - * - LV_OS_WINDOWS - * - LV_OS_CUSTOM */ -#define LV_USE_OS LV_OS_NONE - -#if LV_USE_OS == LV_OS_CUSTOM - #define LV_OS_CUSTOM_INCLUDE -#endif - -/*======================== - * RENDERING CONFIGURATION - *========================*/ - -/*Align the stride of all layers and images to this bytes*/ -#define LV_DRAW_BUF_STRIDE_ALIGN 1 - -/*Align the start address of draw_buf addresses to this bytes*/ -#define LV_DRAW_BUF_ALIGN 4 - -/* If a widget has `style_opa < 255` (not `bg_opa`, `text_opa` etc) or not NORMAL blend mode - * it is buffered into a "simple" layer before rendering. The widget can be buffered in smaller chunks. - * "Transformed layers" (if `transform_angle/zoom` are set) use larger buffers - * and can't be drawn in chunks. */ - -/*The target buffer size for simple layer chunks.*/ -#define LV_DRAW_LAYER_SIMPLE_BUF_SIZE (24 * 1024) /*[bytes]*/ - -#define LV_USE_DRAW_SW 1 -#if LV_USE_DRAW_SW == 1 - /* Set the number of draw unit. - * > 1 requires an operating system enabled in `LV_USE_OS` - * > 1 means multiply threads will render the screen in parallel */ - #define LV_DRAW_SW_DRAW_UNIT_CNT 1 - - /* Use Arm-2D to accelerate the sw render */ - #define LV_USE_DRAW_ARM2D_SYNC 0 - - /* Enable native helium assembly to be compiled */ - #define LV_USE_NATIVE_HELIUM_ASM 0 - - /* 0: use a simple renderer capable of drawing only simple rectangles with gradient, images, texts, and straight lines only - * 1: use a complex renderer capable of drawing rounded corners, shadow, skew lines, and arcs too */ - #define LV_DRAW_SW_COMPLEX 1 - - #if LV_DRAW_SW_COMPLEX == 1 - /*Allow buffering some shadow calculation. - *LV_DRAW_SW_SHADOW_CACHE_SIZE is the max. shadow size to buffer, where shadow size is `shadow_width + radius` - *Caching has LV_DRAW_SW_SHADOW_CACHE_SIZE^2 RAM cost*/ - #define LV_DRAW_SW_SHADOW_CACHE_SIZE 0 - - /* Set number of maximally cached circle data. - * The circumference of 1/4 circle are saved for anti-aliasing - * radius * 4 bytes are used per circle (the most often used radiuses are saved) - * 0: to disable caching */ - #define LV_DRAW_SW_CIRCLE_CACHE_SIZE 4 - #endif - - #define LV_USE_DRAW_SW_ASM LV_DRAW_SW_ASM_NONE - - #if LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_CUSTOM - #define LV_DRAW_SW_ASM_CUSTOM_INCLUDE "" - #endif -#endif - -/* Use NXP's VG-Lite GPU on iMX RTxxx platforms. */ -#define LV_USE_DRAW_VGLITE 0 - -#if LV_USE_DRAW_VGLITE - /* Enable blit quality degradation workaround recommended for screen's dimension > 352 pixels. */ - #define LV_USE_VGLITE_BLIT_SPLIT 0 - - #if LV_USE_OS - /* Enable VGLite draw async. Queue multiple tasks and flash them once to the GPU. */ - #define LV_USE_VGLITE_DRAW_ASYNC 1 - #endif - - /* Enable VGLite asserts. */ - #define LV_USE_VGLITE_ASSERT 0 -#endif - -/* Use NXP's PXP on iMX RTxxx platforms. */ -#define LV_USE_DRAW_PXP 0 - -#if LV_USE_DRAW_PXP - /* Enable PXP asserts. */ - #define LV_USE_PXP_ASSERT 0 -#endif - -/* Use Renesas Dave2D on RA platforms. */ -#define LV_USE_DRAW_DAVE2D 0 - -/* Draw using cached SDL textures*/ -#define LV_USE_DRAW_SDL 0 - -/* Use VG-Lite GPU. */ -#define LV_USE_DRAW_VG_LITE 0 - -#if LV_USE_DRAW_VG_LITE -/* Enable VG-Lite custom external 'gpu_init()' function */ -#define LV_VG_LITE_USE_GPU_INIT 0 - -/* Enable VG-Lite assert. */ -#define LV_VG_LITE_USE_ASSERT 0 - -/* VG-Lite flush commit trigger threshold. GPU will try to batch these many draw tasks. */ -#define LV_VG_LITE_FLUSH_MAX_COUNT 8 - -/* Enable border to simulate shadow - * NOTE: which usually improves performance, - * but does not guarantee the same rendering quality as the software. */ -#define LV_VG_LITE_USE_BOX_SHADOW 0 - -/* VG-Lite gradient image maximum cache number. - * NOTE: The memory usage of a single gradient image is 4K bytes. - */ -#define LV_VG_LITE_GRAD_CACHE_SIZE 32 - -#endif - -/*======================= - * FEATURE CONFIGURATION - *=======================*/ - -/*------------- - * Logging - *-----------*/ - -/*Enable the log module*/ -#define LV_USE_LOG 1 -#if LV_USE_LOG - - /*How important log should be added: - *LV_LOG_LEVEL_TRACE A lot of logs to give detailed information - *LV_LOG_LEVEL_INFO Log important events - *LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem - *LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail - *LV_LOG_LEVEL_USER Only logs added by the user - *LV_LOG_LEVEL_NONE Do not log anything*/ - #define LV_LOG_LEVEL LV_LOG_LEVEL_INFO - - /*1: Print the log with 'printf'; - *0: User need to register a callback with `lv_log_register_print_cb()`*/ - #define LV_LOG_PRINTF 0 - - /*1: Enable print timestamp; - *0: Disable print timestamp*/ - #define LV_LOG_USE_TIMESTAMP 1 - - /*1: Print file and line number of the log; - *0: Do not print file and line number of the log*/ - #define LV_LOG_USE_FILE_LINE 1 - - /*Enable/disable LV_LOG_TRACE in modules that produces a huge number of logs*/ - #define LV_LOG_TRACE_MEM 1 - #define LV_LOG_TRACE_TIMER 1 - #define LV_LOG_TRACE_INDEV 1 - #define LV_LOG_TRACE_DISP_REFR 1 - #define LV_LOG_TRACE_EVENT 1 - #define LV_LOG_TRACE_OBJ_CREATE 1 - #define LV_LOG_TRACE_LAYOUT 1 - #define LV_LOG_TRACE_ANIM 1 - #define LV_LOG_TRACE_CACHE 1 - -#endif /*LV_USE_LOG*/ - -/*------------- - * Asserts - *-----------*/ - -/*Enable asserts if an operation is failed or an invalid data is found. - *If LV_USE_LOG is enabled an error message will be printed on failure*/ -#define LV_USE_ASSERT_NULL 1 /*Check if the parameter is NULL. (Very fast, recommended)*/ -#define LV_USE_ASSERT_MALLOC 1 /*Checks is the memory is successfully allocated or no. (Very fast, recommended)*/ -#define LV_USE_ASSERT_STYLE 0 /*Check if the styles are properly initialized. (Very fast, recommended)*/ -#define LV_USE_ASSERT_MEM_INTEGRITY 0 /*Check the integrity of `lv_mem` after critical operations. (Slow)*/ -#define LV_USE_ASSERT_OBJ 0 /*Check the object's type and existence (e.g. not deleted). (Slow)*/ - -/*Add a custom handler when assert happens e.g. to restart the MCU*/ -#define LV_ASSERT_HANDLER_INCLUDE -#define LV_ASSERT_HANDLER while(1); /*Halt by default*/ - -/*------------- - * Debug - *-----------*/ - -/*1: Draw random colored rectangles over the redrawn areas*/ -#define LV_USE_REFR_DEBUG 0 - -/*1: Draw a red overlay for ARGB layers and a green overlay for RGB layers*/ -#define LV_USE_LAYER_DEBUG 0 - -/*1: Draw overlays with different colors for each draw_unit's tasks. - *Also add the index number of the draw unit on white background. - *For layers add the index number of the draw unit on black background.*/ -#define LV_USE_PARALLEL_DRAW_DEBUG 0 - -/*------------- - * Others - *-----------*/ - -#define LV_ENABLE_GLOBAL_CUSTOM 0 -#if LV_ENABLE_GLOBAL_CUSTOM - /*Header to include for the custom 'lv_global' function"*/ - #define LV_GLOBAL_CUSTOM_INCLUDE -#endif - -/*Default cache size in bytes. - *Used by image decoders such as `lv_lodepng` to keep the decoded image in the memory. - *If size is not set to 0, the decoder will fail to decode when the cache is full. - *If size is 0, the cache function is not enabled and the decoded mem will be released immediately after use.*/ -#define LV_CACHE_DEF_SIZE 0 - -/*Default number of image header cache entries. The cache is used to store the headers of images - *The main logic is like `LV_CACHE_DEF_SIZE` but for image headers.*/ -#define LV_IMAGE_HEADER_CACHE_DEF_CNT 0 - -/*Number of stops allowed per gradient. Increase this to allow more stops. - *This adds (sizeof(lv_color_t) + 1) bytes per additional stop*/ -#define LV_GRADIENT_MAX_STOPS 2 - -/* Adjust color mix functions rounding. GPUs might calculate color mix (blending) differently. - * 0: round down, 64: round up from x.75, 128: round up from half, 192: round up from x.25, 254: round up */ -#define LV_COLOR_MIX_ROUND_OFS 0 - -/* Add 2 x 32 bit variables to each lv_obj_t to speed up getting style properties */ -#define LV_OBJ_STYLE_CACHE 0 - -/* Add `id` field to `lv_obj_t` */ -#define LV_USE_OBJ_ID 0 - -/* Use lvgl builtin method for obj ID */ -#define LV_USE_OBJ_ID_BUILTIN 0 - -/*Use obj property set/get API*/ -#define LV_USE_OBJ_PROPERTY 0 - -/* VG-Lite Simulator */ -/*Requires: LV_USE_THORVG_INTERNAL or LV_USE_THORVG_EXTERNAL */ -#define LV_USE_VG_LITE_THORVG 0 - -#if LV_USE_VG_LITE_THORVG - - /*Enable LVGL's blend mode support*/ - #define LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT 0 - - /*Enable YUV color format support*/ - #define LV_VG_LITE_THORVG_YUV_SUPPORT 0 - - /*Enable 16 pixels alignment*/ - #define LV_VG_LITE_THORVG_16PIXELS_ALIGN 1 - - /*Buffer address alignment*/ - #define LV_VG_LITE_THORVG_BUF_ADDR_ALIGN 64 - - /*Enable multi-thread render*/ - #define LV_VG_LITE_THORVG_THREAD_RENDER 0 - -#endif - -/*===================== - * COMPILER SETTINGS - *====================*/ - -/*For big endian systems set to 1*/ -#define LV_BIG_ENDIAN_SYSTEM 0 - -/*Define a custom attribute to `lv_tick_inc` function*/ -#define LV_ATTRIBUTE_TICK_INC - -/*Define a custom attribute to `lv_timer_handler` function*/ -#define LV_ATTRIBUTE_TIMER_HANDLER - -/*Define a custom attribute to `lv_display_flush_ready` function*/ -#define LV_ATTRIBUTE_FLUSH_READY - -/*Required alignment size for buffers*/ -#define LV_ATTRIBUTE_MEM_ALIGN_SIZE 1 - -/*Will be added where memories needs to be aligned (with -Os data might not be aligned to boundary by default). - * E.g. __attribute__((aligned(4)))*/ -#define LV_ATTRIBUTE_MEM_ALIGN - -/*Attribute to mark large constant arrays for example font's bitmaps*/ -#define LV_ATTRIBUTE_LARGE_CONST - -/*Compiler prefix for a big array declaration in RAM*/ -#define LV_ATTRIBUTE_LARGE_RAM_ARRAY - -/*Place performance critical functions into a faster memory (e.g RAM)*/ -#define LV_ATTRIBUTE_FAST_MEM - -/*Export integer constant to binding. This macro is used with constants in the form of LV_ that - *should also appear on LVGL binding API such as Micropython.*/ -#define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning /*The default value just prevents GCC warning*/ - -/*Prefix all global extern data with this*/ -#define LV_ATTRIBUTE_EXTERN_DATA - -/* Use `float` as `lv_value_precise_t` */ -#define LV_USE_FLOAT 0 - -/*================== - * FONT USAGE - *===================*/ - -/*Montserrat fonts with ASCII range and some symbols using bpp = 4 - *https://fonts.google.com/specimen/Montserrat*/ -#define LV_FONT_MONTSERRAT_8 0 -#define LV_FONT_MONTSERRAT_10 0 -#define LV_FONT_MONTSERRAT_12 0 -#define LV_FONT_MONTSERRAT_14 0 -#define LV_FONT_MONTSERRAT_16 0 -#define LV_FONT_MONTSERRAT_18 0 -#define LV_FONT_MONTSERRAT_20 0 -#define LV_FONT_MONTSERRAT_22 0 -#define LV_FONT_MONTSERRAT_24 0 -#define LV_FONT_MONTSERRAT_26 0 -#define LV_FONT_MONTSERRAT_28 0 -#define LV_FONT_MONTSERRAT_30 0 -#define LV_FONT_MONTSERRAT_32 0 -#define LV_FONT_MONTSERRAT_34 0 -#define LV_FONT_MONTSERRAT_36 0 -#define LV_FONT_MONTSERRAT_38 0 -#define LV_FONT_MONTSERRAT_40 0 -#define LV_FONT_MONTSERRAT_42 0 -#define LV_FONT_MONTSERRAT_44 0 -#define LV_FONT_MONTSERRAT_46 0 -#define LV_FONT_MONTSERRAT_48 1 - -/*Demonstrate special features*/ -#define LV_FONT_MONTSERRAT_28_COMPRESSED 0 /*bpp = 3*/ -#define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 0 /*Hebrew, Arabic, Persian letters and all their forms*/ -#define LV_FONT_SIMSUN_16_CJK 0 /*1000 most common CJK radicals*/ - -/*Pixel perfect monospace fonts*/ -#define LV_FONT_UNSCII_8 0 -#define LV_FONT_UNSCII_16 0 - -/*Optionally declare custom fonts here. - *You can use these fonts as default font too and they will be available globally. - *E.g. #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) LV_FONT_DECLARE(my_font_2)*/ -#define LV_FONT_CUSTOM_DECLARE - -/*Always set a default font*/ -#define LV_FONT_DEFAULT &lv_font_montserrat_48 - -/*Enable handling large font and/or fonts with a lot of characters. - *The limit depends on the font size, font face and bpp. - *Compiler error will be triggered if a font needs it.*/ -#define LV_FONT_FMT_TXT_LARGE 0 - -/*Enables/disables support for compressed fonts.*/ -#define LV_USE_FONT_COMPRESSED 0 - -/*Enable drawing placeholders when glyph dsc is not found*/ -#define LV_USE_FONT_PLACEHOLDER 1 - -/*================= - * TEXT SETTINGS - *=================*/ - -/** - * Select a character encoding for strings. - * Your IDE or editor should have the same character encoding - * - LV_TXT_ENC_UTF8 - * - LV_TXT_ENC_ASCII - */ -#define LV_TXT_ENC LV_TXT_ENC_UTF8 - -/*Can break (wrap) texts on these chars*/ -#define LV_TXT_BREAK_CHARS " ,.;:-_)]}" - -/*If a word is at least this long, will break wherever "prettiest" - *To disable, set to a value <= 0*/ -#define LV_TXT_LINE_BREAK_LONG_LEN 0 - -/*Minimum number of characters in a long word to put on a line before a break. - *Depends on LV_TXT_LINE_BREAK_LONG_LEN.*/ -#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3 - -/*Minimum number of characters in a long word to put on a line after a break. - *Depends on LV_TXT_LINE_BREAK_LONG_LEN.*/ -#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3 - -/*Support bidirectional texts. Allows mixing Left-to-Right and Right-to-Left texts. - *The direction will be processed according to the Unicode Bidirectional Algorithm: - *https://www.w3.org/International/articles/inline-bidi-markup/uba-basics*/ -#define LV_USE_BIDI 0 -#if LV_USE_BIDI - /*Set the default direction. Supported values: - *`LV_BASE_DIR_LTR` Left-to-Right - *`LV_BASE_DIR_RTL` Right-to-Left - *`LV_BASE_DIR_AUTO` detect texts base direction*/ - #define LV_BIDI_BASE_DIR_DEF LV_BASE_DIR_AUTO -#endif - -/*Enable Arabic/Persian processing - *In these languages characters should be replaced with an other form based on their position in the text*/ -#define LV_USE_ARABIC_PERSIAN_CHARS 0 - -/*================== - * WIDGETS - *================*/ - -/*Documentation of the widgets: https://docs.lvgl.io/latest/en/html/widgets/index.html*/ - -#define LV_WIDGETS_HAS_DEFAULT_VALUE 1 - -#define LV_USE_ANIMIMG 1 - -#define LV_USE_ARC 1 - -#define LV_USE_BAR 1 - -#define LV_USE_BUTTON 1 - -#define LV_USE_BUTTONMATRIX 1 - -#define LV_USE_CALENDAR 1 -#if LV_USE_CALENDAR - #define LV_CALENDAR_WEEK_STARTS_MONDAY 0 - #if LV_CALENDAR_WEEK_STARTS_MONDAY - #define LV_CALENDAR_DEFAULT_DAY_NAMES {"Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"} - #else - #define LV_CALENDAR_DEFAULT_DAY_NAMES {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"} - #endif - - #define LV_CALENDAR_DEFAULT_MONTH_NAMES {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"} - #define LV_USE_CALENDAR_HEADER_ARROW 1 - #define LV_USE_CALENDAR_HEADER_DROPDOWN 1 -#endif /*LV_USE_CALENDAR*/ - -#define LV_USE_CANVAS 1 - -#define LV_USE_CHART 1 - -#define LV_USE_CHECKBOX 1 - -#define LV_USE_DROPDOWN 1 /*Requires: lv_label*/ - -#define LV_USE_IMAGE 1 /*Requires: lv_label*/ - -#define LV_USE_IMAGEBUTTON 1 - -#define LV_USE_KEYBOARD 1 - -#define LV_USE_LABEL 1 -#if LV_USE_LABEL - #define LV_LABEL_TEXT_SELECTION 1 /*Enable selecting text of the label*/ - #define LV_LABEL_LONG_TXT_HINT 1 /*Store some extra info in labels to speed up drawing of very long texts*/ - #define LV_LABEL_WAIT_CHAR_COUNT 3 /*The count of wait chart*/ -#endif - -#define LV_USE_LED 1 - -#define LV_USE_LINE 1 - -#define LV_USE_LIST 1 - -#define LV_USE_MENU 1 - -#define LV_USE_MSGBOX 1 - -#define LV_USE_ROLLER 1 /*Requires: lv_label*/ - -#define LV_USE_SCALE 1 - -#define LV_USE_SLIDER 1 /*Requires: lv_bar*/ - -#define LV_USE_SPAN 1 -#if LV_USE_SPAN - /*A line text can contain maximum num of span descriptor */ - #define LV_SPAN_SNIPPET_STACK_SIZE 64 -#endif - -#define LV_USE_SPINBOX 1 - -#define LV_USE_SPINNER 1 - -#define LV_USE_SWITCH 1 - -#define LV_USE_TEXTAREA 1 /*Requires: lv_label*/ -#if LV_USE_TEXTAREA != 0 - #define LV_TEXTAREA_DEF_PWD_SHOW_TIME 1500 /*ms*/ -#endif - -#define LV_USE_TABLE 1 - -#define LV_USE_TABVIEW 1 - -#define LV_USE_TILEVIEW 1 - -#define LV_USE_WIN 1 - -/*================== - * THEMES - *==================*/ - -/*A simple, impressive and very complete theme*/ -#define LV_USE_THEME_DEFAULT 1 -#if LV_USE_THEME_DEFAULT - - /*0: Light mode; 1: Dark mode*/ - #define LV_THEME_DEFAULT_DARK 0 - - /*1: Enable grow on press*/ - #define LV_THEME_DEFAULT_GROW 1 - - /*Default transition time in [ms]*/ - #define LV_THEME_DEFAULT_TRANSITION_TIME 80 -#endif /*LV_USE_THEME_DEFAULT*/ - -/*A very simple theme that is a good starting point for a custom theme*/ -#define LV_USE_THEME_SIMPLE 1 - -/*A theme designed for monochrome displays*/ -#define LV_USE_THEME_MONO 1 - -/*================== - * LAYOUTS - *==================*/ - -/*A layout similar to Flexbox in CSS.*/ -#define LV_USE_FLEX 1 - -/*A layout similar to Grid in CSS.*/ -#define LV_USE_GRID 1 - -/*==================== - * 3RD PARTS LIBRARIES - *====================*/ - -/*File system interfaces for common APIs */ - -/*API for fopen, fread, etc*/ -#define LV_USE_FS_STDIO 0 -#if LV_USE_FS_STDIO - #define LV_FS_STDIO_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ - #define LV_FS_STDIO_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/ - #define LV_FS_STDIO_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ -#endif - -/*API for open, read, etc*/ -#define LV_USE_FS_POSIX 0 -#if LV_USE_FS_POSIX - #define LV_FS_POSIX_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ - #define LV_FS_POSIX_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/ - #define LV_FS_POSIX_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ -#endif - -/*API for CreateFile, ReadFile, etc*/ -#define LV_USE_FS_WIN32 0 -#if LV_USE_FS_WIN32 - #define LV_FS_WIN32_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ - #define LV_FS_WIN32_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/ - #define LV_FS_WIN32_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ -#endif - -/*API for FATFS (needs to be added separately). Uses f_open, f_read, etc*/ -#define LV_USE_FS_FATFS 0 -#if LV_USE_FS_FATFS - #define LV_FS_FATFS_LETTER 'A' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ - #define LV_FS_FATFS_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ -#endif - -/*API for memory-mapped file access. */ -#define LV_USE_FS_MEMFS 0 -#if LV_USE_FS_MEMFS - #define LV_FS_MEMFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ -#endif - -/*API for LittleFs. */ -#define LV_USE_FS_LITTLEFS 0 -#if LV_USE_FS_LITTLEFS - #define LV_FS_LITTLEFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ -#endif - -/*LODEPNG decoder library*/ -#define LV_USE_LODEPNG 0 - -/*PNG decoder(libpng) library*/ -#define LV_USE_LIBPNG 0 - -/*BMP decoder library*/ -#define LV_USE_BMP 0 - -/* JPG + split JPG decoder library. - * Split JPG is a custom format optimized for embedded systems. */ -#define LV_USE_TJPGD 0 - -/* libjpeg-turbo decoder library. - * Supports complete JPEG specifications and high-performance JPEG decoding. */ -#define LV_USE_LIBJPEG_TURBO 0 - -/*GIF decoder library*/ -#define LV_USE_GIF 1 -#if LV_USE_GIF -/*GIF decoder accelerate*/ -#define LV_GIF_CACHE_DECODE_DATA 1 -#endif - - -/*Decode bin images to RAM*/ -#define LV_BIN_DECODER_RAM_LOAD 0 - -/*RLE decompress library*/ -#define LV_USE_RLE 0 - -/*QR code library*/ -#define LV_USE_QRCODE 0 - -/*Barcode code library*/ -#define LV_USE_BARCODE 0 - -/*FreeType library*/ -#define LV_USE_FREETYPE 0 -#if LV_USE_FREETYPE - /*Let FreeType to use LVGL memory and file porting*/ - #define LV_FREETYPE_USE_LVGL_PORT 0 - - /*Cache count of the glyphs in FreeType. It means the number of glyphs that can be cached. - *The higher the value, the more memory will be used.*/ - #define LV_FREETYPE_CACHE_FT_GLYPH_CNT 256 -#endif - -/* Built-in TTF decoder */ -#define LV_USE_TINY_TTF 0 -#if LV_USE_TINY_TTF - /* Enable loading TTF data from files */ - #define LV_TINY_TTF_FILE_SUPPORT 0 -#endif - -/*Rlottie library*/ -#define LV_USE_RLOTTIE 0 - -/*Enable Vector Graphic APIs*/ -#define LV_USE_VECTOR_GRAPHIC 0 - -/* Enable ThorVG (vector graphics library) from the src/libs folder */ -#define LV_USE_THORVG_INTERNAL 0 - -/* Enable ThorVG by assuming that its installed and linked to the project */ -#define LV_USE_THORVG_EXTERNAL 0 - -/*Use lvgl built-in LZ4 lib*/ -#define LV_USE_LZ4_INTERNAL 0 - -/*Use external LZ4 library*/ -#define LV_USE_LZ4_EXTERNAL 0 - -/*FFmpeg library for image decoding and playing videos - *Supports all major image formats so do not enable other image decoder with it*/ -#define LV_USE_FFMPEG 0 -#if LV_USE_FFMPEG - /*Dump input information to stderr*/ - #define LV_FFMPEG_DUMP_FORMAT 0 -#endif - -/*================== - * OTHERS - *==================*/ - -/*1: Enable API to take snapshot for object*/ -#define LV_USE_SNAPSHOT 0 - -/*1: Enable system monitor component*/ -#define LV_USE_SYSMON 0 -#if LV_USE_SYSMON - /*Get the idle percentage. E.g. uint32_t my_get_idle(void);*/ - #define LV_SYSMON_GET_IDLE lv_timer_get_idle - - /*1: Show CPU usage and FPS count - * Requires `LV_USE_SYSMON = 1`*/ - #define LV_USE_PERF_MONITOR 0 - #if LV_USE_PERF_MONITOR - #define LV_USE_PERF_MONITOR_POS LV_ALIGN_BOTTOM_RIGHT - - /*0: Displays performance data on the screen, 1: Prints performance data using log.*/ - #define LV_USE_PERF_MONITOR_LOG_MODE 0 - #endif - - /*1: Show the used memory and the memory fragmentation - * Requires `LV_USE_STDLIB_MALLOC = LV_STDLIB_BUILTIN` - * Requires `LV_USE_SYSMON = 1`*/ - #define LV_USE_MEM_MONITOR 0 - #if LV_USE_MEM_MONITOR - #define LV_USE_MEM_MONITOR_POS LV_ALIGN_BOTTOM_LEFT - #endif - -#endif /*LV_USE_SYSMON*/ - -/*1: Enable the runtime performance profiler*/ -#define LV_USE_PROFILER 0 -#if LV_USE_PROFILER - /*1: Enable the built-in profiler*/ - #define LV_USE_PROFILER_BUILTIN 1 - #if LV_USE_PROFILER_BUILTIN - /*Default profiler trace buffer size*/ - #define LV_PROFILER_BUILTIN_BUF_SIZE (16 * 1024) /*[bytes]*/ - #endif - - /*Header to include for the profiler*/ - #define LV_PROFILER_INCLUDE "lvgl/src/misc/lv_profiler_builtin.h" - - /*Profiler start point function*/ - #define LV_PROFILER_BEGIN LV_PROFILER_BUILTIN_BEGIN - - /*Profiler end point function*/ - #define LV_PROFILER_END LV_PROFILER_BUILTIN_END - - /*Profiler start point function with custom tag*/ - #define LV_PROFILER_BEGIN_TAG LV_PROFILER_BUILTIN_BEGIN_TAG - - /*Profiler end point function with custom tag*/ - #define LV_PROFILER_END_TAG LV_PROFILER_BUILTIN_END_TAG -#endif - -/*1: Enable Monkey test*/ -#define LV_USE_MONKEY 0 - -/*1: Enable grid navigation*/ -#define LV_USE_GRIDNAV 0 - -/*1: Enable lv_obj fragment*/ -#define LV_USE_FRAGMENT 0 - -/*1: Support using images as font in label or span widgets */ -#define LV_USE_IMGFONT 0 - -/*1: Enable an observer pattern implementation*/ -#define LV_USE_OBSERVER 1 - -/*1: Enable Pinyin input method*/ -/*Requires: lv_keyboard*/ -#define LV_USE_IME_PINYIN 0 -#if LV_USE_IME_PINYIN - /*1: Use default thesaurus*/ - /*If you do not use the default thesaurus, be sure to use `lv_ime_pinyin` after setting the thesauruss*/ - #define LV_IME_PINYIN_USE_DEFAULT_DICT 1 - /*Set the maximum number of candidate panels that can be displayed*/ - /*This needs to be adjusted according to the size of the screen*/ - #define LV_IME_PINYIN_CAND_TEXT_NUM 6 - - /*Use 9 key input(k9)*/ - #define LV_IME_PINYIN_USE_K9_MODE 1 - #if LV_IME_PINYIN_USE_K9_MODE == 1 - #define LV_IME_PINYIN_K9_CAND_TEXT_NUM 3 - #endif /*LV_IME_PINYIN_USE_K9_MODE*/ -#endif - -/*1: Enable file explorer*/ -/*Requires: lv_table*/ -#define LV_USE_FILE_EXPLORER 0 -#if LV_USE_FILE_EXPLORER - /*Maximum length of path*/ - #define LV_FILE_EXPLORER_PATH_MAX_LEN (128) - /*Quick access bar, 1:use, 0:not use*/ - /*Requires: lv_list*/ - #define LV_FILE_EXPLORER_QUICK_ACCESS 1 -#endif - -/*================== - * DEVICES - *==================*/ - -/*Use SDL to open window on PC and handle mouse and keyboard*/ -#define LV_USE_SDL 0 -#if LV_USE_SDL - #define LV_SDL_INCLUDE_PATH - #define LV_SDL_RENDER_MODE LV_DISPLAY_RENDER_MODE_DIRECT /*LV_DISPLAY_RENDER_MODE_DIRECT is recommended for best performance*/ - #define LV_SDL_BUF_COUNT 1 /*1 or 2*/ - #define LV_SDL_FULLSCREEN 0 /*1: Make the window full screen by default*/ - #define LV_SDL_DIRECT_EXIT 1 /*1: Exit the application when all SDL windows are closed*/ - #define LV_SDL_MOUSEWHEEL_MODE LV_SDL_MOUSEWHEEL_MODE_ENCODER /*LV_SDL_MOUSEWHEEL_MODE_ENCODER/CROWN*/ -#endif - -/*Use X11 to open window on Linux desktop and handle mouse and keyboard*/ -#define LV_USE_X11 0 -#if LV_USE_X11 - #define LV_X11_DIRECT_EXIT 1 /*Exit the application when all X11 windows have been closed*/ - #define LV_X11_DOUBLE_BUFFER 1 /*Use double buffers for endering*/ - /*select only 1 of the following render modes (LV_X11_RENDER_MODE_PARTIAL preferred!)*/ - #define LV_X11_RENDER_MODE_PARTIAL 1 /*Partial render mode (preferred)*/ - #define LV_X11_RENDER_MODE_DIRECT 0 /*direct render mode*/ - #define LV_X11_RENDER_MODE_FULL 0 /*Full render mode*/ -#endif - -/*Driver for /dev/fb*/ -#define LV_USE_LINUX_FBDEV 0 -#if LV_USE_LINUX_FBDEV - #define LV_LINUX_FBDEV_BSD 0 - #define LV_LINUX_FBDEV_RENDER_MODE LV_DISPLAY_RENDER_MODE_PARTIAL - #define LV_LINUX_FBDEV_BUFFER_COUNT 0 - #define LV_LINUX_FBDEV_BUFFER_SIZE 60 -#endif - -/*Use Nuttx to open window and handle touchscreen*/ -#define LV_USE_NUTTX 0 - -#if LV_USE_NUTTX - #define LV_USE_NUTTX_LIBUV 0 - - /*Use Nuttx custom init API to open window and handle touchscreen*/ - #define LV_USE_NUTTX_CUSTOM_INIT 0 - - /*Driver for /dev/lcd*/ - #define LV_USE_NUTTX_LCD 0 - #if LV_USE_NUTTX_LCD - #define LV_NUTTX_LCD_BUFFER_COUNT 0 - #define LV_NUTTX_LCD_BUFFER_SIZE 60 - #endif - - /*Driver for /dev/input*/ - #define LV_USE_NUTTX_TOUCHSCREEN 0 - -#endif - -/*Driver for /dev/dri/card*/ -#define LV_USE_LINUX_DRM 0 - -/*Interface for TFT_eSPI*/ -#define LV_USE_TFT_ESPI 0 - -/*Driver for evdev input devices*/ -#define LV_USE_EVDEV 0 - -/*Driver for libinput input devices*/ -#define LV_USE_LIBINPUT 0 - -#if LV_USE_LIBINPUT - #define LV_LIBINPUT_BSD 0 - - /*Full keyboard support*/ - #define LV_LIBINPUT_XKB 0 - #if LV_LIBINPUT_XKB - /*"setxkbmap -query" can help find the right values for your keyboard*/ - #define LV_LIBINPUT_XKB_KEY_MAP { .rules = NULL, .model = "pc101", .layout = "us", .variant = NULL, .options = NULL } - #endif -#endif - -/*Drivers for LCD devices connected via SPI/parallel port*/ -#define LV_USE_ST7735 0 -#define LV_USE_ST7789 0 -#define LV_USE_ST7796 0 -#define LV_USE_ILI9341 0 - -#define LV_USE_GENERIC_MIPI (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341) - -/* LVGL Windows backend */ -#define LV_USE_WINDOWS 0 - -/*================== -* EXAMPLES -*==================*/ - -/*Enable the examples to be built with the library*/ -#define LV_BUILD_EXAMPLES 0 - -/*=================== - * DEMO USAGE - ====================*/ - -/*Show some widget. It might be required to increase `LV_MEM_SIZE` */ -#define LV_USE_DEMO_WIDGETS 0 - -/*Demonstrate the usage of encoder and keyboard*/ -#define LV_USE_DEMO_KEYPAD_AND_ENCODER 0 - -/*Benchmark your system*/ -#define LV_USE_DEMO_BENCHMARK 0 - -/*Render test for each primitives. Requires at least 480x272 display*/ -#define LV_USE_DEMO_RENDER 0 - -/*Stress test for LVGL*/ -#define LV_USE_DEMO_STRESS 0 - -/*Music player demo*/ -#define LV_USE_DEMO_MUSIC 0 -#if LV_USE_DEMO_MUSIC - #define LV_DEMO_MUSIC_SQUARE 0 - #define LV_DEMO_MUSIC_LANDSCAPE 0 - #define LV_DEMO_MUSIC_ROUND 0 - #define LV_DEMO_MUSIC_LARGE 0 - #define LV_DEMO_MUSIC_AUTO_PLAY 0 -#endif - -/*Flex layout demo*/ -#define LV_USE_DEMO_FLEX_LAYOUT 0 - -/*Smart-phone like multi-language demo*/ -#define LV_USE_DEMO_MULTILANG 0 - -/*Widget transformation demo*/ -#define LV_USE_DEMO_TRANSFORM 0 - -/*Demonstrate scroll settings*/ -#define LV_USE_DEMO_SCROLL 0 - -/*Vector graphic demo*/ -#define LV_USE_DEMO_VECTOR_GRAPHIC 0 -/*--END OF LV_CONF_H--*/ - -#endif /*LV_CONF_H*/ - -#endif /*End of "Content enable"*/ diff --git a/10-OBD-Display-2024/_archive/lvgl9_broken/scr_st77916.h b/10-OBD-Display-2024/_archive/lvgl9_broken/scr_st77916.h deleted file mode 100644 index 05e97bc..0000000 --- a/10-OBD-Display-2024/_archive/lvgl9_broken/scr_st77916.h +++ /dev/null @@ -1,446 +0,0 @@ -#ifndef _SCR_ST77916_H_ -#define _SCR_ST77916_H_ - -#include "pincfg.h" -#include -#include -#include - -#define SCREEN_RES_HOR 360 -#define SCREEN_RES_VER 360 - -static lv_color_t *disp_draw_buf; -static lv_draw_buf_t draw_buf; -static lv_fs_drv_t disp_drv; -static lv_indev_t *indev_touchpad; -static ESP_PanelBacklight *backlight = NULL; -static ESP_PanelLcd *lcd = NULL; -static ESP_PanelTouch *touch = NULL; - -#define USE_CUSTOM_INIT_CMD 0 // 是否用自定义的初始化代码 - -#if TOUCH_PIN_NUM_INT >= 0 - -IRAM_ATTR bool onTouchInterruptCallback(void *user_data) -{ - return false; -} - -#endif - -const esp_lcd_panel_vendor_init_cmd_t lcd_init_cmd[] = { - {0xF0, (uint8_t[]){0x08}, 1, 0}, - {0xF2, (uint8_t[]){0x08}, 1, 0}, - {0x9B, (uint8_t[]){0x51}, 1, 0}, - {0x86, (uint8_t[]){0x53}, 1, 0}, - {0xF2, (uint8_t[]){0x80}, 1, 0}, - {0xF0, (uint8_t[]){0x00}, 1, 0}, - {0xF0, (uint8_t[]){0x01}, 1, 0}, - {0xF1, (uint8_t[]){0x01}, 1, 0}, - {0xB0, (uint8_t[]){0x54}, 1, 0}, - {0xB1, (uint8_t[]){0x3F}, 1, 0}, - {0xB2, (uint8_t[]){0x2A}, 1, 0}, - {0xB4, (uint8_t[]){0x46}, 1, 0}, - {0xB5, (uint8_t[]){0x34}, 1, 0}, - {0xB6, (uint8_t[]){0xD5}, 1, 0}, - {0xB7, (uint8_t[]){0x30}, 1, 0}, - {0xBA, (uint8_t[]){0x00}, 1, 0}, - {0xBB, (uint8_t[]){0x08}, 1, 0}, - {0xBC, (uint8_t[]){0x08}, 1, 0}, - {0xBD, (uint8_t[]){0x00}, 1, 0}, - {0xC0, (uint8_t[]){0x80}, 1, 0}, - {0xC1, (uint8_t[]){0x10}, 1, 0}, - {0xC2, (uint8_t[]){0x37}, 1, 0}, - {0xC3, (uint8_t[]){0x80}, 1, 0}, - {0xC4, (uint8_t[]){0x10}, 1, 0}, - {0xC5, (uint8_t[]){0x37}, 1, 0}, - {0xC6, (uint8_t[]){0xA9}, 1, 0}, - {0xC7, (uint8_t[]){0x41}, 1, 0}, - {0xC8, (uint8_t[]){0x51}, 1, 0}, - {0xC9, (uint8_t[]){0xA9}, 1, 0}, - {0xCA, (uint8_t[]){0x41}, 1, 0}, - {0xCB, (uint8_t[]){0x51}, 1, 0}, - {0xD0, (uint8_t[]){0x91}, 1, 0}, - {0xD1, (uint8_t[]){0x68}, 1, 0}, - {0xD2, (uint8_t[]){0x69}, 1, 0}, - {0xF5, (uint8_t[]){0x00, 0xA5}, 2, 0}, - {0xDD, (uint8_t[]){0x3F}, 1, 0}, - {0xDE, (uint8_t[]){0x3F}, 1, 0}, - {0xF1, (uint8_t[]){0x10}, 1, 0}, - {0xF0, (uint8_t[]){0x00}, 1, 0}, - {0xF0, (uint8_t[]){0x02}, 1, 0}, - {0xE0, (uint8_t[]){0x70, 0x09, 0x12, 0x0C, 0x0B, 0x27, 0x38, 0x54, 0x4E, 0x19, 0x15, 0x15, 0x2C, 0x2F}, 14, 0}, - {0xE1, (uint8_t[]){0x70, 0x08, 0x11, 0x0C, 0x0B, 0x27, 0x38, 0x43, 0x4C, 0x18, 0x14, 0x14, 0x2B, 0x2D}, 14, 0}, - {0xF0, (uint8_t[]){0x10}, 1, 0}, - {0xF3, (uint8_t[]){0x10}, 1, 0}, - {0xE0, (uint8_t[]){0x08}, 1, 0}, - {0xE1, (uint8_t[]){0x00}, 1, 0}, - {0xE2, (uint8_t[]){0x00}, 1, 0}, - {0xE3, (uint8_t[]){0x00}, 1, 0}, - {0xE4, (uint8_t[]){0xE0}, 1, 0}, - {0xE5, (uint8_t[]){0x06}, 1, 0}, - {0xE6, (uint8_t[]){0x21}, 1, 0}, - {0xE7, (uint8_t[]){0x00}, 1, 0}, - {0xE8, (uint8_t[]){0x05}, 1, 0}, - {0xE9, (uint8_t[]){0x82}, 1, 0}, - {0xEA, (uint8_t[]){0xDF}, 1, 0}, - {0xEB, (uint8_t[]){0x89}, 1, 0}, - {0xEC, (uint8_t[]){0x20}, 1, 0}, - {0xED, (uint8_t[]){0x14}, 1, 0}, - {0xEE, (uint8_t[]){0xFF}, 1, 0}, - {0xEF, (uint8_t[]){0x00}, 1, 0}, - {0xF8, (uint8_t[]){0xFF}, 1, 0}, - {0xF9, (uint8_t[]){0x00}, 1, 0}, - {0xFA, (uint8_t[]){0x00}, 1, 0}, - {0xFB, (uint8_t[]){0x30}, 1, 0}, - {0xFC, (uint8_t[]){0x00}, 1, 0}, - {0xFD, (uint8_t[]){0x00}, 1, 0}, - {0xFE, (uint8_t[]){0x00}, 1, 0}, - {0xFF, (uint8_t[]){0x00}, 1, 0}, - {0x60, (uint8_t[]){0x42}, 1, 0}, - {0x61, (uint8_t[]){0xE0}, 1, 0}, - {0x62, (uint8_t[]){0x40}, 1, 0}, - {0x63, (uint8_t[]){0x40}, 1, 0}, - {0x64, (uint8_t[]){0x02}, 1, 0}, - {0x65, (uint8_t[]){0x00}, 1, 0}, - {0x66, (uint8_t[]){0x40}, 1, 0}, - {0x67, (uint8_t[]){0x03}, 1, 0}, - {0x68, (uint8_t[]){0x00}, 1, 0}, - {0x69, (uint8_t[]){0x00}, 1, 0}, - {0x6A, (uint8_t[]){0x00}, 1, 0}, - {0x6B, (uint8_t[]){0x00}, 1, 0}, - {0x70, (uint8_t[]){0x42}, 1, 0}, - {0x71, (uint8_t[]){0xE0}, 1, 0}, - {0x72, (uint8_t[]){0x40}, 1, 0}, - {0x73, (uint8_t[]){0x40}, 1, 0}, - {0x74, (uint8_t[]){0x02}, 1, 0}, - {0x75, (uint8_t[]){0x00}, 1, 0}, - {0x76, (uint8_t[]){0x40}, 1, 0}, - {0x77, (uint8_t[]){0x03}, 1, 0}, - {0x78, (uint8_t[]){0x00}, 1, 0}, - {0x79, (uint8_t[]){0x00}, 1, 0}, - {0x7A, (uint8_t[]){0x00}, 1, 0}, - {0x7B, (uint8_t[]){0x00}, 1, 0}, - {0x80, (uint8_t[]){0x48}, 1, 0}, - {0x81, (uint8_t[]){0x00}, 1, 0}, - {0x82, (uint8_t[]){0x05}, 1, 0}, - {0x83, (uint8_t[]){0x02}, 1, 0}, - {0x84, (uint8_t[]){0xDD}, 1, 0}, - {0x85, (uint8_t[]){0x00}, 1, 0}, - {0x86, (uint8_t[]){0x00}, 1, 0}, - {0x87, (uint8_t[]){0x00}, 1, 0}, - {0x88, (uint8_t[]){0x48}, 1, 0}, - {0x89, (uint8_t[]){0x00}, 1, 0}, - {0x8A, (uint8_t[]){0x07}, 1, 0}, - {0x8B, (uint8_t[]){0x02}, 1, 0}, - {0x8C, (uint8_t[]){0xDF}, 1, 0}, - {0x8D, (uint8_t[]){0x00}, 1, 0}, - {0x8E, (uint8_t[]){0x00}, 1, 0}, - {0x8F, (uint8_t[]){0x00}, 1, 0}, - {0x90, (uint8_t[]){0x48}, 1, 0}, - {0x91, (uint8_t[]){0x00}, 1, 0}, - {0x92, (uint8_t[]){0x09}, 1, 0}, - {0x93, (uint8_t[]){0x02}, 1, 0}, - {0x94, (uint8_t[]){0xE1}, 1, 0}, - {0x95, (uint8_t[]){0x00}, 1, 0}, - {0x96, (uint8_t[]){0x00}, 1, 0}, - {0x97, (uint8_t[]){0x00}, 1, 0}, - {0x98, (uint8_t[]){0x48}, 1, 0}, - {0x99, (uint8_t[]){0x00}, 1, 0}, - {0x9A, (uint8_t[]){0x0B}, 1, 0}, - {0x9B, (uint8_t[]){0x02}, 1, 0}, - {0x9C, (uint8_t[]){0xE3}, 1, 0}, - {0x9D, (uint8_t[]){0x00}, 1, 0}, - {0x9E, (uint8_t[]){0x00}, 1, 0}, - {0x9F, (uint8_t[]){0x00}, 1, 0}, - {0xA0, (uint8_t[]){0x48}, 1, 0}, - {0xA1, (uint8_t[]){0x00}, 1, 0}, - {0xA2, (uint8_t[]){0x04}, 1, 0}, - {0xA3, (uint8_t[]){0x02}, 1, 0}, - {0xA4, (uint8_t[]){0xDC}, 1, 0}, - {0xA5, (uint8_t[]){0x00}, 1, 0}, - {0xA6, (uint8_t[]){0x00}, 1, 0}, - {0xA7, (uint8_t[]){0x00}, 1, 0}, - {0xA8, (uint8_t[]){0x48}, 1, 0}, - {0xA9, (uint8_t[]){0x00}, 1, 0}, - {0xAA, (uint8_t[]){0x06}, 1, 0}, - {0xAB, (uint8_t[]){0x02}, 1, 0}, - {0xAC, (uint8_t[]){0xDE}, 1, 0}, - {0xAD, (uint8_t[]){0x00}, 1, 0}, - {0xAE, (uint8_t[]){0x00}, 1, 0}, - {0xAF, (uint8_t[]){0x00}, 1, 0}, - {0xB0, (uint8_t[]){0x48}, 1, 0}, - {0xB1, (uint8_t[]){0x00}, 1, 0}, - {0xB2, (uint8_t[]){0x08}, 1, 0}, - {0xB3, (uint8_t[]){0x02}, 1, 0}, - {0xB4, (uint8_t[]){0xE0}, 1, 0}, - {0xB5, (uint8_t[]){0x00}, 1, 0}, - {0xB6, (uint8_t[]){0x00}, 1, 0}, - {0xB7, (uint8_t[]){0x00}, 1, 0}, - {0xB8, (uint8_t[]){0x48}, 1, 0}, - {0xB9, (uint8_t[]){0x00}, 1, 0}, - {0xBA, (uint8_t[]){0x0A}, 1, 0}, - {0xBB, (uint8_t[]){0x02}, 1, 0}, - {0xBC, (uint8_t[]){0xE2}, 1, 0}, - {0xBD, (uint8_t[]){0x00}, 1, 0}, - {0xBE, (uint8_t[]){0x00}, 1, 0}, - {0xBF, (uint8_t[]){0x00}, 1, 0}, - {0xC0, (uint8_t[]){0x12}, 1, 0}, - {0xC1, (uint8_t[]){0xAA}, 1, 0}, - {0xC2, (uint8_t[]){0x65}, 1, 0}, - {0xC3, (uint8_t[]){0x74}, 1, 0}, - {0xC4, (uint8_t[]){0x47}, 1, 0}, - {0xC5, (uint8_t[]){0x56}, 1, 0}, - {0xC6, (uint8_t[]){0x00}, 1, 0}, - {0xC7, (uint8_t[]){0x88}, 1, 0}, - {0xC8, (uint8_t[]){0x99}, 1, 0}, - {0xC9, (uint8_t[]){0x33}, 1, 0}, - {0xD0, (uint8_t[]){0x21}, 1, 0}, - {0xD1, (uint8_t[]){0xAA}, 1, 0}, - {0xD2, (uint8_t[]){0x65}, 1, 0}, - {0xD3, (uint8_t[]){0x74}, 1, 0}, - {0xD4, (uint8_t[]){0x47}, 1, 0}, - {0xD5, (uint8_t[]){0x56}, 1, 0}, - {0xD6, (uint8_t[]){0x00}, 1, 0}, - {0xD7, (uint8_t[]){0x88}, 1, 0}, - {0xD8, (uint8_t[]){0x99}, 1, 0}, - {0xD9, (uint8_t[]){0x33}, 1, 0}, - {0xF3, (uint8_t[]){0x01}, 1, 0}, - {0xF0, (uint8_t[]){0x00}, 1, 0}, - {0xF0, (uint8_t[]){0x01}, 1, 0}, - {0xF1, (uint8_t[]){0x01}, 1, 0}, - {0xA0, (uint8_t[]){0x0B}, 1, 0}, - {0xA3, (uint8_t[]){0x2A}, 1, 0}, - {0xA5, (uint8_t[]){0xC3}, 1, 1}, - {0xA3, (uint8_t[]){0x2B}, 1, 0}, - {0xA5, (uint8_t[]){0xC3}, 1, 1}, - {0xA3, (uint8_t[]){0x2C}, 1, 0}, - {0xA5, (uint8_t[]){0xC3}, 1, 1}, - {0xA3, (uint8_t[]){0x2D}, 1, 0}, - {0xA5, (uint8_t[]){0xC3}, 1, 1}, - {0xA3, (uint8_t[]){0x2E}, 1, 0}, - {0xA5, (uint8_t[]){0xC3}, 1, 1}, - {0xA3, (uint8_t[]){0x2F}, 1, 0}, - {0xA5, (uint8_t[]){0xC3}, 1, 1}, - {0xA3, (uint8_t[]){0x30}, 1, 0}, - {0xA5, (uint8_t[]){0xC3}, 1, 1}, - {0xA3, (uint8_t[]){0x31}, 1, 0}, - {0xA5, (uint8_t[]){0xC3}, 1, 1}, - {0xA3, (uint8_t[]){0x32}, 1, 0}, - {0xA5, (uint8_t[]){0xC3}, 1, 1}, - {0xA3, (uint8_t[]){0x33}, 1, 0}, - {0xA5, (uint8_t[]){0xC3}, 1, 1}, - {0xA0, (uint8_t[]){0x09}, 1, 0}, - {0xF1, (uint8_t[]){0x10}, 1, 0}, - {0xF0, (uint8_t[]){0x00}, 1, 0}, - {0x2A, (uint8_t[]){0x00, 0x00, 0x01, 0x67}, 4, 0}, - {0x2B, (uint8_t[]){0x01, 0x68, 0x01, 0x68}, 4, 0}, - {0x4D, (uint8_t[]){0x00}, 1, 0}, - {0x4E, (uint8_t[]){0x00}, 1, 0}, - {0x4F, (uint8_t[]){0x00}, 1, 0}, - {0x4C, (uint8_t[]){0x01}, 1, 10}, - {0x4C, (uint8_t[]){0x00}, 1, 0}, - {0x2A, (uint8_t[]){0x00, 0x00, 0x01, 0x67}, 4, 0}, - {0x2B, (uint8_t[]){0x00, 0x00, 0x01, 0x67}, 4, 0}, - {0x21, (uint8_t[]){0x00}, 1, 0}, - //{0x3A, (uint8_t[]){0x55}, 1, 0}, // color=16 - {0x11, (uint8_t[]){0x00}, 1, 120}, - {0x29, (uint8_t[]){0x00}, 1, 0}, -}; - -#define TFT_SPI_FREQ_HZ (50 * 1000 * 1000) - -// static void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) -void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) -lv_display_flush_cb_t flush_cbstatic void my_disp_flush(lv_display_t *disp, const lv_area_t *area, lv_color_t *color_p){ - ESP_PanelLcd *lcd = (ESP_PanelLcd *)disp->user_data; - const int offsetx1 = area->x1; - const int offsetx2 = area->x2; - const int offsety1 = area->y1; - const int offsety2 = area->y2; - lcd->drawBitmap(offsetx1, offsety1, offsetx2 - offsetx1 + 1, offsety2 - offsety1 + 1, (const uint8_t *)color_p); -} - -IRAM_ATTR bool onRefreshFinishCallback(void *user_data) -{ - lv_display_t *drv = (lv_display_t *)user_data; - lv_disp_flush_ready(drv); - return false; -} - -void setRotation(uint8_t rot) -{ - if (rot > 3) - return; - if (lcd == NULL || touch == NULL) - return; - - switch (rot) - { - case 1: // 顺时针90度 - lcd->swapXY(true); - lcd->mirrorX(true); - lcd->mirrorY(false); - touch->swapXY(true); - touch->mirrorX(true); - touch->mirrorY(false); - break; - case 2: - lcd->swapXY(false); - lcd->mirrorX(true); - lcd->mirrorY(true); - touch->swapXY(false); - touch->mirrorX(true); - touch->mirrorY(true); - break; - case 3: - lcd->swapXY(true); - lcd->mirrorX(false); - lcd->mirrorY(true); - touch->swapXY(true); - touch->mirrorX(false); - touch->mirrorY(true); - break; - default: - lcd->swapXY(false); - lcd->mirrorX(false); - lcd->mirrorY(false); - touch->swapXY(false); - touch->mirrorX(false); - touch->mirrorY(false); - break; - } -} - -void screen_switch(bool on) -{ - if (NULL == backlight) - return; - if (on) - backlight->on(); - else - backlight->off(); -} - -// 输入值为0-100 -void set_brightness(uint8_t bri) -{ - if (NULL == backlight) - return; - backlight->setBrightness(bri); -} - -// static void touchpad_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data) -// { -// ESP_PanelTouch *tp = (ESP_PanelTouch *)indev_drv->user_data; -// ESP_PanelTouchPoint point; - -// int read_touch_result = tp->readPoints(&point, 1); -// if (read_touch_result > 0) -// { -// data->point.x = point.x; -// data->point.y = point.y; -// data->state = LV_INDEV_STATE_PRESSED; -// } -// else -// { -// data->state = LV_INDEV_STATE_RELEASED; -// } -// } - -// static lv_indev_t *indev_init(ESP_PanelTouch *tp) -// { -// ESP_PANEL_CHECK_FALSE_RET(tp != nullptr, nullptr, "Invalid touch device"); -// ESP_PANEL_CHECK_FALSE_RET(tp->getHandle() != nullptr, nullptr, "Touch device is not initialized"); -// static lv_indev_drv_tt indev_drv_tp; -// lv_fs_drv_init(&indev_drv_tp); -// indev_drv_tp.type = LV_INDEV_TYPE_POINTER; -// // indev_drv_tp.read_cb = touchpad_read; -// indev_drv_tp.user_data = (void *)tp; -// return lv_fs_drv_register(&indev_drv_tp); -// } - -void scr_lvgl_init() -{ - ledc_timer_config_t ledc_timer = { - .speed_mode = LEDC_LOW_SPEED_MODE, - .duty_resolution = LEDC_TIMER_13_BIT, - .timer_num = LEDC_TIMER_0, - .freq_hz = 5000, - .clk_cfg = LEDC_AUTO_CLK}; - ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer)); - - ledc_channel_config_t ledc_channel = { - .gpio_num = (TFT_BLK), - .speed_mode = LEDC_LOW_SPEED_MODE, - .channel = LEDC_CHANNEL_0, - .intr_type = LEDC_INTR_DISABLE, - .timer_sel = LEDC_TIMER_0, - .duty = 0, - .hpoint = 0}; - - ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel)); - - backlight = new ESP_PanelBacklight(ledc_timer, ledc_channel); - backlight->begin(); - backlight->off(); - - ESP_PanelBus_I2C *touch_bus = new ESP_PanelBus_I2C(TOUCH_PIN_NUM_I2C_SCL, TOUCH_PIN_NUM_I2C_SDA, ESP_LCD_TOUCH_IO_I2C_CST816S_CONFIG()); - touch_bus->configI2cFreqHz(400000); - touch_bus->begin(); - - touch = new ESP_PanelTouch_CST816S(touch_bus, SCREEN_RES_HOR, SCREEN_RES_VER, TOUCH_PIN_NUM_RST, TOUCH_PIN_NUM_INT); - - touch->init(); - touch->begin(); - -#if TOUCH_PIN_NUM_INT >= 0 - touch->attachInterruptCallback(onTouchInterruptCallback, NULL); -#endif - - ESP_PanelBus_QSPI *panel_bus = new ESP_PanelBus_QSPI(TFT_CS, TFT_SCK, TFT_SDA0, TFT_SDA1, TFT_SDA2, TFT_SDA3); - panel_bus->configQspiFreqHz(TFT_SPI_FREQ_HZ); - panel_bus->begin(); - - lcd = new ESP_PanelLcd_ST77916(panel_bus, 16, TFT_RST); - // 注意,初始化代码的设置必须在INIT之前 - // lcd->configVendorCommands(lcd_init_cmd, sizeof(lcd_init_cmd) / sizeof(lcd_init_cmd[0])); - lcd->init(); - lcd->reset(); - lcd->begin(); - - lcd->invertColor(true); - // setRotation(0); //设置屏幕方向 - lcd->displayOn(); - - screen_switch(true); - backlight->setBrightness(100); // 设置亮度 - - size_t lv_cache_rows = 72; - - disp_draw_buf = (lv_color_t *)heap_caps_malloc(lv_cache_rows * SCREEN_RES_HOR * 2, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); - lv_init(); - // lv_disp_draw_buf_init(&draw_buf, disp_draw_buf, NULL, SCREEN_RES_HOR * lv_cache_rows); - lv_draw_buf_init(&draw_buf, SCREEN_RES_HOR, SCREEN_RES_VER, LV_COLOR_FORMAT_RGB565, 0, disp_draw_buf, SCREEN_RES_HOR * lv_cache_rows); - - // lv_disp_drv_init(&disp_drv); - // disp_drv.hor_res = SCREEN_RES_HOR; - // disp_drv.ver_res = SCREEN_RES_VER; - // disp_drv.flush_cb = my_disp_flush; - // disp_drv.draw_buf = &draw_buf; - // disp_drv.user_data = (void *)lcd; - // lv_disp_t *disp = lv_disp_drv_register(&disp_drv); - ///// - lv_display_t * display = lv_display_create(SCREEN_RES_HOR, SCREEN_RES_VER); - lv_display_set_flush_cb(display, my_disp_flush); - lv_display_set_buffers(display, draw_buf, null, SCREEN_RES_HOR * lv_cache_rows, LV_DISPLAY_RENDER_MODE_PARTIAL); - ///// - - if (lcd->getBus()->getType() != ESP_PANEL_BUS_TYPE_RGB) - { - lcd->attachRefreshFinishCallback(onRefreshFinishCallback, (void *)disp->driver); - } - // indev_touchpad = indev_init(touch); -} - -#endif \ No newline at end of file diff --git a/10-OBD-Display-2024/display_gif_embedded/include/pincfg.h b/10-OBD-Display-2024/display_gif_embedded/include/pincfg.h deleted file mode 100644 index 2ab5a5a..0000000 --- a/10-OBD-Display-2024/display_gif_embedded/include/pincfg.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef _PINCFG_H_ -#define _PINCFG_H_ - -#define TFT_BLK 15 - -#define TFT_RST 47 -#define TFT_CS 10 -#define TFT_SCK 9 -#define TFT_SDA0 11 -#define TFT_SDA1 12 -#define TFT_SDA2 13 -#define TFT_SDA3 14 - -#define BTN_PIN 0 - -#define TOUCH_PIN_NUM_I2C_SCL 8 -#define TOUCH_PIN_NUM_I2C_SDA 7 -#define TOUCH_PIN_NUM_INT 41 -#define TOUCH_PIN_NUM_RST 40 - -#define SD_MMC_D0_PIN 2 -#define SD_MMC_D1_PIN 1 -#define SD_MMC_D2_PIN 6 -#define SD_MMC_D3_PIN 5 -#define SD_MMC_CLK_PIN 3 -#define SD_MMC_CMD_PIN 4 - -#define AUDIO_I2S_MCK_IO -1 // MCK -#define AUDIO_I2S_BCK_IO 18 // BCK -#define AUDIO_I2S_WS_IO 16 // LCK -#define AUDIO_I2S_DO_IO 17 // DIN -#define AUDIO_MUTE_PIN 48 // 低电平静音 - -#define MIC_I2S_WS 45 -#define MIC_I2S_SD 46 -#define MIC_I2S_SCK 42 - -#endif \ No newline at end of file diff --git a/10-OBD-Display-2024/display_gif_embedded/platformio.ini b/10-OBD-Display-2024/display_gif_embedded/platformio.ini index 87f2318..96e61f3 100644 --- a/10-OBD-Display-2024/display_gif_embedded/platformio.ini +++ b/10-OBD-Display-2024/display_gif_embedded/platformio.ini @@ -1,34 +1,12 @@ -; JC3636W518 — ESP32-S3R8, 16 MB QIO flash, 8 MB OPI PSRAM, 360x360 ST77916 QSPI + CST816S -; Settings mirror the vendor Arduino IDE setup (2-Program Example/Demo_Arduino/docs/Arduino set up.png) - -[env:jc3636w518] -; pioarduino = Arduino core 3.0.5 (ESP32_Display_Panel 0.1.4 needs core 3.x) -platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.05/platform-espressif32.zip -board = esp32-s3-devkitc-1 -framework = arduino - -board_build.arduino.memory_type = qio_opi -board_build.flash_mode = qio -board_upload.flash_size = 16MB -; GIF compiled into firmware -> 3.4 MB, too big for huge_app (3 MB); 6.25 MB app slots -board_build.partitions = default_16MB.csv - -; optimise for speed instead of size (faster GIF decoding) -build_unflags = -Os -build_flags = - -O2 - -DBOARD_HAS_PSRAM - -DARDUINO_USB_CDC_ON_BOOT=1 - ; LVGL (also when compiled as a library) picks up include/lv_conf.h of this project - -DLV_CONF_INCLUDE_SIMPLE - -Iinclude - -; vendor-bundled libraries: ESP32_Display_Panel 0.1.4, ESP32_IO_Expander 0.0.2 -; (the vendor folder also has lvgl 8.3.11 - ignored here, this project uses LVGL 9 from lib_deps) -lib_extra_dirs = ../../2-Program Example/Demo_Arduino/library -lib_deps = lvgl/lvgl@9.6.0 - -upload_port = COM21 -monitor_port = COM21 -monitor_speed = 115200 -monitor_filters = esp32_exception_decoder +; GIF compiled into the firmware — JC3636W518, common settings in shared/jc3636w518.ini + +[platformio] +extra_configs = ../../shared/jc3636w518.ini + +[shared] +dir = ../../shared + +[env:jc3636w518] +extends = jc3636w518 +; GIF compiled into firmware -> 3.5 MB, too big for huge_app (3 MB); 6.25 MB app slots +board_build.partitions = default_16MB.csv diff --git a/10-OBD-Display-2024/display_gif_embedded/src/main.cpp b/10-OBD-Display-2024/display_gif_embedded/src/main.cpp index 98a696d..83a7356 100644 --- a/10-OBD-Display-2024/display_gif_embedded/src/main.cpp +++ b/10-OBD-Display-2024/display_gif_embedded/src/main.cpp @@ -1,231 +1,188 @@ -#include -#include "scr_st77916.h" -#include "SD_MMC.h" - - -// https://randomnerdtutorials.com/esp32-client-server-wi-fi/ -#include -#include - -const char* ssid = "ESP32-Access-Point"; -const char* password = "123456789"; - -String httpGETRequest(const char* serverName); - -// FPS measurement: counts screen refreshes that actually rendered something (= one GIF frame here) -static volatile uint32_t refr_count = 0; -static volatile uint32_t refr_time_ms = 0; -static uint32_t busy_us = 0; // time spent inside lv_timer_handler() - -static void refr_event_cb(lv_event_t* e) { - static uint32_t refr_start_ms = 0; - static bool rendered = false; - switch (lv_event_get_code(e)) { - case LV_EVENT_REFR_START: - refr_start_ms = millis(); - rendered = false; - break; - case LV_EVENT_RENDER_START: - rendered = true; - break; - case LV_EVENT_REFR_READY: - if (rendered) { - refr_count++; - refr_time_ms += millis() - refr_start_ms; - } - break; - default: - break; - } -} - -void print_fps() { - static uint32_t last_ms = 0; - uint32_t now = millis(); - if (now - last_ms < 1000) return; - // decode = busy time not spent refreshing the screen (mostly GIF decoding) - Serial.printf("FPS: %.1f avg refresh: %lu ms avg decode: %lu ms\n", refr_count * 1000.0f / (now - last_ms), - refr_count ? refr_time_ms / refr_count : 0, - refr_count ? (busy_us / 1000 - refr_time_ms) / refr_count : 0); - refr_count = 0; - refr_time_ms = 0; - busy_us = 0; - last_ms = now; -} - - -void my_print(const char* buf) { - Serial.println(buf); // Print logs to the serial monitor -} - -void display_animation() { - lv_obj_t* img; - - LV_IMAGE_DECLARE(loligod); - - img = lv_gif_create(lv_screen_active()); - - Serial.print("Available Heap before: "); - Serial.println(esp_get_free_heap_size()); - - lv_mem_monitor_t mem_mon; - lv_mem_monitor(&mem_mon); - printf("Free memory: %d bytes\n", mem_mon.free_size); - - // lv_fs_file_t file; - // if (lv_fs_open(&file, "A:wallpaper.gif", LV_FS_MODE_RD) == LV_FS_RES_OK) { - // lv_fs_close(&file); // File exists, proceed with loading - // lv_gif_set_src(img, "A:wallpaper.gif"); - // Serial.println("GIF Loaded Successfully"); - // } else { - // Serial.println("Failed to Load GIF: File not found or inaccessible"); - // } - lv_gif_set_src(img, &loligod); - - Serial.print("Available Heap after: "); - Serial.println(esp_get_free_heap_size()); - - lv_mem_monitor(&mem_mon); - printf("Free memory: %d bytes\n", mem_mon.free_size); - - lv_obj_align(img, LV_ALIGN_CENTER, 0, 0); -} - -lv_obj_t* label1; - -void display_text() { - // Create a style for the text - static lv_style_t style_text; - lv_style_init(&style_text); - - // Set the text color to white - lv_style_set_text_color(&style_text, lv_color_white()); - - // // Set the shadow color to black (this will simulate the outline) - // lv_style_set_shadow_color(&style_text, lv_color_black()); - - // // Set the shadow width to create the outline effect - // lv_style_set_shadow_width(&style_text, 2); // Adjust for desired outline thickness - - // // Set the shadow offset to 0 so it surrounds the text evenly - // lv_style_set_shadow_ofs_x(&style_text, 0); - // lv_style_set_shadow_ofs_y(&style_text, 0); - - label1 = lv_label_create(lv_screen_active()); - - // Apply the style to the label - lv_obj_add_style(label1, &style_text, LV_PART_MAIN); - - // lv_style_set_text_font(&label1, &Montserrat); /*Set a larger font*/ - lv_label_set_long_mode(label1, LV_LABEL_LONG_WRAP); /*Break the long lines*/ - lv_label_set_text(label1, "0"); - lv_obj_set_width(label1, 150); /*Set smaller width to make the lines wrap*/ - lv_obj_set_style_text_align(label1, LV_TEXT_ALIGN_CENTER, 0); - lv_obj_align(label1, LV_ALIGN_CENTER, 0, 0); - // lv_obj_set_style_transform_zoom(label1, 256 * 2, 0); // Zoom: 256 = 1x scale (default) -} - -void connectToWifi() { - WiFi.begin(ssid, password); - Serial.println("Connecting"); - if (WiFi.status() != WL_CONNECTED) { - Serial.println("Wifi not connected"); - return; - } - int timeout = 0; - while (WiFi.status() != WL_CONNECTED && timeout <= 20) { - timeout++; - delay(500); - Serial.print("."); - } - Serial.println(""); - Serial.print("Connected to WiFi network with IP Address: "); - Serial.println(WiFi.localIP()); -} - -void setup() { - delay(200); - Serial.begin(115200); - scr_lvgl_init(); - lv_display_add_event_cb(lv_display_get_default(), refr_event_cb, LV_EVENT_ALL, NULL); - - //lv_log_register_print_cb(my_print); // Register print function for LVGL logs - - // Get the active screen (root object for the display) - lv_obj_t* screen = lv_screen_active(); - - // Set the background color of the entire screen to black - lv_obj_set_style_bg_color(screen, lv_color_black(), 0); // 0 is the part ID for the main part - lv_obj_set_style_bg_opa(screen, LV_OPA_COVER, 0); // Set opacity to fully opaque - - // GIF is compiled into the firmware, so start it before (and independent of) the SD card - display_animation(); - - // Configure the SDMMC host - SD_MMC.setPins(SD_MMC_CLK_PIN, SD_MMC_CMD_PIN, SD_MMC_D0_PIN, SD_MMC_D1_PIN, SD_MMC_D2_PIN, SD_MMC_D3_PIN); - - if (!SD_MMC.begin()) { - Serial.println("Card Mount Failed"); - return; - } - - uint8_t cardType = SD_MMC.cardType(); - if (cardType == CARD_NONE) { - Serial.println("No SD card attached"); - return; - } - - Serial.println("SD Card initialized successfully."); - - //connectToWifi(); - - //display_text(); -} - -void loop() { - uint32_t t0 = micros(); - lv_timer_handler(); - busy_us += micros() - t0; - vTaskDelay(1); - print_fps(); - - - // if (WiFi.status() == WL_CONNECTED) { - // String speed = httpGETRequest("http://192.168.4.1/speed"); - - // Serial.print("Speed: "); - // Serial.println(speed); - - // lv_label_set_text(label1, speed.c_str()); - // } else { - // Serial.println("WiFi Disconnected"); - // connectToWifi(); - // } -} - - -String httpGETRequest(const char* serverName) { - WiFiClient client; - HTTPClient http; - - // Your Domain name with URL path or IP address with path - http.begin(client, serverName); - - // Send HTTP POST request - int httpResponseCode = http.GET(); - - String payload = "--"; - - if (httpResponseCode > 0) { - Serial.print("HTTP Response code: "); - Serial.println(httpResponseCode); - payload = http.getString(); - } else { - Serial.print("Error code: "); - Serial.println(httpResponseCode); - } - // Free resources - http.end(); - - return payload; +#include +#include "jc3636w518.h" +#include "perf_monitor.h" +#include "SD_MMC.h" + + +// https://randomnerdtutorials.com/esp32-client-server-wi-fi/ +#include +#include + +const char* ssid = "ESP32-Access-Point"; +const char* password = "123456789"; + +String httpGETRequest(const char* serverName); + +void my_print(const char* buf) { + Serial.println(buf); // Print logs to the serial monitor +} + +void display_animation() { + lv_obj_t* img; + + LV_IMAGE_DECLARE(loligod); + + img = lv_gif_create(lv_screen_active()); + + Serial.print("Available Heap before: "); + Serial.println(esp_get_free_heap_size()); + + lv_mem_monitor_t mem_mon; + lv_mem_monitor(&mem_mon); + printf("Free memory: %d bytes\n", mem_mon.free_size); + + // lv_fs_file_t file; + // if (lv_fs_open(&file, "A:wallpaper.gif", LV_FS_MODE_RD) == LV_FS_RES_OK) { + // lv_fs_close(&file); // File exists, proceed with loading + // lv_gif_set_src(img, "A:wallpaper.gif"); + // Serial.println("GIF Loaded Successfully"); + // } else { + // Serial.println("Failed to Load GIF: File not found or inaccessible"); + // } + lv_gif_set_src(img, &loligod); + + Serial.print("Available Heap after: "); + Serial.println(esp_get_free_heap_size()); + + lv_mem_monitor(&mem_mon); + printf("Free memory: %d bytes\n", mem_mon.free_size); + + lv_obj_align(img, LV_ALIGN_CENTER, 0, 0); +} + +lv_obj_t* label1; + +void display_text() { + // Create a style for the text + static lv_style_t style_text; + lv_style_init(&style_text); + + // Set the text color to white + lv_style_set_text_color(&style_text, lv_color_white()); + + // // Set the shadow color to black (this will simulate the outline) + // lv_style_set_shadow_color(&style_text, lv_color_black()); + + // // Set the shadow width to create the outline effect + // lv_style_set_shadow_width(&style_text, 2); // Adjust for desired outline thickness + + // // Set the shadow offset to 0 so it surrounds the text evenly + // lv_style_set_shadow_ofs_x(&style_text, 0); + // lv_style_set_shadow_ofs_y(&style_text, 0); + + label1 = lv_label_create(lv_screen_active()); + + // Apply the style to the label + lv_obj_add_style(label1, &style_text, LV_PART_MAIN); + + // lv_style_set_text_font(&label1, &Montserrat); /*Set a larger font*/ + lv_label_set_long_mode(label1, LV_LABEL_LONG_WRAP); /*Break the long lines*/ + lv_label_set_text(label1, "0"); + lv_obj_set_width(label1, 150); /*Set smaller width to make the lines wrap*/ + lv_obj_set_style_text_align(label1, LV_TEXT_ALIGN_CENTER, 0); + lv_obj_align(label1, LV_ALIGN_CENTER, 0, 0); + // lv_obj_set_style_transform_zoom(label1, 256 * 2, 0); // Zoom: 256 = 1x scale (default) +} + +void connectToWifi() { + WiFi.begin(ssid, password); + Serial.println("Connecting"); + if (WiFi.status() != WL_CONNECTED) { + Serial.println("Wifi not connected"); + return; + } + int timeout = 0; + while (WiFi.status() != WL_CONNECTED && timeout <= 20) { + timeout++; + delay(500); + Serial.print("."); + } + Serial.println(""); + Serial.print("Connected to WiFi network with IP Address: "); + Serial.println(WiFi.localIP()); +} + +void setup() { + delay(200); + Serial.begin(115200); + lv_display_t* disp = scr_lvgl_init(); + perf_monitor_begin(disp); + + //lv_log_register_print_cb(my_print); // Register print function for LVGL logs + + // Get the active screen (root object for the display) + lv_obj_t* screen = lv_screen_active(); + + // Set the background color of the entire screen to black + lv_obj_set_style_bg_color(screen, lv_color_black(), 0); // 0 is the part ID for the main part + lv_obj_set_style_bg_opa(screen, LV_OPA_COVER, 0); // Set opacity to fully opaque + + // GIF is compiled into the firmware, so start it before (and independent of) the SD card + display_animation(); + + // Configure the SDMMC host + SD_MMC.setPins(SD_MMC_CLK_PIN, SD_MMC_CMD_PIN, SD_MMC_D0_PIN, SD_MMC_D1_PIN, SD_MMC_D2_PIN, SD_MMC_D3_PIN); + + if (!SD_MMC.begin()) { + Serial.println("Card Mount Failed"); + return; + } + + uint8_t cardType = SD_MMC.cardType(); + if (cardType == CARD_NONE) { + Serial.println("No SD card attached"); + return; + } + + Serial.println("SD Card initialized successfully."); + + //connectToWifi(); + + //display_text(); +} + +void loop() { + perf_timer_handler(); + vTaskDelay(1); + perf_monitor_print(); + + + // if (WiFi.status() == WL_CONNECTED) { + // String speed = httpGETRequest("http://192.168.4.1/speed"); + + // Serial.print("Speed: "); + // Serial.println(speed); + + // lv_label_set_text(label1, speed.c_str()); + // } else { + // Serial.println("WiFi Disconnected"); + // connectToWifi(); + // } +} + + +String httpGETRequest(const char* serverName) { + WiFiClient client; + HTTPClient http; + + // Your Domain name with URL path or IP address with path + http.begin(client, serverName); + + // Send HTTP POST request + int httpResponseCode = http.GET(); + + String payload = "--"; + + if (httpResponseCode > 0) { + Serial.print("HTTP Response code: "); + Serial.println(httpResponseCode); + payload = http.getString(); + } else { + Serial.print("Error code: "); + Serial.println(httpResponseCode); + } + // Free resources + http.end(); + + return payload; } \ No newline at end of file diff --git a/10-OBD-Display-2024/display_gif_embedded/include/lv_conf.h b/shared/include/lv_conf.h similarity index 100% rename from 10-OBD-Display-2024/display_gif_embedded/include/lv_conf.h rename to shared/include/lv_conf.h diff --git a/shared/jc3636w518.ini b/shared/jc3636w518.ini new file mode 100644 index 0000000..561f0f8 --- /dev/null +++ b/shared/jc3636w518.ini @@ -0,0 +1,43 @@ +; Shared PlatformIO settings for all JC3636W518 projects +; (ESP32-S3R8, 16 MB QIO flash, 8 MB OPI PSRAM, 360x360 ST77916 QSPI + CST816S). +; +; Use from a project's platformio.ini: +; [platformio] +; extra_configs = /jc3636w518.ini +; [shared] +; dir = +; [env:jc3636w518] +; extends = jc3636w518 + +[jc3636w518] +; pioarduino = Arduino core 3.0.5 (ESP32_Display_Panel 0.1.4 needs core 3.x) +platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.05/platform-espressif32.zip +board = esp32-s3-devkitc-1 +framework = arduino + +board_build.arduino.memory_type = qio_opi +board_build.flash_mode = qio +board_upload.flash_size = 16MB +board_build.partitions = huge_app.csv + +; optimise for speed instead of size +build_unflags = -Os +build_flags = + -O2 + -DBOARD_HAS_PSRAM + -DARDUINO_USB_CDC_ON_BOOT=1 + ; LVGL (also when compiled as a library) uses shared/include/lv_conf.h + -DLV_CONF_INCLUDE_SIMPLE + -I${shared.dir}/include + +; shared/lib: JC3636W518 board library +; vendor folder: ESP32_Display_Panel 0.1.4, ESP32_IO_Expander 0.0.2 (its lvgl 8.3.11 is not used) +lib_extra_dirs = + ${shared.dir}/lib + ${shared.dir}/../2-Program Example/Demo_Arduino/library +lib_deps = lvgl/lvgl@9.6.0 + +upload_port = COM21 +monitor_port = COM21 +monitor_speed = 115200 +monitor_filters = esp32_exception_decoder diff --git a/shared/lib/JC3636W518/library.json b/shared/lib/JC3636W518/library.json new file mode 100644 index 0000000..d9cee0c --- /dev/null +++ b/shared/lib/JC3636W518/library.json @@ -0,0 +1,7 @@ +{ + "name": "JC3636W518", + "version": "1.0.0", + "description": "Board support for the JC3636W518 (ESP32-S3, ST77916 360x360 QSPI LCD, CST816S touch) with LVGL 9 glue and a performance monitor", + "frameworks": "arduino", + "platforms": "espressif32" +} diff --git a/10-OBD-Display-2024/display_gif_embedded/include/scr_st77916.h b/shared/lib/JC3636W518/src/jc3636w518.cpp similarity index 91% rename from 10-OBD-Display-2024/display_gif_embedded/include/scr_st77916.h rename to shared/lib/JC3636W518/src/jc3636w518.cpp index bbfd0a8..3ecc44a 100644 --- a/10-OBD-Display-2024/display_gif_embedded/include/scr_st77916.h +++ b/shared/lib/JC3636W518/src/jc3636w518.cpp @@ -1,442 +1,439 @@ -#ifndef _SCR_ST77916_H_ -#define _SCR_ST77916_H_ - -#include "pincfg.h" -#include -#include -#include - -#define SCREEN_RES_HOR 360 -#define SCREEN_RES_VER 360 - -static uint8_t *disp_draw_buf; -static uint8_t *disp_draw_buf2; // second buffer: LVGL renders into one while the other is sent to the LCD -static lv_display_t *disp = NULL; -static lv_indev_t *indev_touchpad; -static ESP_PanelBacklight *backlight = NULL; -static ESP_PanelLcd *lcd = NULL; -static ESP_PanelTouch *touch = NULL; - -#define USE_CUSTOM_INIT_CMD 0 // 是否用自定义的初始化代码 - -#if TOUCH_PIN_NUM_INT >= 0 - -IRAM_ATTR bool onTouchInterruptCallback(void *user_data) -{ - return false; -} - -#endif - -const esp_lcd_panel_vendor_init_cmd_t lcd_init_cmd[] = { - {0xF0, (uint8_t[]){0x08}, 1, 0}, - {0xF2, (uint8_t[]){0x08}, 1, 0}, - {0x9B, (uint8_t[]){0x51}, 1, 0}, - {0x86, (uint8_t[]){0x53}, 1, 0}, - {0xF2, (uint8_t[]){0x80}, 1, 0}, - {0xF0, (uint8_t[]){0x00}, 1, 0}, - {0xF0, (uint8_t[]){0x01}, 1, 0}, - {0xF1, (uint8_t[]){0x01}, 1, 0}, - {0xB0, (uint8_t[]){0x54}, 1, 0}, - {0xB1, (uint8_t[]){0x3F}, 1, 0}, - {0xB2, (uint8_t[]){0x2A}, 1, 0}, - {0xB4, (uint8_t[]){0x46}, 1, 0}, - {0xB5, (uint8_t[]){0x34}, 1, 0}, - {0xB6, (uint8_t[]){0xD5}, 1, 0}, - {0xB7, (uint8_t[]){0x30}, 1, 0}, - {0xBA, (uint8_t[]){0x00}, 1, 0}, - {0xBB, (uint8_t[]){0x08}, 1, 0}, - {0xBC, (uint8_t[]){0x08}, 1, 0}, - {0xBD, (uint8_t[]){0x00}, 1, 0}, - {0xC0, (uint8_t[]){0x80}, 1, 0}, - {0xC1, (uint8_t[]){0x10}, 1, 0}, - {0xC2, (uint8_t[]){0x37}, 1, 0}, - {0xC3, (uint8_t[]){0x80}, 1, 0}, - {0xC4, (uint8_t[]){0x10}, 1, 0}, - {0xC5, (uint8_t[]){0x37}, 1, 0}, - {0xC6, (uint8_t[]){0xA9}, 1, 0}, - {0xC7, (uint8_t[]){0x41}, 1, 0}, - {0xC8, (uint8_t[]){0x51}, 1, 0}, - {0xC9, (uint8_t[]){0xA9}, 1, 0}, - {0xCA, (uint8_t[]){0x41}, 1, 0}, - {0xCB, (uint8_t[]){0x51}, 1, 0}, - {0xD0, (uint8_t[]){0x91}, 1, 0}, - {0xD1, (uint8_t[]){0x68}, 1, 0}, - {0xD2, (uint8_t[]){0x69}, 1, 0}, - {0xF5, (uint8_t[]){0x00, 0xA5}, 2, 0}, - {0xDD, (uint8_t[]){0x3F}, 1, 0}, - {0xDE, (uint8_t[]){0x3F}, 1, 0}, - {0xF1, (uint8_t[]){0x10}, 1, 0}, - {0xF0, (uint8_t[]){0x00}, 1, 0}, - {0xF0, (uint8_t[]){0x02}, 1, 0}, - {0xE0, (uint8_t[]){0x70, 0x09, 0x12, 0x0C, 0x0B, 0x27, 0x38, 0x54, 0x4E, 0x19, 0x15, 0x15, 0x2C, 0x2F}, 14, 0}, - {0xE1, (uint8_t[]){0x70, 0x08, 0x11, 0x0C, 0x0B, 0x27, 0x38, 0x43, 0x4C, 0x18, 0x14, 0x14, 0x2B, 0x2D}, 14, 0}, - {0xF0, (uint8_t[]){0x10}, 1, 0}, - {0xF3, (uint8_t[]){0x10}, 1, 0}, - {0xE0, (uint8_t[]){0x08}, 1, 0}, - {0xE1, (uint8_t[]){0x00}, 1, 0}, - {0xE2, (uint8_t[]){0x00}, 1, 0}, - {0xE3, (uint8_t[]){0x00}, 1, 0}, - {0xE4, (uint8_t[]){0xE0}, 1, 0}, - {0xE5, (uint8_t[]){0x06}, 1, 0}, - {0xE6, (uint8_t[]){0x21}, 1, 0}, - {0xE7, (uint8_t[]){0x00}, 1, 0}, - {0xE8, (uint8_t[]){0x05}, 1, 0}, - {0xE9, (uint8_t[]){0x82}, 1, 0}, - {0xEA, (uint8_t[]){0xDF}, 1, 0}, - {0xEB, (uint8_t[]){0x89}, 1, 0}, - {0xEC, (uint8_t[]){0x20}, 1, 0}, - {0xED, (uint8_t[]){0x14}, 1, 0}, - {0xEE, (uint8_t[]){0xFF}, 1, 0}, - {0xEF, (uint8_t[]){0x00}, 1, 0}, - {0xF8, (uint8_t[]){0xFF}, 1, 0}, - {0xF9, (uint8_t[]){0x00}, 1, 0}, - {0xFA, (uint8_t[]){0x00}, 1, 0}, - {0xFB, (uint8_t[]){0x30}, 1, 0}, - {0xFC, (uint8_t[]){0x00}, 1, 0}, - {0xFD, (uint8_t[]){0x00}, 1, 0}, - {0xFE, (uint8_t[]){0x00}, 1, 0}, - {0xFF, (uint8_t[]){0x00}, 1, 0}, - {0x60, (uint8_t[]){0x42}, 1, 0}, - {0x61, (uint8_t[]){0xE0}, 1, 0}, - {0x62, (uint8_t[]){0x40}, 1, 0}, - {0x63, (uint8_t[]){0x40}, 1, 0}, - {0x64, (uint8_t[]){0x02}, 1, 0}, - {0x65, (uint8_t[]){0x00}, 1, 0}, - {0x66, (uint8_t[]){0x40}, 1, 0}, - {0x67, (uint8_t[]){0x03}, 1, 0}, - {0x68, (uint8_t[]){0x00}, 1, 0}, - {0x69, (uint8_t[]){0x00}, 1, 0}, - {0x6A, (uint8_t[]){0x00}, 1, 0}, - {0x6B, (uint8_t[]){0x00}, 1, 0}, - {0x70, (uint8_t[]){0x42}, 1, 0}, - {0x71, (uint8_t[]){0xE0}, 1, 0}, - {0x72, (uint8_t[]){0x40}, 1, 0}, - {0x73, (uint8_t[]){0x40}, 1, 0}, - {0x74, (uint8_t[]){0x02}, 1, 0}, - {0x75, (uint8_t[]){0x00}, 1, 0}, - {0x76, (uint8_t[]){0x40}, 1, 0}, - {0x77, (uint8_t[]){0x03}, 1, 0}, - {0x78, (uint8_t[]){0x00}, 1, 0}, - {0x79, (uint8_t[]){0x00}, 1, 0}, - {0x7A, (uint8_t[]){0x00}, 1, 0}, - {0x7B, (uint8_t[]){0x00}, 1, 0}, - {0x80, (uint8_t[]){0x48}, 1, 0}, - {0x81, (uint8_t[]){0x00}, 1, 0}, - {0x82, (uint8_t[]){0x05}, 1, 0}, - {0x83, (uint8_t[]){0x02}, 1, 0}, - {0x84, (uint8_t[]){0xDD}, 1, 0}, - {0x85, (uint8_t[]){0x00}, 1, 0}, - {0x86, (uint8_t[]){0x00}, 1, 0}, - {0x87, (uint8_t[]){0x00}, 1, 0}, - {0x88, (uint8_t[]){0x48}, 1, 0}, - {0x89, (uint8_t[]){0x00}, 1, 0}, - {0x8A, (uint8_t[]){0x07}, 1, 0}, - {0x8B, (uint8_t[]){0x02}, 1, 0}, - {0x8C, (uint8_t[]){0xDF}, 1, 0}, - {0x8D, (uint8_t[]){0x00}, 1, 0}, - {0x8E, (uint8_t[]){0x00}, 1, 0}, - {0x8F, (uint8_t[]){0x00}, 1, 0}, - {0x90, (uint8_t[]){0x48}, 1, 0}, - {0x91, (uint8_t[]){0x00}, 1, 0}, - {0x92, (uint8_t[]){0x09}, 1, 0}, - {0x93, (uint8_t[]){0x02}, 1, 0}, - {0x94, (uint8_t[]){0xE1}, 1, 0}, - {0x95, (uint8_t[]){0x00}, 1, 0}, - {0x96, (uint8_t[]){0x00}, 1, 0}, - {0x97, (uint8_t[]){0x00}, 1, 0}, - {0x98, (uint8_t[]){0x48}, 1, 0}, - {0x99, (uint8_t[]){0x00}, 1, 0}, - {0x9A, (uint8_t[]){0x0B}, 1, 0}, - {0x9B, (uint8_t[]){0x02}, 1, 0}, - {0x9C, (uint8_t[]){0xE3}, 1, 0}, - {0x9D, (uint8_t[]){0x00}, 1, 0}, - {0x9E, (uint8_t[]){0x00}, 1, 0}, - {0x9F, (uint8_t[]){0x00}, 1, 0}, - {0xA0, (uint8_t[]){0x48}, 1, 0}, - {0xA1, (uint8_t[]){0x00}, 1, 0}, - {0xA2, (uint8_t[]){0x04}, 1, 0}, - {0xA3, (uint8_t[]){0x02}, 1, 0}, - {0xA4, (uint8_t[]){0xDC}, 1, 0}, - {0xA5, (uint8_t[]){0x00}, 1, 0}, - {0xA6, (uint8_t[]){0x00}, 1, 0}, - {0xA7, (uint8_t[]){0x00}, 1, 0}, - {0xA8, (uint8_t[]){0x48}, 1, 0}, - {0xA9, (uint8_t[]){0x00}, 1, 0}, - {0xAA, (uint8_t[]){0x06}, 1, 0}, - {0xAB, (uint8_t[]){0x02}, 1, 0}, - {0xAC, (uint8_t[]){0xDE}, 1, 0}, - {0xAD, (uint8_t[]){0x00}, 1, 0}, - {0xAE, (uint8_t[]){0x00}, 1, 0}, - {0xAF, (uint8_t[]){0x00}, 1, 0}, - {0xB0, (uint8_t[]){0x48}, 1, 0}, - {0xB1, (uint8_t[]){0x00}, 1, 0}, - {0xB2, (uint8_t[]){0x08}, 1, 0}, - {0xB3, (uint8_t[]){0x02}, 1, 0}, - {0xB4, (uint8_t[]){0xE0}, 1, 0}, - {0xB5, (uint8_t[]){0x00}, 1, 0}, - {0xB6, (uint8_t[]){0x00}, 1, 0}, - {0xB7, (uint8_t[]){0x00}, 1, 0}, - {0xB8, (uint8_t[]){0x48}, 1, 0}, - {0xB9, (uint8_t[]){0x00}, 1, 0}, - {0xBA, (uint8_t[]){0x0A}, 1, 0}, - {0xBB, (uint8_t[]){0x02}, 1, 0}, - {0xBC, (uint8_t[]){0xE2}, 1, 0}, - {0xBD, (uint8_t[]){0x00}, 1, 0}, - {0xBE, (uint8_t[]){0x00}, 1, 0}, - {0xBF, (uint8_t[]){0x00}, 1, 0}, - {0xC0, (uint8_t[]){0x12}, 1, 0}, - {0xC1, (uint8_t[]){0xAA}, 1, 0}, - {0xC2, (uint8_t[]){0x65}, 1, 0}, - {0xC3, (uint8_t[]){0x74}, 1, 0}, - {0xC4, (uint8_t[]){0x47}, 1, 0}, - {0xC5, (uint8_t[]){0x56}, 1, 0}, - {0xC6, (uint8_t[]){0x00}, 1, 0}, - {0xC7, (uint8_t[]){0x88}, 1, 0}, - {0xC8, (uint8_t[]){0x99}, 1, 0}, - {0xC9, (uint8_t[]){0x33}, 1, 0}, - {0xD0, (uint8_t[]){0x21}, 1, 0}, - {0xD1, (uint8_t[]){0xAA}, 1, 0}, - {0xD2, (uint8_t[]){0x65}, 1, 0}, - {0xD3, (uint8_t[]){0x74}, 1, 0}, - {0xD4, (uint8_t[]){0x47}, 1, 0}, - {0xD5, (uint8_t[]){0x56}, 1, 0}, - {0xD6, (uint8_t[]){0x00}, 1, 0}, - {0xD7, (uint8_t[]){0x88}, 1, 0}, - {0xD8, (uint8_t[]){0x99}, 1, 0}, - {0xD9, (uint8_t[]){0x33}, 1, 0}, - {0xF3, (uint8_t[]){0x01}, 1, 0}, - {0xF0, (uint8_t[]){0x00}, 1, 0}, - {0xF0, (uint8_t[]){0x01}, 1, 0}, - {0xF1, (uint8_t[]){0x01}, 1, 0}, - {0xA0, (uint8_t[]){0x0B}, 1, 0}, - {0xA3, (uint8_t[]){0x2A}, 1, 0}, - {0xA5, (uint8_t[]){0xC3}, 1, 1}, - {0xA3, (uint8_t[]){0x2B}, 1, 0}, - {0xA5, (uint8_t[]){0xC3}, 1, 1}, - {0xA3, (uint8_t[]){0x2C}, 1, 0}, - {0xA5, (uint8_t[]){0xC3}, 1, 1}, - {0xA3, (uint8_t[]){0x2D}, 1, 0}, - {0xA5, (uint8_t[]){0xC3}, 1, 1}, - {0xA3, (uint8_t[]){0x2E}, 1, 0}, - {0xA5, (uint8_t[]){0xC3}, 1, 1}, - {0xA3, (uint8_t[]){0x2F}, 1, 0}, - {0xA5, (uint8_t[]){0xC3}, 1, 1}, - {0xA3, (uint8_t[]){0x30}, 1, 0}, - {0xA5, (uint8_t[]){0xC3}, 1, 1}, - {0xA3, (uint8_t[]){0x31}, 1, 0}, - {0xA5, (uint8_t[]){0xC3}, 1, 1}, - {0xA3, (uint8_t[]){0x32}, 1, 0}, - {0xA5, (uint8_t[]){0xC3}, 1, 1}, - {0xA3, (uint8_t[]){0x33}, 1, 0}, - {0xA5, (uint8_t[]){0xC3}, 1, 1}, - {0xA0, (uint8_t[]){0x09}, 1, 0}, - {0xF1, (uint8_t[]){0x10}, 1, 0}, - {0xF0, (uint8_t[]){0x00}, 1, 0}, - {0x2A, (uint8_t[]){0x00, 0x00, 0x01, 0x67}, 4, 0}, - {0x2B, (uint8_t[]){0x01, 0x68, 0x01, 0x68}, 4, 0}, - {0x4D, (uint8_t[]){0x00}, 1, 0}, - {0x4E, (uint8_t[]){0x00}, 1, 0}, - {0x4F, (uint8_t[]){0x00}, 1, 0}, - {0x4C, (uint8_t[]){0x01}, 1, 10}, - {0x4C, (uint8_t[]){0x00}, 1, 0}, - {0x2A, (uint8_t[]){0x00, 0x00, 0x01, 0x67}, 4, 0}, - {0x2B, (uint8_t[]){0x00, 0x00, 0x01, 0x67}, 4, 0}, - {0x21, (uint8_t[]){0x00}, 1, 0}, - //{0x3A, (uint8_t[]){0x55}, 1, 0}, // color=16 - {0x11, (uint8_t[]){0x00}, 1, 120}, - {0x29, (uint8_t[]){0x00}, 1, 0}, -}; - -#define TFT_SPI_FREQ_HZ (50 * 1000 * 1000) - -// LVGL tick source (replaces LV_TICK_CUSTOM of LVGL 8) -static uint32_t lv_tick_millis(void) -{ - return millis(); -} - -static void my_disp_flush(lv_display_t *disp, const lv_area_t *area, uint8_t *px_map) -{ - ESP_PanelLcd *lcd = (ESP_PanelLcd *)lv_display_get_user_data(disp); - const int w = lv_area_get_width(area); - const int h = lv_area_get_height(area); - // LVGL 9 renders little-endian RGB565, the ST77916 expects big-endian (LVGL 8 used LV_COLOR_16_SWAP) - lv_draw_rgb565_swap(px_map, w * h); - lcd->drawBitmap(area->x1, area->y1, w, h, (const uint8_t *)px_map); -} - -IRAM_ATTR bool onRefreshFinishCallback(void *user_data) -{ - lv_display_flush_ready((lv_display_t *)user_data); - return false; -} - -void setRotation(uint8_t rot) -{ - if (rot > 3) - return; - if (lcd == NULL || touch == NULL) - return; - - switch (rot) - { - case 1: // 顺时针90度 - lcd->swapXY(true); - lcd->mirrorX(true); - lcd->mirrorY(false); - touch->swapXY(true); - touch->mirrorX(true); - touch->mirrorY(false); - break; - case 2: - lcd->swapXY(false); - lcd->mirrorX(true); - lcd->mirrorY(true); - touch->swapXY(false); - touch->mirrorX(true); - touch->mirrorY(true); - break; - case 3: - lcd->swapXY(true); - lcd->mirrorX(false); - lcd->mirrorY(true); - touch->swapXY(true); - touch->mirrorX(false); - touch->mirrorY(true); - break; - default: - lcd->swapXY(false); - lcd->mirrorX(false); - lcd->mirrorY(false); - touch->swapXY(false); - touch->mirrorX(false); - touch->mirrorY(false); - break; - } -} - -void screen_switch(bool on) -{ - if (NULL == backlight) - return; - if (on) - backlight->on(); - else - backlight->off(); -} - -// 输入值为0-100 -void set_brightness(uint8_t bri) -{ - if (NULL == backlight) - return; - backlight->setBrightness(bri); -} - -static void touchpad_read(lv_indev_t *indev, lv_indev_data_t *data) -{ - ESP_PanelTouch *tp = (ESP_PanelTouch *)lv_indev_get_user_data(indev); - ESP_PanelTouchPoint point; - - int read_touch_result = tp->readPoints(&point, 1); - if (read_touch_result > 0) - { - data->point.x = point.x; - data->point.y = point.y; - data->state = LV_INDEV_STATE_PRESSED; - } - else - { - data->state = LV_INDEV_STATE_RELEASED; - } -} - -static lv_indev_t *indev_init(ESP_PanelTouch *tp) -{ - ESP_PANEL_CHECK_FALSE_RET(tp != nullptr, nullptr, "Invalid touch device"); - ESP_PANEL_CHECK_FALSE_RET(tp->getHandle() != nullptr, nullptr, "Touch device is not initialized"); - lv_indev_t *indev = lv_indev_create(); - lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); - lv_indev_set_read_cb(indev, touchpad_read); - lv_indev_set_user_data(indev, (void *)tp); - return indev; -} - -void scr_lvgl_init() -{ - ledc_timer_config_t ledc_timer = { - .speed_mode = LEDC_LOW_SPEED_MODE, - .duty_resolution = LEDC_TIMER_13_BIT, - .timer_num = LEDC_TIMER_0, - .freq_hz = 5000, - .clk_cfg = LEDC_AUTO_CLK}; - ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer)); - - ledc_channel_config_t ledc_channel = { - .gpio_num = (TFT_BLK), - .speed_mode = LEDC_LOW_SPEED_MODE, - .channel = LEDC_CHANNEL_0, - .intr_type = LEDC_INTR_DISABLE, - .timer_sel = LEDC_TIMER_0, - .duty = 0, - .hpoint = 0}; - - ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel)); - - backlight = new ESP_PanelBacklight(ledc_timer, ledc_channel); - backlight->begin(); - backlight->off(); - - ESP_PanelBus_I2C *touch_bus = new ESP_PanelBus_I2C(TOUCH_PIN_NUM_I2C_SCL, TOUCH_PIN_NUM_I2C_SDA, ESP_LCD_TOUCH_IO_I2C_CST816S_CONFIG()); - touch_bus->configI2cFreqHz(400000); - touch_bus->begin(); - - touch = new ESP_PanelTouch_CST816S(touch_bus, SCREEN_RES_HOR, SCREEN_RES_VER, TOUCH_PIN_NUM_RST, TOUCH_PIN_NUM_INT); - - touch->init(); - touch->begin(); - -#if TOUCH_PIN_NUM_INT >= 0 - touch->attachInterruptCallback(onTouchInterruptCallback, NULL); -#endif - - ESP_PanelBus_QSPI *panel_bus = new ESP_PanelBus_QSPI(TFT_CS, TFT_SCK, TFT_SDA0, TFT_SDA1, TFT_SDA2, TFT_SDA3); - panel_bus->configQspiFreqHz(TFT_SPI_FREQ_HZ); - panel_bus->begin(); - - lcd = new ESP_PanelLcd_ST77916(panel_bus, 16, TFT_RST); - // 注意,初始化代码的设置必须在INIT之前 - // lcd->configVendorCommands(lcd_init_cmd, sizeof(lcd_init_cmd) / sizeof(lcd_init_cmd[0])); - lcd->init(); - lcd->reset(); - lcd->begin(); - - lcd->invertColor(true); - // setRotation(0); //设置屏幕方向 - lcd->displayOn(); - - screen_switch(true); - backlight->setBrightness(100); // 设置亮度 - - size_t lv_cache_rows = 72; - - size_t buf_bytes = lv_cache_rows * SCREEN_RES_HOR * 2; // RGB565 - disp_draw_buf = (uint8_t *)heap_caps_malloc(buf_bytes, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); - disp_draw_buf2 = (uint8_t *)heap_caps_malloc(buf_bytes, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); - lv_init(); - lv_tick_set_cb(lv_tick_millis); - - disp = lv_display_create(SCREEN_RES_HOR, SCREEN_RES_VER); - lv_display_set_flush_cb(disp, my_disp_flush); - lv_display_set_buffers(disp, disp_draw_buf, disp_draw_buf2, buf_bytes, LV_DISPLAY_RENDER_MODE_PARTIAL); - lv_display_set_user_data(disp, (void *)lcd); - - if (lcd->getBus()->getType() != ESP_PANEL_BUS_TYPE_RGB) - { - lcd->attachRefreshFinishCallback(onRefreshFinishCallback, (void *)disp); - } - indev_touchpad = indev_init(touch); -} - -#endif \ No newline at end of file +#include "jc3636w518.h" + +#include +#include +#include + +static uint8_t *disp_draw_buf; +static uint8_t *disp_draw_buf2; // second buffer: LVGL renders into one while the other is sent to the LCD +static lv_display_t *disp = NULL; +static lv_indev_t *indev_touchpad; +static ESP_PanelBacklight *backlight = NULL; +static ESP_PanelLcd *lcd = NULL; +static ESP_PanelTouch *touch = NULL; + +#define USE_CUSTOM_INIT_CMD 0 // 1 = use the vendor init sequence below instead of the library default + +#if TOUCH_PIN_NUM_INT >= 0 + +IRAM_ATTR bool onTouchInterruptCallback(void *user_data) +{ + return false; +} + +#endif + +#if USE_CUSTOM_INIT_CMD +// Vendor ST77916 init sequence (from the original scr_st77916.h) +const esp_lcd_panel_vendor_init_cmd_t lcd_init_cmd[] = { + {0xF0, (uint8_t[]){0x08}, 1, 0}, + {0xF2, (uint8_t[]){0x08}, 1, 0}, + {0x9B, (uint8_t[]){0x51}, 1, 0}, + {0x86, (uint8_t[]){0x53}, 1, 0}, + {0xF2, (uint8_t[]){0x80}, 1, 0}, + {0xF0, (uint8_t[]){0x00}, 1, 0}, + {0xF0, (uint8_t[]){0x01}, 1, 0}, + {0xF1, (uint8_t[]){0x01}, 1, 0}, + {0xB0, (uint8_t[]){0x54}, 1, 0}, + {0xB1, (uint8_t[]){0x3F}, 1, 0}, + {0xB2, (uint8_t[]){0x2A}, 1, 0}, + {0xB4, (uint8_t[]){0x46}, 1, 0}, + {0xB5, (uint8_t[]){0x34}, 1, 0}, + {0xB6, (uint8_t[]){0xD5}, 1, 0}, + {0xB7, (uint8_t[]){0x30}, 1, 0}, + {0xBA, (uint8_t[]){0x00}, 1, 0}, + {0xBB, (uint8_t[]){0x08}, 1, 0}, + {0xBC, (uint8_t[]){0x08}, 1, 0}, + {0xBD, (uint8_t[]){0x00}, 1, 0}, + {0xC0, (uint8_t[]){0x80}, 1, 0}, + {0xC1, (uint8_t[]){0x10}, 1, 0}, + {0xC2, (uint8_t[]){0x37}, 1, 0}, + {0xC3, (uint8_t[]){0x80}, 1, 0}, + {0xC4, (uint8_t[]){0x10}, 1, 0}, + {0xC5, (uint8_t[]){0x37}, 1, 0}, + {0xC6, (uint8_t[]){0xA9}, 1, 0}, + {0xC7, (uint8_t[]){0x41}, 1, 0}, + {0xC8, (uint8_t[]){0x51}, 1, 0}, + {0xC9, (uint8_t[]){0xA9}, 1, 0}, + {0xCA, (uint8_t[]){0x41}, 1, 0}, + {0xCB, (uint8_t[]){0x51}, 1, 0}, + {0xD0, (uint8_t[]){0x91}, 1, 0}, + {0xD1, (uint8_t[]){0x68}, 1, 0}, + {0xD2, (uint8_t[]){0x69}, 1, 0}, + {0xF5, (uint8_t[]){0x00, 0xA5}, 2, 0}, + {0xDD, (uint8_t[]){0x3F}, 1, 0}, + {0xDE, (uint8_t[]){0x3F}, 1, 0}, + {0xF1, (uint8_t[]){0x10}, 1, 0}, + {0xF0, (uint8_t[]){0x00}, 1, 0}, + {0xF0, (uint8_t[]){0x02}, 1, 0}, + {0xE0, (uint8_t[]){0x70, 0x09, 0x12, 0x0C, 0x0B, 0x27, 0x38, 0x54, 0x4E, 0x19, 0x15, 0x15, 0x2C, 0x2F}, 14, 0}, + {0xE1, (uint8_t[]){0x70, 0x08, 0x11, 0x0C, 0x0B, 0x27, 0x38, 0x43, 0x4C, 0x18, 0x14, 0x14, 0x2B, 0x2D}, 14, 0}, + {0xF0, (uint8_t[]){0x10}, 1, 0}, + {0xF3, (uint8_t[]){0x10}, 1, 0}, + {0xE0, (uint8_t[]){0x08}, 1, 0}, + {0xE1, (uint8_t[]){0x00}, 1, 0}, + {0xE2, (uint8_t[]){0x00}, 1, 0}, + {0xE3, (uint8_t[]){0x00}, 1, 0}, + {0xE4, (uint8_t[]){0xE0}, 1, 0}, + {0xE5, (uint8_t[]){0x06}, 1, 0}, + {0xE6, (uint8_t[]){0x21}, 1, 0}, + {0xE7, (uint8_t[]){0x00}, 1, 0}, + {0xE8, (uint8_t[]){0x05}, 1, 0}, + {0xE9, (uint8_t[]){0x82}, 1, 0}, + {0xEA, (uint8_t[]){0xDF}, 1, 0}, + {0xEB, (uint8_t[]){0x89}, 1, 0}, + {0xEC, (uint8_t[]){0x20}, 1, 0}, + {0xED, (uint8_t[]){0x14}, 1, 0}, + {0xEE, (uint8_t[]){0xFF}, 1, 0}, + {0xEF, (uint8_t[]){0x00}, 1, 0}, + {0xF8, (uint8_t[]){0xFF}, 1, 0}, + {0xF9, (uint8_t[]){0x00}, 1, 0}, + {0xFA, (uint8_t[]){0x00}, 1, 0}, + {0xFB, (uint8_t[]){0x30}, 1, 0}, + {0xFC, (uint8_t[]){0x00}, 1, 0}, + {0xFD, (uint8_t[]){0x00}, 1, 0}, + {0xFE, (uint8_t[]){0x00}, 1, 0}, + {0xFF, (uint8_t[]){0x00}, 1, 0}, + {0x60, (uint8_t[]){0x42}, 1, 0}, + {0x61, (uint8_t[]){0xE0}, 1, 0}, + {0x62, (uint8_t[]){0x40}, 1, 0}, + {0x63, (uint8_t[]){0x40}, 1, 0}, + {0x64, (uint8_t[]){0x02}, 1, 0}, + {0x65, (uint8_t[]){0x00}, 1, 0}, + {0x66, (uint8_t[]){0x40}, 1, 0}, + {0x67, (uint8_t[]){0x03}, 1, 0}, + {0x68, (uint8_t[]){0x00}, 1, 0}, + {0x69, (uint8_t[]){0x00}, 1, 0}, + {0x6A, (uint8_t[]){0x00}, 1, 0}, + {0x6B, (uint8_t[]){0x00}, 1, 0}, + {0x70, (uint8_t[]){0x42}, 1, 0}, + {0x71, (uint8_t[]){0xE0}, 1, 0}, + {0x72, (uint8_t[]){0x40}, 1, 0}, + {0x73, (uint8_t[]){0x40}, 1, 0}, + {0x74, (uint8_t[]){0x02}, 1, 0}, + {0x75, (uint8_t[]){0x00}, 1, 0}, + {0x76, (uint8_t[]){0x40}, 1, 0}, + {0x77, (uint8_t[]){0x03}, 1, 0}, + {0x78, (uint8_t[]){0x00}, 1, 0}, + {0x79, (uint8_t[]){0x00}, 1, 0}, + {0x7A, (uint8_t[]){0x00}, 1, 0}, + {0x7B, (uint8_t[]){0x00}, 1, 0}, + {0x80, (uint8_t[]){0x48}, 1, 0}, + {0x81, (uint8_t[]){0x00}, 1, 0}, + {0x82, (uint8_t[]){0x05}, 1, 0}, + {0x83, (uint8_t[]){0x02}, 1, 0}, + {0x84, (uint8_t[]){0xDD}, 1, 0}, + {0x85, (uint8_t[]){0x00}, 1, 0}, + {0x86, (uint8_t[]){0x00}, 1, 0}, + {0x87, (uint8_t[]){0x00}, 1, 0}, + {0x88, (uint8_t[]){0x48}, 1, 0}, + {0x89, (uint8_t[]){0x00}, 1, 0}, + {0x8A, (uint8_t[]){0x07}, 1, 0}, + {0x8B, (uint8_t[]){0x02}, 1, 0}, + {0x8C, (uint8_t[]){0xDF}, 1, 0}, + {0x8D, (uint8_t[]){0x00}, 1, 0}, + {0x8E, (uint8_t[]){0x00}, 1, 0}, + {0x8F, (uint8_t[]){0x00}, 1, 0}, + {0x90, (uint8_t[]){0x48}, 1, 0}, + {0x91, (uint8_t[]){0x00}, 1, 0}, + {0x92, (uint8_t[]){0x09}, 1, 0}, + {0x93, (uint8_t[]){0x02}, 1, 0}, + {0x94, (uint8_t[]){0xE1}, 1, 0}, + {0x95, (uint8_t[]){0x00}, 1, 0}, + {0x96, (uint8_t[]){0x00}, 1, 0}, + {0x97, (uint8_t[]){0x00}, 1, 0}, + {0x98, (uint8_t[]){0x48}, 1, 0}, + {0x99, (uint8_t[]){0x00}, 1, 0}, + {0x9A, (uint8_t[]){0x0B}, 1, 0}, + {0x9B, (uint8_t[]){0x02}, 1, 0}, + {0x9C, (uint8_t[]){0xE3}, 1, 0}, + {0x9D, (uint8_t[]){0x00}, 1, 0}, + {0x9E, (uint8_t[]){0x00}, 1, 0}, + {0x9F, (uint8_t[]){0x00}, 1, 0}, + {0xA0, (uint8_t[]){0x48}, 1, 0}, + {0xA1, (uint8_t[]){0x00}, 1, 0}, + {0xA2, (uint8_t[]){0x04}, 1, 0}, + {0xA3, (uint8_t[]){0x02}, 1, 0}, + {0xA4, (uint8_t[]){0xDC}, 1, 0}, + {0xA5, (uint8_t[]){0x00}, 1, 0}, + {0xA6, (uint8_t[]){0x00}, 1, 0}, + {0xA7, (uint8_t[]){0x00}, 1, 0}, + {0xA8, (uint8_t[]){0x48}, 1, 0}, + {0xA9, (uint8_t[]){0x00}, 1, 0}, + {0xAA, (uint8_t[]){0x06}, 1, 0}, + {0xAB, (uint8_t[]){0x02}, 1, 0}, + {0xAC, (uint8_t[]){0xDE}, 1, 0}, + {0xAD, (uint8_t[]){0x00}, 1, 0}, + {0xAE, (uint8_t[]){0x00}, 1, 0}, + {0xAF, (uint8_t[]){0x00}, 1, 0}, + {0xB0, (uint8_t[]){0x48}, 1, 0}, + {0xB1, (uint8_t[]){0x00}, 1, 0}, + {0xB2, (uint8_t[]){0x08}, 1, 0}, + {0xB3, (uint8_t[]){0x02}, 1, 0}, + {0xB4, (uint8_t[]){0xE0}, 1, 0}, + {0xB5, (uint8_t[]){0x00}, 1, 0}, + {0xB6, (uint8_t[]){0x00}, 1, 0}, + {0xB7, (uint8_t[]){0x00}, 1, 0}, + {0xB8, (uint8_t[]){0x48}, 1, 0}, + {0xB9, (uint8_t[]){0x00}, 1, 0}, + {0xBA, (uint8_t[]){0x0A}, 1, 0}, + {0xBB, (uint8_t[]){0x02}, 1, 0}, + {0xBC, (uint8_t[]){0xE2}, 1, 0}, + {0xBD, (uint8_t[]){0x00}, 1, 0}, + {0xBE, (uint8_t[]){0x00}, 1, 0}, + {0xBF, (uint8_t[]){0x00}, 1, 0}, + {0xC0, (uint8_t[]){0x12}, 1, 0}, + {0xC1, (uint8_t[]){0xAA}, 1, 0}, + {0xC2, (uint8_t[]){0x65}, 1, 0}, + {0xC3, (uint8_t[]){0x74}, 1, 0}, + {0xC4, (uint8_t[]){0x47}, 1, 0}, + {0xC5, (uint8_t[]){0x56}, 1, 0}, + {0xC6, (uint8_t[]){0x00}, 1, 0}, + {0xC7, (uint8_t[]){0x88}, 1, 0}, + {0xC8, (uint8_t[]){0x99}, 1, 0}, + {0xC9, (uint8_t[]){0x33}, 1, 0}, + {0xD0, (uint8_t[]){0x21}, 1, 0}, + {0xD1, (uint8_t[]){0xAA}, 1, 0}, + {0xD2, (uint8_t[]){0x65}, 1, 0}, + {0xD3, (uint8_t[]){0x74}, 1, 0}, + {0xD4, (uint8_t[]){0x47}, 1, 0}, + {0xD5, (uint8_t[]){0x56}, 1, 0}, + {0xD6, (uint8_t[]){0x00}, 1, 0}, + {0xD7, (uint8_t[]){0x88}, 1, 0}, + {0xD8, (uint8_t[]){0x99}, 1, 0}, + {0xD9, (uint8_t[]){0x33}, 1, 0}, + {0xF3, (uint8_t[]){0x01}, 1, 0}, + {0xF0, (uint8_t[]){0x00}, 1, 0}, + {0xF0, (uint8_t[]){0x01}, 1, 0}, + {0xF1, (uint8_t[]){0x01}, 1, 0}, + {0xA0, (uint8_t[]){0x0B}, 1, 0}, + {0xA3, (uint8_t[]){0x2A}, 1, 0}, + {0xA5, (uint8_t[]){0xC3}, 1, 1}, + {0xA3, (uint8_t[]){0x2B}, 1, 0}, + {0xA5, (uint8_t[]){0xC3}, 1, 1}, + {0xA3, (uint8_t[]){0x2C}, 1, 0}, + {0xA5, (uint8_t[]){0xC3}, 1, 1}, + {0xA3, (uint8_t[]){0x2D}, 1, 0}, + {0xA5, (uint8_t[]){0xC3}, 1, 1}, + {0xA3, (uint8_t[]){0x2E}, 1, 0}, + {0xA5, (uint8_t[]){0xC3}, 1, 1}, + {0xA3, (uint8_t[]){0x2F}, 1, 0}, + {0xA5, (uint8_t[]){0xC3}, 1, 1}, + {0xA3, (uint8_t[]){0x30}, 1, 0}, + {0xA5, (uint8_t[]){0xC3}, 1, 1}, + {0xA3, (uint8_t[]){0x31}, 1, 0}, + {0xA5, (uint8_t[]){0xC3}, 1, 1}, + {0xA3, (uint8_t[]){0x32}, 1, 0}, + {0xA5, (uint8_t[]){0xC3}, 1, 1}, + {0xA3, (uint8_t[]){0x33}, 1, 0}, + {0xA5, (uint8_t[]){0xC3}, 1, 1}, + {0xA0, (uint8_t[]){0x09}, 1, 0}, + {0xF1, (uint8_t[]){0x10}, 1, 0}, + {0xF0, (uint8_t[]){0x00}, 1, 0}, + {0x2A, (uint8_t[]){0x00, 0x00, 0x01, 0x67}, 4, 0}, + {0x2B, (uint8_t[]){0x01, 0x68, 0x01, 0x68}, 4, 0}, + {0x4D, (uint8_t[]){0x00}, 1, 0}, + {0x4E, (uint8_t[]){0x00}, 1, 0}, + {0x4F, (uint8_t[]){0x00}, 1, 0}, + {0x4C, (uint8_t[]){0x01}, 1, 10}, + {0x4C, (uint8_t[]){0x00}, 1, 0}, + {0x2A, (uint8_t[]){0x00, 0x00, 0x01, 0x67}, 4, 0}, + {0x2B, (uint8_t[]){0x00, 0x00, 0x01, 0x67}, 4, 0}, + {0x21, (uint8_t[]){0x00}, 1, 0}, + //{0x3A, (uint8_t[]){0x55}, 1, 0}, // color=16 + {0x11, (uint8_t[]){0x00}, 1, 120}, + {0x29, (uint8_t[]){0x00}, 1, 0}, +}; +#endif + +#define TFT_SPI_FREQ_HZ (50 * 1000 * 1000) + +// LVGL tick source +static uint32_t lv_tick_millis(void) +{ + return millis(); +} + +static void my_disp_flush(lv_display_t *disp, const lv_area_t *area, uint8_t *px_map) +{ + ESP_PanelLcd *lcd = (ESP_PanelLcd *)lv_display_get_user_data(disp); + const int w = lv_area_get_width(area); + const int h = lv_area_get_height(area); +#if LV_COLOR_FORMAT_DEFAULT == LV_COLOR_FORMAT_RGB565 + // LVGL renders little-endian RGB565, the ST77916 expects big-endian + lv_draw_rgb565_swap(px_map, w * h); +#endif + lcd->drawBitmap(area->x1, area->y1, w, h, (const uint8_t *)px_map); +} + +IRAM_ATTR bool onRefreshFinishCallback(void *user_data) +{ + lv_display_flush_ready((lv_display_t *)user_data); + return false; +} + +void setRotation(uint8_t rot) +{ + if (rot > 3) + return; + if (lcd == NULL || touch == NULL) + return; + + switch (rot) + { + case 1: // 90° clockwise + lcd->swapXY(true); + lcd->mirrorX(true); + lcd->mirrorY(false); + touch->swapXY(true); + touch->mirrorX(true); + touch->mirrorY(false); + break; + case 2: + lcd->swapXY(false); + lcd->mirrorX(true); + lcd->mirrorY(true); + touch->swapXY(false); + touch->mirrorX(true); + touch->mirrorY(true); + break; + case 3: + lcd->swapXY(true); + lcd->mirrorX(false); + lcd->mirrorY(true); + touch->swapXY(true); + touch->mirrorX(false); + touch->mirrorY(true); + break; + default: + lcd->swapXY(false); + lcd->mirrorX(false); + lcd->mirrorY(false); + touch->swapXY(false); + touch->mirrorX(false); + touch->mirrorY(false); + break; + } +} + +void screen_switch(bool on) +{ + if (NULL == backlight) + return; + if (on) + backlight->on(); + else + backlight->off(); +} + +void set_brightness(uint8_t bri) +{ + if (NULL == backlight) + return; + backlight->setBrightness(bri); +} + +static void touchpad_read(lv_indev_t *indev, lv_indev_data_t *data) +{ + ESP_PanelTouch *tp = (ESP_PanelTouch *)lv_indev_get_user_data(indev); + ESP_PanelTouchPoint point; + + int read_touch_result = tp->readPoints(&point, 1); + if (read_touch_result > 0) + { + data->point.x = point.x; + data->point.y = point.y; + data->state = LV_INDEV_STATE_PRESSED; + } + else + { + data->state = LV_INDEV_STATE_RELEASED; + } +} + +static lv_indev_t *indev_init(ESP_PanelTouch *tp) +{ + ESP_PANEL_CHECK_FALSE_RET(tp != nullptr, nullptr, "Invalid touch device"); + ESP_PANEL_CHECK_FALSE_RET(tp->getHandle() != nullptr, nullptr, "Touch device is not initialized"); + lv_indev_t *indev = lv_indev_create(); + lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); + lv_indev_set_read_cb(indev, touchpad_read); + lv_indev_set_user_data(indev, (void *)tp); + return indev; +} + +lv_display_t *scr_lvgl_init() +{ + ledc_timer_config_t ledc_timer = { + .speed_mode = LEDC_LOW_SPEED_MODE, + .duty_resolution = LEDC_TIMER_13_BIT, + .timer_num = LEDC_TIMER_0, + .freq_hz = 5000, + .clk_cfg = LEDC_AUTO_CLK}; + ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer)); + + ledc_channel_config_t ledc_channel = { + .gpio_num = (TFT_BLK), + .speed_mode = LEDC_LOW_SPEED_MODE, + .channel = LEDC_CHANNEL_0, + .intr_type = LEDC_INTR_DISABLE, + .timer_sel = LEDC_TIMER_0, + .duty = 0, + .hpoint = 0}; + + ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel)); + + backlight = new ESP_PanelBacklight(ledc_timer, ledc_channel); + backlight->begin(); + backlight->off(); + + ESP_PanelBus_I2C *touch_bus = new ESP_PanelBus_I2C(TOUCH_PIN_NUM_I2C_SCL, TOUCH_PIN_NUM_I2C_SDA, ESP_LCD_TOUCH_IO_I2C_CST816S_CONFIG()); + touch_bus->configI2cFreqHz(400000); + touch_bus->begin(); + + touch = new ESP_PanelTouch_CST816S(touch_bus, SCREEN_RES_HOR, SCREEN_RES_VER, TOUCH_PIN_NUM_RST, TOUCH_PIN_NUM_INT); + + touch->init(); + touch->begin(); + +#if TOUCH_PIN_NUM_INT >= 0 + touch->attachInterruptCallback(onTouchInterruptCallback, NULL); +#endif + + ESP_PanelBus_QSPI *panel_bus = new ESP_PanelBus_QSPI(TFT_CS, TFT_SCK, TFT_SDA0, TFT_SDA1, TFT_SDA2, TFT_SDA3); + panel_bus->configQspiFreqHz(TFT_SPI_FREQ_HZ); + panel_bus->begin(); + + lcd = new ESP_PanelLcd_ST77916(panel_bus, 16, TFT_RST); + // vendor init commands must be configured before init() +#if USE_CUSTOM_INIT_CMD + lcd->configVendorCommands(lcd_init_cmd, sizeof(lcd_init_cmd) / sizeof(lcd_init_cmd[0])); +#endif + lcd->init(); + lcd->reset(); + lcd->begin(); + + lcd->invertColor(true); + lcd->displayOn(); + + screen_switch(true); + backlight->setBrightness(100); + + size_t buf_bytes = JC_DRAW_BUF_ROWS * SCREEN_RES_HOR * 2; // RGB565 + disp_draw_buf = (uint8_t *)heap_caps_malloc(buf_bytes, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + disp_draw_buf2 = (uint8_t *)heap_caps_malloc(buf_bytes, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + lv_init(); + lv_tick_set_cb(lv_tick_millis); + + disp = lv_display_create(SCREEN_RES_HOR, SCREEN_RES_VER); + lv_display_set_flush_cb(disp, my_disp_flush); + lv_display_set_buffers(disp, disp_draw_buf, disp_draw_buf2, buf_bytes, LV_DISPLAY_RENDER_MODE_PARTIAL); + lv_display_set_user_data(disp, (void *)lcd); + + if (lcd->getBus()->getType() != ESP_PANEL_BUS_TYPE_RGB) + { + lcd->attachRefreshFinishCallback(onRefreshFinishCallback, (void *)disp); + } + indev_touchpad = indev_init(touch); + return disp; +} diff --git a/shared/lib/JC3636W518/src/jc3636w518.h b/shared/lib/JC3636W518/src/jc3636w518.h new file mode 100644 index 0000000..ef98726 --- /dev/null +++ b/shared/lib/JC3636W518/src/jc3636w518.h @@ -0,0 +1,28 @@ +// JC3636W518 board support: ST77916 QSPI LCD (360x360), CST816S touch, PWM backlight, LVGL 9 glue. +// Shared by all JC3636W518 projects (see shared/README.md). +#ifndef _JC3636W518_H_ +#define _JC3636W518_H_ + +#include +#include "pincfg.h" + +#define SCREEN_RES_HOR 360 +#define SCREEN_RES_VER 360 + +// Rows per LVGL draw buffer (two buffers, internal RAM, RGB565). Override with -DJC_DRAW_BUF_ROWS=. +#ifndef JC_DRAW_BUF_ROWS +#define JC_DRAW_BUF_ROWS 72 +#endif + +// Initializes backlight, touch, LCD and LVGL (lv_init, tick, display, touch input). Returns the display. +lv_display_t *scr_lvgl_init(); + +// 0 = normal, 1 = 90° clockwise, 2 = 180°, 3 = 270° (LCD and touch together) +void setRotation(uint8_t rot); + +void screen_switch(bool on); + +// 0-100 +void set_brightness(uint8_t bri); + +#endif diff --git a/shared/lib/JC3636W518/src/perf_monitor.cpp b/shared/lib/JC3636W518/src/perf_monitor.cpp new file mode 100644 index 0000000..22a4335 --- /dev/null +++ b/shared/lib/JC3636W518/src/perf_monitor.cpp @@ -0,0 +1,64 @@ +#include "perf_monitor.h" + +#include + +static uint32_t refr_count = 0; // refreshes that actually rendered something +static uint32_t refr_time_us = 0; // time spent in those refreshes +static uint32_t busy_us = 0; // time spent inside lv_timer_handler() + +static void refr_event_cb(lv_event_t *e) +{ + static uint32_t refr_start_us = 0; + static bool rendered = false; + switch (lv_event_get_code(e)) + { + case LV_EVENT_REFR_START: + refr_start_us = micros(); + rendered = false; + break; + case LV_EVENT_RENDER_START: + rendered = true; + break; + case LV_EVENT_REFR_READY: + if (rendered) + { + refr_count++; + refr_time_us += micros() - refr_start_us; + } + break; + default: + break; + } +} + +void perf_monitor_begin(lv_display_t *disp) +{ + lv_display_add_event_cb(disp, refr_event_cb, LV_EVENT_ALL, NULL); +} + +uint32_t perf_timer_handler() +{ + uint32_t t0 = micros(); + uint32_t next = lv_timer_handler(); + busy_us += micros() - t0; + return next; +} + +void perf_monitor_print() +{ + static uint32_t last_us = 0; + uint32_t now = micros(); + uint32_t elapsed = now - last_us; + if (elapsed < 1000000) + return; + uint32_t other_us = busy_us > refr_time_us ? busy_us - refr_time_us : 0; + Serial.printf("FPS: %.1f refresh: %.1f ms other: %.1f ms cpu: %.0f%%\n", + refr_count * 1e6f / elapsed, + refr_count ? refr_time_us / 1000.0f / refr_count : 0.0f, + refr_count ? other_us / 1000.0f / refr_count : 0.0f, + busy_us * 100.0f / elapsed); + refr_count = 0; + refr_time_us = 0; + busy_us = 0; + last_us = now; +} diff --git a/shared/lib/JC3636W518/src/perf_monitor.h b/shared/lib/JC3636W518/src/perf_monitor.h new file mode 100644 index 0000000..a19b8c1 --- /dev/null +++ b/shared/lib/JC3636W518/src/perf_monitor.h @@ -0,0 +1,19 @@ +// Simple LVGL performance monitor, printed to Serial once per second: +// FPS: rendered frames/s refresh: avg ms per rendered frame (render + flush) +// other: avg ms per frame spent in LVGL timers outside refresh (e.g. GIF decode) +// cpu: % of time inside lv_timer_handler() +#ifndef _PERF_MONITOR_H_ +#define _PERF_MONITOR_H_ + +#include + +// Hook the display's refresh events. +void perf_monitor_begin(lv_display_t *disp); + +// Call instead of lv_timer_handler(); measures the time spent in it. +uint32_t perf_timer_handler(); + +// Prints the statistics once per second (call every loop). +void perf_monitor_print(); + +#endif diff --git a/10-OBD-Display-2024/_archive/lvgl9_broken/pincfg.h b/shared/lib/JC3636W518/src/pincfg.h similarity index 100% rename from 10-OBD-Display-2024/_archive/lvgl9_broken/pincfg.h rename to shared/lib/JC3636W518/src/pincfg.h