PBL mbed final
Fork of nRF51822 by
Revision 510:7dded1f7473c, committed 2015-12-02
- Comitter:
- rgrover1
- Date:
- Wed Dec 02 12:35:26 2015 +0000
- Parent:
- 509:7dc75f30064f
- Child:
- 511:2df149fad2cd
- Commit message:
- Synchronized with git rev a5a46f2f
Author: Rohit Grover
Release 2.0.7
=============
* Fix a bug in the assembly sequence that starts the Nordic bootloader. With
GCC, a MOV instruction was getting converted into an ADDS, which came with
an unwanted side-effect of updating the XPSR. We relocated the offending MOV
instruction such that it would not affect a conditional branch statement.
This would show only with GCC, and when jumping to the bootloader while in
handler mode.
* Fix hardfaults generated from the handling of Radio Notification events.
Radio notification events are interrupts generated at very high priority.
They have the potential to pre-empt other interrupt handling, causing race
conditions when interrupted handlers were involved in calling into BLE_API.
Radio-notification events should defer their callback handling to low-
priority handlers through the use of Tickers or Timeouts.
* Introduce watchdog header file from Nordic SDK 8.1.
* Update license headers to reflect the latest licenses from Nordic.
Changed in this revision
--- a/LICENSE Wed Dec 02 12:35:26 2015 +0000 +++ b/LICENSE Wed Dec 02 12:35:26 2015 +0000 @@ -1,6 +1,9 @@ Many of the files in this module have been inherited from the Nordic SDK for -nRF51822; they come with a BSD-like license offered by Nordic for use in mbed. -Some other files come from the mbed SDK, and are licensed under Apache-2.0. -Unless specifically indicated otherwise in a file, files are licensed -under the Apache 2.0 license, as can be found in: apache-2.0.txt. -The BSD-like Nordic license can be found in BSD-3clause-Nordic.txt \ No newline at end of file +nRF51822. With the exception of the softdevice, they come with a BSD license +offered by Nordic for use in mbed. The Nordic Softdevice License Agreement, a +BSD-like licence for binary distributions, applies to the softdevice. Some +other files come from the mbed SDK, and are licensed under Apache-2.0. Unless +specifically indicated otherwise in a file, files are licensed under the +Apache 2.0 license, as can be found in: apache-2.0.txt. The BSD-like Nordic +license can be found in BSD-3clause-Nordic.txt. The Nordic Semiconductor Softdevice +License Agreement can be found in softdevice_nrf51822_licence_agreement.txt. \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bootloader/softdevice_nrf51822_licence_agreement.txt Wed Dec 02 12:35:26 2015 +0000 @@ -0,0 +1,30 @@ +/* + * S110/S120/S130 License Agreement + * + * Copyright (c) 2015, Nordic Semiconductor ASA, All rights reserved. + * + * Redistribution. Redistribution and use in binary form, without modification, + * are permitted provided that the following conditions are met: + * + * • Redistributions must reproduce the above copyright notice and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * • Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * • No reverse engineering, decompilation, or disassembly of this software is + * permitted. + * + * DISCLAIMER. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. + * + * / \ No newline at end of file
--- a/module.json Wed Dec 02 12:35:26 2015 +0000 +++ b/module.json Wed Dec 02 12:35:26 2015 +0000 @@ -1,6 +1,6 @@ { "name": "ble-nrf51822", - "version": "2.0.2", + "version": "2.0.7", "description": "Nordic stack and drivers for the mbed BLE API.", "keywords": [ "Bluetooth", @@ -18,6 +18,9 @@ { "url": "https://spdx.org/licenses/Apache-2.0", "type": "Apache-2.0" + }, + { + "type": "LicenseRef-softdevice_nrf51822_licence_agreement.txt" } ], "dependencies": {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/softdevice_nrf51822_licence_agreement.txt Wed Dec 02 12:35:26 2015 +0000 @@ -0,0 +1,30 @@ +/* + * S110/S120/S130 License Agreement + * + * Copyright (c) 2015, Nordic Semiconductor ASA, All rights reserved. + * + * Redistribution. Redistribution and use in binary form, without modification, + * are permitted provided that the following conditions are met: + * + * • Redistributions must reproduce the above copyright notice and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * • Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * • No reverse engineering, decompilation, or disassembly of this software is + * permitted. + * + * DISCLAIMER. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. + * + * / \ No newline at end of file
--- a/source/btle/btle.cpp Wed Dec 02 12:35:26 2015 +0000 +++ b/source/btle/btle.cpp Wed Dec 02 12:35:26 2015 +0000 @@ -19,7 +19,6 @@ #include "btle.h" -#include "ble_stack_handler_types.h" #include "ble_flash.h" #include "ble_conn_params.h" @@ -27,15 +26,17 @@ #include "btle_advertising.h" #include "custom/custom_helper.h" -#include "softdevice_handler.h" -#include "pstorage.h" - #include "ble/GapEvents.h" #include "nRF5xGap.h" #include "nRF5xGattServer.h" #include "nRF5xSecurityManager.h" +extern "C" { +#include "pstorage.h" #include "device_manager.h" +#include "softdevice_handler.h" +#include "ble_stack_handler_types.h" +} #include "ble_hci.h" #include "btle_discovery.h"
--- a/source/btle/btle_security.cpp Wed Dec 02 12:35:26 2015 +0000 +++ b/source/btle/btle_security.cpp Wed Dec 02 12:35:26 2015 +0000 @@ -15,12 +15,15 @@ */ #include "btle.h" -#include "pstorage.h" #include "nRF5xGap.h" #include "nRF5xSecurityManager.h" +extern "C" { +#include "pstorage.h" #include "device_manager.h" +} + #include "btle_security.h" static dm_application_instance_t applicationInstance;
--- a/source/nRF5xGap.h Wed Dec 02 12:35:26 2015 +0000 +++ b/source/nRF5xGap.h Wed Dec 02 12:35:26 2015 +0000 @@ -26,7 +26,11 @@ #include "ble/GapScanningParams.h" #include "nrf_soc.h" + +extern "C" { #include "ble_radio_notification.h" +} + #include "btle_security.h" void radioNotificationStaticCallback(bool param); @@ -109,12 +113,64 @@ #endif private: +#ifdef YOTTA_CFG_MBED_OS + /* + * In mbed OS, all user-facing BLE events (interrupts) are posted to the + * MINAR scheduler to be executed as callbacks in thread mode. MINAR guards + * its critical sections from interrupts by acquiring CriticalSectionLock, + * which results in a call to sd_nvic_critical_region_enter(). Thus, it is + * safe to invoke MINAR APIs from interrupt context as long as those + * interrupts are blocked by sd_nvic_critical_region_enter(). + * + * Radio notifications are a special case for the above. The Radio + * Notification IRQ is handled at a very high priority--higher than the + * level blocked by sd_nvic_critical_region_enter(). Thus Radio Notification + * events can preempt MINAR's critical sections. Using MINAR APIs (such as + * posting an event) directly in processRadioNotification() may result in a + * race condition ending in a hard-fault. + * + * The solution is to *not* call MINAR APIs directly from the Radio + * Notification handling; i.e. to do the bulk of RadioNotification + * processing at a reduced priority which respects MINAR's critical + * sections. Unfortunately, on a cortex-M0, there is no clean way to demote + * priority for the currently executing interrupt--we wouldn't want to + * demote the radio notification handling anyway because it is sensitive to + * timing, and the system expects to finish this handling very quickly. The + * workaround is to employ a Timeout to trigger + * postRadioNotificationCallback() after a very short delay (~0 us) and post + * the MINAR callback that context. + * + * !!!WARNING!!! Radio notifications are very time critical events. The + * current solution is expected to work under the assumption that + * postRadioNotificationCalback() will be executed BEFORE the next radio + * notification event is generated. + */ + + bool radioNotificationCallbackParam; /* parameter to be passed into the Timeout-generated radio notification callback. */ + Timeout radioNotificationTimeout; + + /* + * A helper function to post radio notification callbacks through MINAR when using mbed OS. + */ + void postRadioNotificationCallback(void) { + minar::Scheduler::postCallback( + mbed::util::FunctionPointer1<void, bool>(&radioNotificationCallback, &FunctionPointerWithContext<bool>::call).bind(radioNotificationCallbackParam) + ); + } +#endif /* #ifdef YOTTA_CFG_MBED_OS */ + /** * A helper function to process radio-notification events; to be called internally. * @param param [description] */ void processRadioNotificationEvent(bool param) { +#ifdef YOTTA_CFG_MBED_OS + /* When using mbed OS the callback to the user-defined function will be posted through minar */ + radioNotificationCallbackParam = param; + radioNotificationTimeout.attach_us(this, &nRF5xGap::postRadioNotificationCallback, 0); +#else radioNotificationCallback.call(param); +#endif } friend void radioNotificationStaticCallback(bool param); /* allow invocations of processRadioNotificationEvent() */
--- a/source/nRF5xn.cpp Wed Dec 02 12:35:26 2015 +0000 +++ b/source/nRF5xn.cpp Wed Dec 02 12:35:26 2015 +0000 @@ -22,7 +22,9 @@ #include "btle/btle.h" #include "nrf_delay.h" +extern "C" { #include "softdevice_handler.h" +} /** * The singleton which represents the nRF51822 transport for the BLE.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/nordic-sdk/components/drivers_nrf/hal/nrf_wdt.h Wed Dec 02 12:35:26 2015 +0000 @@ -0,0 +1,299 @@ +/* Copyright (c) 2015 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. + * + */ + +/** + * @defgroup nrf_wdt_hal WDT HAL + * @{ + * @ingroup nrf_wdt + * + * @brief Hardware abstraction layer for accessing the watchdog timer (WDT) peripheral. + */ + +#ifndef NRF_WDT_H__ +#define NRF_WDT_H__ + +#include <stddef.h> +#include <stdbool.h> +#include <stdint.h> + +#include "nrf.h" + +#define NRF_WDT_CHANNEL_NUMBER 0x8UL +#define NRF_WDT_RR_VALUE 0x6E524635UL /* Fixed value, shouldn't be modified.*/ + +#define NRF_WDT_TASK_SET 1UL +#define NRF_WDT_EVENT_CLEAR 0UL + +/** + * @enum nrf_wdt_task_t + * @brief WDT tasks. + */ +typedef enum +{ + /*lint -save -e30 -esym(628,__INTADDR__)*/ + NRF_WDT_TASK_START = offsetof(NRF_WDT_Type, TASKS_START), /**< Task for starting WDT. */ + /*lint -restore*/ +} nrf_wdt_task_t; + +/** + * @enum nrf_wdt_event_t + * @brief WDT events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_WDT_EVENT_TIMEOUT = offsetof(NRF_WDT_Type, EVENTS_TIMEOUT), /**< Event from WDT time-out. */ + /*lint -restore*/ +} nrf_wdt_event_t; + +/** + * @enum nrf_wdt_behaviour_t + * @brief WDT behavior in CPU SLEEP or HALT mode. + */ +typedef enum +{ + NRF_WDT_BEHAVIOUR_RUN_SLEEP = WDT_CONFIG_SLEEP_Msk, /**< WDT will run when CPU is in SLEEP mode. */ + NRF_WDT_BEHAVIOUR_RUN_HALT = WDT_CONFIG_HALT_Msk, /**< WDT will run when CPU is in HALT mode. */ + NRF_WDT_BEHAVIOUR_RUN_SLEEP_HALT = WDT_CONFIG_SLEEP_Msk | WDT_CONFIG_HALT_Msk, /**< WDT will run when CPU is in SLEEP or HALT mode. */ + NRF_WDT_BEHAVIOUR_PAUSE_SLEEP_HALT = 0, /**< WDT will be paused when CPU is in SLEEP or HALT mode. */ +} nrf_wdt_behaviour_t; + +/** + * @enum nrf_wdt_rr_register_t + * @brief WDT reload request registers. + */ +typedef enum +{ + NRF_WDT_RR0 = 0, /**< Reload request register 0. */ + NRF_WDT_RR1, /**< Reload request register 1. */ + NRF_WDT_RR2, /**< Reload request register 2. */ + NRF_WDT_RR3, /**< Reload request register 3. */ + NRF_WDT_RR4, /**< Reload request register 4. */ + NRF_WDT_RR5, /**< Reload request register 5. */ + NRF_WDT_RR6, /**< Reload request register 6. */ + NRF_WDT_RR7 /**< Reload request register 7. */ +} nrf_wdt_rr_register_t; + +/** + * @enum nrf_wdt_int_mask_t + * @brief WDT interrupts. + */ +typedef enum +{ + NRF_WDT_INT_TIMEOUT_MASK = WDT_INTENSET_TIMEOUT_Msk, /**< WDT interrupt from time-out event. */ +} nrf_wdt_int_mask_t; + +/** + * @brief Function for configuring the watchdog behavior when the CPU is sleeping or halted. + * + * @param behaviour Watchdog behavior when CPU is in SLEEP or HALT mode. + */ +__STATIC_INLINE void nrf_wdt_behaviour_set(nrf_wdt_behaviour_t behaviour) +{ + NRF_WDT->CONFIG = behaviour; +} + + +/** + * @brief Function for starting the watchdog. + * + * @param[in] task Task. + */ +__STATIC_INLINE void nrf_wdt_task_trigger(nrf_wdt_task_t task) +{ + *((volatile uint32_t *)((uint8_t *)NRF_WDT + task)) = NRF_WDT_TASK_SET; +} + + +/** + * @brief Function for clearing the WDT event. + * + * @param[in] event Event. + */ +__STATIC_INLINE void nrf_wdt_event_clear(nrf_wdt_event_t event) +{ + *((volatile uint32_t *)((uint8_t *)NRF_WDT + (uint32_t)event)) = NRF_WDT_EVENT_CLEAR; +} + + +/** + * @brief Function for retrieving the state of the WDT event. + * + * @param[in] event Event. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_wdt_event_check(nrf_wdt_event_t event) +{ + return (bool)*((volatile uint32_t *)((uint8_t *)NRF_WDT + event)); +} + + +/** + * @brief Function for enabling a specific interrupt. + * + * @param[in] int_mask Interrupt. + */ +__STATIC_INLINE void nrf_wdt_int_enable(uint32_t int_mask) +{ + NRF_WDT->INTENSET = int_mask; +} + + +/** + * @brief Function for retrieving the state of given interrupt. + * + * @param[in] int_mask Interrupt. + * + * @retval true Interrupt is enabled. + * @retval false Interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_wdt_int_enable_check(uint32_t int_mask) +{ + return (bool)(NRF_WDT->INTENSET & int_mask); +} + + +/** + * @brief Function for disabling a specific interrupt. + * + * @param[in] int_mask Interrupt. + */ +__STATIC_INLINE void nrf_wdt_int_disable(uint32_t int_mask) +{ + NRF_WDT->INTENCLR = int_mask; +} + + +/** + * @brief Function for returning the address of a specific WDT task register. + * + * @param[in] task Task. + */ +__STATIC_INLINE uint32_t nrf_wdt_task_address_get(nrf_wdt_task_t task) +{ + return ((uint32_t)NRF_WDT + task); +} + + +/** + * @brief Function for returning the address of a specific WDT event register. + * + * @param[in] event Event. + * + * @retval address of requested event register + */ +__STATIC_INLINE uint32_t nrf_wdt_event_address_get(nrf_wdt_event_t event) +{ + return ((uint32_t)NRF_WDT + event); +} + + +/** + * @brief Function for retrieving the watchdog status. + * + * @retval true If the watchdog is started. + * @retval false If the watchdog is not started. + */ +__STATIC_INLINE bool nrf_wdt_started(void) +{ + return (bool)(NRF_WDT->RUNSTATUS); +} + + +/** + * @brief Function for retrieving the watchdog reload request status. + * + * @param[in] rr_register Reload request register to check. + * + * @retval true If a reload request is running. + * @retval false If no reload request is running. + */ +__STATIC_INLINE bool nrf_wdt_request_status(nrf_wdt_rr_register_t rr_register) +{ + return (bool)(((NRF_WDT->REQSTATUS) >> rr_register) & 0x1UL); +} + + +/** + * @brief Function for setting the watchdog reload value. + * + * @param[in] reload_value Watchdog counter initial value. + */ +__STATIC_INLINE void nrf_wdt_reload_value_set(uint32_t reload_value) +{ + NRF_WDT->CRV = reload_value; +} + + +/** + * @brief Function for retrieving the watchdog reload value. + * + * @retval Reload value. + */ +__STATIC_INLINE uint32_t nrf_wdt_reload_value_get(void) +{ + return (uint32_t)NRF_WDT->CRV; +} + + +/** + * @brief Function for enabling a specific reload request register. + * + * @param[in] rr_register Reload request register to enable. + */ +__STATIC_INLINE void nrf_wdt_reload_request_enable(nrf_wdt_rr_register_t rr_register) +{ + NRF_WDT->RREN |= 0x1UL << rr_register; +} + + +/** + * @brief Function for disabling a specific reload request register. + * + * @param[in] rr_register Reload request register to disable. + */ +__STATIC_INLINE void nrf_wdt_reload_request_disable(nrf_wdt_rr_register_t rr_register) +{ + NRF_WDT->RREN &= ~(0x1UL << rr_register); +} + + +/** + * @brief Function for retrieving the status of a specific reload request register. + * + * @param[in] rr_register Reload request register to check. + * + * @retval true If the reload request register is enabled. + * @retval false If the reload request register is not enabled. + */ +__STATIC_INLINE bool nrf_wdt_reload_request_is_enabled(nrf_wdt_rr_register_t rr_register) +{ + return (bool)(NRF_WDT->RREN & (0x1UL << rr_register)); +} + + +/** + * @brief Function for setting a specific reload request register. + * + * @param[in] rr_register Reload request register to set. + */ +__STATIC_INLINE void nrf_wdt_reload_request_set(nrf_wdt_rr_register_t rr_register) +{ + NRF_WDT->RR[rr_register] = NRF_WDT_RR_VALUE; +} + + +#endif + +/** @} */ \ No newline at end of file
--- a/source/nordic-sdk/components/libraries/bootloader_dfu/bootloader_util_arm.c Wed Dec 02 12:35:26 2015 +0000 +++ b/source/nordic-sdk/components/libraries/bootloader_dfu/bootloader_util_arm.c Wed Dec 02 12:35:26 2015 +0000 @@ -59,10 +59,10 @@ MSR MSP, R5 ; Set the main stack pointer to the applications MSP. LDR R6, [R0, #0x04] ; Load Reset handler into register 6. + MOV R0, R6 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 - MOV R0, R6 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. @@ -98,10 +98,10 @@ "MSR MSP, r5 \n\t" /* Set the main stack pointer to the applications MSP. */ "LDR r6,[r0, #0x04] \n\t" /* Load Reset handler into register 0. */ + "MOV R0, R6 \n\t" "LDR r2, =MASK_ZEROS\n\t" /* Load zeros to R2 */ "MRS r3, IPSR \n\t" /* Load IPSR to R3 to check for handler or thread mode */ "CMP r2, r3 \n\t" /* Compare, if 0 then we are in thread mode and can continue to reset handler of bootloader */ - "MOV R0, R6 \n\t" "BNE isr_abort \n\t" /* If not zero we need to exit current ISR and jump to reset handler of bootloader */ "LDR r4, =MASK_ONES \n\t" /* Load ones to R4 to be placed in Link Register. */