Hi,
I am transferring data received via ble to uart PC.
BLE MTU - 247, connection priority - HIGH (15ms).
I successfully receive data from ble, put it in the fifo, then take it out and send it to libuarte.
But less data comes to the PC than I sent (provided that the data was larger than 244 bytes).
Example: I send 256 bytes (00 - FF) from my smartphone, it will be 244 and 12 bytes.
output in RTT:
<info> app: uart_loop fifo_read: 244 bytes
<warning> libUARTE: Started TX total length:244, first chunk:244
<info> app: uart_loop fifo_read: 12 bytes
<warning> libUARTE: Started TX total length:12, first chunk:12
data on PC:

my code:
#include <string.h>
#include <nrf_libuarte_async.h>
#include <nrf_queue.h>
#include <app_fifo.h>
#include "custom_board.h"
#include "config.h"
#include "uart.h"
#include "cpu.h"
#include "log.h"
#define UART_BUF_SIZE (1024 * 8)
#define RX_BUF_SIZE UART_BUF_SIZE
#define TX_BUF_SIZE UART_BUF_SIZE
#define UART_MTU_SIZE 244
#define UART_TX_SIZE 244
NRF_LIBUARTE_ASYNC_DEFINE(libuarte, 0, 2, NRF_LIBUARTE_PERIPHERAL_NOT_USED, 3, 255, 3);
static uint8_t rx_fifo_buf[RX_BUF_SIZE] __attribute__ ((aligned (32)));
static uint8_t tx_fifo_buf[TX_BUF_SIZE] __attribute__ ((aligned (32)));
static app_fifo_t m_rx_fifo;
static app_fifo_t m_tx_fifo;
static uint8_t rx_buf[UART_MTU_SIZE] __attribute__ ((aligned (32)));
static uint8_t tx_buf[UART_MTU_SIZE] __attribute__ ((aligned (32)));
static bool tx_is_busy = false;
static bool libuarte_is_error = false;
void uart_event_handler(void *context, nrf_libuarte_async_evt_t *p_evt)
{
ret_code_t err_code;
nrf_libuarte_async_t *p_libuarte = (nrf_libuarte_async_t *)context;
uint32_t size;
switch (p_evt->type)
{
case NRF_LIBUARTE_ASYNC_EVT_RX_DATA:
size = (uint32_t)p_evt->data.rxtx.length;
err_code = app_fifo_write(&m_rx_fifo, p_evt->data.rxtx.p_data, &size);
if (size != p_evt->data.rxtx.length || err_code != NRF_SUCCESS)
libuarte_is_error = true;
nrf_libuarte_async_rx_free(p_libuarte,
p_evt->data.rxtx.p_data,
p_evt->data.rxtx.length);
break;
case NRF_LIBUARTE_ASYNC_EVT_TX_DONE:
tx_is_busy = false;
break;
case NRF_LIBUARTE_ASYNC_EVT_ERROR:
case NRF_LIBUARTE_ASYNC_EVT_OVERRUN_ERROR:
libuarte_is_error = true;
tx_is_busy = false;
break;
default:
break;
}
}
void uart_init(void)
{
ret_code_t err_code;
err_code = app_fifo_init(&m_rx_fifo, rx_fifo_buf, RX_BUF_SIZE);
APP_ERROR_CHECK(err_code);
err_code = app_fifo_init(&m_tx_fifo, tx_fifo_buf, TX_BUF_SIZE);
APP_ERROR_CHECK(err_code);
nrf_libuarte_async_config_t nrf_libuarte_async_config = {
.tx_pin = TX_PIN_NUMBER,
.rx_pin = RX_PIN_NUMBER,
.baudrate = NRF_UARTE_BAUDRATE_1000000,
.parity = NRF_UARTE_PARITY_EXCLUDED,
.hwfc = NRF_UARTE_HWFC_DISABLED,
.timeout_us = 100,
.pullup_rx = false,
.int_prio = APP_IRQ_PRIORITY_LOW_MID};
err_code = nrf_libuarte_async_init(&libuarte,
&nrf_libuarte_async_config,
uart_event_handler,
(void *)&libuarte);
APP_ERROR_CHECK(err_code);
nrf_libuarte_async_enable(&libuarte);
}
void uart_tx(const uint8_t *data, uint8_t len)
{
ret_code_t err_code;
uint32_t size = len;
err_code = app_fifo_write(&m_tx_fifo, data, &size);
if (size != len || err_code != NRF_SUCCESS)
DBG_LOG_ERROR("%s fifo_write_error!", __func__);
}
void uart_rx(uint8_t *data, uint8_t *len)
{
ret_code_t err_code;
uint32_t size = *len;
if (size > UART_MTU_SIZE)
{
DBG_LOG_ERROR("%s len > UART_MTU_SIZE!", __func__);
*len = 0;
return;
}
err_code = app_fifo_read(&m_rx_fifo, rx_buf, &size);
if (err_code == NRF_SUCCESS && size != 0)
{
memcpy(data, rx_buf, size);
*len = size;
}
else
{
*len = 0;
}
}
void uart_loop(void)
{
ret_code_t err_code;
uint32_t n_bytes;
if (libuarte_is_error)
{
libuarte_is_error = false;
DBG_LOG_ERROR("%s libuarte_error!", __func__);
}
if (!tx_is_busy)
{
n_bytes = UART_TX_SIZE;
err_code = app_fifo_read(&m_tx_fifo, tx_buf, &n_bytes);
if (err_code == NRF_SUCCESS && n_bytes != 0)
{
DBG_LOG_INFO("%s fifo_read: %d bytes", __func__, n_bytes);
tx_is_busy = true;
err_code = nrf_libuarte_async_tx(&libuarte, tx_buf, n_bytes);
if (err_code != NRF_SUCCESS)
{
tx_is_busy = false;
DBG_LOG_ERROR("%s libuarte_tx Error!", __func__);
}
}
}
}
main loop:
for (;;)
{
ble_receive(data, &len);
if (len)
{
uart_tx(data, len);
}
uart_loop();
...
}
I have tried different settings but without success.
The transfer works successfully if you generate data locally, do not use bluetooth to receive data.
Maybe when data is received via bluetooth, does the libuarte_tx stop?
Ideas and advice? (I would be very happy to discuss and provide additional information)





