Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of nRF51822 by
Revision 66:b3680699d9a4, committed 2014-09-22
- 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
--- 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__
+
+/** @} */
