/* * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: CC0-1.0 */ #include #include #include #include "sdkconfig.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_chip_info.h" #include "esp_flash.h" #include "esp_system.h" // #include "common/constants.h" #include "common/queue_defs.h" #include "io/nvs_handler.h" #include "info/info.h" #include "display/display.h" #include "touch/touch.h" #include extern "C" void app_main(void); void init_queues( QueueHandle_t& touch_queue, EventGroupHandle_t& system_event_group, EventGroupHandle_t& system_lifecycle_event_group ); void app_main(void) { display_chip_info(); try { QueueHandle_t touch_event_queue = NULL; EventGroupHandle_t system_event_group = NULL, system_lifecycle_event_group = NULL; init_queues(touch_event_queue, system_event_group, system_lifecycle_event_group); if (touch_event_queue == NULL || system_event_group == NULL || system_lifecycle_event_group == NULL) { throw std::runtime_error("Failed to create one or more queues/event groups"); } printf("Queues initialized.\n"); SemaphoreHandle_t lvgl_mutex = xSemaphoreCreateMutex(); if (lvgl_mutex == NULL) { throw std::runtime_error("Failed to create LVGL mutex"); } // KVStorageHandler* kv_storage_handler = new NVSStorageHandler( "storage" ); DisplayHandler* display_handler = new EInkDisplayHandler(touch_event_queue, lvgl_mutex); TouchHandler* touch_handler = new EInkTouchHandler(touch_event_queue); // kv_storage_handler->init(system_event_group); display_handler->init(system_event_group); touch_handler->init(system_event_group); // // LVGL tick timer auto lvgl_tick_timer_callback = [](TimerHandle_t xTimer) { lv_tick_inc(5); }; TimerHandle_t lvgl_tick_timer = xTimerCreate( "lvgl_tick_timer", pdMS_TO_TICKS(5), pdTRUE, NULL, lvgl_tick_timer_callback ); if (lvgl_tick_timer == NULL) { throw std::runtime_error("Failed to create LVGL tick timer"); } xTimerStart(lvgl_tick_timer, 0); // printf("Waiting for system to be ready...\n"); xEventGroupWaitBits( system_event_group, DISPLAY_READY_BIT | TOUCH_CALIBRATED_BIT | STORAGE_READY_BIT, // do not clear on exit, require explicit reset pdFALSE, pdTRUE, portMAX_DELAY ); printf("System is ready. Starting main application...\n"); // starting event loops display_handler->start_event_loop(); touch_handler->start_event_loop(); // wait for shutdown signal EventBits_t bits = xEventGroupWaitBits( system_lifecycle_event_group, SYSTEM_SHUTDOWN_BIT | SYSTEM_RESTART_BIT, // do not clear on exit, require explicit reset pdFALSE, pdFALSE, portMAX_DELAY ); printf("Shutdown signal received. Cleaning up...\n"); // cleanup shutdown_display_handlerFunc shutdown_display_handler = display_handler->get_shutdown_display_handler(); restart_display_handlerFunc restart_display_handler = display_handler->get_restart_display_handler(); delete display_handler; delete touch_handler; vSemaphoreDelete(lvgl_mutex); vEventGroupDelete(system_event_group); vQueueDelete(touch_event_queue); printf("Cleanup complete.\n"); // handle shutdown or restart if (bits & SYSTEM_SHUTDOWN_BIT) { if (shutdown_display_handler != nullptr) { printf("Calling display shutdown handler...\n"); shutdown_display_handler(); } else { printf("No display shutdown handler to call.\n"); } printf("System is shutting down.\n"); fflush(stdout); // wait for start bit to be set again if future restart is desired, else expect manual power cycle EventBits_t bits = xEventGroupWaitBits( system_lifecycle_event_group, SYSTEM_START_BIT, pdFALSE, pdFALSE, portMAX_DELAY ); } else if (bits & SYSTEM_RESTART_BIT) { if (restart_display_handler != nullptr) { printf("Calling display restart handler...\n"); restart_display_handler(); } else { printf("No display restart handler to call.\n"); } printf("System is restarting.\n"); fflush(stdout); } else { printf("Unknown shutdown signal received. Restarting by default.\n"); fflush(stdout); } return esp_restart(); } catch (const std::exception& e) { printf("Exception occurred during initialization: %s\n", e.what()); printf("System will restart due to the error.\n"); for (int i = 5; i >= 0; --i) { printf("Restarting in %d seconds...\n", i); vTaskDelay(1000 / portTICK_PERIOD_MS); } printf("Restarting now.\n"); fflush(stdout); return esp_restart(); } printf("Reached end of app_main unexpectedly.\n"); printf("System will restart in 10 seconds...\n"); for (int i = 10; i >= 0; --i) { printf("Restarting in %d seconds...\n", i); vTaskDelay(1000 / portTICK_PERIOD_MS); } printf("Restarting now.\n"); fflush(stdout); return esp_restart(); } void init_queues( QueueHandle_t& touch_queue, EventGroupHandle_t& system_event_group, EventGroupHandle_t& system_lifecycle_event_group ) { // Implementation of queue initialization touch_queue = xQueueCreate(10, sizeof(touch_event_t)); system_event_group = xEventGroupCreate(); system_lifecycle_event_group = xEventGroupCreate(); }