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
82 changes: 82 additions & 0 deletions drivers/serial/uart_nrfx_uarte.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,27 @@
*/
#define UARTE_ANY_HIGH_SPEED (UARTE_FOR_EACH_INSTANCE(INSTANCE_IS_HIGH_SPEED, (||), (0)))

#define UARTE_PINS_CROSS_DOMAIN(unused, prefix, idx, _) \
COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(UARTE(prefix##idx)), \

Check notice on line 152 in drivers/serial/uart_nrfx_uarte.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/serial/uart_nrfx_uarte.c:152 -#define UARTE_PINS_CROSS_DOMAIN(unused, prefix, idx, _) \ +#define UARTE_PINS_CROSS_DOMAIN(unused, prefix, idx, _) \
(UARTE_PROP(idx, cross_domain_pins_supported)), \
(0))

#if UARTE_FOR_EACH_INSTANCE(UARTE_PINS_CROSS_DOMAIN, (||), (0))
#include <hal/nrf_gpio.h>
/* Certain UARTE instances support usage of cross domain pins in form of dedicated pins on
* a port different from the default one.
*/
#define UARTE_CROSS_DOMAIN_PINS_SUPPORTED 1
#endif

#if UARTE_CROSS_DOMAIN_PINS_SUPPORTED && defined(CONFIG_NRF_SYS_EVENT)
#include <nrf_sys_event.h>
/* To use cross domain pins, constant latency mode needs to be applied, which is
* handled via nrf_sys_event requests.
*/
#define UARTE_CROSS_DOMAIN_PINS_HANDLE 1
#endif

#ifdef UARTE_ANY_CACHE
/* uart120 instance does not retain BAUDRATE register when ENABLE=0. When this instance
* is used then baudrate must be set after enabling the peripheral and not before.
Expand Down Expand Up @@ -371,6 +392,10 @@
#endif
uint8_t *poll_out_byte;
uint8_t *poll_in_byte;
#if UARTE_CROSS_DOMAIN_PINS_SUPPORTED
bool cross_domain;
int8_t default_port;
#endif
};

/* Using Macro instead of static inline function to handle NO_OPTIMIZATIONS case
Expand Down Expand Up @@ -444,6 +469,32 @@
nrf_uarte_disable(get_uarte_instance(dev));
}

#if UARTE_CROSS_DOMAIN_PINS_SUPPORTED
static bool uarte_has_cross_domain_connection(const struct uarte_nrfx_config *config)
{
const struct pinctrl_dev_config *pcfg = config->pcfg;
const struct pinctrl_state *state;
int ret;

ret = pinctrl_lookup_state(pcfg, PINCTRL_STATE_DEFAULT, &state);
if (ret < 0) {
LOG_ERR("Unable to read pin state");
return false;
}

for (uint8_t i = 0U; i < state->pin_cnt; i++) {
uint32_t pin = NRF_GET_PIN(state->pins[i]);

if ((pin != NRF_PIN_DISCONNECTED) &&
(nrf_gpio_pin_port_number_extract(&pin) != config->default_port)) {
return true;
}
}

return false;
}
#endif

#if defined(UARTE_ANY_NONE_ASYNC) && !defined(CONFIG_UART_NRFX_UARTE_NO_IRQ)
/**
* @brief Interrupt service routine.
Expand Down Expand Up @@ -727,6 +778,19 @@
#ifdef CONFIG_SOC_NRF54H20_GPD
nrf_gpd_retain_pins_set(config->pcfg, false);
#endif
#if UARTE_CROSS_DOMAIN_PINS_SUPPORTED
if (config->cross_domain && uarte_has_cross_domain_connection(config)) {
#if UARTE_CROSS_DOMAIN_PINS_HANDLE
int err;

err = nrf_sys_event_request_global_constlat();
(void)err;
__ASSERT_NO_MSG(err >= 0);
#else
__ASSERT(false, "NRF_SYS_EVENT needs to be enabled to use cross domain pins.\n");
#endif
}
#endif
#if UARTE_BAUDRATE_RETENTION_WORKAROUND
nrf_uarte_baudrate_set(uarte,
COND_CODE_1(CONFIG_UART_USE_RUNTIME_CONFIGURE,
Expand Down Expand Up @@ -2411,6 +2475,19 @@
#ifdef CONFIG_SOC_NRF54H20_GPD
nrf_gpd_retain_pins_set(cfg->pcfg, true);
#endif
#if UARTE_CROSS_DOMAIN_PINS_SUPPORTED
if (cfg->cross_domain && uarte_has_cross_domain_connection(cfg)) {
#if UARTE_CROSS_DOMAIN_PINS_HANDLE
int err;

err = nrf_sys_event_release_global_constlat();
(void)err;
__ASSERT_NO_MSG(err >= 0);
#else
__ASSERT(false, "NRF_SYS_EVENT needs to be enabled to use cross domain pins.\n");
#endif
}
#endif

nrf_uarte_disable(uarte);

Expand Down Expand Up @@ -2698,6 +2775,11 @@
.accuracy = 0, \
.precision = NRF_CLOCK_CONTROL_PRECISION_DEFAULT,\
},)) \
IF_ENABLED(UARTE_PINS_CROSS_DOMAIN(_, /*empty*/, idx, _), \
(.cross_domain = true, \
.default_port = \
DT_PROP_OR(DT_PHANDLE(UARTE(idx), \
default_gpio_port), port, -1),)) \
}; \
UARTE_DIRECT_ISR_DECLARE(idx) \
static int uarte_##idx##_init(const struct device *dev) \
Expand All @@ -2719,7 +2801,7 @@
UARTE_INIT_LEVEL(idx), \
UARTE_INIT_PRIO(idx), \
&uart_nrfx_uarte_driver_api)

