SG RFID nRF51822 fork

Fork of nRF51822 by Nordic Semiconductor

Files at this revision

API Documentation at this revision

Comitter:
Rohit Grover
Date:
Mon Sep 22 11:19:51 2014 +0100
Parent:
65:98215c4f3a25
Child:
67:e6cc149033a6
Commit message:
Release 0.2.0
=============

Highlights:
Add support for over-the-air firmware updates.

Features
~~~~~~~~

- Add files to support DFU bootloader.

- charHandle is now a part of GattCharacteristicWriteCBParams.

- nRF51GattServer::addService(): Skip any incompletely defined, read-only
characteristics. For instance, the DeviceInformationService may have many
optional, read-only characteristics which may be safely dropped if the
application hasn't defined them.

Bugfixes
~~~~~~~~

None.

Compatibility
~~~~~~~~~~~~~

Works with 0.2.0 of BLE_API.

Changed in this revision

btle/custom/custom_helper.cpp Show annotated file Show diff for this revision Revisions of this file
nRF51GattServer.cpp Show annotated file Show diff for this revision Revisions of this file
nordic/bootloader_dfu/bootloader_util_arm.c Show annotated file Show diff for this revision Revisions of this file
nordic/bootloader_dfu/dfu_app_handler.c Show annotated file Show diff for this revision Revisions of this file
nordic/nrf-sdk/bootloader_dfu/bootloader_types.h Show annotated file Show diff for this revision Revisions of this file
nordic/nrf-sdk/bootloader_dfu/bootloader_util.h Show annotated file Show diff for this revision Revisions of this file
nordic/nrf-sdk/bootloader_dfu/dfu_app_handler.h Show annotated file Show diff for this revision Revisions of this file
--- a/btle/custom/custom_helper.cpp	Mon Sep 08 17:21:46 2014 +0100
+++ b/btle/custom/custom_helper.cpp	Mon Sep 22 11:19:51 2014 +0100
@@ -26,16 +26,14 @@
     LongUUIDBytes_t uuid;
     uint8_t         type;
 } converted_uuid_table_entry_t;
-static const unsigned UUID_TABLE_MAX_ENTRIES = 8; /* This is the maximum number
-                                    * of 128-bit UUIDs with distinct bases that
-                                    * we expect to be in use; increase this
-                                    * limit if needed. */
+static const unsigned UUID_TABLE_MAX_ENTRIES = 8; /* This is the maximum number of 128-bit UUIDs with distinct bases that
+                                                   * we expect to be in use; increase this limit if needed. */
 static unsigned uuidTableEntries = 0; /* current usage of the table */
 converted_uuid_table_entry_t convertedUUIDTable[UUID_TABLE_MAX_ENTRIES];
 
 /**
  * lookup the cache of previously converted 128-bit UUIDs to find a type value.
- * @param  uuid          long UUID
+ * @param  uuid          base 128-bit UUID
  * @param  recoveredType the type field of the 3-byte nRF's uuid.
  * @return               true if a match is found.
  */
