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

Problem in jumping from application to bootloader

Dear team,

Device  - nRF52832
SDK - SDK_15.0.0
IDE - Segger Embedded studio
Softdevice - s132_nrf52_6.0.0

I am doing buttonless DFU in my application. I have successfully build the secure bootloader code and also jump from bootloader to application by following your guidelines.

The problem is that When i tried to jump from application to bootloader it causes "GATT connection timeout" error. I have seen this error in nrfconnect android application. 

But when i remove "CONFIG_AS_GPIO_PINRESET" macro in both codes bootloader and application then everything works perfectly. I don't want to remove this macro but want some another solution .

Please guide me on the same.
Your quick reply would be highly appreciated.

Thanks.  

  • Hi

    Can you confirm that the macro is "CONFIG_GPIO_AS_PINRESET"? What GPIO(s) have you configured as reset pins? Are GPIO(s) configured to the same pins in the bootloader and application?

    Best regards,

    Simon

  • Can you confirm that the macro is "CONFIG_GPIO_AS_PINRESET"?
    Yes, the macro is "CONFIG_GPIO_AS_PINRESET".

    What GPIO(s) have you configured as reset pins?
    I have configured pin P0.21 as reset pin.

     Are GPIO(s) configured to the same pins in the bootloader and application?
    Yes, i have configured P0.21 as reset pin in both bootloader and application code.

  • Hi

    Are you using a custom board or the Development kit? It might be that P0.21 is held high for some reason when you try going from application to bootloader. Could you show me the snippet of your code that makes the application go to the bootloader?

    Best regards,

    Simon

  • /**
     * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
     * 
     * All rights reserved.
     * 
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     * 
     * 1. Redistributions of source code must retain the above copyright notice, this
     *    list of conditions and the following disclaimer.
     * 
     * 2. Redistributions in binary form, except as embedded into a Nordic
     *    Semiconductor ASA integrated circuit in a product or a software update for
     *    such product, must reproduce the above copyright notice, this list of
     *    conditions and the following disclaimer in the documentation and/or other
     *    materials provided with the distribution.
     * 
     * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
     *    contributors may be used to endorse or promote products derived from this
     *    software without specific prior written permission.
     * 
     * 4. This software, with or without modification, must only be used with a
     *    Nordic Semiconductor ASA integrated circuit.
     * 
     * 5. Any software provided in binary form under this license must not be reverse
     *    engineered, decompiled, modified and/or disassembled.
     * 
     * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
     * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     * 
     */
    
    #include <stdint.h>
    #include <stdbool.h>
    #include <stddef.h>
    #include "nrf_dfu_ble_svci_bond_sharing.h"
    #include "nordic_common.h"
    #include "nrf_error.h"
    #include "ble_dfu.h"
    #include "nrf_log.h"
    #include "nrf_sdh_soc.h"
    #include "nrf_gpio.h"
    #include "nrf_delay.h"
    
    #if (!NRF_DFU_BLE_BUTTONLESS_SUPPORTS_BONDS)
    
    #define NRF_DFU_ADV_NAME_MAX_LENGTH     (20)
    
    
    void ble_dfu_buttonless_on_sys_evt(uint32_t, void * );
    uint32_t nrf_dfu_svci_vector_table_set(void);
    uint32_t nrf_dfu_svci_vector_table_unset(void);
    
    /**@brief Define functions for async interface to set new advertisement name for DFU mode.  */
    NRF_SVCI_ASYNC_FUNC_DEFINE(NRF_DFU_SVCI_SET_ADV_NAME, nrf_dfu_set_adv_name, nrf_dfu_adv_name_t);
    
    // Register SoC observer for the Buttonless Secure DFU service
    NRF_SDH_SOC_OBSERVER(m_dfu_buttonless_soc_obs, BLE_DFU_SOC_OBSERVER_PRIO, ble_dfu_buttonless_on_sys_evt, NULL);
    
    ble_dfu_buttonless_t      * mp_dfu = NULL;
    static nrf_dfu_adv_name_t   m_adv_name;
    
    //extern bool ResetPinDisable;
    
    
    /**@brief Function for setting an advertisement name.
     *
     * @param[in]   adv_name    The new advertisement name.
     *
     * @retval NRF_SUCCESS      Advertisement name was successfully set.
     * @retval DFU_RSP_BUSY     Advertisement name was not set because of an ongoing operation.
     * @retval Any other errors from the SVCI interface call.
     */
    static uint32_t set_adv_name(nrf_dfu_adv_name_t * p_adv_name)
    {
        uint32_t err_code;
    
        if (mp_dfu->is_waiting_for_svci)
        {
            return DFU_RSP_BUSY;
        }
    
        err_code = nrf_dfu_set_adv_name(p_adv_name);
        if (err_code == NRF_SUCCESS)
        {
            // The request was accepted.
            mp_dfu->is_waiting_for_svci = true;
        }
        else if (err_code == NRF_ERROR_FORBIDDEN)
        {
            NRF_LOG_ERROR("The bootloader has write protected its settings page. This prohibits setting the advertising name. "\
                          "The bootloader must be compiled with NRF_BL_SETTINGS_PAGE_PROTECT=0 to allow setting the advertising name.");
        }
    
        return err_code;
    }
    
    
    /**@brief Function for entering the bootloader.
     */
    static uint32_t enter_bootloader()
    {
        uint32_t err_code;
    
        if (mp_dfu->is_waiting_for_svci)
        {
            // We have an ongoing async operation. Entering bootloader mode is not possible at this time.
            err_code = ble_dfu_buttonless_resp_send(DFU_OP_ENTER_BOOTLOADER, DFU_RSP_BUSY);
            if (err_code != NRF_SUCCESS)
            {
                mp_dfu->evt_handler(BLE_DFU_EVT_RESPONSE_SEND_ERROR);
    
            }
            
            return NRF_SUCCESS;
        }
    
        // Set the flag indicating that we expect DFU mode.
        // This will be handled on acknowledgement of the characteristic indication.
        mp_dfu->is_waiting_for_reset = true;
    
        err_code = ble_dfu_buttonless_resp_send(DFU_OP_ENTER_BOOTLOADER, DFU_RSP_SUCCESS);
        if (err_code != NRF_SUCCESS)
        {
            mp_dfu->is_waiting_for_reset = false;
        }
        
        return err_code;
    }
    
    
    uint32_t ble_dfu_buttonless_backend_init(ble_dfu_buttonless_t * p_dfu)
    {
        VERIFY_PARAM_NOT_NULL(p_dfu);
    
        mp_dfu = p_dfu;
    
        return NRF_SUCCESS;
    }
    
    
    uint32_t ble_dfu_buttonless_async_svci_init(void)
    {
        uint32_t ret_val;
    
        ret_val = nrf_dfu_svci_vector_table_set();
        VERIFY_SUCCESS(ret_val);
    
        ret_val = nrf_dfu_set_adv_name_init();
        VERIFY_SUCCESS(ret_val);
    
        ret_val = nrf_dfu_svci_vector_table_unset();
    
        return ret_val;
    }
    
    
    void ble_dfu_buttonless_on_sys_evt(uint32_t sys_evt, void * p_context)
    {
        uint32_t err_code;
    
        if (!nrf_dfu_set_adv_name_is_initialized())
        {
            return;
        }
    
        err_code = nrf_dfu_set_adv_name_on_sys_evt(sys_evt);
        if (err_code == NRF_ERROR_INVALID_STATE)
        {
            // The system event is not from an operation started by buttonless DFU.
            // No action is taken, and nothing is reported.
        }
        else if (err_code == NRF_SUCCESS)
        {
            // The async operation is finished.
            // Set the flag indicating that we are waiting for indication response
            // to activate the reset.
            mp_dfu->is_waiting_for_svci = false;
    
            // Report back the positive response
            err_code = ble_dfu_buttonless_resp_send(DFU_OP_SET_ADV_NAME, DFU_RSP_SUCCESS);
            if (err_code != NRF_SUCCESS)
            {
                mp_dfu->evt_handler(BLE_DFU_EVT_RESPONSE_SEND_ERROR);
            }
        }
        else
        {
            // Invalid error code reported back.
            mp_dfu->is_waiting_for_svci = false;
    
            err_code = ble_dfu_buttonless_resp_send(DFU_OP_SET_ADV_NAME, DFU_RSP_BUSY);
            if (err_code != NRF_SUCCESS)
            {
                mp_dfu->evt_handler(BLE_DFU_EVT_RESPONSE_SEND_ERROR);
            }
    
            // Report the failure to enter DFU mode
            mp_dfu->evt_handler(BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED);
        }
    }
    
    
    uint32_t ble_dfu_buttonless_char_add(ble_dfu_buttonless_t * p_dfu)
    {
        ble_gatts_char_md_t char_md         = {{0}};
        ble_gatts_attr_md_t cccd_md         = {{0}};
        ble_gatts_attr_t    attr_char_value = {0};
        ble_gatts_attr_md_t attr_md         = {{0}};
        ble_uuid_t          char_uuid;
    
    
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
    
        cccd_md.vloc = BLE_GATTS_VLOC_STACK;
    
        char_md.char_props.indicate     = 1;
        char_md.char_props.write        = 1;
        char_md.p_char_user_desc        = NULL;
        char_md.p_char_pf               = NULL;
        char_md.p_user_desc_md          = NULL;
        char_md.p_cccd_md               = &cccd_md;
        char_md.p_sccd_md               = NULL;
    
        char_uuid.type = p_dfu->uuid_type;
        char_uuid.uuid = BLE_DFU_BUTTONLESS_CHAR_UUID;
    
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
    
        attr_md.vloc    = BLE_GATTS_VLOC_STACK;
        attr_md.rd_auth = 0;
        attr_md.wr_auth = 1;
        attr_md.vlen    = 1;
    
        attr_char_value.p_uuid    = &char_uuid;
        attr_char_value.p_attr_md = &attr_md;
        attr_char_value.init_len  = 0;
        attr_char_value.init_offs = 0;
        attr_char_value.max_len   = BLE_GATT_ATT_MTU_DEFAULT;
        attr_char_value.p_value   = 0;
    
        return sd_ble_gatts_characteristic_add(p_dfu->service_handle,
                                               &char_md,
                                               &attr_char_value,
                                               &p_dfu->control_point_char);
    }
    
    
    void ble_dfu_buttonless_on_ctrl_pt_write(ble_gatts_evt_write_t const * p_evt_write)
    {
        uint32_t err_code;
        ble_dfu_buttonless_rsp_code_t rsp_code = DFU_RSP_OPERATION_FAILED;
    
        // Start executing the control point write operation
        /*lint -e415 -e416 -save "Out of bounds access"*/
        switch (p_evt_write->data[0])
        {
            case DFU_OP_ENTER_BOOTLOADER:
    //              nrf_gpio_cfg_output(29);
    //              nrf_gpio_pin_set(29);
    //              nrf_delay_ms(2000);
                  err_code = enter_bootloader();
               if (err_code == NRF_SUCCESS)
                {
                    rsp_code = DFU_RSP_SUCCESS;
                    //nrf_gpio_cfg_output(4);
                    //nrf_gpio_pin_set(4);
                    
                }
                else if (err_code == NRF_ERROR_BUSY)
                {
                    rsp_code = DFU_RSP_BUSY;
                    /*nrf_gpio_cfg_output(4);
                    nrf_gpio_pin_set(4);*/
                }
                //break;
    
            case DFU_OP_SET_ADV_NAME:
                if(    (p_evt_write->data[1] > NRF_DFU_ADV_NAME_MAX_LENGTH)
                    || (p_evt_write->data[1] == 0))
                {
                    // New advertisement name too short or too long.
                    rsp_code = DFU_RSP_ADV_NAME_INVALID;
                    
                }
                else
                {
                    memcpy(m_adv_name.name, &p_evt_write->data[2], p_evt_write->data[1]);
                    m_adv_name.len = p_evt_write->data[1];
                    err_code = set_adv_name(&m_adv_name);
                    if (err_code == NRF_SUCCESS)
                    {
                        rsp_code = DFU_RSP_SUCCESS;
                    }
                }
                break;
    
            default:
                rsp_code = DFU_RSP_OP_CODE_NOT_SUPPORTED;
                break;
        }
        /*lint -restore*/
    
    
        // Report back in case of error
        if (rsp_code != DFU_RSP_SUCCESS)
        {
            err_code = ble_dfu_buttonless_resp_send((ble_dfu_buttonless_op_code_t)p_evt_write->data[0], rsp_code);
            if (err_code != NRF_SUCCESS)
            {
                mp_dfu->evt_handler(BLE_DFU_EVT_RESPONSE_SEND_ERROR);
    
            }
            // Report the error to the main application
            mp_dfu->evt_handler(BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED);
        }
    }
    
    uint32_t ble_dfu_buttonless_bootloader_start_prepare(void)
    {
        uint32_t err_code;
    
        
        //nrf_delay_ms(10);
    
        // Indicate to main app that DFU mode is starting.
        mp_dfu->evt_handler(BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE);
    
        err_code = ble_dfu_buttonless_bootloader_start_finalize();
        //ResetPinDisable = true;
        return err_code;
    
    }
    
    #endif // NRF_DFU_BOTTONLESS_SUPPORT_BOND
    
    /**
     * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
     * 
     * All rights reserved.
     * 
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     * 
     * 1. Redistributions of source code must retain the above copyright notice, this
     *    list of conditions and the following disclaimer.
     * 
     * 2. Redistributions in binary form, except as embedded into a Nordic
     *    Semiconductor ASA integrated circuit in a product or a software update for
     *    such product, must reproduce the above copyright notice, this list of
     *    conditions and the following disclaimer in the documentation and/or other
     *    materials provided with the distribution.
     * 
     * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
     *    contributors may be used to endorse or promote products derived from this
     *    software without specific prior written permission.
     * 
     * 4. This software, with or without modification, must only be used with a
     *    Nordic Semiconductor ASA integrated circuit.
     * 
     * 5. Any software provided in binary form under this license must not be reverse
     *    engineered, decompiled, modified and/or disassembled.
     * 
     * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
     * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     * 
     */
    /* Attention!
     *  To maintain compliance with Nordic Semiconductor ASA's Bluetooth profile
     *  qualification listings, this section of source code must not be modified.
     */
    
    #include "ble_dfu.h"
    #include <string.h>
    #include "ble_hci.h"
    #include "sdk_macros.h"
    #include "ble_srv_common.h"
    #include "nrf_nvic.h"
    #include "nrf_sdm.h"
    #include "nrf_soc.h"
    #include "nrf_log.h"
    #include "nrf_dfu_ble_svci_bond_sharing.h"
    #include "nrf_bootloader_info.h"
    #include "nrf_svci_async_function.h"
    #include "nrf_pwr_mgmt.h"
    #include "peer_manager.h"
    #include "gatts_cache_manager.h"
    #include "peer_id.h"
    #include "nrf_gpio.h"
    #include "nrf_delay.h"
    
    #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. */
    
    static ble_dfu_buttonless_t             m_dfu;                      /**< Structure holding information about the Buttonless Secure DFU Service. */
    //extern bool ResetPinDisable;
    NRF_SDH_BLE_OBSERVER(m_dfus_obs, BLE_DFU_BLE_OBSERVER_PRIO, ble_dfu_buttonless_on_ble_evt, &m_dfu);
    
    /**@brief Function for handling write events to the Buttonless Secure DFU Service Service Control Point characteristic.
     *
     * @param[in]   p_evt_write   Write event received from the BLE stack.
     */
    static void on_ctrlpt_write(ble_gatts_evt_write_t const * p_evt_write)
    {
        uint32_t      err_code;
    
    
        ble_gatts_rw_authorize_reply_params_t write_authorize_reply;
        memset(&write_authorize_reply, 0, sizeof(write_authorize_reply));
    
        write_authorize_reply.type   = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
    
        if (m_dfu.is_ctrlpt_indication_enabled)
        {
            write_authorize_reply.params.write.update      = 1;
            write_authorize_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
        }
        else
        {
            write_authorize_reply.params.write.gatt_status = DFU_RSP_CCCD_CONFIG_IMPROPER;
        }
    
        // Authorize the write request
        do {
            err_code = sd_ble_gatts_rw_authorize_reply(m_dfu.conn_handle, &write_authorize_reply);
        } while (err_code == NRF_ERROR_BUSY);
    
    
        if (write_authorize_reply.params.write.gatt_status != BLE_GATT_STATUS_SUCCESS)
        {
            return;
        }
    
        // Forward the write event to the Buttonless DFU module.
        ble_dfu_buttonless_on_ctrl_pt_write(p_evt_write);
    }
    
    
    /**@brief Write authorization request event handler.
     *
     * @details The write authorization request event handler is called when writing to the control point.
     *
     * @param[in]   p_ble_evt Event received from the BLE stack.
     */
    static void on_rw_authorize_req(ble_evt_t const * p_ble_evt)
    {
        if (p_ble_evt->evt.gatts_evt.conn_handle != m_dfu.conn_handle)
        {
            return;
        }
    
        const ble_gatts_evt_rw_authorize_request_t * p_auth_req =
            &p_ble_evt->evt.gatts_evt.params.authorize_request;
    
        if (
            (p_auth_req->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)                            &&
            (p_auth_req->request.write.handle == m_dfu.control_point_char.value_handle)     &&
            (p_auth_req->request.write.op != BLE_GATTS_OP_PREP_WRITE_REQ)                   &&
            (p_auth_req->request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_NOW)               &&
            (p_auth_req->request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL)
           )
        {
            on_ctrlpt_write(&p_auth_req->request.write);
        }
    }
    
    
    /**@brief Connect event handler.
     *
     * @param[in]   p_ble_evt   Event received from the BLE stack.
     */
    static void on_connect(ble_evt_t const * p_ble_evt)
    {
        m_dfu.conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
    }
    
    
    /**@brief Disconnect event handler.
     *
     * @param[in]   p_ble_evt   Event received from the BLE stack.
     */
    static void on_disconnect(ble_evt_t const * p_ble_evt)
    {
        if (m_dfu.conn_handle != p_ble_evt->evt.gatts_evt.conn_handle)
        {
            return;
        }
    
        m_dfu.conn_handle = BLE_CONN_HANDLE_INVALID;
    }
    
    
    /**@brief Write event handler.
     *
     * @param[in]   p_ble_evt Event received from the BLE stack.
     */
    static void on_write(ble_evt_t const * p_ble_evt)
    {
        const ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
    
    //    nrf_gpio_cfg_output(29);
    //    nrf_gpio_pin_set(29);
    //    nrf_delay_ms(300);
    
        if (p_evt_write->handle != m_dfu.control_point_char.cccd_handle)
        {
            return;
        }
    
        if (p_evt_write->len == BLE_CCCD_VALUE_LEN)
        {
            // CCCD written, update indications state
             m_dfu.is_ctrlpt_indication_enabled = ble_srv_is_indication_enabled(p_evt_write->data);
             
             NRF_LOG_INFO("Received indication state %d",
                          m_dfu.is_ctrlpt_indication_enabled);
        }
    }
    
    
    /**@brief Function for handling the HVC events.
     *
     * @details Handles HVC events from the BLE stack.
     *
     * @param[in] p_ble_evt  Event received from the BLE stack.
     */
    static void on_hvc(ble_evt_t const * p_ble_evt)
    {
        uint32_t err_code;
        ble_gatts_evt_hvc_t const * p_hvc = &p_ble_evt->evt.gatts_evt.params.hvc;
    //    nrf_gpio_cfg_output(29);
    //    nrf_gpio_pin_set(29);
    //    nrf_delay_ms(300);
    
        if (p_hvc->handle == m_dfu.control_point_char.value_handle)
        {
    
            // Enter bootloader if we were waiting for reset after hvc indication confimation.
            if (m_dfu.is_waiting_for_reset)
            {
                err_code = ble_dfu_buttonless_bootloader_start_prepare();
                if (err_code != NRF_SUCCESS)
                {
                    m_dfu.evt_handler(BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED);
                }
            }
        }
    }
    
    
    void ble_dfu_buttonless_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
    {
        VERIFY_PARAM_NOT_NULL_VOID(p_ble_evt);
    
        switch (p_ble_evt->header.evt_id)
        {
            case BLE_GAP_EVT_CONNECTED:
                on_connect(p_ble_evt);
                break;
    
            case BLE_GAP_EVT_DISCONNECTED:
                on_disconnect(p_ble_evt);
                break;
    
            case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
    
                on_rw_authorize_req(p_ble_evt);
                break;
    
            case BLE_GATTS_EVT_WRITE:
    
                on_write(p_ble_evt);
                break;
    
            case BLE_GATTS_EVT_HVC:
    
                on_hvc(p_ble_evt);
                break;
    
            default:
                // no implementation
                break;
        }
    }
    
    
    uint32_t ble_dfu_buttonless_resp_send(ble_dfu_buttonless_op_code_t op_code, ble_dfu_buttonless_rsp_code_t rsp_code)
    {
        // Send notification
        uint32_t                err_code;
        const uint16_t          len = 3;
        uint16_t                hvx_len;
        uint8_t                 hvx_data[MAX_CTRL_POINT_RESP_PARAM_LEN];
        ble_gatts_hvx_params_t  hvx_params;
        
    
        memset(&hvx_params, 0, sizeof(hvx_params));
    
        hvx_len = len;
        hvx_data[0] = DFU_OP_RESPONSE_CODE;
        hvx_data[1] = (uint8_t)op_code;
        hvx_data[2] = (uint8_t)rsp_code;
    
        hvx_params.handle   = m_dfu.control_point_char.value_handle;
        hvx_params.type     = BLE_GATT_HVX_INDICATION;
        hvx_params.offset   = 0;
        hvx_params.p_len    = &hvx_len;
        hvx_params.p_data   = hvx_data;
    
    
        err_code = sd_ble_gatts_hvx(m_dfu.conn_handle, &hvx_params);
        if ((err_code == NRF_SUCCESS) && (hvx_len != len))
        {
            err_code = NRF_ERROR_DATA_SIZE;
        }
    
        return err_code;
    }
    
    
    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);
        
    //    nrf_gpio_pin_clear(4);
        // Signal that DFU mode is to be enter to the power management module
    
        
        
        nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_DFU);
        
        //NVIC_SystemReset();
        return NRF_SUCCESS;
    }
    
    
    uint32_t ble_dfu_buttonless_init(const ble_dfu_buttonless_init_t * p_dfu_init)
    {
        uint32_t        err_code;
        ble_uuid_t      service_uuid;
        ble_uuid128_t   nordic_base_uuid = BLE_NORDIC_VENDOR_BASE_UUID;
    
        VERIFY_PARAM_NOT_NULL(p_dfu_init);
    
        // Initialize the service structure.
        m_dfu.conn_handle                  = BLE_CONN_HANDLE_INVALID;
        m_dfu.evt_handler                  = p_dfu_init->evt_handler;
        m_dfu.is_waiting_for_reset         = false;
        m_dfu.is_ctrlpt_indication_enabled = false;
    
        err_code = ble_dfu_buttonless_backend_init(&m_dfu);
        VERIFY_SUCCESS(err_code);
        
        BLE_UUID_BLE_ASSIGN(service_uuid, BLE_DFU_SERVICE_UUID);
    
        // Add the DFU service declaration.
        err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
                                            &service_uuid,
                                            &(m_dfu.service_handle));
    
        VERIFY_SUCCESS(err_code);
    
        // Add vendor specific base UUID to use with the Buttonless DFU characteristic.
        err_code = sd_ble_uuid_vs_add(&nordic_base_uuid, &m_dfu.uuid_type);
        VERIFY_SUCCESS(err_code);
    
        // Add the Buttonless DFU Characteristic (with bonds/without bonds).
        err_code = ble_dfu_buttonless_char_add(&m_dfu);
        VERIFY_SUCCESS(err_code);
    
        return NRF_SUCCESS;
    }
    
    Yes I am using custom board. I am attaching ble_dfu.c and ble_dfu_unbounded.c files of my application code. i have not make any changed in both files. One more thing , What is the need of making reset pin low during jumping from application to bootloader?

Related