From ee8adce5eaf7c609148e0942b5b99c3974aff710 Mon Sep 17 00:00:00 2001 From: Sudeep Mohanty Date: Fri, 28 Jul 2023 11:32:05 +0200 Subject: [PATCH 1/3] fix(lp_i2c): Fixed incorrect clock setting for LP_I2C The LP_I2C clock setting was incorrect and a lower frequency value was being set during initialization. This commit fixes the behavior. --- components/ulp/lp_core/lp_core_i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/ulp/lp_core/lp_core_i2c.c b/components/ulp/lp_core/lp_core_i2c.c index b75e7b2afb..4726602f0a 100644 --- a/components/ulp/lp_core/lp_core_i2c.c +++ b/components/ulp/lp_core/lp_core_i2c.c @@ -112,7 +112,7 @@ static esp_err_t lp_i2c_config_clk(const lp_core_i2c_cfg_t *cfg) lp_i2c_ll_set_source_clk(i2c_hal.dev, source_clk); /* Configure LP I2C timing paramters. source_clk is ignored for LP_I2C in this call */ - i2c_hal_set_bus_timing(&i2c_hal, (i2c_clock_source_t)source_clk, cfg->i2c_timing_cfg.clk_speed_hz, source_freq); + i2c_hal_set_bus_timing(&i2c_hal, cfg->i2c_timing_cfg.clk_speed_hz, (i2c_clock_source_t)source_clk, source_freq); return ret; } From a9ef76b0318bbb6c2d9ff4064c8c931f160d936e Mon Sep 17 00:00:00 2001 From: Sudeep Mohanty Date: Mon, 7 Aug 2023 09:59:28 +0200 Subject: [PATCH 2/3] fix(lp_i2c): Fixed a bug where LP I2C write got stuck This commit fixes a bug where an I2C write got stuck when using the lp_core_i2c_master_write_read_device() API. This was because the LP I2C HW was not programmed with an END condition and therefore did not know the end of a transaction. Closes: https://github.com/espressif/esp-idf/issues/11958 --- components/ulp/lp_core/lp_core/lp_core_i2c.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/components/ulp/lp_core/lp_core/lp_core_i2c.c b/components/ulp/lp_core/lp_core/lp_core_i2c.c index feccabc5b1..7b73fc1cc2 100644 --- a/components/ulp/lp_core/lp_core/lp_core_i2c.c +++ b/components/ulp/lp_core/lp_core/lp_core_i2c.c @@ -382,11 +382,9 @@ esp_err_t lp_core_i2c_master_write_read_device(i2c_port_t lp_i2c_num, uint16_t d i2c_ll_write_txfifo(dev, &data_wr[data_idx], fifo_size); lp_core_i2c_format_cmd(cmd_idx++, I2C_LL_CMD_WRITE, 0, LP_I2C_ACK, s_ack_check_en, fifo_size); - if (remaining_bytes) { - /* This means we have to send more than what can fit in the Tx FIFO. Insert an End command. */ - lp_core_i2c_format_cmd(cmd_idx++, I2C_LL_CMD_END, 0, 0, 0, 0); - cmd_idx = 0; - } + /* Insert an End command to signal the end of the write transaction to the HW */ + lp_core_i2c_format_cmd(cmd_idx++, I2C_LL_CMD_END, 0, 0, 0, 0); + cmd_idx = 0; /* Initiate I2C transfer */ i2c_ll_update(dev); From 6b1292284e7b85f4fca6c6c9bcd75748e7008a8f Mon Sep 17 00:00:00 2001 From: Sudeep Mohanty Date: Mon, 7 Aug 2023 10:43:16 +0200 Subject: [PATCH 3/3] fix(lp_i2c): Fixed a bug where the LP_I2C did not send NACK for 16-byte reads This commit updates the LP_I2C driver used by the LP CPU wherein the driver did not send out a NACK when we do a read of multiple of the FIFO depth bytes. This was because the LP I2C controller was configured to send an ACK when the Rx FIFO reaches the threshold instead of a NACK. This commit updates the behavior. --- components/hal/esp32c6/include/hal/i2c_ll.h | 14 ++++++++++++++ components/ulp/lp_core/lp_core_i2c.c | 3 +++ 2 files changed, 17 insertions(+) diff --git a/components/hal/esp32c6/include/hal/i2c_ll.h b/components/hal/esp32c6/include/hal/i2c_ll.h index 83c73a3e03..76aa53949d 100644 --- a/components/hal/esp32c6/include/hal/i2c_ll.h +++ b/components/hal/esp32c6/include/hal/i2c_ll.h @@ -656,6 +656,20 @@ static inline void i2c_ll_master_clr_bus(i2c_dev_t *hw) hw->ctr.conf_upgate = 1; } +/** + * @brief Set the ACK level that the I2C master must send when the Rx FIFO count has reached the threshold value. + * ack_level: 1 (NACK) + * ack_level: 0 (ACK) + * + * @param hw Beginning address of the peripheral registers + * + * @return None + */ +static inline void i2c_ll_master_rx_full_ack_level(i2c_dev_t *hw, int ack_level) +{ + hw->ctr.rx_full_ack_level = ack_level; +} + /** * @brief Set I2C source clock * diff --git a/components/ulp/lp_core/lp_core_i2c.c b/components/ulp/lp_core/lp_core_i2c.c index 4726602f0a..71ce2118d7 100644 --- a/components/ulp/lp_core/lp_core_i2c.c +++ b/components/ulp/lp_core/lp_core_i2c.c @@ -143,6 +143,9 @@ esp_err_t lp_core_i2c_master_init(i2c_port_t lp_i2c_num, const lp_core_i2c_cfg_t /* Enable SDA and SCL filtering. This configuration matches the HP I2C filter config */ i2c_ll_set_filter(i2c_hal.dev, LP_I2C_FILTER_CYC_NUM_DEF); + /* Configure the I2C master to send a NACK when the Rx FIFO count is full */ + i2c_ll_master_rx_full_ack_level(i2c_hal.dev, 1); + /* Synchronize the config register values to the LP I2C peripheral clock */ i2c_ll_update(i2c_hal.dev);