nRF51822 uart flow control

Hello,

I am using nrf starter kit and nRF51822 DK modules atached. I'm using external usb-com uart modules (based on FT232 chips) for communication with PC (Win7) and hyper terminal clients for data send/receive. Currently I'm experimenting with modified gazell example project to include data received from uart and to transfer between modules as in com cable replacement setup. If I connect usb-com modules directly with each other (thus error free communication) and set baudrate 921600bps, I can transfer data at aproximately 890kpbs transfer rate (using zmodem file transfer). Now i'm trying to include radio transfer in data path. Uart is configured with hardware flow control, uart module on nrf51 is configured on high priority with extended buffering (fifo like size of 1kB) and aditional checking for receive buffer usage to stop and start RX transfers. Uart Error interrupt is enabled and i'm getting several errors representing Buffer overflow during large data chunk receive (3-15kB in size). I'm guessing that hardware flow control is not quick enough to prevent RX register overwriting. Another issue is stopping RX transfer without data loss. I'm thinking that it could be possible to use aditional I/O for RTS/CTS manual control together with uart hardware to pause Rx transfers correctly. What solutions could be usable to correct flow control not lowering baudrate? as this is the basis of transportation layer for later tasks.

Parents
  • The latest app_uart_fifo file (included in the SDK 9) contains a bug. 3 bytes where systematically lost (even with HFC) because of a bug in the UART0_IRQHandler function.

    Be sure that the in the UART0_IRQHandler function you check that the RX FIFO is not full before reading the RXD register or some bytes will be lost !

    if (FIFO_LENGTH(m_rx_fifo) <= m_rx_fifo.buf_size_mask)
        err_code = app_fifo_put(&m_rx_fifo, (uint8_t) NRF_UART0->RXD);
        // ...
    

    I successfully transferred a 2MB file over a UART link (115'200 bauds) without any error, using the new chip revision with the six-byte buffer.

  • yes, i see that it is not the best solution and has opened up ways to deadlock the reads. I think the best solution is along with your fix, we should add below

    whenever app_fifo_get is called, if the fifo was full, empty one slot to user byte address. Then read the EVENTS_RXDRDY status, and if set, new read on RXD and clear RXRDY event. This will make sure that the last ignored read will be done here.

    Also the clearing of event should be done like this inside UART0_IRQHandler

    if (FIFO_LENGTH(m_rx_fifo) <= m_rx_fifo.buf_size_mask)
    {
        err_code = app_fifo_put(&m_rx_fifo, (uint8_t) NRF_UART0->RXD);
    
        // Clear UART RX event flag
        NRF_UART0->EVENTS_RXDRDY = 0;    
    }
    
Reply
  • yes, i see that it is not the best solution and has opened up ways to deadlock the reads. I think the best solution is along with your fix, we should add below

    whenever app_fifo_get is called, if the fifo was full, empty one slot to user byte address. Then read the EVENTS_RXDRDY status, and if set, new read on RXD and clear RXRDY event. This will make sure that the last ignored read will be done here.

    Also the clearing of event should be done like this inside UART0_IRQHandler

    if (FIFO_LENGTH(m_rx_fifo) <= m_rx_fifo.buf_size_mask)
    {
        err_code = app_fifo_put(&m_rx_fifo, (uint8_t) NRF_UART0->RXD);
    
        // Clear UART RX event flag
        NRF_UART0->EVENTS_RXDRDY = 0;    
    }
    
Children
No Data
Related