Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 37 additions & 38 deletions drivers/spi/spi_nrfx_spim.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#ifdef CONFIG_SOC_NRF54H20_GPD
#include <nrf/gpd.h>
#endif
#include <dmm.h>
#ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58
#include <nrfx_ppi.h>
#endif
Expand Down Expand Up @@ -123,9 +124,6 @@
#endif
uint32_t wake_pin;
nrfx_gpiote_t wake_gpiote;
#ifdef CONFIG_DCACHE
uint32_t mem_attr;
#endif
#ifdef USE_CLOCK_REQUESTS
const struct device *clk_dev;
struct nrf_clock_spec clk_spec;
Expand All @@ -134,6 +132,7 @@
bool cross_domain;
int8_t default_port;
#endif
void *mem_reg;
};

static void event_handler(const nrfx_spim_evt_t *p_event, void *p_context);
Expand Down Expand Up @@ -504,11 +503,6 @@
}

memcpy(dev_data->tx_buffer, tx_buf, chunk_len);
#ifdef CONFIG_DCACHE
if (dev_config->mem_attr & DT_MEM_CACHEABLE) {
sys_cache_data_flush_range(dev_data->tx_buffer, chunk_len);
}
#endif
tx_buf = dev_data->tx_buffer;
}

Expand All @@ -525,10 +519,20 @@

dev_data->chunk_len = chunk_len;

xfer.p_tx_buffer = tx_buf;
xfer.tx_length = spi_context_tx_buf_on(ctx) ? chunk_len : 0;
xfer.p_rx_buffer = rx_buf;
xfer.rx_length = spi_context_rx_buf_on(ctx) ? chunk_len : 0;
xfer.tx_length = spi_context_tx_buf_on(ctx) ? chunk_len : 0;
xfer.rx_length = spi_context_rx_buf_on(ctx) ? chunk_len : 0;

error = dmm_buffer_out_prepare(dev_config->mem_reg, tx_buf, xfer.tx_length,
(void **)&xfer.p_tx_buffer);
if (error != 0) {
goto out_alloc_failed;
}

error = dmm_buffer_in_prepare(dev_config->mem_reg, rx_buf, xfer.rx_length,
(void **)&xfer.p_rx_buffer);
if (error != 0) {
goto in_alloc_failed;
}

#ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58
if (xfer.rx_length == 1 && xfer.tx_length <= 1) {
Expand All @@ -551,6 +555,13 @@
anomaly_58_workaround_clear(dev_data);
#endif
}

/* On nrfx_spim_xfer() error */
dmm_buffer_in_release(dev_config->mem_reg, rx_buf, xfer.rx_length,
(void **)&xfer.p_rx_buffer);
in_alloc_failed:
dmm_buffer_out_release(dev_config->mem_reg, (void **)&xfer.p_tx_buffer);
out_alloc_failed:
}

