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

Correct/best way to implement a UART-serial passthrough?

Hello, the SDK example ble_peripheral\ble_app_uart includes the code below in order to forward data from the UART over the BLE.  What it does is wait for a CRLF, or a certain amount of data, and then writes the data to the TX. 

This isn't exactly what we want, we don't want to require a CRLF, we just want to pass through the data.  Among other reasons we are sending binary data sometimes and CR or LF could be part of the data.  

But when I remove the check for the CRLF, it just writes every character immediately to the BLE, and apparently fails, and we end up losing data (presumably because the send is slower than the receive, and the first character is still transmitting when the second arrives, so theres nothing to do with it.

Theres a few ways to handle this I can think of:

1) Just dont send until the buffer fills.  The problem with this is that there will be data left over in the buffer when we are done.  So we could add a timer to send automatically if we haven't received any data for x msec.  But this adds latency and seems kludgy.

2) In bare metal UART, there would be a "tx ready" interrupt we could handle to load the next characters into the TX register.  Is there any equivalent in the SDK?  An event handler that corresponds to this would be the perfect thing.

Is there any way to get #2 to work, or does anybody have an approach better than #1?

Thanks for any thoughts. 

switch (p_event->evt_type)
{
case APP_UART_DATA_READY:
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;

Parents Reply Children
No Data
Related