Check notice on line 2804 in drivers/serial/uart_nrfx_uarte.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/serial/uart_nrfx_uarte.c:2804 - (PM_DEVICE_ISR_SAFE), (0)))))) \ - -#define UART_NRF_UARTE_DEVICE(idx) \ - NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(UARTE(idx)); \ - UARTE_INT_DRIVEN(idx); \ - PINCTRL_DT_DEFINE(UARTE(idx)); \ + (PM_DEVICE_ISR_SAFE), (0)))))) + +#define UART_NRF_UARTE_DEVICE(idx) \ + NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(UARTE(idx)); \ + UARTE_INT_DRIVEN(idx); \ + PINCTRL_DT_DEFINE(UARTE(idx)); \ IF_ENABLED(CONFIG_UART_##idx##_ASYNC, ( \ static uint8_t \ uarte##idx##_tx_cache[CONFIG_UART_ASYNC_TX_CACHE_SIZE] \ DMM_MEMORY_SECTION(UARTE(idx)); \ static uint8_t uarte##idx##_flush_buf[UARTE_HW_RX_FIFO_SIZE] \ DMM_MEMORY_SECTION(UARTE(idx)); \ - struct uarte_async_cb uarte##idx##_async;)) \ - static uint8_t uarte##idx##_poll_out_byte DMM_MEMORY_SECTION(UARTE(idx));\ - static uint8_t uarte##idx##_poll_in_byte DMM_MEMORY_SECTION(UARTE(idx)); \ - static struct uarte_nrfx_data uarte_##idx##_data = { \ - IF_ENABLED(CONFIG_UART_USE_RUNTIME_CONFIGURE, \ - (.uart_config = UARTE_CONFIG(idx),)) \ - IF_ENABLED(CONFIG_UART_##idx##_ASYNC, \ - (.async = &uarte##idx##_async,)) \ - IF_ENABLED(CONFIG_UART_##idx##_INTERRUPT_DRIVEN, \ - (.int_driven = &uarte##idx##_int_driven,)) \ - }; \ + struct uarte_async_cb uarte##idx##_async;)) \ + static uint8_t uarte##idx##_poll_out_byte DMM_MEMORY_SECTION(UARTE(idx)); \ + static uint8_t uarte##idx##_poll_in_byte DMM_MEMORY_SECTION(UARTE(idx)); \ + static struct uarte_nrfx_data uarte_##idx##_data = {IF_ENABLED(CONFIG_UART_USE_RUNTIME_CONFIGURE, \ + (.uart_config = UARTE_CONFIG(idx),)) \ + IF_ENABLED(CONFIG_UART_##idx##_ASYNC, \ + (.async = &uarte##idx##_async,)) \ + IF_ENABLED(CONFIG_UART_##idx##_INTERRUPT_DRIVEN, \ + (.int_driven = &uarte##idx##_int_driven,)) }; \ COND_CODE_1(CONFIG_UART_USE_RUNTIME_CONFIGURE, (), \ (BUILD_ASSERT(UARTE_GET_BAUDRATE(idx) > 0, \ - "Unsupported baudrate");)) \ - static const struct uarte_nrfx_config uarte_##idx##z_config = { \ - COND_CODE_1(CONFIG_UART_USE_RUNTIME_CONFIGURE, \ + "Unsupported baudrate");)) \ + static const struct uarte_nrfx_config uarte_##idx##z_config = {COND_CODE_1(CONFIG_UART_USE_RUNTIME_CONFIGURE, \ (.clock_freq = NRF_PERIPH_GET_FREQUENCY(UARTE(idx)),), \ (IF_ENABLED(UARTE_HAS_FRAME_TIMEOUT, \ (.baudrate = UARTE_PROP(idx, current_speed),)) \ .nrf_baudrate = UARTE_GET_BAUDRATE(idx), \ - .hw_config = UARTE_NRF_CONFIG(idx),)) \ - .pcfg = PINCTRL_DT_DEV_CONFIG_GET(UARTE(idx)), \ - .uarte_regs = _CONCAT(NRF_UARTE, idx), \ - IF_ENABLED(CONFIG_HAS_NORDIC_DMM, \ - (.mem_reg = DMM_DEV_TO_REG(UARTE(idx)),)) \ - .flags = \ - (IS_ENABLED(CONFIG_UART_##idx##_ENHANCED_POLL_OUT) ? \ - UARTE_CFG_FLAG_PPI_ENDTX : 0) | \ - (IS_ENABLED(CONFIG_UART_##idx##_NRF_HW_ASYNC) ? \ - UARTE_CFG_FLAG_HW_BYTE_COUNTING : 0) | \ - (!IS_ENABLED(CONFIG_HAS_NORDIC_DMM) ? 0 : \ - (UARTE_IS_CACHEAB
#define UARTE_INT_DRIVEN(idx) \
IF_ENABLED(CONFIG_UART_##idx##_INTERRUPT_DRIVEN, \
(static uint8_t uarte##idx##_tx_buffer \
Expand Down
102 changes: 93 additions & 9 deletions drivers/spi/spi_nrfx_spim.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@
#define SPI_BUFFER_IN_RAM 1
#endif

/*
* We use NODELABEL here because the nrfx API requires us to call
* functions which are named according to SoC peripheral instance
* being operated on. Since DT_INST() makes no guarantees about that,
* it won't work.
*/
#define SPIM(idx) DT_NODELABEL(spi##idx)
#define SPIM_PROP(idx, prop) DT_PROP(SPIM(idx), prop)
#define SPIM_HAS_PROP(idx, prop) DT_NODE_HAS_PROP(SPIM(idx), prop)

Check notice on line 55 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:55 -#define SPIM(idx) DT_NODELABEL(spi##idx) -#define SPIM_PROP(idx, prop) DT_PROP(SPIM(idx), prop) -#define SPIM_HAS_PROP(idx, prop) DT_NODE_HAS_PROP(SPIM(idx), prop) +#define SPIM(idx) DT_NODELABEL(spi##idx) +#define SPIM_PROP(idx, prop) DT_PROP(SPIM(idx), prop) +#define SPIM_HAS_PROP(idx, prop) DT_NODE_HAS_PROP(SPIM(idx), prop)
#if defined(CONFIG_CLOCK_CONTROL_NRF_HSFLL_GLOBAL)
#define SPIM_REQUESTS_CLOCK(node) \
DT_NODE_HAS_COMPAT(DT_CLOCKS_CTLR(node), nordic_nrf_hsfll_global)
Expand All @@ -59,6 +69,28 @@
#define SPIM_REQUESTS_CLOCK(node) 0
#endif

#define SPIM_PINS_CROSS_DOMAIN(unused, prefix, idx, _) \
COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(SPIM(prefix##idx)), \

Check notice on line 73 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:73 -#define SPIM_PINS_CROSS_DOMAIN(unused, prefix, idx, _) \ +#define SPIM_PINS_CROSS_DOMAIN(unused, prefix, idx, _) \
(SPIM_PROP(idx, cross_domain_pins_supported)), \
(0))

#if NRFX_FOREACH_PRESENT(SPIM, SPIM_PINS_CROSS_DOMAIN, (||), (0))
#include <hal/nrf_gpio.h>
/* Certain SPIM instances support usage of cross domain pins in form of dedicated pins on
* a port different from the default one.
*/
#define SPIM_CROSS_DOMAIN_SUPPORTED 1
#endif

#if SPIM_CROSS_DOMAIN_SUPPORTED && defined(CONFIG_NRF_SYS_EVENT)
#include <nrf_sys_event.h>
/* To use cross domain pins, constant latency mode needs to be applied, which is
* handled via nrf_sys_event requests.
*/
#define SPIM_CROSS_DOMAIN_PINS_HANDLE 1
#endif


Check notice on line 93 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:93 -
struct spi_nrfx_data {
struct spi_context ctx;
const struct device *dev;
Expand Down Expand Up @@ -98,6 +130,10 @@
const struct device *clk_dev;
struct nrf_clock_spec clk_spec;
#endif
#if SPIM_CROSS_DOMAIN_SUPPORTED
bool cross_domain;
int8_t default_port;
#endif
};

static void event_handler(const nrfx_spim_evt_t *p_event, void *p_context);
Expand Down Expand Up @@ -147,6 +183,32 @@
#endif
}

#if SPIM_CROSS_DOMAIN_SUPPORTED
static bool spim_has_cross_domain_connection(const struct spi_nrfx_config *config)
{
const struct pinctrl_dev_config *pcfg = config->pcfg;
const struct pinctrl_state *state;
int ret;

ret = pinctrl_lookup_state(pcfg, PINCTRL_STATE_DEFAULT, &state);
if (ret < 0) {
LOG_ERR("Unable to read pin state");
return false;
}

for (uint8_t i = 0U; i < state->pin_cnt; i++) {
uint32_t pin = NRF_GET_PIN(state->pins[i]);

if ((pin != NRF_PIN_DISCONNECTED) &&
(nrf_gpio_pin_port_number_extract(&pin) != config->default_port)) {
return true;
}
}

return false;
}
#endif

static inline void finalize_spi_transaction(const struct device *dev, bool deactivate_cs)
{
struct spi_nrfx_data *dev_data = dev->data;
Expand Down Expand Up @@ -688,6 +750,19 @@
#ifdef CONFIG_SOC_NRF54H20_GPD
nrf_gpd_retain_pins_set(dev_config->pcfg, false);
#endif
#if SPIM_CROSS_DOMAIN_SUPPORTED
if (dev_config->cross_domain && spim_has_cross_domain_connection(dev_config)) {
#if SPIM_CROSS_DOMAIN_PINS_HANDLE
int err;

err = nrf_sys_event_request_global_constlat();
(void)err;
__ASSERT_NO_MSG(err >= 0);
#else
__ASSERT(false, "NRF_SYS_EVENT needs to be enabled to use cross domain pins.\n");
#endif
}
#endif

return IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME) ? request_clock(dev) : 0;
}
Expand All @@ -711,6 +786,19 @@
#ifdef CONFIG_SOC_NRF54H20_GPD
nrf_gpd_retain_pins_set(dev_config->pcfg, true);
#endif
#if SPIM_CROSS_DOMAIN_SUPPORTED
if (dev_config->cross_domain && spim_has_cross_domain_connection(dev_config)) {
#if SPIM_CROSS_DOMAIN_PINS_HANDLE
int err;

err = nrf_sys_event_request_global_constlat();
(void)err;
__ASSERT_NO_MSG(err >= 0);
#else
__ASSERT(false, "NRF_SYS_EVENT needs to be enabled to use cross domain pins.\n");
#endif
}
#endif

(void)pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_SLEEP);
}
Expand Down Expand Up @@ -790,15 +878,6 @@
return 0;
}

