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

Nordic UART Service custom flow control based on RX buffer size

Hi,

We have a question regarding a custom implementation of flow control for nrf52840 using SDK16 w/ SoftDevice 7.0.1. Currently, our sensor's primary micro transfers data via UART to a nrf52840 module running the peripheral ble_app_uart firmware. This issue is that we cannot use the standard uart flow control implementation within ble_app_uart (.flow_control = APP_UART_FLOW_CONTROL_ENABLED) because our micro sends bursts of data (512 bytes chunks) to the BLE module and cannot react to RTS instantaneously. 

That being said, our RX/TX buffer are set to a size which is >> the data chunks.

Ex. #define UART_RX_BUF_SIZE                8192

We were wondering if there was a way to track the current size of the RX buffer as its being fed data over UART so that we can manually deassert the RTS flag when the buffer is, for example, 75% full and re-assert RTS when the RX buffer is 25% full. This way, we will not have to worry about reacting instantaneously to RTS as I see is required by my logic analyzer when using APP_UART_FLOW_CONTROL_ENABLED.

Looking at ble_app_uart_pca10056_s140, I added some pseudo code to the following function which aims to check the current size of RX receiving buffer and assert/deassert RTS.

void uart_event_handle(app_uart_evt_t * p_event)
{
    static uint8_t data_array[BLE_NUS_MAX_DATA_LEN];
    static uint8_t index = 0;
    uint32_t       err_code;

    switch (p_event->evt_type)
    {
        case APP_UART_DATA_READY:
          if (CURRENT_RXBUFFER_SIZE < (0.75 * UART_RX_BUF_SIZE))
          {
              **(set RTS GPIO low - enable UART data transmission from micro)**

              UNUSED_VARIABLE(app_uart_get(&data_array[index]));
              index++;

              if ((data_array[index - 1] == '\n') ||
                  (data_array[index - 1] == '\r') ||
                  (index >= m_ble_nus_max_data_len))
              {
                  if (index > 1)
                  {
                      NRF_LOG_DEBUG("Ready to send data over BLE NUS");
                      NRF_LOG_HEXDUMP_DEBUG(data_array, index);

                      do
                      {
                          uint16_t length = (uint16_t)index;
                          err_code = ble_nus_data_send(&m_nus, data_array, &length, m_conn_handle);
                          if ((err_code != NRF_ERROR_INVALID_STATE) &&
                              (err_code != NRF_ERROR_RESOURCES) &&
                              (err_code != NRF_ERROR_NOT_FOUND))
                          {
                              APP_ERROR_CHECK(err_code);
                          }
                      } while (err_code == NRF_ERROR_RESOURCES);
                  }

                  index = 0;
              }
            break;
          }
          else {
            **(set RTS GPIO high - disable UART data transmission from micro)**
          }
        case APP_UART_COMMUNICATION_ERROR:
            APP_ERROR_HANDLER(p_event->data.error_communication);
            break;

        case APP_UART_FIFO_ERROR:
            APP_ERROR_HANDLER(p_event->data.error_code);
            break;

        default:
            break;
    }
}

Thoughts?

As I mentioned above, we cannot react instantly to RTS using the built in flow control so we'd like to trigger based on current BLE RX buffer size so as to not trigger the APP_UART_FIFO_ERROR when we transmit too much data too fast.

Thank you for your assistance.

Best,

Robert

Parents Reply Children
No Data
Related