From 7fa73d618319879971f33a7d70875c47978920ba Mon Sep 17 00:00:00 2001 From: Misaki Date: Mon, 25 Aug 2025 11:07:52 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E6=B5=8B=E8=AF=95=E4=BA=86=E5=B1=8F?= =?UTF-8?q?=E5=B9=95=E9=A9=B1=E5=8A=A8=EF=BC=8Clvgl,=E8=A7=A6=E6=91=B8?= =?UTF-8?q?=EF=BC=8C=E9=A9=B1=E5=8A=A8=E6=96=87=E4=BB=B6=E5=9C=A8Lib/Displ?= =?UTF-8?q?ay=E5=BD=93=E4=B8=AD=E3=80=82=E5=85=A8=E9=83=A8=E9=80=9A?= =?UTF-8?q?=E8=BF=87(=E4=BF=AE=E6=94=B9=E4=BA=86sdkconfig,=E4=BB=A5?= =?UTF-8?q?=E9=80=82=E9=85=8Dlvgl)=202.=20=E6=96=B0=E5=A2=9E=E4=BA=86?= =?UTF-8?q?=E4=BC=98=E9=9B=85=E7=9A=84C=E8=AF=AD=E8=A8=80=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Lib/Display/LCD_Driver/ST77916.c | 388 ++++++ Lib/Display/LCD_Driver/ST77916.h | 70 ++ .../esp_lcd_st77916/esp_lcd_st77916.c | 1036 +++++++++++++++++ .../esp_lcd_st77916/esp_lcd_st77916.h | 114 ++ Lib/Display/LVGL_Driver/LVGL_Driver.c | 127 ++ Lib/Display/LVGL_Driver/LVGL_Driver.h | 25 + Lib/Display/LVGL_UI/LVGL_Example.c | 360 ++++++ Lib/Display/LVGL_UI/LVGL_Example.h | 19 + Lib/Display/LVGL_UI/LVGL_Music.c | 813 +++++++++++++ Lib/Display/LVGL_UI/LVGL_Music.h | 69 ++ Lib/Display/Touch_Driver/CST816.c | 243 ++++ Lib/Display/Touch_Driver/CST816.h | 70 ++ .../esp_lcd_touch/esp_lcd_touch.c | 258 ++++ .../esp_lcd_touch/esp_lcd_touch.h | 413 +++++++ Util/general_err_handle/err_handle.c | 3 + Util/general_err_handle/err_handle.h | 12 + main/Bionic_sphere.c | 11 +- main/CMakeLists.txt | 19 +- sdkconfig | 23 +- sdkconfig.old | 395 ++++++- test/driver_test/drivers_test.c | 34 + test/driver_test/drivers_test.h | 3 + 项目开发日志.md | 6 + 23 files changed, 4495 insertions(+), 16 deletions(-) create mode 100644 Lib/Display/LCD_Driver/ST77916.c create mode 100644 Lib/Display/LCD_Driver/ST77916.h create mode 100644 Lib/Display/LCD_Driver/esp_lcd_st77916/esp_lcd_st77916.c create mode 100644 Lib/Display/LCD_Driver/esp_lcd_st77916/esp_lcd_st77916.h create mode 100644 Lib/Display/LVGL_Driver/LVGL_Driver.c create mode 100644 Lib/Display/LVGL_Driver/LVGL_Driver.h create mode 100644 Lib/Display/LVGL_UI/LVGL_Example.c create mode 100644 Lib/Display/LVGL_UI/LVGL_Example.h create mode 100644 Lib/Display/LVGL_UI/LVGL_Music.c create mode 100644 Lib/Display/LVGL_UI/LVGL_Music.h create mode 100644 Lib/Display/Touch_Driver/CST816.c create mode 100644 Lib/Display/Touch_Driver/CST816.h create mode 100644 Lib/Display/Touch_Driver/esp_lcd_touch/esp_lcd_touch.c create mode 100644 Lib/Display/Touch_Driver/esp_lcd_touch/esp_lcd_touch.h create mode 100644 Util/general_err_handle/err_handle.c create mode 100644 Util/general_err_handle/err_handle.h diff --git a/Lib/Display/LCD_Driver/ST77916.c b/Lib/Display/LCD_Driver/ST77916.c new file mode 100644 index 0000000..2e3d608 --- /dev/null +++ b/Lib/Display/LCD_Driver/ST77916.c @@ -0,0 +1,388 @@ +#include "ST77916.h" + + +#define LCD_OPCODE_WRITE_CMD (0x02ULL) +#define LCD_OPCODE_READ_CMD (0x0BULL) +#define LCD_OPCODE_WRITE_COLOR (0x32ULL) + +static const char *TAG_LCD = "ST77916"; + +esp_lcd_panel_handle_t panel_handle = NULL; + + +static const st77916_lcd_init_cmd_t vendor_specific_init_new[] = { + {0xF0, (uint8_t []){0x28}, 1, 0}, + {0xF2, (uint8_t []){0x28}, 1, 0}, + {0x73, (uint8_t []){0xF0}, 1, 0}, + {0x7C, (uint8_t []){0xD1}, 1, 0}, + {0x83, (uint8_t []){0xE0}, 1, 0}, + {0x84, (uint8_t []){0x61}, 1, 0}, + {0xF2, (uint8_t []){0x82}, 1, 0}, + {0xF0, (uint8_t []){0x00}, 1, 0}, + {0xF0, (uint8_t []){0x01}, 1, 0}, + {0xF1, (uint8_t []){0x01}, 1, 0}, + {0xB0, (uint8_t []){0x56}, 1, 0}, + {0xB1, (uint8_t []){0x4D}, 1, 0}, + {0xB2, (uint8_t []){0x24}, 1, 0}, + {0xB4, (uint8_t []){0x87}, 1, 0}, + {0xB5, (uint8_t []){0x44}, 1, 0}, + {0xB6, (uint8_t []){0x8B}, 1, 0}, + {0xB7, (uint8_t []){0x40}, 1, 0}, + {0xB8, (uint8_t []){0x86}, 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 []){0x01}, 1, 0}, + {0xC9, (uint8_t []){0xA9}, 1, 0}, + {0xCA, (uint8_t []){0x41}, 1, 0}, + {0xCB, (uint8_t []){0x01}, 1, 0}, + {0xD0, (uint8_t []){0x91}, 1, 0}, + {0xD1, (uint8_t []){0x68}, 1, 0}, + {0xD2, (uint8_t []){0x68}, 1, 0}, + {0xF5, (uint8_t []){0x00, 0xA5}, 2, 0}, + {0xDD, (uint8_t []){0x4F}, 1, 0}, + {0xDE, (uint8_t []){0x4F}, 1, 0}, + {0xF1, (uint8_t []){0x10}, 1, 0}, + {0xF0, (uint8_t []){0x00}, 1, 0}, + {0xF0, (uint8_t []){0x02}, 1, 0}, + {0xE0, (uint8_t []){0xF0, 0x0A, 0x10, 0x09, 0x09, 0x36, 0x35, 0x33, 0x4A, 0x29, 0x15, 0x15, 0x2E, 0x34}, 14, 0}, + {0xE1, (uint8_t []){0xF0, 0x0A, 0x0F, 0x08, 0x08, 0x05, 0x34, 0x33, 0x4A, 0x39, 0x15, 0x15, 0x2D, 0x33}, 14, 0}, + {0xF0, (uint8_t []){0x10}, 1, 0}, + {0xF3, (uint8_t []){0x10}, 1, 0}, + {0xE0, (uint8_t []){0x07}, 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 []){0x01}, 1, 0}, + {0xE8, (uint8_t []){0x05}, 1, 0}, + {0xE9, (uint8_t []){0x02}, 1, 0}, + {0xEA, (uint8_t []){0xDA}, 1, 0}, + {0xEB, (uint8_t []){0x00}, 1, 0}, + {0xEC, (uint8_t []){0x00}, 1, 0}, + {0xED, (uint8_t []){0x0F}, 1, 0}, + {0xEE, (uint8_t []){0x00}, 1, 0}, + {0xEF, (uint8_t []){0x00}, 1, 0}, + {0xF8, (uint8_t []){0x00}, 1, 0}, + {0xF9, (uint8_t []){0x00}, 1, 0}, + {0xFA, (uint8_t []){0x00}, 1, 0}, + {0xFB, (uint8_t []){0x00}, 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 []){0x40}, 1, 0}, + {0x61, (uint8_t []){0x04}, 1, 0}, + {0x62, (uint8_t []){0x00}, 1, 0}, + {0x63, (uint8_t []){0x42}, 1, 0}, + {0x64, (uint8_t []){0xD9}, 1, 0}, + {0x65, (uint8_t []){0x00}, 1, 0}, + {0x66, (uint8_t []){0x00}, 1, 0}, + {0x67, (uint8_t []){0x00}, 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 []){0x40}, 1, 0}, + {0x71, (uint8_t []){0x03}, 1, 0}, + {0x72, (uint8_t []){0x00}, 1, 0}, + {0x73, (uint8_t []){0x42}, 1, 0}, + {0x74, (uint8_t []){0xD8}, 1, 0}, + {0x75, (uint8_t []){0x00}, 1, 0}, + {0x76, (uint8_t []){0x00}, 1, 0}, + {0x77, (uint8_t []){0x00}, 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 []){0x06}, 1, 0}, + {0x83, (uint8_t []){0x02}, 1, 0}, + {0x84, (uint8_t []){0xD6}, 1, 0}, + {0x85, (uint8_t []){0x04}, 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 []){0x08}, 1, 0}, + {0x8B, (uint8_t []){0x02}, 1, 0}, + {0x8C, (uint8_t []){0xD8}, 1, 0}, + {0x8D, (uint8_t []){0x04}, 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 []){0x0A}, 1, 0}, + {0x93, (uint8_t []){0x02}, 1, 0}, + {0x94, (uint8_t []){0xDA}, 1, 0}, + {0x95, (uint8_t []){0x04}, 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 []){0x0C}, 1, 0}, + {0x9B, (uint8_t []){0x02}, 1, 0}, + {0x9C, (uint8_t []){0xDC}, 1, 0}, + {0x9D, (uint8_t []){0x04}, 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 []){0x05}, 1, 0}, + {0xA3, (uint8_t []){0x02}, 1, 0}, + {0xA4, (uint8_t []){0xD5}, 1, 0}, + {0xA5, (uint8_t []){0x04}, 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 []){0x07}, 1, 0}, + {0xAB, (uint8_t []){0x02}, 1, 0}, + {0xAC, (uint8_t []){0xD7}, 1, 0}, + {0xAD, (uint8_t []){0x04}, 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 []){0x09}, 1, 0}, + {0xB3, (uint8_t []){0x02}, 1, 0}, + {0xB4, (uint8_t []){0xD9}, 1, 0}, + {0xB5, (uint8_t []){0x04}, 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 []){0x0B}, 1, 0}, + {0xBB, (uint8_t []){0x02}, 1, 0}, + {0xBC, (uint8_t []){0xDB}, 1, 0}, + {0xBD, (uint8_t []){0x04}, 1, 0}, + {0xBE, (uint8_t []){0x00}, 1, 0}, + {0xBF, (uint8_t []){0x00}, 1, 0}, + {0xC0, (uint8_t []){0x10}, 1, 0}, + {0xC1, (uint8_t []){0x47}, 1, 0}, + {0xC2, (uint8_t []){0x56}, 1, 0}, + {0xC3, (uint8_t []){0x65}, 1, 0}, + {0xC4, (uint8_t []){0x74}, 1, 0}, + {0xC5, (uint8_t []){0x88}, 1, 0}, + {0xC6, (uint8_t []){0x99}, 1, 0}, + {0xC7, (uint8_t []){0x01}, 1, 0}, + {0xC8, (uint8_t []){0xBB}, 1, 0}, + {0xC9, (uint8_t []){0xAA}, 1, 0}, + {0xD0, (uint8_t []){0x10}, 1, 0}, + {0xD1, (uint8_t []){0x47}, 1, 0}, + {0xD2, (uint8_t []){0x56}, 1, 0}, + {0xD3, (uint8_t []){0x65}, 1, 0}, + {0xD4, (uint8_t []){0x74}, 1, 0}, + {0xD5, (uint8_t []){0x88}, 1, 0}, + {0xD6, (uint8_t []){0x99}, 1, 0}, + {0xD7, (uint8_t []){0x01}, 1, 0}, + {0xD8, (uint8_t []){0xBB}, 1, 0}, + {0xD9, (uint8_t []){0xAA}, 1, 0}, + {0xF3, (uint8_t []){0x01}, 1, 0}, + {0xF0, (uint8_t []){0x00}, 1, 0}, + {0x21, (uint8_t []){0x00}, 1, 0}, + {0x11, (uint8_t []){0x00}, 1, 120}, + {0x29, (uint8_t []){0x00}, 1, 0}, +}; +void ST7701_Reset(){ + Set_EXIO(TCA9554_EXIO2,false); + vTaskDelay(pdMS_TO_TICKS(10)); + Set_EXIO(TCA9554_EXIO2,true); + vTaskDelay(pdMS_TO_TICKS(50)); +} +void LCD_Init() { + ST77916_Init(); + Backlight_Init(); + Touch_Init(); +} + +static void test_draw_bitmap(esp_lcd_panel_handle_t panel_handle) +{ + uint16_t row_line = ((EXAMPLE_LCD_WIDTH / EXAMPLE_LCD_COLOR_BITS) << 1) >> 1; + uint8_t byte_per_pixel = EXAMPLE_LCD_COLOR_BITS / 8; + uint8_t *color = (uint8_t *)heap_caps_calloc(1, row_line * EXAMPLE_LCD_HEIGHT * byte_per_pixel, MALLOC_CAP_DMA); + + + for (int j = 0; j < EXAMPLE_LCD_COLOR_BITS; j++) { + for (int i = 0; i < row_line * EXAMPLE_LCD_HEIGHT; i++) { + for (int k = 0; k < byte_per_pixel; k++) { + color[i * byte_per_pixel + k] = (SPI_SWAP_DATA_TX(BIT(j), EXAMPLE_LCD_COLOR_BITS) >> (k * 8)) & 0xff; + } + } + esp_lcd_panel_draw_bitmap(panel_handle, 0, j * row_line, EXAMPLE_LCD_HEIGHT, (j + 1) * row_line, color); + } + free(color); +} + +int QSPI_Init(void){ + static const spi_bus_config_t host_config = { + .data0_io_num = ESP_PANEL_LCD_SPI_IO_DATA0, + .data1_io_num = ESP_PANEL_LCD_SPI_IO_DATA1, + .sclk_io_num = ESP_PANEL_LCD_SPI_IO_SCK, + .data2_io_num = ESP_PANEL_LCD_SPI_IO_DATA2, + .data3_io_num = ESP_PANEL_LCD_SPI_IO_DATA3, + .data4_io_num = -1, + .data5_io_num = -1, + .data6_io_num = -1, + .data7_io_num = -1, + .max_transfer_sz = ESP_PANEL_HOST_SPI_MAX_TRANSFER_SIZE, + .flags = SPICOMMON_BUSFLAG_MASTER, + .intr_flags = 0, + }; + if(spi_bus_initialize(ESP_PANEL_HOST_SPI_ID_DEFAULT, &host_config, SPI_DMA_CH_AUTO) != ESP_OK){ + printf("The SPI initialization failed.\r\n"); + return 0; + } + printf("The SPI initialization succeeded.\r\n"); + + esp_lcd_panel_io_spi_config_t io_config ={ + .cs_gpio_num = ESP_PANEL_LCD_SPI_IO_CS, + .dc_gpio_num = -1, + .spi_mode = ESP_PANEL_LCD_SPI_MODE, + .pclk_hz = 3 * 1000 * 1000, + .trans_queue_depth = ESP_PANEL_LCD_SPI_TRANS_QUEUE_SZ, + .on_color_trans_done = NULL, + .user_ctx = NULL, + .lcd_cmd_bits = ESP_PANEL_LCD_SPI_CMD_BITS, + .lcd_param_bits = ESP_PANEL_LCD_SPI_PARAM_BITS, + .flags = { + .dc_low_on_data = 0, + .octal_mode = 0, + .quad_mode = 1, + .sio_mode = 0, + .lsb_first = 0, + .cs_high_active = 0, + }, + }; + esp_lcd_panel_io_handle_t io_handle = NULL; + if(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)ESP_PANEL_HOST_SPI_ID_DEFAULT, &io_config, &io_handle) != ESP_OK){ + printf("Failed to set LCD communication parameters -- SPI\r\n"); + return 0; + } + printf("LCD communication parameters are set successfully -- SPI\r\n"); + + printf("Install LCD driver of st77916\r\n"); + st77916_vendor_config_t vendor_config={ + .flags = { + .use_qspi_interface = 1, + }, + }; + printf("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\n"); + esp_err_t ret; + int lcd_cmd = 0x04; + uint8_t register_data[4]; + size_t param_size = sizeof(register_data); + lcd_cmd &= 0xff; + lcd_cmd <<= 8; + lcd_cmd |= LCD_OPCODE_READ_CMD << 24; // Use the read opcode instead of write + ret = esp_lcd_panel_io_rx_param(io_handle, lcd_cmd, register_data, param_size); + if (ret == ESP_OK) { + printf("Register 0x04 data: %02x %02x %02x %02x\n", register_data[0], register_data[1], register_data[2], register_data[3]); + } else { + printf("Failed to read register 0x04, error code: %d\n", ret); + } + // panel_io_spi_del(io_handle); + io_config.pclk_hz = ESP_PANEL_LCD_SPI_CLK_HZ; + if(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)ESP_PANEL_HOST_SPI_ID_DEFAULT, &io_config, &io_handle) != ESP_OK){ + printf("Failed to set LCD communication parameters -- SPI\r\n"); + return 0; + } + printf("LCD communication parameters are set successfully -- SPI\r\n"); + + // Check register values and configure accordingly + if (register_data[0] == 0x00 && register_data[1] == 0x7F && register_data[2] == 0x7F && register_data[3] == 0x7F) { + // Handle the case where the register data matches this pattern + printf("Vendor-specific initialization for case 1.\n"); + } + else if (register_data[0] == 0x00 && register_data[1] == 0x02 && register_data[2] == 0x7F && register_data[3] == 0x7F) { + // Provide vendor-specific initialization commands if register data matches this pattern + vendor_config.init_cmds = vendor_specific_init_new; + vendor_config.init_cmds_size = sizeof(vendor_specific_init_new) / sizeof(st77916_lcd_init_cmd_t); + printf("Vendor-specific initialization for case 2.\n"); + } + printf("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\n"); + + esp_lcd_panel_dev_config_t panel_config={ + .reset_gpio_num = EXAMPLE_LCD_PIN_NUM_RST, + .rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB, + // .data_endian = LCD_RGB_DATA_ENDIAN_LITTLE, + .bits_per_pixel = EXAMPLE_LCD_COLOR_BITS, + .flags = { + .reset_active_high = 0, + }, + .vendor_config = (void *) &vendor_config, + }; + esp_lcd_new_panel_st77916(io_handle, &panel_config, &panel_handle); + + esp_lcd_panel_reset(panel_handle); + esp_lcd_panel_init(panel_handle); + // esp_lcd_panel_invert_color(panel_handle,false); + + esp_lcd_panel_disp_on_off(panel_handle, true); + test_draw_bitmap(panel_handle); + return 1; +} + +void ST77916_Init() { + ST7701_Reset(); + if(!QSPI_Init()){ + printf("ST77916 Failed to be initialized\r\n"); + } +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Backlight program + +uint8_t LCD_Backlight = 70; +static ledc_channel_config_t ledc_channel; +void Backlight_Init(void) +{ + ESP_LOGI(TAG_LCD, "Turn off LCD backlight"); + gpio_config_t bk_gpio_config = { + .mode = GPIO_MODE_OUTPUT, + .pin_bit_mask = 1ULL << EXAMPLE_LCD_PIN_NUM_BK_LIGHT + }; + ESP_ERROR_CHECK(gpio_config(&bk_gpio_config)); + + ledc_timer_config_t ledc_timer = { + .duty_resolution = LEDC_TIMER_13_BIT, + .freq_hz = 5000, + .speed_mode = LEDC_LS_MODE, + .timer_num = LEDC_HS_TIMER, + .clk_cfg = LEDC_AUTO_CLK + }; + ledc_timer_config(&ledc_timer); + + ledc_channel.channel = LEDC_HS_CH0_CHANNEL; + ledc_channel.duty = 0; + ledc_channel.gpio_num = EXAMPLE_LCD_PIN_NUM_BK_LIGHT; + ledc_channel.speed_mode = LEDC_LS_MODE; + ledc_channel.timer_sel = LEDC_HS_TIMER; + ledc_channel_config(&ledc_channel); + ledc_fade_func_install(0); + + Set_Backlight(LCD_Backlight); //0~100 +} +void Set_Backlight(uint8_t Light) +{ + if(Light > Backlight_MAX) Light = Backlight_MAX; + uint16_t Duty = LEDC_MAX_Duty-(81*(Backlight_MAX-Light)); + if(Light == 0) + Duty = 0; + ledc_set_duty(ledc_channel.speed_mode, ledc_channel.channel, Duty); + ledc_update_duty(ledc_channel.speed_mode, ledc_channel.channel); +} +// end Backlight program \ No newline at end of file diff --git a/Lib/Display/LCD_Driver/ST77916.h b/Lib/Display/LCD_Driver/ST77916.h new file mode 100644 index 0000000..2c678c0 --- /dev/null +++ b/Lib/Display/LCD_Driver/ST77916.h @@ -0,0 +1,70 @@ +#pragma once +#include "esp_err.h" +#include "esp_log.h" +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "driver/gpio.h" +#include "driver/spi_master.h" +#include "esp_timer.h" +#include "esp_lcd_panel_io.h" +#include "esp_lcd_panel_io_interface.h" +#include "esp_intr_alloc.h" +#include "esp_lcd_panel_ops.h" +#include "esp_lcd_panel_vendor.h" +#include "lvgl.h" +#include "driver/ledc.h" + +#include "esp_lcd_st77916.h" +#include "CST816.h" +#include "LVGL_Driver.h" +#include "TCA9554PWR.h" + + +#define EXAMPLE_LCD_WIDTH (360) +#define EXAMPLE_LCD_HEIGHT (360) +#define EXAMPLE_LCD_COLOR_BITS (16) + +#define ESP_PANEL_HOST_SPI_ID_DEFAULT (SPI2_HOST) +#define ESP_PANEL_LCD_SPI_MODE (0) // 0/1/2/3, typically set to 0 +#define ESP_PANEL_LCD_SPI_CLK_HZ (80 * 1000 * 1000) // Should be an integer divisor of 80M, typically set to 40M +#define ESP_PANEL_LCD_SPI_TRANS_QUEUE_SZ (10) // Typically set to 10 +#define ESP_PANEL_LCD_SPI_CMD_BITS (32) // Typically set to 32 +#define ESP_PANEL_LCD_SPI_PARAM_BITS (8) // Typically set to 8 + +#define ESP_PANEL_LCD_SPI_IO_TE (18) +#define ESP_PANEL_LCD_SPI_IO_SCK (40) +#define ESP_PANEL_LCD_SPI_IO_DATA0 (46) +#define ESP_PANEL_LCD_SPI_IO_DATA1 (45) +#define ESP_PANEL_LCD_SPI_IO_DATA2 (42) +#define ESP_PANEL_LCD_SPI_IO_DATA3 (41) +#define ESP_PANEL_LCD_SPI_IO_CS (21) +#define EXAMPLE_LCD_PIN_NUM_RST (-1) // EXIO2 +#define EXAMPLE_LCD_PIN_NUM_BK_LIGHT (5) + +#define EXAMPLE_LCD_BK_LIGHT_ON_LEVEL (1) +#define EXAMPLE_LCD_BK_LIGHT_OFF_LEVEL !EXAMPLE_LCD_BK_LIGHT_ON_LEVEL + +#define ESP_PANEL_HOST_SPI_MAX_TRANSFER_SIZE (2048) + +#define LEDC_HS_TIMER LEDC_TIMER_0 +#define LEDC_LS_MODE LEDC_LOW_SPEED_MODE +#define LEDC_HS_CH0_GPIO EXAMPLE_LCD_PIN_NUM_BK_LIGHT +#define LEDC_HS_CH0_CHANNEL LEDC_CHANNEL_0 +#define LEDC_TEST_DUTY (4000) +#define LEDC_ResolutionRatio LEDC_TIMER_13_BIT +#define LEDC_MAX_Duty ((1 << LEDC_ResolutionRatio) - 1) +#define Backlight_MAX 100 + +extern esp_lcd_panel_handle_t panel_handle; +extern uint8_t LCD_Backlight; + +void ST77916_Init(); + +void LCD_Init(void); // Call this function to initialize the screen (must be called in the main function) !!!!! +void LCD_addWindow(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend,uint16_t* color); + +void Backlight_Init(void); // Initialize the LCD backlight, which has been called in the LCD_Init function, ignore it +void Set_Backlight(uint8_t Light); // Call this function to adjust the brightness of the backlight. The value of the parameter Light ranges from 0 to 100 diff --git a/Lib/Display/LCD_Driver/esp_lcd_st77916/esp_lcd_st77916.c b/Lib/Display/LCD_Driver/esp_lcd_st77916/esp_lcd_st77916.c new file mode 100644 index 0000000..5614497 --- /dev/null +++ b/Lib/Display/LCD_Driver/esp_lcd_st77916/esp_lcd_st77916.c @@ -0,0 +1,1036 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "driver/gpio.h" +#include "esp_check.h" +#include "esp_lcd_panel_interface.h" +#include "esp_lcd_panel_io.h" +#include "esp_lcd_panel_vendor.h" +#include "esp_lcd_panel_ops.h" +#include "esp_lcd_panel_commands.h" +#include "esp_log.h" + +#include "esp_lcd_st77916.h" + +#define LCD_OPCODE_WRITE_CMD (0x02ULL) +#define LCD_OPCODE_READ_CMD (0x0BULL) +#define LCD_OPCODE_WRITE_COLOR (0x32ULL) + +#define ST77916_CMD_SET (0xF0) +#define ST77916_PARAM_SET (0x00) + +static const char *TAG = "st77916"; + +static esp_err_t panel_st77916_del(esp_lcd_panel_t *panel); +static esp_err_t panel_st77916_reset(esp_lcd_panel_t *panel); +static esp_err_t panel_st77916_init(esp_lcd_panel_t *panel); +static esp_err_t panel_st77916_draw_bitmap(esp_lcd_panel_t *panel, int x_start, int y_start, int x_end, int y_end, const void *color_data); +static esp_err_t panel_st77916_invert_color(esp_lcd_panel_t *panel, bool invert_color_data); +static esp_err_t panel_st77916_mirror(esp_lcd_panel_t *panel, bool mirror_x, bool mirror_y); +static esp_err_t panel_st77916_swap_xy(esp_lcd_panel_t *panel, bool swap_axes); +static esp_err_t panel_st77916_set_gap(esp_lcd_panel_t *panel, int x_gap, int y_gap); +static esp_err_t panel_st77916_disp_on_off(esp_lcd_panel_t *panel, bool off); + +typedef struct { + esp_lcd_panel_t base; + esp_lcd_panel_io_handle_t io; + int reset_gpio_num; + int x_gap; + int y_gap; + uint8_t fb_bits_per_pixel; + uint8_t madctl_val; // save current value of LCD_CMD_MADCTL register + uint8_t colmod_val; // save surrent value of LCD_CMD_COLMOD register + const st77916_lcd_init_cmd_t *init_cmds; + uint16_t init_cmds_size; + struct { + unsigned int use_qspi_interface: 1; + unsigned int reset_level: 1; + } flags; +} st77916_panel_t; + +esp_err_t esp_lcd_new_panel_st77916(const esp_lcd_panel_io_handle_t io, const esp_lcd_panel_dev_config_t *panel_dev_config, esp_lcd_panel_handle_t *ret_panel) +{ + ESP_RETURN_ON_FALSE(io && panel_dev_config && ret_panel, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + + esp_err_t ret = ESP_OK; + st77916_panel_t *st77916 = NULL; + st77916 = calloc(1, sizeof(st77916_panel_t)); + ESP_GOTO_ON_FALSE(st77916, ESP_ERR_NO_MEM, err, TAG, "no mem for st77916 panel"); + + if (panel_dev_config->reset_gpio_num >= 0) { + gpio_config_t io_conf = { + .mode = GPIO_MODE_OUTPUT, + .pin_bit_mask = 1ULL << panel_dev_config->reset_gpio_num, + }; + ESP_GOTO_ON_ERROR(gpio_config(&io_conf), err, TAG, "configure GPIO for RST line failed"); + } + + switch (panel_dev_config->rgb_ele_order) { + case LCD_RGB_ELEMENT_ORDER_RGB: + st77916->madctl_val = 0; + break; + case LCD_RGB_ELEMENT_ORDER_BGR: + st77916->madctl_val |= LCD_CMD_BGR_BIT; + break; + default: + ESP_GOTO_ON_FALSE(false, ESP_ERR_NOT_SUPPORTED, err, TAG, "unsupported color element order"); + break; + } + + switch (panel_dev_config->bits_per_pixel) { + case 16: // RGB565 + st77916->colmod_val = 0x55; + st77916->fb_bits_per_pixel = 16; + break; + case 18: // RGB666 + st77916->colmod_val = 0x66; + // each color component (R/G/B) should occupy the 6 high bits of a byte, which means 3 full bytes are required for a pixel + st77916->fb_bits_per_pixel = 24; + break; + default: + ESP_GOTO_ON_FALSE(false, ESP_ERR_NOT_SUPPORTED, err, TAG, "unsupported pixel width"); + break; + } + + st77916->io = io; + st77916->reset_gpio_num = panel_dev_config->reset_gpio_num; + st77916->flags.reset_level = panel_dev_config->flags.reset_active_high; + st77916_vendor_config_t *vendor_config = (st77916_vendor_config_t *)panel_dev_config->vendor_config; + if (vendor_config) { + st77916->init_cmds = vendor_config->init_cmds; + st77916->init_cmds_size = vendor_config->init_cmds_size; + st77916->flags.use_qspi_interface = vendor_config->flags.use_qspi_interface; + } + st77916->base.del = panel_st77916_del; + st77916->base.reset = panel_st77916_reset; + st77916->base.init = panel_st77916_init; + st77916->base.draw_bitmap = panel_st77916_draw_bitmap; + st77916->base.invert_color = panel_st77916_invert_color; + st77916->base.set_gap = panel_st77916_set_gap; + st77916->base.mirror = panel_st77916_mirror; + st77916->base.swap_xy = panel_st77916_swap_xy; + st77916->base.disp_on_off = panel_st77916_disp_on_off; + *ret_panel = &(st77916->base); + ESP_LOGD(TAG, "new st77916 panel @%p", st77916); + + // ESP_LOGI(TAG, "LCD panel create success, version: %d.%d.%d", ESP_LCD_ST77916_VER_MAJOR, ESP_LCD_ST77916_VER_MINOR, ESP_LCD_ST77916_VER_PATCH); + + return ESP_OK; + +err: + if (st77916) { + if (panel_dev_config->reset_gpio_num >= 0) { + gpio_reset_pin(panel_dev_config->reset_gpio_num); + } + free(st77916); + } + return ret; +} + +static esp_err_t tx_param(st77916_panel_t *st77916, esp_lcd_panel_io_handle_t io, int lcd_cmd, const void *param, size_t param_size) +{ + if (st77916->flags.use_qspi_interface) { + lcd_cmd &= 0xff; + lcd_cmd <<= 8; + lcd_cmd |= LCD_OPCODE_WRITE_CMD << 24; + } + return esp_lcd_panel_io_tx_param(io, lcd_cmd, param, param_size); +} + +static esp_err_t tx_color(st77916_panel_t *st77916, esp_lcd_panel_io_handle_t io, int lcd_cmd, const void *param, size_t param_size) +{ + if (st77916->flags.use_qspi_interface) { + lcd_cmd &= 0xff; + lcd_cmd <<= 8; + lcd_cmd |= LCD_OPCODE_WRITE_COLOR << 24; + } + return esp_lcd_panel_io_tx_color(io, lcd_cmd, param, param_size); +} + +static esp_err_t panel_st77916_del(esp_lcd_panel_t *panel) +{ + st77916_panel_t *st77916 = __containerof(panel, st77916_panel_t, base); + + if (st77916->reset_gpio_num >= 0) { + gpio_reset_pin(st77916->reset_gpio_num); + } + ESP_LOGD(TAG, "del st77916 panel @%p", st77916); + free(st77916); + return ESP_OK; +} + +static esp_err_t panel_st77916_reset(esp_lcd_panel_t *panel) +{ + st77916_panel_t *st77916 = __containerof(panel, st77916_panel_t, base); + esp_lcd_panel_io_handle_t io = st77916->io; + + // Perform hardware reset + if (st77916->reset_gpio_num >= 0) { + gpio_set_level(st77916->reset_gpio_num, st77916->flags.reset_level); + vTaskDelay(pdMS_TO_TICKS(10)); + gpio_set_level(st77916->reset_gpio_num, !st77916->flags.reset_level); + vTaskDelay(pdMS_TO_TICKS(120)); + } else { // Perform software reset + ESP_RETURN_ON_ERROR(tx_param(st77916, io, LCD_CMD_SWRESET, NULL, 0), TAG, "send command failed"); + vTaskDelay(pdMS_TO_TICKS(120)); + } + + return ESP_OK; +} + +static const st77916_lcd_init_cmd_t vendor_specific_init_default[] = { + // {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}, + // // {0xB8, (uint8_t []){0x04}, 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 []){0x35}, 1, 0}, + // // {0xDE, (uint8_t []){0x35}, 1, 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}, + // {0xE0, (uint8_t []){0xF0, 0x06, 0x0B, 0x09, 0x09, 0x16, 0x32, 0x44, 0x4A, 0x37, 0x13, 0x13, 0x2E, 0x34}, 14, 0}, + // {0xE1, (uint8_t []){0xF0, 0x06, 0x0B, 0x09, 0x08, 0x05, 0x32, 0x33, 0x49, 0x17, 0x13, 0x13, 0x2E, 0x34}, 14, 0}, + // {0xF0, (uint8_t []){0x10}, 1, 0}, + // {0xF3, (uint8_t []){0x10}, 1, 0}, + // {0xE0, (uint8_t []){0x0A}, 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 []){0x38}, 1, 0}, + // {0x80, (uint8_t []){0x48}, 1, 0}, + // {0x81, (uint8_t []){0x00}, 1, 0}, + // // {0x82, (uint8_t []){0x04}, 1, 0}, + // {0x82, (uint8_t []){0x05}, 1, 0}, + // {0x83, (uint8_t []){0x02}, 1, 0}, + // // {0x84, (uint8_t []){0xDC}, 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 []){0x38}, 1, 0}, + // {0x88, (uint8_t []){0x48}, 1, 0}, + // {0x89, (uint8_t []){0x00}, 1, 0}, + // // {0x8A, (uint8_t []){0x06}, 1, 0}, + // {0x8A, (uint8_t []){0x07}, 1, 0}, + // {0x8B, (uint8_t []){0x02}, 1, 0}, + // // {0x8C, (uint8_t []){0xDE}, 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 []){0x38}, 1, 0}, + // {0x90, (uint8_t []){0x48}, 1, 0}, + // {0x91, (uint8_t []){0x00}, 1, 0}, + // // {0x92, (uint8_t []){0x08}, 1, 0}, + // {0x92, (uint8_t []){0x09}, 1, 0}, + // {0x93, (uint8_t []){0x02}, 1, 0}, + // // {0x94, (uint8_t []){0xE0}, 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 []){0x38}, 1, 0}, + // {0x98, (uint8_t []){0x48}, 1, 0}, + // {0x99, (uint8_t []){0x00}, 1, 0}, + // // {0x9A, (uint8_t []){0x0A}, 1, 0}, + // {0x9A, (uint8_t []){0x0B}, 1, 0}, + // {0x9B, (uint8_t []){0x02}, 1, 0}, + // // {0x9C, (uint8_t []){0xE2}, 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 []){0x38}, 1, 0}, + // {0xA0, (uint8_t []){0x48}, 1, 0}, + // {0xA1, (uint8_t []){0x00}, 1, 0}, + // // {0xA2, (uint8_t []){0x03}, 1, 0}, + // {0xA2, (uint8_t []){0x04}, 1, 0}, + // {0xA3, (uint8_t []){0x02}, 1, 0}, + // // {0xA4, (uint8_t []){0xDB}, 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 []){0x38}, 1, 0}, + // {0xA8, (uint8_t []){0x48}, 1, 0}, + // {0xA9, (uint8_t []){0x00}, 1, 0}, + // // {0xAA, (uint8_t []){0x05}, 1, 0}, + // {0xAA, (uint8_t []){0x06}, 1, 0}, + // {0xAB, (uint8_t []){0x02}, 1, 0}, + // // {0xAC, (uint8_t []){0xDD}, 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 []){0x38}, 1, 0}, + // {0xB0, (uint8_t []){0x48}, 1, 0}, + // {0xB1, (uint8_t []){0x00}, 1, 0}, + // // {0xB2, (uint8_t []){0x07}, 1, 0}, + // {0xB2, (uint8_t []){0x08}, 1, 0}, + // {0xB3, (uint8_t []){0x02}, 1, 0}, + // // {0xB4, (uint8_t []){0xDF}, 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 []){0x38}, 1, 0}, + // {0xB8, (uint8_t []){0x48}, 1, 0}, + // {0xB9, (uint8_t []){0x00}, 1, 0}, + // // {0xBA, (uint8_t []){0x09}, 1, 0}, + // {0xBA, (uint8_t []){0x0A}, 1, 0}, + // {0xBB, (uint8_t []){0x02}, 1, 0}, + // // {0xBC, (uint8_t []){0xE1}, 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 []){0x22}, 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 []){0x11}, 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}, + // // {0x3A, (uint8_t []){0x55}, 1, 0}, + // {0x21, (uint8_t []){0x00}, 0, 0}, + // {0x11, (uint8_t []){0x00}, 0, 120}, + // {0x29, (uint8_t []){0x00}, 0, 0}, + // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // {0xF0, (uint8_t []){0x28}, 1, 0}, + // {0xF2, (uint8_t []){0x28}, 1, 0}, + // {0x7C, (uint8_t []){0xD1}, 1, 0}, + // {0x83, (uint8_t []){0xE0}, 1, 0}, + // {0x84, (uint8_t []){0x61}, 1, 0}, + // {0xF2, (uint8_t []){0x82}, 1, 0}, + // {0xF0, (uint8_t []){0x00}, 1, 0}, + // {0xF0, (uint8_t []){0x01}, 1, 0}, + // {0xF1, (uint8_t []){0x01}, 1, 0}, + // {0xB0, (uint8_t []){0x49}, 1, 0}, + // {0xB1, (uint8_t []){0x4A}, 1, 0}, + // {0xB2, (uint8_t []){0x1F}, 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}, + // {0xB8, (uint8_t []){0x04}, 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 []){0x01}, 1, 0}, + // {0xC9, (uint8_t []){0xA9}, 1, 0}, + // {0xCA, (uint8_t []){0x41}, 1, 0}, + // {0xCB, (uint8_t []){0x01}, 1, 0}, + // {0xD0, (uint8_t []){0x91}, 1, 0}, + // {0xD1, (uint8_t []){0x68}, 1, 0}, + // {0xD2, (uint8_t []){0x68}, 1, 0}, + // {0xF5, (uint8_t []){0x00, 0xA5}, 2, 0}, + // // {0xDD, (uint8_t []){0x35}, 1, 0}, + // // {0xDE, (uint8_t []){0x35}, 1, 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}, + // {0xE0, (uint8_t []){0xF0, 0x0E, 0x15, 0x0B, 0x0B, 0x07, 0x3C, 0x44, 0x51, 0x38, 0x15, 0x15, 0x32, 0x36}, 14, 0}, + // {0xE1, (uint8_t []){0xF0, 0x0D, 0x15, 0x0A, 0x0A, 0x26, 0x3B, 0x43, 0x50, 0x37, 0x14, 0x15, 0x31, 0x36}, 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 []){0x0B}, 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 []){0x38}, 1, 0}, + // {0x80, (uint8_t []){0x38}, 1, 0}, + // {0x81, (uint8_t []){0x00}, 1, 0}, + // // {0x82, (uint8_t []){0x04}, 1, 0}, + // {0x82, (uint8_t []){0x04}, 1, 0}, + // {0x83, (uint8_t []){0x02}, 1, 0}, + // // {0x84, (uint8_t []){0xDC}, 1, 0}, + // {0x84, (uint8_t []){0xDC}, 1, 0}, + // {0x85, (uint8_t []){0x00}, 1, 0}, + // {0x86, (uint8_t []){0x00}, 1, 0}, + // {0x87, (uint8_t []){0x00}, 1, 0}, + // // {0x88, (uint8_t []){0x38}, 1, 0}, + // {0x88, (uint8_t []){0x38}, 1, 0}, + // {0x89, (uint8_t []){0x00}, 1, 0}, + // // {0x8A, (uint8_t []){0x06}, 1, 0}, + // {0x8A, (uint8_t []){0x06}, 1, 0}, + // {0x8B, (uint8_t []){0x02}, 1, 0}, + // // {0x8C, (uint8_t []){0xDE}, 1, 0}, + // {0x8C, (uint8_t []){0xDE}, 1, 0}, + // {0x8D, (uint8_t []){0x00}, 1, 0}, + // {0x8E, (uint8_t []){0x00}, 1, 0}, + // {0x8F, (uint8_t []){0x00}, 1, 0}, + // // {0x90, (uint8_t []){0x38}, 1, 0}, + // {0x90, (uint8_t []){0x38}, 1, 0}, + // {0x91, (uint8_t []){0x00}, 1, 0}, + // // {0x92, (uint8_t []){0x08}, 1, 0}, + // {0x92, (uint8_t []){0x08}, 1, 0}, + // {0x93, (uint8_t []){0x02}, 1, 0}, + // // {0x94, (uint8_t []){0xE0}, 1, 0}, + // {0x94, (uint8_t []){0xE0}, 1, 0}, + // {0x95, (uint8_t []){0x00}, 1, 0}, + // {0x96, (uint8_t []){0x00}, 1, 0}, + // {0x97, (uint8_t []){0x00}, 1, 0}, + // // {0x98, (uint8_t []){0x38}, 1, 0}, + // {0x98, (uint8_t []){0x38}, 1, 0}, + // {0x99, (uint8_t []){0x00}, 1, 0}, + // // {0x9A, (uint8_t []){0x0A}, 1, 0}, + // {0x9A, (uint8_t []){0x0A}, 1, 0}, + // {0x9B, (uint8_t []){0x02}, 1, 0}, + // // {0x9C, (uint8_t []){0xE2}, 1, 0}, + // {0x9C, (uint8_t []){0xE2}, 1, 0}, + // {0x9D, (uint8_t []){0x00}, 1, 0}, + // {0x9E, (uint8_t []){0x00}, 1, 0}, + // {0x9F, (uint8_t []){0x00}, 1, 0}, + // // {0xA0, (uint8_t []){0x38}, 1, 0}, + // {0xA0, (uint8_t []){0x38}, 1, 0}, + // {0xA1, (uint8_t []){0x00}, 1, 0}, + // // {0xA2, (uint8_t []){0x03}, 1, 0}, + // {0xA2, (uint8_t []){0x03}, 1, 0}, + // {0xA3, (uint8_t []){0x02}, 1, 0}, + // // {0xA4, (uint8_t []){0xDB}, 1, 0}, + // {0xA4, (uint8_t []){0xDB}, 1, 0}, + // {0xA5, (uint8_t []){0x00}, 1, 0}, + // {0xA6, (uint8_t []){0x00}, 1, 0}, + // {0xA7, (uint8_t []){0x00}, 1, 0}, + // // {0xA8, (uint8_t []){0x38}, 1, 0}, + // {0xA8, (uint8_t []){0x38}, 1, 0}, + // {0xA9, (uint8_t []){0x00}, 1, 0}, + // // {0xAA, (uint8_t []){0x05}, 1, 0}, + // {0xAA, (uint8_t []){0x05}, 1, 0}, + // {0xAB, (uint8_t []){0x02}, 1, 0}, + // // {0xAC, (uint8_t []){0xDD}, 1, 0}, + // {0xAC, (uint8_t []){0xDD}, 1, 0}, + // {0xAD, (uint8_t []){0x00}, 1, 0}, + // {0xAE, (uint8_t []){0x00}, 1, 0}, + // {0xAF, (uint8_t []){0x00}, 1, 0}, + // // {0xB0, (uint8_t []){0x38}, 1, 0}, + // {0xB0, (uint8_t []){0x38}, 1, 0}, + // {0xB1, (uint8_t []){0x00}, 1, 0}, + // // {0xB2, (uint8_t []){0x07}, 1, 0}, + // {0xB2, (uint8_t []){0x07}, 1, 0}, + // {0xB3, (uint8_t []){0x02}, 1, 0}, + // // {0xB4, (uint8_t []){0xDF}, 1, 0}, + // {0xB4, (uint8_t []){0xDF}, 1, 0}, + // {0xB5, (uint8_t []){0x00}, 1, 0}, + // {0xB6, (uint8_t []){0x00}, 1, 0}, + // {0xB7, (uint8_t []){0x00}, 1, 0}, + // // {0xB8, (uint8_t []){0x38}, 1, 0}, + // {0xB8, (uint8_t []){0x38}, 1, 0}, + // {0xB9, (uint8_t []){0x00}, 1, 0}, + // // {0xBA, (uint8_t []){0x09}, 1, 0}, + // {0xBA, (uint8_t []){0x09}, 1, 0}, + // {0xBB, (uint8_t []){0x02}, 1, 0}, + // // {0xBC, (uint8_t []){0xE1}, 1, 0}, + // {0xBC, (uint8_t []){0xE1}, 1, 0}, + // {0xBD, (uint8_t []){0x00}, 1, 0}, + // {0xBE, (uint8_t []){0x00}, 1, 0}, + // {0xBF, (uint8_t []){0x00}, 1, 0}, + // // {0xC0, (uint8_t []){0x22}, 1, 0}, + // {0xC0, (uint8_t []){0x22}, 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 []){0x11}, 1, 0}, + // {0xD0, (uint8_t []){0x11}, 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}, + // // {0x3A, (uint8_t []){0x55}, 1, 0}, + // {0x21, (uint8_t []){0x00}, 0, 0}, + // {0x11, (uint8_t []){0x00}, 0, 120}, + // {0x29, (uint8_t []){0x00}, 0, 0}, + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + {0xF0, (uint8_t []){0x28}, 1, 0}, + {0xF2, (uint8_t []){0x28}, 1, 0}, + {0x7C, (uint8_t []){0xD1}, 1, 0}, + {0x83, (uint8_t []){0xE0}, 1, 0}, + {0x84, (uint8_t []){0x61}, 1, 0}, + {0xF2, (uint8_t []){0x82}, 1, 0}, + {0xF0, (uint8_t []){0x00}, 1, 0}, + {0xF0, (uint8_t []){0x01}, 1, 0}, + {0xF1, (uint8_t []){0x01}, 1, 0}, + {0xB0, (uint8_t []){0x49}, 1, 0}, + {0xB1, (uint8_t []){0x4A}, 1, 0}, + {0xB2, (uint8_t []){0x1F}, 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}, + {0xB8, (uint8_t []){0x04}, 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 []){0x01}, 1, 0}, + {0xC9, (uint8_t []){0xA9}, 1, 0}, + {0xCA, (uint8_t []){0x41}, 1, 0}, + {0xCB, (uint8_t []){0x01}, 1, 0}, + {0xD0, (uint8_t []){0x91}, 1, 0}, + {0xD1, (uint8_t []){0x68}, 1, 0}, + {0xD2, (uint8_t []){0x68}, 1, 0}, + {0xF5, (uint8_t []){0x00, 0xA5}, 2, 0}, + // {0xDD, (uint8_t []){0x35}, 1, 0}, + // {0xDE, (uint8_t []){0x35}, 1, 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}, + // {0xE0, (uint8_t []){0xF0, 0x0E, 0x15, 0x0B, 0x0B, 0x07, 0x3C, 0x44, 0x51, 0x38, 0x15, 0x15, 0x32, 0x36}, 14, 0}, + // {0xE1, (uint8_t []){0xF0, 0x0D, 0x15, 0x0A, 0x0A, 0x26, 0x3B, 0x43, 0x50, 0x37, 0x14, 0x15, 0x31, 0x36}, 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 []){0x0B}, 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 []){0x38}, 1, 0}, + {0x80, (uint8_t []){0x38}, 1, 0}, + {0x81, (uint8_t []){0x00}, 1, 0}, + // {0x82, (uint8_t []){0x04}, 1, 0}, + {0x82, (uint8_t []){0x04}, 1, 0}, + {0x83, (uint8_t []){0x02}, 1, 0}, + // {0x84, (uint8_t []){0xDC}, 1, 0}, + {0x84, (uint8_t []){0xDC}, 1, 0}, + {0x85, (uint8_t []){0x00}, 1, 0}, + {0x86, (uint8_t []){0x00}, 1, 0}, + {0x87, (uint8_t []){0x00}, 1, 0}, + // {0x88, (uint8_t []){0x38}, 1, 0}, + {0x88, (uint8_t []){0x38}, 1, 0}, + {0x89, (uint8_t []){0x00}, 1, 0}, + // {0x8A, (uint8_t []){0x06}, 1, 0}, + {0x8A, (uint8_t []){0x06}, 1, 0}, + {0x8B, (uint8_t []){0x02}, 1, 0}, + // {0x8C, (uint8_t []){0xDE}, 1, 0}, + {0x8C, (uint8_t []){0xDE}, 1, 0}, + {0x8D, (uint8_t []){0x00}, 1, 0}, + {0x8E, (uint8_t []){0x00}, 1, 0}, + {0x8F, (uint8_t []){0x00}, 1, 0}, + // {0x90, (uint8_t []){0x38}, 1, 0}, + {0x90, (uint8_t []){0x38}, 1, 0}, + {0x91, (uint8_t []){0x00}, 1, 0}, + // {0x92, (uint8_t []){0x08}, 1, 0}, + {0x92, (uint8_t []){0x08}, 1, 0}, + {0x93, (uint8_t []){0x02}, 1, 0}, + // {0x94, (uint8_t []){0xE0}, 1, 0}, + {0x94, (uint8_t []){0xE0}, 1, 0}, + {0x95, (uint8_t []){0x00}, 1, 0}, + {0x96, (uint8_t []){0x00}, 1, 0}, + {0x97, (uint8_t []){0x00}, 1, 0}, + // {0x98, (uint8_t []){0x38}, 1, 0}, + {0x98, (uint8_t []){0x38}, 1, 0}, + {0x99, (uint8_t []){0x00}, 1, 0}, + // {0x9A, (uint8_t []){0x0A}, 1, 0}, + {0x9A, (uint8_t []){0x0A}, 1, 0}, + {0x9B, (uint8_t []){0x02}, 1, 0}, + // {0x9C, (uint8_t []){0xE2}, 1, 0}, + {0x9C, (uint8_t []){0xE2}, 1, 0}, + {0x9D, (uint8_t []){0x00}, 1, 0}, + {0x9E, (uint8_t []){0x00}, 1, 0}, + {0x9F, (uint8_t []){0x00}, 1, 0}, + // {0xA0, (uint8_t []){0x38}, 1, 0}, + {0xA0, (uint8_t []){0x38}, 1, 0}, + {0xA1, (uint8_t []){0x00}, 1, 0}, + // {0xA2, (uint8_t []){0x03}, 1, 0}, + {0xA2, (uint8_t []){0x03}, 1, 0}, + {0xA3, (uint8_t []){0x02}, 1, 0}, + // {0xA4, (uint8_t []){0xDB}, 1, 0}, + {0xA4, (uint8_t []){0xDB}, 1, 0}, + {0xA5, (uint8_t []){0x00}, 1, 0}, + {0xA6, (uint8_t []){0x00}, 1, 0}, + {0xA7, (uint8_t []){0x00}, 1, 0}, + // {0xA8, (uint8_t []){0x38}, 1, 0}, + {0xA8, (uint8_t []){0x38}, 1, 0}, + {0xA9, (uint8_t []){0x00}, 1, 0}, + // {0xAA, (uint8_t []){0x05}, 1, 0}, + {0xAA, (uint8_t []){0x05}, 1, 0}, + {0xAB, (uint8_t []){0x02}, 1, 0}, + // {0xAC, (uint8_t []){0xDD}, 1, 0}, + {0xAC, (uint8_t []){0xDD}, 1, 0}, + {0xAD, (uint8_t []){0x00}, 1, 0}, + {0xAE, (uint8_t []){0x00}, 1, 0}, + {0xAF, (uint8_t []){0x00}, 1, 0}, + // {0xB0, (uint8_t []){0x38}, 1, 0}, + {0xB0, (uint8_t []){0x38}, 1, 0}, + {0xB1, (uint8_t []){0x00}, 1, 0}, + // {0xB2, (uint8_t []){0x07}, 1, 0}, + {0xB2, (uint8_t []){0x07}, 1, 0}, + {0xB3, (uint8_t []){0x02}, 1, 0}, + // {0xB4, (uint8_t []){0xDF}, 1, 0}, + {0xB4, (uint8_t []){0xDF}, 1, 0}, + {0xB5, (uint8_t []){0x00}, 1, 0}, + {0xB6, (uint8_t []){0x00}, 1, 0}, + {0xB7, (uint8_t []){0x00}, 1, 0}, + // {0xB8, (uint8_t []){0x38}, 1, 0}, + {0xB8, (uint8_t []){0x38}, 1, 0}, + {0xB9, (uint8_t []){0x00}, 1, 0}, + // {0xBA, (uint8_t []){0x09}, 1, 0}, + {0xBA, (uint8_t []){0x09}, 1, 0}, + {0xBB, (uint8_t []){0x02}, 1, 0}, + // {0xBC, (uint8_t []){0xE1}, 1, 0}, + {0xBC, (uint8_t []){0xE1}, 1, 0}, + {0xBD, (uint8_t []){0x00}, 1, 0}, + {0xBE, (uint8_t []){0x00}, 1, 0}, + {0xBF, (uint8_t []){0x00}, 1, 0}, + // {0xC0, (uint8_t []){0x22}, 1, 0}, + {0xC0, (uint8_t []){0x22}, 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 []){0x11}, 1, 0}, + {0xD0, (uint8_t []){0x11}, 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}, + // {0x3A, (uint8_t []){0x55}, 1, 0}, + {0x21, (uint8_t []){0x00}, 0, 0}, + {0x11, (uint8_t []){0x00}, 0, 120}, + {0x29, (uint8_t []){0x00}, 0, 0}, +}; + +static esp_err_t panel_st77916_init(esp_lcd_panel_t *panel) +{ + st77916_panel_t *st77916 = __containerof(panel, st77916_panel_t, base); + esp_lcd_panel_io_handle_t io = st77916->io; + const st77916_lcd_init_cmd_t *init_cmds = NULL; + uint16_t init_cmds_size = 0; + bool is_user_set = true; + bool is_cmd_overwritten = false; + + ESP_RETURN_ON_ERROR(tx_param(st77916, io, LCD_CMD_MADCTL, (uint8_t[]) { + st77916->madctl_val, + }, 1), TAG, "send command failed"); + ESP_RETURN_ON_ERROR(tx_param(st77916, io, LCD_CMD_COLMOD, (uint8_t[]) { + st77916->colmod_val, + }, 1), TAG, "send command failed"); + + // vendor specific initialization, it can be different between manufacturers + // should consult the LCD supplier for initialization sequence code + if (st77916->init_cmds) { + init_cmds = st77916->init_cmds; + init_cmds_size = st77916->init_cmds_size; + } else { + init_cmds = vendor_specific_init_default; + init_cmds_size = sizeof(vendor_specific_init_default) / sizeof(st77916_lcd_init_cmd_t); + } + + for (int i = 0; i < init_cmds_size; i++) { + // Check if the command has been used or conflicts with the internal + if (is_user_set && (init_cmds[i].data_bytes > 0)) { + switch (init_cmds[i].cmd) { + case LCD_CMD_MADCTL: + is_cmd_overwritten = true; + st77916->madctl_val = ((uint8_t *)init_cmds[i].data)[0]; + break; + case LCD_CMD_COLMOD: + is_cmd_overwritten = true; + st77916->colmod_val = ((uint8_t *)init_cmds[i].data)[0]; + break; + default: + is_cmd_overwritten = false; + break; + } + + if (is_cmd_overwritten) { + is_cmd_overwritten = false; + ESP_LOGW(TAG, "The %02Xh command has been used and will be overwritten by external initialization sequence", init_cmds[i].cmd); + } + } + + // Send command + ESP_RETURN_ON_ERROR(tx_param(st77916, io, init_cmds[i].cmd, init_cmds[i].data, init_cmds[i].data_bytes), TAG, "send command failed"); + vTaskDelay(pdMS_TO_TICKS(init_cmds[i].delay_ms)); + + // Check if the current cmd is the "command set" cmd + if ((init_cmds[i].cmd == ST77916_CMD_SET)) { + is_user_set = ((uint8_t *)init_cmds[i].data)[0] == ST77916_PARAM_SET ? true : false; + } + } + ESP_LOGD(TAG, "send init commands success"); + + return ESP_OK; +} + +static esp_err_t panel_st77916_draw_bitmap(esp_lcd_panel_t *panel, int x_start, int y_start, int x_end, int y_end, const void *color_data) +{ + st77916_panel_t *st77916 = __containerof(panel, st77916_panel_t, base); + assert((x_start < x_end) && (y_start < y_end) && "start position must be smaller than end position"); + esp_lcd_panel_io_handle_t io = st77916->io; + + x_start += st77916->x_gap; + x_end += st77916->x_gap; + y_start += st77916->y_gap; + y_end += st77916->y_gap; + + // define an area of frame memory where MCU can access + ESP_RETURN_ON_ERROR(tx_param(st77916, io, LCD_CMD_CASET, (uint8_t[]) { + (x_start >> 8) & 0xFF, + x_start & 0xFF, + ((x_end - 1) >> 8) & 0xFF, + (x_end - 1) & 0xFF, + }, 4), TAG, "send command failed"); + ESP_RETURN_ON_ERROR(tx_param(st77916, io, LCD_CMD_RASET, (uint8_t[]) { + (y_start >> 8) & 0xFF, + y_start & 0xFF, + ((y_end - 1) >> 8) & 0xFF, + (y_end - 1) & 0xFF, + }, 4), TAG, "send command failed"); + // transfer frame buffer + size_t len = (x_end - x_start) * (y_end - y_start) * st77916->fb_bits_per_pixel / 8; + tx_color(st77916, io, LCD_CMD_RAMWR, color_data, len); + + return ESP_OK; +} + +static esp_err_t panel_st77916_invert_color(esp_lcd_panel_t *panel, bool invert_color_data) +{ + st77916_panel_t *st77916 = __containerof(panel, st77916_panel_t, base); + esp_lcd_panel_io_handle_t io = st77916->io; + int command = 0; + if (invert_color_data) { + command = LCD_CMD_INVON; + } else { + command = LCD_CMD_INVOFF; + } + ESP_RETURN_ON_ERROR(tx_param(st77916, io, command, NULL, 0), TAG, "send command failed"); + return ESP_OK; +} + +static esp_err_t panel_st77916_mirror(esp_lcd_panel_t *panel, bool mirror_x, bool mirror_y) +{ + st77916_panel_t *st77916 = __containerof(panel, st77916_panel_t, base); + esp_lcd_panel_io_handle_t io = st77916->io; + esp_err_t ret = ESP_OK; + + if (mirror_x) { + st77916->madctl_val |= BIT(6); + } else { + st77916->madctl_val &= ~BIT(6); + } + if (mirror_y) { + st77916->madctl_val |= BIT(7); + } else { + st77916->madctl_val &= ~BIT(7); + } + ESP_RETURN_ON_ERROR(tx_param(st77916, io, LCD_CMD_MADCTL, (uint8_t[]) { + st77916->madctl_val + }, 1), TAG, "send command failed"); + return ret; +} + +static esp_err_t panel_st77916_swap_xy(esp_lcd_panel_t *panel, bool swap_axes) +{ + st77916_panel_t *st77916 = __containerof(panel, st77916_panel_t, base); + esp_lcd_panel_io_handle_t io = st77916->io; + if (swap_axes) { + st77916->madctl_val |= LCD_CMD_MV_BIT; + } else { + st77916->madctl_val &= ~LCD_CMD_MV_BIT; + } + esp_lcd_panel_io_tx_param(io, LCD_CMD_MADCTL, (uint8_t[]) { + st77916->madctl_val + }, 1); + return ESP_OK; +} + +static esp_err_t panel_st77916_set_gap(esp_lcd_panel_t *panel, int x_gap, int y_gap) +{ + st77916_panel_t *st77916 = __containerof(panel, st77916_panel_t, base); + st77916->x_gap = x_gap; + st77916->y_gap = y_gap; + return ESP_OK; +} + +static esp_err_t panel_st77916_disp_on_off(esp_lcd_panel_t *panel, bool on_off) +{ + st77916_panel_t *st77916 = __containerof(panel, st77916_panel_t, base); + esp_lcd_panel_io_handle_t io = st77916->io; + int command = 0; + + if (on_off) { + command = LCD_CMD_DISPON; + } else { + command = LCD_CMD_DISPOFF; + } + ESP_RETURN_ON_ERROR(tx_param(st77916, io, command, NULL, 0), TAG, "send command failed"); + return ESP_OK; +} diff --git a/Lib/Display/LCD_Driver/esp_lcd_st77916/esp_lcd_st77916.h b/Lib/Display/LCD_Driver/esp_lcd_st77916/esp_lcd_st77916.h new file mode 100644 index 0000000..cd4311c --- /dev/null +++ b/Lib/Display/LCD_Driver/esp_lcd_st77916/esp_lcd_st77916.h @@ -0,0 +1,114 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include + +#include "esp_lcd_panel_vendor.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief LCD panel initialization commands. + * + */ +typedef struct { + int cmd; /*user_data; + int offsetx1 = area->x1; + int offsetx2 = area->x2; + int offsety1 = area->y1; + int offsety2 = area->y2; + // copy a buffer's content to a specific area of the display + esp_lcd_panel_draw_bitmap(panel_handle, offsetx1, offsety1, offsetx2 +1, offsety2 + 1, color_map); + lv_disp_flush_ready(drv); +} + +/*Read the touchpad*/ +void example_touchpad_read( lv_indev_drv_t * drv, lv_indev_data_t * data ) +{ + uint16_t touchpad_x[5] = {0}; + uint16_t touchpad_y[5] = {0}; + uint8_t touchpad_cnt = 0; + + /* Read touch controller data */ + esp_lcd_touch_read_data(drv->user_data); + + /* Get coordinates */ + bool touchpad_pressed = esp_lcd_touch_get_coordinates(drv->user_data, touchpad_x, touchpad_y, NULL, &touchpad_cnt, 5); + + // printf("CCCCCCCCCCCCC=%d \r\n",touchpad_cnt); + if (touchpad_pressed && touchpad_cnt > 0) { + data->point.x = touchpad_x[0]; + data->point.y = touchpad_y[0]; + data->state = LV_INDEV_STATE_PR; + // printf("X=%u Y=%u num=%d \r\n", data->point.x, data->point.y,touchpad_cnt); + } else { + data->state = LV_INDEV_STATE_REL; + } + +} +/* Rotate display and touch, when rotated screen in LVGL. Called when driver parameters are updated. */ +void example_lvgl_port_update_callback(lv_disp_drv_t *drv) +{ + esp_lcd_panel_handle_t panel_handle = (esp_lcd_panel_handle_t) drv->user_data; + + switch (drv->rotated) { + case LV_DISP_ROT_NONE: + // Rotate LCD display + esp_lcd_panel_swap_xy(panel_handle, false); + esp_lcd_panel_mirror(panel_handle, true, false); + break; + case LV_DISP_ROT_90: + // Rotate LCD display + esp_lcd_panel_swap_xy(panel_handle, true); + esp_lcd_panel_mirror(panel_handle, true, true); + break; + case LV_DISP_ROT_180: + // Rotate LCD display + esp_lcd_panel_swap_xy(panel_handle, false); + esp_lcd_panel_mirror(panel_handle, false, true); + break; + case LV_DISP_ROT_270: + // Rotate LCD display + esp_lcd_panel_swap_xy(panel_handle, true); + esp_lcd_panel_mirror(panel_handle, false, false); + break; + } +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +lv_disp_t *disp; +void LVGL_Init(void) +{ + ESP_LOGI(TAG_LVGL, "Initialize LVGL library"); + lv_init(); + + lv_color_t *buf1 = heap_caps_malloc(LVGL_BUF_LEN * sizeof(lv_color_t), MALLOC_CAP_SPIRAM); + assert(buf1); + lv_color_t *buf2 = heap_caps_malloc(LVGL_BUF_LEN * sizeof(lv_color_t) , MALLOC_CAP_SPIRAM); + assert(buf2); + lv_disp_draw_buf_init(&disp_buf, buf1, buf2, LVGL_BUF_LEN); // initialize LVGL draw buffers + + ESP_LOGI(TAG_LVGL, "Register display driver to LVGL"); + lv_disp_drv_init(&disp_drv); // Create a new screen object and initialize the associated device + disp_drv.hor_res = EXAMPLE_LCD_WIDTH; + disp_drv.ver_res = EXAMPLE_LCD_HEIGHT; // Horizontal pixel count + // disp_drv.rotated = LV_DISP_ROT_90; // 图像旋转 // Vertical axis pixel count + disp_drv.flush_cb = example_lvgl_flush_cb; // Function : copy a buffer's content to a specific area of the display + disp_drv.drv_update_cb = example_lvgl_port_update_callback; // Function : Rotate display and touch, when rotated screen in LVGL. Called when driver parameters are updated. + disp_drv.draw_buf = &disp_buf; // LVGL will use this buffer(s) to draw the screens contents + disp_drv.user_data = panel_handle; + ESP_LOGI(TAG_LVGL,"Register display indev to LVGL"); // Custom display driver user data + disp = lv_disp_drv_register(&disp_drv); + + lv_indev_drv_init ( &indev_drv ); + indev_drv.type = LV_INDEV_TYPE_POINTER; + indev_drv.disp = disp; + indev_drv.read_cb = example_touchpad_read; + indev_drv.user_data = tp; + lv_indev_drv_register( &indev_drv ); + + /********************* LVGL *********************/ + ESP_LOGI(TAG_LVGL, "Install LVGL tick timer"); + // Tick interface for LVGL (using esp_timer to generate 2ms periodic event) + const esp_timer_create_args_t lvgl_tick_timer_args = { + .callback = &example_increase_lvgl_tick, + .name = "lvgl_tick" + }; + + esp_timer_handle_t lvgl_tick_timer = NULL; + ESP_ERROR_CHECK(esp_timer_create(&lvgl_tick_timer_args, &lvgl_tick_timer)); + ESP_ERROR_CHECK(esp_timer_start_periodic(lvgl_tick_timer, EXAMPLE_LVGL_TICK_PERIOD_MS * 1000)); + +} diff --git a/Lib/Display/LVGL_Driver/LVGL_Driver.h b/Lib/Display/LVGL_Driver/LVGL_Driver.h new file mode 100644 index 0000000..186759a --- /dev/null +++ b/Lib/Display/LVGL_Driver/LVGL_Driver.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_timer.h" +#include "esp_err.h" +#include "esp_log.h" +#include "lvgl.h" +#include "demos/lv_demos.h" + +#include "ST77916.h" + +#define LVGL_BUF_LEN (EXAMPLE_LCD_WIDTH * EXAMPLE_LCD_HEIGHT / 20) +#define EXAMPLE_LVGL_TICK_PERIOD_MS 2 + +extern lv_disp_draw_buf_t disp_buf; // contains internal graphic buffer(s) called draw buffer(s) +extern lv_disp_drv_t disp_drv; // contains callback functions +extern lv_disp_t *disp; + +void example_lvgl_flush_cb(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map); +/* Rotate display and touch, when rotated screen in LVGL. Called when driver parameters are updated. */ +void example_lvgl_port_update_callback(lv_disp_drv_t *drv); +void example_increase_lvgl_tick(void *arg); + +void LVGL_Init(void); // Call this function to initialize the screen (must be called in the main function) !!!!! \ No newline at end of file diff --git a/Lib/Display/LVGL_UI/LVGL_Example.c b/Lib/Display/LVGL_UI/LVGL_Example.c new file mode 100644 index 0000000..934db1c --- /dev/null +++ b/Lib/Display/LVGL_UI/LVGL_Example.c @@ -0,0 +1,360 @@ +#include "LVGL_Example.h" +#include "LVGL_Music.h" +#include +// #include +// #include + + +/********************** + * TYPEDEFS + **********************/ +typedef enum { + DISP_SMALL, + DISP_MEDIUM, + DISP_LARGE, +} disp_size_t; + +/********************** + * STATIC PROTOTYPES + **********************/ +static void Onboard_create(lv_obj_t * parent); +static void Music_create(lv_obj_t * parent); + +static void ta_event_cb(lv_event_t * e); +void example1_increase_lvgl_tick(lv_timer_t * t); +/********************** + * STATIC VARIABLES + **********************/ +static disp_size_t disp_size; + +static lv_obj_t * tv; +// static lv_obj_t * calendar; +lv_style_t style_text_muted; +lv_style_t style_title; +static lv_style_t style_icon; +static lv_style_t style_bullet; + + +static const lv_font_t * font_large; +static const lv_font_t * font_normal; + +static lv_timer_t * auto_step_timer; +static lv_color_t original_screen_bg_color; + +static lv_timer_t * meter2_timer; + +lv_obj_t * SD_Size; +lv_obj_t * FlashSize; +lv_obj_t * BAT_Volts; +lv_obj_t * Board_angle; +lv_obj_t * RTC_Time; +lv_obj_t * Wireless_Scan; +lv_obj_t * Backlight_slider; + + + +void auto_switch(lv_timer_t * t) +{ + uint16_t page = lv_tabview_get_tab_act(tv); + + if (page == 0) { + lv_tabview_set_act(tv, 1, LV_ANIM_ON); + } else if (page == 3) { + lv_tabview_set_act(tv, 2, LV_ANIM_ON); + } +} + +void Lvgl_Example1(void){ + + disp_size = DISP_SMALL; + + font_large = LV_FONT_DEFAULT; + font_normal = LV_FONT_DEFAULT; + + lv_coord_t tab_h; + tab_h = 45; + #if LV_FONT_MONTSERRAT_18 + font_large = &lv_font_montserrat_18; + #else + LV_LOG_WARN("LV_FONT_MONTSERRAT_18 is not enabled for the widgets demo. Using LV_FONT_DEFAULT instead."); + #endif + #if LV_FONT_MONTSERRAT_12 + font_normal = &lv_font_montserrat_12; + #else + LV_LOG_WARN("LV_FONT_MONTSERRAT_12 is not enabled for the widgets demo. Using LV_FONT_DEFAULT instead."); + #endif + + lv_style_init(&style_text_muted); + lv_style_set_text_opa(&style_text_muted, LV_OPA_90); + + lv_style_init(&style_title); + lv_style_set_text_font(&style_title, font_large); + + lv_style_init(&style_icon); + lv_style_set_text_color(&style_icon, lv_theme_get_color_primary(NULL)); + lv_style_set_text_font(&style_icon, font_large); + + lv_style_init(&style_bullet); + lv_style_set_border_width(&style_bullet, 0); + lv_style_set_radius(&style_bullet, LV_RADIUS_CIRCLE); + + tv = lv_tabview_create(lv_scr_act(), LV_DIR_TOP, tab_h); + + lv_obj_set_style_text_font(lv_scr_act(), font_normal, 0); + + if(disp_size == DISP_LARGE) { + lv_obj_t * tab_btns = lv_tabview_get_tab_btns(tv); + lv_obj_set_style_pad_left(tab_btns, LV_HOR_RES / 2, 0); + lv_obj_t * logo = lv_img_create(tab_btns); + LV_IMG_DECLARE(img_lvgl_logo); + lv_img_set_src(logo, &img_lvgl_logo); + lv_obj_align(logo, LV_ALIGN_LEFT_MID, -LV_HOR_RES / 2 + 25, 0); + + lv_obj_t * label = lv_label_create(tab_btns); + lv_obj_add_style(label, &style_title, 0); + lv_label_set_text(label, "LVGL v8"); + lv_obj_align_to(label, logo, LV_ALIGN_OUT_RIGHT_TOP, 10, 0); + + label = lv_label_create(tab_btns); + lv_label_set_text(label, "Widgets demo"); + lv_obj_add_style(label, &style_text_muted, 0); + lv_obj_align_to(label, logo, LV_ALIGN_OUT_RIGHT_BOTTOM, 10, 0); + } + + lv_obj_t * t0 = lv_tabview_add_tab(tv, " "); + lv_obj_t * t1 = lv_tabview_add_tab(tv, "Onboard"); + lv_obj_t * t2 = lv_tabview_add_tab(tv, "music"); + lv_obj_t * t3 = lv_tabview_add_tab(tv, " "); + + LV_UNUSED(t0); + LV_UNUSED(t3); + Onboard_create(t1); + Music_create(t2); + lv_timer_create(auto_switch, 100, NULL); + +} + +void Lvgl_Example1_close(void) +{ + /*Delete all animation*/ + lv_anim_del(NULL, NULL); + + lv_timer_del(meter2_timer); + meter2_timer = NULL; + + lv_obj_clean(lv_scr_act()); + + lv_style_reset(&style_text_muted); + lv_style_reset(&style_title); + lv_style_reset(&style_icon); + lv_style_reset(&style_bullet); +} + + +/********************** +* STATIC FUNCTIONS +**********************/ + +static void Onboard_create(lv_obj_t * parent) +{ + + /*Create a panel*/ + lv_obj_t * panel1 = lv_obj_create(parent); + lv_obj_set_height(panel1, LV_SIZE_CONTENT); + + lv_obj_t * panel1_title = lv_label_create(panel1); + lv_label_set_text(panel1_title, "Onboard parameter"); + lv_obj_add_style(panel1_title, &style_title, 0); + + lv_obj_t * SD_label = lv_label_create(panel1); + lv_label_set_text(SD_label, "SD Card"); + lv_obj_add_style(SD_label, &style_text_muted, 0); + + SD_Size = lv_textarea_create(panel1); + lv_textarea_set_one_line(SD_Size, true); + lv_textarea_set_placeholder_text(SD_Size, "SD Size"); + lv_obj_add_event_cb(SD_Size, ta_event_cb, LV_EVENT_ALL, NULL); + + lv_obj_t * Flash_label = lv_label_create(panel1); + lv_label_set_text(Flash_label, "Flash Size"); + lv_obj_add_style(Flash_label, &style_text_muted, 0); + + FlashSize = lv_textarea_create(panel1); + lv_textarea_set_one_line(FlashSize, true); + lv_textarea_set_placeholder_text(FlashSize, "Flash Size"); + lv_obj_add_event_cb(FlashSize, ta_event_cb, LV_EVENT_ALL, NULL); + + lv_obj_t * BAT_label = lv_label_create(panel1); + lv_label_set_text(BAT_label, "Battery Voltage"); + lv_obj_add_style(BAT_label, &style_text_muted, 0); + + BAT_Volts = lv_textarea_create(panel1); + lv_textarea_set_one_line(BAT_Volts, true); + lv_textarea_set_placeholder_text(BAT_Volts, "BAT Volts"); + lv_obj_add_event_cb(BAT_Volts, ta_event_cb, LV_EVENT_ALL, NULL); + + lv_obj_t * angle_label = lv_label_create(panel1); + lv_label_set_text(angle_label, "Angular deflection"); + lv_obj_add_style(angle_label, &style_text_muted, 0); + + Board_angle = lv_textarea_create(panel1); + lv_textarea_set_one_line(Board_angle, true); + lv_textarea_set_placeholder_text(Board_angle, "Board angle"); + lv_obj_add_event_cb(Board_angle, ta_event_cb, LV_EVENT_ALL, NULL); + + lv_obj_t * Time_label = lv_label_create(panel1); + lv_label_set_text(Time_label, "RTC Time"); + lv_obj_add_style(Time_label, &style_text_muted, 0); + + RTC_Time = lv_textarea_create(panel1); + lv_textarea_set_one_line(RTC_Time, true); + lv_textarea_set_placeholder_text(RTC_Time, "Display time"); + lv_obj_add_event_cb(RTC_Time, ta_event_cb, LV_EVENT_ALL, NULL); + + + lv_obj_t * Wireless_label = lv_label_create(panel1); + lv_label_set_text(Wireless_label, "Wireless scan"); + lv_obj_add_style(Wireless_label, &style_text_muted, 0); + + Wireless_Scan = lv_textarea_create(panel1); + lv_textarea_set_one_line(Wireless_Scan, true); + lv_textarea_set_placeholder_text(Wireless_Scan, "Wireless number"); + lv_obj_add_event_cb(Wireless_Scan, ta_event_cb, LV_EVENT_ALL, NULL); + + lv_obj_t * Backlight_label = lv_label_create(panel1); + lv_label_set_text(Backlight_label, "Backlight brightness"); + lv_obj_add_style(Backlight_label, &style_text_muted, 0); + + Backlight_slider = lv_slider_create(panel1); + lv_obj_add_flag(Backlight_slider, LV_OBJ_FLAG_CLICKABLE); + lv_obj_set_size(Backlight_slider, 200, 35); + lv_obj_set_style_radius(Backlight_slider, 3, LV_PART_KNOB); // Adjust the value for more or less rounding + lv_obj_set_style_bg_opa(Backlight_slider, LV_OPA_TRANSP, LV_PART_KNOB); + // lv_obj_set_style_pad_all(Backlight_slider, 0, LV_PART_KNOB); + lv_obj_set_style_bg_color(Backlight_slider, lv_color_hex(0xAAAAAA), LV_PART_KNOB); + lv_obj_set_style_bg_color(Backlight_slider, lv_color_hex(0xFFFFFF), LV_PART_INDICATOR); + lv_obj_set_style_outline_width(Backlight_slider, 2, LV_PART_INDICATOR); + lv_obj_set_style_outline_color(Backlight_slider, lv_color_hex(0xD3D3D3), LV_PART_INDICATOR); + lv_slider_set_range(Backlight_slider, 5, Backlight_MAX); + lv_slider_set_value(Backlight_slider, LCD_Backlight, LV_ANIM_ON); + lv_obj_add_event_cb(Backlight_slider, Backlight_adjustment_event_cb, LV_EVENT_VALUE_CHANGED, NULL); + + static lv_coord_t grid_main_col_dsc[] = {LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST}; + static lv_coord_t grid_main_row_dsc[] = {LV_GRID_CONTENT, LV_GRID_CONTENT, LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST}; + lv_obj_set_grid_dsc_array(parent, grid_main_col_dsc, grid_main_row_dsc); + + + /*Create the top panel*/ + static lv_coord_t grid_1_col_dsc[] = {LV_GRID_CONTENT, LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST}; + static lv_coord_t grid_1_row_dsc[] = {LV_GRID_CONTENT, /*Avatar*/ + LV_GRID_CONTENT, /*Name*/ + LV_GRID_CONTENT, /*Description*/ + LV_GRID_CONTENT, /*Email*/ + LV_GRID_CONTENT, /*Phone number*/ + LV_GRID_CONTENT, /*Button1*/ + LV_GRID_CONTENT, /*Button2*/ + LV_GRID_TEMPLATE_LAST + }; + + lv_obj_set_grid_dsc_array(panel1, grid_1_col_dsc, grid_1_row_dsc); + + + /*Create the top panel*/ + static lv_coord_t grid_2_col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(5), LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST}; + static lv_coord_t grid_2_row_dsc[] = { + LV_GRID_CONTENT, /*Title*/ + 5, /*Separator*/ + LV_GRID_CONTENT, /*Box title*/ + 40, /*Box*/ + LV_GRID_CONTENT, /*Box title*/ + 40, /*Box*/ + LV_GRID_CONTENT, /*Box title*/ + 40, /*Box*/ + LV_GRID_CONTENT, /*Box title*/ + 40, /*Box*/ + LV_GRID_CONTENT, /*Box title*/ + 40, /*Box*/ + LV_GRID_CONTENT, /*Box title*/ + 40, /*Box*/ + LV_GRID_CONTENT, /*Box title*/ + 40, /*Box*/ + LV_GRID_TEMPLATE_LAST + }; + + lv_obj_set_grid_cell(panel1, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_START, 0, 1); + lv_obj_set_grid_dsc_array(panel1, grid_2_col_dsc, grid_2_row_dsc); + lv_obj_set_grid_cell(panel1_title, LV_GRID_ALIGN_START, 1, 1, LV_GRID_ALIGN_CENTER, 0, 1); + lv_obj_set_grid_cell(SD_label, LV_GRID_ALIGN_START, 1, 1, LV_GRID_ALIGN_START, 2, 1); + lv_obj_set_grid_cell(SD_Size, LV_GRID_ALIGN_STRETCH, 1, 1, LV_GRID_ALIGN_CENTER, 3, 1); + lv_obj_set_grid_cell(Flash_label, LV_GRID_ALIGN_START, 1, 1, LV_GRID_ALIGN_START, 4, 1); + lv_obj_set_grid_cell(FlashSize, LV_GRID_ALIGN_STRETCH, 1, 1, LV_GRID_ALIGN_CENTER, 5, 1); + lv_obj_set_grid_cell(BAT_label, LV_GRID_ALIGN_START, 1, 1, LV_GRID_ALIGN_START, 6, 1); + lv_obj_set_grid_cell(BAT_Volts, LV_GRID_ALIGN_STRETCH, 1, 1, LV_GRID_ALIGN_CENTER, 7, 1); + lv_obj_set_grid_cell(angle_label, LV_GRID_ALIGN_START, 1, 1, LV_GRID_ALIGN_START, 8, 1); + lv_obj_set_grid_cell(Board_angle, LV_GRID_ALIGN_STRETCH, 1, 1, LV_GRID_ALIGN_CENTER, 9, 1); + lv_obj_set_grid_cell(Time_label, LV_GRID_ALIGN_START, 1, 1, LV_GRID_ALIGN_START, 10, 1); + lv_obj_set_grid_cell(RTC_Time, LV_GRID_ALIGN_STRETCH, 1, 1, LV_GRID_ALIGN_CENTER, 11, 1); + lv_obj_set_grid_cell(Wireless_label, LV_GRID_ALIGN_START, 1, 1, LV_GRID_ALIGN_START, 12, 1); + lv_obj_set_grid_cell(Wireless_Scan, LV_GRID_ALIGN_STRETCH, 1, 1, LV_GRID_ALIGN_CENTER, 13, 1); + lv_obj_set_grid_cell(Backlight_label, LV_GRID_ALIGN_START, 1, 1, LV_GRID_ALIGN_START, 14, 1); + lv_obj_set_grid_cell(Backlight_slider, LV_GRID_ALIGN_STRETCH, 1, 1, LV_GRID_ALIGN_CENTER, 15, 1); + + auto_step_timer = lv_timer_create(example1_increase_lvgl_tick, 100, NULL); +} + +void example1_increase_lvgl_tick(lv_timer_t * t) +{ + char buf[100]; + + snprintf(buf, sizeof(buf), "%ld MB\r\n", SDCard_Size); + lv_textarea_set_placeholder_text(SD_Size, buf); + snprintf(buf, sizeof(buf), "%ld MB\r\n", Flash_Size); + lv_textarea_set_placeholder_text(FlashSize, buf); + snprintf(buf, sizeof(buf), "%.2f V\r\n", BAT_analogVolts); + lv_textarea_set_placeholder_text(BAT_Volts, buf); + snprintf(buf, sizeof(buf), "X:%.2f Y:%.2f Z:%.2f\r\n", Accel.x, Accel.y, Accel.z); + lv_textarea_set_placeholder_text(Board_angle, buf); + snprintf(buf, sizeof(buf), "%d.%d.%d %d:%d:%d\r\n",datetime.year,datetime.month,datetime.day,datetime.hour,datetime.minute,datetime.second); + lv_textarea_set_placeholder_text(RTC_Time, buf); + if(Scan_finish) + // snprintf(buf, sizeof(buf), "WIFI: %d BLE: %d ..Scan Finish.\r\n",WIFI_NUM,BLE_NUM); + snprintf(buf, sizeof(buf), "WIFI: %d ..Scan Finish.\r\n",WIFI_NUM); + else + snprintf(buf, sizeof(buf), "WIFI: %d \r\n",WIFI_NUM); + // snprintf(buf, sizeof(buf), "WIFI: %d BLE: %d\r\n",WIFI_NUM,BLE_NUM); + lv_textarea_set_placeholder_text(Wireless_Scan, buf); + lv_slider_set_value(Backlight_slider, LCD_Backlight, LV_ANIM_ON); + LVGL_Backlight_adjustment(LCD_Backlight); +} +static void Music_create(lv_obj_t * parent) +{ + original_screen_bg_color = lv_obj_get_style_bg_color(parent, 0); + lv_obj_set_style_bg_color(parent, lv_color_hex(0x343247), 0); + + _lv_demo_music_main_create(parent); +} + +void Backlight_adjustment_event_cb(lv_event_t * e) { + uint8_t Backlight = lv_slider_get_value(lv_event_get_target(e)); + if (Backlight <= Backlight_MAX) { + lv_slider_set_value(Backlight_slider, Backlight, LV_ANIM_ON); + LCD_Backlight = Backlight; + LVGL_Backlight_adjustment(Backlight); + } + else + printf("Volume out of range: %d\n", Backlight); + +} + + +static void ta_event_cb(lv_event_t * e) +{ +} + +void LVGL_Backlight_adjustment(uint8_t Backlight) { + Set_Backlight(Backlight); +} + + + + diff --git a/Lib/Display/LVGL_UI/LVGL_Example.h b/Lib/Display/LVGL_UI/LVGL_Example.h new file mode 100644 index 0000000..08d80ac --- /dev/null +++ b/Lib/Display/LVGL_UI/LVGL_Example.h @@ -0,0 +1,19 @@ +#pragma once + +#include "lvgl.h" +#include "demos/lv_demos.h" + +#include "LVGL_Driver.h" +#include "PCF85063.h" +#include "QMI8658.h" +#include "SD_MMC.h" +#include "BAT_Driver.h" +#include "Wireless.h" + +#define EXAMPLE1_LVGL_TICK_PERIOD_MS 1000 + + +void Backlight_adjustment_event_cb(lv_event_t * e); + +void Lvgl_Example1(void); +void LVGL_Backlight_adjustment(uint8_t Backlight); \ No newline at end of file diff --git a/Lib/Display/LVGL_UI/LVGL_Music.c b/Lib/Display/LVGL_UI/LVGL_Music.c new file mode 100644 index 0000000..17184b9 --- /dev/null +++ b/Lib/Display/LVGL_UI/LVGL_Music.c @@ -0,0 +1,813 @@ +#include "LVGL_Music.h" +#include +#include +#include +/********************* + * DEFINES + *********************/ +#define INTRO_TIME 2000 +#define BAR_COLOR1 lv_color_hex(0xe9dbfc) +#define BAR_COLOR2 lv_color_hex(0x6f8af6) +#define BAR_COLOR3 lv_color_hex(0xffffff) +#if LV_DEMO_MUSIC_LARGE + #define BAR_COLOR1_STOP 160 + #define BAR_COLOR2_STOP 200 +#else + #define BAR_COLOR1_STOP 80 + #define BAR_COLOR2_STOP 100 +#endif +#define BAR_COLOR3_STOP (2 * LV_HOR_RES / 3) +#define BAR_CNT 20 +#define DEG_STEP (180/BAR_CNT) +#define BAND_CNT 4 +#define BAR_PER_BAND_CNT (BAR_CNT / BAND_CNT) + + +/********************** + * STATIC VARIABLES + **********************/ +lv_style_t music_style; +lv_style_t parts_style; + +lv_obj_t * panel1; +lv_obj_t * panel2; +static lv_obj_t * main_cont; +static lv_obj_t * spectrum_obj; +static lv_obj_t * title_label; +static lv_obj_t * album_img_obj; +static uint32_t time_act; +static lv_timer_t * sec_counter_timer; +static const lv_font_t * font_small; +static const lv_font_t * font_large; +static bool Playing_Flag; +static uint32_t track_id; +static lv_obj_t * play_obj; +static const uint16_t (* spectrum)[4]; +static uint32_t spectrum_len; + +lv_obj_t * Music_img; + + +char SD_Name[100][100] ; +char File_Name[100][100] ; +char Audio_Name[100] ; +uint16_t ACTIVE_TRACK_CNT; +uint16_t Audio_energy; + +static lv_obj_t * list; +static lv_style_t style_btn_round; +static lv_style_t style_btn_pr; +static lv_style_t style_btn_play; +static lv_style_t style_btn_stop; +static lv_style_t style_title; +static bool first_Flag = false; +LV_IMG_DECLARE(img_lv_demo_music_btn_list_play); +LV_IMG_DECLARE(img_lv_demo_music_btn_list_pause); + +void refresh_screen() { + lv_obj_t *screen = lv_scr_act(); + lv_obj_invalidate(screen); +} +/* + * Callback adapter function to convert parameter types to avoid compile-time + * warning. + */ +void _img_set_zoom_anim_cb(void * obj, int32_t zoom) +{ + lv_img_set_zoom((lv_obj_t *)obj, (uint16_t)zoom); +} + +/* + * Callback adapter function to convert parameter types to avoid compile-time + * warning. + */ +void _obj_set_x_anim_cb(void * obj, int32_t x) +{ + lv_obj_set_x((lv_obj_t *)obj, (lv_coord_t)x); +} + +lv_obj_t * _lv_demo_music_main_create(lv_obj_t * parent) +{ + + LVGL_Search_Music(); + if(ACTIVE_TRACK_CNT) { + lv_style_init(&music_style); + lv_style_set_text_font(&music_style, font_large); + + font_small = &lv_font_montserrat_12; + font_large = &lv_font_montserrat_16; + + // 1 + panel1 = lv_obj_create(parent); + lv_obj_set_height(panel1, LV_SIZE_CONTENT); + + lv_obj_t * cont = create_cont(panel1); + create_wave_images(cont); + spectrum_obj = create_spectrum_obj(panel1); + lv_obj_add_style(spectrum_obj, &music_style, 0); + + lv_obj_t * title_box = create_title_box(panel1); + lv_obj_add_style(title_box, &music_style, 0); + lv_obj_t * ctrl_box = create_ctrl_box(panel1); + lv_obj_add_style(ctrl_box, &music_style, 0); + + static lv_coord_t grid_main_col_dsc[] = {LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST}; + static lv_coord_t grid_main_row_dsc[] = {LV_GRID_CONTENT, LV_GRID_CONTENT, LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST}; + lv_obj_set_grid_dsc_array(parent, grid_main_col_dsc, grid_main_row_dsc); + /*Create the top panel*/ + static lv_coord_t grid_1_col_dsc[] = {LV_GRID_CONTENT, LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST}; + static lv_coord_t grid_1_row_dsc[] = { + LV_GRID_CONTENT, /*title_box*/ + LV_GRID_CONTENT, /*cont*/ + 170, /*spectrum_obj*/ + LV_GRID_CONTENT, /*ctrl_box*/ + LV_GRID_CONTENT, /*handle_box*/ + LV_GRID_CONTENT, /*Button2*/ + LV_GRID_TEMPLATE_LAST + }; + lv_obj_set_grid_cell(panel1, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_START, 0, 1); + lv_obj_set_grid_dsc_array(panel1, grid_1_col_dsc, grid_1_row_dsc); + lv_obj_set_grid_cell(title_box , LV_GRID_ALIGN_STRETCH, 0, 2, LV_GRID_ALIGN_CENTER, 0, 1); + lv_obj_set_grid_cell(cont , LV_GRID_ALIGN_STRETCH, 1, 1, LV_GRID_ALIGN_CENTER, 1, 1); + lv_obj_set_grid_cell(spectrum_obj , LV_GRID_ALIGN_STRETCH, 0, 2, LV_GRID_ALIGN_CENTER, 2, 1); + lv_obj_set_grid_cell(ctrl_box , LV_GRID_ALIGN_STRETCH, 0, 2, LV_GRID_ALIGN_CENTER, 3, 1); + + // 2 + panel2 = lv_obj_create(parent); + lv_obj_set_height(panel2, LV_SIZE_CONTENT); + + lv_obj_t * list_box = create_List_box(panel2); + + lv_obj_set_size(list_box, LV_SIZE_CONTENT, LV_SIZE_CONTENT); + // lv_obj_add_style(list_box, &music_style, 0); + + static lv_coord_t grid_2_col_dsc[] = {LV_GRID_FR(1),LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST}; + static lv_coord_t grid_2_row_dsc[] = { + LV_GRID_CONTENT, /*list_box*/ + LV_GRID_TEMPLATE_LAST + }; + lv_obj_set_grid_cell(panel2, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_START, 1, 1); + lv_obj_set_grid_dsc_array(panel2, grid_2_col_dsc, grid_2_row_dsc); + lv_obj_set_grid_cell(list_box , LV_GRID_ALIGN_STRETCH, 0, 2, LV_GRID_ALIGN_CENTER, 0, 1); + + + lv_timer_create(timer_cb, 100, NULL); + + + lv_obj_fade_in(title_box, 500, INTRO_TIME - 1000); + lv_obj_fade_in(ctrl_box, 500, INTRO_TIME - 1000); + lv_obj_fade_in(album_img_obj, 300, INTRO_TIME - 1000); + lv_obj_fade_in(spectrum_obj, 0, INTRO_TIME - 1000); + } + else{ + lv_obj_t *label = lv_label_create(parent); + lv_label_set_text(label, "No MP3 file found in SD card!"); + // lv_obj_set_size(label, LV_PCT(100), LV_PCT(100)); + + lv_obj_set_size(label, LV_SIZE_CONTENT, LV_SIZE_CONTENT); + lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0); + } + return main_cont; +} + + +/************************************************************************************************************************************ + * create_title_box +************************************************************************************************************************************/ +lv_obj_t * create_title_box(lv_obj_t * parent) +{ + /*Create the titles*/ + lv_obj_t * cont = lv_obj_create(parent); + lv_obj_remove_style_all(cont); + lv_obj_set_height(cont, LV_SIZE_CONTENT); + lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(cont, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + + title_label = lv_label_create(cont); + lv_obj_set_style_text_font(title_label, font_large, 0); + lv_obj_set_style_text_color(title_label, lv_color_hex(0x504d6d), 0); + lv_label_set_text(title_label, Audio_Name); + lv_obj_set_height(title_label, lv_font_get_line_height(font_large) ); + return cont; +} +/************************************************************************************************************************************ + * create_title_box END * create_title_box END * create_title_box END * create_title_box END +************************************************************************************************************************************/ + +/************************************************************************************************************************************ + * create_cont * create_cont * create_cont * create_cont +************************************************************************************************************************************/ +lv_obj_t * create_cont(lv_obj_t * parent) +{ + /* */ + /*A transparent container in which the player section will be scrolled*/ + main_cont = lv_obj_create(parent); + lv_obj_clear_flag(main_cont, LV_OBJ_FLAG_CLICKABLE); + lv_obj_clear_flag(main_cont, LV_OBJ_FLAG_SCROLL_ELASTIC); + lv_obj_remove_style_all(main_cont); /*Make it transparent*/ + lv_obj_set_size(main_cont, lv_pct(100), lv_pct(100)); + lv_obj_set_scroll_snap_y(main_cont, LV_SCROLL_SNAP_CENTER); /*Snap the children to the center*/ + + /*Create a container for the player*/ + lv_obj_t * player = lv_obj_create(main_cont); + lv_obj_set_y(player, - LV_DEMO_MUSIC_HANDLE_SIZE); + lv_obj_set_size(player, LV_HOR_RES, 2 * LV_VER_RES + LV_DEMO_MUSIC_HANDLE_SIZE * 2); + + lv_obj_set_style_bg_color(player, lv_color_hex(0xffffff), 0); + lv_obj_set_style_border_width(player, 0, 0); + lv_obj_set_style_pad_all(player, 0, 0); + lv_obj_set_scroll_dir(player, LV_DIR_VER); + + /* Transparent placeholders below the player container + * It is used only to snap it to center.*/ + lv_obj_t * placeholder1 = lv_obj_create(main_cont); + lv_obj_remove_style_all(placeholder1); + lv_obj_clear_flag(placeholder1, LV_OBJ_FLAG_CLICKABLE); + lv_obj_t * placeholder2 = lv_obj_create(main_cont); + lv_obj_remove_style_all(placeholder2); + lv_obj_clear_flag(placeholder2, LV_OBJ_FLAG_CLICKABLE); + lv_obj_t * placeholder3 = lv_obj_create(main_cont); + lv_obj_remove_style_all(placeholder3); + lv_obj_clear_flag(placeholder3, LV_OBJ_FLAG_CLICKABLE); + lv_obj_set_size(placeholder1, lv_pct(100), LV_VER_RES); + lv_obj_set_y(placeholder1, 0); + lv_obj_set_size(placeholder2, lv_pct(100), LV_VER_RES); + lv_obj_set_y(placeholder2, LV_VER_RES); + lv_obj_set_size(placeholder3, lv_pct(100), LV_VER_RES - 2 * LV_DEMO_MUSIC_HANDLE_SIZE); + lv_obj_set_y(placeholder3, 2 * LV_VER_RES + LV_DEMO_MUSIC_HANDLE_SIZE); + + lv_obj_update_layout(main_cont); + + return player; +} + +void create_wave_images(lv_obj_t * parent) +{ + LV_IMG_DECLARE(img_lv_demo_music_wave_top); + LV_IMG_DECLARE(img_lv_demo_music_wave_bottom); + lv_obj_t * wave_top = lv_img_create(parent); + lv_img_set_src(wave_top, &img_lv_demo_music_wave_top); + lv_obj_set_width(wave_top, LV_HOR_RES); + lv_obj_align(wave_top, LV_ALIGN_TOP_MID, 0, 0); + lv_obj_add_flag(wave_top, LV_OBJ_FLAG_IGNORE_LAYOUT); + + lv_obj_t * wave_bottom = lv_img_create(parent); + lv_img_set_src(wave_bottom, &img_lv_demo_music_wave_bottom); + lv_obj_set_width(wave_bottom, LV_HOR_RES); + lv_obj_align(wave_bottom, LV_ALIGN_BOTTOM_MID, 0, 0); + lv_obj_add_flag(wave_bottom, LV_OBJ_FLAG_IGNORE_LAYOUT); + + LV_IMG_DECLARE(img_lv_demo_music_corner_left); + LV_IMG_DECLARE(img_lv_demo_music_corner_right); + lv_obj_t * wave_corner = lv_img_create(parent); + lv_img_set_src(wave_corner, &img_lv_demo_music_corner_left); + lv_obj_align(wave_corner, LV_ALIGN_BOTTOM_LEFT, -LV_HOR_RES / 6, 0); + lv_obj_add_flag(wave_corner, LV_OBJ_FLAG_IGNORE_LAYOUT); + + wave_corner = lv_img_create(parent); + lv_img_set_src(wave_corner, &img_lv_demo_music_corner_right); + lv_obj_align(wave_corner, LV_ALIGN_BOTTOM_RIGHT, LV_HOR_RES / 6, 0); + lv_obj_add_flag(wave_corner, LV_OBJ_FLAG_IGNORE_LAYOUT); +} + +/************************************************************************************************************************************ + * create_cont END * create_cont END * create_cont END * create_cont END +************************************************************************************************************************************/ + +/************************************************************************************************************************************ + * spectrum * spectrum * spectrum * spectrum +************************************************************************************************************************************/ +lv_obj_t * create_spectrum_obj(lv_obj_t * parent) +{ + /*Create the spectrum visualizer*/ + lv_obj_t * obj = lv_obj_create(parent); + lv_obj_remove_style_all(obj); + lv_obj_set_height(obj, 250); + lv_obj_clear_flag(obj, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_SCROLLABLE); + lv_obj_refresh_ext_draw_size(obj); + album_img_obj = album_img_create(obj); + return obj; +} + +lv_anim_t Music_img_animation; +uint16_t Music_img_angle = 0; +static void set_angle(void* img, int32_t v) +{ + lv_img_set_angle(img, v); +} +static uint16_t get_angle(void* img) +{ + uint16_t Angle = lv_img_get_angle(img); + return Angle; +} + +void Start_animation() { + lv_anim_init(&Music_img_animation); + lv_anim_set_var(&Music_img_animation, Music_img); + lv_anim_set_exec_cb(&Music_img_animation, set_angle); + lv_anim_set_values(&Music_img_animation, Music_img_angle, 3550 + Music_img_angle); + lv_anim_set_time(&Music_img_animation, 7000); + lv_anim_set_repeat_count(&Music_img_animation, LV_ANIM_REPEAT_INFINITE); + lv_anim_start(&Music_img_animation); +} + +void Stop_animation() { + Music_img_angle = get_angle(Music_img); + + lv_anim_del(&Music_img_animation, set_angle); +} +lv_obj_t * album_img_create(lv_obj_t * parent) +{ + LV_IMG_DECLARE(img_lv_demo_music_cover_1); + LV_IMG_DECLARE(img_lv_demo_music_cover_2); + LV_IMG_DECLARE(img_lv_demo_music_cover_3); + + Music_img = lv_img_create(parent); + switch(track_id % 3) { + case 2: + lv_img_set_src(Music_img, &img_lv_demo_music_cover_3); + break; + case 1: + lv_img_set_src(Music_img, &img_lv_demo_music_cover_2); + break; + case 0: + lv_img_set_src(Music_img, &img_lv_demo_music_cover_1); + break; + } + spectrum = spectrum_3; + spectrum_len = sizeof(spectrum_3) / sizeof(spectrum_3[0]); + lv_img_set_antialias(Music_img, true); + lv_obj_align(Music_img, LV_ALIGN_CENTER, 0, 0); + lv_obj_add_event_cb(Music_img, album_gesture_event_cb, LV_EVENT_GESTURE, NULL); + lv_obj_clear_flag(Music_img, LV_OBJ_FLAG_GESTURE_BUBBLE); + lv_obj_add_flag(Music_img, LV_OBJ_FLAG_CLICKABLE); + + + return Music_img; +} + + +void album_gesture_event_cb(lv_event_t * e) +{ + lv_dir_t dir = lv_indev_get_gesture_dir(lv_indev_get_act()); + if(dir == LV_DIR_LEFT) _lv_demo_music_album_next(true); + if(dir == LV_DIR_RIGHT) _lv_demo_music_album_next(false); +} + +/************************************************************************************************************************************ + * spectrum END * spectrum END * spectrum END * spectrum END +************************************************************************************************************************************/ + +/************************************************************************************************************************************ + * create_ctrl_box * create_ctrl_box * create_ctrl_box * create_ctrl_box +************************************************************************************************************************************/ + +lv_obj_t * create_ctrl_box(lv_obj_t * parent) +{ + lv_obj_t * cont = lv_obj_create(parent); + lv_obj_remove_style_all(cont); + lv_obj_set_height(cont, LV_SIZE_CONTENT); + lv_obj_set_style_pad_bottom(cont, 8, 0); + static const lv_coord_t grid_col[] = {LV_GRID_FR(1), LV_GRID_FR(4), LV_GRID_FR(4), LV_GRID_FR(5), LV_GRID_FR(4), LV_GRID_FR(4), LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST}; + static const lv_coord_t grid_row[] = {LV_GRID_CONTENT, LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST}; + lv_obj_set_grid_dsc_array(cont, grid_col, grid_row); + // LV_IMG_DECLARE(img_lv_demo_music_btn_loop); + LV_IMG_DECLARE(img_lv_demo_music_btn_rnd); + LV_IMG_DECLARE(img_lv_demo_music_btn_next); + LV_IMG_DECLARE(img_lv_demo_music_btn_prev); + LV_IMG_DECLARE(img_lv_demo_music_btn_play); + LV_IMG_DECLARE(img_lv_demo_music_btn_pause); + lv_obj_t * icon1; + lv_obj_t * icon2; + lv_obj_t * icon3; + lv_obj_t * icon4; + icon1 = lv_img_create(cont); + lv_img_set_src(icon1, &img_lv_demo_music_btn_rnd); + lv_obj_set_grid_cell(icon1, LV_GRID_ALIGN_CENTER, 1, 1, LV_GRID_ALIGN_CENTER, 0, 1); + + icon2 = lv_obj_create(cont); + lv_obj_set_size(icon2, 70, 150); + lv_obj_set_grid_cell(icon2, LV_GRID_ALIGN_CENTER, 5, 1, LV_GRID_ALIGN_CENTER, 0, 1); + lv_obj_set_style_bg_opa(icon2, LV_OPA_COVER, 0); + lv_obj_set_style_border_width(icon2, 0, 0); + lv_obj_set_style_radius(icon2, LV_RADIUS_CIRCLE, 0); + lv_obj_clear_flag(icon2, LV_OBJ_FLAG_SCROLLABLE); + + lv_obj_t * icon2_volume = lv_label_create(icon2); + lv_label_set_text(icon2_volume, LV_SYMBOL_VOLUME_MAX); + lv_obj_set_style_text_font(icon2_volume, &lv_font_montserrat_14, 0); + lv_obj_align(icon2_volume, LV_ALIGN_CENTER, 0, 0); + + lv_obj_t *circle_button = lv_obj_create(icon2); + lv_obj_set_style_bg_opa(circle_button, LV_OPA_TRANSP, 0); + lv_obj_set_style_border_width(circle_button, 0, 0); + lv_obj_set_size(circle_button, 65, 130); + lv_obj_set_style_radius(circle_button, LV_RADIUS_CIRCLE, 0); + lv_obj_align(circle_button, LV_ALIGN_CENTER, 0, 10); + + lv_obj_add_event_cb(circle_button, volume_event_cb, LV_EVENT_CLICKED, NULL); + lv_obj_add_flag(circle_button, LV_OBJ_FLAG_CLICKABLE); + + icon3 = lv_img_create(cont); + lv_img_set_src(icon3, &img_lv_demo_music_btn_prev); + lv_obj_set_grid_cell(icon3, LV_GRID_ALIGN_CENTER, 2, 1, LV_GRID_ALIGN_CENTER, 0, 1); + lv_obj_add_event_cb(icon3, prev_click_event_cb, LV_EVENT_CLICKED, NULL); + lv_obj_add_flag(icon3, LV_OBJ_FLAG_CLICKABLE); + + play_obj = lv_imgbtn_create(cont); + lv_imgbtn_set_src(play_obj, LV_IMGBTN_STATE_RELEASED, NULL, &img_lv_demo_music_btn_play, NULL); + lv_imgbtn_set_src(play_obj, LV_IMGBTN_STATE_CHECKED_RELEASED, NULL, &img_lv_demo_music_btn_pause, NULL); + lv_obj_add_flag(play_obj, LV_OBJ_FLAG_CHECKABLE); + lv_obj_set_grid_cell(play_obj, LV_GRID_ALIGN_CENTER, 3, 1, LV_GRID_ALIGN_CENTER, 0, 1); + lv_obj_add_event_cb(play_obj, play_event_click_cb, LV_EVENT_CLICKED, NULL); + lv_obj_add_flag(play_obj, LV_OBJ_FLAG_CLICKABLE); + lv_obj_set_width(play_obj, img_lv_demo_music_btn_play.header.w); + + icon4 = lv_img_create(cont); + lv_img_set_src(icon4, &img_lv_demo_music_btn_next); + lv_obj_set_grid_cell(icon4, LV_GRID_ALIGN_CENTER, 4, 1, LV_GRID_ALIGN_CENTER, 0, 1); + lv_obj_add_event_cb(icon4, next_click_event_cb, LV_EVENT_CLICKED, NULL); + lv_obj_add_flag(icon4, LV_OBJ_FLAG_CLICKABLE); + + + return cont; +} + +void track_load(uint32_t id) +{ + if(first_Flag) { + if(id == track_id) return; + } + + time_act = 0; + bool next = false; + if((track_id + 1) % ACTIVE_TRACK_CNT == id) next = true; + if(first_Flag || id != track_id) { + _lv_demo_music_list_btn_check(track_id, false); + track_id = id; + } + _lv_demo_music_list_btn_check(id, true); + first_Flag = true; + lv_label_set_text(title_label, Audio_Name); + + lv_anim_t a; + lv_anim_init(&a); + lv_anim_set_var(&a, album_img_obj); + lv_anim_set_values(&a, lv_obj_get_style_img_opa(album_img_obj, 0), LV_OPA_TRANSP); + lv_anim_set_exec_cb(&a, album_fade_anim_cb); + lv_anim_set_time(&a, 500); + lv_anim_start(&a); + + lv_anim_init(&a); + lv_anim_set_var(&a, album_img_obj); + lv_anim_set_time(&a, 500); + lv_anim_set_path_cb(&a, lv_anim_path_ease_out); + if(next) { + lv_anim_set_values(&a, 0, - LV_HOR_RES / 2); + } + else { + lv_anim_set_values(&a, 0, LV_HOR_RES / 2); + } + lv_anim_set_exec_cb(&a, _obj_set_x_anim_cb); + lv_anim_set_ready_cb(&a, lv_obj_del_anim_ready_cb); + lv_anim_start(&a); + lv_anim_set_path_cb(&a, lv_anim_path_linear); + lv_anim_set_var(&a, album_img_obj); + lv_anim_set_time(&a, 500); + lv_anim_set_values(&a, LV_IMG_ZOOM_NONE, LV_IMG_ZOOM_NONE / 2); + lv_anim_set_exec_cb(&a, _img_set_zoom_anim_cb); + lv_anim_set_ready_cb(&a, NULL); + lv_anim_start(&a); + album_img_obj = album_img_create(spectrum_obj); + lv_anim_set_path_cb(&a, lv_anim_path_overshoot); + lv_anim_set_var(&a, album_img_obj); + lv_anim_set_time(&a, 500); + lv_anim_set_delay(&a, 100); + lv_anim_set_values(&a, LV_IMG_ZOOM_NONE / 4, LV_IMG_ZOOM_NONE); + lv_anim_set_exec_cb(&a, _img_set_zoom_anim_cb); + lv_anim_set_ready_cb(&a, NULL); + lv_anim_start(&a); + lv_anim_init(&a); + lv_anim_set_var(&a, album_img_obj); + lv_anim_set_values(&a, 0, LV_OPA_COVER); + lv_anim_set_exec_cb(&a, album_fade_anim_cb); + lv_anim_set_time(&a, 500); + lv_anim_set_delay(&a, 100); + lv_anim_start(&a); +} + +void play_event_click_cb(lv_event_t * e) +{ + lv_obj_t * obj = lv_event_get_target(e); + lv_anim_del(Music_img, set_angle); + if(lv_obj_has_state(obj, LV_STATE_CHECKED)) { + _lv_demo_music_resume(); + } + else { + _lv_demo_music_pause(); + } +} +void prev_click_event_cb(lv_event_t * e) +{ + lv_event_code_t code = lv_event_get_code(e); + if(code == LV_EVENT_CLICKED) { + _lv_demo_music_album_next(false); + } +} +void next_click_event_cb(lv_event_t * e) +{ + lv_event_code_t code = lv_event_get_code(e); + if(code == LV_EVENT_CLICKED) { + _lv_demo_music_album_next(true); + } +} +void timer_cb(lv_timer_t * t) +{ + LV_UNUSED(t); + if(Music_Next_Flag){ + Music_Next_Flag = 0; + _lv_demo_music_album_next(true); + } +} +static lv_obj_t * panel; +static lv_obj_t * slider; +static lv_obj_t * slider_volume; + +void volume_adjustment_event_cb(lv_event_t * e) { + uint8_t Volume = lv_slider_get_value(lv_event_get_target(e)); + if (Volume <= Volume_MAX) { + lv_slider_set_value(slider, Volume, LV_ANIM_ON); + LVGL_volume_adjustment(Volume); + // printf("Volume:%d\r\n",Volume) ; + } + else + printf("Volume out of range: %d\n", Volume); + +} + +void background_event_cb(lv_event_t * e) { + lv_event_code_t code = lv_event_get_code(e); + if (code == LV_EVENT_CLICKED) { + if (lv_event_get_target(e) == panel && lv_event_get_target(e) != slider_volume) { + lv_obj_add_flag(panel, LV_OBJ_FLAG_HIDDEN); + } + } +} + +void volume_event_cb(lv_event_t * e) { + printf("Clicked on volume icon\r\n"); + lv_event_code_t code = lv_event_get_code(e); + if(code == LV_EVENT_CLICKED) { + if (!slider) { + panel = lv_obj_create(lv_scr_act()); + lv_obj_set_size(panel, lv_obj_get_width(lv_scr_act()), lv_obj_get_height(lv_scr_act())); + lv_obj_set_pos(panel, 0, 0); + lv_obj_set_style_border_width(panel, 0, 0); + lv_obj_clear_flag(panel, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_set_style_bg_opa(panel, LV_OPA_TRANSP, LV_PART_MAIN); + + slider = lv_slider_create(panel); + lv_obj_add_flag(slider, LV_OBJ_FLAG_CLICKABLE); + lv_obj_set_size(slider, 20, 170); + lv_obj_set_style_bg_opa(slider, LV_OPA_TRANSP, LV_PART_KNOB); + lv_obj_set_style_pad_all(slider, 20, LV_PART_KNOB); + lv_obj_set_style_bg_color(slider, lv_color_hex(0xADD8F6), LV_PART_INDICATOR); + lv_obj_set_style_outline_width(slider, 0, 0); + lv_slider_set_range(slider, 0, Volume_MAX); + lv_slider_set_value(slider, Volume, LV_ANIM_ON); + lv_obj_align_to(slider, panel, LV_ALIGN_RIGHT_MID, -10, 0); + + slider_volume = lv_slider_create(panel); + lv_obj_add_flag(slider_volume, LV_OBJ_FLAG_CLICKABLE); + lv_obj_set_size(slider_volume, 50, 170); + lv_obj_set_style_bg_opa(slider_volume, LV_OPA_TRANSP, LV_PART_KNOB); + lv_obj_set_style_pad_all(slider_volume, 50, LV_PART_KNOB); + lv_obj_set_style_bg_color(slider_volume, lv_color_hex(0xFFFFFF), LV_PART_INDICATOR); + lv_obj_set_style_outline_width(slider_volume, 0, 0); + lv_slider_set_range(slider_volume, 0, Volume_MAX); + lv_slider_set_value(slider_volume, Volume, LV_ANIM_ON); + lv_obj_align_to(slider_volume, panel, LV_ALIGN_RIGHT_MID, 20, 0); + lv_obj_set_style_bg_opa(slider_volume, LV_OPA_TRANSP, LV_PART_MAIN); + lv_obj_set_style_bg_opa(slider_volume, LV_OPA_TRANSP, LV_PART_KNOB); + lv_obj_set_style_bg_opa(slider_volume, LV_OPA_TRANSP, LV_PART_INDICATOR); + + lv_obj_add_event_cb(slider_volume, volume_adjustment_event_cb, LV_EVENT_VALUE_CHANGED, NULL); + lv_obj_add_event_cb(panel, background_event_cb, LV_EVENT_ALL, NULL); + } + lv_obj_clear_flag(panel, LV_OBJ_FLAG_HIDDEN); + } +} + + +void album_fade_anim_cb(void * var, int32_t v) +{ + lv_obj_set_style_img_opa(var, v, 0); +} + +/************************************************************************************************************************************ + * create_ctrl_box END * create_ctrl_box END * create_ctrl_box END * create_ctrl_box END +************************************************************************************************************************************/ +/************************************************************************************************************************************ + * create_ctrl_box * create_ctrl_box * create_ctrl_box * create_ctrl_box +************************************************************************************************************************************/ + +lv_obj_t * create_List_box(lv_obj_t * parent) +{ + static const lv_coord_t grid_cols[] = {LV_GRID_CONTENT, LV_GRID_FR(1), LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST}; + static const lv_coord_t grid_rows[] = {LV_GRID_CONTENT, LV_GRID_CONTENT, LV_GRID_CONTENT, LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST}; + lv_style_init(&style_btn_stop); + lv_style_set_bg_opa(&style_btn_stop, LV_OPA_TRANSP); + lv_style_set_grid_column_dsc_array(&style_btn_stop, grid_cols); + lv_style_set_grid_row_dsc_array(&style_btn_stop, grid_rows); + lv_style_set_grid_row_align(&style_btn_stop, LV_GRID_ALIGN_CENTER); + lv_style_set_layout(&style_btn_stop, LV_LAYOUT_GRID); + lv_style_set_pad_right(&style_btn_stop, 20); + + lv_style_init(&style_btn_round); + lv_style_set_radius(&style_btn_round, 10); + + lv_style_init(&style_btn_pr); + lv_style_set_bg_opa(&style_btn_pr, LV_OPA_COVER); + lv_style_set_bg_color(&style_btn_pr, lv_color_hex(0xCDE8F3)); + + lv_style_init(&style_btn_play); + lv_style_set_bg_opa(&style_btn_play, LV_OPA_COVER); + lv_style_set_bg_color(&style_btn_play, lv_color_hex(0xAAD3E0)); + + lv_style_init(&style_title); + lv_style_set_text_font(&style_title, font_small); + lv_style_set_text_color(&style_title, lv_color_hex(0x101010)); + + list = lv_obj_create(parent); + lv_obj_remove_style_all(list); + lv_obj_set_size(list, LV_SIZE_CONTENT, LV_SIZE_CONTENT); + lv_obj_set_pos(list, 0, LV_DEMO_MUSIC_HANDLE_SIZE); + // lv_obj_set_y(list, LV_DEMO_MUSIC_HANDLE_SIZE); + lv_obj_add_style(list, &music_style, LV_PART_SCROLLBAR); + lv_obj_set_flex_flow(list, LV_FLEX_FLOW_COLUMN); + + uint32_t List_id; + for(List_id = 0; List_id < ACTIVE_TRACK_CNT; List_id++) { + add_list_btn(list, List_id); + } + lv_obj_set_scroll_snap_y(list, LV_SCROLL_SNAP_CENTER); + _lv_demo_music_list_btn_check(0, true); + return list; +} +lv_obj_t * add_list_btn(lv_obj_t * parent, uint32_t List_id) +{ + lv_obj_t * btn = lv_obj_create(parent); + lv_obj_remove_style_all(btn); + lv_obj_set_size(btn, lv_pct(100), 60); + lv_obj_add_style(btn, &style_btn_round, 0); + + lv_obj_add_style(btn, &style_btn_stop, 0); + lv_obj_add_style(btn, &style_btn_play, LV_STATE_CHECKED); + lv_obj_add_style(btn, &style_btn_pr, LV_STATE_PRESSED); + lv_obj_add_event_cb(btn, btn_click_event_cb, LV_EVENT_CLICKED, NULL); + + + lv_obj_t * icon = lv_img_create(btn); + lv_img_set_src(icon, &img_lv_demo_music_btn_list_play); + lv_obj_set_grid_cell(icon, LV_GRID_ALIGN_START, 0, 1, LV_GRID_ALIGN_CENTER, 0, 2); + + lv_obj_t * title_label = lv_label_create(btn); + lv_label_set_text(title_label, File_Name[List_id]); + lv_obj_set_grid_cell(title_label, LV_GRID_ALIGN_START, 1, 1, LV_GRID_ALIGN_CENTER, 0, 1); + lv_obj_add_style(title_label, &style_title, 0); + + return btn; +} + +void _lv_demo_music_list_btn_check(uint32_t List_id, bool state) +{ + lv_obj_t * btn = lv_obj_get_child(list, List_id); + lv_obj_t * icon = lv_obj_get_child(btn, 0); + + if(state) { + lv_obj_add_state(btn, LV_STATE_CHECKED); + lv_img_set_src(icon, &img_lv_demo_music_btn_list_pause); + lv_obj_scroll_to_view(btn, LV_ANIM_ON); + } + else { + lv_obj_clear_state(btn, LV_STATE_CHECKED); + lv_img_set_src(icon, &img_lv_demo_music_btn_list_play); + } + // lv_obj_scroll_to_view(panel1, LV_ANIM_ON); + lv_obj_invalidate(panel1); +} + +void btn_click_event_cb(lv_event_t * e) +{ + lv_obj_t * btn = lv_event_get_target(e); + uint32_t idx = lv_obj_get_child_id(btn); + if(idx == track_id) + _lv_demo_music_resume(); + else + _lv_demo_music_play(idx); +} + +/************************************************************************************************************************************ + * create_ctrl_box END * create_ctrl_box END * create_ctrl_box END * create_ctrl_box END +************************************************************************************************************************************/ +/************************************************************************************************************************************ + * Music * Music * Music * Music +************************************************************************************************************************************/ +void _lv_demo_music_main_close(void) +{ + lv_timer_del(sec_counter_timer); +} + +void _lv_demo_music_album_next(bool next) +{ + uint32_t id = track_id; + if(next) { + id++; + if(id >= ACTIVE_TRACK_CNT) id = 0; + } + else { + if(id == 0) { + id = ACTIVE_TRACK_CNT - 1; + } + else { + id--; + } + } + _lv_demo_music_play(id); +} +void _lv_demo_music_play(uint32_t id) +{ + if(Playing_Flag && id == track_id){ + } + else{ + if(id == track_id){ + LVGL_Resume_Music(); + _lv_demo_music_resume(); + } + else{ + Music_img_angle = 0; + track_load(id); + LVGL_Play_Music(id); + _lv_demo_music_resume(); + } + } +} +void _lv_demo_music_resume(void) { + Playing_Flag = true; + + lv_obj_add_state(play_obj, LV_STATE_CHECKED); + LVGL_Resume_Music(); + Start_animation(); + refresh_screen(); +} +void _lv_demo_music_pause(void) +{ + Playing_Flag = false; + + lv_img_set_zoom(album_img_obj, LV_IMG_ZOOM_NONE); + lv_obj_clear_state(play_obj, LV_STATE_CHECKED); + + LVGL_Pause_Music(); + Stop_animation(); + refresh_screen(); +} + +/************************************************************************************************************************************ + * Other * Other * Other * Other +************************************************************************************************************************************/ + +void remove_file_extension(char *file_name) { + char *last_dot = strrchr(file_name, '.'); + if (last_dot != NULL) { + *last_dot = '\0'; + } +} +void LVGL_Search_Music() { + ACTIVE_TRACK_CNT = Folder_retrieval("/sdcard",".mp3",SD_Name,100); + if(ACTIVE_TRACK_CNT) { + for (int i = 0; i < ACTIVE_TRACK_CNT; i++) { + strcpy(File_Name[i], SD_Name[i]); + remove_file_extension(File_Name[i]); + } + LVGL_Play_Music(0); + } +} +void LVGL_Play_Music(uint32_t ID) { + Play_Music("/sdcard",SD_Name[ID]); + LVGL_Pause_Music(); + strncpy(Audio_Name,File_Name[ID], sizeof(File_Name[ID])); +} + +void LVGL_Resume_Music() { + Music_resume(); +} +void LVGL_Pause_Music() { + Music_pause(); +} +void LVGL_volume_adjustment(uint8_t Volume) { + Volume_adjustment(Volume); +} +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Lib/Display/LVGL_UI/LVGL_Music.h b/Lib/Display/LVGL_UI/LVGL_Music.h new file mode 100644 index 0000000..caf3f5f --- /dev/null +++ b/Lib/Display/LVGL_UI/LVGL_Music.h @@ -0,0 +1,69 @@ +#pragma once +/********************* + * INCLUDES + *********************/ +// #include +#include +#include +#include + +// #include "assets/spectrum_1.h" +// #include "assets/spectrum_2.h" +// #include "assets/spectrum_3.h" + +#include "SD_MMC.h" +#include "PCM5101.h" + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +extern uint16_t ACTIVE_TRACK_CNT; +/* + * Callback adapter function to convert parameter types to avoid compile-time + * warning. + */ +void _img_set_zoom_anim_cb(void * obj, int32_t zoom); +/* + * Callback adapter function to convert parameter types to avoid compile-time + * warning. + */ +void _obj_set_x_anim_cb(void * obj, int32_t x); +lv_obj_t * _lv_demo_music_main_create(lv_obj_t * parent); +void _lv_demo_music_main_close(void); +void _lv_demo_music_album_next(bool next); +void _lv_demo_music_play(uint32_t id); +void _lv_demo_music_resume(void); +void _lv_demo_music_pause(void); + +/********************** + * STATIC FUNCTIONS + **********************/ +lv_obj_t * create_List_box(lv_obj_t * parent); +lv_obj_t * add_list_btn(lv_obj_t * parent, uint32_t track_id); +void _lv_demo_music_list_btn_check(uint32_t track_id, bool state); +void btn_click_event_cb(lv_event_t * e); + +lv_obj_t * create_cont(lv_obj_t * parent); +void create_wave_images(lv_obj_t * parent); +lv_obj_t * create_title_box(lv_obj_t * parent); +lv_obj_t * create_icon_box(lv_obj_t * parent); +lv_obj_t * create_spectrum_obj(lv_obj_t * parent); +lv_obj_t * create_ctrl_box(lv_obj_t * parent); +lv_obj_t * create_handle(lv_obj_t * parent); +void track_load(uint32_t id); +lv_obj_t * album_img_create(lv_obj_t * parent); +void album_gesture_event_cb(lv_event_t * e); +void play_event_click_cb(lv_event_t * e); +void prev_click_event_cb(lv_event_t * e); +void next_click_event_cb(lv_event_t * e); +void volume_event_cb(lv_event_t * e); + +void album_fade_anim_cb(void * var, int32_t v); +void timer_cb(lv_timer_t * t); + +void LVGL_Search_Music(); +void LVGL_Resume_Music(); +void LVGL_Pause_Music(); +void LVGL_Play_Music(uint32_t ID); +void LVGL_volume_adjustment(uint8_t Volume); diff --git a/Lib/Display/Touch_Driver/CST816.c b/Lib/Display/Touch_Driver/CST816.c new file mode 100644 index 0000000..01c2efc --- /dev/null +++ b/Lib/Display/Touch_Driver/CST816.c @@ -0,0 +1,243 @@ +#include "CST816.h" + + +#define POINT_NUM_MAX (1) + +#define DATA_START_REG (0x02) +#define CHIP_ID_REG (0xA7) +#define AutoSleep_REG (0xFE) + +static const char *TAG = "CST816"; + +esp_lcd_touch_handle_t tp = NULL; + +static esp_err_t read_data(esp_lcd_touch_handle_t tp); +static bool get_xy(esp_lcd_touch_handle_t tp, uint16_t *x, uint16_t *y, uint16_t *strength, uint8_t *point_num, uint8_t max_point_num); +static esp_err_t del(esp_lcd_touch_handle_t tp); + +static esp_err_t i2c_read_bytes(esp_lcd_touch_handle_t tp, uint16_t reg, uint8_t *data, uint8_t len); +static esp_err_t i2c_write_bytes(esp_lcd_touch_handle_t tp, uint16_t reg, uint8_t* data, uint8_t len); + +static esp_err_t reset(esp_lcd_touch_handle_t tp); +static esp_err_t read_id(esp_lcd_touch_handle_t tp); +static void AutoSleep(bool Sleep_State); + +esp_err_t esp_lcd_touch_new_i2c_cst816(const esp_lcd_panel_io_handle_t io, const esp_lcd_touch_config_t *config, esp_lcd_touch_handle_t *tp) +{ + ESP_RETURN_ON_FALSE(io, ESP_ERR_INVALID_ARG, TAG, "Invalid io"); + ESP_RETURN_ON_FALSE(config, ESP_ERR_INVALID_ARG, TAG, "Invalid config"); + ESP_RETURN_ON_FALSE(tp, ESP_ERR_INVALID_ARG, TAG, "Invalid touch handle"); + + /* Prepare main structure */ + esp_err_t ret = ESP_OK; + esp_lcd_touch_handle_t cst816s = calloc(1, sizeof(esp_lcd_touch_t)); + ESP_GOTO_ON_FALSE(cst816s, ESP_ERR_NO_MEM, err, TAG, "Touch handle malloc failed"); + + /* Communication interface */ + cst816s->io = io; + /* Only supported callbacks are set */ + cst816s->read_data = read_data; + cst816s->get_xy = get_xy; + cst816s->del = del; + /* Mutex */ + cst816s->data.lock.owner = portMUX_FREE_VAL; + /* Save config */ + memcpy(&cst816s->config, config, sizeof(esp_lcd_touch_config_t)); + + /* Prepare pin for touch interrupt */ + if (cst816s->config.int_gpio_num != GPIO_NUM_NC) { + const gpio_config_t int_gpio_config = { + .mode = GPIO_MODE_INPUT, + .intr_type = (cst816s->config.levels.interrupt ? GPIO_INTR_POSEDGE : GPIO_INTR_NEGEDGE), + .pin_bit_mask = BIT64(cst816s->config.int_gpio_num) + }; + ESP_GOTO_ON_ERROR(gpio_config(&int_gpio_config), err, TAG, "GPIO intr config failed"); + + /* Register interrupt callback */ + if (cst816s->config.interrupt_callback) { + esp_lcd_touch_register_interrupt_callback(cst816s, cst816s->config.interrupt_callback); + } + } + /* Prepare pin for touch controller reset */ + if (cst816s->config.rst_gpio_num != GPIO_NUM_NC) { + const gpio_config_t rst_gpio_config = { + .mode = GPIO_MODE_OUTPUT, + .pin_bit_mask = BIT64(cst816s->config.rst_gpio_num) + }; + ESP_GOTO_ON_ERROR(gpio_config(&rst_gpio_config), err, TAG, "GPIO reset config failed"); + } + /* Reset controller */ + ESP_GOTO_ON_ERROR(reset(cst816s), err, TAG, "Reset failed"); + + /* Read product id */ + ESP_GOTO_ON_ERROR(read_id(cst816s), err, TAG, "Read version failed"); + *tp = cst816s; + AutoSleep(false); + return ESP_OK; +err: + if (cst816s) { + del(cst816s); + } + ESP_LOGE(TAG, "Initialization failed!"); + return ret; +} + +static esp_err_t read_data(esp_lcd_touch_handle_t tp) +{ + typedef struct { + uint8_t num; + uint8_t x_h : 4; + uint8_t : 4; + uint8_t x_l; + uint8_t y_h : 4; + uint8_t : 4; + uint8_t y_l; + } data_t; + + data_t point; + ESP_RETURN_ON_ERROR(i2c_read_bytes(tp, DATA_START_REG, (uint8_t *)&point, sizeof(data_t)), TAG, "I2C read failed"); + + portENTER_CRITICAL(&tp->data.lock); + point.num = (point.num > POINT_NUM_MAX ? POINT_NUM_MAX : point.num); + tp->data.points = point.num; + /* Fill all coordinates */ + for (int i = 0; i < point.num; i++) { + tp->data.coords[i].x = point.x_h << 8 | point.x_l; + tp->data.coords[i].y = point.y_h << 8 | point.y_l; + } + portEXIT_CRITICAL(&tp->data.lock); + + return ESP_OK; +} + +static bool get_xy(esp_lcd_touch_handle_t tp, uint16_t *x, uint16_t *y, uint16_t *strength, uint8_t *point_num, uint8_t max_point_num) +{ + portENTER_CRITICAL(&tp->data.lock); + /* Count of points */ + *point_num = (tp->data.points > max_point_num ? max_point_num : tp->data.points); + for (size_t i = 0; i < *point_num; i++) { + x[i] = tp->data.coords[i].x; + y[i] = tp->data.coords[i].y; + + if (strength) { + strength[i] = tp->data.coords[i].strength; + } + } + /* Invalidate */ + tp->data.points = 0; + portEXIT_CRITICAL(&tp->data.lock); + + return (*point_num > 0); +} + +static esp_err_t del(esp_lcd_touch_handle_t tp) +{ + /* Reset GPIO pin settings */ + if (tp->config.int_gpio_num != GPIO_NUM_NC) { + gpio_reset_pin(tp->config.int_gpio_num); + if (tp->config.interrupt_callback) { + gpio_isr_handler_remove(tp->config.int_gpio_num); + } + } + if (tp->config.rst_gpio_num != GPIO_NUM_NC) { + gpio_reset_pin(tp->config.rst_gpio_num); + } + /* Release memory */ + free(tp); + + return ESP_OK; +} + +static esp_err_t reset(esp_lcd_touch_handle_t tp) +{ + + Set_EXIO(TCA9554_EXIO1,false); + vTaskDelay(pdMS_TO_TICKS(10)); + Set_EXIO(TCA9554_EXIO1,true); + vTaskDelay(pdMS_TO_TICKS(50)); + + return ESP_OK; +} + +static esp_err_t read_id(esp_lcd_touch_handle_t tp) +{ + uint8_t id; + ESP_RETURN_ON_ERROR(i2c_read_bytes(tp, CHIP_ID_REG, &id, 1), TAG, "I2C read failed"); + ESP_LOGI(TAG, "IC id: %d", id); + return ESP_OK; +} +/*! + @brief Fall asleep automatically +*/ +static void AutoSleep(bool Sleep_State) { + uint8_t Sleep_State_Set = (uint8_t)(!Sleep_State); + i2c_write_bytes(tp, AutoSleep_REG, &Sleep_State_Set, 1); +} + +static esp_err_t i2c_read_bytes(esp_lcd_touch_handle_t tp, uint16_t reg, uint8_t *data, uint8_t len) +{ + ESP_RETURN_ON_FALSE(data, ESP_ERR_INVALID_ARG, TAG, "Invalid data"); + + return esp_lcd_panel_io_rx_param(tp->io, reg, data, len); +} + +static esp_err_t i2c_write_bytes(esp_lcd_touch_handle_t tp, uint16_t reg, uint8_t* data, uint8_t len) +{ + assert(tp != NULL); + + // *INDENT-OFF* + /* Write data */ + return esp_lcd_panel_io_tx_param(tp->io, reg, data, len); + // *INDENT-ON* +} + +/** + * @brief i2c master initialization + */ +esp_err_t Touch_I2C_Init(void) +{ + int i2c_master_port = I2C_Touch_MASTER_NUM; + + i2c_config_t conf = { + .mode = I2C_MODE_MASTER, + .sda_io_num = I2C_Touch_SDA_IO, + .scl_io_num = I2C_Touch_SCL_IO, + .sda_pullup_en = GPIO_PULLUP_ENABLE, + .scl_pullup_en = GPIO_PULLUP_ENABLE, + .master.clk_speed = I2C_Touch_MASTER_FREQ_HZ, + }; + + i2c_param_config(i2c_master_port, &conf); + + return i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0); +} +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void Touch_Init(void) +{ + + ESP_ERROR_CHECK(Touch_I2C_Init()); + ESP_LOGI(TAG, "I2C initialized successfully"); +/********************* Touch *********************/ + + esp_lcd_panel_io_handle_t tp_io_handle = NULL; + esp_lcd_panel_io_i2c_config_t tp_io_config = ESP_LCD_TOUCH_IO_I2C_CST816_CONFIG(); + ESP_LOGI(TAG, "Initialize touch IO (I2C)"); + /* Touch IO handle */ + ESP_ERROR_CHECK(esp_lcd_new_panel_io_i2c((esp_lcd_i2c_bus_handle_t)I2C_Touch_MASTER_NUM, &tp_io_config, &tp_io_handle)); + esp_lcd_touch_config_t tp_cfg = { + .x_max = EXAMPLE_LCD_WIDTH, + .y_max = EXAMPLE_LCD_HEIGHT, + .rst_gpio_num = I2C_Touch_RST_IO, + .int_gpio_num = I2C_Touch_INT_IO, + .flags = { + .swap_xy = 0, + .mirror_x = 0, + .mirror_y = 0, + }, + }; + /* Initialize touch */ + ESP_LOGI(TAG, "Initialize touch controller CST816"); + ESP_ERROR_CHECK(esp_lcd_touch_new_i2c_cst816(tp_io_handle, &tp_cfg, &tp)); +} + diff --git a/Lib/Display/Touch_Driver/CST816.h b/Lib/Display/Touch_Driver/CST816.h new file mode 100644 index 0000000..07ab1a6 --- /dev/null +++ b/Lib/Display/Touch_Driver/CST816.h @@ -0,0 +1,70 @@ +/** + * @file + * @brief ESP LCD touch: CST820 + */ + +#pragma once +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "driver/gpio.h" +#include "driver/i2c.h" +#include "esp_system.h" +#include "esp_err.h" +#include "esp_log.h" +#include "esp_check.h" +#include "esp_lcd_panel_io.h" +#include "esp_lcd_touch.h" + +#include "TCA9554PWR.h" +#include "ST77916.h" + +/** + * @brief Create a new CST816S touch driver + * + * @note The I2C communication should be initialized before use this function. + * + * @param io LCD panel IO handle, it should be created by `esp_lcd_new_panel_io_i2c()` + * @param config Touch panel configuration + * @param tp Touch panel handle + * @return + * - ESP_OK: on success + */ +esp_err_t esp_lcd_touch_new_i2c_cst816s(const esp_lcd_panel_io_handle_t io, const esp_lcd_touch_config_t *config, esp_lcd_touch_handle_t *tp); + +/** + * @brief I2C address of the CST816S controller + * + */ +#define ESP_LCD_TOUCH_IO_I2C_CST816S_ADDRESS (0x15) + +/** + * @brief Touch IO configuration structure + * + */ +#define ESP_LCD_TOUCH_IO_I2C_CST816_CONFIG() \ + { \ + .dev_addr = ESP_LCD_TOUCH_IO_I2C_CST816S_ADDRESS, \ + .control_phase_bytes = 1, \ + .dc_bit_offset = 0, \ + .lcd_cmd_bits = 8, \ + .flags = \ + { \ + .disable_control_phase = 1, \ + } \ + } + + +// I2C settings +#define I2C_Touch_SDA_IO 1 /*!< GPIO number used for I2C master data */ +#define I2C_Touch_SCL_IO 3 /*!< GPIO number used for I2C master clock */ +#define I2C_Touch_INT_IO 4 /*!< GPIO number used for I2C master data */ +#define I2C_Touch_RST_IO -1 /*!< GPIO number used for I2C master clock */ +#define I2C_Touch_MASTER_NUM 1 /*!< I2C master i2c port number, the number of i2c peripheral interfaces available will depend on the chip */ +#define I2C_Touch_MASTER_FREQ_HZ 400000 /*!< I2C master clock frequency */ + +extern esp_lcd_touch_handle_t tp; + +void Touch_Init(void); diff --git a/Lib/Display/Touch_Driver/esp_lcd_touch/esp_lcd_touch.c b/Lib/Display/Touch_Driver/esp_lcd_touch/esp_lcd_touch.c new file mode 100644 index 0000000..a52ed52 --- /dev/null +++ b/Lib/Display/Touch_Driver/esp_lcd_touch/esp_lcd_touch.c @@ -0,0 +1,258 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "driver/gpio.h" +#include "esp_system.h" +#include "esp_err.h" +#include "esp_check.h" +#include "esp_log.h" +#include "esp_lcd_touch.h" + +static const char *TAG = "TP"; + +/******************************************************************************* +* Function definitions +*******************************************************************************/ + +/******************************************************************************* +* Local variables +*******************************************************************************/ + +/******************************************************************************* +* Public API functions +*******************************************************************************/ + +esp_err_t esp_lcd_touch_enter_sleep(esp_lcd_touch_handle_t tp) +{ + assert(tp != NULL); + if (tp->enter_sleep == NULL) { + ESP_LOGE(TAG, "Sleep mode not supported!"); + return ESP_FAIL; + } else { + return tp->enter_sleep(tp); + } +} + +esp_err_t esp_lcd_touch_exit_sleep(esp_lcd_touch_handle_t tp) +{ + assert(tp != NULL); + if (tp->exit_sleep == NULL) { + ESP_LOGE(TAG, "Sleep mode not supported!"); + return ESP_FAIL; + } else { + return tp->exit_sleep(tp); + } +} + +esp_err_t esp_lcd_touch_read_data(esp_lcd_touch_handle_t tp) +{ + assert(tp != NULL); + assert(tp->read_data != NULL); + + return tp->read_data(tp); +} + +bool esp_lcd_touch_get_coordinates(esp_lcd_touch_handle_t tp, uint16_t *x, uint16_t *y, uint16_t *strength, uint8_t *point_num, uint8_t max_point_num) +{ + bool touched = false; + + assert(tp != NULL); + assert(x != NULL); + assert(y != NULL); + assert(tp->get_xy != NULL); + + touched = tp->get_xy(tp, x, y, strength, point_num, max_point_num); + if (!touched) { + return false; + } + + /* Process coordinates by user */ + if (tp->config.process_coordinates != NULL) { + tp->config.process_coordinates(tp, x, y, strength, point_num, max_point_num); + } + + /* Software coordinates adjustment needed */ + bool sw_adj_needed = ((tp->config.flags.mirror_x && (tp->set_mirror_x == NULL)) || + (tp->config.flags.mirror_y && (tp->set_mirror_y == NULL)) || + (tp->config.flags.swap_xy && (tp->set_swap_xy == NULL))); + + /* Adjust all coordinates */ + for (int i = 0; (sw_adj_needed && i < *point_num); i++) { + + /* Mirror X coordinates (if not supported by HW) */ + if (tp->config.flags.mirror_x && tp->set_mirror_x == NULL) { + x[i] = tp->config.x_max - x[i]; + } + + /* Mirror Y coordinates (if not supported by HW) */ + if (tp->config.flags.mirror_y && tp->set_mirror_y == NULL) { + y[i] = tp->config.y_max - y[i]; + } + + /* Swap X and Y coordinates (if not supported by HW) */ + if (tp->config.flags.swap_xy && tp->set_swap_xy == NULL) { + uint16_t tmp = x[i]; + x[i] = y[i]; + y[i] = tmp; + } + } + + return touched; +} + +#if (CONFIG_ESP_LCD_TOUCH_MAX_BUTTONS > 0) +esp_err_t esp_lcd_touch_get_button_state(esp_lcd_touch_handle_t tp, uint8_t n, uint8_t *state) +{ + assert(tp != NULL); + assert(state != NULL); + + *state = 0; + + if (tp->get_button_state) { + return tp->get_button_state(tp, n, state); + } else { + return ESP_ERR_NOT_SUPPORTED; + } + + return ESP_OK; +} +#endif + +esp_err_t esp_lcd_touch_set_swap_xy(esp_lcd_touch_handle_t tp, bool swap) +{ + assert(tp != NULL); + + tp->config.flags.swap_xy = swap; + + /* Is swap supported by HW? */ + if (tp->set_swap_xy) { + return tp->set_swap_xy(tp, swap); + } + + return ESP_OK; +} + +esp_err_t esp_lcd_touch_get_swap_xy(esp_lcd_touch_handle_t tp, bool *swap) +{ + assert(tp != NULL); + assert(swap != NULL); + + /* Is swap supported by HW? */ + if (tp->get_swap_xy) { + return tp->get_swap_xy(tp, swap); + } else { + *swap = tp->config.flags.swap_xy; + } + + return ESP_OK; +} + +esp_err_t esp_lcd_touch_set_mirror_x(esp_lcd_touch_handle_t tp, bool mirror) +{ + assert(tp != NULL); + + tp->config.flags.mirror_x = mirror; + + /* Is mirror supported by HW? */ + if (tp->set_mirror_x) { + return tp->set_mirror_x(tp, mirror); + } + + return ESP_OK; +} + +esp_err_t esp_lcd_touch_get_mirror_x(esp_lcd_touch_handle_t tp, bool *mirror) +{ + assert(tp != NULL); + assert(mirror != NULL); + + /* Is swap supported by HW? */ + if (tp->get_mirror_x) { + return tp->get_mirror_x(tp, mirror); + } else { + *mirror = tp->config.flags.mirror_x; + } + + return ESP_OK; +} + +esp_err_t esp_lcd_touch_set_mirror_y(esp_lcd_touch_handle_t tp, bool mirror) +{ + assert(tp != NULL); + + tp->config.flags.mirror_y = mirror; + + /* Is mirror supported by HW? */ + if (tp->set_mirror_y) { + return tp->set_mirror_y(tp, mirror); + } + + return ESP_OK; +} + +esp_err_t esp_lcd_touch_get_mirror_y(esp_lcd_touch_handle_t tp, bool *mirror) +{ + assert(tp != NULL); + assert(mirror != NULL); + + /* Is swap supported by HW? */ + if (tp->get_mirror_y) { + return tp->get_mirror_y(tp, mirror); + } else { + *mirror = tp->config.flags.mirror_y; + } + + return ESP_OK; +} + +esp_err_t esp_lcd_touch_del(esp_lcd_touch_handle_t tp) +{ + assert(tp != NULL); + + if (tp->del != NULL) { + return tp->del(tp); + } + + return ESP_OK; +} + +esp_err_t esp_lcd_touch_register_interrupt_callback(esp_lcd_touch_handle_t tp, esp_lcd_touch_interrupt_callback_t callback) +{ + esp_err_t ret = ESP_OK; + assert(tp != NULL); + + /* Interrupt pin is not selected */ + if (tp->config.int_gpio_num == GPIO_NUM_NC) { + return ESP_ERR_INVALID_ARG; + } + + tp->config.interrupt_callback = callback; + + if (callback != NULL) { + ret = gpio_install_isr_service(0); + /* ISR service can be installed from user before, then it returns invalid state */ + if (ret != ESP_OK && ret != ESP_ERR_INVALID_STATE) { + ESP_LOGE(TAG, "GPIO ISR install failed"); + return ret; + } + /* Add GPIO ISR handler */ + ret = gpio_intr_enable(tp->config.int_gpio_num); + ESP_RETURN_ON_ERROR(ret, TAG, "GPIO ISR install failed"); + ret = gpio_isr_handler_add(tp->config.int_gpio_num, (gpio_isr_t)tp->config.interrupt_callback, tp); + ESP_RETURN_ON_ERROR(ret, TAG, "GPIO ISR install failed"); + } else { + /* Remove GPIO ISR handler */ + ret = gpio_isr_handler_remove(tp->config.int_gpio_num); + ESP_RETURN_ON_ERROR(ret, TAG, "GPIO ISR remove handler failed"); + ret = gpio_intr_disable(tp->config.int_gpio_num); + ESP_RETURN_ON_ERROR(ret, TAG, "GPIO ISR disable failed"); + } + + return ESP_OK; +} diff --git a/Lib/Display/Touch_Driver/esp_lcd_touch/esp_lcd_touch.h b/Lib/Display/Touch_Driver/esp_lcd_touch/esp_lcd_touch.h new file mode 100644 index 0000000..4549ac9 --- /dev/null +++ b/Lib/Display/Touch_Driver/esp_lcd_touch/esp_lcd_touch.h @@ -0,0 +1,413 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief ESP LCD touch + */ + +#pragma once + +#include +#include "sdkconfig.h" +#include "esp_err.h" +#include "driver/gpio.h" +#include "esp_lcd_panel_io.h" +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" + +#ifdef __cplusplus +extern "C" { +#endif +#define CONFIG_ESP_LCD_TOUCH_MAX_POINTS 2 +/** + * @brief Touch controller type + * + */ +typedef struct esp_lcd_touch_s esp_lcd_touch_t; +typedef esp_lcd_touch_t *esp_lcd_touch_handle_t; + +/** + * @brief Touch controller interrupt callback type + * + */ +typedef void (*esp_lcd_touch_interrupt_callback_t)(esp_lcd_touch_handle_t tp); + +/** + * @brief Touch Configuration Type + * + */ +typedef struct { + uint16_t x_max; /*!< X coordinates max (for mirroring) */ + uint16_t y_max; /*!< Y coordinates max (for mirroring) */ + + gpio_num_t rst_gpio_num; /*!< GPIO number of reset pin */ + gpio_num_t int_gpio_num; /*!< GPIO number of interrupt pin */ + + struct { + unsigned int reset: 1; /*!< Level of reset pin in reset */ + unsigned int interrupt: 1;/*!< Active Level of interrupt pin */ + } levels; + + struct { + unsigned int swap_xy: 1; /*!< Swap X and Y after read coordinates */ + unsigned int mirror_x: 1; /*!< Mirror X after read coordinates */ + unsigned int mirror_y: 1; /*!< Mirror Y after read coordinates */ + } flags; + + /*!< User callback called after get coordinates from touch controller for apply user adjusting */ + void (*process_coordinates)(esp_lcd_touch_handle_t tp, uint16_t *x, uint16_t *y, uint16_t *strength, uint8_t *point_num, uint8_t max_point_num); + /*!< User callback called after the touch interrupt occured */ + esp_lcd_touch_interrupt_callback_t interrupt_callback; +} esp_lcd_touch_config_t; + +typedef struct { + uint8_t points; /*!< Count of touch points saved */ + + struct { + uint16_t x; /*!< X coordinate */ + uint16_t y; /*!< Y coordinate */ + uint16_t strength; /*!< Strength */ + } coords[CONFIG_ESP_LCD_TOUCH_MAX_POINTS]; + +#if (CONFIG_ESP_LCD_TOUCH_MAX_BUTTONS > 0) + uint8_t buttons; /*!< Count of buttons states saved */ + + struct { + uint8_t status; /*!< Status of button */ + } button[CONFIG_ESP_LCD_TOUCH_MAX_BUTTONS]; +#endif + + portMUX_TYPE lock; /*!< Lock for read/write */ +} esp_lcd_touch_data_t; + +/** + * @brief Declare of Touch Type + * + */ +struct esp_lcd_touch_s { + + /** + * @brief set touch controller into sleep mode + * + * @note This function is usually blocking. + * + * @param tp: Touch handler + * + * @return + * - ESP_OK on success, otherwise returns ESP_ERR_xxx + */ + esp_err_t (*enter_sleep)(esp_lcd_touch_handle_t tp); + + /** + * @brief set touch controller into normal mode + * + * @note This function is usually blocking. + * + * @param tp: Touch handler + * + * @return + * - ESP_OK on success, otherwise returns ESP_ERR_xxx + */ + esp_err_t (*exit_sleep)(esp_lcd_touch_handle_t tp); + + /** + * @brief Read data from touch controller (mandatory) + * + * @note This function is usually blocking. + * + * @param tp: Touch handler + * + * @return + * - ESP_OK on success, otherwise returns ESP_ERR_xxx + */ + esp_err_t (*read_data)(esp_lcd_touch_handle_t tp); + + /** + * @brief Get coordinates from touch controller (mandatory) + * + * @param tp: Touch handler + * @param x: Array of X coordinates + * @param y: Array of Y coordinates + * @param strength: Array of strengths + * @param point_num: Count of points touched (equals with count of items in x and y array) + * @param max_point_num: Maximum count of touched points to return (equals with max size of x and y array) + * + * @return + * - Returns true, when touched and coordinates readed. Otherwise returns false. + */ + bool (*get_xy)(esp_lcd_touch_handle_t tp, uint16_t *x, uint16_t *y, uint16_t *strength, uint8_t *point_num, uint8_t max_point_num); + + +#if (CONFIG_ESP_LCD_TOUCH_MAX_BUTTONS > 0) + /** + * @brief Get button state (optional) + * + * @param tp: Touch handler + * @param n: Button index + * @param state: Button state + * + * @return + * - Returns true, when touched and coordinates readed. Otherwise returns false. + */ + esp_err_t (*get_button_state)(esp_lcd_touch_handle_t tp, uint8_t n, uint8_t *state); +#endif + + /** + * @brief Swap X and Y after read coordinates (optional) + * If set, then not used SW swapping. + * + * @param tp: Touch handler + * @param swap: Set swap value + * + * @return + * - ESP_OK on success, otherwise returns ESP_ERR_xxx + */ + esp_err_t (*set_swap_xy)(esp_lcd_touch_handle_t tp, bool swap); + + /** + * @brief Are X and Y coordinates swapped (optional) + * + * @param tp: Touch handler + * @param swap: Get swap value + * + * @return + * - ESP_OK on success, otherwise returns ESP_ERR_xxx + */ + esp_err_t (*get_swap_xy)(esp_lcd_touch_handle_t tp, bool *swap); + + /** + * @brief Mirror X after read coordinates + * If set, then not used SW mirroring. + * + * @param tp: Touch handler + * @param mirror: Set X mirror value + * + * @return + * - ESP_OK on success, otherwise returns ESP_ERR_xxx + */ + esp_err_t (*set_mirror_x)(esp_lcd_touch_handle_t tp, bool mirror); + + /** + * @brief Is mirrored X (optional) + * + * @param tp: Touch handler + * @param mirror: Get X mirror value + * + * @return + * - ESP_OK on success, otherwise returns ESP_ERR_xxx + */ + esp_err_t (*get_mirror_x)(esp_lcd_touch_handle_t tp, bool *mirror); + + /** + * @brief Mirror Y after read coordinates + * If set, then not used SW mirroring. + * + * @param tp: Touch handler + * @param mirror: Set Y mirror value + * + * @return + * - ESP_OK on success, otherwise returns ESP_ERR_xxx + */ + esp_err_t (*set_mirror_y)(esp_lcd_touch_handle_t tp, bool mirror); + + /** + * @brief Is mirrored Y (optional) + * + * @param tp: Touch handler + * @param mirror: Get Y mirror value + * + * @return + * - ESP_OK on success, otherwise returns ESP_ERR_xxx + */ + esp_err_t (*get_mirror_y)(esp_lcd_touch_handle_t tp, bool *mirror); + + /** + * @brief Delete Touch + * + * @param tp: Touch handler + * + * @return + * - ESP_OK on success, otherwise returns ESP_ERR_xxx + */ + esp_err_t (*del)(esp_lcd_touch_handle_t tp); + + /** + * @brief Configuration structure + */ + esp_lcd_touch_config_t config; + + /** + * @brief Communication interface + */ + esp_lcd_panel_io_handle_t io; + + /** + * @brief Data structure + */ + esp_lcd_touch_data_t data; +}; + +/** + * @brief Read data from touch controller + * + * @note This function is usually blocking. + * + * @param tp: Touch handler + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG parameter error + * - ESP_FAIL sending command error, slave hasn't ACK the transfer + * - ESP_ERR_INVALID_STATE I2C driver not installed or not in master mode + * - ESP_ERR_TIMEOUT operation timeout because the bus is busy + */ +esp_err_t esp_lcd_touch_read_data(esp_lcd_touch_handle_t tp); + +/** + * @brief Read coordinates from touch controller + * + * @param tp: Touch handler + * @param x: Array of X coordinates + * @param y: Array of Y coordinates + * @param strength: Array of the strengths (can be NULL) + * @param point_num: Count of points touched (equals with count of items in x and y array) + * @param max_point_num: Maximum count of touched points to return (equals with max size of x and y array) + * + * @return + * - Returns true, when touched and coordinates readed. Otherwise returns false. + */ +bool esp_lcd_touch_get_coordinates(esp_lcd_touch_handle_t tp, uint16_t *x, uint16_t *y, uint16_t *strength, uint8_t *point_num, uint8_t max_point_num); + + +#if (CONFIG_ESP_LCD_TOUCH_MAX_BUTTONS > 0) +/** + * @brief Get button state + * + * @param tp: Touch handler + * @param n: Button index + * @param state: Button state + * + * @return + * - ESP_OK on success + * - ESP_ERR_NOT_SUPPORTED if this function is not supported by controller + * - ESP_ERR_INVALID_ARG if bad button index + */ +esp_err_t esp_lcd_touch_get_button_state(esp_lcd_touch_handle_t tp, uint8_t n, uint8_t *state); +#endif + +/** + * @brief Swap X and Y after read coordinates + * + * @param tp: Touch handler + * @param swap: Set swap value + * + * @return + * - ESP_OK on success + */ +esp_err_t esp_lcd_touch_set_swap_xy(esp_lcd_touch_handle_t tp, bool swap); + +/** + * @brief Are X and Y coordinates swapped + * + * @param tp: Touch handler + * @param swap: Get swap value + * + * @return + * - ESP_OK on success + */ +esp_err_t esp_lcd_touch_get_swap_xy(esp_lcd_touch_handle_t tp, bool *swap); + +/** + * @brief Mirror X after read coordinates + * + * @param tp: Touch handler + * @param mirror: Set X mirror value + * + * @return + * - ESP_OK on success + */ +esp_err_t esp_lcd_touch_set_mirror_x(esp_lcd_touch_handle_t tp, bool mirror); + +/** + * @brief Is mirrored X + * + * @param tp: Touch handler + * @param mirror: Get X mirror value + * + * @return + * - ESP_OK on success + */ +esp_err_t esp_lcd_touch_get_mirror_x(esp_lcd_touch_handle_t tp, bool *mirror); + +/** + * @brief Mirror Y after read coordinates + * + * @param tp: Touch handler + * @param mirror: Set Y mirror value + * + * @return + * - ESP_OK on success + */ +esp_err_t esp_lcd_touch_set_mirror_y(esp_lcd_touch_handle_t tp, bool mirror); + +/** + * @brief Is mirrored Y + * + * @param tp: Touch handler + * @param mirror: Get Y mirror value + * + * @return + * - ESP_OK on success + */ +esp_err_t esp_lcd_touch_get_mirror_y(esp_lcd_touch_handle_t tp, bool *mirror); + +/** + * @brief Delete touch (free all allocated memory and restart HW) + * + * @param tp: Touch handler + * + * @return + * - ESP_OK on success + */ +esp_err_t esp_lcd_touch_del(esp_lcd_touch_handle_t tp); + +/** + * @brief Register user callback called after the touch interrupt occured + * + * @param tp: Touch handler + * @param callback: Interrupt callback + * + * @return + * - ESP_OK on success + */ +esp_err_t esp_lcd_touch_register_interrupt_callback(esp_lcd_touch_handle_t tp, esp_lcd_touch_interrupt_callback_t callback); + +/** + * @brief Enter sleep mode + * + * @param tp: Touch handler + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG if parameter is invalid + */ +esp_err_t esp_lcd_touch_enter_sleep(esp_lcd_touch_handle_t tp); + +/** + * @brief Exit sleep mode + * + * @param tp: Touch handler + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG if parameter is invalid + */ +esp_err_t esp_lcd_touch_exit_sleep(esp_lcd_touch_handle_t tp); + +#ifdef __cplusplus +} +#endif diff --git a/Util/general_err_handle/err_handle.c b/Util/general_err_handle/err_handle.c new file mode 100644 index 0000000..35cd6c3 --- /dev/null +++ b/Util/general_err_handle/err_handle.c @@ -0,0 +1,3 @@ +// +// Created by misaki on 2025/8/25. +// \ No newline at end of file diff --git a/Util/general_err_handle/err_handle.h b/Util/general_err_handle/err_handle.h new file mode 100644 index 0000000..316979d --- /dev/null +++ b/Util/general_err_handle/err_handle.h @@ -0,0 +1,12 @@ +// +// Created by misaki on 2025/8/25. +// + +#ifndef BIONIC_SPHERE_ERR_HANDLE_H +#define BIONIC_SPHERE_ERR_HANDLE_H + +#define ESP_GOTO(goto_tag) do { \ +goto goto_tag; \ +} while (0) + +#endif //BIONIC_SPHERE_ERR_HANDLE_H \ No newline at end of file diff --git a/main/Bionic_sphere.c b/main/Bionic_sphere.c index 8bb9375..bd29a5e 100644 --- a/main/Bionic_sphere.c +++ b/main/Bionic_sphere.c @@ -3,7 +3,10 @@ #include -#include +#include "err_handle.h" + +#include "drivers_test.h" + void app_main(void) @@ -21,4 +24,10 @@ void app_main(void) // exio_text(); // audio_test(); + + lcd_touch_lvgl_test(); + + ESP_GOTO(err); +err: + ESP_LOGI("app_main", "app_main error"); } diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 8de6a67..2e34302 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -2,6 +2,7 @@ idf_component_register(SRCS "Bionic_sphere.c" "../test/driver_test/drivers_test.c" # 测试用例 "../test/EXIO_Test/TCA9554PWR_Test.c" # 测试用例 "../test/audio_test/audio_test.c" # 测试用例 + "../Util/general_err_handle/err_handle.c" # 错误处理库 "../Lib/I2C_Driver/I2C_Driver.c" # IIC底层驱动库 "../Lib/QMI8658/QMI8658.c" # IMU驱动库 "../Lib/BAT_Driver/BAT_Driver.c" # 电池adc驱动库 @@ -10,10 +11,18 @@ idf_component_register(SRCS "Bionic_sphere.c" "../Lib/PCF85063/PCF85063.c" # RTC驱动库 "../Lib/EXIO/TCA9554PWR.c" # IO拓展库 "../Lib/Audio_Driver/PCM5101.c" # 音频驱动库(播放) - INCLUDE_DIRS "." + "../Lib/Display/LCD_Driver/ST77916.c" + "../Lib/Display/LCD_Driver/esp_lcd_st77916/esp_lcd_st77916.c" + "../Lib/Display/LVGL_Driver/LVGL_Driver.c" + "../Lib/Display/LVGL_UI/LVGL_Music.c" + "../Lib/Display/LVGL_UI/LVGL_Example.c" + "../Lib/Display/Touch_Driver/CST816.c" + "../Lib/Display/Touch_Driver/esp_lcd_touch/esp_lcd_touch.c" + INCLUDE_DIRS "." "../test/driver_test" "../test/EXIO_Test" "../test/audio_test" + "../Util/general_err_handle" "../Lib/I2C_Driver" "../Lib/QMI8658" "../Lib/BAT_Driver" @@ -22,6 +31,13 @@ idf_component_register(SRCS "Bionic_sphere.c" "../Lib/PCF85063" "../Lib/EXIO" "../Lib/Audio_Driver" + "../Lib/Display/LCD_Driver" + "../Lib/Display/LCD_Driver/esp_lcd_st77916" + "../Lib/Display/LVGL_Driver" + "../Lib/Display/LVGL_UI" + "../Lib/Display/LVGL_UI" + "../Lib/Display/Touch_Driver" + "../Lib/Display/Touch_Driver/esp_lcd_touch" PRIV_REQUIRES # 私有依赖 driver bt @@ -30,4 +46,5 @@ idf_component_register(SRCS "Bionic_sphere.c" esp_adc fatfs unity + esp_lcd ) diff --git a/sdkconfig b/sdkconfig index 0de77d0..9536365 100644 --- a/sdkconfig +++ b/sdkconfig @@ -2475,7 +2475,7 @@ CONFIG_LV_COLOR_DEPTH_16=y # CONFIG_LV_COLOR_DEPTH_8 is not set # CONFIG_LV_COLOR_DEPTH_1 is not set CONFIG_LV_COLOR_DEPTH=16 -# CONFIG_LV_COLOR_16_SWAP is not set +CONFIG_LV_COLOR_16_SWAP=y # CONFIG_LV_COLOR_SCREEN_TRANSP is not set CONFIG_LV_COLOR_MIX_ROUND_OFS=128 CONFIG_LV_COLOR_CHROMA_KEY_HEX=0x00FF00 @@ -2485,7 +2485,7 @@ CONFIG_LV_COLOR_CHROMA_KEY_HEX=0x00FF00 # Memory settings # # CONFIG_LV_MEM_CUSTOM is not set -CONFIG_LV_MEM_SIZE_KILOBYTES=32 +CONFIG_LV_MEM_SIZE_KILOBYTES=48 CONFIG_LV_MEM_ADDR=0x0 CONFIG_LV_MEM_BUF_MAX_NUM=16 # CONFIG_LV_MEMCPY_MEMSET_STD is not set @@ -2578,9 +2578,9 @@ CONFIG_LV_ATTRIBUTE_MEM_ALIGN_SIZE=1 # # CONFIG_LV_FONT_MONTSERRAT_8 is not set # CONFIG_LV_FONT_MONTSERRAT_10 is not set -# CONFIG_LV_FONT_MONTSERRAT_12 is not set +CONFIG_LV_FONT_MONTSERRAT_12=y CONFIG_LV_FONT_MONTSERRAT_14=y -# CONFIG_LV_FONT_MONTSERRAT_16 is not set +CONFIG_LV_FONT_MONTSERRAT_16=y # CONFIG_LV_FONT_MONTSERRAT_18 is not set # CONFIG_LV_FONT_MONTSERRAT_20 is not set # CONFIG_LV_FONT_MONTSERRAT_22 is not set @@ -2758,11 +2758,18 @@ CONFIG_LV_BUILD_EXAMPLES=y # # Demos # -# CONFIG_LV_USE_DEMO_WIDGETS is not set -# CONFIG_LV_USE_DEMO_KEYPAD_AND_ENCODER is not set -# CONFIG_LV_USE_DEMO_BENCHMARK is not set +CONFIG_LV_USE_DEMO_WIDGETS=y +CONFIG_LV_DEMO_WIDGETS_SLIDESHOW=y +CONFIG_LV_USE_DEMO_KEYPAD_AND_ENCODER=y +CONFIG_LV_USE_DEMO_BENCHMARK=y +# CONFIG_LV_DEMO_BENCHMARK_RGB565A8 is not set # CONFIG_LV_USE_DEMO_STRESS is not set -# CONFIG_LV_USE_DEMO_MUSIC is not set +CONFIG_LV_USE_DEMO_MUSIC=y +# CONFIG_LV_DEMO_MUSIC_SQUARE is not set +# CONFIG_LV_DEMO_MUSIC_LANDSCAPE is not set +# CONFIG_LV_DEMO_MUSIC_ROUND is not set +# CONFIG_LV_DEMO_MUSIC_LARGE is not set +# CONFIG_LV_DEMO_MUSIC_AUTO_PLAY is not set # end of Demos # end of LVGL configuration # end of Component config diff --git a/sdkconfig.old b/sdkconfig.old index 97f9dd1..be82a8e 100644 --- a/sdkconfig.old +++ b/sdkconfig.old @@ -536,6 +536,59 @@ CONFIG_PARTITION_TABLE_OFFSET=0x8000 CONFIG_PARTITION_TABLE_MD5=y # end of Partition Table +# +# ESP Speech Recognition +# +CONFIG_MODEL_IN_FLASH=y +# CONFIG_MODEL_IN_SDCARD is not set +CONFIG_USE_AFE=y +CONFIG_AFE_INTERFACE_V1=y +# CONFIG_USE_NSNET is not set +CONFIG_USE_WAKENET=y +# CONFIG_SR_WN_WN8_ALEXA is not set +CONFIG_SR_WN_WN9_HILEXIN=y +# CONFIG_SR_WN_WN9_XIAOAITONGXUE is not set +# CONFIG_SR_WN_WN9_ALEXA is not set +# CONFIG_SR_WN_WN9_HIESP is not set +# CONFIG_SR_WN_WN9_HIMFIVE is not set +# CONFIG_SR_WN_WN9_NIHAOXIAOZHI_TTS is not set +# CONFIG_SR_WN_WN9_JARVIS_TTS is not set +# CONFIG_SR_WN_WN9_COMPUTER_TTS is not set +# CONFIG_SR_WN_WN9_HEYWILLOW_TTS is not set +# CONFIG_SR_WN_WN9_SOPHIA_TTS is not set +# CONFIG_SR_WN_WN9_NIHAOXIAOXIN_TTS is not set +# CONFIG_SR_WN_WN9_XIAOMEITONGXUE_TTS is not set +# CONFIG_SR_WN_WN9_HIXIAOXING_TTS is not set +# CONFIG_SR_WN_WN9_MYCROFT_TTS is not set +# CONFIG_SR_WN_WN9_HEYPRINTER_TTS is not set +# CONFIG_SR_WN_WN9_XIAOLONGXIAOLONG_TTS is not set +# CONFIG_SR_WN_WN9_MIAOMIAOTONGXUE_TTS is not set +# CONFIG_SR_WN_WN9_HIJOY_TTS is not set +# CONFIG_SR_WN_WN9_HILILI_TTS is not set +# CONFIG_SR_WN_WN9_HITELLY_TTS is not set +# CONFIG_SR_WN_WN9_HEYWANDA_TTS is not set +# CONFIG_SR_WN_WN9_HIMIAOMIAO_TTS is not set +# CONFIG_SR_WN_WN9_XIAOBINXIAOBIN_TTS is not set +# CONFIG_SR_WN_WN9_HAIXIAOWU_TTS is not set +# CONFIG_SR_WN_WN9_ASTROLABE_TTS is not set +# CONFIG_SR_WN_WN9_XIAOYAXIAOYA_TTS2 is not set +# CONFIG_SR_WN_WN9_HIJASON_TTS2 is not set +# CONFIG_SR_WN_WN9_LINAIBAN_TTS2 is not set +# CONFIG_SR_WN_WN9_CUSTOMWORD is not set +# CONFIG_SR_WN_LOAD_MULIT_WORD is not set +CONFIG_USE_MULTINET=y +# CONFIG_SR_MN_CN_NONE is not set +# CONFIG_SR_MN_CN_MULTINET5_RECOGNITION_QUANT8 is not set +CONFIG_SR_MN_CN_MULTINET6_QUANT=y +# CONFIG_SR_MN_CN_MULTINET6_AC_QUANT is not set +# CONFIG_SR_MN_CN_MULTINET7_QUANT is not set +# CONFIG_SR_MN_CN_MULTINET7_AC_QUANT is not set +CONFIG_SR_MN_EN_NONE=y +# CONFIG_SR_MN_EN_MULTINET5_SINGLE_RECOGNITION_QUANT8 is not set +# CONFIG_SR_MN_EN_MULTINET6_QUANT is not set +# CONFIG_SR_MN_EN_MULTINET7_QUANT is not set +# end of ESP Speech Recognition + # # Compiler options # @@ -1392,9 +1445,9 @@ CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768 # ESP System Settings # # CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80 is not set -CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160=y -# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240 is not set -CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160 +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160 is not set +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=240 # # Cache config @@ -2382,6 +2435,336 @@ CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # CONFIG_WIFI_PROV_STA_FAST_SCAN is not set # end of Wi-Fi Provisioning Manager + +# +# Audio playback +# +CONFIG_AUDIO_PLAYER_ENABLE_MP3=y +CONFIG_AUDIO_PLAYER_ENABLE_WAV=y +CONFIG_AUDIO_PLAYER_LOG_LEVEL=0 +# end of Audio playback + +# +# DSP Library +# +CONFIG_DSP_OPTIMIZATIONS_SUPPORTED=y +# CONFIG_DSP_ANSI is not set +CONFIG_DSP_OPTIMIZED=y +CONFIG_DSP_OPTIMIZATION=1 +# CONFIG_DSP_MAX_FFT_SIZE_512 is not set +# CONFIG_DSP_MAX_FFT_SIZE_1024 is not set +# CONFIG_DSP_MAX_FFT_SIZE_2048 is not set +CONFIG_DSP_MAX_FFT_SIZE_4096=y +# CONFIG_DSP_MAX_FFT_SIZE_8192 is not set +# CONFIG_DSP_MAX_FFT_SIZE_16384 is not set +# CONFIG_DSP_MAX_FFT_SIZE_32768 is not set +CONFIG_DSP_MAX_FFT_SIZE=4096 +# end of DSP Library + +# +# LVGL configuration +# +CONFIG_LV_CONF_SKIP=y +# CONFIG_LV_CONF_MINIMAL is not set + +# +# Color settings +# +# CONFIG_LV_COLOR_DEPTH_32 is not set +CONFIG_LV_COLOR_DEPTH_16=y +# CONFIG_LV_COLOR_DEPTH_8 is not set +# CONFIG_LV_COLOR_DEPTH_1 is not set +CONFIG_LV_COLOR_DEPTH=16 +# CONFIG_LV_COLOR_16_SWAP is not set +# CONFIG_LV_COLOR_SCREEN_TRANSP is not set +CONFIG_LV_COLOR_MIX_ROUND_OFS=128 +CONFIG_LV_COLOR_CHROMA_KEY_HEX=0x00FF00 +# end of Color settings + +# +# Memory settings +# +# CONFIG_LV_MEM_CUSTOM is not set +CONFIG_LV_MEM_SIZE_KILOBYTES=32 +CONFIG_LV_MEM_ADDR=0x0 +CONFIG_LV_MEM_BUF_MAX_NUM=16 +# CONFIG_LV_MEMCPY_MEMSET_STD is not set +# end of Memory settings + +# +# HAL Settings +# +CONFIG_LV_DISP_DEF_REFR_PERIOD=30 +CONFIG_LV_INDEV_DEF_READ_PERIOD=30 +# CONFIG_LV_TICK_CUSTOM is not set +CONFIG_LV_DPI_DEF=130 +# end of HAL Settings + +# +# Feature configuration +# + +# +# Drawing +# +CONFIG_LV_DRAW_COMPLEX=y +CONFIG_LV_SHADOW_CACHE_SIZE=0 +CONFIG_LV_CIRCLE_CACHE_SIZE=4 +CONFIG_LV_LAYER_SIMPLE_BUF_SIZE=24576 +CONFIG_LV_IMG_CACHE_DEF_SIZE=0 +CONFIG_LV_GRADIENT_MAX_STOPS=2 +CONFIG_LV_GRAD_CACHE_DEF_SIZE=0 +# CONFIG_LV_DITHER_GRADIENT is not set +CONFIG_LV_DISP_ROT_MAX_BUF=10240 +# end of Drawing + +# +# GPU +# +# CONFIG_LV_USE_GPU_ARM2D is not set +# CONFIG_LV_USE_GPU_STM32_DMA2D is not set +# CONFIG_LV_USE_GPU_RA6M3_G2D is not set +# CONFIG_LV_USE_GPU_SWM341_DMA2D is not set +# CONFIG_LV_USE_GPU_NXP_PXP is not set +# CONFIG_LV_USE_GPU_NXP_VG_LITE is not set +# CONFIG_LV_USE_GPU_SDL is not set +# end of GPU + +# +# Logging +# +# CONFIG_LV_USE_LOG is not set +# end of Logging + +# +# Asserts +# +CONFIG_LV_USE_ASSERT_NULL=y +CONFIG_LV_USE_ASSERT_MALLOC=y +# CONFIG_LV_USE_ASSERT_STYLE is not set +# CONFIG_LV_USE_ASSERT_MEM_INTEGRITY is not set +# CONFIG_LV_USE_ASSERT_OBJ is not set +CONFIG_LV_ASSERT_HANDLER_INCLUDE="assert.h" +# end of Asserts + +# +# Others +# +# CONFIG_LV_USE_PERF_MONITOR is not set +# CONFIG_LV_USE_MEM_MONITOR is not set +# CONFIG_LV_USE_REFR_DEBUG is not set +# CONFIG_LV_SPRINTF_CUSTOM is not set +# CONFIG_LV_SPRINTF_USE_FLOAT is not set +CONFIG_LV_USE_USER_DATA=y +# CONFIG_LV_ENABLE_GC is not set +# end of Others + +# +# Compiler settings +# +# CONFIG_LV_BIG_ENDIAN_SYSTEM is not set +CONFIG_LV_ATTRIBUTE_MEM_ALIGN_SIZE=1 +# CONFIG_LV_ATTRIBUTE_FAST_MEM_USE_IRAM is not set +# CONFIG_LV_USE_LARGE_COORD is not set +# end of Compiler settings +# end of Feature configuration + +# +# Font usage +# + +# +# Enable built-in fonts +# +# CONFIG_LV_FONT_MONTSERRAT_8 is not set +# CONFIG_LV_FONT_MONTSERRAT_10 is not set +CONFIG_LV_FONT_MONTSERRAT_12=y +CONFIG_LV_FONT_MONTSERRAT_14=y +CONFIG_LV_FONT_MONTSERRAT_16=y +# CONFIG_LV_FONT_MONTSERRAT_18 is not set +# CONFIG_LV_FONT_MONTSERRAT_20 is not set +# CONFIG_LV_FONT_MONTSERRAT_22 is not set +# CONFIG_LV_FONT_MONTSERRAT_24 is not set +# CONFIG_LV_FONT_MONTSERRAT_26 is not set +# CONFIG_LV_FONT_MONTSERRAT_28 is not set +# CONFIG_LV_FONT_MONTSERRAT_30 is not set +# CONFIG_LV_FONT_MONTSERRAT_32 is not set +# CONFIG_LV_FONT_MONTSERRAT_34 is not set +# CONFIG_LV_FONT_MONTSERRAT_36 is not set +# CONFIG_LV_FONT_MONTSERRAT_38 is not set +# CONFIG_LV_FONT_MONTSERRAT_40 is not set +# CONFIG_LV_FONT_MONTSERRAT_42 is not set +# CONFIG_LV_FONT_MONTSERRAT_44 is not set +# CONFIG_LV_FONT_MONTSERRAT_46 is not set +# CONFIG_LV_FONT_MONTSERRAT_48 is not set +# CONFIG_LV_FONT_MONTSERRAT_12_SUBPX is not set +# CONFIG_LV_FONT_MONTSERRAT_28_COMPRESSED is not set +# CONFIG_LV_FONT_DEJAVU_16_PERSIAN_HEBREW is not set +# CONFIG_LV_FONT_SIMSUN_16_CJK is not set +# CONFIG_LV_FONT_UNSCII_8 is not set +# CONFIG_LV_FONT_UNSCII_16 is not set +# CONFIG_LV_FONT_CUSTOM is not set +# end of Enable built-in fonts + +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_8 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_12 is not set +CONFIG_LV_FONT_DEFAULT_MONTSERRAT_14=y +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_16 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_18 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_20 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_22 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_24 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_26 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_28 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_30 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_32 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_34 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_36 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_38 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_40 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_42 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_44 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_46 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_48 is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_12_SUBPX is not set +# CONFIG_LV_FONT_DEFAULT_MONTSERRAT_28_COMPRESSED is not set +# CONFIG_LV_FONT_DEFAULT_DEJAVU_16_PERSIAN_HEBREW is not set +# CONFIG_LV_FONT_DEFAULT_SIMSUN_16_CJK is not set +# CONFIG_LV_FONT_DEFAULT_UNSCII_8 is not set +# CONFIG_LV_FONT_DEFAULT_UNSCII_16 is not set +# CONFIG_LV_FONT_FMT_TXT_LARGE is not set +# CONFIG_LV_USE_FONT_COMPRESSED is not set +# CONFIG_LV_USE_FONT_SUBPX is not set +CONFIG_LV_USE_FONT_PLACEHOLDER=y +# end of Font usage + +# +# Text Settings +# +CONFIG_LV_TXT_ENC_UTF8=y +# CONFIG_LV_TXT_ENC_ASCII is not set +CONFIG_LV_TXT_BREAK_CHARS=" ,.;:-_" +CONFIG_LV_TXT_LINE_BREAK_LONG_LEN=0 +CONFIG_LV_TXT_COLOR_CMD="#" +# CONFIG_LV_USE_BIDI is not set +# CONFIG_LV_USE_ARABIC_PERSIAN_CHARS is not set +# end of Text Settings + +# +# Widget usage +# +CONFIG_LV_USE_ARC=y +CONFIG_LV_USE_BAR=y +CONFIG_LV_USE_BTN=y +CONFIG_LV_USE_BTNMATRIX=y +CONFIG_LV_USE_CANVAS=y +CONFIG_LV_USE_CHECKBOX=y +CONFIG_LV_USE_DROPDOWN=y +CONFIG_LV_USE_IMG=y +CONFIG_LV_USE_LABEL=y +CONFIG_LV_LABEL_TEXT_SELECTION=y +CONFIG_LV_LABEL_LONG_TXT_HINT=y +CONFIG_LV_USE_LINE=y +CONFIG_LV_USE_ROLLER=y +CONFIG_LV_ROLLER_INF_PAGES=7 +CONFIG_LV_USE_SLIDER=y +CONFIG_LV_USE_SWITCH=y +CONFIG_LV_USE_TEXTAREA=y +CONFIG_LV_TEXTAREA_DEF_PWD_SHOW_TIME=1500 +CONFIG_LV_USE_TABLE=y +# end of Widget usage + +# +# Extra Widgets +# +CONFIG_LV_USE_ANIMIMG=y +CONFIG_LV_USE_CALENDAR=y +# CONFIG_LV_CALENDAR_WEEK_STARTS_MONDAY is not set +CONFIG_LV_USE_CALENDAR_HEADER_ARROW=y +CONFIG_LV_USE_CALENDAR_HEADER_DROPDOWN=y +CONFIG_LV_USE_CHART=y +CONFIG_LV_USE_COLORWHEEL=y +CONFIG_LV_USE_IMGBTN=y +CONFIG_LV_USE_KEYBOARD=y +CONFIG_LV_USE_LED=y +CONFIG_LV_USE_LIST=y +CONFIG_LV_USE_MENU=y +CONFIG_LV_USE_METER=y +CONFIG_LV_USE_MSGBOX=y +CONFIG_LV_USE_SPAN=y +CONFIG_LV_SPAN_SNIPPET_STACK_SIZE=64 +CONFIG_LV_USE_SPINBOX=y +CONFIG_LV_USE_SPINNER=y +CONFIG_LV_USE_TABVIEW=y +CONFIG_LV_USE_TILEVIEW=y +CONFIG_LV_USE_WIN=y +# end of Extra Widgets + +# +# Themes +# +CONFIG_LV_USE_THEME_DEFAULT=y +# CONFIG_LV_THEME_DEFAULT_DARK is not set +CONFIG_LV_THEME_DEFAULT_GROW=y +CONFIG_LV_THEME_DEFAULT_TRANSITION_TIME=80 +CONFIG_LV_USE_THEME_BASIC=y +# CONFIG_LV_USE_THEME_MONO is not set +# end of Themes + +# +# Layouts +# +CONFIG_LV_USE_FLEX=y +CONFIG_LV_USE_GRID=y +# end of Layouts + +# +# 3rd Party Libraries +# +# CONFIG_LV_USE_FS_STDIO is not set +# CONFIG_LV_USE_FS_POSIX is not set +# CONFIG_LV_USE_FS_WIN32 is not set +# CONFIG_LV_USE_FS_FATFS is not set +# CONFIG_LV_USE_FS_LITTLEFS is not set +# CONFIG_LV_USE_PNG is not set +# CONFIG_LV_USE_BMP is not set +# CONFIG_LV_USE_SJPG is not set +# CONFIG_LV_USE_GIF is not set +# CONFIG_LV_USE_QRCODE is not set +# CONFIG_LV_USE_FREETYPE is not set +# CONFIG_LV_USE_TINY_TTF is not set +# CONFIG_LV_USE_RLOTTIE is not set +# CONFIG_LV_USE_FFMPEG is not set +# end of 3rd Party Libraries + +# +# Others +# +CONFIG_LV_USE_SNAPSHOT=y +# CONFIG_LV_USE_MONKEY is not set +# CONFIG_LV_USE_GRIDNAV is not set +# CONFIG_LV_USE_FRAGMENT is not set +# CONFIG_LV_USE_IMGFONT is not set +# CONFIG_LV_USE_MSG is not set +# CONFIG_LV_USE_IME_PINYIN is not set +# end of Others + +# +# Examples +# +CONFIG_LV_BUILD_EXAMPLES=y +# end of Examples + +# +# Demos +# +# CONFIG_LV_USE_DEMO_WIDGETS is not set +# CONFIG_LV_USE_DEMO_KEYPAD_AND_ENCODER is not set +# CONFIG_LV_USE_DEMO_BENCHMARK is not set +# CONFIG_LV_USE_DEMO_STRESS is not set +# CONFIG_LV_USE_DEMO_MUSIC is not set +# end of Demos +# end of LVGL configuration # end of Component config # CONFIG_IDF_EXPERIMENTAL_FEATURES is not set @@ -2633,9 +3016,9 @@ CONFIG_ESP32S3_SPIRAM_SUPPORT=y CONFIG_DEFAULT_PSRAM_CLK_IO=30 CONFIG_DEFAULT_PSRAM_CS_IO=26 # CONFIG_ESP32S3_DEFAULT_CPU_FREQ_80 is not set -CONFIG_ESP32S3_DEFAULT_CPU_FREQ_160=y -# CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240 is not set -CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ=160 +# CONFIG_ESP32S3_DEFAULT_CPU_FREQ_160 is not set +CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240=y +CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ=240 CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 CONFIG_MAIN_TASK_STACK_SIZE=3584 diff --git a/test/driver_test/drivers_test.c b/test/driver_test/drivers_test.c index e72a15f..ba40777 100644 --- a/test/driver_test/drivers_test.c +++ b/test/driver_test/drivers_test.c @@ -209,4 +209,38 @@ void exio_text(void) void audio_test(void) { run_audio_test(); +} + + +#include "ST77916.h" +#include "LVGL_Driver.h" +#include "LVGL_Example.h" +void lcd_touch_lvgl_test(void) +{ + // 1. 初始化硬件 + I2C_Init(); + LCD_Init(); // 初始化屏幕和背光 + LVGL_Init(); // 初始化 LVGL + + // 2. 创建一个简单的测试界面 + lv_obj_t *label = lv_label_create(lv_scr_act()); + lv_label_set_text(label, "Hello, ST77916 + LVGL!"); + lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); + + // 3. 创建一个按钮用于测试触摸 + lv_obj_t *btn = lv_btn_create(lv_scr_act()); + lv_obj_align(btn, LV_ALIGN_CENTER, 0, 50); + lv_obj_t *btn_label = lv_label_create(btn); + lv_label_set_text(btn_label, "Click Me"); + lv_obj_center(btn_label); + + // lv_obj_add_event_cb(btn, [](lv_event_t *e) { + // lv_label_set_text(label, "Button Clicked!"); + // }, LV_EVENT_CLICKED, NULL); + + // 4. 在主循环中运行 LVGL + while (1) { + lv_timer_handler(); + vTaskDelay(pdMS_TO_TICKS(10)); + } } \ No newline at end of file diff --git a/test/driver_test/drivers_test.h b/test/driver_test/drivers_test.h index ad20735..50f377d 100644 --- a/test/driver_test/drivers_test.h +++ b/test/driver_test/drivers_test.h @@ -26,5 +26,8 @@ void exio_text(void); // 音频测试 void audio_test(void); +// LCD测试 +void lcd_touch_lvgl_test(void); + #endif //BIONIC_SPHERE_DRIVERS_TEST_H \ No newline at end of file diff --git a/项目开发日志.md b/项目开发日志.md index 627126f..e839d20 100644 --- a/项目开发日志.md +++ b/项目开发日志.md @@ -146,3 +146,9 @@ - [x] 9. 测试了音频播放功能,测试通过 +#### Day4 2025.8.25 +##### 主要目标:测试开发板官方提供的例程中的驱动能否使用 +实际完成任务: +- [x] 1. 测试了屏幕驱动,lvgl,触摸,驱动文件在Lib/Display当中。全部通过(修改了sdkconfig,以适配lvgl) + +- [x] 2. 新增了优雅的C语言错误处理 \ No newline at end of file