From f2bd628c5ad3a2570a63bb2138ff2e803ea5cd62 Mon Sep 17 00:00:00 2001 From: Mieszko Mierunski Date: Mon, 26 Aug 2019 11:25:35 +0200 Subject: [PATCH] drivers: nrf: Fix RX timeout and ENDRX ISR handling. Ensure that two routines won't interfere with eachother. In current situation there is possibility that ENDRX will be called during rx_timeout routine or vice-versa which will result in wrong offset and length passed to user. Signed-off-by: Mieszko Mierunski --- drivers/serial/uart_nrfx_uarte.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/serial/uart_nrfx_uarte.c b/drivers/serial/uart_nrfx_uarte.c index d368c450e4e..4776344056b 100644 --- a/drivers/serial/uart_nrfx_uarte.c +++ b/drivers/serial/uart_nrfx_uarte.c @@ -81,6 +81,8 @@ struct uarte_async_cb { bool rx_enabled; bool hw_rx_counting; + /* Flag to ensure that RX timeout won't be executed during ENDRX ISR */ + volatile bool is_in_irq; }; #endif @@ -588,6 +590,16 @@ static void rx_timeout(struct k_timer *timer) const struct uarte_nrfx_config *cfg = get_dev_config(dev); u32_t read; + if (data->async->is_in_irq) { + return; + } + + /* Disable ENDRX ISR, in case ENDRX event is generated, it will be + * handled after rx_timeout routine is complete. + */ + nrf_uarte_int_disable(get_uarte_instance(dev), + NRF_UARTE_INT_ENDRX_MASK); + if (hw_rx_counting_enabled(data)) { read = nrfx_timer_capture(&cfg->timer, 0); } else { @@ -623,6 +635,9 @@ static void rx_timeout(struct k_timer *timer) data->async->rx_timeout_slab; } } + + nrf_uarte_int_enable(get_uarte_instance(dev), + NRF_UARTE_INT_ENDRX_MASK); } #define UARTE_ERROR_FROM_MASK(mask) \ @@ -667,6 +682,9 @@ static void endrx_isr(struct device *dev) if (!data->async->rx_enabled) { return; } + + data->async->is_in_irq = true; + if (data->async->rx_next_buf) { nrf_uarte_task_trigger(uarte, NRF_UARTE_TASK_STARTRX); } @@ -708,6 +726,8 @@ static void endrx_isr(struct device *dev) evt.type = UART_RX_DISABLED; user_callback(dev, &evt); } + + data->async->is_in_irq = false; } /* This handler is called when the reception is interrupted, in contrary to