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

DFU Mode through selecting the GPREGRET Register

Hi Nordic Team,

I'm working with Nordic NRF52832 BLE development Kit. Currently, we are working with DFU Secure bootloader. In this bootloader, we tried the button pressed mode, it goes to DFU mode. I tried  to enable the  GPREGRET by NRF_BL_DFU_ENTER_METHOD_GPREGRET 1 , Bootloader code isn't goes to DFU mode. Without Button, How to enable the GPREGRET register?. 

Please give solution for the above problems.

Thanks & Regards,

Poovai Anitha.L

Parents
  • HI Poovai, in order to enter the bootloader using the GPREGRET method you will need to write a specific value to the GPREGRET register and then perform a SoftReset. This is how we do it in our ble_app_buttonless_dfu example. 

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

    Best regards

    Bjørn

Reply
  • HI Poovai, in order to enter the bootloader using the GPREGRET method you will need to write a specific value to the GPREGRET register and then perform a SoftReset. This is how we do it in our ble_app_buttonless_dfu example. 

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

    Best regards

    Bjørn

Children
  • Hello Bjorn,

       I am wondering if you could share the declaration of

    1- m_dfu. 

    I found one in nrf_dfu_ble.h in the secure_bootloader_ble_s140_pca10056 in SDK 17.2

    typedef struct
    {
        uint16_t                     service_handle;                        /**< Handle of the DFU Service (as provided by the SoftDevice). */
        uint8_t                      uuid_type;                                  /**< UUID type assigned to the DFU Service by the SoftDevice. */
        ble_gatts_char_handles_t     dfu_pkt_handles;          /**< Handles related to the DFU Packet Characteristic. */
        ble_gatts_char_handles_t     dfu_ctrl_pt_handles;     /**< Handles related to the DFU Control Point Characteristic. */
    } ble_dfu_t;

    but this one doesn't have evt_handler as a member.

    Also where are these macros declared?

    2- BLE_DFU_EVT_BOOTLOADER_ENTER, and

    3- NRF_PWR_MGMT_SHUTDOWN_GOTO_DFU

    Would this function be called from main application to start a subsequent DFU?

    Thanks,

    Mano

  • Hi Mano, 

    You should look at the ble_app_buttonless_dfu example found in examples\ble_peripheral\ble_app_buttonless_dfu. The decleration of m_dfu looks like this. 

    // Declared in ble_dfu.c
    static ble_dfu_buttonless_t             m_dfu;                      /**< Structure holding information about the Buttonless Secure DFU Service. */
    
    
    // Declared in ble_dfu.h 
    
    /**@brief Type holding memory used by Secure DFU Buttonless Service.
      */
    typedef struct
    {
        uint8_t                             uuid_type;                      /**< UUID type for DFU UUID. */
        uint16_t                            service_handle;                 /**< Service Handle of DFU (as provided by the SoftDevice). */
        uint16_t                            conn_handle;                    /**< Connection handle for the current peer. */
        ble_gatts_char_handles_t            control_point_char;             /**< Handles related to the DFU Control Point characteristic. */
        uint32_t                            peers_count;                    /**< Counter to see how many persistently stored peers must be updated for Service Changed indication. This value will be counted down when comparing write requests. */
        ble_dfu_buttonless_evt_handler_t    evt_handler;                    /**< Event handler that is called upon Buttonless DFU events. See @ref ble_dfu_buttonless_evt_type_t. */
        bool                                is_waiting_for_reset;           /**< Flag indicating that the device will enter bootloader. */
        bool                                is_waiting_for_svci;            /**< Flag indicating that the device is waiting for async SVCI operation */
    } ble_dfu_buttonless_t;

    BLE_DFU_EVT_BOOTLOADER_ENTER and NRF_PWR_MGMT_SHUTDOWN_GOTO_DFU are enumerations, not macros. 

    The declaration of the BLE_DFU_EVT_BOOTLOADER_ENTER enum is found in

    /**@brief Nordic Buttonless DFU Service event type .
     */
    typedef enum
    {
        BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE,   /**< Event indicating that the device is preparing to enter bootloader.*/
        BLE_DFU_EVT_BOOTLOADER_ENTER,           /**< Event indicating that the bootloader will be entered after return of this event.*/
        BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED,    /**< Failure to enter bootloader mode.*/
        BLE_DFU_EVT_RESPONSE_SEND_ERROR,        /**< Failure to send response.*/
    } ble_dfu_buttonless_evt_type_t;

    The declaration of the NRF_PWR_MGMT_SHUTDOWN_GOTO_DFU enum is found in nrf_pwr_mgmt.h

    /**@brief Power management shutdown types. */
    typedef enum
    {
        NRF_PWR_MGMT_SHUTDOWN_GOTO_SYSOFF,
        //!< Go to System OFF.
    
        NRF_PWR_MGMT_SHUTDOWN_STAY_IN_SYSOFF,
        //!< Go to System OFF and stay there.
        /**<
         * Useful when battery level is dangerously low, for example.
         */
    
        NRF_PWR_MGMT_SHUTDOWN_GOTO_DFU,
        //!< Go to DFU mode.
    
        NRF_PWR_MGMT_SHUTDOWN_RESET,
        //!< Reset chip.
    
        NRF_PWR_MGMT_SHUTDOWN_CONTINUE
        //!< Continue shutdown.
        /**<
         * This should be used by modules that block the shutdown process, when they become ready for
         * shutdown.
         */
    } nrf_pwr_mgmt_shutdown_t;

    Mano said:
    Would this function be called from main application to start a subsequent DFU?

     Yes, the ble_dfu_buttonless_bootloader_start_finalize function should be called from the main application to enter bootloader mode. 

Related