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

NRF52840-DK hangs after starting sd_ble_enable() with ATT MTU over 247 bytes

Hello,

I've got a NRF52840-DK development kit and tried to configure it with a ATT MTU size of 512 bytes (larger than 247 bytes). I've activated data length extension and configured the BLE softdevice with the following code:

static uint32_t ble_ram_start = 0x200030d0;
static nrf_clock_lf_cfg_t const softdevice_clock = {
    .source = 1,
    .rc_ctiv = 0,
    .rc_temp_ctiv = 0,
    .accuracy = 7};
  
  //Enable softdevice
  ret_error = sd_softdevice_enable(&softdevice_clock, app_error_fault_handler);
  APP_ERROR_CHECK(ret_error);

  //Enable interrupt handler
  ret_error = sd_nvic_EnableIRQ(SWI2_IRQn);
  APP_ERROR_CHECK(ret_error);
  
  //Create BLE configuration
  ble_cfg_t ble_config;

  //Common CFG
  memset(&ble_config, 0, sizeof(ble_config));
  ble_config.common_cfg.vs_uuid_cfg.vs_uuid_count = 1;   //Number of Vendor UUIDs
  ret_error = sd_ble_cfg_set(BLE_COMMON_CFG_VS_UUID, &ble_config, ble_ram_start); //Configure Common CFG
  APP_ERROR_CHECK(ret_error);                                                     //Check for error

  //CONN CFG GAP
  memset(&ble_config, 0, sizeof(ble_config));
  ble_config.conn_cfg.conn_cfg_tag = 1;                             //Configuration tag for identifiing
  ble_config.conn_cfg.params.gap_conn_cfg.conn_count = 1;        //Maximum connections at a time
  ble_config.conn_cfg.params.gap_conn_cfg.event_length = BLE_GAP_EVENT_LENGTH_MIN; //Minimum event length timing for faster events
  ret_error = sd_ble_cfg_set(BLE_CONN_CFG_GAP, &ble_config, ble_ram_start);        //Configure CONN GAP
  APP_ERROR_CHECK(ret_error);                                                      //Check for error

  //CONN CFG GATT
  memset(&ble_config, 0, sizeof(ble_config));
  ble_config.conn_cfg.conn_cfg_tag = 1;                       //Configuration tag for identifiing
  ble_config.conn_cfg.params.gatt_conn_cfg.att_mtu = 512;           //Set maximum ATT MTU package size like in specification
  ret_error = sd_ble_cfg_set(BLE_CONN_CFG_GATT, &ble_config, ble_ram_start); //Configure CONN GATT
  APP_ERROR_CHECK(ret_error);                                                //Check for error

  //CONN CFG GATTC
  memset(&ble_config, 0, sizeof(ble_config));
  ble_config.conn_cfg.conn_cfg_tag = 1;                                                           //Configuration tag for identifiing
  ble_config.conn_cfg.params.gattc_conn_cfg.write_cmd_tx_queue_size = BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT; //Minimum one write without response request
  ret_error = sd_ble_cfg_set(BLE_CONN_CFG_GATTC, &ble_config, ble_ram_start);                                    //Configure CONN GATTC
  APP_ERROR_CHECK(ret_error);                                                                                    //Check for error

  //CONN CFG GATTS
  memset(&ble_config, 0, sizeof(ble_config));
  ble_config.conn_cfg.conn_cfg_tag = 1;                                               //Configuration tag for identifiing
  ble_config.conn_cfg.params.gatts_conn_cfg.hvn_tx_queue_size = BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT; //Minimum one handle request for queue
  ret_error = sd_ble_cfg_set(BLE_CONN_CFG_GATTS, &ble_config, ble_ram_start);                        //Configure CONN GATTS
  APP_ERROR_CHECK(ret_error);                                                                        //Check for error

  //CONN CFG L2CAP
  memset(&ble_config, 0, sizeof(ble_config));
  ble_config.conn_cfg.conn_cfg_tag = 1; //Configuration tag for identifiing
  ble_config.conn_cfg.params.l2cap_conn_cfg.ch_count = 0; //Turn off L2CAP
  ret_error = sd_ble_cfg_set(BLE_CONN_CFG_L2CAP, &ble_config, ble_ram_start); //Configure CONN L2CAP
  APP_ERROR_CHECK(ret_error);                                                 //Check for error

  //GAP CFG name
  ble_gap_conn_sec_mode_t access_permissions = {.sm = 1, .lv = 1};
  memset(&ble_config, 0, sizeof(ble_config));
  ble_config.gap_cfg.device_name_cfg.write_perm = access_permissions;              //No restrictions in permissions
  ble_config.gap_cfg.device_name_cfg.vloc = BLE_GATTS_VLOC_USER;                   //Name in stack
  ble_config.gap_cfg.device_name_cfg.p_value = device_name;                        //Device name buffer
  ble_config.gap_cfg.device_name_cfg.max_len = sizeof(device_name);                //Maximum size of device name
  ble_config.gap_cfg.device_name_cfg.current_len = sizeof(device_name);            //Size of device name
  ret_error = sd_ble_cfg_set(BLE_GAP_CFG_DEVICE_NAME, &ble_config, ble_ram_start); //Configure device name
  APP_ERROR_CHECK(ret_error);                                                      //Check for error

  //GAP CFG role
  memset(&ble_config, 0, sizeof(ble_config));
  ble_config.gap_cfg.role_count_cfg.adv_set_count = 1;       //Maximum advertising set
  ble_config.gap_cfg.role_count_cfg.periph_role_count = 1;      //Maximum connections as peripheral
  ble_config.gap_cfg.role_count_cfg.central_role_count = 0;                       //Maximum connections as central
  ble_config.gap_cfg.role_count_cfg.central_sec_count = 0;                        //Maximum shared instances as central
  ble_config.gap_cfg.role_count_cfg.qos_channel_survey_role_available = 0;        //Quality survey not available
  ret_error = sd_ble_cfg_set(BLE_GAP_CFG_ROLE_COUNT, &ble_config, ble_ram_start); //Configure gap role
  APP_ERROR_CHECK(ret_error);                                                     //Check for error

  //GATTS CFG attr size
  memset(&ble_config, 0, sizeof(ble_config));
  ble_config.gatts_cfg.attr_tab_size.attr_tab_size = 1408;          //Default GATTS attribute table size
  ret_error = sd_ble_cfg_set(BLE_GATTS_CFG_ATTR_TAB_SIZE, &ble_config, ble_ram_start); //Configure attribute size
  APP_ERROR_CHECK(ret_error);                                                          //Check for error

  //GATTS CFG service changed
  memset(&ble_config, 0, sizeof(ble_config));
  ble_config.gatts_cfg.service_changed.service_changed = 0;                              //Don't include service changed characteristic
  ret_error = sd_ble_cfg_set(BLE_GATTS_CFG_SERVICE_CHANGED, &ble_config, ble_ram_start); //Configure service changed
  APP_ERROR_CHECK(ret_error);                                                            //Check for error

  //Enable BLE
  ret_error = sd_ble_enable(&ble_ram_start);
  APP_ERROR_CHECK(ret_error);

