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

How to configure MTU of nRF52840 dongle?

Hi,

When I used nRF52840 dongle (connectivity_5.1.0_usb_with_s132_5.1.0.uf2 firmware) to receive peripheral device notifications, nRF52840 dongle can only receive 20 bytes. The peripheral device has been configured to send 240 bytes notification and Iphone received 240 bytes notifications correctly.

static uint32_t ble_cfg_set(uint8_t conn_cfg_tag)

{

...

memset(&ble_cfg, 0, sizeof(ble_cfg));

ble_cfg.gap_cfg.role_count_cfg.periph_role_count = 0;
ble_cfg.gap_cfg.role_count_cfg.central_role_count = 1;
ble_cfg.gap_cfg.role_count_cfg.central_sec_count = 0;

error_code = sd_ble_cfg_set(m_adapter, BLE_GAP_CFG_ROLE_COUNT, &ble_cfg, ram_start);
if (error_code != NRF_SUCCESS)
{
printf("sd_ble_cfg_set() failed when attempting to set BLE_GAP_CFG_ROLE_COUNT.\n");
return error_code;
}

memset(&ble_cfg, 0x00, sizeof(ble_cfg));
ble_cfg.conn_cfg.conn_cfg_tag = conn_cfg_tag;
ble_cfg.conn_cfg.params.gatt_conn_cfg.att_mtu = 240; 

error_code = sd_ble_cfg_set(m_adapter, BLE_CONN_CFG_GATTC, &ble_cfg, ram_start);
if (error_code != NRF_SUCCESS)
{
printf("sd_ble_cfg_set() failed when attempting to set BLE_CONN_CFG_GATTC. \n");
return error_code;
}

...

}

static void on_hvx(const ble_gattc_evt_t *const p_ble_gattc_evt)
{
if (p_ble_gattc_evt->params.hvx.handle >= m_hrm_char_handle ||
p_ble_gattc_evt->params.hvx.handle <= m_hrm_cccd_handle) 
{
printf("Received data length: %d\n", p_ble_gattc_evt->params.hvx.len);//Received data length:20
}
}

  • I compiled pc-ble-driver that downloaded from  https://github.com/NordicSemiconductor/pc-ble-driver/releases/tag/v4.1.1. And the nRF52840 dongle received 20 bytes.

    Then I found this file - "pc-ble-driver-4.1.1\hex\nRF5_SDK_15.3.0_connectivity.patch". 

    Line 3783:

    +/** @brief Default MTU size, in bytes. */
    +#define GATT_MTU_SIZE_DEFAULT 23

    I changed this definition:

    +#define GATT_MTU_SIZE_DEFAULT 250

    But the nRF52840 dongle stll received 20 bytes!

  • This is just the default size that will be used in the start of any connection. You should leave it as 23. 

    I suggest that you check out the ble_app_uart and the ble_app_uart_c examples. They both use NRF_SDH_BLE_GATT_MAX_MTU_SIZE 247.

    See how it is used in gatt_init() in main.c:

    /**@brief Function for initializing the GATT library. */
    void gatt_init(void)
    {
        ret_code_t err_code;
    
        err_code = nrf_ble_gatt_init(&m_gatt, gatt_evt_handler);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_ble_gatt_att_mtu_periph_set(&m_gatt, NRF_SDH_BLE_GATT_MAX_MTU_SIZE);
        APP_ERROR_CHECK(err_code);
    }

    And the callback:

     

    /**@brief Function for handling events from the GATT library. */
    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_DEBUG("ATT MTU exchange completed. central 0x%x peripheral 0x%x",
                      p_gatt->att_mtu_desired_central,
                      p_gatt->att_mtu_desired_periph);
    }

    It will print the MTU that the central and peripheral will agree upon.

    Check what you get in the MTU callback.

    BR,

    Edvin

  • As you suggested, I checked out ble_app_uart_c example, but nrf_ble_gatt_att_mtu_central_set() is not available in win10 operating system.

Related