diff --git a/firmware/main/CMakeLists.txt b/firmware/main/CMakeLists.txt index 9b036b4..a98197a 100755 --- a/firmware/main/CMakeLists.txt +++ b/firmware/main/CMakeLists.txt @@ -2,6 +2,7 @@ idf_component_register(SRCS main.cpp app_task.cpp button_handling.c + i2c_checker.c hal/u8g2_esp32_hal.c INCLUDE_DIRS "." PRIV_REQUIRES @@ -14,4 +15,5 @@ idf_component_register(SRCS driver esp_timer esp_event + app_update ) diff --git a/firmware/main/app_task.cpp b/firmware/main/app_task.cpp index 3d514be..da51e50 100644 --- a/firmware/main/app_task.cpp +++ b/firmware/main/app_task.cpp @@ -1,25 +1,19 @@ #include "app_task.h" -#include "esp_log.h" -#include "esp_timer.h" -#include "hal/u8g2_esp32_hal.h" -#include "u8g2.h" - #include "button_handling.h" #include "common/InactivityTracker.h" +#include "driver/i2c.h" +#include "esp_log.h" +#include "esp_timer.h" +#include "hal/u8g2_esp32_hal.h" #include "hal_esp32/PersistenceManager.h" +#include "i2c_checker.h" +#include "led_status.h" +#include "u8g2.h" #include "ui/ClockScreenSaver.h" #include "ui/ScreenSaver.h" #include "ui/SplashScreen.h" -#if defined(CONFIG_IDF_TARGET_ESP32S3) -#define PIN_SDA GPIO_NUM_35 -#define PIN_SCL GPIO_NUM_36 -#else -/// just dummy pins, because of compile check -#define PIN_SDA GPIO_NUM_20 -#define PIN_SCL GPIO_NUM_21 -#endif #define PIN_RST GPIO_NUM_NC static const char *TAG = "app_task"; @@ -38,13 +32,13 @@ extern QueueHandle_t buttonQueue; static void setup_screen(void) { u8g2_esp32_hal_t u8g2_esp32_hal = U8G2_ESP32_HAL_DEFAULT; - u8g2_esp32_hal.bus.i2c.sda = PIN_SDA; - u8g2_esp32_hal.bus.i2c.scl = PIN_SCL; + u8g2_esp32_hal.bus.i2c.sda = I2C_MASTER_SDA_PIN; + u8g2_esp32_hal.bus.i2c.scl = I2C_MASTER_SCL_PIN; u8g2_esp32_hal.reset = PIN_RST; u8g2_esp32_hal_init(u8g2_esp32_hal); u8g2_Setup_sh1106_i2c_128x64_noname_f(&u8g2, U8G2_R0, u8g2_esp32_i2c_byte_cb, u8g2_esp32_gpio_and_delay_cb); - u8x8_SetI2CAddress(&u8g2.u8x8, 0x3C * 2); + u8x8_SetI2CAddress(&u8g2.u8x8, DISPLAY_I2C_ADDRESS << 1); ESP_LOGI(TAG, "u8g2_InitDisplay"); u8g2_InitDisplay(&u8g2); @@ -150,6 +144,17 @@ static void handle_button(uint8_t button) void app_task(void *args) { + if (i2c_bus_scan_and_check() != ESP_OK) + { + led_behavior_t led0_behavior = { + .mode = LED_MODE_BLINK, .color = {.r = 50, .g = 0, .b = 0}, .on_time_ms = 200, .off_time_ms = 200}; + led_status_set_behavior(0, led0_behavior); + + ESP_LOGE(TAG, "Display not found, cannot continue."); + vTaskDelete(nullptr); + return; + } + setup_screen(); setup_buttons(); init_ui(); @@ -183,4 +188,4 @@ void app_task(void *args) } cleanup_buttons(); -} \ No newline at end of file +} diff --git a/firmware/main/i2c_checker.c b/firmware/main/i2c_checker.c new file mode 100644 index 0000000..c9a290b --- /dev/null +++ b/firmware/main/i2c_checker.c @@ -0,0 +1,73 @@ +#include "i2c_checker.h" + +#include "driver/i2c.h" +#include "esp_log.h" +#include "hal/u8g2_esp32_hal.h" + +static const char *TAG = "i2c_checker"; + +esp_err_t i2c_device_check(i2c_port_t i2c_port, uint8_t device_address) +{ + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + // Send the device address with the write bit (LSB = 0) + i2c_master_write_byte(cmd, (device_address << 1) | I2C_MASTER_WRITE, true); + i2c_master_stop(cmd); + + esp_err_t ret = i2c_master_cmd_begin(i2c_port, cmd, pdMS_TO_TICKS(100)); + + i2c_cmd_link_delete(cmd); + + return ret; +} + +esp_err_t i2c_bus_scan_and_check(void) +{ + // 1. Configure and install I2C bus + i2c_config_t conf = { + .mode = I2C_MODE_MASTER, + .sda_io_num = I2C_MASTER_SDA_PIN, + .scl_io_num = I2C_MASTER_SCL_PIN, + .sda_pullup_en = GPIO_PULLUP_ENABLE, + .scl_pullup_en = GPIO_PULLUP_ENABLE, + .master.clk_speed = I2C_MASTER_FREQ_HZ, + }; + esp_err_t err = i2c_param_config(I2C_MASTER_NUM, &conf); + if (err != ESP_OK) + { + ESP_LOGE(TAG, "I2C parameter configuration failed: %s", esp_err_to_name(err)); + return err; + } + + err = i2c_driver_install(I2C_MASTER_NUM, conf.mode, 0, 0, 0); + if (err != ESP_OK) + { + ESP_LOGE(TAG, "I2C driver installation failed: %s", esp_err_to_name(err)); + return err; + } + + ESP_LOGI(TAG, "I2C driver initialized. Searching for device..."); + + // 2. Check if the device is present + err = i2c_device_check(I2C_MASTER_NUM, DISPLAY_I2C_ADDRESS); + + if (err == ESP_OK) + { + ESP_LOGI(TAG, "Device found at address 0x%02X!", DISPLAY_I2C_ADDRESS); + // Here you could now call e.g. setup_screen() + } + else if (err == ESP_ERR_TIMEOUT) + { + ESP_LOGE(TAG, "Timeout! Device at address 0x%02X is not responding.", DISPLAY_I2C_ADDRESS); + } + else + { + ESP_LOGE(TAG, "Error communicating with address 0x%02X: %s", DISPLAY_I2C_ADDRESS, esp_err_to_name(err)); + } + + // 3. Uninstall I2C driver if it is no longer needed + i2c_driver_delete(I2C_MASTER_NUM); + ESP_LOGI(TAG, "I2C driver uninstalled."); + + return err; +} diff --git a/firmware/main/i2c_checker.h b/firmware/main/i2c_checker.h new file mode 100644 index 0000000..95d1167 --- /dev/null +++ b/firmware/main/i2c_checker.h @@ -0,0 +1,23 @@ +#pragma once + +#include "esp_err.h" + +#define DISPLAY_I2C_ADDRESS 0x3C + +#if defined(CONFIG_IDF_TARGET_ESP32S3) +#define I2C_MASTER_SDA_PIN GPIO_NUM_35 +#define I2C_MASTER_SCL_PIN GPIO_NUM_36 +#else +/// just dummy pins, because of compile check +#define I2C_MASTER_SDA_PIN GPIO_NUM_20 +#define I2C_MASTER_SCL_PIN GPIO_NUM_21 +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + esp_err_t i2c_bus_scan_and_check(void); +#ifdef __cplusplus +} +#endif diff --git a/firmware/main/main.cpp b/firmware/main/main.cpp index d334e89..51fb933 100644 --- a/firmware/main/main.cpp +++ b/firmware/main/main.cpp @@ -3,7 +3,9 @@ #include "esp_event.h" #include "esp_insights.h" #include "esp_log.h" +#include "esp_ota_ops.h" #include "freertos/FreeRTOS.h" +#include "freertos/task.h" #include "led_manager.h" #include "led_status.h" #include "nvs_flash.h" @@ -20,6 +22,26 @@ "2nVyZI5Y253Nch6MaeBpvrfRXhUI6uWXZuSDa3nrS5MmtElZgQjEyAJSX5lfhRwEc2Qi2LlHc4LHPD0YvO1JhSF4N6Rwf1FrJZ1qU_" \ "IxNTdTxtzLC0BUcYA" +static const char *TAG = "main"; + +void show_partition(void) +{ + const esp_partition_t *running_partition = esp_ota_get_running_partition(); + + if (running_partition != NULL) + { + ESP_LOGI(TAG, "Currently running partition: %s", running_partition->label); + ESP_LOGI(TAG, " Type: %s", (running_partition->type == ESP_PARTITION_TYPE_APP) ? "APP" : "DATA"); + ESP_LOGI(TAG, " Subtype: %d", running_partition->subtype); + ESP_LOGI(TAG, " Offset: 0x%lx", running_partition->address); + ESP_LOGI(TAG, " Size: %ld bytes", running_partition->size); + } + else + { + ESP_LOGE(TAG, "Could not determine the running partition!"); + } +} + #ifdef __cplusplus extern "C" { @@ -34,6 +56,8 @@ extern "C" ESP_ERROR_CHECK(nvs_flash_init()); } + show_partition(); + esp_insights_config_t config = { .log_type = ESP_DIAG_LOG_TYPE_ERROR, .node_id = nullptr, @@ -45,26 +69,15 @@ extern "C" led_status_init(CONFIG_STATUS_WLED_PIN); - // LED 0: solid red - led_behavior_t led0_solid_red = {.mode = LED_MODE_SOLID, .color = {.r = 50, .g = 0, .b = 0}}; - led_status_set_behavior(0, led0_solid_red); - - // LED 1: fast blinking green (200ms an, 200ms aus) - led_behavior_t led1_blink_green = { - .mode = LED_MODE_BLINK, .color = {.r = 0, .g = 50, .b = 0}, .on_time_ms = 200, .off_time_ms = 200}; - led_status_set_behavior(1, led1_blink_green); - - // LED 2: slow blinking blue (1000ms an, 500ms aus) - led_behavior_t led2_blink_blue = { - .mode = LED_MODE_BLINK, .color = {.r = 0, .g = 0, .b = 50}, .on_time_ms = 1000, .off_time_ms = 500}; - led_status_set_behavior(2, led2_blink_blue); - wled_init(); register_handler(); xTaskCreatePinnedToCore(app_task, "main_loop", 4096, NULL, tskIDLE_PRIORITY + 1, NULL, portNUM_PROCESSORS - 1); - xTaskCreatePinnedToCore(ble_manager_task, "ble_manager", 4096, NULL, tskIDLE_PRIORITY + 1, NULL, - portNUM_PROCESSORS - 1); + // xTaskCreatePinnedToCore(ble_manager_task, "ble_manager", 4096, NULL, tskIDLE_PRIORITY + 1, NULL, + // portNUM_PROCESSORS - 1); + + led_event_data_t payload = {.value = 42}; + send_event(EVENT_LED_ON, &payload); } #ifdef __cplusplus }