forked from espressif/esp-idf
Merge branch 'fix/ble_i2c_v5.3' into 'release/v5.3'
fix(i2c): Fix i2c read from fifo issue when enabling bt/wifi/uart, etc... (backport v5.3) See merge request espressif/esp-idf!36054
This commit is contained in:
@@ -153,7 +153,11 @@ esp_err_t i2c_acquire_bus_handle(i2c_port_num_t port_num, i2c_bus_handle_t *i2c_
|
||||
break;
|
||||
}
|
||||
}
|
||||
ESP_RETURN_ON_FALSE((bus_found == true), ESP_ERR_NOT_FOUND, TAG, "acquire bus failed, no free bus");
|
||||
if (bus_found == false) {
|
||||
ESP_LOGE(TAG, "acquire bus failed, no free bus");
|
||||
_lock_release(&s_i2c_platform.mutex);
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
} else {
|
||||
ret = s_i2c_bus_handle_acquire(port_num, i2c_new_bus, mode);
|
||||
if (ret != ESP_OK) {
|
||||
|
@@ -760,7 +760,11 @@ static esp_err_t i2c_master_bus_destroy(i2c_master_bus_handle_t bus_handle)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(bus_handle, ESP_ERR_INVALID_ARG, TAG, "no memory for i2c master bus");
|
||||
i2c_master_bus_handle_t i2c_master = bus_handle;
|
||||
if (i2c_release_bus_handle(i2c_master->base) == ESP_OK) {
|
||||
esp_err_t err = ESP_OK;
|
||||
if (i2c_master->base) {
|
||||
err = i2c_release_bus_handle(i2c_master->base);
|
||||
}
|
||||
if (err == ESP_OK) {
|
||||
if (i2c_master) {
|
||||
if (i2c_master->bus_lock_mux) {
|
||||
vSemaphoreDeleteWithCaps(i2c_master->bus_lock_mux);
|
||||
@@ -932,6 +936,19 @@ esp_err_t i2c_new_master_bus(const i2c_master_bus_config_t *bus_config, i2c_mast
|
||||
}
|
||||
#if SOC_LP_I2C_SUPPORTED
|
||||
else {
|
||||
|
||||
soc_periph_lp_i2c_clk_src_t clk_srcs[] = SOC_LP_I2C_CLKS;
|
||||
bool lp_clock_match = false;
|
||||
for (int i = 0; i < sizeof(clk_srcs) / sizeof(clk_srcs[0]); i++) {
|
||||
if ((int)clk_srcs[i] == (int)i2c_master->base->clk_src) {
|
||||
/* Clock source matches. Override the source clock type with the user configured value */
|
||||
lp_clock_match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ESP_GOTO_ON_FALSE(lp_clock_match, ESP_ERR_NOT_SUPPORTED, err, TAG, "the clock source does not support lp i2c, please check");
|
||||
|
||||
LP_I2C_SRC_CLK_ATOMIC() {
|
||||
lp_i2c_ll_set_source_clk(hal->dev, i2c_master->base->clk_src);
|
||||
}
|
||||
|
@@ -146,6 +146,41 @@ TEST_CASE("I2C device add & remove check", "[i2c]")
|
||||
TEST_ESP_OK(i2c_del_master_bus(bus_handle));
|
||||
}
|
||||
|
||||
TEST_CASE("I2C peripheral allocate all", "[i2c]")
|
||||
{
|
||||
i2c_master_bus_handle_t bus_handle[SOC_HP_I2C_NUM];
|
||||
for (int i = 0; i < SOC_HP_I2C_NUM; i++) {
|
||||
i2c_master_bus_config_t i2c_mst_config_1 = {
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = -1,
|
||||
.scl_io_num = I2C_MASTER_SCL_IO,
|
||||
.sda_io_num = I2C_MASTER_SDA_IO,
|
||||
.flags.enable_internal_pullup = true,
|
||||
};
|
||||
|
||||
TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config_1, &bus_handle[i]));
|
||||
}
|
||||
i2c_master_bus_config_t i2c_mst_config_1 = {
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = -1,
|
||||
.scl_io_num = I2C_MASTER_SCL_IO,
|
||||
.sda_io_num = I2C_MASTER_SDA_IO,
|
||||
.flags.enable_internal_pullup = true,
|
||||
};
|
||||
i2c_master_bus_handle_t bus_handle_2;
|
||||
|
||||
TEST_ESP_ERR(ESP_ERR_NOT_FOUND, i2c_new_master_bus(&i2c_mst_config_1, &bus_handle_2));
|
||||
|
||||
for (int i = 0; i < SOC_HP_I2C_NUM; i++) {
|
||||
TEST_ESP_OK(i2c_del_master_bus(bus_handle[i]));
|
||||
}
|
||||
|
||||
// Get another one
|
||||
|
||||
TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config_1, &bus_handle_2));
|
||||
TEST_ESP_OK(i2c_del_master_bus(bus_handle_2));
|
||||
}
|
||||
|
||||
TEST_CASE("I2C master probe device test", "[i2c]")
|
||||
{
|
||||
// 0x22,33,44,55 does not exist on the I2C bus, so it's expected to return `not found` error
|
||||
|
@@ -64,6 +64,20 @@ TEST_CASE("LP I2C initialize with wrong IO", "[i2c]")
|
||||
|
||||
#endif
|
||||
|
||||
TEST_CASE("LP I2C initialize with wrong clock source", "[i2c]")
|
||||
{
|
||||
i2c_master_bus_config_t i2c_mst_config = {
|
||||
.lp_source_clk = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = LP_I2C_NUM_0,
|
||||
.scl_io_num = LP_I2C_SCL_IO,
|
||||
.sda_io_num = LP_I2C_SDA_IO,
|
||||
.flags.enable_internal_pullup = true,
|
||||
};
|
||||
i2c_master_bus_handle_t bus_handle;
|
||||
|
||||
TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, i2c_new_master_bus(&i2c_mst_config, &bus_handle));
|
||||
}
|
||||
|
||||
static IRAM_ATTR bool test_i2c_rx_done_callback(i2c_slave_dev_handle_t channel, const i2c_slave_rx_done_event_data_t *edata, void *user_data)
|
||||
{
|
||||
BaseType_t high_task_wakeup = pdFALSE;
|
||||
|
@@ -323,8 +323,8 @@ static inline void i2c_ll_set_slave_addr(i2c_dev_t *hw, uint16_t slave_addr, boo
|
||||
hw->slave_addr.en_10bit = addr_10bit_en;
|
||||
if (addr_10bit_en) {
|
||||
uint16_t addr_14_7 = (slave_addr & 0xff) << 7;
|
||||
uint8_t addr_6_0 = ((slave_addr & 0x300) >> 8) || 0x78;
|
||||
hw->slave_addr.addr = addr_14_7 || addr_6_0;
|
||||
uint8_t addr_6_0 = ((slave_addr & 0x300) >> 8) | 0x78;
|
||||
hw->slave_addr.addr = addr_14_7 | addr_6_0;
|
||||
} else {
|
||||
hw->slave_addr.addr = slave_addr;
|
||||
}
|
||||
@@ -573,7 +573,9 @@ __attribute__((always_inline))
|
||||
static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len)
|
||||
{
|
||||
for(int i = 0; i < len; i++) {
|
||||
ptr[i] = HAL_FORCE_READ_U32_REG_FIELD(hw->fifo_data, data);
|
||||
// Known issue that hardware read fifo will cause data lose, (fifo pointer jump over a random address)
|
||||
// use `DPORT_REG_READ` can avoid this issue.
|
||||
ptr[i] = DPORT_REG_READ((uint32_t)&hw->fifo_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -387,6 +387,10 @@ config SOC_I2C_SUPPORT_APB
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_I2C_SUPPORT_10BIT_ADDR
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_I2C_STOP_INDEPENDENT
|
||||
bool
|
||||
default y
|
||||
|
@@ -206,6 +206,7 @@
|
||||
#define SOC_I2C_SUPPORT_SLAVE (1)
|
||||
|
||||
#define SOC_I2C_SUPPORT_APB (1)
|
||||
#define SOC_I2C_SUPPORT_10BIT_ADDR (1)
|
||||
|
||||
// On ESP32, the stop bit should be independent, we can't put trans data and stop command together
|
||||
#define SOC_I2C_STOP_INDEPENDENT (1)
|
||||
|
@@ -451,7 +451,7 @@ Whenever the master writes data to the slave, the slave will automatically store
|
||||
i2c_slave_dev_handle_t slave_handle;
|
||||
ESP_ERROR_CHECK(i2c_new_slave_device(&i2c_slv_config, &slave_handle));
|
||||
|
||||
s_receive_queue = xQueueCreate(1, sizeof(i2c_slave_rx_done_event_data_t));
|
||||
QueueHandle_t s_receive_queue = xQueueCreate(1, sizeof(i2c_slave_rx_done_event_data_t));
|
||||
i2c_slave_event_callbacks_t cbs = {
|
||||
.on_recv_done = i2c_slave_rx_done_callback,
|
||||
};
|
||||
|
Reference in New Issue
Block a user