drivers: nrf: nrf uarte fix TX interrupts disabling.

Make sure that TX interrupts are disabled after transmission
is finished.

Signed-off-by: Mieszko Mierunski <mieszko.mierunski@nordicsemi.no>
This commit is contained in:
Mieszko Mierunski 2018-11-19 13:43:47 +01:00 committed by Carles Cufí
commit 1bfa721373

View file

@ -28,6 +28,7 @@ struct uarte_nrfx_data {
uart_irq_callback_user_data_t cb; /**< Callback function pointer */
void *cb_data; /**< Callback function arg */
u8_t *tx_buffer;
volatile bool disable_tx_irq;
#endif /* UARTE_INTERRUPT_DRIVEN */
};
@ -82,7 +83,22 @@ static inline NRF_UARTE_Type *get_uarte_instance(struct device *dev)
static void uarte_nrfx_isr(void *arg)
{
struct device *dev = arg;
const struct uarte_nrfx_data *data = get_dev_data(dev);
struct uarte_nrfx_data *data = get_dev_data(dev);
NRF_UARTE_Type *uarte = get_uarte_instance(dev);
if (data->disable_tx_irq &&
nrf_uarte_event_check(uarte, NRF_UARTE_EVENT_ENDTX)) {
nrf_uarte_int_disable(uarte, NRF_UARTE_INT_ENDTX_MASK);
/* If there is nothing to send, driver will save an energy
* when TX is stopped.
*/
nrf_uarte_task_trigger(uarte, NRF_UARTE_TASK_STOPTX);
data->disable_tx_irq = false;
return;
}
if (data->cb) {
data->cb(data->cb_data);
@ -323,21 +339,18 @@ static int uarte_nrfx_fifo_read(struct device *dev,
static void uarte_nrfx_irq_tx_enable(struct device *dev)
{
NRF_UARTE_Type *uarte = get_uarte_instance(dev);
struct uarte_nrfx_data *data = get_dev_data(dev);
nrf_uarte_int_enable(uarte, NRF_UARTE_INT_ENDTX_MASK);
data->disable_tx_irq = false;
}
/** Interrupt driven transfer disabling function */
static void uarte_nrfx_irq_tx_disable(struct device *dev)
{
NRF_UARTE_Type *uarte = get_uarte_instance(dev);
nrf_uarte_int_disable(uarte, NRF_UARTE_INT_ENDTX_MASK);
/* If there is nothing to send, driver will save an energy
* when TX is stopped.
*/
nrf_uarte_task_trigger(uarte, NRF_UARTE_TASK_STOPTX);
struct uarte_nrfx_data *data = get_dev_data(dev);
/* TX IRQ will be disabled after current transmission is finished */
data->disable_tx_irq = true;
}
/** Interrupt driven transfer ready function */
@ -345,7 +358,13 @@ static int uarte_nrfx_irq_tx_ready_complete(struct device *dev)
{
NRF_UARTE_Type *uarte = get_uarte_instance(dev);
return nrf_uarte_event_check(uarte, NRF_UARTE_EVENT_ENDTX);
/* ENDTX flag is always on so that ISR is called when we enable TX IRQ.
* Because of that we have to explicitly check if ENDTX interrupt is
* enabled, otherwise this function would always return true no matter
* what would be the source of interrupt.
*/
return nrf_uarte_event_check(uarte, NRF_UARTE_EVENT_ENDTX) &&
nrf_uarte_int_enable_check(uarte, NRF_UARTE_INT_ENDTX_MASK);
}
static int uarte_nrfx_irq_rx_ready(struct device *dev)