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

  • The transmit code can send "m_ble_nus_max_data_len" bytes at a time. It will not be limited to 20 bytes if the gap central supports a larger MTU. You make the following changes to main.c to print out the actual MTU and link layer packet size:

    --- a/examples/ble_peripheral/ble_app_uart/main.c
    +++ b/examples/ble_peripheral/ble_app_uart/main.c
    @@ -452,7 +452,11 @@ void gatt_evt_handler(nrf_ble_gatt_t * p_gatt, nrf_ble_gatt_evt_t const * p_evt)
         if ((m_conn_handle == p_evt->conn_handle) && (p_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED))
         {
             m_ble_nus_max_data_len = p_evt->params.att_mtu_effective - OPCODE_LENGTH - HANDLE_LENGTH;
    -        NRF_LOG_INFO("Data len is set to 0x%X(%d)", m_ble_nus_max_data_len, m_ble_nus_max_data_len);
    +        NRF_LOG_INFO("MTU is set to %d", p_evt->params.att_mtu_effective);
    +    }
    +    else if ((m_conn_handle == p_evt->conn_handle) && (p_evt->evt_id == NRF_BLE_GATT_EVT_DATA_LENGTH_UPDATED))
    +    {
    +        NRF_LOG_INFO("ll len is set to %d", p_gatt->links[m_conn_handle].data_length_effective);
         }
         NRF_LOG_DEBUG("ATT MTU exchange completed. central 0x%x peripheral 0x%x",
                       p_gatt->att_mtu_desired_central,
     

    When you say it doesn't work, is the transfer speed too low, or is it not advertising/connectable? Note that you need to increase the application RAM base when increasing the GAP event length in order to allocate more RAM to the softdevice, see debug log for appropriate RAM base/size. 

    I would suggest to set min=max=15 msec if that works. The connection param module (ble_conn_params.c) will notify the application through the registered callback if the central rejects the requested connection interval. In that case you have request a new longer interval, or disconnect.   

     

     

  • When I say it doesn't work I mean the transfer is too slow and I lose packets or get distorted ones.

    I increased the application RAM but still the mentioned configurations didn't work, was I missing something?

     min=max=15 msec is not a good idea for me since it is the minimum allowed by iOS and Android at the moment, if in next versions of the OS they will decide to raise the minimum as they did before, the application will not work (though 30 msec or longer with longer event length, should).

    Another solution is to use 100-200 msec interval when using low data rate (45 bytes per second) in my case, and lower it to 15 msec when needed. Not sure if it will work though. constant interval of 200-400 with higher event length seems better, as it covers all scenarios.

  • If you see lost or corrupted packets it is likely caused by an error in the application code on one of your devices (see endnode's answer in this thread). As long as ble_nus_data_send() is called with the correct data and returns NRF_SUCCESS you should not see this problem. Have you verified that your ring buffer implementation works as intended? 

    Given that you are checking return codes, your application would have failed during initialization if you had the wrong RAM configuration.

  • As I said, with connection interval of min = 15 max = 15 it works fine, so yes, my ring buffer implementation is good (and used in other projects as well).

    What do I do if ble_nus_data_send returns with something other than NRF_SUCCESS?
    What I currently do is leave the ring buffer indices as they are (as to force re-transmit). What is not clear is if ble_nus_data_send can return with error but manage to send parts of the data, in which case I will get distorted buffers.

    I work in debug mode so I can see if I stop in app_error_fault_handler, so I configured the RAM as was indicated the first time I got an error. still the configurations with higher event length didn't work well.

  • ble_nus_data_send() will only transfer data if it returns NRF_SUCCESS so your buffer handling appears to be correct. But you are less likely to run out of buffer space when you have a shorter CI (15 ms). Please try to increase the hvn queue size to see if it helps:

    in ble_stack_init()

    ...

    // Configure the BLE stack using the default settings.
    // Fetch the start address of the application RAM.
    uint32_t ram_start = 0;
    err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
    APP_ERROR_CHECK(err_code);

    memset(&ble_cfg, 0, sizeof(ble_cfg_t));
    ble_cfg.conn_cfg.conn_cfg_tag = APP_BLE_CONN_CFG_TAG;
    ble_cfg.conn_cfg.params.gatts_conn_cfg.hvn_tx_queue_size = 12;
    err_code = sd_ble_cfg_set(BLE_CONN_CFG_GATTS, &ble_cfg, ram_start);
    APP_ERROR_CHECK(err_code);

Related