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

Do i need to wary about HW UART buffer when using UART driver library ?

I am using nrf_drv_uart library.

UART communication is set in non-blocing mode, and transfer od data is relised with nrf_drv_uart_rx and nrf_drv_uart_tx functions.

I am using: uint8_t[100] rx_buffer = {0}; for data reception. But, problem is that nrf_drv_uart_rx function returns error: NRF_ERROR_NO_MEM even if rx_buffer is mostly free.

I thouth that i dont need to think of peripheral UART buffer (hardware UART buffer of 6 bytes) when using UART driver library.

And i can not find any documentation how and way to handle this error event, can anyone confirm this and perhaps gives some advice.

Thanks in advance.

//Handler
void uart_co2_bsl_handler(nrf_drv_uart_event_t * p_event, void * p_context)
{
    switch(p_event->type)
    { 
        case NRF_DRV_UART_EVT_TX_DONE:
            flag_co2_tx_done = 1;
        break;

        case NRF_DRV_UART_EVT_RX_DONE: 
            flag_co2_rx_done = 1;
        break;
    
        case NRF_DRV_UART_EVT_ERROR: 
            if(p_event->data.error.error_mask == NRF_ERROR_DATA_SIZE)
            {
                NRF_UART0->ERRORSRC = CLEAR_REGISTAR;
            }
            else if(p_event->data.error.error_mask == NRF_ERROR_INVALID_DATA)
            {
                NRF_UART0->ERRORSRC = CLEAR_REGISTAR;
            }
            else if(p_event->data.error.error_mask == NRF_ERROR_TIMEOUT)
            {
                nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_RXTO);
            }
            else if(p_event->data.error.error_mask == NRF_ERROR_SVC_HANDLER_MISSING)
            {
                nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_ERROR);
            }
            else if(p_event->data.error.error_mask == NRF_ERROR_NO_MEM)
            { 
                nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_ERROR);
            }
            else
            {
                APP_ERROR_HANDLER(p_event->data.error.error_mask);
            }
        break;
    
        default:
        break;
    }
}

//Init.
void uart_co2_bsl_config(void)
{ 
    nrf_drv_uart_config_t config;
    config.pselrxd = UART_RX;
    config.pseltxd = UART_TX;
    config.pselrts = RTS_PIN_NUMBER;
    config.pselcts = CTS_PIN_NUMBER;
    config.baudrate = NRF_UART_BAUDRATE_115200
    config.hwfc = NRF_UART_HWFC_DISABLED;
    config.parity = NRF_UART_PARITY_EXCLUDED;
    config.interrupt_priority = APP_IRQ_PRIORITY_LOWEST;
    config.p_context = NULL;
    
    APP_ERROR_CHECK(nrf_drv_uart_init(&config, uart_handler));
}

  • Which SDK are you using? you also need to set the buffer sizes for the library in sdk_config.h file

  • I am using SDKv11, nRF51422 chip and Keil_v5.21 IDE.

    SDK11 does not support sdk_config.h files, instead it is using nrf_drv_config.h files.

    Part of the nrf_drv_config.h file regarding UART:

    /* UART */
    
    #define UART0_ENABLED 1
    
    #if (UART0_ENABLED == 1)
    #define UART0_CONFIG_HWFC         NRF_UART_HWFC_DISABLED
    #define UART0_CONFIG_PARITY       NRF_UART_PARITY_EXCLUDED
    #define UART0_CONFIG_BAUDRATE     NRF_UART_BAUDRATE_115200
    #define UART0_CONFIG_PSEL_TXD 9
    #define UART0_CONFIG_PSEL_RXD 11
    #define UART0_CONFIG_PSEL_CTS 10
    #define UART0_CONFIG_PSEL_RTS 8
    #define UART0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
    #ifdef NRF52
    #define UART0_CONFIG_USE_EASY_DMA false
    //Compile time flag
    #define UART_EASY_DMA_SUPPORT     1
    #define UART_LEGACY_SUPPORT       1
    #endif //NRF52
    #endif

  • Then you still have configuration for buffers like below

    #define UART_TX_BUF_SIZE 256                         /**< UART TX buffer size. */
    #define UART_RX_BUF_SIZE 1                           /**< UART RX buffer size. */

    used in 

        APP_UART_FIFO_INIT(&comm_params,
                             UART_RX_BUF_SIZE,
                             UART_TX_BUF_SIZE,
                             uart_error_handle,
                             APP_IRQ_PRIORITY_LOW,
                             err_code);

    You need to increase the RX buffer size if you are receiving data faster than your device can process.

  • But i do not use APP_UART_FIFO.

    void uart_co2_bsl_config(void)
    { 
        nrf_drv_uart_config_t config;
        config.pselrxd = UART_RX;
        config.pseltxd = UART_TX;
        config.pselrts = RTS_PIN_NUMBER;
        config.pselcts = CTS_PIN_NUMBER;
        config.baudrate = NRF_UART_BAUDRATE_115200
        config.hwfc = NRF_UART_HWFC_DISABLED;
        config.parity = NRF_UART_PARITY_EXCLUDED;
        config.interrupt_priority = APP_IRQ_PRIORITY_LOWEST;
        config.p_context = NULL;
        
        APP_ERROR_CHECK(nrf_drv_uart_init(&config, uart_handler));
    }

  • Than you #Aryan for your response, but i think that we are going in the wrong direction here. Maybe my question is not good. I have working firmware with APP_UART module, but i first tried NRF_DRV_UART library (as you can see in my code) and did not have much success with it (the reason is explained in the question).

    I just want to know if it is requested of me to manually clear hardware UART buffer when using UART driver library, and if i do how do i flush it, because i did not find any function for than in library.

    One more time i do not looking for solution(debugging that piece of code) i just want to know a "big picture", concept if you will, of how driver function works.

    And this buffer thing is what causes confusion.

    As i can see, everybody is staying away of this library, there is no good examples and everybody are using APP_UART module and APP_UART_FIFO.

    So, the answer can be as simple as "No" or "Yes, here you go a function that does that".

Related