/*
* We use NODELABEL here because the nrfx API requires us to call
* functions which are named according to SoC peripheral instance
* being operated on. Since DT_INST() makes no guarantees about that,
* it won't work.
*/
#define SPIM(idx) DT_NODELABEL(spi##idx)
#define SPIM_PROP(idx, prop) DT_PROP(SPIM(idx), prop)
#define SPIM_HAS_PROP(idx, prop) DT_NODE_HAS_PROP(SPIM(idx), prop)
#define SPIM_MEM_REGION(idx) DT_PHANDLE(SPIM(idx), memory_regions)

#define SPI_NRFX_SPIM_EXTENDED_CONFIG(idx) \
Expand Down Expand Up @@ -890,6 +969,11 @@
.clk_spec = { \
.frequency = NRF_CLOCK_CONTROL_FREQUENCY_MAX, \
},)) \
IF_ENABLED(SPIM_PINS_CROSS_DOMAIN(_, /*empty*/, idx, _), \
(.cross_domain = true, \
.default_port = \
DT_PROP_OR(DT_PHANDLE(SPIM(idx), \
default_gpio_port), port, -1),)) \
}; \
BUILD_ASSERT(!SPIM_HAS_PROP(idx, wake_gpios) || \
!(DT_GPIO_FLAGS(SPIM(idx), wake_gpios) & GPIO_ACTIVE_LOW),\
Expand All @@ -903,7 +987,7 @@
&spi_##idx##z_config, \
POST_KERNEL, SPIM_INIT_PRIORITY(idx), \
&spi_nrfx_driver_api)

Check notice on line 990 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:990 -#define SPI_NRFX_SPIM_DEFINE(idx) \ - NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(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)); \ + 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] \ SPIM_MEMORY_SECTION(idx); \ static uint8_t spim_##idx##_rx_buffer \ [CONFIG_SPI_NRFX_RAM_BUFFER_SIZE] \ - SPIM_MEMORY_SECTION(idx);)) \ - static struct spi_nrfx_data spi_##idx##_data = { \ + SPIM_MEMORY_SECTION(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)); \ - static const struct spi_nrfx_config spi_##idx##z_config = { \ - .spim = { \ - .p_reg = (NRF_SPIM_Type *)DT_REG_ADDR(SPIM(idx)), \ - .drv_inst_idx = NRFX_SPIM##idx##_INST_IDX, \ - }, \ - .max_freq = SPIM_PROP(idx, max_frequency), \ - .def_config = { \ - .skip_gpio_cfg = true, \ - .skip_psel_cfg = true, \ - .ss_pin = NRF_SPIM_PIN_NOT_CONNECTED, \ - .orc = SPIM_PROP(idx, overrun_character), \ - SPI_NRFX_SPIM_EXTENDED_CONFIG(idx) \ - }, \ - .irq_connect = irq_connect##idx, \ - .pcfg = PINCTRL_DT_DEV_CONFIG_GET(SPIM(idx)), \ - .max_chunk_len = BIT_MASK(SPIM_PROP(idx, easydma_maxcnt_bits)),\ - COND_CODE_1(CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58, \ + .rx_buffer = spim_##idx##_rx_buffer,)) .dev = \ + DEVICE_DT_GET(SPIM(idx)), \ + .busy = false, \ + }; \ + PINCTRL_DT_DEFINE(SPIM(idx)); \ + static const struct spi_nrfx_config spi_##idx##z_config = \ + {.spim = \ + { \ + .p_reg = (NRF_SPIM_Type *)DT_REG_ADDR(SPIM(idx)), \ + .drv_inst_idx = NRFX_SPIM##idx##_INST_IDX, \ +
#define SPIM_MEMORY_SECTION(idx) \
COND_CODE_1(SPIM_HAS_PROP(idx, memory_regions), \
(__attribute__((__section__(LINKER_DT_NODE_REGION_NAME( \
Expand Down
Loading
Loading