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

LIBUARTE+BLE_APP_UART (ble_nus_data_send seems can't handle too many data or fast enough that comes from libuarte - app just hangs)

Hi Nordic Support Team,

My current setup is : Android Phone <--BLE--> nRF52840 <--LIBUARTE--> External STM32 MCU

I started the example with this folder in the link provided (pca10056 with S140):

https://devzone.nordicsemi.com/f/nordic-q-a/71665/nrf-52832-uart-high-speed-communication/294686#294686

It works fine when I am sending command from my phone to nRF and send to the external MCU.

However, when I tried fetching data from the nRF to the phone through ble_nus_data_send(), the nRF will only send some data (outputted to my phone serial terminal) and then hangs, even when I am in debug mode, the application doesn't even stop. (maybe it it stuck in a while loop or something). Note that nRF and external MCU is exchanging a lot of data at baud rate of 115200.

Also, by "hangs" means that the device doesn't react to my command request from the phone and the debug terminal doesn't output anything after.

When I commented out the ble_nus_data_send() part, the uart is exchanging data smoothly between nRF and External MCU.

I have looked through some of the threads relating to this implementation, but I don't what I am doing wrong here. I think these important pieces of code will be able to show you :

// <q> NRF_LIBUARTE_ASYNC_WITH_APP_TIMER  - nrf_libuarte_async - libUARTE_async library
 

#ifndef NRF_LIBUARTE_ASYNC_WITH_APP_TIMER
#define NRF_LIBUARTE_ASYNC_WITH_APP_TIMER 1
#endif

#define APP_BLE_CONN_CFG_TAG            1                                           /**< A tag identifying the SoftDevice BLE configuration. */

#define DEVICE_NAME                     "nRF_libUARTE"                               /**< Name of device. Will be included in the advertising data. */
#define NUS_SERVICE_UUID_TYPE           BLE_UUID_TYPE_VENDOR_BEGIN                  /**< UUID type for the Nordic UART Service (vendor specific). */

#define APP_BLE_OBSERVER_PRIO           3                                           /**< Application's BLE observer priority. You shouldn't need to modify this value. */

#define APP_ADV_INTERVAL                64                                          /**< The advertising interval (in units of 0.625 ms. This value corresponds to 40 ms). */

#define APP_ADV_DURATION                18000                                       /**< The advertising duration (180 seconds) in units of 10 milliseconds. */

#define MIN_CONN_INTERVAL               MSEC_TO_UNITS(20, UNIT_1_25_MS)             /**< Minimum acceptable connection interval (20 ms), Connection interval uses 1.25 ms units. */
#define MAX_CONN_INTERVAL               MSEC_TO_UNITS(75, UNIT_1_25_MS)             /**< Maximum acceptable connection interval (75 ms), Connection interval uses 1.25 ms units. */
#define SLAVE_LATENCY                   0                                           /**< Slave latency. */
#define CONN_SUP_TIMEOUT                MSEC_TO_UNITS(4000, UNIT_10_MS)             /**< Connection supervisory timeout (4 seconds), Supervision Timeout uses 10 ms units. */
#define FIRST_CONN_PARAMS_UPDATE_DELAY  APP_TIMER_TICKS(5000)                       /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (5 seconds). */
#define NEXT_CONN_PARAMS_UPDATE_DELAY   APP_TIMER_TICKS(30000)                      /**< Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */
#define MAX_CONN_PARAMS_UPDATE_COUNT    3                                           /**< Number of attempts before giving up the connection parameter negotiation. */

#define DEAD_BEEF                       0xDEADBEEF                                  /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */

NRF_LIBUARTE_ASYNC_DEFINE(libuarte, 0, 2, 2, NRF_LIBUARTE_PERIPHERAL_NOT_USED, 255, 3);

BLE_NUS_DEF(m_nus, NRF_SDH_BLE_TOTAL_LINK_COUNT);                                   /**< BLE NUS service instance. */
NRF_BLE_GATT_DEF(m_gatt);                                                           /**< GATT module instance. */
NRF_BLE_QWR_DEF(m_qwr);                                                             /**< Context for the Queued Write module.*/
BLE_ADVERTISING_DEF(m_advertising);                                                 /**< Advertising module instance. */

static uint16_t   m_conn_handle          = BLE_CONN_HANDLE_INVALID;                 /**< Handle of the current connection. */
static uint16_t   m_ble_nus_max_data_len = BLE_GATT_ATT_MTU_DEFAULT - 3;            /**< Maximum length of data (in bytes) that can be transmitted to the peer by the Nordic UART service module. */
static ble_uuid_t m_adv_uuids[]          =                                          /**< Universally unique service identifier. */
{
    {BLE_UUID_NUS_SERVICE, NUS_SERVICE_UUID_TYPE}
};

static void nus_data_handler(ble_nus_evt_t * p_evt)
{

    if (p_evt->type == BLE_NUS_EVT_RX_DATA)
    {
        uint32_t err_code;

        NRF_LOG_DEBUG("Received data from BLE NUS. Writing data on UART.");
        NRF_LOG_HEXDUMP_DEBUG(p_evt->params.rx_data.p_data, p_evt->params.rx_data.length);

        uint8_t uart_string[BLE_NUS_MAX_DATA_LEN+2] = "";
        memcpy(uart_string, p_evt->params.rx_data.p_data, p_evt->params.rx_data.length);
        uart_string[p_evt->params.rx_data.length] = '\r';
        uart_string[p_evt->params.rx_data.length+1] = '\n';

        err_code = nrf_libuarte_async_tx(&libuarte,uart_string, p_evt->params.rx_data.length + 2);
        // APP_ERROR_CHECK(err_code);
    }

    else if (p_evt->type == BLE_NUS_EVT_TX_RDY)
    {
        flag_transmitted = true;
        NRF_LOG_DEBUG("TX IS READY");
    }
    else if (p_evt->type == BLE_NUS_EVT_COMM_STARTED)
    {
        NRF_LOG_DEBUG("NOTIFICATION IS STARTED!");
    }
}

/**@brief   Function for handling app_uart events.
 *
 * @details This function will receive a single character from the app_uart module and append it to
 *          a string. The string will be be sent over BLE when the last character received was a
 *          'new line' '\n' (hex 0x0A) or if the string has reached the maximum data length.
 */
/**@snippet [Handling the data received over UART] */
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;
    uint16_t index = 0;

    switch (p_evt->type)
    {
        case NRF_LIBUARTE_ASYNC_EVT_ERROR:
            break;
        case NRF_LIBUARTE_ASYNC_EVT_RX_DATA:
            NRF_LOG_DEBUG("NRF_LIBUARTE_ASYNC_EVT_RX_DATA : Received data from libuarte. Writing data on UART.");
            NRF_LOG_HEXDUMP_DEBUG(p_evt->data.rxtx.p_data,  p_evt->data.rxtx.length);
            // NRF_LOG_DEBUG("Flag Transmitted : %d.", flag_transmitted);
            
            while (index < p_evt->data.rxtx.length)
            {
                NRF_LOG_INFO("data rxtx loop");
                uint16_t length = (uint16_t)(p_evt->data.rxtx.length - index > BLE_NUS_MAX_DATA_LEN) ? BLE_NUS_MAX_DATA_LEN : p_evt->data.rxtx.length - index;
                do
                {
                    ret = ble_nus_data_send(&m_nus, p_evt->data.rxtx.p_data + index, &length, m_conn_handle);
                    if ((ret != NRF_ERROR_INVALID_STATE) &&
                        (ret != NRF_ERROR_RESOURCES) &&
                        (ret != NRF_ERROR_NOT_FOUND))
                    {
                        APP_ERROR_CHECK(ret);
                    }
                } while (ret == NRF_ERROR_RESOURCES);
                index += length;

             }

             if (p_evt->data.rxtx.p_data == NULL){

             }
             else {
                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:
            // NRF_LOG_DEBUG("NRF_LIBUARTE_ASYNC_EVT_TX_DONE : Received data from libuarte. Writing data on UART.");
            // NRF_LOG_HEXDUMP_DEBUG(p_evt->data.rxtx.p_data,  p_evt->data.rxtx.length);

            break;
        default:
            break;
    }
}
/**@snippet [Handling the data received over UART] */


/**@brief  Function for initializing the UART module.
 */
/**@snippet [UART Initialization] */
static void uart_init(void)
{
    uint32_t                     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_115200,
            .parity     = NRF_UARTE_PARITY_EXCLUDED,
            .hwfc       = NRF_UARTE_HWFC_DISABLED,
            .timeout_us = 100,
            .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);

    static uint8_t text[] = "ble_app_libUARTE example started.\r\n";
    static uint8_t text_size = sizeof(text);

    err_code = nrf_libuarte_async_tx(&libuarte, text, text_size);
    APP_ERROR_CHECK(err_code);
}

Parents Reply Children
No Data
Related