87 lines
2.0 KiB
C
87 lines
2.0 KiB
C
#include "driver/i2c.h"
|
|
#include "esp_err.h"
|
|
#include "esp_log.h"
|
|
#include "driver/gpio.h"
|
|
#include "esp_rom_sys.h"
|
|
|
|
#define SDA_PIN 21
|
|
#define SCL_PIN 22
|
|
#define I2C_PORT I2C_NUM_0
|
|
|
|
static const char *TAG_I2C = "I2C";
|
|
|
|
static void i2c_bus_reset(void)
|
|
{
|
|
// Solta o bus: gera 9 clocks em SCL para libertar SDA se algum escravo ficou preso
|
|
gpio_config_t io = {
|
|
.pin_bit_mask = (1ULL << SDA_PIN) | (1ULL << SCL_PIN),
|
|
.mode = GPIO_MODE_OUTPUT_OD,
|
|
.pull_up_en = GPIO_PULLUP_ENABLE,
|
|
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
|
.intr_type = GPIO_INTR_DISABLE
|
|
};
|
|
gpio_config(&io);
|
|
|
|
gpio_set_level(SDA_PIN, 1);
|
|
gpio_set_level(SCL_PIN, 1);
|
|
esp_rom_delay_us(5);
|
|
|
|
|
|
for (int i = 0; i < 9; i++) {
|
|
gpio_set_level(SCL_PIN, 0);
|
|
esp_rom_delay_us(5);
|
|
|
|
gpio_set_level(SCL_PIN, 1);
|
|
esp_rom_delay_us(5);
|
|
|
|
}
|
|
|
|
// STOP
|
|
gpio_set_level(SDA_PIN, 0);
|
|
esp_rom_delay_us(5);
|
|
|
|
gpio_set_level(SCL_PIN, 1);
|
|
esp_rom_delay_us(5);
|
|
|
|
gpio_set_level(SDA_PIN, 1);
|
|
esp_rom_delay_us(5);
|
|
|
|
|
|
// devolve os pinos ao I2C driver depois
|
|
}
|
|
|
|
esp_err_t i2c_init(void)
|
|
{
|
|
// se já estava instalado, limpa e volta a instalar
|
|
i2c_driver_delete(I2C_PORT);
|
|
|
|
i2c_bus_reset();
|
|
|
|
i2c_config_t cfg = {
|
|
.mode = I2C_MODE_MASTER,
|
|
.sda_io_num = SDA_PIN,
|
|
.scl_io_num = SCL_PIN,
|
|
.sda_pullup_en = GPIO_PULLUP_ENABLE,
|
|
.scl_pullup_en = GPIO_PULLUP_ENABLE,
|
|
.master.clk_speed = 100000, // começa seguro
|
|
.clk_flags = 0
|
|
};
|
|
|
|
esp_err_t err;
|
|
|
|
err = i2c_param_config(I2C_PORT, &cfg);
|
|
if (err != ESP_OK) {
|
|
ESP_LOGE(TAG_I2C, "i2c_param_config falhou: %s", esp_err_to_name(err));
|
|
return err;
|
|
}
|
|
|
|
err = i2c_driver_install(I2C_PORT, cfg.mode, 0, 0, 0);
|
|
if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) {
|
|
ESP_LOGE(TAG_I2C, "i2c_driver_install falhou: %s", esp_err_to_name(err));
|
|
return err;
|
|
}
|
|
|
|
ESP_LOGI(TAG_I2C, "I2C OK (SDA=%d SCL=%d) freq=100kHz", SDA_PIN, SCL_PIN);
|
|
return ESP_OK;
|
|
}
|