Feature: 支持 LVGL 作为嵌入式显示屏的底层。 #7
| @@ -10,6 +10,12 @@ dependencies: | |||||||
|     source: |     source: | ||||||
|       type: idf |       type: idf | ||||||
|     version: 5.0.1 |     version: 5.0.1 | ||||||
| manifest_hash: d23f3b15e8b95dfe5da6cf83768d24158a3a0222f95694b1fa09c3ca8602f79f |   lvgl/lvgl: | ||||||
|  |     component_hash: 0f2006e7b800eee17b73ed4f92ffbaa76d61c02ba4779ec9efbcd5f453bb0102 | ||||||
|  |     source: | ||||||
|  |       service_url: https://api.components.espressif.com/ | ||||||
|  |       type: service | ||||||
|  |     version: 8.3.6~1 | ||||||
|  | manifest_hash: 9a88337b9db92c26041847f5fd4efc58df1dcf0e9c6b8758da96aaac2e63c2a2 | ||||||
| target: esp32c3 | target: esp32c3 | ||||||
| version: 1.0.0 | version: 1.0.0 | ||||||
|   | |||||||
| @@ -1,2 +1,24 @@ | |||||||
| idf_component_register(SRCS "udp_server.c" "service_discovery.c" "app_nvs.c" "apds_9960.c" "pca9555.c" "i2c.c" "asr_pro.c" "ci_03t.c" "ui_input.c" "ambient_light.c" "temperature.c" "embedded_display.c" "mqtt.c" "main.c" "wifi.c" "light.c" "mqtt.c" "led_strip_encoder/led_strip_encoder.c" | idf_component_register( | ||||||
|                     INCLUDE_DIRS ".") |   SRCS | ||||||
|  |     "udp_server.c" | ||||||
|  |     "service_discovery.c" | ||||||
|  |     "app_nvs.c" | ||||||
|  |     "ch1116.c" | ||||||
|  |     # "apds_9960.c" | ||||||
|  |     "pca9555.c" | ||||||
|  |     "i2c.c" | ||||||
|  |     "asr_pro.c" | ||||||
|  |     "ci_03t.c" | ||||||
|  |     "ui_input.c" | ||||||
|  |     # "ambient_light.c" | ||||||
|  |     # "temperature.c" | ||||||
|  |     # "mqtt.c" | ||||||
|  |     "main.c" | ||||||
|  |     "wifi.c" | ||||||
|  |     "light.c" | ||||||
|  |     "led_strip_encoder/led_strip_encoder.c" | ||||||
|  |     "gui.c" | ||||||
|  |     "lvgl_demo_ui.c" | ||||||
|  |     "app_icon_8.c" | ||||||
|  |   INCLUDE_DIRS "." | ||||||
|  | ) | ||||||
| @@ -1,10 +1,10 @@ | |||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
|  |  | ||||||
|  | #include "ch1116.c" | ||||||
| #include "common.h" | #include "common.h" | ||||||
| #include "driver/gpio.h" | #include "driver/gpio.h" | ||||||
| #include "driver/i2c.h" | #include "driver/i2c.h" | ||||||
| #include "embedded_display.c" |  | ||||||
| #include "esp_log.h" | #include "esp_log.h" | ||||||
| #include "esp_timer.h" | #include "esp_timer.h" | ||||||
| #include "freertos/FreeRTOS.h" | #include "freertos/FreeRTOS.h" | ||||||
|   | |||||||
							
								
								
									
										157
									
								
								main/app_icon_8.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								main/app_icon_8.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,157 @@ | |||||||
