fix(i2c): Ensure that semaphore is properly given if init fails (#10313)
Currently code can return before semaphore is given, which can cause the bus to lock. Change makes sure that it's properly given in case of failure.
This commit is contained in:
parent
ef23d52d9b
commit
2c4ce95e16
1 changed files with 12 additions and 4 deletions
|
|
@ -71,6 +71,7 @@ bool i2cIsInit(uint8_t i2c_num) {
|
|||
}
|
||||
|
||||
esp_err_t i2cInit(uint8_t i2c_num, int8_t sda, int8_t scl, uint32_t frequency) {
|
||||
esp_err_t ret = ESP_OK;
|
||||
if (i2c_num >= SOC_I2C_NUM) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
|
@ -90,7 +91,8 @@ esp_err_t i2cInit(uint8_t i2c_num, int8_t sda, int8_t scl, uint32_t frequency) {
|
|||
#endif
|
||||
if (bus[i2c_num].initialized) {
|
||||
log_e("bus is already initialized");
|
||||
return ESP_FAIL;
|
||||
ret = ESP_FAIL;
|
||||
goto init_fail;
|
||||
}
|
||||
|
||||
if (!frequency) {
|
||||
|
|
@ -103,7 +105,8 @@ esp_err_t i2cInit(uint8_t i2c_num, int8_t sda, int8_t scl, uint32_t frequency) {
|
|||
perimanSetBusDeinit(ESP32_BUS_TYPE_I2C_MASTER_SCL, i2cDetachBus);
|
||||
|
||||
if (!perimanClearPinBus(sda) || !perimanClearPinBus(scl)) {
|
||||
return false;
|
||||
ret = ESP_FAIL;
|
||||
goto init_fail;
|
||||
}
|
||||
|
||||
log_i("Initializing I2C Master: sda=%d scl=%d freq=%d", sda, scl, frequency);
|
||||
|
|
@ -117,7 +120,7 @@ esp_err_t i2cInit(uint8_t i2c_num, int8_t sda, int8_t scl, uint32_t frequency) {
|
|||
conf.master.clk_speed = frequency;
|
||||
conf.clk_flags = I2C_SCLK_SRC_FLAG_FOR_NOMAL; //Any one clock source that is available for the specified frequency may be chosen
|
||||
|
||||
esp_err_t ret = i2c_param_config((i2c_port_t)i2c_num, &conf);
|
||||
ret = i2c_param_config((i2c_port_t)i2c_num, &conf);
|
||||
if (ret != ESP_OK) {
|
||||
log_e("i2c_param_config failed");
|
||||
} else {
|
||||
|
|
@ -133,11 +136,16 @@ esp_err_t i2cInit(uint8_t i2c_num, int8_t sda, int8_t scl, uint32_t frequency) {
|
|||
i2c_set_timeout((i2c_port_t)i2c_num, I2C_LL_MAX_TIMEOUT);
|
||||
if (!perimanSetPinBus(sda, ESP32_BUS_TYPE_I2C_MASTER_SDA, (void *)(i2c_num + 1), i2c_num, -1)
|
||||
|| !perimanSetPinBus(scl, ESP32_BUS_TYPE_I2C_MASTER_SCL, (void *)(i2c_num + 1), i2c_num, -1)) {
|
||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||
//release lock so that i2cDetachBus can execute i2cDeinit
|
||||
xSemaphoreGive(bus[i2c_num].lock);
|
||||
#endif
|
||||
i2cDetachBus((void *)(i2c_num + 1));
|
||||
return false;
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
init_fail:
|
||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||
//release lock
|
||||
xSemaphoreGive(bus[i2c_num].lock);
|
||||
|
|
|
|||
Loading…
Reference in a new issue