When I enter 247 as the size for the ATT MTU all works perfect, but when I choose a larger number (in my case 512 byte) as ATT MTU, sd_ble_enable() does not return an error and I can debug over the code line. But when I try to step over the APP_ERROR_CHECK, it stops at the assembler command "4B01 ldr r3, [pc, #4]". When I debug through the assembler commands it ends after the command "4798 blx r3" with a NRF_BREAKPOINT_COND. What can I do to use a ATT MTU size over 247 bytes?

Thank you in advance, Jannik

Parents
  • Hi,

    I recommend you build with DEBUG in these cases, as the debug error handler will tell you not only where the error occurred (file and line number), but also the error code.

    I expect you are getting NRF_ERROR_NO_MEM returned from nrf_sdh_ble_enable() because the application RAM start address is too low for the SoftDevice configuration. The typical reason is that when you increase the max ATT MTU the SoftDevice need more memory, and to make room for that you need to move the application RAM start address (and size) in your project/linker configuration. You can see the correct RAM start address and size for your application if you enable debug logging.

Reply
  • Hi,

    I recommend you build with DEBUG in these cases, as the debug error handler will tell you not only where the error occurred (file and line number), but also the error code.

    I expect you are getting NRF_ERROR_NO_MEM returned from nrf_sdh_ble_enable() because the application RAM start address is too low for the SoftDevice configuration. The typical reason is that when you increase the max ATT MTU the SoftDevice need more memory, and to make room for that you need to move the application RAM start address (and size) in your project/linker configuration. You can see the correct RAM start address and size for your application if you enable debug logging.

Children
Related