|  | /******************************************************************************* | ||||||
|  |  * Size: 8 px | ||||||
|  |  * Bpp: 1 | ||||||
|  |  * Opts: | ||||||
|  |  ******************************************************************************/ | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "lvgl.h" | ||||||
|  |  | ||||||
|  | #ifndef APP_ICON_8 | ||||||
|  | #define APP_ICON_8 1 | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #if APP_ICON_8 | ||||||
|  |  | ||||||
|  | /*----------------- | ||||||
|  |  *    BITMAPS | ||||||
|  |  *----------------*/ | ||||||
|  |  | ||||||
|  | /*Store the image of the glyphs*/ | ||||||
|  | static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { | ||||||
|  |     /* U+E1CB "" */ | ||||||
|  |     0x38, 0x31, 0x88, 0xfa, 0x49, 0x54, 0x44, 0x10, 0xf8, | ||||||
|  |  | ||||||
|  |     /* U+E1CC "" */ | ||||||
|  |     0x80, 0x1f, 0xa, 0x22, 0x6b, 0xd4, 0x44, 0xd0, 0xc8, 0x1, | ||||||
|  |  | ||||||
|  |     /* U+E29E "" */ | ||||||
|  |     0xe, 0x4, 0xa8, 0x32, 0x18, 0xe, 0xd, 0x8c, 0x7c, | ||||||
|  |  | ||||||
|  |     /* U+F1EB "" */ | ||||||
|  |     0x1e, 0x18, 0x68, 0x4, 0x78, 0x21, 0x0, 0x0, 0xc0, 0x0, | ||||||
|  |  | ||||||
|  |     /* U+F6AA "" */ | ||||||
|  |     0xc0, | ||||||
|  |  | ||||||
|  |     /* U+F6AB "" */ | ||||||
|  |     0x79, 0x8, 0x1, 0x80}; | ||||||
|  |  | ||||||
|  | /*--------------------- | ||||||
|  |  *  GLYPH DESCRIPTION | ||||||
|  |  *--------------------*/ | ||||||
|  |  | ||||||
|  | static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { | ||||||
|  |     {.bitmap_index = 0, | ||||||
|  |      .adv_w = 0, | ||||||
|  |      .box_w = 0, | ||||||
|  |      .box_h = 0, | ||||||
|  |      .ofs_x = 0, | ||||||
|  |      .ofs_y = 0} /* id = 0 reserved */, | ||||||
|  |     {.bitmap_index = 0, | ||||||
|  |      .adv_w = 160, | ||||||
|  |      .box_w = 10, | ||||||
|  |      .box_h = 7, | ||||||
|  |      .ofs_x = 0, | ||||||
|  |      .ofs_y = 0}, | ||||||
|  |     {.bitmap_index = 9, | ||||||
|  |      .adv_w = 160, | ||||||
|  |      .box_w = 10, | ||||||
|  |      .box_h = 8, | ||||||
|  |      .ofs_x = 0, | ||||||
|  |      .ofs_y = -1}, | ||||||
|  |     {.bitmap_index = 19, | ||||||
|  |      .adv_w = 128, | ||||||
|  |      .box_w = 9, | ||||||
|  |      .box_h = 8, | ||||||
|  |      .ofs_x = 0, | ||||||
|  |      .ofs_y = -1}, | ||||||
|  |     {.bitmap_index = 28, | ||||||
|  |      .adv_w = 160, | ||||||
|  |      .box_w = 10, | ||||||
|  |      .box_h = 8, | ||||||
|  |      .ofs_x = 0, | ||||||
|  |      .ofs_y = -1}, | ||||||
|  |     {.bitmap_index = 38, | ||||||
|  |      .adv_w = 32, | ||||||
|  |      .box_w = 2, | ||||||
|  |      .box_h = 2, | ||||||
|  |      .ofs_x = 4, | ||||||
|  |      .ofs_y = -1}, | ||||||
|  |     {.bitmap_index = 39, | ||||||
|  |      .adv_w = 112, | ||||||
|  |      .box_w = 7, | ||||||
|  |      .box_h = 4, | ||||||
|  |      .ofs_x = 2, | ||||||
|  |      .ofs_y = 0}}; | ||||||
|  |  | ||||||
|  | /*--------------------- | ||||||
|  |  *  CHARACTER MAPPING | ||||||
|  |  *--------------------*/ | ||||||
|  |  | ||||||
|  | static const uint16_t unicode_list_0[] = {0x0,    0x1,    0xd3, | ||||||
|  |                                           0x1020, 0x14df, 0x14e0}; | ||||||
|  |  | ||||||
|  | /*Collect the unicode lists and glyph_id offsets*/ | ||||||
|  | static const lv_font_fmt_txt_cmap_t cmaps[] = { | ||||||
|  |     {.range_start = 57803, | ||||||
|  |      .range_length = 5345, | ||||||
|  |      .glyph_id_start = 1, | ||||||
|  |      .unicode_list = unicode_list_0, | ||||||
|  |      .glyph_id_ofs_list = NULL, | ||||||
|  |      .list_length = 6, | ||||||
|  |      .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY}}; | ||||||
|  |  | ||||||
|  | /*-------------------- | ||||||
|  |  *  ALL CUSTOM DATA | ||||||
|  |  *--------------------*/ | ||||||
|  |  | ||||||
|  | #if LV_VERSION_CHECK(8, 0, 0) | ||||||
|  | /*Store all the custom data of the font*/ | ||||||
|  | static lv_font_fmt_txt_glyph_cache_t cache; | ||||||
|  | static const lv_font_fmt_txt_dsc_t font_dsc = { | ||||||
|  | #else | ||||||
|  | static lv_font_fmt_txt_dsc_t font_dsc = { | ||||||
|  | #endif | ||||||
|  |     .glyph_bitmap = glyph_bitmap, | ||||||
|  |     .glyph_dsc = glyph_dsc, | ||||||
|  |     .cmaps = cmaps, | ||||||
|  |     .kern_dsc = NULL, | ||||||
|  |     .kern_scale = 0, | ||||||
|  |     .cmap_num = 1, | ||||||
|  |     .bpp = 1, | ||||||
|  |     .kern_classes = 0, | ||||||
|  |     .bitmap_format = 0, | ||||||
|  | #if LV_VERSION_CHECK(8, 0, 0) | ||||||
|  |     .cache = &cache | ||||||
|  | #endif | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /*----------------- | ||||||
|  |  *  PUBLIC FONT | ||||||
|  |  *----------------*/ | ||||||
|  |  | ||||||
|  | /*Initialize a public general font descriptor*/ | ||||||
|  | #if LV_VERSION_CHECK(8, 0, 0) | ||||||
|  | const lv_font_t app_icon_8 = { | ||||||
|  | #else | ||||||
|  | lv_font_t app_icon_8 = { | ||||||
|  | #endif | ||||||
|  |     .get_glyph_dsc = | ||||||
|  |         lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ | ||||||
|  |     .get_glyph_bitmap = | ||||||
|  |         lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/ | ||||||
|  |     .line_height = 8, /*The maximum line height required by the font*/ | ||||||
|  |     .base_line = 1,   /*Baseline measured from the bottom of the line*/ | ||||||
|  | #if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) | ||||||
|  |     .subpx = LV_FONT_SUBPX_NONE, | ||||||
|  | #endif | ||||||
|  | #if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8 | ||||||
|  |     .underline_position = -1, | ||||||
|  |     .underline_thickness = 0, | ||||||
|  | #endif | ||||||
|  |     .dsc = &font_dsc /*The custom font data. Will be accessed by | ||||||
|  |                         `get_glyph_bitmap/dsc` */ | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif /*#if APP_ICON_8*/ | ||||||
							
								
								
									
										269
									
								
								main/ch1116.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										269
									
								
								main/ch1116.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,269 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  | #include "driver/gpio.h" | ||||||
|  | #include "driver/i2c.h" | ||||||
|  | #include "esp_err.h" | ||||||
|  | #include "esp_log.h" | ||||||
|  | #include "freertos/task.h" | ||||||
|  | #include "sdkconfig.h"  // generated by "make menuconfig" | ||||||
|  |  | ||||||
|  | #define CH1116_TAG "CH1116" | ||||||
|  |  | ||||||
|  | #define SDA_PIN GPIO_NUM_4 | ||||||
|  | #define SCL_PIN GPIO_NUM_5 | ||||||
|  |  | ||||||
|  | #define CH1116_WIDTH 128 | ||||||
|  | #define CH1116_HEIGHT 64 | ||||||
|  |  | ||||||
|  | #define CH1116_ADDRESS 0x3C  // 011110+SA0 - 0x3C or 0x3D | ||||||
|  |  | ||||||
|  | // CH1116 Control | ||||||
|  |  | ||||||
|  | #define CH1116_CONTROL_BYTE_COMMAND_SINGLE 0x80 | ||||||
|  | #define CH1116_CONTROL_BYTE_COMMAND_STREAM 0x00 | ||||||
|  | #define CH1116_CONTROL_BYTE_DATA_SINGLE 0xC0 | ||||||
|  | #define CH1116_CONTROL_BYTE_DATA_STREAM 0x40 | ||||||
|  |  | ||||||
|  | // CH1116 Config Commands | ||||||
|  |  | ||||||
|  | #define CH1116_DISPLAY_OFF 0xAE  // #13 | ||||||
|  |  | ||||||
|  | #define CH1116_LOWER_COLUMN_ADDRESS 0x02   // #1 0x02-0x0F | ||||||
|  | #define CH1116_HIGHER_COLUMN_ADDRESS 0x10  // #2 0x10-0x1F | ||||||
|  |  | ||||||
|  | #define CH1116_DISPLAY_START_LINE 0x40  // #3 | ||||||
|  |  | ||||||
|  | #define CH1116_PAGE_ADDRESS 0xB0  // #18 0xB0-0xB7 | ||||||
|  |  | ||||||
|  | #define CH1116_CONTRACT_CONTROL 0x81      // #10 | ||||||
|  | #define CH1116_CONTRACT_CONTROL_128 0xCF  // #10 | ||||||
|  |  | ||||||
|  | #define CH1116_SEGMENT_REMAP 0xA1  // #12   ADC=1 (right) | ||||||
|  |  | ||||||
|  | #define CH1116_NORMAL_DISPLAY 0xA6  // #14 | ||||||
|  |  | ||||||
|  | #define CH1116_MULTIPLEX_RATIO 0xA8  // #15 | ||||||
|  | #define CH1116_MULTIPLEX_RATIO_1_64 0x3F | ||||||
|  |  | ||||||
|  | // VCC Generated by Internal DC/DC Circuit | ||||||
|  | #define CH1116_CHARGE_PUMP_ENABLE 0xAD               // #16 | ||||||
|  | #define CH1116_CHARGE_PUMP_ENABLE_INTERNAL_VCC 0x8B  // #16 | ||||||
|  |  | ||||||
|  | #define CH1116_CHARGE_PUMP_VOLTAGE_9V 0x33  // #8 | ||||||
|  |  | ||||||
|  | #define CH1116_COM_SCAN_DIRECTION 0xC8  // #19 | ||||||
|  |  | ||||||
|  | #define CH1116_DISPLAY_OFFSET 0xD3    // #20 | ||||||
|  | #define CH1116_DISPLAY_OFFSET_0 0x00  // #20 | ||||||
|  |  | ||||||
|  | #define CH1116_SET_OSC_DIVISION 0xD5    // #21 | ||||||
|  | #define CH1116_SET_OSC_DIVISION_1 0x80  // #21 | ||||||
|  |  | ||||||
|  | #define CH1116_SET_PRE_CHARGE_PERIOD 0xD9    // #22 | ||||||
|  | #define CH1116_SET_PRE_CHARGE_PERIOD_1 0x1F  // #22 | ||||||
|  |  | ||||||
|  | #define CH1116_SET_COM_PINS 0xDA    // #23 | ||||||
|  | #define CH1116_SET_COM_PINS_1 0x12  // #23 | ||||||
|  |  | ||||||
|  | #define CH1116_SET_VCOMH 0xDB    // #24 | ||||||
|  | #define CH1116_SET_VCOMH_1 0x40  // #24 | ||||||
|  |  | ||||||
|  | #define CH1116_DISPLAY_ON 0xAF  // #13 | ||||||
|  |  | ||||||
|  | void ch1116_init() { | ||||||
|  |   esp_err_t err; | ||||||
|  |  | ||||||
|  |   i2c_cmd_handle_t cmd = i2c_cmd_link_create(); | ||||||
|  |  | ||||||
|  |   i2c_master_start(cmd); | ||||||
|  |   i2c_master_write_byte(cmd, (CH1116_ADDRESS << 1) | I2C_MASTER_WRITE, true); | ||||||
|  |  | ||||||
|  |   i2c_master_write_byte(cmd, CH1116_CONTROL_BYTE_COMMAND_STREAM, true); | ||||||
|  |  | ||||||
|  |   i2c_master_write_byte(cmd, CH1116_DISPLAY_OFF, true); | ||||||
|  |  | ||||||
|  |   i2c_master_write_byte(cmd, CH1116_LOWER_COLUMN_ADDRESS, true); | ||||||
|  |   i2c_master_write_byte(cmd, CH1116_HIGHER_COLUMN_ADDRESS, true); | ||||||
|  |  | ||||||
|  |   i2c_master_write_byte(cmd, CH1116_DISPLAY_START_LINE, true); | ||||||
|  |  | ||||||
|  |   i2c_master_write_byte(cmd, CH1116_PAGE_ADDRESS, true); | ||||||
|  |  | ||||||
|  |   i2c_master_write_byte(cmd, CH1116_CONTRACT_CONTROL, true); | ||||||
|  |   i2c_master_write_byte(cmd, CH1116_CONTRACT_CONTROL_128, true); | ||||||
|  |  | ||||||
|  |   i2c_master_write_byte(cmd, CH1116_SEGMENT_REMAP, true); | ||||||
|  |  | ||||||
|  |   i2c_master_write_byte(cmd, CH1116_NORMAL_DISPLAY, true); | ||||||
|  |  | ||||||
|  |   i2c_master_write_byte(cmd, CH1116_MULTIPLEX_RATIO, true); | ||||||
|  |   i2c_master_write_byte(cmd, CH1116_MULTIPLEX_RATIO_1_64, true); | ||||||
|  |  | ||||||
|  |   i2c_master_write_byte(cmd, CH1116_CHARGE_PUMP_ENABLE, true); | ||||||
|  |   i2c_master_write_byte(cmd, CH1116_CHARGE_PUMP_ENABLE_INTERNAL_VCC, true); | ||||||
|  |  | ||||||
|  |   i2c_master_write_byte(cmd, CH1116_CHARGE_PUMP_VOLTAGE_9V, true); | ||||||
|  |  | ||||||
|  |   i2c_master_write_byte(cmd, CH1116_COM_SCAN_DIRECTION, true); | ||||||
|  |  | ||||||
|  |   i2c_master_write_byte(cmd, CH1116_DISPLAY_OFFSET, true); | ||||||
|  |   i2c_master_write_byte(cmd, CH1116_DISPLAY_OFFSET_0, true); | ||||||
|  |  | ||||||
|  |   i2c_master_write_byte(cmd, CH1116_SET_OSC_DIVISION, true); | ||||||
|  |   i2c_master_write_byte(cmd, CH1116_SET_OSC_DIVISION_1, true); | ||||||
|  |  | ||||||
|  |   i2c_master_write_byte(cmd, CH1116_SET_PRE_CHARGE_PERIOD, true); | ||||||
|  |   i2c_master_write_byte(cmd, CH1116_SET_PRE_CHARGE_PERIOD_1, true); | ||||||
|  |  | ||||||
|  |   i2c_master_write_byte(cmd, CH1116_SET_COM_PINS, true); | ||||||
|  |   i2c_master_write_byte(cmd, CH1116_SET_COM_PINS_1, true); | ||||||
|  |  | ||||||
|  |   i2c_master_write_byte(cmd, CH1116_SET_VCOMH, true); | ||||||
|  |   i2c_master_write_byte(cmd, CH1116_SET_VCOMH_1, true); | ||||||
|  |  | ||||||
|  |   i2c_master_write_byte(cmd, CH1116_DISPLAY_ON, true); | ||||||
|  |  | ||||||
|  |   i2c_master_stop(cmd); | ||||||
|  |  | ||||||
|  |   err = i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS); | ||||||
|  |   if (err == ESP_OK) { | ||||||
|  |     ESP_LOGI(CH1116_TAG, "OLED configured successfully"); | ||||||
|  |   } else { | ||||||
|  |     ESP_LOGE(CH1116_TAG, "OLED configuration failed. code: %s", | ||||||
|  |              esp_err_to_name(err)); | ||||||
|  |   } | ||||||
|  |   i2c_cmd_link_delete(cmd); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void task_ch1116_display_pattern(void *ignore) { | ||||||
|  |   i2c_cmd_handle_t cmd; | ||||||
|  |  | ||||||
|  |   for (uint8_t i = 0; i < 8; i++) { | ||||||
|  |     cmd = i2c_cmd_link_create(); | ||||||
|  |     i2c_master_start(cmd); | ||||||
|  |     i2c_master_write_byte(cmd, (CH1116_ADDRESS << 1) | I2C_MASTER_WRITE, true); | ||||||
|  |     i2c_master_write_byte(cmd, CH1116_CONTROL_BYTE_COMMAND_SINGLE, true); | ||||||
|  |     i2c_master_write_byte(cmd, 0xB0 | i, true); | ||||||
|  |     i2c_master_write_byte(cmd, CH1116_CONTROL_BYTE_DATA_STREAM, true); | ||||||
|  |     for (uint8_t j = 0; j < 132; j++) { | ||||||
|  |       i2c_master_write_byte(cmd, 0xFF >> (j % 8), true); | ||||||
|  |     } | ||||||
|  |     i2c_master_stop(cmd); | ||||||
|  |     i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS); | ||||||
|  |     i2c_cmd_link_delete(cmd); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void task_ch1116_display_clear(void *ignore) { | ||||||
|  |   i2c_cmd_handle_t cmd; | ||||||
|  |  | ||||||
|  |   uint8_t zero[132]; | ||||||
|  |   memset(zero, 0, 132); | ||||||
|  |   for (uint8_t i = 0; i < 8; i++) { | ||||||
|  |     cmd = i2c_cmd_link_create(); | ||||||
|  |     i2c_master_start(cmd); | ||||||
|  |     i2c_master_write_byte(cmd, (CH1116_ADDRESS << 1) | I2C_MASTER_WRITE, true); | ||||||
|  |     i2c_master_write_byte(cmd, CH1116_CONTROL_BYTE_COMMAND_SINGLE, true); | ||||||
|  |     i2c_master_write_byte(cmd, 0xB0 | i, true); | ||||||
|  |  | ||||||
|  |     i2c_master_write_byte(cmd, CH1116_CONTROL_BYTE_DATA_STREAM, true); | ||||||
|  |     i2c_master_write(cmd, zero, 132, true); | ||||||
|  |     i2c_master_stop(cmd); | ||||||
|  |     i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS); | ||||||
|  |     i2c_cmd_link_delete(cmd); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   cmd = i2c_cmd_link_create(); | ||||||
|  |   i2c_master_start(cmd); | ||||||
|  |   i2c_master_write_byte(cmd, CH1116_CONTROL_BYTE_COMMAND_STREAM, true); | ||||||
|  |   i2c_master_write_byte(cmd, 0x00, true);  // reset column | ||||||
|  |   i2c_master_write_byte(cmd, 0x10, true); | ||||||
|  |   i2c_master_write_byte(cmd, 0xB0, true);  // reset page | ||||||
|  |   i2c_master_stop(cmd); | ||||||
|  |   i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS); | ||||||
|  |   i2c_cmd_link_delete(cmd); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static esp_err_t ch1116_draw_bitmap(int x_start, int y_start, int x_end, | ||||||
|  |                                     int y_end, const void *color_data) { | ||||||
|  |   assert((x_start < x_end) && (y_start < y_end) && | ||||||
|  |          "start position must be smaller than end position"); | ||||||
|  |  | ||||||
|  |   // one page contains 8 rows (COMs) | ||||||
|  |   uint8_t page_start = y_start / 8; | ||||||
|  |   uint8_t page_end = y_end / 8; | ||||||
|  |   // define an area of frame memory where MCU can access | ||||||
|  |  | ||||||
|  |   esp_err_t err; | ||||||
|  |  | ||||||
|  |   i2c_cmd_handle_t cmd; | ||||||
|  |  | ||||||
|  |   uint8_t *color_data_ptr = (uint8_t *)color_data; | ||||||
|  |   uint16_t page_data_size = (x_end - x_start + 1); | ||||||
|  |  | ||||||
|  |   // ESP_LOGI(CH1116_TAG, "y_start: %d, y_end: %d, page_start: %d, page_end: | ||||||
|  |   // %d", | ||||||
|  |   //          y_start, y_end, page_start, page_end); | ||||||
|  |   // ESP_LOGI(CH1116_TAG, "x_start: %d, x_end: %d, page_data_size: %d", x_start, | ||||||
|  |   //          x_end, page_data_size); | ||||||
|  |  | ||||||
|  |   for (int page = page_start; page <= page_end; page++) { | ||||||
|  |     cmd = i2c_cmd_link_create(); | ||||||
|  |  | ||||||
|  |     i2c_master_start(cmd); | ||||||
|  |     i2c_master_write_byte(cmd, (CH1116_ADDRESS << 1) | I2C_MASTER_WRITE, true); | ||||||
|  |  | ||||||
|  |     // set cursor position | ||||||
|  |     i2c_master_write_byte(cmd, CH1116_CONTROL_BYTE_COMMAND_STREAM, true); | ||||||
|  |     i2c_master_write_byte(cmd, CH1116_LOWER_COLUMN_ADDRESS | (x_start & 0x0f), | ||||||
|  |                           true); | ||||||
|  |     i2c_master_write_byte(cmd, CH1116_HIGHER_COLUMN_ADDRESS | (x_start >> 4), | ||||||
|  |                           true); | ||||||
|  |     i2c_master_write_byte(cmd, CH1116_PAGE_ADDRESS | (page & 0x0f), true); | ||||||
|  |  | ||||||
|  |     i2c_master_stop(cmd); | ||||||
|  |  | ||||||
|  |     err = i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS); | ||||||
|  |     if (err != ESP_OK) { | ||||||
|  |       i2c_cmd_link_delete(cmd); | ||||||
|  |       return err; | ||||||
|  |     } | ||||||
|  |     i2c_cmd_link_delete(cmd); | ||||||
|  |  | ||||||
|  |     // write page data | ||||||
|  |     cmd = i2c_cmd_link_create(); | ||||||
|  |  | ||||||
|  |     i2c_master_start(cmd); | ||||||
|  |     i2c_master_write_byte(cmd, (CH1116_ADDRESS << 1) | I2C_MASTER_WRITE, true); | ||||||
|  |  | ||||||
|  |     i2c_master_write_byte(cmd, CH1116_CONTROL_BYTE_DATA_STREAM, true); | ||||||
|  |     i2c_master_write(cmd, color_data_ptr, page_data_size, true); | ||||||
|  |  | ||||||
|  |     i2c_master_stop(cmd); | ||||||
|  |  | ||||||
|  |     err = i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS); | ||||||
|  |  | ||||||
|  |     // ESP_LOG_BUFFER_HEXDUMP(CH1116_TAG, color_data_ptr, page_data_size, | ||||||
|  |     //                        ESP_LOG_INFO); | ||||||
|  |  | ||||||
|  |     color_data_ptr += page_data_size; | ||||||
|  |  | ||||||
|  |     if (err != ESP_OK) { | ||||||
|  |       i2c_cmd_link_delete(cmd); | ||||||
|  |       return err; | ||||||
|  |     } | ||||||
|  |     i2c_cmd_link_delete(cmd); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return ESP_OK; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ch1116_main(void) { | ||||||
|  |   ch1116_init(); | ||||||
|  |  | ||||||
|  |   task_ch1116_display_pattern(NULL); | ||||||
|  |   // vTaskDelay(1000 / portTICK_PERIOD_MS); | ||||||
|  |   // task_ch1116_display_clear(NULL); | ||||||
|  | } | ||||||
| @@ -1,145 +0,0 @@ | |||||||
| #pragma once |  | ||||||
| #include <stdio.h> |  | ||||||
| #include <stdlib.h> |  | ||||||
| #include <string.h> |  | ||||||
|  |  | ||||||
| #include "codetab.h" |  | ||||||
| #include "config_key.h" |  | ||||||
| #include "driver/i2c.h" |  | ||||||
| #include "esp_log.h" |  | ||||||
| #include "i2c.c" |  | ||||||
|  |  | ||||||
| #define Brightness 0xCF |  | ||||||
| #define X_WIDTH 128 |  | ||||||
| #define Y_WIDTH 64 |  | ||||||
|  |  | ||||||
| void i2cWriteByte(uint8_t reg, uint8_t data) { |  | ||||||
|   i2c_cmd_handle_t cmd = i2c_cmd_link_create(); |  | ||||||
|   i2c_master_start(cmd); |  | ||||||
|   i2c_master_write_byte(cmd, SSD1306_ADDRESS << 1 | I2C_MASTER_WRITE, true); |  | ||||||
|   i2c_master_write_byte(cmd, reg, true); |  | ||||||
|   i2c_master_write_byte(cmd, data, true); |  | ||||||
|   i2c_master_stop(cmd); |  | ||||||
|   i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_PERIOD_MS); |  | ||||||
|   i2c_cmd_link_delete(cmd); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void i2cWriteCommand(uint8_t data) { i2cWriteByte(0x00, data); } |  | ||||||
|  |  | ||||||
| void i2cWriteData(uint8_t data) { i2cWriteByte(0x40, data); } |  | ||||||
|  |  | ||||||
| void display_fill(uint8_t bmpData) { |  | ||||||
|   for (int y = 0; y < 8; y++) { |  | ||||||
|     i2cWriteCommand(0xB0 + y); |  | ||||||
|     i2cWriteCommand(0x01); |  | ||||||
|     i2cWriteCommand(0x10); |  | ||||||
|     for (int x = 0; x < X_WIDTH; x++) { |  | ||||||
|       i2cWriteData(bmpData); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| void display_fill_rect(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, |  | ||||||
|                        uint8_t bmpData) { |  | ||||||
|   for (int y = y0; y < y1; y++) { |  | ||||||
|     i2cWriteCommand(0xB0 + y); |  | ||||||
|     i2cWriteCommand(0x01); |  | ||||||
|     i2cWriteCommand(0x10); |  | ||||||
|     for (int x = x0; x < x1; x++) { |  | ||||||
|       i2cWriteData(bmpData); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void display_set_pos(uint8_t x, uint8_t y) { |  | ||||||
|   i2cWriteCommand(0xB0 + y); |  | ||||||
|   i2cWriteCommand(((x & 0xF0) >> 4) | 0x10); |  | ||||||
|   i2cWriteCommand((x & 0x0F) | 0x01); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void display_print8_str(uint8_t x, uint8_t y, char str[]) { |  | ||||||
|   if (!is_embedded_display_online) { |  | ||||||
|     return; |  | ||||||
|   } |  | ||||||
|   uint8_t c; |  | ||||||
|   for (uint8_t ch, ci = 0; ch = str[ci], ch != '\0'; ci++, x += 8) { |  | ||||||
|     c = ch - 0x20; |  | ||||||
|     display_set_pos(x, y); |  | ||||||
|     for (uint8_t cx = 0; cx < 8; cx++) { |  | ||||||
|       i2cWriteData(F8X16[c * 16 + cx]); |  | ||||||
|     } |  | ||||||
|     display_set_pos(x, y + 1); |  | ||||||
|     for (uint8_t cx = 0; cx < 8; cx++) { |  | ||||||
|       i2cWriteData(F8X16[c * 16 + cx + 8]); |  | ||||||
|     }; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void init_display() { |  | ||||||
|   if (is_embedded_display_online == 0) { |  | ||||||
|     ESP_LOGE("display", "display is offline"); |  | ||||||
|     return; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   i2cWriteCommand(0xAE);  // display off |  | ||||||
|   i2cWriteCommand(0x00);  // set lower column address |  | ||||||
|   i2cWriteCommand(0x10);  // set higher column address |  | ||||||
|   i2cWriteCommand(0x40);  // set start line address |  | ||||||
|   i2cWriteCommand(0x81);  // set contrast control register |  | ||||||
|   i2cWriteCommand(0xCF);  // set contrast |  | ||||||
|   i2cWriteCommand(0xA1);  // set segment re-map |  | ||||||
|   i2cWriteCommand(0xC8);  // set COM output scan direction |  | ||||||
|   i2cWriteCommand(0xA6);  // set normal display |  | ||||||
|   i2cWriteCommand(0xA8);  // set multiplex ratio(1 to 64) |  | ||||||
|   i2cWriteCommand(0x3F);  // 1/64 duty |  | ||||||
|   i2cWriteCommand(0xD3);  // set display offset |  | ||||||
|   i2cWriteCommand(0x00);  // not offset |  | ||||||
|   i2cWriteCommand(0xD5);  // set display clock divide ratio/oscillator frequency |  | ||||||
|   i2cWriteCommand(0x80);  // set divide ratio |  | ||||||
|   i2cWriteCommand(0xD9);  // set pre-charge period |  | ||||||
|   i2cWriteCommand(0xF1);  // set pre-charge voltage |  | ||||||
|   i2cWriteCommand(0xDA);  // set com pins hardware configuration |  | ||||||
|   i2cWriteCommand(0x12); |  | ||||||
|   i2cWriteCommand(0xDB);  // set vcomh |  | ||||||
|   i2cWriteCommand(0x40);  // 0.77*vcc |  | ||||||
|   i2cWriteCommand(0x20);  // set memory addressing mode |  | ||||||
|   i2cWriteCommand(0x02);  // set page addressing mode |  | ||||||
|   i2cWriteCommand(0x8D);  // set charge pump enable/disable |  | ||||||
|   i2cWriteCommand(0x14);  // set(0x10) disable |  | ||||||
|   i2cWriteCommand(0xAF);  // display on |  | ||||||
|  |  | ||||||
|   display_fill(0x00); |  | ||||||
|   display_set_pos(0, 0); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void gui_update_config_uint8(uint8_t key, uint8_t value) { |  | ||||||
|   char changing_str[12] = "NC"; |  | ||||||
|   switch (key) { |  | ||||||
|     case ui_input_key_display_0_brightness: |  | ||||||
|       sprintf(changing_str, "Dis0: % 3d", value); |  | ||||||
|       break; |  | ||||||
|     case ui_input_key_display_1_brightness: |  | ||||||
|       sprintf(changing_str, "Dis1: % 3d", value); |  | ||||||
|       break; |  | ||||||
|     case ui_input_key_computer_volume: |  | ||||||
|       sprintf(changing_str, "CVol: % 3d", value); |  | ||||||
|       break; |  | ||||||
|     case ui_input_key_display_ambient_lighting_level: |  | ||||||
|       sprintf(changing_str, "ALLv: % 3d", value); |  | ||||||
|       break; |  | ||||||
|     case ui_input_key_display_ambient_lighting_mode: |  | ||||||
|       sprintf(changing_str, "ALMd: % 3d", value); |  | ||||||
|       break; |  | ||||||
|     case ui_input_key_display_0_mode: |  | ||||||
|       sprintf(changing_str, "Dis0M: % 2d", value); |  | ||||||
|       break; |  | ||||||
|     case ui_input_key_display_1_mode: |  | ||||||
|       sprintf(changing_str, "Dis1M: % 2d", value); |  | ||||||
|       break; |  | ||||||
|  |  | ||||||
|     default: |  | ||||||
|       strcpy(changing_str, "NC"); |  | ||||||
|       break; |  | ||||||
|   } |  | ||||||
|   display_fill_rect(0, 6, 128, 8, 0); |  | ||||||
|   display_print8_str(8, 6, changing_str); |  | ||||||
| } |  | ||||||
							
								
								
									
										399
									
								
								main/gui.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										399
									
								
								main/gui.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,399 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include <stdio.h> | ||||||
|  |  | ||||||
|  | #include "app_icon_8.c" | ||||||
|  | #include "ch1116.c" | ||||||
|  | #include "driver/i2c.h" | ||||||
|  | #include "esp_err.h" | ||||||
|  | #include "esp_log.h" | ||||||
|  | #include "esp_timer.h" | ||||||
|  | #include "freertos/FreeRTOS.h" | ||||||
|  | #include "freertos/task.h" | ||||||
|  | #include "lvgl.h" | ||||||
|  |  | ||||||
|  | static const char *GUI_TAG = "LVGL_GUI"; | ||||||
|  |  | ||||||
|  | #define I2C_HOST 0 | ||||||
|  |  | ||||||
|  | #define EXAMPLE_LCD_PIXEL_CLOCK_HZ (400 * 1000) | ||||||
|  |  | ||||||
|  | #define EXAMPLE_LCD_H_RES CH1116_WIDTH | ||||||
|  | #define EXAMPLE_LCD_V_RES CH1116_HEIGHT | ||||||
|  |  | ||||||
|  | #define EXAMPLE_LVGL_TICK_PERIOD_MS 2 | ||||||
|  |  | ||||||
|  | // EF 9A AA | ||||||
|  | #define APP_WIFI_WEAK_SYMBOL "\xEF\x9A\xAA" | ||||||
|  | // EF 9A AB | ||||||
|  | #define APP_WIFI_FAIR_SYMBOL "\xEF\x9A\xAB" | ||||||
|  | //	EF 87 AB | ||||||
|  | #define APP_WIFI_GOOD_SYMBOL "\xEF\x87\xAB" | ||||||
|  |  | ||||||
|  | // EE 87 8B | ||||||
|  | #define APP_CONNECTED_SYMBOL "\xEE\x87\x8B" | ||||||
|  | // EE 87 8C | ||||||
|  | #define APP_DISCONNECTED_SYMBOL "\xEE\x87\x8C" | ||||||
|  |  | ||||||
|  | // EE 8A 9E | ||||||
|  | #define APP_TIMER_SYMBOL "\xEE\x8A\x9E" | ||||||
|  |  | ||||||
|  | extern void example_lvgl_demo_ui(lv_disp_t *disp); | ||||||
|  |  | ||||||
|  | static void example_lvgl_flush_cb(lv_disp_drv_t *drv, const lv_area_t *area, | ||||||
|  |                                   lv_color_t *color_map) { | ||||||
|  |   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 | ||||||
|  |   ch1116_draw_bitmap(offsetx1, offsety1, offsetx2, offsety2, color_map); | ||||||
|  |   lv_disp_flush_ready(drv); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void example_lvgl_set_px_cb(lv_disp_drv_t *disp_drv, uint8_t *buf, | ||||||
|  |                                    lv_coord_t buf_w, lv_coord_t x, lv_coord_t y, | ||||||
|  |                                    lv_color_t color, lv_opa_t opa) { | ||||||
|  |   uint16_t byte_index = x + ((y >> 3) * buf_w); | ||||||
|  |   uint8_t bit_index = y & 0x7; | ||||||
|  |  | ||||||
|  |   if ((color.full == 0) && (LV_OPA_TRANSP != opa)) { | ||||||
|  |     buf[byte_index] |= (1 << bit_index); | ||||||
|  |   } else { | ||||||
|  |     buf[byte_index] &= ~(1 << bit_index); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static lv_obj_t *wifi_label; | ||||||
|  | static lv_anim_t wifi_animate; | ||||||
|  |  | ||||||
|  | static lv_obj_t *timer_label; | ||||||
|  | static lv_anim_t timer_animate; | ||||||
|  |  | ||||||
|  | static lv_obj_t *desktop_label; | ||||||
|  | static lv_anim_t desktop_animate; | ||||||
|  |  | ||||||
|  | static lv_obj_t *value_setting_panel; | ||||||
|  | static lv_obj_t *value_setting_bar; | ||||||
|  | static lv_obj_t *value_setting_label; | ||||||
|  | static lv_obj_t *value_setting_value_label; | ||||||
|  |  | ||||||
|  | static lv_obj_t *scr; | ||||||
|  |  | ||||||
|  | static void example_lvgl_rounder(lv_disp_drv_t *disp_drv, lv_area_t *area) { | ||||||
|  |   area->y1 = area->y1 & (~0x7); | ||||||
|  |   area->y2 = area->y2 | 0x7; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void example_increase_lvgl_tick(void *arg) { | ||||||
|  |   /* Tell LVGL how many milliseconds has elapsed */ | ||||||
|  |   lv_tick_inc(EXAMPLE_LVGL_TICK_PERIOD_MS); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void set_value(void *bar, int32_t v) { | ||||||
|  |   lv_bar_set_value(bar, v, LV_ANIM_OFF); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void set_visible(void *obj, int32_t v) { | ||||||
|  |   if (v) { | ||||||
|  |     lv_obj_clear_flag(obj, LV_OBJ_FLAG_HIDDEN); | ||||||
|  |   } else { | ||||||
|  |     lv_obj_add_flag(obj, LV_OBJ_FLAG_HIDDEN); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void set_obj_blink_animate(lv_obj_t *obj, lv_anim_t *a) { | ||||||
|  |   lv_anim_init(a); | ||||||
|  |   lv_anim_set_exec_cb(a, set_visible); | ||||||
|  |   lv_anim_set_time(a, 100); | ||||||
|  |   lv_anim_set_playback_time(a, 100); | ||||||
|  |   lv_anim_set_playback_delay(a, 200); | ||||||
|  |   lv_anim_set_repeat_delay(a, 200); | ||||||
|  |   lv_anim_set_values(a, 0, 1); | ||||||
|  |   lv_anim_set_var(a, obj); | ||||||
|  |   lv_anim_set_repeat_count(a, LV_ANIM_REPEAT_INFINITE); | ||||||
|  |   lv_anim_start(a); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void change_wifi_icon(void *obj, int32_t v) { | ||||||
|  |   switch (v) { | ||||||
|  |     case 0: | ||||||
|  |       lv_label_set_text(obj, APP_WIFI_WEAK_SYMBOL); | ||||||
|  |       break; | ||||||
|  |     case 1: | ||||||
|  |       lv_label_set_text(obj, APP_WIFI_FAIR_SYMBOL); | ||||||
|  |       break; | ||||||
|  |     case 2: | ||||||
|  |       lv_label_set_text(obj, APP_WIFI_GOOD_SYMBOL); | ||||||
|  |       break; | ||||||
|  |     default: | ||||||
|  |       ESP_LOGW(GUI_TAG, "Unknown wifi strength: %ld", v); | ||||||
|  |       break; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void gui_set_wifi_connecting() { | ||||||
|  |   lv_obj_clear_flag(wifi_label, LV_OBJ_FLAG_HIDDEN); | ||||||
|  |  | ||||||
|  |   lv_anim_init(&wifi_animate); | ||||||
|  |   lv_anim_set_exec_cb(&wifi_animate, change_wifi_icon); | ||||||
|  |   lv_anim_set_time(&wifi_animate, 300); | ||||||
|  |   lv_anim_set_repeat_delay(&wifi_animate, 300); | ||||||
|  |   lv_anim_set_values(&wifi_animate, 0, 2); | ||||||
|  |   lv_anim_set_var(&wifi_animate, wifi_label); | ||||||
|  |   lv_anim_set_repeat_count(&wifi_animate, LV_ANIM_REPEAT_INFINITE); | ||||||
|  |   lv_anim_start(&wifi_animate); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void gui_set_wifi_connected() { | ||||||
|  |   lv_anim_del(wifi_label, NULL); | ||||||
|  |   vTaskDelay(300 / portTICK_PERIOD_MS); | ||||||
|  |   lv_obj_clear_flag(wifi_label, LV_OBJ_FLAG_HIDDEN); | ||||||
|  |   lv_label_set_text(wifi_label, APP_WIFI_GOOD_SYMBOL); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void gui_set_wifi_disconnected() { | ||||||
|  |   lv_anim_del(&wifi_label, NULL); | ||||||
|  |   vTaskDelay(300 / portTICK_PERIOD_MS); | ||||||
|  |   lv_obj_clear_flag(wifi_label, LV_OBJ_FLAG_HIDDEN); | ||||||
|  |   lv_label_set_text(wifi_label, APP_WIFI_WEAK_SYMBOL); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void gui_set_server_connecting() { | ||||||
|  |   set_obj_blink_animate(desktop_label, &desktop_animate); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void gui_set_server_connected() { | ||||||
|  |   lv_anim_del(desktop_label, NULL); | ||||||
|  |   vTaskDelay(300 / portTICK_PERIOD_MS); | ||||||
|  |   lv_obj_clear_flag(desktop_label, LV_OBJ_FLAG_HIDDEN); | ||||||
|  |   lv_label_set_text(desktop_label, APP_CONNECTED_SYMBOL); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void gui_set_server_disconnected() { | ||||||
|  |   lv_anim_del(desktop_label, NULL); | ||||||
|  |   vTaskDelay(300 / portTICK_PERIOD_MS); | ||||||
|  |   lv_obj_clear_flag(desktop_label, LV_OBJ_FLAG_HIDDEN); | ||||||
|  |   lv_label_set_text(desktop_label, APP_DISCONNECTED_SYMBOL); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void gui_bar_value_update_cb(lv_event_t *e) { | ||||||
|  |   lv_obj_draw_part_dsc_t *dsc = lv_event_get_param(e); | ||||||
|  |   if (dsc->part != LV_PART_INDICATOR) return; | ||||||
|  |  | ||||||
|  |   lv_obj_t *obj = lv_event_get_target(e); | ||||||
|  |  | ||||||
|  |   lv_draw_label_dsc_t label_dsc; | ||||||
|  |   lv_draw_label_dsc_init(&label_dsc); | ||||||
|  |   label_dsc.font = &lv_font_montserrat_10; | ||||||
|  |  | ||||||
|  |   char buf[8]; | ||||||
|  |   lv_snprintf(buf, sizeof(buf), "%ld", lv_bar_get_value(obj)); | ||||||
|  |  | ||||||
|  |   lv_point_t txt_size; | ||||||
|  |   lv_txt_get_size(&txt_size, buf, label_dsc.font, label_dsc.letter_space, | ||||||
|  |                   label_dsc.line_space, LV_COORD_MAX, label_dsc.flag); | ||||||
|  |  | ||||||
|  |   lv_coord_t txt_x; | ||||||
|  |   /*If the indicator is long enough put the text inside on the right*/ | ||||||
|  |   if (lv_area_get_width(dsc->draw_area) > txt_size.x + 20) { | ||||||
|  |     txt_x = dsc->draw_area->x2 - 8 - txt_size.x + 1; | ||||||
|  |     lv_obj_set_style_text_color(value_setting_value_label, lv_color_white(), | ||||||
|  |                                 LV_PART_MAIN); | ||||||
|  |     label_dsc.color = lv_color_white(); | ||||||
|  |   } | ||||||
|  |   /*If the indicator is still short put the text out of it on the right*/ | ||||||
|  |   else { | ||||||
|  |     txt_x = dsc->draw_area->x2 - 8 + txt_size.x - 1; | ||||||
|  |     lv_obj_set_style_text_color(value_setting_value_label, lv_color_black(), | ||||||
|  |                                 LV_PART_MAIN); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   lv_obj_align(value_setting_value_label, LV_ALIGN_LEFT_MID, txt_x, 0); | ||||||
|  |   lv_label_set_text(value_setting_value_label, buf); | ||||||
|  |   lv_obj_set_width(value_setting_value_label, txt_size.x); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void gui_create_value_setting_panel() { | ||||||
|  |   if (value_setting_panel != NULL) { | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   value_setting_panel = lv_obj_create(scr); | ||||||
|  |   lv_obj_set_size(value_setting_panel, 128, 40); | ||||||
|  |   lv_obj_align(value_setting_panel, LV_ALIGN_BOTTOM_MID, 0, 0); | ||||||
|  |   lv_obj_set_style_border_width(value_setting_panel, 1, LV_PART_MAIN); | ||||||
|  |   lv_obj_set_style_border_color(value_setting_panel, lv_color_black(), | ||||||
|  |                                 LV_PART_MAIN); | ||||||
|  |   lv_obj_set_style_radius(value_setting_panel, 5, LV_PART_MAIN); | ||||||
|  |   lv_obj_set_style_pad_all(value_setting_panel, 2, LV_PART_MAIN); | ||||||
|  |  | ||||||
|  |   value_setting_label = lv_label_create(value_setting_panel); | ||||||
|  |   lv_obj_align(value_setting_label, LV_ALIGN_BOTTOM_LEFT, 0, 0); | ||||||
|  |  | ||||||
|  |   value_setting_bar = lv_bar_create(value_setting_panel); | ||||||
|  |   lv_obj_set_size(value_setting_bar, 120, 12); | ||||||
|  |   lv_obj_align(value_setting_bar, LV_ALIGN_TOP_MID, 0, 0); | ||||||
|  |   lv_bar_set_range(value_setting_bar, 0, 100); | ||||||
|  |   lv_bar_set_value(value_setting_bar, 50, LV_ANIM_ON); | ||||||
|  |   lv_obj_set_style_bg_color(value_setting_bar, lv_color_white(), LV_PART_MAIN); | ||||||
|  |   lv_obj_set_style_border_color(value_setting_bar, lv_color_black(), | ||||||
|  |                                 LV_PART_MAIN); | ||||||
|  |   lv_obj_set_style_border_width(value_setting_bar, 1, LV_PART_MAIN); | ||||||
|  |   lv_obj_set_style_radius(value_setting_bar, 5, LV_PART_MAIN); | ||||||
|  |   lv_obj_set_style_pad_hor(value_setting_bar, 0, LV_PART_MAIN); | ||||||
|  |   lv_obj_set_style_pad_ver(value_setting_bar, 2, LV_PART_MAIN); | ||||||
|  |   lv_obj_set_style_bg_color(value_setting_bar, lv_color_black(), | ||||||
|  |                             LV_PART_INDICATOR); | ||||||
|  |   lv_obj_add_event_cb(value_setting_bar, gui_bar_value_update_cb, | ||||||
|  |                       LV_EVENT_DRAW_PART_END, NULL); | ||||||
|  |  | ||||||
|  |   value_setting_value_label = lv_label_create(value_setting_bar); | ||||||
|  |   lv_obj_align(value_setting_value_label, LV_ALIGN_CENTER, 0, 0); | ||||||
|  |   lv_obj_set_style_text_font(value_setting_value_label, &lv_font_montserrat_10, | ||||||
|  |                              LV_PART_MAIN); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void gui_change_strip_level(int32_t target_value) { | ||||||
|  |   gui_create_value_setting_panel(); | ||||||
|  |   lv_label_set_text(value_setting_label, "Strip Level"); | ||||||
|  |   lv_bar_set_range(value_setting_bar, 0, 255); | ||||||
|  |   lv_bar_set_value(value_setting_bar, target_value, LV_ANIM_ON); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void lv_example_bar_6(lv_obj_t *src) { | ||||||
|  |   static lv_style_t style_bar; | ||||||
|  |   lv_style_init(&style_bar); | ||||||
|  |  | ||||||
|  |   lv_style_set_bg_color(&style_bar, lv_color_white()); | ||||||
|  |   lv_style_set_border_width(&style_bar, 1); | ||||||
|  |   lv_style_set_border_color(&style_bar, lv_color_black()); | ||||||
|  |   lv_style_set_pad_hor(&style_bar, 4); | ||||||
|  |   lv_style_set_pad_ver(&style_bar, 2); | ||||||
|  |  | ||||||
|  |   static lv_style_t style_indic; | ||||||
|  |   lv_style_init(&style_indic); | ||||||
|  |  | ||||||
|  |   lv_style_set_bg_color(&style_indic, lv_color_black()); | ||||||
|  |  | ||||||
|  |   lv_obj_t *bar = lv_bar_create(src); | ||||||
|  |   lv_obj_set_size(bar, 100, 10); | ||||||
|  |   lv_obj_center(bar); | ||||||
|  |   lv_obj_add_style(bar, &style_bar, LV_PART_MAIN); | ||||||
|  |   lv_obj_add_style(bar, &style_indic, LV_PART_INDICATOR); | ||||||
|  |   lv_bar_set_range(bar, 0, 100); | ||||||
|  |   lv_bar_set_value(bar, 0, LV_ANIM_ON); | ||||||
|  |  | ||||||
|  |   lv_anim_t a; | ||||||
|  |   lv_anim_init(&a); | ||||||
|  |   lv_anim_set_exec_cb(&a, set_value); | ||||||
|  |   lv_anim_set_time(&a, 3000); | ||||||
|  |   lv_anim_set_playback_time(&a, 3000); | ||||||
|  |   lv_anim_set_var(&a, bar); | ||||||
|  |   lv_anim_set_values(&a, 0, 50); | ||||||
|  |   lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE); | ||||||
|  |   lv_anim_start(&a); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void gui_status_bar_create(lv_obj_t *scr) { | ||||||
|  |   // wifi icon | ||||||
|  |   wifi_label = lv_label_create(scr); | ||||||
|  |   lv_label_set_long_mode(wifi_label, LV_LABEL_LONG_SCROLL_CIRCULAR); | ||||||
|  |   lv_label_set_text(wifi_label, APP_WIFI_GOOD_SYMBOL); | ||||||
|  |   lv_obj_set_width(wifi_label, 10); | ||||||
|  |   lv_obj_align(wifi_label, LV_ALIGN_OUT_TOP_LEFT, 0, 0); | ||||||
|  |   lv_obj_set_style_text_color(wifi_label, lv_color_black(), LV_PART_MAIN); | ||||||
|  |   lv_obj_set_style_text_font(wifi_label, &app_icon_8, LV_PART_MAIN); | ||||||
|  |   lv_obj_add_flag(wifi_label, LV_OBJ_FLAG_HIDDEN); | ||||||
|  |  | ||||||
|  |   // timer icon | ||||||
|  |   timer_label = lv_label_create(scr); | ||||||
|  |   lv_label_set_long_mode(timer_label, LV_LABEL_LONG_SCROLL_CIRCULAR); | ||||||
|  |   lv_label_set_text(timer_label, APP_TIMER_SYMBOL); | ||||||
|  |   lv_obj_set_width(timer_label, 10); | ||||||
|  |   lv_obj_align(timer_label, LV_ALIGN_OUT_TOP_LEFT, 12, 0); | ||||||
|  |   lv_obj_set_style_text_color(timer_label, lv_color_black(), LV_PART_MAIN); | ||||||
|  |   lv_obj_set_style_text_font(timer_label, &app_icon_8, LV_PART_MAIN); | ||||||
|  |   lv_obj_add_flag(timer_label, LV_OBJ_FLAG_HIDDEN); | ||||||
|  |  | ||||||
|  |   // desktop icon | ||||||
|  |   desktop_label = lv_label_create(scr); | ||||||
|  |   lv_label_set_long_mode(desktop_label, LV_LABEL_LONG_SCROLL_CIRCULAR); | ||||||
|  |   lv_label_set_text(desktop_label, APP_CONNECTED_SYMBOL); | ||||||
|  |   lv_obj_set_width(desktop_label, 10); | ||||||
|  |   lv_obj_align(desktop_label, LV_ALIGN_OUT_TOP_LEFT, 24, 0); | ||||||
|  |   lv_obj_set_style_text_color(desktop_label, lv_color_black(), LV_PART_MAIN); | ||||||
|  |   lv_obj_set_style_text_font(desktop_label, &app_icon_8, LV_PART_MAIN); | ||||||
|  |   lv_obj_add_flag(desktop_label, LV_OBJ_FLAG_HIDDEN); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void example_lvgl_demo_ui(lv_disp_t *disp) { | ||||||
|  |   scr = lv_disp_get_scr_act(disp); | ||||||
|  |  | ||||||
|  |   lv_obj_t *label = lv_label_create(scr); | ||||||
|  |   lv_label_set_long_mode(label, | ||||||
|  |                          LV_LABEL_LONG_SCROLL_CIRCULAR); /* Circular scroll | ||||||
|  |                                                           */ | ||||||
|  |   lv_label_set_text(label, "Hello Espressif, Hello LVGL."); | ||||||
|  |   lv_obj_set_width(label, 120); | ||||||
|  |   lv_obj_align(label, LV_ALIGN_BOTTOM_RIGHT, 0, 0); | ||||||
|  |  | ||||||
|  |   lv_example_bar_6(scr); | ||||||
|  |  | ||||||
|  |   gui_status_bar_create(scr); | ||||||
|  |  | ||||||
|  |   gui_create_value_setting_panel(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void gui_tick(void *pvParameters) { | ||||||
|  |   while (1) { | ||||||
|  |     // raise the task priority of LVGL and/or reduce the handler period can | ||||||
|  |     // improve the performance | ||||||
|  |     vTaskDelay(pdMS_TO_TICKS(10)); | ||||||
|  |     // The task running lv_timer_handler should have lower priority than that | ||||||
|  |     // running `lv_tick_inc` | ||||||
|  |     lv_timer_handler(); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void gui_main(void) { | ||||||
|  |   static lv_disp_draw_buf_t | ||||||
|  |       disp_buf;  // contains internal graphic buffer(s) called draw buffer(s) | ||||||
|  |   static lv_disp_drv_t disp_drv;  // contains callback functions | ||||||
|  |  | ||||||
|  |   ESP_LOGI(GUI_TAG, "Initialize LVGL library"); | ||||||
|  |   lv_init(); | ||||||
|  |   // alloc draw buffers used by LVGL | ||||||
|  |   // it's recommended to choose the size of the draw buffer(s) to be at least | ||||||
|  |   // 1/10 screen sized | ||||||
|  |   lv_color_t *buf1 = malloc(EXAMPLE_LCD_H_RES * 20 * sizeof(lv_color_t)); | ||||||
|  |   assert(buf1); | ||||||
|  |   lv_color_t *buf2 = malloc(EXAMPLE_LCD_H_RES * 20 * sizeof(lv_color_t)); | ||||||
|  |   assert(buf2); | ||||||
|  |   // initialize LVGL draw buffers | ||||||
|  |   lv_disp_draw_buf_init(&disp_buf, buf1, buf2, EXAMPLE_LCD_H_RES * 20); | ||||||
|  |  | ||||||
|  |   ESP_LOGI(GUI_TAG, "Register display driver to LVGL"); | ||||||
|  |   lv_disp_drv_init(&disp_drv); | ||||||
|  |   disp_drv.hor_res = EXAMPLE_LCD_H_RES; | ||||||
|  |   disp_drv.ver_res = EXAMPLE_LCD_V_RES; | ||||||
|  |   disp_drv.flush_cb = example_lvgl_flush_cb; | ||||||
|  |   disp_drv.draw_buf = &disp_buf; | ||||||
|  |   disp_drv.rounder_cb = example_lvgl_rounder; | ||||||
|  |   disp_drv.set_px_cb = example_lvgl_set_px_cb; | ||||||
|  |   lv_disp_t *disp = lv_disp_drv_register(&disp_drv); | ||||||
|  |  | ||||||
|  |   ESP_LOGI(GUI_TAG, "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)); | ||||||
|  |  | ||||||
|  |   ESP_LOGI(GUI_TAG, "Display LVGL Scroll Text"); | ||||||
|  |   example_lvgl_demo_ui(disp); | ||||||
|  |  | ||||||
|  |   xTaskCreate(gui_tick, "gui_tick", 4096, (void *)NULL, 5, NULL); | ||||||
|  | } | ||||||
| @@ -1,5 +1,6 @@ | |||||||
| ## IDF Component Manager Manifest File | ## IDF Component Manager Manifest File | ||||||
| dependencies: | dependencies: | ||||||
|  |   lvgl/lvgl: "^8.3.6~1" | ||||||
|   espressif/mdns: "^1.0.9" |   espressif/mdns: "^1.0.9" | ||||||
|   ## Required IDF version |   ## Required IDF version | ||||||
|   idf: |   idf: | ||||||
|   | |||||||
							
								
								
									
										19
									
								
								main/lvgl_demo_ui.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										19
									
								
								main/lvgl_demo_ui.c
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,19 @@ | |||||||
|  | /* | ||||||
|  |  * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: CC0-1.0 | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include "lvgl.h" | ||||||
|  |  | ||||||
|  | void example_lvgl_demo_ui(lv_disp_t *disp) { | ||||||
|  |   lv_obj_t *scr = lv_disp_get_scr_act(disp); | ||||||
|  |  | ||||||
|  |   lv_obj_t *label = lv_label_create(scr); | ||||||
|  |   lv_label_set_long_mode(label, | ||||||
|  |                          LV_LABEL_LONG_SCROLL_CIRCULAR); /* Circular scroll | ||||||
|  |                                                           */ | ||||||
|  |   lv_label_set_text(label, "Hello Espressif, Hello LVGL."); | ||||||
|  |   lv_obj_set_width(label, 120); | ||||||
|  |   lv_obj_align(label, LV_ALIGN_TOP_MID, 0, 0); | ||||||
|  | } | ||||||
							
								
								
									
										47
									
								
								main/main.c
									
									
									
									
									
								
							
							
						
						
									
										47
									
								
								main/main.c
									
									
									
									
									
								
							| @@ -1,17 +1,18 @@ | |||||||
| #include "apds_9960.c" | // #include "apds_9960.c" | ||||||
| #include "app_nvs.c" | #include "app_nvs.c" | ||||||
|  | #include "ch1116.c" | ||||||
| #include "ci_03t.c" | #include "ci_03t.c" | ||||||
| #include "embedded_display.c" |  | ||||||
| #include "esp_log.h" | #include "esp_log.h" | ||||||
| #include "freertos/FreeRTOS.h" | #include "freertos/FreeRTOS.h" | ||||||
| #include "freertos/task.h" | #include "freertos/task.h" | ||||||
|  | #include "gui.c" | ||||||
| #include "i2c.c" | #include "i2c.c" | ||||||
| #include "light.c" | #include "light.c" | ||||||
| #include "mqtt.c" | // #include "mqtt.c" | ||||||
| #include "pca9555.c" | // #include "pca9555.c" | ||||||
| #include "sdkconfig.h" | #include "sdkconfig.h" | ||||||
| #include "service_discovery.c" | #include "service_discovery.c" | ||||||
| #include "temperature.c" | // #include "temperature.c" | ||||||
| #include "udp_server.c" | #include "udp_server.c" | ||||||
| #include "ui_input.c" | #include "ui_input.c" | ||||||
| #include "wifi.c" | #include "wifi.c" | ||||||
| @@ -26,33 +27,41 @@ void app_main(void) { | |||||||
|   init_i2c(); |   init_i2c(); | ||||||
|   i2c_check_slaves(); |   i2c_check_slaves(); | ||||||
|  |  | ||||||
|   init_display(); |   ch1116_main(); | ||||||
|   display_print8_str(0, 0, "Ambient Light"); |   gui_main(); | ||||||
|  |  | ||||||
|   ci_03t_init(); |   gui_set_wifi_connecting(); | ||||||
|   apds_9960_init(); |   gui_set_server_connecting(); | ||||||
|   apds_9960_auto_fetch(); |  | ||||||
|   auto_fetch_temperature(); |   // display_print8_str(0, 0, "Ambient Light"); | ||||||
|  |  | ||||||
|  |   // ci_03t_init(); | ||||||
|  |   // apds_9960_init(); | ||||||
|  |   // apds_9960_auto_fetch(); | ||||||
|  |   // auto_fetch_temperature(); | ||||||
|   pca9555_init(); |   pca9555_init(); | ||||||
|   ui_input_init(); |   ui_input_init(); | ||||||
|   xTaskCreate(mqtt_publish_ui_input, "mqtt_publish_ui_input", 2048, NULL, 10, |   // xTaskCreate(mqtt_publish_ui_input, "mqtt_publish_ui_input", 2048, NULL, 10, | ||||||
|               NULL); |   //             NULL); | ||||||
|   vTaskDelay(pdMS_TO_TICKS(10)); |   // vTaskDelay(pdMS_TO_TICKS(10)); | ||||||
|   light_play(light_mode_connection_wifi); |   light_play(light_mode_connection_wifi); | ||||||
|   if (connect_wifi()) { |   if (connect_wifi()) { | ||||||
|  |     gui_set_wifi_connected(); | ||||||
|     light_play(light_mode_idle); |     light_play(light_mode_idle); | ||||||
|  |   } else { | ||||||
|  |     gui_set_wifi_disconnected(); | ||||||
|   } |   } | ||||||
|   udp_server_init(); |   udp_server_init(); | ||||||
|   service_discovery_init(); |   service_discovery_init(); | ||||||
|   vTaskDelay(pdMS_TO_TICKS(1000)); |   // vTaskDelay(pdMS_TO_TICKS(1000)); | ||||||
|   mqtt_app_start(); |   // mqtt_app_start(); | ||||||
|   // if (waiting_for_mqtt_connected()) { |   // if (waiting_for_mqtt_connected()) { | ||||||
|   //   light_play(light_mode_mqtt_connected); |   //   light_play(light_mode_mqtt_connected); | ||||||
|   // } |   // } | ||||||
|   // if (waiting_for_desktop_online()) { |   // if (waiting_for_desktop_online()) { | ||||||
|   //   light_play(light_mode_desktop_online); |   //   light_play(light_mode_desktop_online); | ||||||
|   // } |   // } | ||||||
|   while (waiting_and_get_colors()) { |   // while (waiting_and_get_colors()) { | ||||||
|     light_play_colors(NUMBER_OF_LEDS * 3, mqtt_colors_buffer); |   //   light_play_colors(NUMBER_OF_LEDS * 3, mqtt_colors_buffer); | ||||||
|   } |   // } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -4,7 +4,6 @@ | |||||||
|  |  | ||||||
| #include "cJSON.h" | #include "cJSON.h" | ||||||
| #include "ci_03t.c" | #include "ci_03t.c" | ||||||
| #include "embedded_display.c" |  | ||||||
| #include "esp_bit_defs.h" | #include "esp_bit_defs.h" | ||||||
| #include "esp_event.h" | #include "esp_event.h" | ||||||
| #include "esp_log.h" | #include "esp_log.h" | ||||||
|   | |||||||
| @@ -3,7 +3,6 @@ | |||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
|  |  | ||||||
| #include "driver/i2c.h" | #include "driver/i2c.h" | ||||||
| #include "embedded_display.c" |  | ||||||
| #include "esp_log.h" | #include "esp_log.h" | ||||||
| #include "i2c.c" | #include "i2c.c" | ||||||
|  |  | ||||||
| @@ -79,19 +78,15 @@ void pca9555_fetch(void* arg) { | |||||||
|   esp_err_t error; |   esp_err_t error; | ||||||
|   uint8_t buff; |   uint8_t buff; | ||||||
|   char disp_str[17]; |   char disp_str[17]; | ||||||
|   display_fill_rect(0, 6, 128, 8, 0x00); |  | ||||||
|   for (;;) { |   for (;;) { | ||||||
|     error = pca9555_read_one_input(PCA95555_CMD_INPUT_PORT_1, &buff); |     error = pca9555_read_one_input(PCA95555_CMD_INPUT_PORT_1, &buff); | ||||||
|     if (error != ESP_OK) { |     if (error != ESP_OK) { | ||||||
|       ESP_LOGW(PCA_9555_TAG, "read failed. %x", error); |       ESP_LOGW(PCA_9555_TAG, "read failed. %x", error); | ||||||
|     } else { |     } else { | ||||||
|       sprintf(disp_str, "IO0: 0x%2x  ", buff); |  | ||||||
|       display_print8_str(8, 6, disp_str); |  | ||||||
|       ESP_LOGD(PCA_9555_TAG, "IO0: 0x%2x", buff); |       ESP_LOGD(PCA_9555_TAG, "IO0: 0x%2x", buff); | ||||||
|     } |     } | ||||||
|     vTaskDelay(pdMS_TO_TICKS(10)); |     vTaskDelay(pdMS_TO_TICKS(10)); | ||||||
|   } |   } | ||||||
|   display_fill_rect(0, 6, 128, 8, 0x00); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void pca9555_auto_fetch() { | void pca9555_auto_fetch() { | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ | |||||||
| #include "esp_wifi.h" | #include "esp_wifi.h" | ||||||
| #include "freertos/FreeRTOS.h" | #include "freertos/FreeRTOS.h" | ||||||
| #include "freertos/task.h" | #include "freertos/task.h" | ||||||
|  | #include "gui.c" | ||||||
| #include "light.c" | #include "light.c" | ||||||
| #include "lwip/err.h" | #include "lwip/err.h" | ||||||
| #include "lwip/sockets.h" | #include "lwip/sockets.h" | ||||||
| @@ -20,6 +21,9 @@ | |||||||
|  |  | ||||||
| static const char *UDP_SERVER_TAG = "UDP_SERVER"; | static const char *UDP_SERVER_TAG = "UDP_SERVER"; | ||||||
|  |  | ||||||
|  | static bool desktop_connected = false; | ||||||
|  | static uint64_t last_desktop_ping_at = 0; | ||||||
|  |  | ||||||
| static void udp_server_task(void *pvParameters) { | static void udp_server_task(void *pvParameters) { | ||||||
|   char rx_buffer[1024]; |   char rx_buffer[1024]; | ||||||
|   char addr_str[128]; |   char addr_str[128]; | ||||||
| @@ -84,6 +88,7 @@ static void udp_server_task(void *pvParameters) { | |||||||
|  |  | ||||||
|           switch (rx_buffer[0]) { |           switch (rx_buffer[0]) { | ||||||
|             case 1: |             case 1: | ||||||
|  |               last_desktop_ping_at = esp_timer_get_time(); | ||||||
|               sendto(sock, rx_buffer, 1, 0, (struct sockaddr *)&source_addr, |               sendto(sock, rx_buffer, 1, 0, (struct sockaddr *)&source_addr, | ||||||
|                      sizeof(source_addr)); |                      sizeof(source_addr)); | ||||||
|               break; |               break; | ||||||
| @@ -127,8 +132,28 @@ static void udp_server_task(void *pvParameters) { | |||||||
|   vTaskDelete(NULL); |   vTaskDelete(NULL); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static void change_desktop_connection_status(bool connected) { | ||||||
|  |   desktop_connected = connected; | ||||||
|  |   if (connected) { | ||||||
|  |     gui_set_server_connected(); | ||||||
|  |   } else { | ||||||
|  |     gui_set_server_disconnected(); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void desktop_online_check_task(void *pvParameters) { | ||||||
|  |   while (1) { | ||||||
|  |     if (esp_timer_get_time() - last_desktop_ping_at > 5000000) {  // 2 seconds | ||||||
|  |       change_desktop_connection_status(false); | ||||||
|  |     } else { | ||||||
|  |       change_desktop_connection_status(true); | ||||||
|  |     } | ||||||
|  |     vTaskDelay(1000 / portTICK_PERIOD_MS); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
| void udp_server_init(void) { | void udp_server_init(void) { | ||||||
|   ESP_ERROR_CHECK(nvs_flash_init()); |  | ||||||
|   ESP_ERROR_CHECK(esp_netif_init()); |  | ||||||
|   xTaskCreate(udp_server_task, "udp_server", 4096, (void *)AF_INET, 5, NULL); |   xTaskCreate(udp_server_task, "udp_server", 4096, (void *)AF_INET, 5, NULL); | ||||||
|  |   xTaskCreate(desktop_online_check_task, "desktop_online_check", 4096, NULL, 10, | ||||||
|  |               NULL); | ||||||
| } | } | ||||||
| @@ -6,10 +6,10 @@ | |||||||
|  |  | ||||||
| #include "config_key.h" | #include "config_key.h" | ||||||
| #include "driver/gpio.h" | #include "driver/gpio.h" | ||||||
| #include "embedded_display.c" |  | ||||||
| #include "freertos/FreeRTOS.h" | #include "freertos/FreeRTOS.h" | ||||||
| #include "freertos/queue.h" | #include "freertos/queue.h" | ||||||
| #include "freertos/task.h" | #include "freertos/task.h" | ||||||
|  | #include "gui.c" | ||||||
| #include "light.c" | #include "light.c" | ||||||
| #include "pca9555.c" | #include "pca9555.c" | ||||||
|  |  | ||||||
| @@ -72,7 +72,6 @@ static void ui_input_update_embedded_display(void *arg) { | |||||||
|           sprintf(changing_str, "CVol: % 3d", input.value); |           sprintf(changing_str, "CVol: % 3d", input.value); | ||||||
|           break; |           break; | ||||||
|         case ui_input_key_display_ambient_lighting_level: |         case ui_input_key_display_ambient_lighting_level: | ||||||
|           sprintf(changing_str, "ALLv: % 3d", display_ambient_lighting_level); |  | ||||||
|           break; |           break; | ||||||
|         case ui_input_key_display_ambient_lighting_mode: |         case ui_input_key_display_ambient_lighting_mode: | ||||||
|           sprintf(changing_str, "ALMd: % 3d", input.value); |           sprintf(changing_str, "ALMd: % 3d", input.value); | ||||||
| @@ -88,8 +87,6 @@ static void ui_input_update_embedded_display(void *arg) { | |||||||
|           strcpy(changing_str, "NC"); |           strcpy(changing_str, "NC"); | ||||||
|           break; |           break; | ||||||
|       } |       } | ||||||
|       display_fill_rect(0, 6, 128, 8, 0); |  | ||||||
|       display_print8_str(8, 6, changing_str); |  | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @@ -148,6 +145,8 @@ static void encoder_value_change(encoder_state_t *state) { | |||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   ESP_LOGI(UI_INPUT_TAG, "key: %d, delta: %d", state->key, delta); | ||||||
|  |  | ||||||
|   s_ui_input_t event = {.value = delta}; |   s_ui_input_t event = {.value = delta}; | ||||||
|   if (state->key == ui_input_raw_key_encoder_0) { |   if (state->key == ui_input_raw_key_encoder_0) { | ||||||
|     if (state->value & 1) { |     if (state->value & 1) { | ||||||
| @@ -159,6 +158,7 @@ static void encoder_value_change(encoder_state_t *state) { | |||||||
|     if (state->value & 1) { |     if (state->value & 1) { | ||||||
|       event.key = ui_input_key_display_ambient_lighting_level; |       event.key = ui_input_key_display_ambient_lighting_level; | ||||||
|       led_strip_set_brightness(display_ambient_lighting_level + delta); |       led_strip_set_brightness(display_ambient_lighting_level + delta); | ||||||
|  |       gui_change_strip_level(display_ambient_lighting_level); | ||||||
|     } else { |     } else { | ||||||
|       event.key = ui_input_key_display_1_brightness; |       event.key = ui_input_key_display_1_brightness; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -151,14 +151,7 @@ bool wifi_init_sta(void) { | |||||||
| } | } | ||||||
|  |  | ||||||
| bool connect_wifi(void) { | bool connect_wifi(void) { | ||||||
|   // Initialize NVS |   //! Should init NVS before wifi init | ||||||
|   esp_err_t ret = nvs_flash_init(); |  | ||||||
|   if (ret == ESP_ERR_NVS_NO_FREE_PAGES || |  | ||||||
|       ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { |  | ||||||
|     ESP_ERROR_CHECK(nvs_flash_erase()); |  | ||||||
|     ret = nvs_flash_init(); |  | ||||||
|   } |  | ||||||
|   ESP_ERROR_CHECK(ret); |  | ||||||
|  |  | ||||||
|   ESP_LOGI(WIFI_TAG, "ESP_WIFI_MODE_STA"); |   ESP_LOGI(WIFI_TAG, "ESP_WIFI_MODE_STA"); | ||||||
|   return wifi_init_sta(); |   return wifi_init_sta(); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user