From caf03a0c22234f26ac89543bd216f68f7b71262d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Fri, 16 May 2025 09:49:39 +0200 Subject: [PATCH 1/3] Revert "[nrf fromlist] drivers: serial: nrfx_uarte: Workaround for spurious RXTO during restart" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit b70dea6a81d401429e05ec89318c43c5f66ccdd6. Signed-off-by: Krzysztof Chruściński --- drivers/serial/Kconfig.nrfx | 5 ----- drivers/serial/uart_nrfx_uarte.c | 17 ----------------- 2 files changed, 22 deletions(-) diff --git a/drivers/serial/Kconfig.nrfx b/drivers/serial/Kconfig.nrfx index 292c993fe22..278540ce382 100644 --- a/drivers/serial/Kconfig.nrfx +++ b/drivers/serial/Kconfig.nrfx @@ -63,11 +63,6 @@ config UART_ASYNC_TX_CACHE_SIZE in RAM, because EasyDMA in UARTE peripherals can only transfer data from RAM. -config UART_NRFX_UARTE_SPURIOUS_RXTO_WORKAROUND - bool - help - Apply workaround for spurious RXTO during restart. - if HAS_HW_NRF_UART0 || HAS_HW_NRF_UARTE0 nrfx_uart_num = 0 rsource "Kconfig.nrfx_uart_instance" diff --git a/drivers/serial/uart_nrfx_uarte.c b/drivers/serial/uart_nrfx_uarte.c index 4cae1e1886b..d2136acf883 100644 --- a/drivers/serial/uart_nrfx_uarte.c +++ b/drivers/serial/uart_nrfx_uarte.c @@ -266,9 +266,6 @@ struct uarte_nrfx_data { /* If enabled then UARTE peripheral is using memory which is cacheable. */ #define UARTE_CFG_FLAG_CACHEABLE BIT(3) -/* Indicates that workaround for spurious RXTO during restart shall be applied. */ -#define UARTE_CFG_FLAG_SPURIOUS_RXTO BIT(3) - /* Formula for getting the baudrate settings is following: * 2^12 * (2^20 / (f_PCLK / desired_baudrate)) where f_PCLK is a frequency that * drives the UARTE. @@ -1549,17 +1546,6 @@ static void endrx_isr(const struct device *dev) unsigned int key = irq_lock(); if (async_rx->buf) { - -#if CONFIG_UART_NRFX_UARTE_SPURIOUS_RXTO_WORKAROUND - /* Check for spurious RXTO event. */ - const struct uarte_nrfx_config *config = dev->config; - - if ((config->flags & UARTE_CFG_FLAG_SPURIOUS_RXTO) && - nrf_uarte_event_check(uarte, NRF_UARTE_EVENT_RXTO)) { - nrf_uarte_event_clear(uarte, NRF_UARTE_EVENT_RXTO); - } -#endif - /* Check is based on assumption that ISR handler handles * ENDRX before RXSTARTED so if short was set on time, RXSTARTED * event will be set. @@ -2581,9 +2567,6 @@ static int uarte_instance_init(const struct device *dev, (!IS_ENABLED(CONFIG_HAS_NORDIC_DMM) ? 0 : \ (UARTE_IS_CACHEABLE(idx) ? \ UARTE_CFG_FLAG_CACHEABLE : 0)) | \ - (IS_ENABLED(CONFIG_UART_NRFX_UARTE_SPURIOUS_RXTO_WORKAROUND) && \ - INSTANCE_IS_HIGH_SPEED(_, /*empty*/, idx, _) ? \ - UARTE_CFG_FLAG_SPURIOUS_RXTO : 0) | \ USE_LOW_POWER(idx), \ UARTE_DISABLE_RX_INIT(UARTE(idx)), \ .poll_out_byte = &uarte##idx##_poll_out_byte, \ From ceebd606a83115255bf2f2ffa20465f0c1ca6f4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Thu, 24 Apr 2025 10:04:17 +0200 Subject: [PATCH 2/3] [nrf fromtree] drivers: serial: nrfx_uarte: Add support for direct interrupts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add option to use direct ISR. Signed-off-by: Krzysztof Chruściński (cherry picked from commit aa8b25850fe469767ab02b133a622ef41352d38a) --- drivers/serial/Kconfig.nrfx | 3 +++ drivers/serial/uart_nrfx_uarte.c | 34 ++++++++++++++++++++++++-------- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/drivers/serial/Kconfig.nrfx b/drivers/serial/Kconfig.nrfx index 278540ce382..cc7556b9561 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" + if HAS_HW_NRF_UART0 || HAS_HW_NRF_UARTE0 nrfx_uart_num = 0 rsource "Kconfig.nrfx_uart_instance" diff --git a/drivers/serial/uart_nrfx_uarte.c b/drivers/serial/uart_nrfx_uarte.c index d2136acf883..db62c4ed3cd 100644 --- a/drivers/serial/uart_nrfx_uarte.c +++ b/drivers/serial/uart_nrfx_uarte.c @@ -2435,11 +2435,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 @@ -2585,11 +2604,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)); \ From f8a07569303329edc14c5b7f7c5143e4ce3c30ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Fri, 16 May 2025 09:51:55 +0200 Subject: [PATCH 3/3] [nrf fromtree] drivers: serial: nrfx_uarte: Workaround for spurious RXTO during restart MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some SoCs generates unexpected RXTO event during restart. Restart happens when ENDRX_STARTRX short is enabled and STOPRX is triggered (via short or by CPU). STOPRX starts closing procedure and ENDRX event is generated at some point which triggers STARTRX and closing procedure is interrupted. RXTO should not be triggered in that case. Due to internal timings some SoC on fast UARTE instance will trigger RXTO followed by RXSTARTED. This RXTO event shall be cleared as receiver is actually restarted and not stopped. Affected SoC is not in tree so Kconfig is added which enables the workaround. Signed-off-by: Krzysztof Chruściński (cherry picked from commit c58ae7467b0f0b152a1dd430966bbc82058e90bd) --- drivers/serial/Kconfig.nrfx | 5 +++++ drivers/serial/uart_nrfx_uarte.c | 17 +++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/drivers/serial/Kconfig.nrfx b/drivers/serial/Kconfig.nrfx index cc7556b9561..44cafe7cedf 100644 --- a/drivers/serial/Kconfig.nrfx +++ b/drivers/serial/Kconfig.nrfx @@ -66,6 +66,11 @@ config UART_ASYNC_TX_CACHE_SIZE config UART_NRFX_UARTE_DIRECT_ISR bool "Use direct ISR" +config UART_NRFX_UARTE_SPURIOUS_RXTO_WORKAROUND + bool + help + Apply workaround for spurious RXTO during restart. + if HAS_HW_NRF_UART0 || HAS_HW_NRF_UARTE0 nrfx_uart_num = 0 rsource "Kconfig.nrfx_uart_instance" diff --git a/drivers/serial/uart_nrfx_uarte.c b/drivers/serial/uart_nrfx_uarte.c index db62c4ed3cd..16c27ca7ffe 100644 --- a/drivers/serial/uart_nrfx_uarte.c +++ b/drivers/serial/uart_nrfx_uarte.c @@ -266,6 +266,9 @@ struct uarte_nrfx_data { /* If enabled then UARTE peripheral is using memory which is cacheable. */ #define UARTE_CFG_FLAG_CACHEABLE BIT(3) +/* Indicates that workaround for spurious RXTO during restart shall be applied. */ +#define UARTE_CFG_FLAG_SPURIOUS_RXTO BIT(3) + /* Formula for getting the baudrate settings is following: * 2^12 * (2^20 / (f_PCLK / desired_baudrate)) where f_PCLK is a frequency that * drives the UARTE. @@ -1546,6 +1549,17 @@ static void endrx_isr(const struct device *dev) unsigned int key = irq_lock(); if (async_rx->buf) { + +#if CONFIG_UART_NRFX_UARTE_SPURIOUS_RXTO_WORKAROUND + /* Check for spurious RXTO event. */ + const struct uarte_nrfx_config *config = dev->config; + + if ((config->flags & UARTE_CFG_FLAG_SPURIOUS_RXTO) && + nrf_uarte_event_check(uarte, NRF_UARTE_EVENT_RXTO)) { + nrf_uarte_event_clear(uarte, NRF_UARTE_EVENT_RXTO); + } +#endif + /* Check is based on assumption that ISR handler handles * ENDRX before RXSTARTED so if short was set on time, RXSTARTED * event will be set. @@ -2586,6 +2600,9 @@ static int uarte_instance_init(const struct device *dev, (!IS_ENABLED(CONFIG_HAS_NORDIC_DMM) ? 0 : \ (UARTE_IS_CACHEABLE(idx) ? \ UARTE_CFG_FLAG_CACHEABLE : 0)) | \ + (IS_ENABLED(CONFIG_UART_NRFX_UARTE_SPURIOUS_RXTO_WORKAROUND) && \ + INSTANCE_IS_HIGH_SPEED(_, /*empty*/, idx, _) ? \ + UARTE_CFG_FLAG_SPURIOUS_RXTO : 0) | \ USE_LOW_POWER(idx), \ UARTE_DISABLE_RX_INIT(UARTE(idx)), \ .poll_out_byte = &uarte##idx##_poll_out_byte, \