Patched version of nrf51822 FOTA compatible driver, with GPTIO disabled, as it clashed with the mbed definitions...

Fork of nRF51822 by Nordic Semiconductor

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers dfu_app_handler.c Source File

dfu_app_handler.c

00001 /* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved.
00002  *
00003  * The information contained herein is property of Nordic Semiconductor ASA.
00004  * Terms and conditions of usage are described in detail in NORDIC
00005  * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
00006  *
00007  * Licensees are granted free, non-transferable use of the information. NO
00008  * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
00009  * the file.
00010  *
00011  */
00012 
00013 #include <string.h>
00014 #include "dfu_app_handler.h "
00015 #include "bootloader_util.h "
00016 #include "nrf.h"
00017 #include "nrf_sdm.h"
00018 #include "ble_gatts.h"
00019 #include "app_error.h "
00020 #include "dfu_ble_svc.h "
00021 #include "device_manager.h "
00022 
00023 #define IRQ_ENABLED            0x01                                            /**< Field identifying if an interrupt is enabled. */
00024 #define MAX_NUMBER_INTERRUPTS  32                                              /**< Maximum number of interrupts available. */
00025 
00026 static void                    dfu_app_reset_prepare(void);                    /**< Forward declare of default reset handler. */
00027 static dfu_app_reset_prepare_t m_reset_prepare = dfu_app_reset_prepare;        /**< Callback function to application to prepare for system reset. Allows application to cleanup of service and memory prior to reset. */
00028 static dfu_ble_peer_data_t     m_peer_data;                                    /**< Peer data to be used for data exchange when reseting into DFU mode. */
00029 static dm_handle_t             m_dm_handle;                                    /**< Device Manager handle with instance id's of current BLE connection. */
00030 static bool                    m_dm_handle_valid = false;                      /**< Variable indicating if the Device Manager handle is valid. */
00031 
00032 
00033 /**@brief Default reset prepare handler if application hasn't registered a handler.
00034  */
00035 static void dfu_app_reset_prepare(void)
00036 {
00037     // Reset prepare should be handled by application.
00038     // This function can be extended to include default handling if application does not implement
00039     // own handler.
00040 }
00041 
00042 
00043 /**@brief Function for disabling all interrupts before jumping from bootloader to application.
00044  */
00045 static void interrupts_disable(void)
00046 {
00047     uint32_t interrupt_setting_mask;
00048     uint32_t irq = 0; // We start from first interrupt, i.e. interrupt 0.
00049 
00050     // Fetch the current interrupt settings.
00051     interrupt_setting_mask = NVIC->ISER[0];
00052 
00053     for (; irq < MAX_NUMBER_INTERRUPTS; irq++)
00054     {
00055         if (interrupt_setting_mask & (IRQ_ENABLED << irq))
00056         {
00057             // The interrupt was enabled, and hence disable it.
00058             NVIC_DisableIRQ((IRQn_Type )irq);
00059         }
00060     }
00061 }
00062 
00063 
00064 /**@brief Function for providing peer information to DFU for re-establishing bonded connection in
00065  *        DFU mode.
00066  */
00067 static void dfu_app_set_peer_data(void)
00068 {
00069     uint32_t        err_code;
00070     dm_sec_keyset_t key_set;
00071 
00072 /** [DFU bond sharing] */
00073     err_code = dm_distributed_keys_get(&m_dm_handle, &key_set);
00074     APP_ERROR_CHECK(err_code);
00075 
00076     m_peer_data.addr     = key_set.keys_central.p_id_key->id_addr_info;
00077     m_peer_data.enc_info = *key_set.keys_central.enc_key.p_enc_info;
00078     m_peer_data.irk      = key_set.keys_central.p_id_key->id_info;
00079 
00080     err_code = dfu_ble_svc_set_peer_data(&m_peer_data);
00081     APP_ERROR_CHECK(err_code);
00082 /** [DFU bond sharing] */
00083 }
00084 
00085 
00086 /**@brief Function for preparing the reset, disabling SoftDevice and jump to the bootloader.
00087  */
00088 void bootloader_start(void)
00089 {
00090     m_reset_prepare();
00091 
00092     uint32_t err_code = sd_power_gpregret_set(BOOTLOADER_DFU_START);
00093     APP_ERROR_CHECK(err_code);
00094 
00095     err_code = sd_softdevice_disable();
00096     APP_ERROR_CHECK(err_code);
00097 
00098     err_code = sd_softdevice_vector_table_base_set(NRF_UICR->BOOTLOADERADDR);
00099     APP_ERROR_CHECK(err_code);
00100 
00101     // Commenting out the following block because it brings in unwanted dependencies from bonding.
00102     // TODO: discuss this with Nordic.
00103     // if (m_dm_handle_valid)
00104     // {
00105     //     dfu_app_set_peer_data();
00106     // }
00107 
00108     NVIC_ClearPendingIRQ(SWI2_IRQn );
00109     interrupts_disable();
00110     bootloader_util_app_start(NRF_UICR->BOOTLOADERADDR);
00111 }
00112 
00113 
00114 void dfu_app_on_dfu_evt(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt)
00115 {
00116     switch (p_evt->ble_dfu_evt_type)
00117     {
00118         case BLE_DFU_START:
00119             // Starting the bootloader - will cause reset.
00120             bootloader_start();
00121             break;
00122 
00123         case BLE_DFU_VALIDATE:
00124         case BLE_DFU_ACTIVATE_N_RESET:
00125         case BLE_DFU_SYS_RESET:
00126         case BLE_DFU_RECEIVE_INIT_DATA:
00127         case BLE_DFU_RECEIVE_APP_DATA:
00128         case BLE_DFU_PACKET_WRITE:
00129         case BLE_DFU_PKT_RCPT_NOTIF_ENABLED:
00130         case BLE_DFU_PKT_RCPT_NOTIF_DISABLED:
00131         case BLE_DFU_BYTES_RECEIVED_SEND:
00132         default:
00133             {
00134                 // Unsupported event received from DFU Service.
00135                 // Send back BLE_DFU_RESP_VAL_NOT_SUPPORTED message to peer.
00136                 uint32_t err_code = ble_dfu_response_send(p_dfu,
00137                                                           BLE_DFU_START_PROCEDURE,
00138                                                           BLE_DFU_RESP_VAL_NOT_SUPPORTED);
00139                 APP_ERROR_CHECK(err_code);
00140             }
00141             break;
00142     }
00143 }
00144 
00145 
00146 void dfu_app_reset_prepare_set(dfu_app_reset_prepare_t reset_prepare_func)
00147 {
00148     m_reset_prepare = reset_prepare_func;
00149 }
00150 
00151 
00152 void dfu_app_set_dm_handle(dm_handle_t const * p_dm_handle)
00153 {
00154     m_dm_handle_valid = false;
00155 
00156     if (p_dm_handle != NULL)
00157     {
00158         m_dm_handle       = *p_dm_handle;
00159         m_dm_handle_valid = true;
00160     }
00161 }
00162