This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

UART Hardware Flow control does not seem to work - Connecting two nRF52840 dev boards together

Hi all,
I am trying to get my head around UART Flow control on Nordic nRF52. I cannot get it working...
I have two nRF52840 dev boards (PCA10056) that I connected between each others:

Board 1 (Sender)     Board 2 (Receiver)
P0.3 ------------------- P0.4
P0.4 ------------------- P0.3
P0.28 ------------------ P0.29
P0.29 ------------------ P0.28

I have not got UART logging enabled. I use a logic analyzer to see what is being sent.
I noticed the Receiver does not block while waiting to receive.

Here is the source code:

The same source code is build with `-DSENDER=1` for the sender and no declaration for the receiver.
When the receiver is switched off, I can see my packet being sent from the sender.

#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "app_uart.h"
#include "app_error.h"
#include "nrf_delay.h"
#include "nrf.h"
#include "bsp.h"
#if defined (UART_PRESENT)
#include "nrf_uart.h"
#endif
#if defined (UARTE_PRESENT)
#include "nrf_uarte.h"
#endif
#include "nrf_drv_uart.h"

#include "nrf_gpio.h"

#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"

uint8_t command[] = { 7, 198, 4, 8, 255, 159, 1, 253, 136 };

#define UART_RX_PIN   3
#define UART_TX_PIN   4
#define UART_RTS_PIN  28
#define UART_CTS_PIN  29

#define SUPPORT_HARDWARE_FLOW_CONTROL

uint8_t response[32];

/**
 * @brief Function for main application entry.
 */
int main(void)
{
    uint32_t err_code;
    ret_code_t ret;

    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
    NRF_LOG_DEFAULT_BACKENDS_INIT();

    /* Configure board. */
    bsp_board_leds_init();

#if SENDER
    NRF_LOG_ERROR("Sender");
#else
    NRF_LOG_ERROR("Receiver");
#endif

    static nrf_drv_uart_t app_uart_inst = NRF_DRV_UART_INSTANCE(0);

    nrf_drv_uart_config_t uart_config = NRF_DRV_UART_DEFAULT_CONFIG;
    uart_config.baudrate = 0x00275000UL; // 9600
#ifdef SUPPORT_HARDWARE_FLOW_CONTROL
    uart_config.hwfc = 1;
#else
    uart_config.hwfc = 0;
#endif
    uart_config.pselrxd = UART_RX_PIN;
    uart_config.pseltxd = UART_TX_PIN;
#ifdef SUPPORT_HARDWARE_FLOW_CONTROL
    uart_config.pselrts = UART_RTS_PIN;
    uart_config.pselcts = UART_CTS_PIN;
#endif
    uart_config.parity = 0; // No Parity
    uart_config.use_easy_dma = true;

    err_code = nrf_drv_uart_init(&app_uart_inst, &uart_config, NULL);
    if (err_code != NRF_SUCCESS) {
        NRF_LOG_ERROR("Error1 ErrCode:0x%x\n", err_code);
        while(1);
    }

    nrf_drv_uart_rx_enable(&app_uart_inst);

#if SENDER
    ret =  nrf_drv_uart_tx(&app_uart_inst, command, sizeof(command));
#else
    ret = nrf_drv_uart_rx(&app_uart_inst, response, sizeof(command));
#endif

    if (NRF_ERROR_BUSY == ret)
    {
        bsp_board_led_invert(1);
        NRF_LOG_ERROR("Error2");
    }
    else if (ret != NRF_SUCCESS)
    {
        bsp_board_led_invert(2);
        NRF_LOG_ERROR("Error3 ret:0x%x (error_reg:0x%02x)", ret, nrf_drv_uart_errorsrc_get(&app_uart_inst));
    }
    else
    {
        bsp_board_led_invert(0);
        bsp_board_led_invert(3);

#ifndef SENDER
        NRF_LOG_ERROR("Received: %02x%02x%02x%02x", response[0], response[1], response[2], response[3]);
#endif
    }

    while (true)
    {
    // Do nothing.
    }
}


/** @} */

Parents
  • Hello,

    As far as I understand, the RTS/CTS lines does not go high/off (active low means that off is high) until it can't handle any more inputs. Since all your application is doing is receiving the messages, the application can manage to handle the buffers fast enough, and hence, it will not change the RTS/CTS lines. Even though it is sending in one direction, does not mean that it has to block in the other direction. 

     

    Best regards,

    Edvin

  • You are right :-) I should have realised the MCU frequency is much faster than UART. Adding a delay in the reception demonstrate the HW flow control. I changed the reception as follow compare to the code above and I can see the CTS:

        puts("Receiver");
    
        while (true)
        {
            uint8_t cr;
            while (app_uart_get(&cr) != NRF_SUCCESS);
    	    nrf_delay_ms(2);
        }

    I can now confirm UART Hardware Flow control works :-)

Reply Children
No Data
Related