finish_transaction(dev, error);
Expand All @@ -560,9 +571,7 @@
{
const struct device *dev = p_context;
struct spi_nrfx_data *dev_data = dev->data;
#ifdef CONFIG_DCACHE
const struct spi_nrfx_config *dev_config = dev->config;
#endif

if (p_event->type == NRFX_SPIM_EVENT_DONE) {
/* Chunk length is set to 0 when a transaction is aborted
Expand All @@ -576,15 +585,21 @@
#ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58
anomaly_58_workaround_clear(dev_data);
#endif

if (spi_context_tx_buf_on(&dev_data->ctx)) {
dmm_buffer_out_release(dev_config->mem_reg,
(void **)p_event->xfer_desc.p_tx_buffer);
}

if (spi_context_rx_buf_on(&dev_data->ctx)) {
dmm_buffer_in_release(dev_config->mem_reg, dev_data->ctx.rx_buf,
dev_data->chunk_len, p_event->xfer_desc.p_rx_buffer);
}

Check notice on line 597 in drivers/spi/spi_nrfx_spim.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/spi/spi_nrfx_spim.c:597 - dev_data->chunk_len, p_event->xfer_desc.p_rx_buffer); + dev_data->chunk_len, p_event->xfer_desc.p_rx_buffer);

#ifdef SPI_BUFFER_IN_RAM
if (spi_context_rx_buf_on(&dev_data->ctx) &&
p_event->xfer_desc.p_rx_buffer != NULL &&
p_event->xfer_desc.p_rx_buffer != dev_data->ctx.rx_buf) {
#ifdef CONFIG_DCACHE
if (dev_config->mem_attr & DT_MEM_CACHEABLE) {
sys_cache_data_invd_range(dev_data->rx_buffer, dev_data->chunk_len);
}
#endif
(void)memcpy(dev_data->ctx.rx_buf,
dev_data->rx_buffer,
dev_data->chunk_len);
Expand Down Expand Up @@ -878,8 +893,6 @@
return 0;
}

#define SPIM_MEM_REGION(idx) DT_PHANDLE(SPIM(idx), memory_regions)

#define SPI_NRFX_SPIM_EXTENDED_CONFIG(idx) \
IF_ENABLED(NRFX_SPIM_EXTENDED_ENABLED, \
(.dcx_pin = NRF_SPIM_PIN_NOT_CONNECTED, \
Expand All @@ -888,13 +901,6 @@
()) \
))

#define SPIM_GET_MEM_ATTR(idx) \
COND_CODE_1(SPIM_HAS_PROP(idx, memory_regions), \
(COND_CODE_1(DT_NODE_HAS_PROP(SPIM_MEM_REGION(idx), zephyr_memory_attr), \
(DT_PROP(SPIM_MEM_REGION(idx), zephyr_memory_attr)), \
(0))), \
(0))

/* Fast instances depend on the global HSFLL clock controller (as they need
* to request the highest frequency from it to operate correctly), so they
* must be initialized after that controller driver, hence the default SPI
Expand All @@ -921,10 +927,10 @@
IF_ENABLED(SPI_BUFFER_IN_RAM, \
(static uint8_t spim_##idx##_tx_buffer \
[CONFIG_SPI_NRFX_RAM_BUFFER_SIZE] \
SPIM_MEMORY_SECTION(idx); \
DMM_MEMORY_SECTION(SPIM(idx)); \
static uint8_t spim_##idx##_rx_buffer \
[CONFIG_SPI_NRFX_RAM_BUFFER_SIZE] \
SPIM_MEMORY_SECTION(idx);)) \
DMM_MEMORY_SECTION(SPIM(idx));)) \
static struct spi_nrfx_data spi_##idx##_data = { \
IF_ENABLED(CONFIG_MULTITHREADING, \
(SPI_CONTEXT_INIT_LOCK(spi_##idx##_data, ctx),)) \
Expand All @@ -938,7 +944,7 @@
.busy = false, \
}; \
PINCTRL_DT_DEFINE(SPIM(idx)); \
static const struct spi_nrfx_config spi_##idx##z_config = { \

Check notice on line 947 in drivers/spi/spi_nrfx_spim.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/spi/spi_nrfx_spim.c:947 -#define SPI_NRFX_SPIM_DEFINE(idx) \ - NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(SPIM(idx)); \ - NRF_DT_CHECK_NODE_HAS_REQUIRED_MEMORY_REGIONS(SPIM(idx)); \ - static void irq_connect##idx(void) \ - { \ - IRQ_CONNECT(DT_IRQN(SPIM(idx)), DT_IRQ(SPIM(idx), priority), \ - nrfx_isr, nrfx_spim_##idx##_irq_handler, 0); \ - } \ +#define SPI_NRFX_SPIM_DEFINE(idx) \ + NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(SPIM(idx)); \ + NRF_DT_CHECK_NODE_HAS_REQUIRED_MEMORY_REGIONS(SPIM(idx)); \ + static void irq_connect##idx(void) \ + { \ + IRQ_CONNECT(DT_IRQN(SPIM(idx)), DT_IRQ(SPIM(idx), priority), nrfx_isr, \ + nrfx_spim_##idx##_irq_handler, 0); \ + } \ IF_ENABLED(SPI_BUFFER_IN_RAM, \ (static uint8_t spim_##idx##_tx_buffer \ [CONFIG_SPI_NRFX_RAM_BUFFER_SIZE] \ DMM_MEMORY_SECTION(SPIM(idx)); \ static uint8_t spim_##idx##_rx_buffer \ [CONFIG_SPI_NRFX_RAM_BUFFER_SIZE] \ - DMM_MEMORY_SECTION(SPIM(idx));)) \ - static struct spi_nrfx_data spi_##idx##_data = { \ + DMM_MEMORY_SECTION(SPIM(idx));)) \ + static struct spi_nrfx_data spi_##idx##_data = { \ IF_ENABLED(CONFIG_MULTITHREADING, \ - (SPI_CONTEXT_INIT_LOCK(spi_##idx##_data, ctx),)) \ - IF_ENABLED(CONFIG_MULTITHREADING, \ - (SPI_CONTEXT_INIT_SYNC(spi_##idx##_data, ctx),)) \ - SPI_CONTEXT_CS_GPIOS_INITIALIZE(SPIM(idx), ctx) \ - IF_ENABLED(SPI_BUFFER_IN_RAM, \ + (SPI_CONTEXT_INIT_LOCK(spi_##idx##_data, ctx),)) \ + IF_ENABLED(CONFIG_MULTITHREADING, \ + (SPI_CONTEXT_INIT_SYNC(spi_##idx##_data, ctx),)) SPI_CONTEXT_CS_GPIOS_INITIALIZE(SPIM(idx), \ + ctx) \ + IF_ENABLED(SPI_BUFFER_IN_RAM, \ (.tx_buffer = spim_##idx##_tx_buffer, \ - .rx_buffer = spim_##idx##_rx_buffer,)) \ - .dev = DEVICE_DT_GET(SPIM(idx)), \ - .busy = false, \ - }; \ - PINCTRL_DT_DEFINE(SPIM(idx)); \ + .rx_buffer = spim_##idx##_rx_buffer,)) .dev = \ + DEVICE_DT_GET(SPIM(idx)), \ + .busy = false, \ + }; \ + PINCTRL_DT_DEFINE(SPIM(idx)); \
.spim = { \
.p_reg = (NRF_SPIM_Type *)DT_REG_ADDR(SPIM(idx)), \
.drv_inst_idx = NRFX_SPIM##idx##_INST_IDX, \
Expand All @@ -961,8 +967,6 @@
.wake_pin = NRF_DT_GPIOS_TO_PSEL_OR(SPIM(idx), wake_gpios, \
WAKE_PIN_NOT_USED), \
.wake_gpiote = WAKE_GPIOTE_INSTANCE(SPIM(idx)), \
IF_ENABLED(CONFIG_DCACHE, \
(.mem_attr = SPIM_GET_MEM_ATTR(idx),)) \
IF_ENABLED(USE_CLOCK_REQUESTS, \
(.clk_dev = SPIM_REQUESTS_CLOCK(SPIM(idx)) \
? DEVICE_DT_GET(DT_CLOCKS_CTLR(SPIM(idx))) \
Expand All @@ -975,6 +979,7 @@
.default_port = \
DT_PROP_OR(DT_PHANDLE(SPIM(idx), \
default_gpio_port), port, -1),)) \
.mem_reg = DMM_DEV_TO_REG(SPIM(idx)), \
}; \
BUILD_ASSERT(!SPIM_HAS_PROP(idx, wake_gpios) || \
!(DT_GPIO_FLAGS(SPIM(idx), wake_gpios) & GPIO_ACTIVE_LOW),\
Expand All @@ -988,13 +993,7 @@
&spi_##idx##z_config, \
POST_KERNEL, SPIM_INIT_PRIORITY(idx), \
&spi_nrfx_driver_api)

Check notice on line 996 in drivers/spi/spi_nrfx_spim.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/spi/spi_nrfx_spim.c:996 - }; \ - BUILD_ASSERT(!SPIM_HAS_PROP(idx, wake_gpios) || \ - !(DT_GPIO_FLAGS(SPIM(idx), wake_gpios) & GPIO_ACTIVE_LOW),\ - "WAKE line must be configured as active high"); \ - PM_DEVICE_DT_DEFINE(SPIM(idx), spim_nrfx_pm_action); \ - SPI_DEVICE_DT_DEINIT_DEFINE(SPIM(idx), \ - spi_nrfx_init, \ - spi_nrfx_deinit, \ - PM_DEVICE_DT_GET(SPIM(idx)), \ - &spi_##idx##_data, \ - &spi_##idx##z_config, \ - POST_KERNEL, SPIM_INIT_PRIORITY(idx), \ - &spi_nrfx_driver_api) + }; \ + BUILD_ASSERT(!SPIM_HAS_PROP(idx, wake_gpios) || \ + !(DT_GPIO_FLAGS(SPIM(idx), wake_gpios) & GPIO_ACTIVE_LOW), \ + "WAKE line must be configured as active high"); \ + PM_DEVICE_DT_DEFINE(SPIM(idx), spim_nrfx_pm_action); \ + SPI_DEVICE_DT_DEINIT_DEFINE(SPIM(idx), spi_nrfx_init, spi_nrfx_deinit, \ + PM_DEVICE_DT_GET(SPIM(idx)), &spi_##idx##_data, \ + &spi_##idx##z_config, POST_KERNEL, SPIM_INIT_PRIORITY(idx), \ + &spi_nrfx_driver_api)
#define SPIM_MEMORY_SECTION(idx) \
COND_CODE_1(SPIM_HAS_PROP(idx, memory_regions), \
(__attribute__((__section__(LINKER_DT_NODE_REGION_NAME( \
SPIM_MEM_REGION(idx)))))), \
())

#define COND_NRF_SPIM_DEVICE(unused, prefix, i, _) \
IF_ENABLED(CONFIG_HAS_HW_NRF_SPIM##prefix##i, (SPI_NRFX_SPIM_DEFINE(prefix##i);))

Expand Down
4 changes: 2 additions & 2 deletions drivers/spi/spi_nrfx_spis.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,9 +243,9 @@ static int prepare_for_transfer(const struct device *dev,
return 0;

buffers_set_failed:
dmm_buffer_in_release(dev_config->mem_reg, rx_buf, rx_buf_len, rx_buf);
dmm_buffer_in_release(dev_config->mem_reg, rx_buf, rx_buf_len, dmm_rx_buf);
in_alloc_failed:
dmm_buffer_out_release(dev_config->mem_reg, (void *)tx_buf);
dmm_buffer_out_release(dev_config->mem_reg, (void *)dmm_tx_buf);
out_alloc_failed:
return err;
}
Expand Down
7 changes: 7 additions & 0 deletions tests/drivers/spi/spi_controller_peripheral/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,11 @@ config TESTED_SPI_MODE
2: CPOL 1 (Active low), CPHA 0 (leading)
3: CPOL 1 (Active low), CPHA 1 (trailing)

config PREALLOC_BUFFERS
bool "Preallocate buffers"
default y
help
Preallocate buffers used for transaction
using `memory-region` property.

source "Kconfig.zephyr"
9 changes: 6 additions & 3 deletions tests/drivers/spi/spi_controller_peripheral/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,12 @@ static struct k_poll_event async_evt_spim =
K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL, K_POLL_MODE_NOTIFY_ONLY, &async_sig_spim);

#define MEMORY_SECTION(node) \
COND_CODE_1(DT_NODE_HAS_PROP(node, memory_regions), \
(__attribute__((__section__( \
LINKER_DT_NODE_REGION_NAME(DT_PHANDLE(node, memory_regions)))))), \
COND_CODE_1(IS_ENABLED(CONFIG_PREALLOC_BUFFERS), \
(COND_CODE_1(DT_NODE_HAS_PROP(node, memory_regions), \
(__attribute__((__section__( \
LINKER_DT_NODE_REGION_NAME(DT_PHANDLE(node, \
memory_regions)))))), \
())), \
())

static uint8_t spim_buffer[32] MEMORY_SECTION(DT_BUS(DT_NODELABEL(dut_spi_dt)));
Expand Down
11 changes: 11 additions & 0 deletions tests/drivers/spi/spi_controller_peripheral/testcase.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,14 @@ tests:
- nrf54h20dk/nrf54h20/cpuppr
- nrf54l20pdk/nrf54l20/cpuapp
- ophelia4ev/nrf54l15/cpuapp

drivers.spi.direct_xfer:
extra_configs:
- CONFIG_SPI_NRFX_RAM_BUFFER_SIZE=0
filter: CONFIG_SOC_FAMILY_NORDIC_NRF

drivers.spi.direct_xfer.no_prealloc:
extra_configs:
- CONFIG_SPI_NRFX_RAM_BUFFER_SIZE=0
- CONFIG_PREALLOC_BUFFERS=n
filter: CONFIG_SOC_FAMILY_NORDIC_NRF
Loading