Skip to content

Improve flow control on NRF52 #8748

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 41 additions & 1 deletion targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/serial_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -321,13 +321,29 @@ static void nordic_nrf5_uart_timeout_handler(uint32_t instance)
* since the last idle timeout.
*/
if ((nordic_nrf5_uart_state[instance].rxdrdy_counter > 0) ||
(nordic_nrf5_uart_state[instance].endrx_counter > 0)) {
(nordic_nrf5_uart_state[instance].endrx_counter > 0) ||
(nrf_uarte_event_check(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_RXDRDY)) ||
(nrf_uarte_event_check(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_ENDRX))) {

/* Activity detected, reset timeout. */
nordic_custom_ticker_set_timeout(instance);

} else {

/* Check if hardware flow control is set and signal sender to stop.
*
* This signal is set manually because the flow control logic in the UARTE module
* only works when the module is receiving and not after an ENDRX event.
*
* The RTS signal is kept high until the atomic FIFO is empty. This allow systems
* with flow control to reduce their FIFO and DMA buffers.
*/
if ((nordic_nrf5_uart_state[instance].owner->hwfc == NRF_UART_HWFC_ENABLED) &&
(nordic_nrf5_uart_state[instance].owner->rts != NRF_UART_PSEL_DISCONNECTED)) {

nrf_gpio_pin_set(nordic_nrf5_uart_state[instance].owner->rts);
}

/* No activity detected, no timeout set. */
nordic_nrf5_uart_state[instance].ticker_is_running = false;

Expand Down Expand Up @@ -635,6 +651,30 @@ static void nordic_nrf5_uart_event_handler_endrx(int instance)
nordic_nrf5_uart_state[instance].callback_posted = true;
nordic_swi_rx_trigger(instance);
}

} else {

/**
* Use head and tail pointer in FIFO to determine whether there is data available.
*/
nrf_atfifo_t *fifo = nordic_nrf5_uart_state[instance].fifo;

uint16_t *head = &fifo->head.pos.rd;
uint16_t *tail = &fifo->tail.pos.rd;

/* Check if hardware flow control is set and the atomic FIFO buffer is empty.
*
* Receive is halted until the buffer has been completely handled to reduce RAM usage.
*
* This signal is set manually because the flow control logic in the UARTE module
* only works when the module is receiving and not after an ENDRX event.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well that's annoying.

*/
if ((nordic_nrf5_uart_state[instance].owner->hwfc == NRF_UART_HWFC_ENABLED) &&
(nordic_nrf5_uart_state[instance].owner->rts != NRF_UART_PSEL_DISCONNECTED) &&
(*head == *tail)) {

nrf_gpio_pin_clear(nordic_nrf5_uart_state[instance].owner->rts);
}
}
}

Expand Down