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

create ble_dfu_c - triggering enter bootloader doesn't work

Hello everybody,

i currently develop two devices, one master and one slave (sensor). Both devices have the dfu service completly working.

My problem is that the master should trigger the slave to enter bootloader so that the app could load the new firmware.

So i wrote the ble_dfu_c component to enable indication and enter bootloader.

The slave is responding with 0x20 0x01 0x01, which is the same response doing it over the nrf connect app (over the nrf connect app everything is working).

Is there something i forgot?

NRF52832

SDK: 15.2.0 - S132

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* Device Firmware Update Service Client
*/
#include "sdk_common.h"
#if NRF_MODULE_ENABLED(BLE_DFU_C)
#include "ble_dfu_c.h"
#include <string.h>
#define NRF_LOG_MODULE_NAME ble_dfu_c
#include "nrf_log.h"
NRF_LOG_MODULE_REGISTER();
#define MAX_CTRL_POINT_RESP_PARAM_LEN 3 /**< Max length of the responses. */
#define BLE_DFU_SERVICE_UUID 0xFE59 /**< The 16-bit UUID of the Secure DFU Service. */
/**@brief Function that is called if no event handler is provided.
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ble_dfu_c.h

Parents
  • Hi Andrej, 

    The slave is responding to the Enter Bootloader request with a Handle value indication which should be confirmed by the master. This will confirmation will generate the BLE_GATTS_EVT_HVC event on the slave side which will call ble_dfu_buttonless_bootloader_start_finalize() which in turn will write to the GPREGRET register and then reset the chip, see below. 

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    uint32_t ble_dfu_buttonless_bootloader_start_finalize(void)
    {
    uint32_t err_code;
    NRF_LOG_DEBUG("In ble_dfu_buttonless_bootloader_start_finalize\r\n");
    err_code = sd_power_gpregret_clr(0, 0xffffffff);
    VERIFY_SUCCESS(err_code);
    err_code = sd_power_gpregret_set(0, BOOTLOADER_DFU_START);
    VERIFY_SUCCESS(err_code);
    // Indicate that the Secure DFU bootloader will be entered
    m_dfu.evt_handler(BLE_DFU_EVT_BOOTLOADER_ENTER);
    // Signal that DFU mode is to be enter to the power management module
    nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_DFU);
    return NRF_SUCCESS;
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    So since you're getting the 0x20 0x01 0x01 reponse( which is the indication) can you check that the BLE_GATTS_EVT_HVC is generated on the slave side and that ble_dfu_buttonless_bootloader_start_finalize() is called? If it is then the bootloader should be advertising with the device name set to DfuTarget and increment the physical address with one ( if you're using unbonded DFU).

    Best regards

    Bjørn

  • Hi Bjorn,

    thanks for your reply. That was the problem.

  • Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    static void on_hvx(ble_dfu_c_t *p_ble_dfu_c, ble_evt_t const *p_ble_evt)
    {
    // HVX can only occur from client sending.
    if (p_ble_evt->evt.gattc_evt.params.hvx.handle == p_ble_dfu_c->handles.dfu_buttonless_handle )
    {
    ble_dfu_c_evt_t ble_dfu_c_evt;
    ret_code_t err_code=sd_ble_gattc_hv_confirm(p_ble_evt->evt.gattc_evt.conn_handle,
    p_ble_evt->evt.gattc_evt.params.hvx.handle);
    APP_ERROR_CHECK(err_code);
    printf(">>>recv:");
    for(uint8_t i=0;i<p_ble_evt->evt.gattc_evt.params.hvx.len;i++ )
    printf("%d ",p_ble_evt->evt.gattc_evt.params.hvx.data[i]);
    printf("\r\n");
    ble_dfu_c_evt.evt_type = BLE_DFU_C_EVT_ENTER_BOOTLOADER;
    if(p_ble_dfu_c->evt_handler != NULL)
    p_ble_dfu_c->evt_handler(p_ble_dfu_c, &ble_dfu_c_evt);
    }
    if (p_ble_evt->evt.gattc_evt.params.hvx.handle == p_ble_dfu_c->handles.dfu_control_handle)
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Call sd_ble_gattc_hv_confirm after receiving the response

Reply
  • Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    static void on_hvx(ble_dfu_c_t *p_ble_dfu_c, ble_evt_t const *p_ble_evt)
    {
    // HVX can only occur from client sending.
    if (p_ble_evt->evt.gattc_evt.params.hvx.handle == p_ble_dfu_c->handles.dfu_buttonless_handle )
    {
    ble_dfu_c_evt_t ble_dfu_c_evt;
    ret_code_t err_code=sd_ble_gattc_hv_confirm(p_ble_evt->evt.gattc_evt.conn_handle,
    p_ble_evt->evt.gattc_evt.params.hvx.handle);
    APP_ERROR_CHECK(err_code);
    printf(">>>recv:");
    for(uint8_t i=0;i<p_ble_evt->evt.gattc_evt.params.hvx.len;i++ )
    printf("%d ",p_ble_evt->evt.gattc_evt.params.hvx.data[i]);
    printf("\r\n");
    ble_dfu_c_evt.evt_type = BLE_DFU_C_EVT_ENTER_BOOTLOADER;
    if(p_ble_dfu_c->evt_handler != NULL)
    p_ble_dfu_c->evt_handler(p_ble_dfu_c, &ble_dfu_c_evt);
    }
    if (p_ble_evt->evt.gattc_evt.params.hvx.handle == p_ble_dfu_c->handles.dfu_control_handle)
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Call sd_ble_gattc_hv_confirm after receiving the response

Children
No Data