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

How to configure nRF82540 for using multiple BLE packages in one connection interval?

Hi,

I try to achieve high throughput via BLE connection between two nRF82540dk boards. I would like to maximize duty cycle of transmission in the connection interval.
Unfortunately I observe only one or two BLE packets in each interval.
How can I configure SoftDevice to transmit more packets in one interval?

I use slighly modified ble_app_uart_c_pca10056_s140 and ble_app_uart_pca10056_s140 as starting point examples for the serial connection.
A stream of 244 bytes packets is sent from peripheral to the central device. 

Other options:
1) BLE PHY 2Mbps,
2) Connection interval = 7.5ms
3) NRF_SDH_BLE_GAP_EVENT_LENGTH = 6

Kind regards,

Piotr Romaniuk

  • Hi Karl,

    Could you also provide the snippet of code containing all your BLE configurations, from your main.c file?

    sure. 

    [...]
    
    #define APP_ADV_INTERVAL                128                                          /**< 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(7.5, UNIT_1_25_MS)             /**< Minimum acceptable connection interval (20 ms), Connection interval uses 1.25 ms units. */
    #define MAX_CONN_INTERVAL               MSEC_TO_UNITS(7.5, 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. */
    
    [...]
    
    int main(void)
    {
        bool erase_bonds;
    
        // Initialize.
        uart_init();
        log_init();
        timers_init();
        buttons_leds_init(&erase_bonds);
        //power_management_init();
        ble_stack_init();
        gap_params_init();
        gatt_init();
        services_init();
        advertising_init();
        conn_params_init();
    
        nrf_gpio_cfg_output( pin_trig2 );
        nrf_gpio_cfg_output( pin_dbg2 );
    
        // Start execution.
        printf("\r\nUART started.\r\n");
        NRF_LOG_INFO("Debug logging for UART over RTT started.");
        advertising_start();
    
        // Enter main loop.
        for (;;)
        {
            if( m_conn_handle != BLE_CONN_HANDLE_INVALID ){
              idle_state_handle();
            }
        }
    }
    
    
    static void idle_state_handle(void)
    {
        uint32_t err_code;
        uint8_t data_array[244]; 
        int16_t data[100], i, index = sizeof(data_array)-1;
    
        /*if (NRF_LOG_PROCESS() == false)
        {
            nrf_pwr_mgmt_run();
        }*/
    
        for(i = 0; i < (index - 1); i++) 
          data_array[i] = 'U';
    
        static uint8_t pkt_cnt;
        pkt_cnt++;
        if( pkt_cnt >60)
          pkt_cnt=0;
    
        data_array[0]= pkt_cnt+'@';
        data_array[index - 1] = '\n';
        data_array[index] = '\r';
    
        for(i = 0; i < 6; i++){
            data_array[1] = '@'+i;
            do
            {
                uint16_t length = (uint16_t)index+1;
                err_code = ble_nus_data_send(&m_nus, data_array, &length, m_conn_handle);
                
                /*if ((err_code != NRF_ERROR_INVALID_STATE) &&
                    (err_code != NRF_ERROR_RESOURCES) &&
                    (err_code != NRF_ERROR_NOT_FOUND))
                {
                    APP_ERROR_CHECK(err_code);
                }*/
            } while (err_code == NRF_ERROR_RESOURCES);
            nrf_gpio_pin_toggle( pin_dbg2 );
        }
        /*do
        {
            uint16_t length = (uint16_t)index;
            err_code = ble_nus_data_send(&m_nus, data_array, &length, m_conn_handle);
            if ((err_code != NRF_ERROR_INVALID_STATE) &&
                (err_code != NRF_ERROR_RESOURCES) &&
                (err_code != NRF_ERROR_NOT_FOUND))
            {
                APP_ERROR_CHECK(err_code);
            }
        } while (err_code == NRF_ERROR_RESOURCES);*/
        nrf_gpio_pin_write( pin_trig2, 1);
        nrf_delay_ms(100);
        nrf_gpio_pin_write( pin_trig2, 0);
    }
    

    And, just to be clear, is this 8 kB transfer from peripheral to central, or is it central to peripheral?

    From peripheral to central.

    Have you tested the configuration mentioned in the BLE throughput documentation I referenced earlier? Specifically, the configurations from Table 2.

    I tried, but I cannot set event length larger than 6 (i.e. 7.5ms). Runtime memory error appears.

    Kind regards,

    Piotr Romaniuk

  • Piotr Romaniuk said:
    sure. 

    Thank you for sharing this code snippet.

    Piotr Romaniuk said:
    I tried, but I cannot set event length larger than 6 (i.e. 7.5ms). Runtime memory error appears.

    Where do you get this error, and what is the exact error message you encounter?
    Have you defined DEBUG in your preprocessor defines, like shown in the included image?
    This will make a detailed error message be printed to your loggers backend, if a non-NRF_SUCCESS error code is passed to an APP_ERROR_CHECK.


    From your included code snippet it does not look like you pass the returned error codes to an APP_ERROR_CHECK, but rather check them 'manually'. While you are free to do so for specific functions, it is advisable to pass them to an error check and implement the intended handling there instead, for the general case.

    Best regards,
    Karl 

  • Hi Karl,

    DEBUG is not defined in my configuration but I see stack trace and location of APP_ERROR_CHECK that was critical:

    The error code was equal 4.

    Have you defined DEBUG in your preprocessor defines

    If I define DEBUG as you said, there are following messages:

    <info> app_timer: RTC: initialized.
    <warning> nrf_sdh_ble: Insufficient RAM allocated for the SoftDevice.
    <warning> nrf_sdh_ble: Change the RAM start location from 0x20002AE8 to 0x20002BF0.
    <warning> nrf_sdh_ble: Maximum RAM size for application is 0x3D410.
    <error> nrf_sdh_ble: sd_ble_enable() returned NRF_ERROR_NO_MEM.
    <error> app: ERROR 4 [NRF_ERROR_NO_MEM] at [...]\nordic\DeviceDownload\nRF5SDK1702d674dde\nRF5_SDK_171
    PC at: 0x000302F3

    Karl, I sent you private message, where I shared complete code (by a link to zip file) for both devices. I hope you can repeat my problem at your site. 

    Kind regards,

    Piotr Romaniuk

  • Hello again, Piotr

    Piotr Romaniuk said:
    If I define DEBUG as you said, there are following messages:

    Great, this is very helpful! 
    The API Reference documentation for the NRF_ERROR_NO_MEM error returned from sd_ble_enable reads:

    NRF_ERROR_NO_MEM One or more of the following is true:
    • The amount of memory assigned to the SoftDevice by *p_app_ram_base is not large enough to fit this configuration's memory requirement. Check *p_app_ram_base and set the start address of the application RAM region accordingly.
    • Dynamic part of the SoftDevice RAM region is larger then 64 kB which is currently not supported.

    Which suggests that your memory allocation for the SoftDevice are not big enough.
    This is also evident by the other warnings you are getting in your log, saying that the RAM allocated for the SoftDevice is insufficient.
    Please change the RAM start location in your memory allocation macros from 0x20002AE8 to 0x20002BF0 as indicated by the warning message in the log.
    Do this, and let me know if it resolves your issue.

    Best regards,
    Karl

  • Hi Karl,

    How can I change RAM start location?
    That value (i.e. 0x20002AE8) is somehow determined automatically and put into generated linker script.

    Kind regards,

    Piotr Romaniuk

Related