drivers: serial: nrfx_uarte: Fix power management

Power consumption was still high after putting uarte device into off
state. It was caused by ENDRX interrupt that was triggered after
calling STOPRX. ENDRX event was called with 0 amount but interrupt
got triggered and fifo_read was starting RX again.

Added disabling RX interrupt before disabling UARTE and reenabling at
device activation.

Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
Krzysztof Chruscinski 2021-02-04 12:00:12 +01:00 committed by Anas Nashif
commit 4c0266fcf1

View file

@ -99,6 +99,9 @@ struct uarte_nrfx_int_driven {
uint8_t *tx_buffer;
uint16_t tx_buff_size;
volatile bool disable_tx_irq;
#ifdef CONFIG_PM_DEVICE
bool rx_irq_enabled;
#endif
atomic_t fifo_fill_lock;
};
#endif
@ -1545,7 +1548,16 @@ static void uarte_nrfx_set_power_state(const struct device *dev,
#endif
if (nrf_uarte_rx_pin_get(uarte) !=
NRF_UARTE_PSEL_DISCONNECTED) {
nrf_uarte_event_clear(uarte, NRF_UARTE_EVENT_ENDRX);
nrf_uarte_task_trigger(uarte, NRF_UARTE_TASK_STARTRX);
#ifdef UARTE_INTERRUPT_DRIVEN
if (data->int_driven &&
data->int_driven->rx_irq_enabled) {
nrf_uarte_int_enable(uarte,
NRF_UARTE_INT_ENDRX_MASK);
}
#endif
}
data->pm_state = new_state;
@ -1580,6 +1592,17 @@ static void uarte_nrfx_set_power_state(const struct device *dev,
}
#endif
if (nrf_uarte_event_check(uarte, NRF_UARTE_EVENT_RXSTARTED)) {
#ifdef UARTE_INTERRUPT_DRIVEN
if (data->int_driven) {
data->int_driven->rx_irq_enabled =
nrf_uarte_int_enable_check(uarte,
NRF_UARTE_INT_ENDRX_MASK);
if (data->int_driven->rx_irq_enabled) {
nrf_uarte_int_disable(uarte,
NRF_UARTE_INT_ENDRX_MASK);
}
}
#endif
nrf_uarte_task_trigger(uarte, NRF_UARTE_TASK_STOPRX);
while (!nrf_uarte_event_check(uarte,
NRF_UARTE_EVENT_RXTO)) {