diff --git a/drivers/serial/Kconfig.nrfx b/drivers/serial/Kconfig.nrfx index 292c993fe22..44cafe7cedf 100644 --- a/drivers/serial/Kconfig.nrfx +++ b/drivers/serial/Kconfig.nrfx @@ -63,6 +63,9 @@ config UART_ASYNC_TX_CACHE_SIZE in RAM, because EasyDMA in UARTE peripherals can only transfer data from RAM. +config UART_NRFX_UARTE_DIRECT_ISR + bool "Use direct ISR" + config UART_NRFX_UARTE_SPURIOUS_RXTO_WORKAROUND bool help diff --git a/drivers/serial/uart_nrfx_uarte.c b/drivers/serial/uart_nrfx_uarte.c index 4cae1e1886b..16c27ca7ffe 100644 --- a/drivers/serial/uart_nrfx_uarte.c +++ b/drivers/serial/uart_nrfx_uarte.c @@ -2449,11 +2449,30 @@ static int uarte_instance_init(const struct device *dev, return pm_device_driver_init(dev, uarte_nrfx_pm_action); } -#define UARTE_IRQ_CONFIGURE(idx, isr_handler) \ - do { \ - IRQ_CONNECT(DT_IRQN(UARTE(idx)), DT_IRQ(UARTE(idx), priority), \ - isr_handler, DEVICE_DT_GET(UARTE(idx)), 0); \ - irq_enable(DT_IRQN(UARTE(idx))); \ +#define UARTE_GET_ISR(idx) \ + COND_CODE_1(CONFIG_UART_##idx##_ASYNC, (uarte_nrfx_isr_async), (uarte_nrfx_isr_int)) + +/* Declare interrupt handler for direct ISR. */ +#define UARTE_DIRECT_ISR_DECLARE(idx) \ + IF_ENABLED(CONFIG_UART_NRFX_UARTE_DIRECT_ISR, ( \ + ISR_DIRECT_DECLARE(uarte_##idx##_direct_isr) \ + { \ + ISR_DIRECT_PM(); \ + UARTE_GET_ISR(idx)(DEVICE_DT_GET(UARTE(idx))); \ + return 1; \ + } \ + )) + +/* Depending on configuration standard or direct IRQ is connected. */ +#define UARTE_IRQ_CONNECT(idx, irqn, prio) \ + COND_CODE_1(CONFIG_UART_NRFX_UARTE_DIRECT_ISR, \ + (IRQ_DIRECT_CONNECT(irqn, prio, uarte_##idx##_direct_isr, 0)), \ + (IRQ_CONNECT(irqn, prio, UARTE_GET_ISR(idx), DEVICE_DT_GET(UARTE(idx)), 0))) + +#define UARTE_IRQ_CONFIGURE(idx) \ + do { \ + UARTE_IRQ_CONNECT(idx, DT_IRQN(UARTE(idx)), DT_IRQ(UARTE(idx), priority)); \ + irq_enable(DT_IRQN(UARTE(idx))); \ } while (false) /* Low power mode is used when disable_rx is not defined or in async mode if @@ -2602,11 +2621,10 @@ static int uarte_instance_init(const struct device *dev, .precision = NRF_CLOCK_CONTROL_PRECISION_DEFAULT,\ },)) \ }; \ + UARTE_DIRECT_ISR_DECLARE(idx) \ static int uarte_##idx##_init(const struct device *dev) \ { \ - COND_CODE_1(CONFIG_UART_##idx##_ASYNC, \ - (UARTE_IRQ_CONFIGURE(idx, uarte_nrfx_isr_async);), \ - (UARTE_IRQ_CONFIGURE(idx, uarte_nrfx_isr_int);)) \ + UARTE_IRQ_CONFIGURE(idx); \ return uarte_instance_init( \ dev, \ IS_ENABLED(CONFIG_UART_##idx##_INTERRUPT_DRIVEN)); \