add i2c check for display

Signed-off-by: Peter Siegmund <developer@mars3142.org>
This commit is contained in:
2025-09-11 10:39:12 +02:00
parent 597bfeee28
commit b05ffb544c
5 changed files with 149 additions and 33 deletions

View File

@@ -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
)

View File

@@ -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();
}
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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
}