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

NUS Send Function ble_nus_data_send() Faulting (NRF_ERROR_RESOURCES) or Never Successful - Only when Sending to Slower Android

SDK: NRF 5 15.3

SoftDevice: S140

I have been successfully using the NUS code snippet below to send data periodically to my expensive Smartphone running Android 10 (fast device) from my peripheral. I am seeing issues when using a cheaper tablet running Android 9 (slow device). 

// Loop while sending samples from the acc ramstore.
  while(samples_left > 0)
  {
    // Send up to 40 samples at a time (40x6=240 bytes .. fits within BLE packet with minimal waste).
    if(samples_left > 40) { samples_send = 40; }
    else { samples_send = samples_left; }
    //SEGGER_RTT_printf(0, "Samples left %d\n", samples_left);

    // Get byte length from samples.
    resp_len_bytes = samples_send * 6;

    // Setup additional response header bytes.
    resp_bytes[1] = (uint8_t) resp_len_bytes;
    resp_bytes[2] = BLE_SUCCESS;

    // Update payload.
    memcpy(&(resp_bytes[3]), &(xtag_get_acc_ramstore_ptr()[samples_sent]), resp_len_bytes);

    // Send.
    do { err_code = ble_nus_data_send(&m_nus, resp_bytes, &resp_len_bytes, m_conn_handle); }
    while (err_code == NRF_ERROR_RESOURCES);

    // Inc samples_sent.
    samples_sent += samples_send;
  
    // Dec samples_left based on the number of samples sent.
    samples_left -= samples_send;
  }

The while loop is called every 16, 32 or 64 mSec (timer handler) depending on how fast I pull data from my accelerometer (acc). About 150 bytes (25 samples) are sent within each handler call. I have setup 2M phy and 244 byte MTU. No issues on either setting as their negotiation with Android seems to be fine for both fast and slow Android devices. On the slow device, I am not seeing an issue when the handler is called every 64 mS, and I rarely see an issue at 32 mS, but I always see an issue at 16 mS handler period. The issue shows up in 1 of 2 ways.

1. The code gets stuck in the while loop. Its test condition never fails because the ble_nus_data_send() gets stuck returning NRF_ERROR_RESOURCES constantly.

2. I get a fault and the SES Studio Debug terminal shows:

!!!!!!!! - Critical Fault - !!!!!!!!!!!
ERROR 19 [NRF_ERROR_RESOURCES] at :0
PC at: 0x00000000
End of error report
System reseting ....

I do not need to support fast data (16 and 32 mSec handler periods) on the slow device, but I do need to handle the 2 issues listed above more gracefully (if a any slow central device connects to my peripheral). I cannot have my firmware stuck in a loop or faulting out.

Please advise how I can handle my slow device comms errors more effectively to ensure my peripheral does not hang or restart.

Thanks in advance.

Mark J

Parents
  • Hi Mark,

    1. Is the while loop being run inside the timer interrupt?  if it is, please try to run this from your main loop instead. The Softdevice will not be able to clear the error condition if it keeps getting blocked by the timer interrupt.

    2. Are you able to tell where the error came from? It must be from a different part of the code as there are no APP_ERROR_CHECK()s in the code snippet you posted.  Note that the default handler will include the file name and line number of where the error occurred if you build the project with the DEBUG flag.

    Also, I just want to point out that not all phones are going to support a MTU of 244 bytes, so I guess the max. the number of samples to send should be updated according to the outcome of the MTU negotiation. Similar to how the original ble_app_uart example does it. 

    Best regards,

    Vidar

  • Hi ,

    I just wanted to close this off...

    I switched to the main loop and that resolved the issue.

    I also understand your APP_ERROR_CHECK() and MTU 244 byte size packets. I have updated logging for APP_ERROR_CHECK() fails and I can confirm my devices all support 244 byte packets.

    Thanks,

    Mark J

Reply Children
No Data
Related