Skip to content

Commit a5b7573

Browse files
author
Cruz Monrreal
authored
Merge pull request #8292 from marcuschangarm/fix_flow
Fix hardware flow control on NRF52 series
2 parents 3f5eeac + ab04ff1 commit a5b7573

File tree

3 files changed

+36
-5
lines changed

3 files changed

+36
-5
lines changed

targets/TARGET_NORDIC/TARGET_NRF5x/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ const PinMapI2C PinMap_UART[] = {
137137

138138
The table must be placed in a C compilation file.
139139

140+
#### Flow Control (RTS/CTS)
141+
142+
When hardware flow control is enabled the DMA and FIFO buffers can be reduced to save RAM. CTS will be disabled when a DMA buffer is copied to the FIFO and enabled again when the FIFO has been emptied. Because of the dual buffering the FIFO buffer must be twice the size of the DMA buffer (less than half and data mmight be lost and more than half will be a waste of RAM).
140143

141144
#### RTC2
142145

targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/mbed_lib.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,7 @@
101101
"NRF52_PAN_62",
102102
"NRF52_PAN_63",
103103
"NRF52_PAN_64"
104-
],
105-
"target.console-uart-flow-control": "RTSCTS"
104+
]
106105
},
107106
"RBLAB_BLENANO2": {
108107
"target.macros_add": [
@@ -186,8 +185,7 @@
186185
"target.macros_add": [
187186
"CONFIG_GPIO_AS_PINRESET",
188187
"NRF52_ERRATA_20"
189-
],
190-
"target.console-uart-flow-control": "RTSCTS"
188+
]
191189
},
192190
"MTB_LAIRD_BL654": {
193191
"target.macros_add": [

targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/serial_api.c

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,20 @@ static void nordic_nrf5_uart_event_handler_endrx(int instance)
593593

594594
if (available > 0) {
595595

596+
/* Check if hardware flow control is set and signal sender to stop.
597+
*
598+
* This signal is set manually because the flow control logic in the UARTE module
599+
* only works when the module is receiving and not after an ENDRX event.
600+
*
601+
* The RTS signal is kept high until the atomic FIFO is empty. This allow systems
602+
* with flow control to reduce their FIFO and DMA buffers.
603+
*/
604+
if ((nordic_nrf5_uart_state[instance].owner->hwfc == NRF_UART_HWFC_ENABLED) &&
605+
(nordic_nrf5_uart_state[instance].owner->rts != NRF_UART_PSEL_DISCONNECTED)) {
606+
607+
nrf_gpio_pin_set(nordic_nrf5_uart_state[instance].owner->rts);
608+
}
609+
596610
/* Copy data from DMA buffer to FIFO buffer. */
597611
for (size_t index = 0; index < available; index++) {
598612

@@ -810,6 +824,7 @@ static void nordic_nrf5_uart_configure_object(serial_t *obj)
810824
/* Check if pin is set before configuring it. */
811825
if (uart_object->rts != NRF_UART_PSEL_DISCONNECTED) {
812826

827+
nrf_gpio_pin_clear(uart_object->rts);
813828
nrf_gpio_cfg_output(uart_object->rts);
814829
}
815830

@@ -819,8 +834,9 @@ static void nordic_nrf5_uart_configure_object(serial_t *obj)
819834
nrf_gpio_cfg_input(uart_object->cts, NRF_GPIO_PIN_NOPULL);
820835
}
821836

837+
/* Only let UARTE module handle CTS, RTS is handled manually due to buggy UARTE logic. */
822838
nrf_uarte_hwfc_pins_set(nordic_nrf5_uart_register[uart_object->instance],
823-
uart_object->rts,
839+
NRF_UART_PSEL_DISCONNECTED,
824840
uart_object->cts);
825841
}
826842

@@ -1429,6 +1445,20 @@ int serial_getc(serial_t *obj)
14291445
uint8_t *byte = (uint8_t *) nrf_atfifo_item_get(fifo, &context);
14301446
nrf_atfifo_item_free(fifo, &context);
14311447

1448+
/* Check if hardware flow control is set and the atomic FIFO buffer is empty.
1449+
*
1450+
* Receive is halted until the buffer has been completely handled to reduce RAM usage.
1451+
*
1452+
* This signal is set manually because the flow control logic in the UARTE module
1453+
* only works when the module is receiving and not after an ENDRX event.
1454+
*/
1455+
if ((nordic_nrf5_uart_state[instance].owner->hwfc == NRF_UART_HWFC_ENABLED) &&
1456+
(nordic_nrf5_uart_state[instance].owner->rts != NRF_UART_PSEL_DISCONNECTED) &&
1457+
(*head == *tail)) {
1458+
1459+
nrf_gpio_pin_clear(nordic_nrf5_uart_state[instance].owner->rts);
1460+
}
1461+
14321462
return *byte;
14331463
}
14341464

0 commit comments

Comments
 (0)