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 <mieszko.mierunski@nordicsemi.no>
This commit is contained in:
parent
4a13041c38
commit
f2bd628c5a
1 changed files with 20 additions and 0 deletions
|
@ -81,6 +81,8 @@ struct uarte_async_cb {
|
||||||
|
|
||||||
bool rx_enabled;
|
bool rx_enabled;
|
||||||
bool hw_rx_counting;
|
bool hw_rx_counting;
|
||||||
|
/* Flag to ensure that RX timeout won't be executed during ENDRX ISR */
|
||||||
|
volatile bool is_in_irq;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -588,6 +590,16 @@ static void rx_timeout(struct k_timer *timer)
|
||||||
const struct uarte_nrfx_config *cfg = get_dev_config(dev);
|
const struct uarte_nrfx_config *cfg = get_dev_config(dev);
|
||||||
u32_t read;
|
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)) {
|
if (hw_rx_counting_enabled(data)) {
|
||||||
read = nrfx_timer_capture(&cfg->timer, 0);
|
read = nrfx_timer_capture(&cfg->timer, 0);
|
||||||
} else {
|
} else {
|
||||||
|
@ -623,6 +635,9 @@ static void rx_timeout(struct k_timer *timer)
|
||||||
data->async->rx_timeout_slab;
|
data->async->rx_timeout_slab;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nrf_uarte_int_enable(get_uarte_instance(dev),
|
||||||
|
NRF_UARTE_INT_ENDRX_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define UARTE_ERROR_FROM_MASK(mask) \
|
#define UARTE_ERROR_FROM_MASK(mask) \
|
||||||
|
@ -667,6 +682,9 @@ static void endrx_isr(struct device *dev)
|
||||||
if (!data->async->rx_enabled) {
|
if (!data->async->rx_enabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data->async->is_in_irq = true;
|
||||||
|
|
||||||
if (data->async->rx_next_buf) {
|
if (data->async->rx_next_buf) {
|
||||||
nrf_uarte_task_trigger(uarte, NRF_UARTE_TASK_STARTRX);
|
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;
|
evt.type = UART_RX_DISABLED;
|
||||||
user_callback(dev, &evt);
|
user_callback(dev, &evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data->async->is_in_irq = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This handler is called when the reception is interrupted, in contrary to
|
/* This handler is called when the reception is interrupted, in contrary to
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue