/* 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" /********************* * DEFINES *********************/ /********************** * STATIC PROTOTYPES **********************/ static void IRAM_ATTR lv_tick_task(void *arg); /********************** * 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() { 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(); while (1) { vTaskDelay(1); //Try to lock the semaphore, if success, call lvgl stuff if (xSemaphoreTake(xGuiSemaphore, (TickType_t)10) == pdTRUE) { lv_task_handler(); xSemaphoreGive(xGuiSemaphore); } } //A task should NEVER return vTaskDelete(NULL); }