Skip to content

Commit 5449ab7

Browse files
committed
fix(wire): ensure i2c bus is ready
Previously, i2c_master_write and i2c_master_read returned I2C_OK if first HAL call returned HAL_BUSY which was not correct. Now make sure the i2c is ready, which guarantees a good initialization of the read or write sequence. Fixes stm32duino#1774 Signed-off-by: Frederic Pillon <[email protected]>
1 parent f0a043e commit 5449ab7

File tree

1 file changed

+22
-5
lines changed
  • libraries/Wire/src/utility

1 file changed

+22
-5
lines changed

Diff for: libraries/Wire/src/utility/twi.c

+22-5
Original file line numberDiff line numberDiff line change
@@ -856,12 +856,20 @@ i2c_status_e i2c_master_write(i2c_t *obj, uint8_t dev_address,
856856
#if defined(I2C_OTHER_FRAME)
857857
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
858858
#endif
859-
860859
#if defined(I2C_OTHER_FRAME)
861-
if (HAL_I2C_Master_Seq_Transmit_IT(&(obj->handle), dev_address, data, size, XferOptions) == HAL_OK) {
860+
while (HAL_I2C_Master_Seq_Transmit_IT(&(obj->handle), dev_address, data, size, XferOptions) == HAL_BUSY) {
862861
#else
863-
if (HAL_I2C_Master_Transmit_IT(&(obj->handle), dev_address, data, size) == HAL_OK) {
862+
while (HAL_I2C_Master_Transmit_IT(&(obj->handle), dev_address, data, size) == HAL_BUSY) {
864863
#endif
864+
// Ensure i2c ready
865+
delta = (HAL_GetTick() - tickstart);
866+
if (delta > I2C_TIMEOUT_TICK) {
867+
ret = I2C_BUSY;
868+
break;
869+
}
870+
}
871+
if (ret == I2C_OK) {
872+
tickstart = HAL_GetTick();
865873
// wait for transfer completion
866874
while ((HAL_I2C_GetState(&(obj->handle)) != HAL_I2C_STATE_READY) && (delta < I2C_TIMEOUT_TICK)) {
867875
delta = (HAL_GetTick() - tickstart);
@@ -932,10 +940,19 @@ i2c_status_e i2c_master_read(i2c_t *obj, uint8_t dev_address, uint8_t *data, uin
932940
#endif
933941

934942
#if defined(I2C_OTHER_FRAME)
935-
if (HAL_I2C_Master_Seq_Receive_IT(&(obj->handle), dev_address, data, size, XferOptions) == HAL_OK) {
943+
while (HAL_I2C_Master_Seq_Receive_IT(&(obj->handle), dev_address, data, size, XferOptions) == HAL_BUSY) {
936944
#else
937-
if (HAL_I2C_Master_Receive_IT(&(obj->handle), dev_address, data, size) == HAL_OK) {
945+
while (HAL_I2C_Master_Receive_IT(&(obj->handle), dev_address, data, size) == HAL_BUSY) {
938946
#endif
947+
// Ensure i2c ready
948+
delta = (HAL_GetTick() - tickstart);
949+
if (delta > I2C_TIMEOUT_TICK) {
950+
ret = I2C_BUSY;
951+
break;
952+
}
953+
}
954+
if (ret == I2C_OK) {
955+
tickstart = HAL_GetTick();
939956
// wait for transfer completion
940957
while ((HAL_I2C_GetState(&(obj->handle)) != HAL_I2C_STATE_READY) && (delta < I2C_TIMEOUT_TICK)) {
941958
delta = (HAL_GetTick() - tickstart);

0 commit comments

Comments
 (0)