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
}
}

Parents
  • The peripheral device has been configured to send 240 bytes notification and Iphone received 240 bytes notifications correctly.

     What happens to the peripheral if it enters a connection that doesn't support more than 23 bytes of MTU? Does it still send 240 bytes?

    I suspect that the connectivity_5.1.0_usb_with_s132_5.1.0.uf2 doesn't support MTU higher than 23 bytes, and then it would be impossible to send more than 20 bytes of payload in a packet.

    Where exactly did you find connectivity_5.1.0_usb_with_s132_5.1.0.uf2?

    Perhaps you rather want to look into the SDK16.0.0\examples\connectivity\ble_connectivity - example?

    Or even use some custom ble_peripheral? 

    Even before that, I would suggest that you get hold of an nRF52840 DK for your development. The dongle doesn't have a debugger, so it is very hard to actually develop on the dongle. Once it is working on a DK you can port it to the dongle, if you need the dongle's form factor.

    Best regards,

    Edvin

  • Hi,

    I used the connectivity(connectivity_4.1.1_usb_with_s140_6.1.1) which was downloaded from https://github.com/NordicSemiconductor/pc-ble-driver/releases/tag/v4.1.1.

    The nRF52840 dongle only received 20 bytes, at the same time, Iphone can receive 240 bytes.

    How to configure nRF52840 dongle MTU?

    Is this program enough?

    ...

    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);

    ...

    Best regards!

  • That FW doesn't support connectivity over 20 bytes, is my guess. You should compile your own. Use the example from the path in the previous reply, the ble_connectivity example.

  • I found this prigram from pc-ble-driver\examples\heart_rate_collector.

    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 the ble_connectivity support 250 bytes, will sd_ble_cfg_set(m_adapter() configure MTU to 240 bytes.

    And will nRF52840 dongle receive 240 bytes?

    Best regards!

  • Does it use att_mtu = 240 by default? If so, I would guess. My point is that if you see that it doesn't support more than 20 bytes, you need to find out where in your "blackbox" this is limited. With the example that I linked to, you can configure this. 

    And I still recommend you to get hold of a DK, so that you can debug in realtime. 

Reply Children
  • 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