diff --git a/libraries/Wire/src/utility/twi.c b/libraries/Wire/src/utility/twi.c index cf9b8c535e..d349df3c20 100644 --- a/libraries/Wire/src/utility/twi.c +++ b/libraries/Wire/src/utility/twi.c @@ -848,6 +848,7 @@ i2c_status_e i2c_master_write(i2c_t *obj, uint8_t dev_address, uint32_t tickstart = HAL_GetTick(); uint32_t delta = 0; uint32_t err = 0; + HAL_StatusTypeDef status = HAL_OK; /* When size is 0, this is usually an I2C scan / ping to check if device is there and ready */ if (size == 0) { @@ -856,12 +857,26 @@ i2c_status_e i2c_master_write(i2c_t *obj, uint8_t dev_address, #if defined(I2C_OTHER_FRAME) uint32_t XferOptions = obj->handle.XferOptions; // save XferOptions value, because handle can be modified by HAL, which cause issue in case of NACK from slave #endif - + do { #if defined(I2C_OTHER_FRAME) - if (HAL_I2C_Master_Seq_Transmit_IT(&(obj->handle), dev_address, data, size, XferOptions) == HAL_OK) { + status = HAL_I2C_Master_Seq_Transmit_IT(&(obj->handle), dev_address, data, size, XferOptions); #else - if (HAL_I2C_Master_Transmit_IT(&(obj->handle), dev_address, data, size) == HAL_OK) { + status = HAL_I2C_Master_Transmit_IT(&(obj->handle), dev_address, data, size); #endif + // Ensure i2c ready + if (status == HAL_BUSY) { + delta = (HAL_GetTick() - tickstart); + if (delta > I2C_TIMEOUT_TICK) { + ret = I2C_BUSY; + break; + } + } else { + ret = (status == HAL_OK) ? I2C_OK : I2C_ERROR; + } + } while (status == HAL_BUSY); + + if (ret == I2C_OK) { + tickstart = HAL_GetTick(); // wait for transfer completion while ((HAL_I2C_GetState(&(obj->handle)) != HAL_I2C_STATE_READY) && (delta < I2C_TIMEOUT_TICK)) { delta = (HAL_GetTick() - tickstart); @@ -926,16 +941,31 @@ i2c_status_e i2c_master_read(i2c_t *obj, uint8_t dev_address, uint8_t *data, uin uint32_t tickstart = HAL_GetTick(); uint32_t delta = 0; uint32_t err = 0; + HAL_StatusTypeDef status = HAL_OK; #if defined(I2C_OTHER_FRAME) uint32_t XferOptions = obj->handle.XferOptions; // save XferOptions value, because handle can be modified by HAL, which cause issue in case of NACK from slave #endif - + do { #if defined(I2C_OTHER_FRAME) - if (HAL_I2C_Master_Seq_Receive_IT(&(obj->handle), dev_address, data, size, XferOptions) == HAL_OK) { + status = HAL_I2C_Master_Seq_Receive_IT(&(obj->handle), dev_address, data, size, XferOptions); #else - if (HAL_I2C_Master_Receive_IT(&(obj->handle), dev_address, data, size) == HAL_OK) { + status = HAL_I2C_Master_Receive_IT(&(obj->handle), dev_address, data, size); #endif + // Ensure i2c ready + if (status == HAL_BUSY) { + delta = (HAL_GetTick() - tickstart); + if (delta > I2C_TIMEOUT_TICK) { + ret = I2C_BUSY; + break; + } + } else { + ret = (status == HAL_OK) ? I2C_OK : I2C_ERROR; + } + } while (status == HAL_BUSY); + + if (ret == I2C_OK) { + tickstart = HAL_GetTick(); // wait for transfer completion while ((HAL_I2C_GetState(&(obj->handle)) != HAL_I2C_STATE_READY) && (delta < I2C_TIMEOUT_TICK)) { delta = (HAL_GetTick() - tickstart);