drivers: i2c: i2c_nrfx_twim: Utilize memory-region prop from devicetree

This commit aligns TWIM shim to utilize memory-region property.
The memory-region is not required property that enables user
to specify placement of dma buffers in memory region.
It is done by assigning to memory-region property,
phandle to node with zephyr,memory-region and mimo-sram compatible.

When memory-region property is not specified for given
instance, buffer is placed in default RAM region with other data.

Signed-off-by: Adam Wojasinski <adam.wojasinski@nordicsemi.no>
This commit is contained in:
Adam Wojasinski 2023-07-14 15:51:38 +02:00 committed by Carles Cufí
commit 368acbe2d1
3 changed files with 26 additions and 31 deletions

View file

@ -13,6 +13,7 @@
#include <soc.h>
#include <nrfx_twim.h>
#include <zephyr/sys/util.h>
#include <zephyr/linker/devicetree_regions.h>
#include <zephyr/logging/log.h>
#include <zephyr/irq.h>
@ -68,6 +69,8 @@ static int i2c_nrfx_twim_transfer(const struct device *dev,
break;
}
bool dma_accessible = nrf_dma_accessible_check(&dev_config->twim, msgs[i].buf);
/* This fragment needs to be merged with the next one if:
* - it is not the last fragment
* - it does not end a bus transaction
@ -81,18 +84,21 @@ static int i2c_nrfx_twim_transfer(const struct device *dev,
== (msgs[i + 1].flags & I2C_MSG_READ));
/* If we need to concatenate the next message, or we've
* already committed to concatenate this message, add it to
* the buffer after verifying there's room.
* already committed to concatenate this message, or its buffer
* is not accessible by DMA, add it to the internal driver
* buffer after verifying there's room.
*/
if (concat_next || (msg_buf_used != 0)) {
if ((msg_buf_used + msgs[i].len) > buf_size) {
LOG_ERR("Need to use concatenation buffer and "
"provided size is insufficient "
if (concat_next || (msg_buf_used != 0) || !dma_accessible) {
if ((msg_buf_used + msgs[i].len) > msg_buf_size) {
LOG_ERR("Need to use the internal driver "
"buffer but its size is insufficient "
"(%u + %u > %u). "
"Adjust the zephyr,concat-buf-size "
"property in the \"%s\" node.",
"Adjust the zephyr,concat-buf-size or "
"zephyr,flash-buf-max-size property "
"(the one with greater value) in the "
"\"%s\" node.",
msg_buf_used, msgs[i].len,
buf_size, dev->name);
msg_buf_size, dev->name);
ret = -ENOSPC;
break;
}
@ -102,25 +108,6 @@ static int i2c_nrfx_twim_transfer(const struct device *dev,
msgs[i].len);
}
msg_buf_used += msgs[i].len;
/* TWIM peripherals cannot transfer data directly from
* flash. If a buffer located in flash is provided for
* a write transaction, its content must be copied to
* RAM before the transfer can be requested.
*/
} else if (!(msgs[i].flags & I2C_MSG_READ) &&
!nrfx_is_in_ram(msgs[i].buf)) {
if (msgs[i].len > dev_config->flash_buf_max_size) {
LOG_ERR("Cannot copy flash buffer of size: %u. "
"Adjust the zephyr,flash-buf-max-size "
"property in the \"%s\" node.",
msgs[i].len, dev->name);
ret = -EINVAL;
break;
}
memcpy(msg_buf, msgs[i].buf, msgs[i].len);
msg_buf_used = msgs[i].len;
}
if (concat_next) {
@ -376,6 +363,7 @@ static int i2c_nrfx_twim_init(const struct device *dev)
I2C_NRFX_TWIM_INVALID_FREQUENCY)
#define I2C(idx) DT_NODELABEL(i2c##idx)
#define I2C_HAS_PROP(idx, prop) DT_NODE_HAS_PROP(I2C(idx), prop)
#define I2C_FREQUENCY(idx) \
I2C_NRFX_TWIM_FREQUENCY(DT_PROP(I2C(idx), clock_frequency))
@ -403,7 +391,8 @@ static int i2c_nrfx_twim_init(const struct device *dev)
nrfx_isr, nrfx_twim_##idx##_irq_handler, 0); \
} \
IF_ENABLED(USES_MSG_BUF(idx), \
(static uint8_t twim_##idx##_msg_buf[MSG_BUF_SIZE(idx)];)) \
(static uint8_t twim_##idx##_msg_buf[MSG_BUF_SIZE(idx)] \
I2C_MEMORY_SECTION(idx);)) \
static struct i2c_nrfx_twim_data twim_##idx##_data = { \
.transfer_sync = Z_SEM_INITIALIZER( \
twim_##idx##_data.transfer_sync, 1, 1), \
@ -434,6 +423,12 @@ static int i2c_nrfx_twim_init(const struct device *dev)
CONFIG_I2C_INIT_PRIORITY, \
&i2c_nrfx_twim_driver_api)
#define I2C_MEMORY_SECTION(idx) \
COND_CODE_1(I2C_HAS_PROP(idx, memory_regions), \
(__attribute__((__section__(LINKER_DT_NODE_REGION_NAME( \
DT_PHANDLE(I2C(idx), memory_regions)))))), \
())
#ifdef CONFIG_HAS_HW_NRF_TWIM0
I2C_NRFX_TWIM_DEVICE(0);
#endif

View file

@ -23,7 +23,7 @@ description: |
compatible: "nordic,nrf-twim"
include: nordic,nrf-twi-common.yaml
include: ["nordic,nrf-twi-common.yaml", "memory-region.yaml"]
properties:
zephyr,concat-buf-size:

View file

@ -27,7 +27,7 @@ description: |
compatible: "nordic,nrf-twis"
include: nordic,nrf-twi-common.yaml
include: ["nordic,nrf-twi-common.yaml", "memory-region.yaml"]
properties:
address-0: