drivers: i2c_nrfx_twim: Use concatenation buffer by default

Issue an error logging message when the i2c_nrfx_twim driver lacks
a concatenation buffer big enough to properly handle a call to
i2c_burst_write() function, to give the user a hint what is wrong.

Also use by default a 16-bytes long concatenation buffer for every
instance of the i2c_nrfx_twim driver. Such value should cover most
of the simple uses of the i2c_burst_write() function, like those
in the stmemsc sensor drivers, and when a longer buffer is needed,
the user will be provided with the above message pointing to the
property that should be adjusted.

Signed-off-by: Andrzej Głąbek <andrzej.glabek@nordicsemi.no>
This commit is contained in:
Andrzej Głąbek 2021-09-20 11:31:01 +02:00 committed by Carles Cufí
commit 99ce264df7
2 changed files with 24 additions and 17 deletions

View file

@ -65,17 +65,17 @@ static int i2c_nrfx_twim_transfer(const struct device *dev,
break; break;
} }
/* Merge this fragment with the next if we have a buffer, this /* This fragment needs to be merged with the next one if:
* isn't the last fragment, it doesn't end a bus transaction, * - it is not the last fragment
* the next one doesn't start a bus transaction, and the * - it does not end a bus transaction
* direction of the next fragment is the same as this one. * - the next fragment does not start a bus transaction
* - the direction of the next fragment is the same as this one
*/ */
bool concat_next = (concat_buf_size > 0) bool concat_next = ((i + 1) < num_msgs)
&& ((i + 1) < num_msgs) && !(msgs[i].flags & I2C_MSG_STOP)
&& !(msgs[i].flags & I2C_MSG_STOP) && !(msgs[i + 1].flags & I2C_MSG_RESTART)
&& !(msgs[i + 1].flags & I2C_MSG_RESTART) && ((msgs[i].flags & I2C_MSG_READ)
&& ((msgs[i].flags & I2C_MSG_READ) == (msgs[i + 1].flags & I2C_MSG_READ));
== (msgs[i + 1].flags & I2C_MSG_READ));
/* If we need to concatenate the next message, or we've /* If we need to concatenate the next message, or we've
* already committed to concatenate this message, add it to * already committed to concatenate this message, add it to
@ -83,8 +83,13 @@ static int i2c_nrfx_twim_transfer(const struct device *dev,
*/ */
if (concat_next || (concat_len != 0)) { if (concat_next || (concat_len != 0)) {
if ((concat_len + msgs[i].len) > concat_buf_size) { if ((concat_len + msgs[i].len) > concat_buf_size) {
LOG_ERR("concat-buf overflow: %u + %u > %u", LOG_ERR("Need to use concatenation buffer and "
concat_len, msgs[i].len, concat_buf_size); "provided size is insufficient "
"(%u + %u > %u). "
"Adjust the zephyr,concat-buf-size "
"property in the \"%s\" node.",
concat_len, msgs[i].len,
concat_buf_size, dev->name);
ret = -ENOSPC; ret = -ENOSPC;
break; break;
} }

View file

@ -29,12 +29,14 @@ properties:
zephyr,concat-buf-size: zephyr,concat-buf-size:
type: int type: int
required: false required: false
description: default: 16
If concatenation buffer size is set, then multiple messages in the description: |
same direction will be concatenated into single transfers as long Size of a concatenation buffer that the driver is to use for merging
as there is space in buffer and no restart or stop flag is set. multiple same direction I2C messages that have no RESTART or STOP
flag between them (see e.g. the i2c_burst_write() function) into one
transfer on the bus.
This property must be provided when interacting with devices like This property must be provided when interacting with devices like
the SSD1306 display that cannot tolerate a repeated start and the SSD1306 display that cannot tolerate a repeated start and
address appearing on the bus between message fragments. For many address appearing on the bus between message fragments. For many
devices a concatenation buffer is not necessary. devices a concatenation buffer is not necessary.