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

ble_app-uart example - ble_nus_data_send() - BLE_NUS_EVT_TX_RDY - connection interval

I am sending 240-byte data from peripheral to central through notification (without response) by using the ble_nus_data_send() function when the BLE_NUS_EVT_TX_RDY event comes. The issue here is the BLE_NUS_EVT_TX_RDY is triggering 2x times of connection interval.
eg: If we put connection interval 7.5 then the event BLE_NUS_EVT_TX_RDY will trigger every 15 ms only.

parameters being used

nRF5 SDK v17.0.2

NRF_SDH_BLE_GAP_DATA_LENGTH 251

NRF_SDH_BLE_GATT_MAX_MTU_SIZE 247

NRF_SDH_BLE_GAP_EVENT_LENGTH 400

and also am using the conn_evt_len_ext_set() function.

why is that event BLE_NUS_EVT_TX_RDY is triggering 2x time of connection interval?

here I attached the sniffer log

Parents Reply
  • I am getting an error instead of NRF_ERROR_RESOURCES when I am trying to queue more packet on the central side by using the function ble_nus_c_string_send(); 

    (got NRF_SUCCESS for first 4 packets)

    <info> app: ble_nus_c_string_send 0:
    <info> app: ble_nus_c_string_send 0:
    <info> app: ble_nus_c_string_send 0:
    <info> app: ble_nus_c_string_send 0:
    <error> nrf_ble_gq: SD GATT procedure (1) failed on connection handle 0 with error: 0x00000013.

Children
  • Hi AKV,

    I'm sorry for the late reply. I had a look at the error , it's 0x13 meaning 19 in decimal and that means: 

    #define NRF_ERROR_RESOURCES                   (NRF_ERROR_BASE_NUM + 19)

    So it's simply the softdevice buffer was full when queueing for write command packets. However the issue here is that our nrf_ble_gq module which supposed to queue the message when the buffer is full didn't handle the NRF_ERROR_RESOURCES but only handle the NRF_ERROR_BUSY. 

    A patch is needed, please have a look at this case and apply the patch: https://devzone.nordicsemi.com/f/nordic-q-a/60557/bug-improvement-in-handling-nrf_error_resources-response-in-gatt-queue-nrf_ble_gq_req_gatts_hvx-processing

    After that it should work. 

  • I am still getting that error even after I made that change in the nrf_ble_gq.c file.

    I have attached the code please verify the changes that I made nrf_ble_gq.c file.

    static void queue_process(nrf_queue_t const * const p_queue, uint16_t conn_handle)
    case NRF_BLE_GQ_REQ_GATTS_HVX:
                {
                    uint8_t  hvx_data[NRF_BLE_GQ_GATTS_HVX_MAX_DATA_LEN];
                    uint16_t len;
                    uint16_t hvx_len;
    
                    // Retrieve allocated data.
                    ble_req.params.gatts_hvx.p_data = hvx_data;
                    nrf_memobj_read(ble_req.p_mem_obj,
                                    (void *) &hvx_len,
                                    sizeof(uint16_t),
                                    0);
                    ble_req.params.gatts_hvx.p_len = &hvx_len;
                    nrf_memobj_read(ble_req.p_mem_obj,
                                    (void *) ble_req.params.gatts_hvx.p_data,
                                    *ble_req.params.gatts_hvx.p_len,
                                    sizeof(uint16_t));
    
                    len = hvx_len;
    
                    NRF_LOG_DEBUG("GATTS HVX");
                    err_code = sd_ble_gatts_hvx(conn_handle,
                                                &ble_req.params.gatts_hvx);
    
                    if ((err_code == NRF_SUCCESS) &&
                        (len != hvx_len))
                    {
                        err_code = NRF_ERROR_DATA_SIZE;
                    }
                    //Added change
                   if (err_code == NRF_ERROR_RESOURCES)
                    {
                        err_code = NRF_ERROR_BUSY;
                    }
                  
                } break;
                
                
                
      static bool request_process(nrf_ble_gq_req_t const * const p_req, uint16_t conn_handle)
      case NRF_BLE_GQ_REQ_GATTS_HVX:
            {
                uint16_t len = *p_req->params.gatts_hvx.p_len;
    
                NRF_LOG_DEBUG("GATTS Notification or Indication");
    
                err_code = sd_ble_gatts_hvx(conn_handle,
                                            &p_req->params.gatts_hvx);
    
                if ((err_code == NRF_SUCCESS) &&
                    (len != *p_req->params.gatts_hvx.p_len))
                {
                    err_code = NRF_ERROR_DATA_SIZE;
                }
                //Added change
                 if (err_code == NRF_ERROR_RESOURCES)
                {
                    err_code = NRF_ERROR_BUSY;
                }
                
    
            } break;

    Also attached function used to send data from central to peripheral

    void Ble_test_data_send(void)
    {
       uint32_t       err_code; 
       err_code = NRF_SUCCESS;
        
        while (err_code == NRF_SUCCESS)
        { 
        
          err_code = ble_nus_c_string_send(&m_ble_nus_c, Ble_tx_buf, Ble_Tx_length);
          NRF_LOG_INFO("ble_nus_c_string_send %d:",err_code);
    
          if (err_code == NRF_ERROR_RESOURCES)
            {            
                break;
            }
            else if (err_code != NRF_SUCCESS)
            {
                NRF_LOG_ERROR("nrf_ble_gq_item_add failed: 0x%x", err_code);
            }  
        }
    
    
    }

    log:

    <info> app: ble_nus_c_string_send 0:

    <info> app: ble_nus_c_string_send 0:

    <info> app: ble_nus_c_string_send 0:

    <info> app: ble_nus_c_string_send 0:

    <error> nrf_ble_gq: SD GATT procedure (1) failed on connection handle 0 with error: 0x00000013.

    <error> app: Fatal error

    <warning> app: System reset

  • Hi AKV, 
    It's my mistake, in your case you are doing a write command but in the case I pointed to the customer used the notification. 
    So what you need to modify is inside request_process() and in queue_process() to change the check from:


     if (err_code == NRF_ERROR_BUSY)

    to 

     if ((err_code == NRF_ERROR_BUSY)||(err_code == NRF_ERROR_RESOURCES))

    It should work after that. 

  • Thanks.

    After making those changes it's working now.

    <info> app: ble_nus_c_string_send 0:

    <info> app: ble_nus_c_string_send 0:

    <info> app: ble_nus_c_string_send 0:

    <info> app: ble_nus_c_string_send 0:

    <info> app: ble_nus_c_string_send 9:

    And why is that return value is getting 9 (NRF_ERROR_INVALID_LENGTH) instead of NRF_ERROR_RESOURCES

Related