mirror of
https://github.com/espressif/ESP8266_RTOS_SDK.git
synced 2025-05-21 09:05:59 +08:00
feature(i2c): add i2c clock stretch
This commit is contained in:
@ -109,14 +109,21 @@ static i2c_obj_t *p_i2c_obj[I2C_NUM_MAX] = {0};
|
||||
static i2c_config_t *i2c_config[I2C_NUM_MAX] = {NULL};
|
||||
static i2c_last_state_t *i2c_last_state[I2C_NUM_MAX] = {NULL};
|
||||
|
||||
static void i2c_master_set_dc(i2c_port_t i2c_num, uint8_t sda, uint8_t scl)
|
||||
static inline void i2c_master_set_dc(i2c_port_t i2c_num, uint8_t sda, uint8_t scl)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
uint32_t clk_stretch_tick = i2c_config[i2c_num]->clk_stretch_tick;
|
||||
gpio_set_level(i2c_config[i2c_num]->sda_io_num, sda & 0x1);
|
||||
gpio_set_level(i2c_config[i2c_num]->scl_io_num, scl & 0x1);
|
||||
if ((i2c_last_state[i2c_num]->scl == 0) && ((scl & 0x1) == 1)) {
|
||||
// An I2C slave is allowed to hold down the clock if it needs to reduce the bus speed. The master, on the other hand, is required to read back the clock signal after releasing it to the high state and wait until the line has actually gone high.
|
||||
while (gpio_get_level(i2c_config[i2c_num]->scl_io_num) == 0 && (i++) < clk_stretch_tick); // Clock stretching
|
||||
}
|
||||
i2c_last_state[i2c_num]->val = ((sda & 0x1) << 1) | (scl & 0x1);
|
||||
gpio_set_level(i2c_config[i2c_num]->sda_io_num, i2c_last_state[i2c_num]->sda);
|
||||
gpio_set_level(i2c_config[i2c_num]->scl_io_num, i2c_last_state[i2c_num]->scl);
|
||||
|
||||
}
|
||||
|
||||
static uint8_t i2c_master_get_dc(i2c_port_t i2c_num)
|
||||
static inline uint8_t i2c_master_get_dc(i2c_port_t i2c_num)
|
||||
{
|
||||
uint8_t sda_out;
|
||||
sda_out = gpio_get_level(i2c_config[i2c_num]->sda_io_num);
|
||||
|
@ -64,6 +64,7 @@ typedef struct {
|
||||
gpio_pullup_t sda_pullup_en; /*!< Internal GPIO pull mode for I2C sda signal*/
|
||||
gpio_num_t scl_io_num; /*!< GPIO number for I2C scl signal */
|
||||
gpio_pullup_t scl_pullup_en; /*!< Internal GPIO pull mode for I2C scl signal*/
|
||||
uint32_t clk_stretch_tick; /*!< Clock Stretch time, depending on CPU frequency*/
|
||||
} i2c_config_t;
|
||||
|
||||
typedef void *i2c_cmd_handle_t; /*!< I2C command handle */
|
||||
|
@ -99,9 +99,10 @@ static esp_err_t i2c_example_master_init()
|
||||
i2c_config_t conf;
|
||||
conf.mode = I2C_MODE_MASTER;
|
||||
conf.sda_io_num = I2C_EXAMPLE_MASTER_SDA_IO;
|
||||
conf.sda_pullup_en = 0;
|
||||
conf.sda_pullup_en = 1;
|
||||
conf.scl_io_num = I2C_EXAMPLE_MASTER_SCL_IO;
|
||||
conf.scl_pullup_en = 0;
|
||||
conf.scl_pullup_en = 1;
|
||||
conf.clk_stretch_tick = 300; // 300 ticks, Clock stretch is about 210us, you can make changes according to the actual situation.
|
||||
ESP_ERROR_CHECK(i2c_driver_install(i2c_master_port, conf.mode));
|
||||
ESP_ERROR_CHECK(i2c_param_config(i2c_master_port, &conf));
|
||||
return ESP_OK;
|
||||
|
Reference in New Issue
Block a user