diff --git a/ports/esp32/machine_i2c.c b/ports/esp32/machine_i2c.c index 17e98ffc5b..c805dab87e 100644 --- a/ports/esp32/machine_i2c.c +++ b/ports/esp32/machine_i2c.c @@ -32,6 +32,13 @@ #include "driver/i2c.h" +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0) +#include "hal/i2c_ll.h" +#else +#include "soc/i2c_reg.h" +#define I2C_LL_MAX_TIMEOUT I2C_TIME_OUT_REG_V +#endif + #ifndef MICROPY_HW_I2C0_SCL #define MICROPY_HW_I2C0_SCL (GPIO_NUM_18) #define MICROPY_HW_I2C0_SDA (GPIO_NUM_19) @@ -47,6 +54,14 @@ #endif #endif +#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 +#define I2C_SCLK_FREQ XTAL_CLK_FREQ +#elif CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 +#define I2C_SCLK_FREQ I2C_APB_CLK_FREQ +#else +#error "unsupported I2C for ESP32 SoC variant" +#endif + #define I2C_DEFAULT_TIMEOUT_US (10000) // 10ms typedef struct _machine_hw_i2c_obj_t { @@ -71,7 +86,8 @@ STATIC void machine_hw_i2c_init(machine_hw_i2c_obj_t *self, uint32_t freq, uint3 .master.clk_speed = freq, }; i2c_param_config(self->port, &conf); - i2c_set_timeout(self->port, I2C_APB_CLK_FREQ / 1000000 * timeout_us); + int timeout = I2C_SCLK_FREQ / 1000000 * timeout_us; + i2c_set_timeout(self->port, (timeout > I2C_LL_MAX_TIMEOUT) ? I2C_LL_MAX_TIMEOUT : timeout); i2c_driver_install(self->port, I2C_MODE_MASTER, 0, 0, 0); } @@ -131,7 +147,7 @@ STATIC void machine_hw_i2c_print(const mp_print_t *print, mp_obj_t self_in, mp_p int h, l; i2c_get_period(self->port, &h, &l); mp_printf(print, "I2C(%u, scl=%u, sda=%u, freq=%u)", - self->port, self->scl, self->sda, I2C_APB_CLK_FREQ / (h + l)); + self->port, self->scl, self->sda, I2C_SCLK_FREQ / (h + l)); } mp_obj_t machine_hw_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {