#include #include #include #include #include #include #include "driver/gpio.h" #include "driver/i2c.h" #include "driver/sdspi_host.h" #include "driver/spi_common.h" #include "driver/spi_master.h" #include "driver_cache.hpp" #include "esp_freertos_hooks.h" #include "esp_heap_caps.h" #include "esp_intr_alloc.h" #include "esp_log.h" #include "freertos/portmacro.h" #include "freertos/projdefs.h" #include "hal/gpio_types.h" #include "hal/spi_types.h" #include "app_console.hpp" #include "audio_playback.hpp" #include "battery.hpp" #include "dac.hpp" #include "database.hpp" #include "display.hpp" #include "display_init.hpp" #include "gpio_expander.hpp" #include "i2c.hpp" #include "lvgl_task.hpp" #include "spi.hpp" #include "storage.hpp" #include "touchwheel.hpp" static const char* TAG = "MAIN"; void db_main(void* whatever) { database::Database **arg_db = reinterpret_cast(whatever); ESP_LOGI(TAG, "Init database"); std::unique_ptr db; auto db_res = database::Database::Open(); if (db_res.has_error()) { ESP_LOGE(TAG, "database failed :("); } else { db.reset(db_res.value()); ESP_LOGI(TAG, "database good :)"); } *arg_db = db.get(); db->ByTitle(); while (1) { vTaskDelay(portMAX_DELAY); } vTaskDelete(NULL); } extern "C" void app_main(void) { ESP_LOGI(TAG, "Initialising peripherals"); ESP_ERROR_CHECK(drivers::init_i2c()); ESP_ERROR_CHECK(drivers::init_spi()); std::unique_ptr drivers = std::make_unique(); ESP_LOGI(TAG, "Init GPIOs"); drivers::GpioExpander* expander = drivers->AcquireGpios(); ESP_LOGI(TAG, "Enable power rails for development"); expander->with( [&](auto& gpio) { gpio.set_pin(drivers::GpioExpander::AMP_EN, 1); }); ESP_LOGI(TAG, "Init battery measurement"); drivers::Battery* battery = new drivers::Battery(); ESP_LOGI(TAG, "it's reading %d mV!", (int)battery->Millivolts()); ESP_LOGI(TAG, "Init SD card"); auto storage = drivers->AcquireStorage(); if (!storage) { ESP_LOGE(TAG, "Failed! Do you have an SD card?"); } ESP_LOGI(TAG, "Launch database task"); std::size_t db_stack_size = 256 * 1024; StaticTask_t database_task_buffer = {}; StackType_t* database_stack = reinterpret_cast( heap_caps_malloc(db_stack_size, MALLOC_CAP_SPIRAM)); database::Database *db; xTaskCreateStatic(&db_main, "LEVELDB", db_stack_size, &db, 1, database_stack, &database_task_buffer); ESP_LOGI(TAG, "Init touch wheel"); std::shared_ptr touchwheel = drivers->AcquireTouchWheel(); std::atomic lvgl_quit; TaskHandle_t lvgl_task_handle; ui::StartLvgl(drivers.get(), &lvgl_quit, &lvgl_task_handle); std::unique_ptr playback; if (storage) { ESP_LOGI(TAG, "Init audio pipeline"); playback = std::make_unique(drivers.get()); } ESP_LOGI(TAG, "Waiting for background tasks before launching console..."); vTaskDelay(pdMS_TO_TICKS(1000)); ESP_LOGI(TAG, "Launch console"); console::AppConsole console(playback.get(), db); console.Launch(); uint8_t prev_position = 0; while (1) { touchwheel->Update(); auto wheel_data = touchwheel->GetTouchWheelData(); if (wheel_data.wheel_position != prev_position) { prev_position = wheel_data.wheel_position; ESP_LOGI(TAG, "Touch wheel pos: %u", prev_position); } vTaskDelay(pdMS_TO_TICKS(100)); } }