@@ -44,9 +42,7 @@
 {
     unsigned i;
     for (i = 0; i < uuidTableEntries; i++) {
-        if (memcmp(convertedUUIDTable[i].uuid,
-                   uuid,
-                   LENGTH_OF_LONG_UUID) == 0) {
+        if (memcmp(convertedUUIDTable[i].uuid, uuid, LENGTH_OF_LONG_UUID) == 0) {
             *recoveredType = convertedUUIDTable[i].type;
             return true;
         }
@@ -59,8 +55,7 @@
 addToConvertedUUIDTable(const LongUUIDBytes_t uuid, uint8_t type)
 {
     if (uuidTableEntries == UUID_TABLE_MAX_ENTRIES) {
-        return; /* recovery needed; or at least the user should be
-                 * warned about this fact.*/
+        return; /* recovery needed; or at least the user should be warned about this fact.*/
     }
 
     memcpy(convertedUUIDTable[uuidTableEntries].uuid, uuid,LENGTH_OF_LONG_UUID);
--- a/nRF51GattServer.cpp	Mon Sep 08 17:21:46 2014 +0100
+++ b/nRF51GattServer.cpp	Mon Sep 22 11:19:51 2014 +0100
@@ -60,6 +60,13 @@
     for (uint8_t i = 0; i < service.getCharacteristicCount(); i++) {
         GattCharacteristic *p_char = service.getCharacteristic(i);
 
+        /* Skip any incompletely defined, read-only characteristics. */
+        if ((p_char->getValueAttribute().getValuePtr() == NULL) &&
+            (p_char->getValueAttribute().getInitialLength() == 0) &&
+            (p_char->getProperties() == GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ)) {
+            continue;
+        }
+
         nordicUUID = custom_convert_to_nordic_uuid(p_char->getValueAttribute().getUUID());
 
         ASSERT ( ERROR_NONE ==
@@ -277,12 +284,13 @@
             switch (eventType) {
                 case GattServerEvents::GATT_EVENT_DATA_WRITTEN: {
                     GattCharacteristicWriteCBParams cbParams = {
+                        .charHandle = i,
                         .op     = static_cast<GattCharacteristicWriteCBParams::Type>(gattsEventP->params.write.op),
                         .offset = gattsEventP->params.write.offset,
                         .len    = gattsEventP->params.write.len,
                         .data   = gattsEventP->params.write.data
                     };
-                    handleDataWrittenEvent(i, &cbParams);
+                    handleDataWrittenEvent(&cbParams);
                     break;
                 }
                 default:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nordic/bootloader_dfu/bootloader_util_arm.c	Mon Sep 22 11:19:51 2014 +0100
@@ -0,0 +1,91 @@
+/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+
+#include "bootloader_util.h"
+#include <stdint.h>
+
+
+/**
+ * @brief Function for aborting current handler mode and jump to to other application/bootloader.
+ *
+ * @details This functions will use the address provide (reset handler) to be executed after 
+ *          handler mode is exited. It creates an initial stack to ensure correct reset behavior 
+ *          when the reset handler is executed.
+ *
+ * @param[in]  reset_handler  Address of the reset handler to be executed when handler mode exits.
+ *
+ * @note This function must never be called directly from 'C' but is intended only to be used from 
+ *       \ref bootloader_util_reset. This function will never return but issue a reset into 
+ *       provided address.
+ */
+__asm void isr_abort(uint32_t reset_handler)
+{
+xPSR_RESET      EQU 0x21000000  ; Default value of xPSR after System Reset.
+EXC_RETURN_CMD  EQU 0xFFFFFFF9  ; EXC_RETURN for ARM Cortex. When loaded to PC the current interrupt service routine (handler mode) willl exit and the stack will be popped. Execution will continue in thread mode.
+
+    LDR   R4,=MASK_ONES         ; Fill with ones before jumping to reset handling. We be popped as R12 when exiting ISR (Cleaning up the registers).
+    LDR   R5,=MASK_ONES         ; Fill with ones before jumping to reset handling. We be popped as LR when exiting ISR. Ensures no return to application.
+    MOV   R6, R0                ; Move address of reset handler to R6. Will be popped as PC when exiting ISR. Ensures the reset handler will be executed when exist ISR.
+    LDR   R7,=xPSR_RESET        ; Move reset value of xPSR to R7. Will be popped as xPSR when exiting ISR.
+    PUSH  {r4-r7}               ; Push everything to new stack to allow interrupt handler to fetch it on exiting the ISR.
+    
+    LDR   R4,=MASK_ZEROS        ; Fill with zeros before jumping to reset handling. We be popped as R0 when exiting ISR (Cleaning up of the registers).
+    LDR   R5,=MASK_ZEROS        ; Fill with zeros before jumping to reset handling. We be popped as R1 when exiting ISR (Cleaning up of the registers).
+    LDR   R6,=MASK_ZEROS        ; Fill with zeros before jumping to reset handling. We be popped as R2 when exiting ISR (Cleaning up of the registers).
+    LDR   R7,=MASK_ZEROS        ; Fill with zeros before jumping to reset handling. We be popped as R3 when exiting ISR (Cleaning up of the registers).
+    PUSH  {r4-r7}               ; Push zeros (R4-R7) to stack to prepare for exiting the interrupt routine.
+    
+    LDR   R0,=EXC_RETURN_CMD    ; Load the execution return command into register.
+    BX    R0                    ; No return - Handler mode will be exited. Stack will be popped and execution will continue in reset handler initializing other application.
+    ALIGN
+}
+
+
+/**
+ * @brief Function for aborting current application/bootloader jump to to other app/bootloader.
+ *
+ * @details This functions will use the address provide to swap the stack pointer and then load 
+ *          the address of the reset handler to be executed. It will check current system mode 
+ *          (thread/handler) and if in thread mode it will reset into other application.
+ *          If in handler mode \ref isr_abort will be executed to ensure correct exit of handler 
+ *          mode and jump into reset handler of other application.
+ *
+ * @param[in]  start_addr  Start address of other application. This address must point to the 
+               initial stack pointer of the application.
+ *
+ * @note This function will never return but issue a reset into provided application.
+ */
+__asm static void bootloader_util_reset(uint32_t start_addr)
+{
+MASK_ONES       EQU 0xFFFFFFFF  ; Ones, to be loaded into register as default value before reset.
+MASK_ZEROS      EQU 0x00000000  ; Zeros, to be loaded into register as default value before reset.
+
+    LDR   R1, [R0]              ; Get App initial MSP for bootloader.
+    MSR   MSP, R1               ; Set the main stack pointer to the applications MSP.
+    LDR   R0,[R0, #0x04]        ; Load Reset handler into register 0.
+    
+    LDR   R2, =MASK_ZEROS       ; Load zeros to R2
+    MRS   R3, IPSR              ; Load IPSR to R3 to check for handler or thread mode 
+    CMP   R2, R3                ; Compare, if 0 then we are in thread mode and can continue to reset handler of bootloader
+    BNE   isr_abort             ; If not zero we need to exit current ISR and jump to reset handler of bootloader
+
+    LDR   R4, =MASK_ONES        ; Load ones to R4 to be placed in Link Register.
+    MOV   LR, R4                ; Clear the link register and set to ones to ensure no return.
+    BX    R0                    ; Branch to reset handler of bootloader
+    ALIGN
+}
+
+
+void bootloader_util_app_start(uint32_t start_addr)
+{
+    bootloader_util_reset(start_addr);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nordic/bootloader_dfu/dfu_app_handler.c	Mon Sep 22 11:19:51 2014 +0100
@@ -0,0 +1,81 @@
+/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+
+#include "dfu_app_handler.h"
+#include "bootloader_util.h"
+#include "nrf_sdm.h"
+#include "app_error.h"
+
+#define IRQ_ENABLED             0x01                                            /**< Field identifying if an interrupt is enabled. */
+#define MAX_NUMBER_INTERRUPTS   32                                              /**< Maximum number of interrupts available. */
+
+static void                     dfu_app_reset_prepare(void);                    /**< Forward declare of default reset handler. */
+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. */
+
+
+/**@brief Default reset prepare handler if application hasn't registered a handler.
+ */
+static void dfu_app_reset_prepare(void)
+{
+    // Reset prepare should be handled by application.
+    // This function can be extended to include default handling if application does not implement
+    // own handler.
+}
+
+
+/**@brief Function for disabling all interrupts before jumping from bootloader to application.
+ */
+static void interrupts_disable(void)
+{
+    uint32_t interrupt_setting_mask;
+    uint32_t irq = 0; // We start from first interrupt, i.e. interrupt 0.
+
+    // Fetch the current interrupt settings.
+    interrupt_setting_mask = NVIC->ISER[0];
+
+    for (; irq < MAX_NUMBER_INTERRUPTS; irq++)
+    {
+        if (interrupt_setting_mask & (IRQ_ENABLED << irq))
+        {
+            // The interrupt was enabled, and hence disable it.
+            NVIC_DisableIRQ((IRQn_Type)irq);
+        }
+    }
+}
+
+
+/**@brief Function for preparing the reset, disabling SoftDevice and jump to the bootloader.
+ */
+void bootloader_start(void)
+{
+    m_reset_prepare();
+
+    uint32_t err_code = sd_power_gpregret_set(BOOTLOADER_DFU_START);
+    APP_ERROR_CHECK(err_code);
+
+    err_code = sd_softdevice_disable();
+    APP_ERROR_CHECK(err_code);
+
+    interrupts_disable();
+
+    err_code = sd_softdevice_vector_table_base_set(NRF_UICR->BOOTLOADERADDR);
+    APP_ERROR_CHECK(err_code);
+
+    bootloader_util_app_start(NRF_UICR->BOOTLOADERADDR);
+}
+
+
+
+void dfu_app_reset_prepare_set(dfu_app_reset_prepare_t reset_prepare_func)
+{
+    m_reset_prepare = reset_prepare_func;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nordic/nrf-sdk/bootloader_dfu/bootloader_types.h	Mon Sep 22 11:19:51 2014 +0100
@@ -0,0 +1,57 @@
+/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+ 
+/**@file
+ *
+ * @defgroup nrf_bootloader_types Types and definitions.
+ * @{     
+ *  
+ * @ingroup nrf_bootloader
+ * 
+ * @brief Bootloader module type and definitions.
+ */
+ 
+#ifndef BOOTLOADER_TYPES_H__
+#define BOOTLOADER_TYPES_H__
+
+#include <stdint.h>
+
+#define BOOTLOADER_DFU_START 0xB1
+
+/**@brief DFU Bank state code, which indicates wether the bank contains: A valid image, invalid image, or an erased flash.
+  */
+typedef enum
+{
+    BANK_VALID_APP   = 0x01,
+    BANK_VALID_SD    = 0xA5,
+    BANK_VALID_BOOT  = 0xAA,
+    BANK_ERASED      = 0xFE,
+    BANK_INVALID_APP = 0xFF,
+} bootloader_bank_code_t;
+
+/**@brief Structure holding bootloader settings for application and bank data.
+ */
+typedef struct
+{
+    bootloader_bank_code_t bank_0;          /**< Variable to store if bank 0 contains a valid application. */
+    uint16_t               bank_0_crc;      /**< If bank is valid, this field will contain a valid CRC of the total image. */
+    bootloader_bank_code_t bank_1;          /**< Variable to store if bank 1 has been erased/prepared for new image. Bank 1 is only used in Banked Update scenario. */
+    uint32_t               bank_0_size;     /**< Size of active image in bank0 if present, otherwise 0. */
+    uint32_t               sd_image_size;   /**< Size of SoftDevice image in bank0 if bank_0 code is \ref BANK_VALID_SD. */
+    uint32_t               bl_image_size;   /**< Size of Bootloader image in bank0 if bank_0 code is \ref BANK_VALID_SD. */
+    uint32_t               app_image_size;  /**< Size of Application image in bank0 if bank_0 code is \ref BANK_VALID_SD. */
+    uint32_t               sd_image_start;  /**< Location in flash where SoftDevice image is stored for SoftDevice update. */
+} bootloader_settings_t;
+
+#endif // BOOTLOADER_TYPES_H__ 
+
+/**@} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nordic/nrf-sdk/bootloader_dfu/bootloader_util.h	Mon Sep 22 11:19:51 2014 +0100
@@ -0,0 +1,38 @@
+/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+
+ /**@file
+ *
+ * @defgroup nrf_bootloader_util Bootloader util API.
+ * @{     
+ *  
+ * @brief Bootloader util module interface.
+ */
+ 
+#ifndef BOOTLOADER_UTIL_H__
+#define BOOTLOADER_UTIL_H__
+
+#include <stdint.h>
+#include "bootloader_types.h"
+
+/**@brief Function for starting the application (or bootloader) at the provided address.
+ * 
+ * @param[in]  start_addr             Start address.
+ *
+ * @note This function will never retrun. Instead it will reset into the application of the 
+ *       provided address.
+ */
+void bootloader_util_app_start(uint32_t start_addr);
+
+#endif // BOOTLOADER_UTIL_H__
+
+/**@} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nordic/nrf-sdk/bootloader_dfu/dfu_app_handler.h	Mon Sep 22 11:19:51 2014 +0100
@@ -0,0 +1,72 @@
+/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+  
+/** @file
+ *
+ * @defgroup nrf_dfu_app_handler DFU BLE packet handling in Application
+ * @{
+ *
+ * @brief DFU BLE packet handling for application.
+ *
+ * @details This module implements handling of DFU packets transmitted over BLE for switching from 
+ *          application mode to Bootloader running full DFU service.
+ *          This module only handles the StartDFU packet allowing for any BLE application to expose
+ *          support for the DFU service.
+ *          Actual DFU service will execute in dedicated environment after a BLE disconnect and 
+ *          reset of the nRF51 chip.
+ *          The host must then reconnect and can continue the update procedure with access to full
+ *          DFU service.
+ *
+ * @note The application must propagate dfu events to the DFU App handler module by calling
+ *       dfu_app_on_dfu_evt() from the from the @ref ble_dfu_evt_handler_t callback.
+ */
+ 
+#ifndef DFU_APP_HANDLER_H__
+#define DFU_APP_HANDLER_H__
+
+#include "dfu_app_handler.h"
+#include "ble_dfu.h"
+
+/**@brief DFU Application reset prepare function. This function is a callback which allows the 
+ *        application to prepare for an upcoming application reset. 
+ */
+typedef void (*dfu_app_reset_prepare_t)(void);
+
+
+/**@brief   Function for handling of \ref ble_dfu_evt_t from DFU Service. 
+ *
+ * @details The application must inject this function into the DFU service or propagate DFU events
+ *          to dfu_app_handler module by calling this function in application specific DFU event 
+ *          handler.
+ * 
+ * @param[in] p_dfu  Pointer to the DFU Service structure for which the include event relates.
+ * @param[in] p_evt  Pointer to the DFU event.
+ */
+void dfu_app_on_dfu_evt(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt);
+
+
+/**@brief Function for registering for reset prepare calls. 
+ *
+ * @details The function provided will be executed before reseting the system into Bootloader/DFU
+ *          mode. By setting this function the caller will be notified prior to the reset and can
+ *          thus prepare the application for reset. As example the application can gracefully
+ *          disconnect any peers on BLE, turning of LEDS, ensure all pending flash operations
+ *          has completed, etc.
+ *
+ * @param[in] reset_prepare_func  Function to be execute prior to a reset.
+ */
+void dfu_app_reset_prepare_set(dfu_app_reset_prepare_t reset_prepare_func);
+
+
+#endif // DFU_APP_HANDLER_H__
+
+/** @} */