Skip to content

Commit

Permalink
drivers: i2c: add an option to skip auto-sending stop on last message
Browse files Browse the repository at this point in the history
The I2C transfer API has been recently changed to always automatically
set a STOP on the last message, which was well documented but
implemented only by few drivers.

Unfortunately, while documented, this is a change in the current
behavior and it turns out that some applications depended on it for some
complex operations.

Add a flag to temporarily restore the old behavior, buying time to fix
the application code depending on this.

Signed-off-by: Fabio Baltieri <[email protected]>
  • Loading branch information
fabiobaltieri committed Sep 11, 2024
1 parent 884a4e5 commit f21d2d2
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 2 deletions.
13 changes: 13 additions & 0 deletions drivers/i2c/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,19 @@ config I2C_CALLBACK
help
API and implementations of i2c_transfer_cb.

config I2C_ALLOW_NO_STOP_TRANSACTIONS
bool "Allows I2C transfers with no STOP on the last transaction [DEPRECATED]"
depends on !I2C_NRFX_TWI
depends on !I2C_NRFX_TWIM
depends on !I2C_STM32
depends on !I2C_GD32
depends on !I2C_ESP32
depends on !I2C_DW
help
Allow I2C transactions with no STOP on the last message. This is
unsupported and can leave the bus in an unexpected state. The option
will be removed in Zephyr 4.1.

config I2C_RTIO
bool "I2C RTIO API"
select EXPERIMENTAL
Expand Down
8 changes: 6 additions & 2 deletions include/zephyr/drivers/i2c.h
Original file line number Diff line number Diff line change
Expand Up @@ -801,7 +801,9 @@ static inline int z_impl_i2c_transfer(const struct device *dev,
return 0;
}

msgs[num_msgs - 1].flags |= I2C_MSG_STOP;
if (!IS_ENABLED(CONFIG_I2C_ALLOW_NO_STOP_TRANSACTIONS)) {
msgs[num_msgs - 1].flags |= I2C_MSG_STOP;
}

int res = api->transfer(dev, msgs, num_msgs, addr);

Expand Down Expand Up @@ -857,7 +859,9 @@ static inline int i2c_transfer_cb(const struct device *dev,
return 0;
}

msgs[num_msgs - 1].flags |= I2C_MSG_STOP;
if (!IS_ENABLED(CONFIG_I2C_ALLOW_NO_STOP_TRANSACTIONS)) {
msgs[num_msgs - 1].flags |= I2C_MSG_STOP;
}

return api->transfer_cb(dev, msgs, num_msgs, addr, cb, userdata);
}
Expand Down

0 comments on commit f21d2d2

Please sign in to comment.