#include "i2c_bus.h" #include "esp_log.h" static const char *TAG = "i2c"; static i2c_master_bus_handle_t s_bus; esp_err_t i2c_bus_init(void) { if (s_bus) { return ESP_OK; } i2c_master_bus_config_t cfg = { .i2c_port = I2C_NUM_0, .sda_io_num = I2C_BUS_SDA_GPIO, .scl_io_num = I2C_BUS_SCL_GPIO, .clk_source = I2C_CLK_SRC_DEFAULT, .glitch_ignore_cnt = 7, .flags.enable_internal_pullup = true, }; esp_err_t err = i2c_new_master_bus(&cfg, &s_bus); if (err != ESP_OK) { ESP_LOGE(TAG, "bus init failed: %s", esp_err_to_name(err)); return err; } ESP_LOGI(TAG, "bus up on SDA=%d SCL=%d @ %d Hz", I2C_BUS_SDA_GPIO, I2C_BUS_SCL_GPIO, I2C_BUS_FREQ_HZ); return ESP_OK; } esp_err_t i2c_bus_add_device(uint8_t addr, i2c_master_dev_handle_t *out) { if (!s_bus) { return ESP_ERR_INVALID_STATE; } i2c_device_config_t cfg = { .dev_addr_length = I2C_ADDR_BIT_LEN_7, .device_address = addr, .scl_speed_hz = I2C_BUS_FREQ_HZ, }; return i2c_master_bus_add_device(s_bus, &cfg, out); } int i2c_bus_scan(void) { if (!s_bus) { ESP_LOGE(TAG, "scan before init"); return -1; } int found = 0; ESP_LOGI(TAG, "scanning..."); for (uint8_t addr = 0x08; addr < 0x78; addr++) { if (i2c_master_probe(s_bus, addr, 50) == ESP_OK) { const char *who = "?"; if (addr == 0x21) { who = "PCF8574 expander"; } else if (addr == 0x15) { who = "CST826 touch"; } ESP_LOGI(TAG, " 0x%02X %s", addr, who); found++; } } if (found == 0) { /* Loud, because this means the board or the pinout is wrong, and no * amount of display debugging past this point is worth doing. */ ESP_LOGE(TAG, "no I2C devices found — check SDA=%d / SCL=%d wiring " "before debugging anything else", I2C_BUS_SDA_GPIO, I2C_BUS_SCL_GPIO); } else { ESP_LOGI(TAG, "scan done, %d device(s)", found); } return found; }