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
  • The RTS(request to send) and CTS(clear to send) signals are active low, so you should see that they are low by default. They will go high only if something happens so that they are not able to receive a message, e.g. if the receive buffer is full. 

     

    As you may know, RTS is the input and CTS is the output and they are cross connected. So they will not actually send a request, but check that the RTS is ok before sending. 

     

    Best regards,

    Edvin

  • I have trying to stress the UART by sending a lot of characters to fill the UART FIFO of the receiver and see the CTS signal changing. But I cannot get CTS signal changing. Here is the code I am using:

    #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
    
    #ifdef SENDER
    #define UART_RX_PIN_NUMBER  8  /* Received characters from the terminal */
    #define UART_TX_PIN_NUMBER  3  /* Send it to P0.3 */
    #define UART_CTS_PIN_NUMBER 4  /* CTS: P0.4 */
    #define UART_RTS_PIN_NUMBER 28 /* RTS: P0.28 */
    #else
    #define UART_RX_PIN_NUMBER  3  /* Receive characters from Sender */
    #define UART_TX_PIN_NUMBER  6  /* Send characters to the terminal */
    #define UART_CTS_PIN_NUMBER 28 /* RTS: P0.28 */
    #define UART_RTS_PIN_NUMBER 4  /* RTS: P0.4 */
    #endif
    
    #define MAX_TEST_DATA_BYTES     (15U)                /**< max number of test bytes to be used for tx and rx. */
    #define UART_TX_BUF_SIZE 256                         /**< UART TX buffer size. */
    #define UART_RX_BUF_SIZE 256                         /**< UART RX buffer size. */
    
    void uart_error_handle(app_uart_evt_t * p_event)
    {
        if (p_event->evt_type == APP_UART_COMMUNICATION_ERROR)
        {
            APP_ERROR_HANDLER(p_event->data.error_communication);
        }
        else if (p_event->evt_type == APP_UART_FIFO_ERROR)
        {
            APP_ERROR_HANDLER(p_event->data.error_code);
        }
    }
    
    #define UART_HWFC    APP_UART_FLOW_CONTROL_ENABLED
    
    /**
     * @brief Function for main application entry.
     */
    int main(void)
    {
        uint32_t err_code;
    
        bsp_board_leds_init();
    
        const app_uart_comm_params_t comm_params =
          {
              UART_RX_PIN_NUMBER,
    	  UART_TX_PIN_NUMBER,
    	  UART_RTS_PIN_NUMBER,
    	  UART_CTS_PIN_NUMBER,
              UART_HWFC,
              false,
              NRF_UART_BAUDRATE_115200
          };
    
        APP_UART_FIFO_INIT(&comm_params,
                             UART_RX_BUF_SIZE,
                             UART_TX_BUF_SIZE,
                             uart_error_handle,
                             APP_IRQ_PRIORITY_LOWEST,
                             err_code);
    
        APP_ERROR_CHECK(err_code);
    
    #ifdef SENDER
        puts("Sender");
    
        // Send a lot of data to see RTS
        while (true)
        {
            app_uart_put('a');
        }
    #else
        puts("Receiver");
    
        while (true)
        {
            uint8_t cr;
            while (app_uart_get(&cr) != NRF_SUCCESS);
        }
    #endif
    }
    
    
    /** @} */

    The signals:

Reply
  • I have trying to stress the UART by sending a lot of characters to fill the UART FIFO of the receiver and see the CTS signal changing. But I cannot get CTS signal changing. Here is the code I am using:

    #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
    
    #ifdef SENDER
    #define UART_RX_PIN_NUMBER  8  /* Received characters from the terminal */
    #define UART_TX_PIN_NUMBER  3  /* Send it to P0.3 */
    #define UART_CTS_PIN_NUMBER 4  /* CTS: P0.4 */
    #define UART_RTS_PIN_NUMBER 28 /* RTS: P0.28 */
    #else
    #define UART_RX_PIN_NUMBER  3  /* Receive characters from Sender */
    #define UART_TX_PIN_NUMBER  6  /* Send characters to the terminal */
    #define UART_CTS_PIN_NUMBER 28 /* RTS: P0.28 */
    #define UART_RTS_PIN_NUMBER 4  /* RTS: P0.4 */
    #endif
    
    #define MAX_TEST_DATA_BYTES     (15U)                /**< max number of test bytes to be used for tx and rx. */
    #define UART_TX_BUF_SIZE 256                         /**< UART TX buffer size. */
    #define UART_RX_BUF_SIZE 256                         /**< UART RX buffer size. */
    
    void uart_error_handle(app_uart_evt_t * p_event)
    {
        if (p_event->evt_type == APP_UART_COMMUNICATION_ERROR)
        {
            APP_ERROR_HANDLER(p_event->data.error_communication);
        }
        else if (p_event->evt_type == APP_UART_FIFO_ERROR)
        {
            APP_ERROR_HANDLER(p_event->data.error_code);
        }
    }
    
    #define UART_HWFC    APP_UART_FLOW_CONTROL_ENABLED
    
    /**
     * @brief Function for main application entry.
     */
    int main(void)
    {
        uint32_t err_code;
    
        bsp_board_leds_init();
    
        const app_uart_comm_params_t comm_params =
          {
              UART_RX_PIN_NUMBER,
    	  UART_TX_PIN_NUMBER,
    	  UART_RTS_PIN_NUMBER,
    	  UART_CTS_PIN_NUMBER,
              UART_HWFC,
              false,
              NRF_UART_BAUDRATE_115200
          };
    
        APP_UART_FIFO_INIT(&comm_params,
                             UART_RX_BUF_SIZE,
                             UART_TX_BUF_SIZE,
                             uart_error_handle,
                             APP_IRQ_PRIORITY_LOWEST,
                             err_code);
    
        APP_ERROR_CHECK(err_code);
    
    #ifdef SENDER
        puts("Sender");
    
        // Send a lot of data to see RTS
        while (true)
        {
            app_uart_put('a');
        }
    #else
        puts("Receiver");
    
        while (true)
        {
            uint8_t cr;
            while (app_uart_get(&cr) != NRF_SUCCESS);
        }
    #endif
    }
    
    
    /** @} */

    The signals:

Children
No Data
Related