Hi
I have combined the ble_app_uart and libuarte example. The combination works "nearly" well.Transmit is ok, but when receiving characters over UARTE, no NRF_LIBUARTE_ASYNC_EVT_RX_DATA event is generated until a buffer is full. Hence, I don't get any timeout! When printing the buffer, I can see that all RX characters are received correctly, but for small packages, I would like to have timeouts.
I'm using nRF5 SDK version17.2 on a custom board.
this is the definition:
NRF_LIBUARTE_ASYNC_DEFINE(libuarte, 0, 1, 0, NRF_LIBUARTE_PERIPHERAL_NOT_USED, 255, 5);
..and the rest of the essential code:
typedef struct {
uint8_t * p_data;
uint32_t length;
} buffer_t;
NRF_QUEUE_DEF(buffer_t, m_buf_queue, 10, NRF_QUEUE_MODE_NO_OVERFLOW);
void uart_event_handler(void * context, nrf_libuarte_async_evt_t * p_evt)
{
nrf_libuarte_async_t * p_libuarte = (nrf_libuarte_async_t *)context;
ret_code_t ret;
switch (p_evt->type)
{
case NRF_LIBUARTE_ASYNC_EVT_ERROR:
break;
case NRF_LIBUARTE_ASYNC_EVT_RX_DATA:
NRF_LOG_HEXDUMP_INFO(p_evt->data.rxtx.p_data, p_evt->data.rxtx.length);
// Done processing buffer, release buffer back to libUARTE
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:
if (!nrf_queue_is_empty(&m_buf_queue))
{
buffer_t buf;
ret = nrf_queue_pop(&m_buf_queue, &buf);
APP_ERROR_CHECK(ret);
UNUSED_RETURN_VALUE(nrf_libuarte_async_tx(p_libuarte, buf.p_data, buf.length));
}
else
{
// done transmitting....start listening
rs485_duplex_mode(RS485_RX);
}
break;
default:
break;
}
}
void
msgSend (uint8_t* data, uint8_t len)
{
// turn on rs485 Tx --- TODO: turn off in callback
rs485_duplex_mode(RS485_TX);
// NRF_LOG_HEXDUMP_INFO(data,len);
ret_code_t ret = nrf_libuarte_async_tx(&libuarte, data, len);
if (ret == NRF_ERROR_BUSY)
{
buffer_t buf = {
.p_data = data,
.length = len,
};
ret = nrf_queue_push(&m_buf_queue, &buf);
APP_ERROR_CHECK(ret);
}
else
{
APP_ERROR_CHECK(ret);
}
}
void libuarte_init(void){
ret_code_t ret = nrf_drv_clock_init();
APP_ERROR_CHECK(ret);
nrf_drv_clock_lfclk_request(NULL);
nrf_libuarte_async_config_t nrf_libuarte_async_config = {
.tx_pin = TX_PIN_NUMBER,
.rx_pin = RX_PIN_NUMBER,
.baudrate = NRF_UARTE_BAUDRATE_115200,
.parity = NRF_UARTE_PARITY_EXCLUDED,
.hwfc = NRF_UARTE_HWFC_DISABLED,
.timeout_us = 100,
.int_prio = APP_IRQ_PRIORITY_MID
};
ret_code_t 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);
}
Note: The msgSend() is used since I have placed libuarte definitions outside main(), and msgSend() is called from main() since libuarte is not defined in main()
Note: Communication is over half duplex RS485. Hence, rs485_duplex_mode().