/* LVGL Example project * * Basic project to test LVGL on ESP32 based projects. * * This example code is in the Public Domain (or CC0 licensed, at your option.) * * Unless required by applicable law or agreed to in writing, this * software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, either express or implied. */ #include #include #include #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_freertos_hooks.h" #include "freertos/semphr.h" #include "esp_system.h" #include "driver/gpio.h" /* Littlevgl specific */ #include "lvgl/lvgl.h" #include "lvgl_driver.h" //#include "lv_examples/lv_apps/demo/demo.h" //#include "lv_examples/lv_apps/sysmon/sysmon.h" //#include "../lvgl/lvgl.h" #include "lv_conf.h" #include "lvgl.h" #include "display.h" #include #include #include "esp_log.h" #include "esp_console.h" #include "argtable3/argtable3.h" #include "freertos/FreeRTOS.h" #include "freertos/event_groups.h" #include "esp_wifi.h" #include "esp_netif.h" #include "esp_event.h" #include "wifi.h" /********************* * DEFINES *********************/ static lv_obj_t* win; static lv_obj_t* table; extern esp_netif_t *sta_netif; static lv_obj_t* label_bottom; /********************** * STATIC PROTOTYPES **********************/ static void IRAM_ATTR lv_tick_task(void *arg); static lv_obj_t * status_create(void); static void fill_the_table(); /********************** * APPLICATION MAIN ********************** void app_main() { //If you want to use a task to create the graphic, you NEED to create a Pinned task //Otherwise there can be problem such as memory corruption and so on xTaskCreatePinnedToCore(guiTask, "gui", 4096*2, NULL, 0, NULL, 1); } **/ static void IRAM_ATTR lv_tick_task(void *arg) { (void) arg; lv_tick_inc(portTICK_RATE_MS); } //Creates a semaphore to handle concurrent call to lvgl stuff //If you wish to call *any* lvgl function from other threads/tasks //you should lock on the very same semaphore! SemaphoreHandle_t xGuiSemaphore; void guiTask(void* parameter) { struct ca_status buff = *(struct ca_status*)parameter; xGuiSemaphore = xSemaphoreCreateMutex(); lv_init(); lvgl_driver_init(); static lv_color_t buf1[DISP_BUF_SIZE]; static lv_color_t buf2[DISP_BUF_SIZE]; static lv_disp_buf_t disp_buf; lv_disp_buf_init(&disp_buf, buf1, buf2, DISP_BUF_SIZE); lv_disp_drv_t disp_drv; lv_disp_drv_init(&disp_drv); disp_drv.flush_cb = disp_driver_flush; disp_drv.buffer = &disp_buf; lv_disp_drv_register(&disp_drv); #if CONFIG_LVGL_TOUCH_CONTROLLER != TOUCH_CONTROLLER_NONE lv_indev_drv_t indev_drv; lv_indev_drv_init(&indev_drv); indev_drv.read_cb = touch_driver_read; indev_drv.type = LV_INDEV_TYPE_POINTER; lv_indev_drv_register(&indev_drv); #endif const esp_timer_create_args_t periodic_timer_args = { .callback = &lv_tick_task, /* name is optional, but may help identify the timer when debugging */ .name = "periodic_gui" }; esp_timer_handle_t periodic_timer; ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer)); //On ESP32 it's better to create a periodic task instead of esp_register_freertos_tick_hook ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, 10*1000)); //10ms (expressed as microseconds) //demo_create(); //sysmon_create(); status_create(); while (1) { vTaskDelay(10); //Try to lock the semaphore, if success, call lvgl stuff if (xSemaphoreTake(xGuiSemaphore, (TickType_t)10) == pdTRUE) { lv_task_handler(); xSemaphoreGive(xGuiSemaphore); fill_the_table(buff); } } //A task should NEVER return vTaskDelete(NULL); } lv_obj_t * status_create(void){ static lv_style_t style_bg; lv_style_copy(&style_bg,&lv_style_plain); style_bg.body.main_color = lv_color_make(211,211,211); win = lv_obj_create(lv_scr_act(),NULL); lv_obj_set_size(win,LV_HOR_RES,LV_VER_RES); lv_obj_set_style(win,&style_bg); static lv_style_t title; lv_style_copy(&title,&lv_style_transp); title.text.color = LV_COLOR_BLACK; lv_obj_t* label = lv_label_create(win,NULL); lv_obj_set_style(label,&title); lv_label_set_align(label,LV_LABEL_ALIGN_CENTER); lv_label_set_text(label,"Certificate Authority on ESP32"); label_bottom = lv_label_create(win,NULL); lv_obj_set_style(label_bottom,&title); lv_label_set_align(label_bottom,LV_LABEL_ALIGN_CENTER); lv_label_set_text(label_bottom,"Certificate Authority on ESP22222"); lv_obj_align(label_bottom, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); static lv_style_t style_cell1; lv_style_copy(&style_cell1, &lv_style_plain); style_cell1.body.border.width = 1; style_cell1.body.border.color = LV_COLOR_BLACK; style_cell1.body.main_color = LV_COLOR_SILVER; style_cell1.body.grad_color = LV_COLOR_SILVER; table = lv_table_create(win,NULL); lv_table_set_style(table,LV_TABLE_STYLE_CELL1,&style_cell1); lv_table_set_row_cnt(table,4); lv_table_set_col_cnt(table,2); lv_obj_align(table, NULL, LV_ALIGN_IN_LEFT_MID, 0, 0); lv_table_set_col_width(table,0,(LV_HOR_RES-5)/2); lv_table_set_col_width(table,1,(LV_HOR_RES-15)/2); lv_table_set_cell_value(table,0,0,"WIFI"); lv_table_set_cell_value(table,1,0,"Webserver"); lv_table_set_cell_value(table,2,0,"Certificates"); lv_table_set_cell_value(table,3,0,"Initialized"); return win; } void fill_the_table(struct ca_status buff){ // struct ca_status buff = *(struct ca_status*)parameter; esp_netif_ip_info_t ip_info; esp_netif_get_ip_info(sta_netif,&ip_info); char buffer[17]; esp_ip4addr_ntoa(&ip_info.ip,buffer,17); lv_label_set_text(label_bottom,buffer); //ESP_LOGI("IP ADRESA","%s",buffer); if (buff.wifi == true) { lv_table_set_cell_value(table,0,1,"YES"); }else { lv_table_set_cell_value(table,0,1,"OFF"); } if (buff.webserver == true) { lv_table_set_cell_value(table,1,1,"YES"); }else { lv_table_set_cell_value(table,1,1,"OFF"); } if (buff.init == true) { lv_table_set_cell_value(table,3,1,"YES"); }else { lv_table_set_cell_value(table,3,1,"NO"); lv_table_set_cell_value(table,2,1,"0"); } //printf("My IP: %s \n", buffer); //printf("My GW: " IPSTR "\n", IP2STR(&ip_info.gw)); //printf("My NETMASK: " IPSTR "\n", IP2STR(&ip_info.netmask)); //lv_table_set_cell_value(table,0,1,"OFF"); //lv_table_set_cell_value(table,1,1,"OFF"); //lv_table_set_cell_value(table,3,1,"NO"); }