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

Error enabling connection event extension in UART example

Hi all,

I use nRF52832 with the UART peripheral example.

I try to enable connection event extension in the device and get an error.

I use SDK V15.0.0 and Softdevice V 6.0.0

I put the following code at the end of the nrf_sdh_ble_default_cfg_set function:

    ble_opt_t  opt;
    memset(&opt, 0x00, sizeof(opt));
    opt.common_opt.conn_evt_ext.enable = 1;
    ret_code = sd_ble_opt_set(BLE_COMMON_OPT_CONN_EVT_EXT, &opt);
    APP_ERROR_CHECK(ret_code);

ret_code returns with 0x3001.

What am I doing wrong?

I'm am new to BLE and my knowledge is limited, specific detailed answers will be greatly appreciated.

Thank you

Parents
  • Moved the code right after ble_stack_init();

    Now the error doesn't appear, but data rate is awful.

    I have connection interval min = 15, max = 30

    Event length = 12

    sending 906 bytes every 220msec and every 4-6 packets I have a few packets missing.

    The data is sent, instead of within the interrupt, in main, using the following function:

    static void SendDataToHost(void)
    {
      static uint16_t length_to_send;
      static uint16_t current_length_to_send;
    
      uint32_t err_code;
    
      if (ring_buffer_out_point < ring_buffer_fill_point)
        length_to_send = ring_buffer_fill_point - ring_buffer_out_point;
      else if (ring_buffer_out_point > ring_buffer_fill_point)
      {
        length_to_send = kEND_OF_TX_RING_BUFFER_LOCATION - ring_buffer_out_point;
        length_to_send += (ring_buffer_fill_point - application_tx_ring_buffer);
      }
    
      do
      {
        if (f_ble_tx_complete)
        {
          if (length_to_send > m_ble_nus_max_data_len)
          {
            current_length_to_send = m_ble_nus_max_data_len;
    
            if ((current_length_to_send + ring_buffer_out_point) > kEND_OF_TX_RING_BUFFER_LOCATION)
              current_length_to_send = kEND_OF_TX_RING_BUFFER_LOCATION - ring_buffer_out_point;
    
            f_ble_tx_complete = 0;
            err_code = ble_nus_data_send(&m_nus, ring_buffer_out_point, &current_length_to_send, m_conn_handle);
    
            if (err_code != NRF_SUCCESS)
              f_ble_tx_complete = 1;
            else
            {
              ring_buffer_out_point += current_length_to_send;
              if (ring_buffer_out_point >= kEND_OF_TX_RING_BUFFER_LOCATION)
                ring_buffer_out_point = application_tx_ring_buffer;
              length_to_send -= current_length_to_send;
              current_length_to_send = 0;
            }
          }
          else if (length_to_send)
          {
            if ((length_to_send + ring_buffer_out_point) > kEND_OF_TX_RING_BUFFER_LOCATION)
              current_length_to_send = kEND_OF_TX_RING_BUFFER_LOCATION - ring_buffer_out_point;
            else
              current_length_to_send = length_to_send;
    
            f_ble_tx_complete = 0;
            err_code = ble_nus_data_send(&m_nus, ring_buffer_out_point, &current_length_to_send, m_conn_handle);
            if (err_code != NRF_SUCCESS)
              f_ble_tx_complete = 1;
            else
            {
              ring_buffer_out_point += current_length_to_send;
              if (ring_buffer_out_point >= kEND_OF_TX_RING_BUFFER_LOCATION)
                ring_buffer_out_point = application_tx_ring_buffer;
              length_to_send -= current_length_to_send;
              current_length_to_send = 0;
            }
          }
        }
      } while(length_to_send);
    
      length_to_send = 0;
      current_length_to_send = 0;
    
      (void)err_code;
    }

    The ring buffer is of 4KB.

    f_ble_tx_complete is set in BLE_GATTS_EVT_HVN_TX_COMPLETE event.

  • Solved on my side! It seems that our issue is that we have our own message queue and we're waiting for the BLE_GATTS_EVT_HVN_TX_COMPLETE event in order to send the next packet. However, this limits the maximum TX packets to 1 per connection interval. We should use the HVN queue if we want to boost the throughput.

  • What do you mean by:

    "add the message in your queue"

    "you can remove completely your queue"

    Is there a limit on HVN queue size, and is it measured in bytes?

    Thanks

  • , thanks for your comments! ,  hvn_tx_queue_size defines the number of notification packets you can queue in the softdevice's tx buffer. You can't send more than ~12 packets per connection so I don't think it makes sense to increase the buffer to more than 12. 

    excerpt from API documentation for sd_ble_gatts_hvx():

    The number of Handle Value Notifications that can be queued is configured by ble_gatts_conn_cfg_t::hvn_tx_queue_size When the queue is full, the function call will return NRF_ERROR_RESOURCES. A BLE_GATTS_EVT_HVN_TX_COMPLETE event will be issued as soon as the transmission of the notification is complete.The application can keep track of the available queue element count for notifications by following the procedure below:

    • Store initial queue element count in a variable.
    • Decrement the variable, which stores the currently available queue element count, by one when a call to this function returns NRF_SUCCESS.
    • Increment the variable, which stores the current available queue element count, by the count variable in BLE_GATTS_EVT_HVN_TX_COMPLETE event.

     

  • I don't fully understand.

    What if my connection interval is long and I set a high value for the event length, I still can't send more than 12 packets?

  • There is a limit to how many packets you can send per event where it won't help to increase the event length. Not sure what it is for the softdevice, but the largest number of packets I have been able to sent is 12 packets (27 byte link layer packet), and that was with a nRF52 and an iphone 7. For better throughput, the central must support data length extension, long MTU and 2M PHY.

     

      

  • Unfortunately this didn't work.

    I tried first with the configuration that was already working for me (interval min=max=15, event length=6).
    I tried not waiting for BLE_GATTS_EVT_HVN_TX_COMPLETE and just update the indices of the ring buffer if ble_nus_data_send returned with NRF_SUCCESS.

    I tried a different approach also, looping ble_nus_data_send until it returned with NRF_SUCCESS, I had many losses/distortions of data.

Reply
  • Unfortunately this didn't work.

    I tried first with the configuration that was already working for me (interval min=max=15, event length=6).
    I tried not waiting for BLE_GATTS_EVT_HVN_TX_COMPLETE and just update the indices of the ring buffer if ble_nus_data_send returned with NRF_SUCCESS.

    I tried a different approach also, looping ble_nus_data_send until it returned with NRF_SUCCESS, I had many losses/distortions of data.

Children
Related