nRF5 SDK is not maintained anymore
More Info: Consider nRF Connect SDK for new designs

LIBUARTE - no NRF_LIBUARTE_ASYNC_EVT_RX_DATA event

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().

Parents
  • Hi 

    What is your LF clock setting?

    By default the SDK projects are set up to use external 32kHz crystal, which you may or may not have included on your custom board?

    If you don't have an external 32kHz crystal available you need to set CLOCK_CONFIG_LF_SRC to 0 in sdk_config.h

    Other than that I can't really see any issue with your code. 

    Best regards
    Torbjørn

Reply
  • Hi 

    What is your LF clock setting?

    By default the SDK projects are set up to use external 32kHz crystal, which you may or may not have included on your custom board?

    If you don't have an external 32kHz crystal available you need to set CLOCK_CONFIG_LF_SRC to 0 in sdk_config.h

    Other than that I can't really see any issue with your code. 

    Best regards
    Torbjørn

Children
No Data
Related