Introduce nordic SDK v11, cleanup path and targets.

pull/2234/head
Vincent Coubard 2016-06-15 16:43:06 +01:00
parent f2c4b770fd
commit 216fa9dfa7
279 changed files with 83976 additions and 1317 deletions

View File

@ -1,109 +0,0 @@
/* Copyright (c) 2013, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* 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.
*
*/
#ifndef _COMPILER_ABSTRACTION_H
#define _COMPILER_ABSTRACTION_H
/*lint ++flb "Enter library region" */
#if defined ( __CC_ARM )
#ifndef __ASM
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#endif
#ifndef __INLINE
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#endif
#ifndef __WEAK
#define __WEAK __weak /*!< weak keyword for ARM Compiler */
#endif
#define GET_SP() __current_sp() /*!> read current SP function for ARM Compiler */
#elif defined ( __ICCARM__ )
#ifndef __ASM
#define __ASM __asm /*!< asm keyword for IAR Compiler */
#endif
#ifndef __INLINE
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
#endif
#ifndef __WEAK
#define __WEAK __weak /*!> define weak function for IAR Compiler */
#endif
#define GET_SP() __get_SP() /*!> read current SP function for IAR Compiler */
#elif defined ( __GNUC__ )
#ifndef __ASM
#define __ASM __asm /*!< asm keyword for GNU Compiler */
#endif
#ifndef __INLINE
#define __INLINE inline /*!< inline keyword for GNU Compiler */
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak)) /*!< weak keyword for GNU Compiler */
#endif
#define GET_SP() gcc_current_sp() /*!> read current SP function for GNU Compiler */
static inline unsigned int gcc_current_sp(void)
{
register unsigned sp asm("sp");
return sp;
}
#elif defined ( __TASKING__ )
#ifndef __ASM
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
#endif
#ifndef __INLINE
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak)) /*!< weak keyword for TASKING Compiler */
#endif
#define GET_SP() __get_MSP() /*!> read current SP function for TASKING Compiler */
#endif
/*lint --flb "Leave library region" */
#endif

View File

@ -1,74 +0,0 @@
#ifndef _NRF_DELAY_H
#define _NRF_DELAY_H
// #include "nrf.h"
/*lint --e{438, 522} "Variable not used" "Function lacks side-effects" */
#if defined ( __CC_ARM )
static __ASM void __INLINE nrf_delay_us(uint32_t volatile number_of_us)
{
loop
SUBS R0, R0, #1
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
BNE loop
BX LR
}
#elif defined ( __ICCARM__ )
static void __INLINE nrf_delay_us(uint32_t volatile number_of_us)
{
__ASM (
"loop:\n\t"
" SUBS R0, R0, #1\n\t"
" NOP\n\t"
" NOP\n\t"
" NOP\n\t"
" NOP\n\t"
" NOP\n\t"
" NOP\n\t"
" NOP\n\t"
" NOP\n\t"
" NOP\n\t"
" NOP\n\t"
" NOP\n\t"
" NOP\n\t"
" BNE loop\n\t");
}
#elif defined ( __GNUC__ )
__INLINE static void nrf_delay_us(uint32_t volatile number_of_us)
{
do
{
__ASM volatile (
"NOP\n\t"
"NOP\n\t"
"NOP\n\t"
"NOP\n\t"
"NOP\n\t"
"NOP\n\t"
"NOP\n\t"
"NOP\n\t"
"NOP\n\t"
"NOP\n\t"
"NOP\n\t"
"NOP\n\t"
"NOP\n\t"
"NOP\n\t"
);
} while (--number_of_us);
}
#endif
void nrf_delay_ms(uint32_t volatile number_of_ms);
#endif

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2013, Nordic Semiconductor ASA
/* Copyright (c) 2015, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,16 +34,16 @@
#include <stdint.h>
#include <stdbool.h>
#include "nrf.h"
#include "nrf_delay.h"
#include "system_nrf51.h"
/*lint ++flb "Enter library region" */
#define __SYSTEM_CLOCK (16000000UL) /*!< nRF51 devices use a fixed System Clock Frequency of 16MHz */
static bool is_manual_peripheral_setup_needed(void);
static bool is_disabled_in_debug_needed(void);
static void init_clock(void);
static bool is_peripheral_domain_setup_needed(void);
#if defined ( __CC_ARM )
@ -61,27 +61,6 @@ void SystemCoreClockUpdate(void)
void SystemInit(void)
{
#if defined(TARGET_NRF_32MHZ_XTAL)
/* For 32MHz HFCLK XTAL such as Taiyo Yuden
Physically, tiny footprint XTAL oscillate higher freq. To make BLE modules smaller, some modules
are using 32MHz XTAL.
This code wriging the value 0xFFFFFF00 to the UICR (User Information Configuration Register)
at address 0x10001008, to make nRF51 works with 32MHz system clock. This register will be overwritten
by SoftDevice to 0xFFFFFFFF, the default value. Each hex files built with mbed classic online compiler
contain SoftDevice, so that, this code run once just after the hex file will be flashed onto nRF51.
After changing the value, nRF51 need to reboot. */
if (*(uint32_t *)0x10001008 == 0xFFFFFFFF)
{
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
*(uint32_t *)0x10001008 = 0xFFFFFF00;
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
NVIC_SystemReset();
while (true){}
}
#endif
/* If desired, switch off the unused RAM to lower consumption by the use of RAMON register.
It can also be done in the application main() function. */
@ -97,59 +76,27 @@ void SystemInit(void)
}
/* Disable PROTENSET registers under debug, as indicated by PAN 59 "MPU: Reset value of DISABLEINDEBUG
register is incorrect" found at Product Anomaly document four your device found at
register is incorrect" found at Product Anomaly document for your device found at
https://www.nordicsemi.com/. There is no side effect of using these instruction if not needed. */
if (is_disabled_in_debug_needed())
{
NRF_MPU->DISABLEINDEBUG = MPU_DISABLEINDEBUG_DISABLEINDEBUG_Disabled << MPU_DISABLEINDEBUG_DISABLEINDEBUG_Pos;
}
// Start the external 32khz crystal oscillator.
init_clock();
}
void init_clock(void)
{
/* For compatibility purpose, the default behaviour is to first attempt to initialise an
external clock, and after a timeout, use the internal RC one. To avoid this wait, boards that
don't have an external oscillator can set TARGET_NRF_LFCLK_RC directly. */
uint32_t i = 0;
const uint32_t polling_period = 200;
const uint32_t timeout = 1000000;
#if defined(TARGET_NRF_LFCLK_RC)
NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_RC << CLOCK_LFCLKSRC_SRC_Pos);
#else
NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
#endif
NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
NRF_CLOCK->TASKS_LFCLKSTART = 1;
/* Wait for the external oscillator to start up.
nRF51822 product specification (8.1.5) gives a typical value of 300ms for external clock
startup duration, and a maximum value of 1s. When using the internal RC source, typical delay
will be 390µs, so we use a polling period of 200µs.
We can't use us_ticker at this point, so we have to rely on a less precise method for
measuring our timeout. Because of this, the actual timeout will be slightly longer than 1
second, which isn't an issue at all, since this fallback should only be used as a safety net.
*/
for (i = 0; i < (timeout / polling_period); i++) {
if (NRF_CLOCK->EVENTS_LFCLKSTARTED != 0)
return;
nrf_delay_us(polling_period);
}
/* Fallback to internal clock. Belt and braces, since the internal clock is used by default
whilst no external source is running. This is not only a sanity check, but it also allows
code down the road (e.g. ble initialisation) to directly know which clock is used. */
NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_RC << CLOCK_LFCLKSRC_SRC_Pos);
NRF_CLOCK->TASKS_LFCLKSTART = 1;
while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) {
// Do nothing.
/* Execute the following code to eliminate excessive current in sleep mode with RAM retention in nRF51802 devices,
as indicated by PAN 76 "System: Excessive current in sleep mode with retention" found at Product Anomaly document
for your device found at https://www.nordicsemi.com/. */
if (is_peripheral_domain_setup_needed()){
if (*(uint32_t volatile *)0x4006EC00 != 1){
*(uint32_t volatile *)0x4006EC00 = 0x9375;
while (*(uint32_t volatile *)0x4006EC00 != 1){
}
}
*(uint32_t volatile *)0x4006EC14 = 0xC0;
}
}
static bool is_manual_peripheral_setup_needed(void)
{
if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x1) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0))
@ -184,4 +131,21 @@ static bool is_disabled_in_debug_needed(void)
return false;
}
static bool is_peripheral_domain_setup_needed(void)
{
if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x1) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0))
{
if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0xA0) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0))
{
return true;
}
if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0xD0) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0))
{
return true;
}
}
return false;
}
/*lint --flb "Leave library region" */

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2013, Nordic Semiconductor ASA
/* Copyright (c) 2015, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -27,6 +27,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef SYSTEM_NRF51_H
#define SYSTEM_NRF51_H
@ -56,7 +57,7 @@ extern void SystemInit (void);
* @param none
* @return none
*
* @brief Updates the SystemCoreClock with current core Clock
* @brief Updates the SystemCoreClock with current core Clock
* retrieved from cpu registers.
*/
extern void SystemCoreClockUpdate (void);

View File

@ -1,32 +1,30 @@
/*
* Copyright (c) Nordic Semiconductor ASA
/* Copyright (c) 2015, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
* * Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
*
* 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.
* 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.
*
*/
@ -189,20 +187,6 @@ void SystemInit(void)
#endif
SystemCoreClockUpdate();
// Start the external 32khz crystal oscillator.
#if defined(TARGET_NRF_LFCLK_RC)
NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_RC << CLOCK_LFCLKSRC_SRC_Pos);
#else
NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
#endif
NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
NRF_CLOCK->TASKS_LFCLKSTART = 1;
// Wait for the external oscillator to start up.
while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) {
// Do nothing.
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2013, Nordic Semiconductor ASA
/* Copyright (c) 2015, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -27,22 +27,43 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_H
#define NRF_H
#ifndef _WIN32
#ifndef SYSTEM_NRF52_H
#define SYSTEM_NRF52_H
/* Family selection for main includes. NRF51 must be selected. */
#ifdef NRF51
#include "nrf51.h"
#include "nrf51_bitfields.h"
#else
#error "Device family must be defined. See nrf.h."
#endif /* NRF51 */
#ifdef __cplusplus
extern "C" {
#endif
#include "compiler_abstraction.h"
#include <stdint.h>
#endif /* _WIN32 */
#endif /* NRF_H */
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
/**
* Initialize the system
*
* @param none
* @return none
*
* @brief Setup the microcontroller system.
* Initialize the System and update the SystemCoreClock variable.
*/
extern void SystemInit (void);
/**
* Update SystemCoreClock variable
*
* @param none
* @return none
*
* @brief Updates the SystemCoreClock with current core Clock
* retrieved from cpu registers.
*/
extern void SystemCoreClockUpdate (void);
#ifdef __cplusplus
}
#endif
#endif /* SYSTEM_NRF52_H */

View File

@ -1,32 +1,30 @@
/*
* Copyright (c) Nordic Semiconductor ASA
/* Copyright (c) 2015, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
* * Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
*
* 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.
* 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.
*
*/
#ifndef _COMPILER_ABSTRACTION_H

View File

@ -0,0 +1,66 @@
/* Copyright (c) 2015, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* 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.
*
*/
#ifndef NRF_H
#define NRF_H
/* MDK version */
#define MDK_MAJOR_VERSION 8
#define MDK_MINOR_VERSION 5
#define MDK_MICRO_VERSION 0
#if defined(_WIN32)
/* Do not include nrf51 specific files when building for PC host */
#elif defined(__unix)
/* Do not include nrf51 specific files when building for PC host */
#elif defined(__APPLE__)
/* Do not include nrf51 specific files when building for PC host */
#else
/* Family selection for family includes. */
#if defined (NRF51)
#include "nrf51.h"
#include "nrf51_bitfields.h"
#include "nrf51_deprecated.h"
#elif defined (NRF52)
#include "nrf52.h"
#include "nrf52_bitfields.h"
#include "nrf51_to_nrf52.h"
#include "nrf52_name_change.h"
#else
#error "Device family must be defined. See nrf.h."
#endif /* NRF51, NRF52 */
#include "compiler_abstraction.h"
#endif /* _WIN32 || __unix || __APPLE__ */
#endif /* NRF_H */

View File

@ -1,33 +1,33 @@
/****************************************************************************************************//**
* @file nRF51.h
* @file nrf51.h
*
* @brief CMSIS Cortex-M0 Peripheral Access Layer Header File for
* nRF51 from Nordic Semiconductor.
* nrf51 from Nordic Semiconductor.
*
* @version V522
* @date 31. October 2014
* @date 23. February 2016
*
* @note Generated with SVDConv V2.81d
* from CMSIS SVD File 'nRF51.xml' Version 522,
* @note Generated with SVDConv V2.81d
* from CMSIS SVD File 'nrf51.svd' Version 522,
*
* @par Copyright (c) 2013, Nordic Semiconductor ASA
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
*
* * Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
*
* 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
@ -38,7 +38,7 @@
* 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.
*
*
*
*******************************************************************************************************/
@ -48,7 +48,7 @@
* @{
*/
/** @addtogroup nRF51
/** @addtogroup nrf51
* @{
*/
@ -71,7 +71,7 @@ typedef enum {
DebugMonitor_IRQn = -4, /*!< 12 Debug Monitor */
PendSV_IRQn = -2, /*!< 14 Pendable request for system service */
SysTick_IRQn = -1, /*!< 15 System Tick Timer */
/* ---------------------- nRF51 Specific Interrupt Numbers ---------------------- */
/* ---------------------- nrf51 Specific Interrupt Numbers ---------------------- */
POWER_CLOCK_IRQn = 0, /*!< 0 POWER_CLOCK */
RADIO_IRQn = 1, /*!< 1 RADIO */
UART0_IRQn = 2, /*!< 2 UART0 */
@ -117,7 +117,8 @@ typedef enum {
/** @} */ /* End of group Configuration_of_CMSIS */
#include "core_cm0.h" /*!< Cortex-M0 processor and core peripherals */
#include "system_nrf51.h" /*!< nRF51 System */
#include "system_nrf51.h" /*!< nrf51 System */
/* ================================================================================ */
/* ================ Device Specific Peripheral Section ================ */
@ -183,15 +184,6 @@ typedef struct {
__IO uint32_t TEP; /*!< Channel task end-point. */
} PPI_CH_Type;
typedef struct {
__I uint32_t PART; /*!< Part code */
__I uint32_t VARIANT; /*!< Part variant */
__I uint32_t PACKAGE; /*!< Package option */
__I uint32_t RAM; /*!< RAM variant */
__I uint32_t FLASH; /*!< Flash variant */
__I uint32_t RESERVED[3]; /*!< Reserved */
} FICR_INFO_Type;
/* ================================================================================ */
/* ================ POWER ================ */
@ -300,27 +292,6 @@ typedef struct { /*!< MPU Structure
} NRF_MPU_Type;
/* ================================================================================ */
/* ================ PU ================ */
/* ================================================================================ */
/**
* @brief Patch unit. (PU)
*/
typedef struct { /*!< PU Structure */
__I uint32_t RESERVED0[448];
__IO uint32_t REPLACEADDR[8]; /*!< Address of first instruction to replace. */
__I uint32_t RESERVED1[24];
__IO uint32_t PATCHADDR[8]; /*!< Relative address of patch instructions. */
__I uint32_t RESERVED2[24];
__IO uint32_t PATCHEN; /*!< Patch enable register. */
__IO uint32_t PATCHENSET; /*!< Patch enable register. */
__IO uint32_t PATCHENCLR; /*!< Patch disable register. */
} NRF_PU_Type;
/* ================================================================================ */
/* ================ AMLI ================ */
/* ================================================================================ */
@ -366,7 +337,7 @@ typedef struct { /*!< RADIO Structure
__IO uint32_t EVENTS_RSSIEND; /*!< Sampling of the receive signal strength complete. A new RSSI
sample is ready for readout at the RSSISAMPLE register. */
__I uint32_t RESERVED1[2];
__IO uint32_t EVENTS_BCMATCH; /*!< Bit counter reached bit count value specified in BC register. */
__IO uint32_t EVENTS_BCMATCH; /*!< Bit counter reached bit count value specified in BCC register. */
__I uint32_t RESERVED2[53];
__IO uint32_t SHORTS; /*!< Shortcuts for the radio. */
__I uint32_t RESERVED3[64];
@ -374,11 +345,11 @@ typedef struct { /*!< RADIO Structure
__IO uint32_t INTENCLR; /*!< Interrupt enable clear register. */
__I uint32_t RESERVED4[61];
__I uint32_t CRCSTATUS; /*!< CRC status of received packet. */
__I uint32_t CD; /*!< Carrier detect. */
__I uint32_t RESERVED5;
__I uint32_t RXMATCH; /*!< Received address. */
__I uint32_t RXCRC; /*!< Received CRC. */
__I uint32_t DAI; /*!< Device address match index. */
__I uint32_t RESERVED5[60];
__I uint32_t RESERVED6[60];
__IO uint32_t PACKETPTR; /*!< Packet pointer. Decision point: START task. */
__IO uint32_t FREQUENCY; /*!< Frequency. */
__IO uint32_t TXPOWER; /*!< Output power. */
@ -397,22 +368,22 @@ typedef struct { /*!< RADIO Structure
__IO uint32_t TEST; /*!< Test features enable register. */
__IO uint32_t TIFS; /*!< Inter Frame Spacing in microseconds. */
__I uint32_t RSSISAMPLE; /*!< RSSI sample. */
__I uint32_t RESERVED6;
__I uint32_t RESERVED7;
__I uint32_t STATE; /*!< Current radio state. */
__IO uint32_t DATAWHITEIV; /*!< Data whitening initial value. */
__I uint32_t RESERVED7[2];
__I uint32_t RESERVED8[2];
__IO uint32_t BCC; /*!< Bit counter compare. */
__I uint32_t RESERVED8[39];
__I uint32_t RESERVED9[39];
__IO uint32_t DAB[8]; /*!< Device address base segment. */
__IO uint32_t DAP[8]; /*!< Device address prefix. */
__IO uint32_t DACNF; /*!< Device address match configuration. */
__I uint32_t RESERVED9[56];
__I uint32_t RESERVED10[56];
__IO uint32_t OVERRIDE0; /*!< Trim value override register 0. */
__IO uint32_t OVERRIDE1; /*!< Trim value override register 1. */
__IO uint32_t OVERRIDE2; /*!< Trim value override register 2. */
__IO uint32_t OVERRIDE3; /*!< Trim value override register 3. */
__IO uint32_t OVERRIDE4; /*!< Trim value override register 4. */
__I uint32_t RESERVED10[561];
__I uint32_t RESERVED11[561];
__IO uint32_t POWER; /*!< Peripheral power control. */
} NRF_RADIO_Type;
@ -571,39 +542,41 @@ typedef struct { /*!< SPIS Structure
__O uint32_t TASKS_RELEASE; /*!< Release SPI semaphore. */
__I uint32_t RESERVED1[54];
__IO uint32_t EVENTS_END; /*!< Granted transaction completed. */
__I uint32_t RESERVED2[8];
__I uint32_t RESERVED2[2];
__IO uint32_t EVENTS_ENDRX; /*!< End of RXD buffer reached */
__I uint32_t RESERVED3[5];
__IO uint32_t EVENTS_ACQUIRED; /*!< Semaphore acquired. */
__I uint32_t RESERVED3[53];
__I uint32_t RESERVED4[53];
__IO uint32_t SHORTS; /*!< Shortcuts for SPIS. */
__I uint32_t RESERVED4[64];
__I uint32_t RESERVED5[64];
__IO uint32_t INTENSET; /*!< Interrupt enable set register. */
__IO uint32_t INTENCLR; /*!< Interrupt enable clear register. */
__I uint32_t RESERVED5[61];
__I uint32_t RESERVED6[61];
__I uint32_t SEMSTAT; /*!< Semaphore status. */
__I uint32_t RESERVED6[15];
__I uint32_t RESERVED7[15];
__IO uint32_t STATUS; /*!< Status from last transaction. */
__I uint32_t RESERVED7[47];
__I uint32_t RESERVED8[47];
__IO uint32_t ENABLE; /*!< Enable SPIS. */
__I uint32_t RESERVED8;
__I uint32_t RESERVED9;
__IO uint32_t PSELSCK; /*!< Pin select for SCK. */
__IO uint32_t PSELMISO; /*!< Pin select for MISO. */
__IO uint32_t PSELMOSI; /*!< Pin select for MOSI. */
__IO uint32_t PSELCSN; /*!< Pin select for CSN. */
__I uint32_t RESERVED9[7];
__I uint32_t RESERVED10[7];
__IO uint32_t RXDPTR; /*!< RX data pointer. */
__IO uint32_t MAXRX; /*!< Maximum number of bytes in the receive buffer. */
__I uint32_t AMOUNTRX; /*!< Number of bytes received in last granted transaction. */
__I uint32_t RESERVED10;
__I uint32_t RESERVED11;
__IO uint32_t TXDPTR; /*!< TX data pointer. */
__IO uint32_t MAXTX; /*!< Maximum number of bytes in the transmit buffer. */
__I uint32_t AMOUNTTX; /*!< Number of bytes transmitted in last granted transaction. */
__I uint32_t RESERVED11;
__IO uint32_t CONFIG; /*!< Configuration register. */
__I uint32_t RESERVED12;
__IO uint32_t CONFIG; /*!< Configuration register. */
__I uint32_t RESERVED13;
__IO uint32_t DEF; /*!< Default character. */
__I uint32_t RESERVED13[24];
__I uint32_t RESERVED14[24];
__IO uint32_t ORC; /*!< Over-read character. */
__I uint32_t RESERVED14[654];
__I uint32_t RESERVED15[654];
__IO uint32_t POWER; /*!< Peripheral power control. */
} NRF_SPIS_Type;
@ -628,35 +601,28 @@ typedef struct { /*!< SPIM Structure
__IO uint32_t EVENTS_STOPPED; /*!< SPI transaction has stopped. */
__I uint32_t RESERVED3[2];
__IO uint32_t EVENTS_ENDRX; /*!< End of RXD buffer reached. */
__I uint32_t RESERVED4;
__IO uint32_t EVENTS_END; /*!< End of RXD buffer and TXD buffer reached. */
__I uint32_t RESERVED5;
__I uint32_t RESERVED4[3];
__IO uint32_t EVENTS_ENDTX; /*!< End of TXD buffer reached. */
__I uint32_t RESERVED6[10];
__I uint32_t RESERVED5[10];
__IO uint32_t EVENTS_STARTED; /*!< Transaction started. */
__I uint32_t RESERVED7[44];
__IO uint32_t SHORTS; /*!< Shortcuts for SPIM. */
__I uint32_t RESERVED8[64];
__I uint32_t RESERVED6[109];
__IO uint32_t INTENSET; /*!< Interrupt enable set register. */
__IO uint32_t INTENCLR; /*!< Interrupt enable clear register. */
__I uint32_t RESERVED9[125];
__I uint32_t RESERVED7[125];
__IO uint32_t ENABLE; /*!< Enable SPIM. */
__I uint32_t RESERVED10;
__I uint32_t RESERVED8;
SPIM_PSEL_Type PSEL; /*!< Pin select configuration. */
__I uint32_t RESERVED11;
__I uint32_t RXDDATA; /*!< RXD register. */
__IO uint32_t TXDDATA; /*!< TXD register. */
__I uint32_t RESERVED12;
__I uint32_t RESERVED9[4];
__IO uint32_t FREQUENCY; /*!< SPI frequency. */
__I uint32_t RESERVED13[3];
__I uint32_t RESERVED10[3];
SPIM_RXD_Type RXD; /*!< RXD EasyDMA configuration and status. */
__I uint32_t RESERVED14;
__I uint32_t RESERVED11;
SPIM_TXD_Type TXD; /*!< TXD EasyDMA configuration and status. */
__I uint32_t RESERVED15;
__I uint32_t RESERVED12;
__IO uint32_t CONFIG; /*!< Configuration register. */
__I uint32_t RESERVED16[26];
__I uint32_t RESERVED13[26];
__IO uint32_t ORC; /*!< Over-read character. */
__I uint32_t RESERVED17[654];
__I uint32_t RESERVED14[654];
__IO uint32_t POWER; /*!< Peripheral power control. */
} NRF_SPIM_Type;
@ -899,8 +865,8 @@ typedef struct { /*!< AAR Structure
__IO uint32_t IRKPTR; /*!< Pointer to the IRK data structure. */
__I uint32_t RESERVED5;
__IO uint32_t ADDRPTR; /*!< Pointer to the resolvable address (6 bytes). */
__IO uint32_t SCRATCHPTR; /*!< Pointer to a "scratch" data area used for temporary storage
during resolution. A minimum of 3 bytes must be reserved. */
__IO uint32_t SCRATCHPTR; /*!< Pointer to a scratch data area used for temporary storage during
resolution. A minimum of 3 bytes must be reserved. */
__I uint32_t RESERVED6[697];
__IO uint32_t POWER; /*!< Peripheral power control. */
} NRF_AAR_Type;
@ -938,8 +904,8 @@ typedef struct { /*!< CCM Structure
__IO uint32_t CNFPTR; /*!< Pointer to a data structure holding AES key and NONCE vector. */
__IO uint32_t INPTR; /*!< Pointer to the input packet. */
__IO uint32_t OUTPTR; /*!< Pointer to the output packet. */
__IO uint32_t SCRATCHPTR; /*!< Pointer to a "scratch" data area used for temporary storage
during resolution. A minimum of 43 bytes must be reserved. */
__IO uint32_t SCRATCHPTR; /*!< Pointer to a scratch data area used for temporary storage during
resolution. A minimum of 43 bytes must be reserved. */
__I uint32_t RESERVED5[697];
__IO uint32_t POWER; /*!< Peripheral power control. */
} NRF_CCM_Type;
@ -1087,9 +1053,13 @@ typedef struct { /*!< NVMC Structure
__I uint32_t READY; /*!< Ready flag. */
__I uint32_t RESERVED1[64];
__IO uint32_t CONFIG; /*!< Configuration register. */
__IO uint32_t ERASEPAGE; /*!< Register for erasing a non-protected non-volatile memory page. */
union {
__IO uint32_t ERASEPCR1; /*!< Register for erasing a non-protected non-volatile memory page. */
__IO uint32_t ERASEPAGE; /*!< Register for erasing a non-protected non-volatile memory page. */
};
__IO uint32_t ERASEALL; /*!< Register for erasing all non-volatile user memory. */
__IO uint32_t ERASEPROTECTEDPAGE; /*!< Register for erasing a protected non-volatile memory page. */
__IO uint32_t ERASEPCR0; /*!< Register for erasing a protected non-volatile memory page. */
__IO uint32_t ERASEUICR; /*!< Register for start erasing User Information Congfiguration Registers. */
} NRF_NVMC_Type;
@ -1134,7 +1104,7 @@ typedef struct { /*!< FICR Structure
__I uint32_t PPFC; /*!< Pre-programmed factory code present. */
__I uint32_t RESERVED2;
__I uint32_t NUMRAMBLOCK; /*!< Number of individualy controllable RAM blocks. */
union {
__I uint32_t SIZERAMBLOCK[4]; /*!< Deprecated array of size of RAM block in bytes. This name is
kept for backward compatinility purposes. Use SIZERAMBLOCKS
@ -1155,7 +1125,6 @@ typedef struct { /*!< FICR Structure
__I uint32_t RESERVED5[10];
__I uint32_t BLE_1MBIT[5]; /*!< Override values for the OVERRIDEn registers in RADIO for BLE_1Mbit
mode. */
FICR_INFO_Type INFO; /*!< Device info */
} NRF_FICR_Type;
@ -1174,7 +1143,13 @@ typedef struct { /*!< UICR Structure
__IO uint32_t XTALFREQ; /*!< Reset value for CLOCK XTALFREQ register. */
__I uint32_t RESERVED0;
__I uint32_t FWID; /*!< Firmware ID. */
__IO uint32_t BOOTLOADERADDR; /*!< Bootloader start address. */
union {
__IO uint32_t NRFFW[15]; /*!< Reserved for Nordic firmware design. */
__IO uint32_t BOOTLOADERADDR; /*!< Bootloader start address. */
};
__IO uint32_t NRFHW[12]; /*!< Reserved for Nordic hardware design. */
__IO uint32_t CUSTOMER[32]; /*!< Reserved for customer. */
} NRF_UICR_Type;
@ -1226,7 +1201,6 @@ typedef struct { /*!< GPIO Structure
#define NRF_POWER_BASE 0x40000000UL
#define NRF_CLOCK_BASE 0x40000000UL
#define NRF_MPU_BASE 0x40000000UL
#define NRF_PU_BASE 0x40000000UL
#define NRF_AMLI_BASE 0x40000000UL
#define NRF_RADIO_BASE 0x40001000UL
#define NRF_UART0_BASE 0x40002000UL
@ -1266,7 +1240,6 @@ typedef struct { /*!< GPIO Structure
#define NRF_POWER ((NRF_POWER_Type *) NRF_POWER_BASE)
#define NRF_CLOCK ((NRF_CLOCK_Type *) NRF_CLOCK_BASE)
#define NRF_MPU ((NRF_MPU_Type *) NRF_MPU_BASE)
#define NRF_PU ((NRF_PU_Type *) NRF_PU_BASE)
#define NRF_AMLI ((NRF_AMLI_Type *) NRF_AMLI_BASE)
#define NRF_RADIO ((NRF_RADIO_Type *) NRF_RADIO_BASE)
#define NRF_UART0 ((NRF_UART_Type *) NRF_UART0_BASE)
@ -1300,7 +1273,7 @@ typedef struct { /*!< GPIO Structure
/** @} */ /* End of group Device_Peripheral_Registers */
/** @} */ /* End of group nRF51 */
/** @} */ /* End of group nrf51 */
/** @} */ /* End of group Nordic Semiconductor */
#ifdef __cplusplus
@ -1308,5 +1281,5 @@ typedef struct { /*!< GPIO Structure
#endif
#endif /* nRF51_H */
#endif /* nrf51_H */

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2013, Nordic Semiconductor ASA
/* Copyright (c) 2015, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -30,9 +30,7 @@
#ifndef __NRF51_BITS_H
#define __NRF51_BITS_H
/*lint ++flb "Enter library region */
#include <core_cm0.h>
/*lint ++flb "Enter library region" */
/* Peripheral: AAR */
/* Description: Accelerated Address Resolver. */
@ -820,6 +818,7 @@
#define AMLI_RAMPRI_AAR_RAM0_Pri12 (0xCUL) /*!< Priority 12. */
#define AMLI_RAMPRI_AAR_RAM0_Pri14 (0xEUL) /*!< Priority 14. */
/* Peripheral: CCM */
/* Description: AES CCM Mode Encryption. */
@ -1064,8 +1063,8 @@
/* Bits 7..0 : External Xtal frequency selection. */
#define CLOCK_XTALFREQ_XTALFREQ_Pos (0UL) /*!< Position of XTALFREQ field. */
#define CLOCK_XTALFREQ_XTALFREQ_Msk (0xFFUL << CLOCK_XTALFREQ_XTALFREQ_Pos) /*!< Bit mask of XTALFREQ field. */
#define CLOCK_XTALFREQ_XTALFREQ_16MHz (0xFFUL) /*!< 16MHz xtal is used as source for the HFCLK oscillator. */
#define CLOCK_XTALFREQ_XTALFREQ_32MHz (0x00UL) /*!< 32MHz xtal is used as source for the HFCLK oscillator. */
#define CLOCK_XTALFREQ_XTALFREQ_16MHz (0xFFUL) /*!< 16MHz xtal is used as source for the HFCLK oscillator. */
/* Peripheral: ECB */
@ -1124,8 +1123,8 @@
/* Bits 7..0 : Pre-programmed factory code present. */
#define FICR_PPFC_PPFC_Pos (0UL) /*!< Position of PPFC field. */
#define FICR_PPFC_PPFC_Msk (0xFFUL << FICR_PPFC_PPFC_Pos) /*!< Bit mask of PPFC field. */
#define FICR_PPFC_PPFC_NotPresent (0xFFUL) /*!< Not present. */
#define FICR_PPFC_PPFC_Present (0x00UL) /*!< Present. */
#define FICR_PPFC_PPFC_NotPresent (0xFFUL) /*!< Not present. */
/* Register: FICR_CONFIGID */
/* Description: Configuration identifier. */
@ -1162,60 +1161,6 @@
#define FICR_OVERRIDEEN_NRF_1MBIT_Override (0UL) /*!< Override the default values for NRF_1Mbit mode. */
#define FICR_OVERRIDEEN_NRF_1MBIT_NotOverride (1UL) /*!< Do not override the default values for NRF_1Mbit mode. */
/* Register: FICR_INFO_PART */
/* Description: Part code */
/* Bits 31..0 : Part code */
#define FICR_INFO_PART_PART_Pos (0UL) /*!< Position of PART field. */
#define FICR_INFO_PART_PART_Msk (0xFFFFFFFFUL << FICR_INFO_PART_PART_Pos) /*!< Bit mask of PART field. */
#define FICR_INFO_PART_PART_N51822 (0x51822UL) /*!< nRF51822 */
#define FICR_INFO_PART_PART_N51422 (0x51422UL) /*!< nRF51422 */
#define FICR_INFO_PART_PART_Unspecified (0xFFFFFFFFUL) /*!< Unspecified */
/* Register: FICR_INFO_VARIANT */
/* Description: Part variant */
/* Bits 31..0 : Part variant */
#define FICR_INFO_VARIANT_VARIANT_Pos (0UL) /*!< Position of VARIANT field. */
#define FICR_INFO_VARIANT_VARIANT_Msk (0xFFFFFFFFUL << FICR_INFO_VARIANT_VARIANT_Pos) /*!< Bit mask of VARIANT field. */
#define FICR_INFO_VARIANT_VARIANT_nRF51C (0x1002UL) /*!< nRF51-C (XLR3) */
#define FICR_INFO_VARIANT_VARIANT_nRF51D (0x1003UL) /*!< nRF51-D (L3) */
#define FICR_INFO_VARIANT_VARIANT_nRF51E (0x1004UL) /*!< nRF51-E (XLR3P) */
#define FICR_INFO_VARIANT_VARIANT_Unspecified (0xFFFFFFFFUL) /*!< Unspecified */
/* Register: FICR_INFO_PACKAGE */
/* Description: Package option */
/* Bits 31..0 : Package option */
#define FICR_INFO_PACKAGE_PACKAGE_Pos (0UL) /*!< Position of PACKAGE field. */
#define FICR_INFO_PACKAGE_PACKAGE_Msk (0xFFFFFFFFUL << FICR_INFO_PACKAGE_PACKAGE_Pos) /*!< Bit mask of PACKAGE field. */
#define FICR_INFO_PACKAGE_PACKAGE_QFN48 (0x0000UL) /*!< 48-pin QFN with 31 GPIO */
#define FICR_INFO_PACKAGE_PACKAGE_nRF51CSP56A (0x1000UL) /*!< nRF51x22 CDxx - WLCSP 56 balls */
#define FICR_INFO_PACKAGE_PACKAGE_nRF51CSP62A (0x1001UL) /*!< nRF51x22 CExx - WLCSP 62 balls */
#define FICR_INFO_PACKAGE_PACKAGE_nRF51CSP62B (0x1002UL) /*!< nRF51x22 CFxx - WLCSP 62 balls */
#define FICR_INFO_PACKAGE_PACKAGE_nRF51CSP62C (0x1003UL) /*!< nRF51x22 CTxx - WLCSP 62 balls */
#define FICR_INFO_PACKAGE_PACKAGE_Unspecified (0xFFFFFFFFUL) /*!< Unspecified */
/* Register: FICR_INFO_RAM */
/* Description: RAM variant */
/* Bits 31..0 : RAM variant */
#define FICR_INFO_RAM_RAM_Pos (0UL) /*!< Position of RAM field. */
#define FICR_INFO_RAM_RAM_Msk (0xFFFFFFFFUL << FICR_INFO_RAM_RAM_Pos) /*!< Bit mask of RAM field. */
#define FICR_INFO_RAM_RAM_Unspecified (0xFFFFFFFFUL) /*!< Unspecified */
#define FICR_INFO_RAM_RAM_K16 (16UL) /*!< 16 kByte RAM. */
#define FICR_INFO_RAM_RAM_K32 (32UL) /*!< 32 kByte RAM. */
/* Register: FICR_INFO_FLASH */
/* Description: Flash variant */
/* Bits 31..0 : Flash variant */
#define FICR_INFO_FLASH_FLASH_Pos (0UL) /*!< Position of FLASH field. */
#define FICR_INFO_FLASH_FLASH_Msk (0xFFFFFFFFUL << FICR_INFO_FLASH_FLASH_Pos) /*!< Bit mask of FLASH field. */
#define FICR_INFO_FLASH_FLASH_Unspecified (0xFFFFFFFFUL) /*!< Unspecified */
#define FICR_INFO_FLASH_FLASH_K128 (128UL) /*!< 128 kByte FLASH. */
#define FICR_INFO_FLASH_FLASH_K256 (256UL) /*!< 256 kByte FLASH. */
/* Peripheral: GPIO */
/* Description: General purpose input and output. */
@ -2846,6 +2791,7 @@
/* Bits 17..16 : Effects on output when in Task mode, or events on input that generates an event. */
#define GPIOTE_CONFIG_POLARITY_Pos (16UL) /*!< Position of POLARITY field. */
#define GPIOTE_CONFIG_POLARITY_Msk (0x3UL << GPIOTE_CONFIG_POLARITY_Pos) /*!< Bit mask of POLARITY field. */
#define GPIOTE_CONFIG_POLARITY_None (0x00UL) /*!< No task or event. */
#define GPIOTE_CONFIG_POLARITY_LoToHi (0x01UL) /*!< Low to high. */
#define GPIOTE_CONFIG_POLARITY_HiToLo (0x02UL) /*!< High to low. */
#define GPIOTE_CONFIG_POLARITY_Toggle (0x03UL) /*!< Toggle. */
@ -3720,30 +3666,44 @@
/* Bit 18 : Reset from wake-up from OFF mode detected by entering into debug interface mode. */
#define POWER_RESETREAS_DIF_Pos (18UL) /*!< Position of DIF field. */
#define POWER_RESETREAS_DIF_Msk (0x1UL << POWER_RESETREAS_DIF_Pos) /*!< Bit mask of DIF field. */
#define POWER_RESETREAS_DIF_NotDetected (0UL) /*!< Reset not detected. */
#define POWER_RESETREAS_DIF_Detected (1UL) /*!< Reset detected. */
/* Bit 17 : Reset from wake-up from OFF mode detected by the use of ANADETECT signal from LPCOMP. */
#define POWER_RESETREAS_LPCOMP_Pos (17UL) /*!< Position of LPCOMP field. */
#define POWER_RESETREAS_LPCOMP_Msk (0x1UL << POWER_RESETREAS_LPCOMP_Pos) /*!< Bit mask of LPCOMP field. */
#define POWER_RESETREAS_LPCOMP_NotDetected (0UL) /*!< Reset not detected. */
#define POWER_RESETREAS_LPCOMP_Detected (1UL) /*!< Reset detected. */
/* Bit 16 : Reset from wake-up from OFF mode detected by the use of DETECT signal from GPIO. */
#define POWER_RESETREAS_OFF_Pos (16UL) /*!< Position of OFF field. */
#define POWER_RESETREAS_OFF_Msk (0x1UL << POWER_RESETREAS_OFF_Pos) /*!< Bit mask of OFF field. */
#define POWER_RESETREAS_OFF_NotDetected (0UL) /*!< Reset not detected. */
#define POWER_RESETREAS_OFF_Detected (1UL) /*!< Reset detected. */
/* Bit 3 : Reset from CPU lock-up detected. */
#define POWER_RESETREAS_LOCKUP_Pos (3UL) /*!< Position of LOCKUP field. */
#define POWER_RESETREAS_LOCKUP_Msk (0x1UL << POWER_RESETREAS_LOCKUP_Pos) /*!< Bit mask of LOCKUP field. */
#define POWER_RESETREAS_LOCKUP_NotDetected (0UL) /*!< Reset not detected. */
#define POWER_RESETREAS_LOCKUP_Detected (1UL) /*!< Reset detected. */
/* Bit 2 : Reset from AIRCR.SYSRESETREQ detected. */
#define POWER_RESETREAS_SREQ_Pos (2UL) /*!< Position of SREQ field. */
#define POWER_RESETREAS_SREQ_Msk (0x1UL << POWER_RESETREAS_SREQ_Pos) /*!< Bit mask of SREQ field. */
#define POWER_RESETREAS_SREQ_NotDetected (0UL) /*!< Reset not detected. */
#define POWER_RESETREAS_SREQ_Detected (1UL) /*!< Reset detected. */
/* Bit 1 : Reset from watchdog detected. */
#define POWER_RESETREAS_DOG_Pos (1UL) /*!< Position of DOG field. */
#define POWER_RESETREAS_DOG_Msk (0x1UL << POWER_RESETREAS_DOG_Pos) /*!< Bit mask of DOG field. */
#define POWER_RESETREAS_DOG_NotDetected (0UL) /*!< Reset not detected. */
#define POWER_RESETREAS_DOG_Detected (1UL) /*!< Reset detected. */
/* Bit 0 : Reset from pin-reset detected. */
#define POWER_RESETREAS_RESETPIN_Pos (0UL) /*!< Position of RESETPIN field. */
#define POWER_RESETREAS_RESETPIN_Msk (0x1UL << POWER_RESETREAS_RESETPIN_Pos) /*!< Bit mask of RESETPIN field. */
#define POWER_RESETREAS_RESETPIN_NotDetected (0UL) /*!< Reset not detected. */
#define POWER_RESETREAS_RESETPIN_Detected (1UL) /*!< Reset detected. */
/* Register: POWER_RAMSTATUS */
/* Description: Ram status register. */
@ -4636,186 +4596,6 @@
#define PPI_CHG_CH0_Included (1UL) /*!< Channel included. */
/* Peripheral: PU */
/* Description: Patch unit. */
/* Register: PU_PATCHADDR */
/* Description: Relative address of patch instructions. */
/* Bits 24..0 : Relative address of patch instructions. */
#define PU_PATCHADDR_PATCHADDR_Pos (0UL) /*!< Position of PATCHADDR field. */
#define PU_PATCHADDR_PATCHADDR_Msk (0x1FFFFFFUL << PU_PATCHADDR_PATCHADDR_Pos) /*!< Bit mask of PATCHADDR field. */
/* Register: PU_PATCHEN */
/* Description: Patch enable register. */
/* Bit 7 : Patch 7 enabled. */
#define PU_PATCHEN_PATCH7_Pos (7UL) /*!< Position of PATCH7 field. */
#define PU_PATCHEN_PATCH7_Msk (0x1UL << PU_PATCHEN_PATCH7_Pos) /*!< Bit mask of PATCH7 field. */
#define PU_PATCHEN_PATCH7_Disabled (0UL) /*!< Patch disabled. */
#define PU_PATCHEN_PATCH7_Enabled (1UL) /*!< Patch enabled. */
/* Bit 6 : Patch 6 enabled. */
#define PU_PATCHEN_PATCH6_Pos (6UL) /*!< Position of PATCH6 field. */
#define PU_PATCHEN_PATCH6_Msk (0x1UL << PU_PATCHEN_PATCH6_Pos) /*!< Bit mask of PATCH6 field. */
#define PU_PATCHEN_PATCH6_Disabled (0UL) /*!< Patch disabled. */
#define PU_PATCHEN_PATCH6_Enabled (1UL) /*!< Patch enabled. */
/* Bit 5 : Patch 5 enabled. */
#define PU_PATCHEN_PATCH5_Pos (5UL) /*!< Position of PATCH5 field. */
#define PU_PATCHEN_PATCH5_Msk (0x1UL << PU_PATCHEN_PATCH5_Pos) /*!< Bit mask of PATCH5 field. */
#define PU_PATCHEN_PATCH5_Disabled (0UL) /*!< Patch disabled. */
#define PU_PATCHEN_PATCH5_Enabled (1UL) /*!< Patch enabled. */
/* Bit 4 : Patch 4 enabled. */
#define PU_PATCHEN_PATCH4_Pos (4UL) /*!< Position of PATCH4 field. */
#define PU_PATCHEN_PATCH4_Msk (0x1UL << PU_PATCHEN_PATCH4_Pos) /*!< Bit mask of PATCH4 field. */
#define PU_PATCHEN_PATCH4_Disabled (0UL) /*!< Patch disabled. */
#define PU_PATCHEN_PATCH4_Enabled (1UL) /*!< Patch enabled. */
/* Bit 3 : Patch 3 enabled. */
#define PU_PATCHEN_PATCH3_Pos (3UL) /*!< Position of PATCH3 field. */
#define PU_PATCHEN_PATCH3_Msk (0x1UL << PU_PATCHEN_PATCH3_Pos) /*!< Bit mask of PATCH3 field. */
#define PU_PATCHEN_PATCH3_Disabled (0UL) /*!< Patch disabled. */
#define PU_PATCHEN_PATCH3_Enabled (1UL) /*!< Patch enabled. */
/* Bit 2 : Patch 2 enabled. */
#define PU_PATCHEN_PATCH2_Pos (2UL) /*!< Position of PATCH2 field. */
#define PU_PATCHEN_PATCH2_Msk (0x1UL << PU_PATCHEN_PATCH2_Pos) /*!< Bit mask of PATCH2 field. */
#define PU_PATCHEN_PATCH2_Disabled (0UL) /*!< Patch disabled. */
#define PU_PATCHEN_PATCH2_Enabled (1UL) /*!< Patch enabled. */
/* Bit 1 : Patch 1 enabled. */
#define PU_PATCHEN_PATCH1_Pos (1UL) /*!< Position of PATCH1 field. */
#define PU_PATCHEN_PATCH1_Msk (0x1UL << PU_PATCHEN_PATCH1_Pos) /*!< Bit mask of PATCH1 field. */
#define PU_PATCHEN_PATCH1_Disabled (0UL) /*!< Patch disabled. */
#define PU_PATCHEN_PATCH1_Enabled (1UL) /*!< Patch enabled. */
/* Bit 0 : Patch 0 enabled. */
#define PU_PATCHEN_PATCH0_Pos (0UL) /*!< Position of PATCH0 field. */
#define PU_PATCHEN_PATCH0_Msk (0x1UL << PU_PATCHEN_PATCH0_Pos) /*!< Bit mask of PATCH0 field. */
#define PU_PATCHEN_PATCH0_Disabled (0UL) /*!< Patch disabled. */
#define PU_PATCHEN_PATCH0_Enabled (1UL) /*!< Patch enabled. */
/* Register: PU_PATCHENSET */
/* Description: Patch enable register. */
/* Bit 7 : Patch 7 enabled. */
#define PU_PATCHENSET_PATCH7_Pos (7UL) /*!< Position of PATCH7 field. */
#define PU_PATCHENSET_PATCH7_Msk (0x1UL << PU_PATCHENSET_PATCH7_Pos) /*!< Bit mask of PATCH7 field. */
#define PU_PATCHENSET_PATCH7_Disabled (0UL) /*!< Patch disabled. */
#define PU_PATCHENSET_PATCH7_Enabled (1UL) /*!< Patch enabled. */
#define PU_PATCHENSET_PATCH7_Set (1UL) /*!< Enable patch on write. */
/* Bit 6 : Patch 6 enabled. */
#define PU_PATCHENSET_PATCH6_Pos (6UL) /*!< Position of PATCH6 field. */
#define PU_PATCHENSET_PATCH6_Msk (0x1UL << PU_PATCHENSET_PATCH6_Pos) /*!< Bit mask of PATCH6 field. */
#define PU_PATCHENSET_PATCH6_Disabled (0UL) /*!< Patch disabled. */
#define PU_PATCHENSET_PATCH6_Enabled (1UL) /*!< Patch enabled. */
#define PU_PATCHENSET_PATCH6_Set (1UL) /*!< Enable patch on write. */
/* Bit 5 : Patch 5 enabled. */
#define PU_PATCHENSET_PATCH5_Pos (5UL) /*!< Position of PATCH5 field. */
#define PU_PATCHENSET_PATCH5_Msk (0x1UL << PU_PATCHENSET_PATCH5_Pos) /*!< Bit mask of PATCH5 field. */
#define PU_PATCHENSET_PATCH5_Disabled (0UL) /*!< Patch disabled. */
#define PU_PATCHENSET_PATCH5_Enabled (1UL) /*!< Patch enabled. */
#define PU_PATCHENSET_PATCH5_Set (1UL) /*!< Enable patch on write. */
/* Bit 4 : Patch 4 enabled. */
#define PU_PATCHENSET_PATCH4_Pos (4UL) /*!< Position of PATCH4 field. */
#define PU_PATCHENSET_PATCH4_Msk (0x1UL << PU_PATCHENSET_PATCH4_Pos) /*!< Bit mask of PATCH4 field. */
#define PU_PATCHENSET_PATCH4_Disabled (0UL) /*!< Patch disabled. */
#define PU_PATCHENSET_PATCH4_Enabled (1UL) /*!< Patch enabled. */
#define PU_PATCHENSET_PATCH4_Set (1UL) /*!< Enable patch on write. */
/* Bit 3 : Patch 3 enabled. */
#define PU_PATCHENSET_PATCH3_Pos (3UL) /*!< Position of PATCH3 field. */
#define PU_PATCHENSET_PATCH3_Msk (0x1UL << PU_PATCHENSET_PATCH3_Pos) /*!< Bit mask of PATCH3 field. */
#define PU_PATCHENSET_PATCH3_Disabled (0UL) /*!< Patch disabled. */
#define PU_PATCHENSET_PATCH3_Enabled (1UL) /*!< Patch enabled. */
#define PU_PATCHENSET_PATCH3_Set (1UL) /*!< Enable patch on write. */
/* Bit 2 : Patch 2 enabled. */
#define PU_PATCHENSET_PATCH2_Pos (2UL) /*!< Position of PATCH2 field. */
#define PU_PATCHENSET_PATCH2_Msk (0x1UL << PU_PATCHENSET_PATCH2_Pos) /*!< Bit mask of PATCH2 field. */
#define PU_PATCHENSET_PATCH2_Disabled (0UL) /*!< Patch disabled. */
#define PU_PATCHENSET_PATCH2_Enabled (1UL) /*!< Patch enabled. */
#define PU_PATCHENSET_PATCH2_Set (1UL) /*!< Enable patch on write. */
/* Bit 1 : Patch 1 enabled. */
#define PU_PATCHENSET_PATCH1_Pos (1UL) /*!< Position of PATCH1 field. */
#define PU_PATCHENSET_PATCH1_Msk (0x1UL << PU_PATCHENSET_PATCH1_Pos) /*!< Bit mask of PATCH1 field. */
#define PU_PATCHENSET_PATCH1_Disabled (0UL) /*!< Patch disabled. */
#define PU_PATCHENSET_PATCH1_Enabled (1UL) /*!< Patch enabled. */
#define PU_PATCHENSET_PATCH1_Set (1UL) /*!< Enable patch on write. */
/* Bit 0 : Patch 0 enabled. */
#define PU_PATCHENSET_PATCH0_Pos (0UL) /*!< Position of PATCH0 field. */
#define PU_PATCHENSET_PATCH0_Msk (0x1UL << PU_PATCHENSET_PATCH0_Pos) /*!< Bit mask of PATCH0 field. */
#define PU_PATCHENSET_PATCH0_Disabled (0UL) /*!< Patch disabled. */
#define PU_PATCHENSET_PATCH0_Enabled (1UL) /*!< Patch enabled. */
#define PU_PATCHENSET_PATCH0_Set (1UL) /*!< Enable patch on write. */
/* Register: PU_PATCHENCLR */
/* Description: Patch disable register. */
/* Bit 7 : Patch 7 enabled. */
#define PU_PATCHENCLR_PATCH7_Pos (7UL) /*!< Position of PATCH7 field. */
#define PU_PATCHENCLR_PATCH7_Msk (0x1UL << PU_PATCHENCLR_PATCH7_Pos) /*!< Bit mask of PATCH7 field. */
#define PU_PATCHENCLR_PATCH7_Disabled (0UL) /*!< Patch disabled. */
#define PU_PATCHENCLR_PATCH7_Enabled (1UL) /*!< Patch enabled. */
#define PU_PATCHENCLR_PATCH7_Clear (1UL) /*!< Disable patch on write. */
/* Bit 6 : Patch 6 enabled. */
#define PU_PATCHENCLR_PATCH6_Pos (6UL) /*!< Position of PATCH6 field. */
#define PU_PATCHENCLR_PATCH6_Msk (0x1UL << PU_PATCHENCLR_PATCH6_Pos) /*!< Bit mask of PATCH6 field. */
#define PU_PATCHENCLR_PATCH6_Disabled (0UL) /*!< Patch disabled. */
#define PU_PATCHENCLR_PATCH6_Enabled (1UL) /*!< Patch enabled. */
#define PU_PATCHENCLR_PATCH6_Clear (1UL) /*!< Disable patch on write. */
/* Bit 5 : Patch 5 enabled. */
#define PU_PATCHENCLR_PATCH5_Pos (5UL) /*!< Position of PATCH5 field. */
#define PU_PATCHENCLR_PATCH5_Msk (0x1UL << PU_PATCHENCLR_PATCH5_Pos) /*!< Bit mask of PATCH5 field. */
#define PU_PATCHENCLR_PATCH5_Disabled (0UL) /*!< Patch disabled. */
#define PU_PATCHENCLR_PATCH5_Enabled (1UL) /*!< Patch enabled. */
#define PU_PATCHENCLR_PATCH5_Clear (1UL) /*!< Disable patch on write. */
/* Bit 4 : Patch 4 enabled. */
#define PU_PATCHENCLR_PATCH4_Pos (4UL) /*!< Position of PATCH4 field. */
#define PU_PATCHENCLR_PATCH4_Msk (0x1UL << PU_PATCHENCLR_PATCH4_Pos) /*!< Bit mask of PATCH4 field. */
#define PU_PATCHENCLR_PATCH4_Disabled (0UL) /*!< Patch disabled. */
#define PU_PATCHENCLR_PATCH4_Enabled (1UL) /*!< Patch enabled. */
#define PU_PATCHENCLR_PATCH4_Clear (1UL) /*!< Disable patch on write. */
/* Bit 3 : Patch 3 enabled. */
#define PU_PATCHENCLR_PATCH3_Pos (3UL) /*!< Position of PATCH3 field. */
#define PU_PATCHENCLR_PATCH3_Msk (0x1UL << PU_PATCHENCLR_PATCH3_Pos) /*!< Bit mask of PATCH3 field. */
#define PU_PATCHENCLR_PATCH3_Disabled (0UL) /*!< Patch disabled. */
#define PU_PATCHENCLR_PATCH3_Enabled (1UL) /*!< Patch enabled. */
#define PU_PATCHENCLR_PATCH3_Clear (1UL) /*!< Disable patch on write. */
/* Bit 2 : Patch 2 enabled. */
#define PU_PATCHENCLR_PATCH2_Pos (2UL) /*!< Position of PATCH2 field. */
#define PU_PATCHENCLR_PATCH2_Msk (0x1UL << PU_PATCHENCLR_PATCH2_Pos) /*!< Bit mask of PATCH2 field. */
#define PU_PATCHENCLR_PATCH2_Disabled (0UL) /*!< Patch disabled. */
#define PU_PATCHENCLR_PATCH2_Enabled (1UL) /*!< Patch enabled. */
#define PU_PATCHENCLR_PATCH2_Clear (1UL) /*!< Disable patch on write. */
/* Bit 1 : Patch 1 enabled. */
#define PU_PATCHENCLR_PATCH1_Pos (1UL) /*!< Position of PATCH1 field. */
#define PU_PATCHENCLR_PATCH1_Msk (0x1UL << PU_PATCHENCLR_PATCH1_Pos) /*!< Bit mask of PATCH1 field. */
#define PU_PATCHENCLR_PATCH1_Disabled (0UL) /*!< Patch disabled. */
#define PU_PATCHENCLR_PATCH1_Enabled (1UL) /*!< Patch enabled. */
#define PU_PATCHENCLR_PATCH1_Clear (1UL) /*!< Disable patch on write. */
/* Bit 0 : Patch 0 enabled. */
#define PU_PATCHENCLR_PATCH0_Pos (0UL) /*!< Position of PATCH0 field. */
#define PU_PATCHENCLR_PATCH0_Msk (0x1UL << PU_PATCHENCLR_PATCH0_Pos) /*!< Bit mask of PATCH0 field. */
#define PU_PATCHENCLR_PATCH0_Disabled (0UL) /*!< Patch disabled. */
#define PU_PATCHENCLR_PATCH0_Enabled (1UL) /*!< Patch enabled. */
#define PU_PATCHENCLR_PATCH0_Clear (1UL) /*!< Disable patch on write. */
/* Peripheral: QDEC */
/* Description: Rotary decoder. */
@ -5172,13 +4952,6 @@
#define RADIO_CRCSTATUS_CRCSTATUS_CRCError (0UL) /*!< Packet received with CRC error. */
#define RADIO_CRCSTATUS_CRCSTATUS_CRCOk (1UL) /*!< Packet received with CRC ok. */
/* Register: RADIO_CD */
/* Description: Carrier detect. */
/* Bit 0 : Carrier detect. */
#define RADIO_CD_CD_Pos (0UL) /*!< Position of CD field. */
#define RADIO_CD_CD_Msk (0x1UL << RADIO_CD_CD_Pos) /*!< Bit mask of CD field. */
/* Register: RADIO_RXMATCH */
/* Description: Received address. */
@ -5213,14 +4986,14 @@
/* Bits 7..0 : Radio output power. Decision point: TXEN task. */
#define RADIO_TXPOWER_TXPOWER_Pos (0UL) /*!< Position of TXPOWER field. */
#define RADIO_TXPOWER_TXPOWER_Msk (0xFFUL << RADIO_TXPOWER_TXPOWER_Pos) /*!< Bit mask of TXPOWER field. */
#define RADIO_TXPOWER_TXPOWER_Pos4dBm (0x04UL) /*!< +4dBm. */
#define RADIO_TXPOWER_TXPOWER_0dBm (0x00UL) /*!< 0dBm. */
#define RADIO_TXPOWER_TXPOWER_Neg4dBm (0xFCUL) /*!< -4dBm. */
#define RADIO_TXPOWER_TXPOWER_Neg8dBm (0xF8UL) /*!< -8dBm. */
#define RADIO_TXPOWER_TXPOWER_Neg12dBm (0xF4UL) /*!< -12dBm. */
#define RADIO_TXPOWER_TXPOWER_Neg16dBm (0xF0UL) /*!< -16dBm. */
#define RADIO_TXPOWER_TXPOWER_Neg20dBm (0xECUL) /*!< -20dBm. */
#define RADIO_TXPOWER_TXPOWER_Pos4dBm (0x04UL) /*!< +4dBm. */
#define RADIO_TXPOWER_TXPOWER_Neg30dBm (0xD8UL) /*!< -30dBm. */
#define RADIO_TXPOWER_TXPOWER_Neg20dBm (0xECUL) /*!< -20dBm. */
#define RADIO_TXPOWER_TXPOWER_Neg16dBm (0xF0UL) /*!< -16dBm. */
#define RADIO_TXPOWER_TXPOWER_Neg12dBm (0xF4UL) /*!< -12dBm. */
#define RADIO_TXPOWER_TXPOWER_Neg8dBm (0xF8UL) /*!< -8dBm. */
#define RADIO_TXPOWER_TXPOWER_Neg4dBm (0xFCUL) /*!< -4dBm. */
/* Register: RADIO_MODE */
/* Description: Data rate and modulation. */
@ -6000,15 +5773,6 @@
/* Peripheral: SPIM */
/* Description: SPI master with easyDMA 1. */
/* Register: SPIM_SHORTS */
/* Description: Shortcuts for SPIM. */
/* Bit 17 : Shortcut between END event and START task. */
#define SPIM_SHORTS_END_START_Pos (17UL) /*!< Position of END_START field. */
#define SPIM_SHORTS_END_START_Msk (0x1UL << SPIM_SHORTS_END_START_Pos) /*!< Bit mask of END_START field. */
#define SPIM_SHORTS_END_START_Disabled (0UL) /*!< Shortcut disabled. */
#define SPIM_SHORTS_END_START_Enabled (1UL) /*!< Shortcut enabled. */
/* Register: SPIM_INTENSET */
/* Description: Interrupt enable set register. */
@ -6026,13 +5790,6 @@
#define SPIM_INTENSET_ENDTX_Enabled (1UL) /*!< Interrupt enabled. */
#define SPIM_INTENSET_ENDTX_Set (1UL) /*!< Enable interrupt on write. */
/* Bit 6 : Enable interrupt on END event. */
#define SPIM_INTENSET_END_Pos (6UL) /*!< Position of END field. */
#define SPIM_INTENSET_END_Msk (0x1UL << SPIM_INTENSET_END_Pos) /*!< Bit mask of END field. */
#define SPIM_INTENSET_END_Disabled (0UL) /*!< Interrupt disabled. */
#define SPIM_INTENSET_END_Enabled (1UL) /*!< Interrupt enabled. */
#define SPIM_INTENSET_END_Set (1UL) /*!< Enable interrupt on write. */
/* Bit 4 : Enable interrupt on ENDRX event. */
#define SPIM_INTENSET_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */
#define SPIM_INTENSET_ENDRX_Msk (0x1UL << SPIM_INTENSET_ENDRX_Pos) /*!< Bit mask of ENDRX field. */
@ -6064,13 +5821,6 @@
#define SPIM_INTENCLR_ENDTX_Enabled (1UL) /*!< Interrupt enabled. */
#define SPIM_INTENCLR_ENDTX_Clear (1UL) /*!< Disable interrupt on write. */
/* Bit 6 : Disable interrupt on END event. */
#define SPIM_INTENCLR_END_Pos (6UL) /*!< Position of END field. */
#define SPIM_INTENCLR_END_Msk (0x1UL << SPIM_INTENCLR_END_Pos) /*!< Bit mask of END field. */
#define SPIM_INTENCLR_END_Disabled (0UL) /*!< Interrupt disabled. */
#define SPIM_INTENCLR_END_Enabled (1UL) /*!< Interrupt enabled. */
#define SPIM_INTENCLR_END_Clear (1UL) /*!< Disable interrupt on write. */
/* Bit 4 : Disable interrupt on ENDRX event. */
#define SPIM_INTENCLR_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */
#define SPIM_INTENCLR_ENDRX_Msk (0x1UL << SPIM_INTENCLR_ENDRX_Pos) /*!< Bit mask of ENDRX field. */
@ -6094,20 +5844,6 @@
#define SPIM_ENABLE_ENABLE_Disabled (0x00UL) /*!< Disabled SPIM. */
#define SPIM_ENABLE_ENABLE_Enabled (0x07UL) /*!< Enable SPIM. */
/* Register: SPIM_RXDDATA */
/* Description: RXD register. */
/* Bits 7..0 : RX data received. Double buffered. */
#define SPIM_RXDDATA_RXD_Pos (0UL) /*!< Position of RXD field. */
#define SPIM_RXDDATA_RXD_Msk (0xFFUL << SPIM_RXDDATA_RXD_Pos) /*!< Bit mask of RXD field. */
/* Register: SPIM_TXDDATA */
/* Description: TXD register. */
/* Bits 7..0 : TX data to send. Double buffered. */
#define SPIM_TXDDATA_TXD_Pos (0UL) /*!< Position of TXD field. */
#define SPIM_TXDDATA_TXD_Msk (0xFFUL << SPIM_TXDDATA_TXD_Pos) /*!< Bit mask of TXD field. */
/* Register: SPIM_FREQUENCY */
/* Description: SPI frequency. */
@ -6122,43 +5858,6 @@
#define SPIM_FREQUENCY_FREQUENCY_M4 (0x40000000UL) /*!< 4 Mbps. */
#define SPIM_FREQUENCY_FREQUENCY_M8 (0x80000000UL) /*!< 8 Mbps. */
/* Register: SPIM_CONFIG */
/* Description: Configuration register. */
/* Bit 2 : Serial clock (SCK) polarity. */
#define SPIM_CONFIG_CPOL_Pos (2UL) /*!< Position of CPOL field. */
#define SPIM_CONFIG_CPOL_Msk (0x1UL << SPIM_CONFIG_CPOL_Pos) /*!< Bit mask of CPOL field. */
#define SPIM_CONFIG_CPOL_ActiveHigh (0UL) /*!< Active high. */
#define SPIM_CONFIG_CPOL_ActiveLow (1UL) /*!< Active low. */
/* Bit 1 : Serial clock (SCK) phase. */
#define SPIM_CONFIG_CPHA_Pos (1UL) /*!< Position of CPHA field. */
#define SPIM_CONFIG_CPHA_Msk (0x1UL << SPIM_CONFIG_CPHA_Pos) /*!< Bit mask of CPHA field. */
#define SPIM_CONFIG_CPHA_Leading (0UL) /*!< Sample on leading edge of the clock. Shift serial data on trailing edge. */
#define SPIM_CONFIG_CPHA_Trailing (1UL) /*!< Sample on trailing edge of the clock. Shift serial data on leading edge. */
/* Bit 0 : Bit order. */
#define SPIM_CONFIG_ORDER_Pos (0UL) /*!< Position of ORDER field. */
#define SPIM_CONFIG_ORDER_Msk (0x1UL << SPIM_CONFIG_ORDER_Pos) /*!< Bit mask of ORDER field. */
#define SPIM_CONFIG_ORDER_MsbFirst (0UL) /*!< Most significant bit transmitted out first. */
#define SPIM_CONFIG_ORDER_LsbFirst (1UL) /*!< Least significant bit transmitted out first. */
/* Register: SPIM_ORC */
/* Description: Over-read character. */
/* Bits 7..0 : Over-read character. */
#define SPIM_ORC_ORC_Pos (0UL) /*!< Position of ORC field. */
#define SPIM_ORC_ORC_Msk (0xFFUL << SPIM_ORC_ORC_Pos) /*!< Bit mask of ORC field. */
/* Register: SPIM_POWER */
/* Description: Peripheral power control. */
/* Bit 0 : Peripheral power control. */
#define SPIM_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
#define SPIM_POWER_POWER_Msk (0x1UL << SPIM_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
#define SPIM_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
#define SPIM_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
/* Register: SPIM_RXD_PTR */
/* Description: Data pointer. */
@ -6201,6 +5900,43 @@
#define SPIM_TXD_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */
#define SPIM_TXD_AMOUNT_AMOUNT_Msk (0xFFUL << SPIM_TXD_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */
/* Register: SPIM_CONFIG */
/* Description: Configuration register. */
/* Bit 2 : Serial clock (SCK) polarity. */
#define SPIM_CONFIG_CPOL_Pos (2UL) /*!< Position of CPOL field. */
#define SPIM_CONFIG_CPOL_Msk (0x1UL << SPIM_CONFIG_CPOL_Pos) /*!< Bit mask of CPOL field. */
#define SPIM_CONFIG_CPOL_ActiveHigh (0UL) /*!< Active high. */
#define SPIM_CONFIG_CPOL_ActiveLow (1UL) /*!< Active low. */
/* Bit 1 : Serial clock (SCK) phase. */
#define SPIM_CONFIG_CPHA_Pos (1UL) /*!< Position of CPHA field. */
#define SPIM_CONFIG_CPHA_Msk (0x1UL << SPIM_CONFIG_CPHA_Pos) /*!< Bit mask of CPHA field. */
#define SPIM_CONFIG_CPHA_Leading (0UL) /*!< Sample on leading edge of the clock. Shift serial data on trailing edge. */
#define SPIM_CONFIG_CPHA_Trailing (1UL) /*!< Sample on trailing edge of the clock. Shift serial data on leading edge. */
/* Bit 0 : Bit order. */
#define SPIM_CONFIG_ORDER_Pos (0UL) /*!< Position of ORDER field. */
#define SPIM_CONFIG_ORDER_Msk (0x1UL << SPIM_CONFIG_ORDER_Pos) /*!< Bit mask of ORDER field. */
#define SPIM_CONFIG_ORDER_MsbFirst (0UL) /*!< Most significant bit transmitted out first. */
#define SPIM_CONFIG_ORDER_LsbFirst (1UL) /*!< Least significant bit transmitted out first. */
/* Register: SPIM_ORC */
/* Description: Over-read character. */
/* Bits 7..0 : Over-read character. */
#define SPIM_ORC_ORC_Pos (0UL) /*!< Position of ORC field. */
#define SPIM_ORC_ORC_Msk (0xFFUL << SPIM_ORC_ORC_Pos) /*!< Bit mask of ORC field. */
/* Register: SPIM_POWER */
/* Description: Peripheral power control. */
/* Bit 0 : Peripheral power control. */
#define SPIM_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
#define SPIM_POWER_POWER_Msk (0x1UL << SPIM_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
#define SPIM_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
#define SPIM_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
/* Peripheral: SPIS */
/* Description: SPI slave 1. */
@ -6224,6 +5960,13 @@
#define SPIS_INTENSET_ACQUIRED_Enabled (1UL) /*!< Interrupt enabled. */
#define SPIS_INTENSET_ACQUIRED_Set (1UL) /*!< Enable interrupt on write. */
/* Bit 4 : enable interrupt on ENDRX event. */
#define SPIS_INTENSET_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */
#define SPIS_INTENSET_ENDRX_Msk (0x1UL << SPIS_INTENSET_ENDRX_Pos) /*!< Bit mask of ENDRX field. */
#define SPIS_INTENSET_ENDRX_Disabled (0UL) /*!< Interrupt disabled. */
#define SPIS_INTENSET_ENDRX_Enabled (1UL) /*!< Interrupt enabled. */
#define SPIS_INTENSET_ENDRX_Set (1UL) /*!< Enable interrupt on write. */
/* Bit 1 : Enable interrupt on END event. */
#define SPIS_INTENSET_END_Pos (1UL) /*!< Position of END field. */
#define SPIS_INTENSET_END_Msk (0x1UL << SPIS_INTENSET_END_Pos) /*!< Bit mask of END field. */
@ -6241,6 +5984,13 @@
#define SPIS_INTENCLR_ACQUIRED_Enabled (1UL) /*!< Interrupt enabled. */
#define SPIS_INTENCLR_ACQUIRED_Clear (1UL) /*!< Disable interrupt on write. */
/* Bit 4 : Disable interrupt on ENDRX event. */
#define SPIS_INTENCLR_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */
#define SPIS_INTENCLR_ENDRX_Msk (0x1UL << SPIS_INTENCLR_ENDRX_Pos) /*!< Bit mask of ENDRX field. */
#define SPIS_INTENCLR_ENDRX_Disabled (0UL) /*!< Interrupt disabled. */
#define SPIS_INTENCLR_ENDRX_Enabled (1UL) /*!< Interrupt enabled. */
#define SPIS_INTENCLR_ENDRX_Clear (1UL) /*!< Disable interrupt on write. */
/* Bit 1 : Disable interrupt on END event. */
#define SPIS_INTENCLR_END_Pos (1UL) /*!< Position of END field. */
#define SPIS_INTENCLR_END_Msk (0x1UL << SPIS_INTENCLR_END_Pos) /*!< Bit mask of END field. */
@ -6669,6 +6419,13 @@
#define TWI_ERRORSRC_ANACK_Present (1UL) /*!< Error present. */
#define TWI_ERRORSRC_ANACK_Clear (1UL) /*!< Clear error on write. */
/* Bit 0 : Byte received in RXD register before read of the last received byte (data loss). */
#define TWI_ERRORSRC_OVERRUN_Pos (0UL) /*!< Position of OVERRUN field. */
#define TWI_ERRORSRC_OVERRUN_Msk (0x1UL << TWI_ERRORSRC_OVERRUN_Pos) /*!< Bit mask of OVERRUN field. */
#define TWI_ERRORSRC_OVERRUN_NotPresent (0UL) /*!< Error not present. */
#define TWI_ERRORSRC_OVERRUN_Present (1UL) /*!< Error present. */
#define TWI_ERRORSRC_OVERRUN_Clear (1UL) /*!< Clear error on write. */
/* Register: TWI_ENABLE */
/* Description: Enable two-wire master. */
@ -6725,13 +6482,13 @@
/* Register: UART_SHORTS */
/* Description: Shortcuts for UART. */
/* Bit 4 : Shortcut between NCTS event and the STOPRX task. */
/* Bit 4 : Shortcut between NCTS event and STOPRX task. */
#define UART_SHORTS_NCTS_STOPRX_Pos (4UL) /*!< Position of NCTS_STOPRX field. */
#define UART_SHORTS_NCTS_STOPRX_Msk (0x1UL << UART_SHORTS_NCTS_STOPRX_Pos) /*!< Bit mask of NCTS_STOPRX field. */
#define UART_SHORTS_NCTS_STOPRX_Disabled (0UL) /*!< Shortcut disabled. */
#define UART_SHORTS_NCTS_STOPRX_Enabled (1UL) /*!< Shortcut enabled. */
/* Bit 3 : Shortcut between CTS event and the STARTRX task. */
/* Bit 3 : Shortcut between CTS event and STARTRX task. */
#define UART_SHORTS_CTS_STARTRX_Pos (3UL) /*!< Position of CTS_STARTRX field. */
#define UART_SHORTS_CTS_STARTRX_Msk (0x1UL << UART_SHORTS_CTS_STARTRX_Pos) /*!< Bit mask of CTS_STARTRX field. */
#define UART_SHORTS_CTS_STARTRX_Disabled (0UL) /*!< Shortcut disabled. */
@ -6901,7 +6658,7 @@
#define UART_BAUDRATE_BAUDRATE_Baud230400 (0x03AFB000UL) /*!< 230400 baud. */
#define UART_BAUDRATE_BAUDRATE_Baud250000 (0x04000000UL) /*!< 250000 baud. */
#define UART_BAUDRATE_BAUDRATE_Baud460800 (0x075F7000UL) /*!< 460800 baud. */
#define UART_BAUDRATE_BAUDRATE_Baud921600 (0x0EBEDFA4UL) /*!< 921600 baud. */
#define UART_BAUDRATE_BAUDRATE_Baud921600 (0x0EBED000UL) /*!< 921600 baud. */
#define UART_BAUDRATE_BAUDRATE_Baud1M (0x10000000UL) /*!< 1M baud. */
/* Register: UART_CONFIG */
@ -6938,14 +6695,14 @@
/* Bits 15..8 : Readback protect all code in the device. */
#define UICR_RBPCONF_PALL_Pos (8UL) /*!< Position of PALL field. */
#define UICR_RBPCONF_PALL_Msk (0xFFUL << UICR_RBPCONF_PALL_Pos) /*!< Bit mask of PALL field. */
#define UICR_RBPCONF_PALL_Disabled (0xFFUL) /*!< Disabled. */
#define UICR_RBPCONF_PALL_Enabled (0x00UL) /*!< Enabled. */
#define UICR_RBPCONF_PALL_Disabled (0xFFUL) /*!< Disabled. */
/* Bits 7..0 : Readback protect region 0. Will be ignored if pre-programmed factory code is present on the chip. */
#define UICR_RBPCONF_PR0_Pos (0UL) /*!< Position of PR0 field. */
#define UICR_RBPCONF_PR0_Msk (0xFFUL << UICR_RBPCONF_PR0_Pos) /*!< Bit mask of PR0 field. */
#define UICR_RBPCONF_PR0_Disabled (0xFFUL) /*!< Disabled. */
#define UICR_RBPCONF_PR0_Enabled (0x00UL) /*!< Enabled. */
#define UICR_RBPCONF_PR0_Disabled (0xFFUL) /*!< Disabled. */
/* Register: UICR_XTALFREQ */
/* Description: Reset value for CLOCK XTALFREQ register. */
@ -6953,8 +6710,8 @@
/* Bits 7..0 : Reset value for CLOCK XTALFREQ register. */
#define UICR_XTALFREQ_XTALFREQ_Pos (0UL) /*!< Position of XTALFREQ field. */
#define UICR_XTALFREQ_XTALFREQ_Msk (0xFFUL << UICR_XTALFREQ_XTALFREQ_Pos) /*!< Bit mask of XTALFREQ field. */
#define UICR_XTALFREQ_XTALFREQ_16MHz (0xFFUL) /*!< 16MHz Xtal is used. */
#define UICR_XTALFREQ_XTALFREQ_32MHz (0x00UL) /*!< 32MHz Xtal is used. */
#define UICR_XTALFREQ_XTALFREQ_16MHz (0xFFUL) /*!< 16MHz Xtal is used. */
/* Register: UICR_FWID */
/* Description: Firmware ID. */

View File

@ -0,0 +1,438 @@
/* Copyright (c) 2015, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* 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.
*
*/
#ifndef NRF51_DEPRECATED_H
#define NRF51_DEPRECATED_H
/*lint ++flb "Enter library region */
/* This file is given to prevent your SW from not compiling with the updates made to nrf51.h and
* nrf51_bitfields.h. The macros defined in this file were available previously. Do not use these
* macros on purpose. Use the ones defined in nrf51.h and nrf51_bitfields.h instead.
*/
/* NVMC */
/* The register ERASEPROTECTEDPAGE is called ERASEPCR0 in the documentation. */
#define ERASEPROTECTEDPAGE ERASEPCR0
/* LPCOMP */
/* The interrupt ISR was renamed. Adding old name to the macros. */
#define LPCOMP_COMP_IRQHandler LPCOMP_IRQHandler
#define LPCOMP_COMP_IRQn LPCOMP_IRQn
/* MPU */
/* The field MPU.PERR0.LPCOMP_COMP was renamed. Added into deprecated in case somebody was using the macros defined for it. */
#define MPU_PERR0_LPCOMP_COMP_Pos MPU_PERR0_LPCOMP_Pos
#define MPU_PERR0_LPCOMP_COMP_Msk MPU_PERR0_LPCOMP_Msk
#define MPU_PERR0_LPCOMP_COMP_InRegion1 MPU_PERR0_LPCOMP_InRegion1
#define MPU_PERR0_LPCOMP_COMP_InRegion0 MPU_PERR0_LPCOMP_InRegion0
/* POWER */
/* The field POWER.RAMON.OFFRAM3 was eliminated. Added into deprecated in case somebody was using the macros defined for it. */
#define POWER_RAMON_OFFRAM3_Pos (19UL)
#define POWER_RAMON_OFFRAM3_Msk (0x1UL << POWER_RAMON_OFFRAM3_Pos)
#define POWER_RAMON_OFFRAM3_RAM3Off (0UL)
#define POWER_RAMON_OFFRAM3_RAM3On (1UL)
/* The field POWER.RAMON.OFFRAM2 was eliminated. Added into deprecated in case somebody was using the macros defined for it. */
#define POWER_RAMON_OFFRAM2_Pos (18UL)
#define POWER_RAMON_OFFRAM2_Msk (0x1UL << POWER_RAMON_OFFRAM2_Pos)
#define POWER_RAMON_OFFRAM2_RAM2Off (0UL)
#define POWER_RAMON_OFFRAM2_RAM2On (1UL)
/* The field POWER.RAMON.ONRAM3 was eliminated. Added into deprecated in case somebody was using the macros defined for it. */
#define POWER_RAMON_ONRAM3_Pos (3UL)
#define POWER_RAMON_ONRAM3_Msk (0x1UL << POWER_RAMON_ONRAM3_Pos)
#define POWER_RAMON_ONRAM3_RAM3Off (0UL)
#define POWER_RAMON_ONRAM3_RAM3On (1UL)
/* The field POWER.RAMON.ONRAM2 was eliminated. Added into deprecated in case somebody was using the macros defined for it. */
#define POWER_RAMON_ONRAM2_Pos (2UL)
#define POWER_RAMON_ONRAM2_Msk (0x1UL << POWER_RAMON_ONRAM2_Pos)
#define POWER_RAMON_ONRAM2_RAM2Off (0UL)
#define POWER_RAMON_ONRAM2_RAM2On (1UL)
/* RADIO */
/* The enumerated value RADIO.TXPOWER.TXPOWER.Neg40dBm was renamed. Added into deprecated with the new macro name. */
#define RADIO_TXPOWER_TXPOWER_Neg40dBm RADIO_TXPOWER_TXPOWER_Neg30dBm
/* The name of the field SKIPADDR was corrected. Old macros added for compatibility. */
#define RADIO_CRCCNF_SKIP_ADDR_Pos RADIO_CRCCNF_SKIPADDR_Pos
#define RADIO_CRCCNF_SKIP_ADDR_Msk RADIO_CRCCNF_SKIPADDR_Msk
#define RADIO_CRCCNF_SKIP_ADDR_Include RADIO_CRCCNF_SKIPADDR_Include
#define RADIO_CRCCNF_SKIP_ADDR_Skip RADIO_CRCCNF_SKIPADDR_Skip
/* The name of the field PLLLOCK was corrected. Old macros added for compatibility. */
#define RADIO_TEST_PLL_LOCK_Pos RADIO_TEST_PLLLOCK_Pos
#define RADIO_TEST_PLL_LOCK_Msk RADIO_TEST_PLLLOCK_Msk
#define RADIO_TEST_PLL_LOCK_Disabled RADIO_TEST_PLLLOCK_Disabled
#define RADIO_TEST_PLL_LOCK_Enabled RADIO_TEST_PLLLOCK_Enabled
/* The name of the field CONSTCARRIER was corrected. Old macros added for compatibility. */
#define RADIO_TEST_CONST_CARRIER_Pos RADIO_TEST_CONSTCARRIER_Pos
#define RADIO_TEST_CONST_CARRIER_Msk RADIO_TEST_CONSTCARRIER_Msk
#define RADIO_TEST_CONST_CARRIER_Disabled RADIO_TEST_CONSTCARRIER_Disabled
#define RADIO_TEST_CONST_CARRIER_Enabled RADIO_TEST_CONSTCARRIER_Enabled
/* FICR */
/* The registers FICR.SIZERAMBLOCK0, FICR.SIZERAMBLOCK1, FICR.SIZERAMBLOCK2 and FICR.SIZERAMBLOCK3 were renamed into an array. */
#define SIZERAMBLOCK0 SIZERAMBLOCKS
#define SIZERAMBLOCK1 SIZERAMBLOCKS
#define SIZERAMBLOCK2 SIZERAMBLOCK[2] /*!< Note that this macro will disapear when SIZERAMBLOCK array is eliminated. SIZERAMBLOCK is a deprecated array. */
#define SIZERAMBLOCK3 SIZERAMBLOCK[3] /*!< Note that this macro will disapear when SIZERAMBLOCK array is eliminated. SIZERAMBLOCK is a deprecated array. */
/* The registers FICR.DEVICEID0 and FICR.DEVICEID1 were renamed into an array. */
#define DEVICEID0 DEVICEID[0]
#define DEVICEID1 DEVICEID[1]
/* The registers FICR.ER0, FICR.ER1, FICR.ER2 and FICR.ER3 were renamed into an array. */
#define ER0 ER[0]
#define ER1 ER[1]
#define ER2 ER[2]
#define ER3 ER[3]
/* The registers FICR.IR0, FICR.IR1, FICR.IR2 and FICR.IR3 were renamed into an array. */
#define IR0 IR[0]
#define IR1 IR[1]
#define IR2 IR[2]
#define IR3 IR[3]
/* The registers FICR.DEVICEADDR0 and FICR.DEVICEADDR1 were renamed into an array. */
#define DEVICEADDR0 DEVICEADDR[0]
#define DEVICEADDR1 DEVICEADDR[1]
/* PPI */
/* The tasks PPI.TASKS_CHGxEN and PPI.TASKS_CHGxDIS were renamed into an array of structs. */
#define TASKS_CHG0EN TASKS_CHG[0].EN
#define TASKS_CHG0DIS TASKS_CHG[0].DIS
#define TASKS_CHG1EN TASKS_CHG[1].EN
#define TASKS_CHG1DIS TASKS_CHG[1].DIS
#define TASKS_CHG2EN TASKS_CHG[2].EN
#define TASKS_CHG2DIS TASKS_CHG[2].DIS
#define TASKS_CHG3EN TASKS_CHG[3].EN
#define TASKS_CHG3DIS TASKS_CHG[3].DIS
/* The registers PPI.CHx_EEP and PPI.CHx_TEP were renamed into an array of structs. */
#define CH0_EEP CH[0].EEP
#define CH0_TEP CH[0].TEP
#define CH1_EEP CH[1].EEP
#define CH1_TEP CH[1].TEP
#define CH2_EEP CH[2].EEP
#define CH2_TEP CH[2].TEP
#define CH3_EEP CH[3].EEP
#define CH3_TEP CH[3].TEP
#define CH4_EEP CH[4].EEP
#define CH4_TEP CH[4].TEP
#define CH5_EEP CH[5].EEP
#define CH5_TEP CH[5].TEP
#define CH6_EEP CH[6].EEP
#define CH6_TEP CH[6].TEP
#define CH7_EEP CH[7].EEP
#define CH7_TEP CH[7].TEP
#define CH8_EEP CH[8].EEP
#define CH8_TEP CH[8].TEP
#define CH9_EEP CH[9].EEP
#define CH9_TEP CH[9].TEP
#define CH10_EEP CH[10].EEP
#define CH10_TEP CH[10].TEP
#define CH11_EEP CH[11].EEP
#define CH11_TEP CH[11].TEP
#define CH12_EEP CH[12].EEP
#define CH12_TEP CH[12].TEP
#define CH13_EEP CH[13].EEP
#define CH13_TEP CH[13].TEP
#define CH14_EEP CH[14].EEP
#define CH14_TEP CH[14].TEP
#define CH15_EEP CH[15].EEP
#define CH15_TEP CH[15].TEP
/* The registers PPI.CHG0, PPI.CHG1, PPI.CHG2 and PPI.CHG3 were renamed into an array. */
#define CHG0 CHG[0]
#define CHG1 CHG[1]
#define CHG2 CHG[2]
#define CHG3 CHG[3]
/* All bitfield macros for the CHGx registers therefore changed name. */
#define PPI_CHG0_CH15_Pos PPI_CHG_CH15_Pos
#define PPI_CHG0_CH15_Msk PPI_CHG_CH15_Msk
#define PPI_CHG0_CH15_Excluded PPI_CHG_CH15_Excluded
#define PPI_CHG0_CH15_Included PPI_CHG_CH15_Included
#define PPI_CHG0_CH14_Pos PPI_CHG_CH14_Pos
#define PPI_CHG0_CH14_Msk PPI_CHG_CH14_Msk
#define PPI_CHG0_CH14_Excluded PPI_CHG_CH14_Excluded
#define PPI_CHG0_CH14_Included PPI_CHG_CH14_Included
#define PPI_CHG0_CH13_Pos PPI_CHG_CH13_Pos
#define PPI_CHG0_CH13_Msk PPI_CHG_CH13_Msk
#define PPI_CHG0_CH13_Excluded PPI_CHG_CH13_Excluded
#define PPI_CHG0_CH13_Included PPI_CHG_CH13_Included
#define PPI_CHG0_CH12_Pos PPI_CHG_CH12_Pos
#define PPI_CHG0_CH12_Msk PPI_CHG_CH12_Msk
#define PPI_CHG0_CH12_Excluded PPI_CHG_CH12_Excluded
#define PPI_CHG0_CH12_Included PPI_CHG_CH12_Included
#define PPI_CHG0_CH11_Pos PPI_CHG_CH11_Pos
#define PPI_CHG0_CH11_Msk PPI_CHG_CH11_Msk
#define PPI_CHG0_CH11_Excluded PPI_CHG_CH11_Excluded
#define PPI_CHG0_CH11_Included PPI_CHG_CH11_Included
#define PPI_CHG0_CH10_Pos PPI_CHG_CH10_Pos
#define PPI_CHG0_CH10_Msk PPI_CHG_CH10_Msk
#define PPI_CHG0_CH10_Excluded PPI_CHG_CH10_Excluded
#define PPI_CHG0_CH10_Included PPI_CHG_CH10_Included
#define PPI_CHG0_CH9_Pos PPI_CHG_CH9_Pos
#define PPI_CHG0_CH9_Msk PPI_CHG_CH9_Msk
#define PPI_CHG0_CH9_Excluded PPI_CHG_CH9_Excluded
#define PPI_CHG0_CH9_Included PPI_CHG_CH9_Included
#define PPI_CHG0_CH8_Pos PPI_CHG_CH8_Pos
#define PPI_CHG0_CH8_Msk PPI_CHG_CH8_Msk
#define PPI_CHG0_CH8_Excluded PPI_CHG_CH8_Excluded
#define PPI_CHG0_CH8_Included PPI_CHG_CH8_Included
#define PPI_CHG0_CH7_Pos PPI_CHG_CH7_Pos
#define PPI_CHG0_CH7_Msk PPI_CHG_CH7_Msk
#define PPI_CHG0_CH7_Excluded PPI_CHG_CH7_Excluded
#define PPI_CHG0_CH7_Included PPI_CHG_CH7_Included
#define PPI_CHG0_CH6_Pos PPI_CHG_CH6_Pos
#define PPI_CHG0_CH6_Msk PPI_CHG_CH6_Msk
#define PPI_CHG0_CH6_Excluded PPI_CHG_CH6_Excluded
#define PPI_CHG0_CH6_Included PPI_CHG_CH6_Included
#define PPI_CHG0_CH5_Pos PPI_CHG_CH5_Pos
#define PPI_CHG0_CH5_Msk PPI_CHG_CH5_Msk
#define PPI_CHG0_CH5_Excluded PPI_CHG_CH5_Excluded
#define PPI_CHG0_CH5_Included PPI_CHG_CH5_Included
#define PPI_CHG0_CH4_Pos PPI_CHG_CH4_Pos
#define PPI_CHG0_CH4_Msk PPI_CHG_CH4_Msk
#define PPI_CHG0_CH4_Excluded PPI_CHG_CH4_Excluded
#define PPI_CHG0_CH4_Included PPI_CHG_CH4_Included
#define PPI_CHG0_CH3_Pos PPI_CHG_CH3_Pos
#define PPI_CHG0_CH3_Msk PPI_CHG_CH3_Msk
#define PPI_CHG0_CH3_Excluded PPI_CHG_CH3_Excluded
#define PPI_CHG0_CH3_Included PPI_CHG_CH3_Included
#define PPI_CHG0_CH2_Pos PPI_CHG_CH2_Pos
#define PPI_CHG0_CH2_Msk PPI_CHG_CH2_Msk
#define PPI_CHG0_CH2_Excluded PPI_CHG_CH2_Excluded
#define PPI_CHG0_CH2_Included PPI_CHG_CH2_Included
#define PPI_CHG0_CH1_Pos PPI_CHG_CH1_Pos
#define PPI_CHG0_CH1_Msk PPI_CHG_CH1_Msk
#define PPI_CHG0_CH1_Excluded PPI_CHG_CH1_Excluded
#define PPI_CHG0_CH1_Included PPI_CHG_CH1_Included
#define PPI_CHG0_CH0_Pos PPI_CHG_CH0_Pos
#define PPI_CHG0_CH0_Msk PPI_CHG_CH0_Msk
#define PPI_CHG0_CH0_Excluded PPI_CHG_CH0_Excluded
#define PPI_CHG0_CH0_Included PPI_CHG_CH0_Included
#define PPI_CHG1_CH15_Pos PPI_CHG_CH15_Pos
#define PPI_CHG1_CH15_Msk PPI_CHG_CH15_Msk
#define PPI_CHG1_CH15_Excluded PPI_CHG_CH15_Excluded
#define PPI_CHG1_CH15_Included PPI_CHG_CH15_Included
#define PPI_CHG1_CH14_Pos PPI_CHG_CH14_Pos
#define PPI_CHG1_CH14_Msk PPI_CHG_CH14_Msk
#define PPI_CHG1_CH14_Excluded PPI_CHG_CH14_Excluded
#define PPI_CHG1_CH14_Included PPI_CHG_CH14_Included
#define PPI_CHG1_CH13_Pos PPI_CHG_CH13_Pos
#define PPI_CHG1_CH13_Msk PPI_CHG_CH13_Msk
#define PPI_CHG1_CH13_Excluded PPI_CHG_CH13_Excluded
#define PPI_CHG1_CH13_Included PPI_CHG_CH13_Included
#define PPI_CHG1_CH12_Pos PPI_CHG_CH12_Pos
#define PPI_CHG1_CH12_Msk PPI_CHG_CH12_Msk
#define PPI_CHG1_CH12_Excluded PPI_CHG_CH12_Excluded
#define PPI_CHG1_CH12_Included PPI_CHG_CH12_Included
#define PPI_CHG1_CH11_Pos PPI_CHG_CH11_Pos
#define PPI_CHG1_CH11_Msk PPI_CHG_CH11_Msk
#define PPI_CHG1_CH11_Excluded PPI_CHG_CH11_Excluded
#define PPI_CHG1_CH11_Included PPI_CHG_CH11_Included
#define PPI_CHG1_CH10_Pos PPI_CHG_CH10_Pos
#define PPI_CHG1_CH10_Msk PPI_CHG_CH10_Msk
#define PPI_CHG1_CH10_Excluded PPI_CHG_CH10_Excluded
#define PPI_CHG1_CH10_Included PPI_CHG_CH10_Included
#define PPI_CHG1_CH9_Pos PPI_CHG_CH9_Pos
#define PPI_CHG1_CH9_Msk PPI_CHG_CH9_Msk
#define PPI_CHG1_CH9_Excluded PPI_CHG_CH9_Excluded
#define PPI_CHG1_CH9_Included PPI_CHG_CH9_Included
#define PPI_CHG1_CH8_Pos PPI_CHG_CH8_Pos
#define PPI_CHG1_CH8_Msk PPI_CHG_CH8_Msk
#define PPI_CHG1_CH8_Excluded PPI_CHG_CH8_Excluded
#define PPI_CHG1_CH8_Included PPI_CHG_CH8_Included
#define PPI_CHG1_CH7_Pos PPI_CHG_CH7_Pos
#define PPI_CHG1_CH7_Msk PPI_CHG_CH7_Msk
#define PPI_CHG1_CH7_Excluded PPI_CHG_CH7_Excluded
#define PPI_CHG1_CH7_Included PPI_CHG_CH7_Included
#define PPI_CHG1_CH6_Pos PPI_CHG_CH6_Pos
#define PPI_CHG1_CH6_Msk PPI_CHG_CH6_Msk
#define PPI_CHG1_CH6_Excluded PPI_CHG_CH6_Excluded
#define PPI_CHG1_CH6_Included PPI_CHG_CH6_Included
#define PPI_CHG1_CH5_Pos PPI_CHG_CH5_Pos
#define PPI_CHG1_CH5_Msk PPI_CHG_CH5_Msk
#define PPI_CHG1_CH5_Excluded PPI_CHG_CH5_Excluded
#define PPI_CHG1_CH5_Included PPI_CHG_CH5_Included
#define PPI_CHG1_CH4_Pos PPI_CHG_CH4_Pos
#define PPI_CHG1_CH4_Msk PPI_CHG_CH4_Msk
#define PPI_CHG1_CH4_Excluded PPI_CHG_CH4_Excluded
#define PPI_CHG1_CH4_Included PPI_CHG_CH4_Included
#define PPI_CHG1_CH3_Pos PPI_CHG_CH3_Pos
#define PPI_CHG1_CH3_Msk PPI_CHG_CH3_Msk
#define PPI_CHG1_CH3_Excluded PPI_CHG_CH3_Excluded
#define PPI_CHG1_CH3_Included PPI_CHG_CH3_Included
#define PPI_CHG1_CH2_Pos PPI_CHG_CH2_Pos
#define PPI_CHG1_CH2_Msk PPI_CHG_CH2_Msk
#define PPI_CHG1_CH2_Excluded PPI_CHG_CH2_Excluded
#define PPI_CHG1_CH2_Included PPI_CHG_CH2_Included
#define PPI_CHG1_CH1_Pos PPI_CHG_CH1_Pos
#define PPI_CHG1_CH1_Msk PPI_CHG_CH1_Msk
#define PPI_CHG1_CH1_Excluded PPI_CHG_CH1_Excluded
#define PPI_CHG1_CH1_Included PPI_CHG_CH1_Included
#define PPI_CHG1_CH0_Pos PPI_CHG_CH0_Pos
#define PPI_CHG1_CH0_Msk PPI_CHG_CH0_Msk
#define PPI_CHG1_CH0_Excluded PPI_CHG_CH0_Excluded
#define PPI_CHG1_CH0_Included PPI_CHG_CH0_Included
#define PPI_CHG2_CH15_Pos PPI_CHG_CH15_Pos
#define PPI_CHG2_CH15_Msk PPI_CHG_CH15_Msk
#define PPI_CHG2_CH15_Excluded PPI_CHG_CH15_Excluded
#define PPI_CHG2_CH15_Included PPI_CHG_CH15_Included
#define PPI_CHG2_CH14_Pos PPI_CHG_CH14_Pos
#define PPI_CHG2_CH14_Msk PPI_CHG_CH14_Msk
#define PPI_CHG2_CH14_Excluded PPI_CHG_CH14_Excluded
#define PPI_CHG2_CH14_Included PPI_CHG_CH14_Included
#define PPI_CHG2_CH13_Pos PPI_CHG_CH13_Pos
#define PPI_CHG2_CH13_Msk PPI_CHG_CH13_Msk
#define PPI_CHG2_CH13_Excluded PPI_CHG_CH13_Excluded
#define PPI_CHG2_CH13_Included PPI_CHG_CH13_Included
#define PPI_CHG2_CH12_Pos PPI_CHG_CH12_Pos
#define PPI_CHG2_CH12_Msk PPI_CHG_CH12_Msk
#define PPI_CHG2_CH12_Excluded PPI_CHG_CH12_Excluded
#define PPI_CHG2_CH12_Included PPI_CHG_CH12_Included
#define PPI_CHG2_CH11_Pos PPI_CHG_CH11_Pos
#define PPI_CHG2_CH11_Msk PPI_CHG_CH11_Msk
#define PPI_CHG2_CH11_Excluded PPI_CHG_CH11_Excluded
#define PPI_CHG2_CH11_Included PPI_CHG_CH11_Included
#define PPI_CHG2_CH10_Pos PPI_CHG_CH10_Pos
#define PPI_CHG2_CH10_Msk PPI_CHG_CH10_Msk
#define PPI_CHG2_CH10_Excluded PPI_CHG_CH10_Excluded
#define PPI_CHG2_CH10_Included PPI_CHG_CH10_Included
#define PPI_CHG2_CH9_Pos PPI_CHG_CH9_Pos
#define PPI_CHG2_CH9_Msk PPI_CHG_CH9_Msk
#define PPI_CHG2_CH9_Excluded PPI_CHG_CH9_Excluded
#define PPI_CHG2_CH9_Included PPI_CHG_CH9_Included
#define PPI_CHG2_CH8_Pos PPI_CHG_CH8_Pos
#define PPI_CHG2_CH8_Msk PPI_CHG_CH8_Msk
#define PPI_CHG2_CH8_Excluded PPI_CHG_CH8_Excluded
#define PPI_CHG2_CH8_Included PPI_CHG_CH8_Included
#define PPI_CHG2_CH7_Pos PPI_CHG_CH7_Pos
#define PPI_CHG2_CH7_Msk PPI_CHG_CH7_Msk
#define PPI_CHG2_CH7_Excluded PPI_CHG_CH7_Excluded
#define PPI_CHG2_CH7_Included PPI_CHG_CH7_Included
#define PPI_CHG2_CH6_Pos PPI_CHG_CH6_Pos
#define PPI_CHG2_CH6_Msk PPI_CHG_CH6_Msk
#define PPI_CHG2_CH6_Excluded PPI_CHG_CH6_Excluded
#define PPI_CHG2_CH6_Included PPI_CHG_CH6_Included
#define PPI_CHG2_CH5_Pos PPI_CHG_CH5_Pos
#define PPI_CHG2_CH5_Msk PPI_CHG_CH5_Msk
#define PPI_CHG2_CH5_Excluded PPI_CHG_CH5_Excluded
#define PPI_CHG2_CH5_Included PPI_CHG_CH5_Included
#define PPI_CHG2_CH4_Pos PPI_CHG_CH4_Pos
#define PPI_CHG2_CH4_Msk PPI_CHG_CH4_Msk
#define PPI_CHG2_CH4_Excluded PPI_CHG_CH4_Excluded
#define PPI_CHG2_CH4_Included PPI_CHG_CH4_Included
#define PPI_CHG2_CH3_Pos PPI_CHG_CH3_Pos
#define PPI_CHG2_CH3_Msk PPI_CHG_CH3_Msk
#define PPI_CHG2_CH3_Excluded PPI_CHG_CH3_Excluded
#define PPI_CHG2_CH3_Included PPI_CHG_CH3_Included
#define PPI_CHG2_CH2_Pos PPI_CHG_CH2_Pos
#define PPI_CHG2_CH2_Msk PPI_CHG_CH2_Msk
#define PPI_CHG2_CH2_Excluded PPI_CHG_CH2_Excluded
#define PPI_CHG2_CH2_Included PPI_CHG_CH2_Included
#define PPI_CHG2_CH1_Pos PPI_CHG_CH1_Pos
#define PPI_CHG2_CH1_Msk PPI_CHG_CH1_Msk
#define PPI_CHG2_CH1_Excluded PPI_CHG_CH1_Excluded
#define PPI_CHG2_CH1_Included PPI_CHG_CH1_Included
#define PPI_CHG2_CH0_Pos PPI_CHG_CH0_Pos
#define PPI_CHG2_CH0_Msk PPI_CHG_CH0_Msk
#define PPI_CHG2_CH0_Excluded PPI_CHG_CH0_Excluded
#define PPI_CHG2_CH0_Included PPI_CHG_CH0_Included
#define PPI_CHG3_CH15_Pos PPI_CHG_CH15_Pos
#define PPI_CHG3_CH15_Msk PPI_CHG_CH15_Msk
#define PPI_CHG3_CH15_Excluded PPI_CHG_CH15_Excluded
#define PPI_CHG3_CH15_Included PPI_CHG_CH15_Included
#define PPI_CHG3_CH14_Pos PPI_CHG_CH14_Pos
#define PPI_CHG3_CH14_Msk PPI_CHG_CH14_Msk
#define PPI_CHG3_CH14_Excluded PPI_CHG_CH14_Excluded
#define PPI_CHG3_CH14_Included PPI_CHG_CH14_Included
#define PPI_CHG3_CH13_Pos PPI_CHG_CH13_Pos
#define PPI_CHG3_CH13_Msk PPI_CHG_CH13_Msk
#define PPI_CHG3_CH13_Excluded PPI_CHG_CH13_Excluded
#define PPI_CHG3_CH13_Included PPI_CHG_CH13_Included
#define PPI_CHG3_CH12_Pos PPI_CHG_CH12_Pos
#define PPI_CHG3_CH12_Msk PPI_CHG_CH12_Msk
#define PPI_CHG3_CH12_Excluded PPI_CHG_CH12_Excluded
#define PPI_CHG3_CH12_Included PPI_CHG_CH12_Included
#define PPI_CHG3_CH11_Pos PPI_CHG_CH11_Pos
#define PPI_CHG3_CH11_Msk PPI_CHG_CH11_Msk
#define PPI_CHG3_CH11_Excluded PPI_CHG_CH11_Excluded
#define PPI_CHG3_CH11_Included PPI_CHG_CH11_Included
#define PPI_CHG3_CH10_Pos PPI_CHG_CH10_Pos
#define PPI_CHG3_CH10_Msk PPI_CHG_CH10_Msk
#define PPI_CHG3_CH10_Excluded PPI_CHG_CH10_Excluded
#define PPI_CHG3_CH10_Included PPI_CHG_CH10_Included
#define PPI_CHG3_CH9_Pos PPI_CHG_CH9_Pos
#define PPI_CHG3_CH9_Msk PPI_CHG_CH9_Msk
#define PPI_CHG3_CH9_Excluded PPI_CHG_CH9_Excluded
#define PPI_CHG3_CH9_Included PPI_CHG_CH9_Included
#define PPI_CHG3_CH8_Pos PPI_CHG_CH8_Pos
#define PPI_CHG3_CH8_Msk PPI_CHG_CH8_Msk
#define PPI_CHG3_CH8_Excluded PPI_CHG_CH8_Excluded
#define PPI_CHG3_CH8_Included PPI_CHG_CH8_Included
#define PPI_CHG3_CH7_Pos PPI_CHG_CH7_Pos
#define PPI_CHG3_CH7_Msk PPI_CHG_CH7_Msk
#define PPI_CHG3_CH7_Excluded PPI_CHG_CH7_Excluded
#define PPI_CHG3_CH7_Included PPI_CHG_CH7_Included
#define PPI_CHG3_CH6_Pos PPI_CHG_CH6_Pos
#define PPI_CHG3_CH6_Msk PPI_CHG_CH6_Msk
#define PPI_CHG3_CH6_Excluded PPI_CHG_CH6_Excluded
#define PPI_CHG3_CH6_Included PPI_CHG_CH6_Included
#define PPI_CHG3_CH5_Pos PPI_CHG_CH5_Pos
#define PPI_CHG3_CH5_Msk PPI_CHG_CH5_Msk
#define PPI_CHG3_CH5_Excluded PPI_CHG_CH5_Excluded
#define PPI_CHG3_CH5_Included PPI_CHG_CH5_Included
#define PPI_CHG3_CH4_Pos PPI_CHG_CH4_Pos
#define PPI_CHG3_CH4_Msk PPI_CHG_CH4_Msk
#define PPI_CHG3_CH4_Excluded PPI_CHG_CH4_Excluded
#define PPI_CHG3_CH4_Included PPI_CHG_CH4_Included
#define PPI_CHG3_CH3_Pos PPI_CHG_CH3_Pos
#define PPI_CHG3_CH3_Msk PPI_CHG_CH3_Msk
#define PPI_CHG3_CH3_Excluded PPI_CHG_CH3_Excluded
#define PPI_CHG3_CH3_Included PPI_CHG_CH3_Included
#define PPI_CHG3_CH2_Pos PPI_CHG_CH2_Pos
#define PPI_CHG3_CH2_Msk PPI_CHG_CH2_Msk
#define PPI_CHG3_CH2_Excluded PPI_CHG_CH2_Excluded
#define PPI_CHG3_CH2_Included PPI_CHG_CH2_Included
#define PPI_CHG3_CH1_Pos PPI_CHG_CH1_Pos
#define PPI_CHG3_CH1_Msk PPI_CHG_CH1_Msk
#define PPI_CHG3_CH1_Excluded PPI_CHG_CH1_Excluded
#define PPI_CHG3_CH1_Included PPI_CHG_CH1_Included
#define PPI_CHG3_CH0_Pos PPI_CHG_CH0_Pos
#define PPI_CHG3_CH0_Msk PPI_CHG_CH0_Msk
#define PPI_CHG3_CH0_Excluded PPI_CHG_CH0_Excluded
#define PPI_CHG3_CH0_Included PPI_CHG_CH0_Included
/*lint --flb "Leave library region" */
#endif /* NRF51_DEPRECATED_H */

View File

@ -1,32 +1,30 @@
/*
* Copyright (c) Nordic Semiconductor ASA
/* Copyright (c) 2015, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
* * Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
*
* 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.
* 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.
*
*/
@ -934,3 +932,4 @@
/*lint --flb "Leave library region" */
#endif /* NRF51_TO_NRF52_H */

View File

@ -1,35 +1,3 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
*
* 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.
*
*/
/****************************************************************************************************//**
* @file nrf52.h
@ -40,26 +8,26 @@
* @version V1
* @date 23. February 2016
*
* @note Generated with SVDConv V2.81d
* @note Generated with SVDConv V2.81d
* from CMSIS SVD File 'nrf52.svd' Version 1,
*
* @par Copyright (c) 2015, Nordic Semiconductor ASA
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
*
* * Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
*
* 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
@ -70,7 +38,7 @@
* 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.
*
*
*
*******************************************************************************************************/
@ -1822,7 +1790,7 @@ typedef struct { /*!< NVMC Structure
__I uint32_t READY; /*!< Ready flag */
__I uint32_t RESERVED1[64];
__IO uint32_t CONFIG; /*!< Configuration register */
union {
__IO uint32_t ERASEPCR1; /*!< Deprecated register - Register for erasing a page in Code area.
Equivalent to ERASEPAGE. */
@ -2154,3 +2122,4 @@ typedef struct { /*!< GPIO Structure
#endif /* nrf52_H */

View File

@ -1,32 +1,30 @@
/*
* Copyright (c) Nordic Semiconductor ASA
/* Copyright (c) 2015, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
* * Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
*
* 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.
* 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.
*
*/
#ifndef __NRF52_BITS_H

View File

@ -1,32 +1,30 @@
/*
* Copyright (c) Nordic Semiconductor ASA
/* Copyright (c) 2015, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
* * Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
*
* 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.
* 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.
*
*/
@ -35,7 +33,7 @@
/*lint ++flb "Enter library region */
/* This file is given to prevent your SW from not compiling with the updates made to nrf52.h and
/* This file is given to prevent your SW from not compiling with the updates made to nrf52.h and
* nrf52_bitfields.h. The macros defined in this file were available previously. Do not use these
* macros on purpose. Use the ones defined in nrf52.h and nrf52_bitfields.h instead.
*/
@ -69,3 +67,4 @@
/*lint --flb "Leave library region" */
#endif /* NRF52_NAME_CHANGE_H */

View File

@ -1,92 +0,0 @@
/* 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 app_error Common application error handler
* @{
* @ingroup app_common
*
* @brief Common application error handler and macros for utilizing a common error handler.
*/
#ifndef APP_ERROR_H__
#define APP_ERROR_H__
#include <stdint.h>
#include <stdbool.h>
#include "nrf_error.h"
#ifdef __cplusplus
extern "C" {
#endif
/**@brief Function for error handling, which is called when an error has occurred.
*
* @param[in] error_code Error code supplied to the handler.
* @param[in] line_num Line number where the handler is called.
* @param[in] p_file_name Pointer to the file name.
*/
void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name);
#ifdef __cplusplus
}
#endif
/**@brief Macro for calling error handler function.
*
* @param[in] ERR_CODE Error code supplied to the error handler.
*/
#ifdef DEBUG
#define APP_ERROR_HANDLER(ERR_CODE) \
do \
{ \
app_error_handler((ERR_CODE), __LINE__, (uint8_t*) __FILE__); \
} while (0)
#else
#define APP_ERROR_HANDLER(ERR_CODE) \
do \
{ \
app_error_handler((ERR_CODE), 0, 0); \
} while (0)
#endif
/**@brief Macro for calling error handler function if supplied error code any other than NRF_SUCCESS.
*
* @param[in] ERR_CODE Error code supplied to the error handler.
*/
#define APP_ERROR_CHECK(ERR_CODE) \
do \
{ \
const uint32_t LOCAL_ERR_CODE = (ERR_CODE); \
if (LOCAL_ERR_CODE != NRF_SUCCESS) \
{ \
APP_ERROR_HANDLER(LOCAL_ERR_CODE); \
} \
} while (0)
/**@brief Macro for calling error handler function if supplied boolean value is false.
*
* @param[in] BOOLEAN_VALUE Boolean value to be evaluated.
*/
#define APP_ERROR_CHECK_BOOL(BOOLEAN_VALUE) \
do \
{ \
const uint32_t LOCAL_BOOLEAN_VALUE = (BOOLEAN_VALUE); \
if (!LOCAL_BOOLEAN_VALUE) \
{ \
APP_ERROR_HANDLER(0); \
} \
} while (0)
#endif // APP_ERROR_H__
/** @} */

View File

@ -1,234 +0,0 @@
/* 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.
*
*/
/** @file
*
* @defgroup app_util Utility Functions and Definitions
* @{
* @ingroup app_common
*
* @brief Various types and definitions available to all applications.
*/
#ifndef APP_UTIL_H__
#define APP_UTIL_H__
#include <stdint.h>
#include <stdbool.h>
#include "compiler_abstraction.h"
enum
{
UNIT_0_625_MS = 625, /**< Number of microseconds in 0.625 milliseconds. */
UNIT_1_25_MS = 1250, /**< Number of microseconds in 1.25 milliseconds. */
UNIT_10_MS = 10000 /**< Number of microseconds in 10 milliseconds. */
};
/**@brief Macro for doing static (i.e. compile time) assertion.
*
* @note If the assertion fails when compiling using Keil, the compiler will report error message
* "error: #94: the size of an array must be greater than zero" (while gcc will list the
* symbol static_assert_failed, making the error message more readable).
* If the supplied expression can not be evaluated at compile time, Keil will report
* "error: #28: expression must have a constant value".
*
* @note The macro is intentionally implemented not using do while(0), allowing it to be used
* outside function blocks (e.g. close to global type- and variable declarations).
* If used in a code block, it must be used before any executable code in this block.
*
* @param[in] EXPR Constant expression to be verified.
*/
#if defined(__GNUC__)
#define STATIC_ASSERT(EXPR) typedef char __attribute__((unused)) static_assert_failed[(EXPR) ? 1 : -1]
#elif defined(__ICCARM__)
#define STATIC_ASSERT(EXPR) extern char static_assert_failed[(EXPR) ? 1 : -1]
#else
#define STATIC_ASSERT(EXPR) typedef char static_assert_failed[(EXPR) ? 1 : -1]
#endif
/**@brief type for holding an encoded (i.e. little endian) 16 bit unsigned integer. */
typedef uint8_t uint16_le_t[2];
/**@brief type for holding an encoded (i.e. little endian) 32 bit unsigned integer. */
typedef uint8_t uint32_le_t[4];
/**@brief Byte array type. */
typedef struct
{
uint16_t size; /**< Number of array entries. */
uint8_t * p_data; /**< Pointer to array entries. */
} uint8_array_t;
/**@brief Perform rounded integer division (as opposed to truncating the result).
*
* @param[in] A Numerator.
* @param[in] B Denominator.
*
* @return Rounded (integer) result of dividing A by B.
*/
#define ROUNDED_DIV(A, B) (((A) + ((B) / 2)) / (B))
/**@brief Check if the integer provided is a power of two.
*
* @param[in] A Number to be tested.
*
* @return true if value is power of two.
* @return false if value not power of two.
*/
#define IS_POWER_OF_TWO(A) ( ((A) != 0) && ((((A) - 1) & (A)) == 0) )
/**@brief To convert milliseconds to ticks.
* @param[in] TIME Number of milliseconds to convert.
* @param[in] RESOLUTION Unit to be converted to in [us/ticks].
*/
#define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION))
/**@brief Perform integer division, making sure the result is rounded up.
*
* @details One typical use for this is to compute the number of objects with size B is needed to
* hold A number of bytes.
*
* @param[in] A Numerator.
* @param[in] B Denominator.
*
* @return Integer result of dividing A by B, rounded up.
*/
#define CEIL_DIV(A, B) \
/*lint -save -e573 */ \
((((A) - 1) / (B)) + 1) \
/*lint -restore */
/**@brief Function for encoding a uint16 value.
*
* @param[in] value Value to be encoded.
* @param[out] p_encoded_data Buffer where the encoded data is to be written.
*
* @return Number of bytes written.
*/
static __INLINE uint8_t uint16_encode(uint16_t value, uint8_t * p_encoded_data)
{
p_encoded_data[0] = (uint8_t) ((value & 0x00FF) >> 0);
p_encoded_data[1] = (uint8_t) ((value & 0xFF00) >> 8);
return sizeof(uint16_t);
}
/**@brief Function for encoding a uint32 value.
*
* @param[in] value Value to be encoded.
* @param[out] p_encoded_data Buffer where the encoded data is to be written.
*
* @return Number of bytes written.
*/
static __INLINE uint8_t uint32_encode(uint32_t value, uint8_t * p_encoded_data)
{
p_encoded_data[0] = (uint8_t) ((value & 0x000000FF) >> 0);
p_encoded_data[1] = (uint8_t) ((value & 0x0000FF00) >> 8);
p_encoded_data[2] = (uint8_t) ((value & 0x00FF0000) >> 16);
p_encoded_data[3] = (uint8_t) ((value & 0xFF000000) >> 24);
return sizeof(uint32_t);
}
/**@brief Function for decoding a uint16 value.
*
* @param[in] p_encoded_data Buffer where the encoded data is stored.
*
* @return Decoded value.
*/
static __INLINE uint16_t uint16_decode(const uint8_t * p_encoded_data)
{
return ( (((uint16_t)((uint8_t *)p_encoded_data)[0])) |
(((uint16_t)((uint8_t *)p_encoded_data)[1]) << 8 ));
}
/**@brief Function for decoding a uint32 value.
*
* @param[in] p_encoded_data Buffer where the encoded data is stored.
*
* @return Decoded value.
*/
static __INLINE uint32_t uint32_decode(const uint8_t * p_encoded_data)
{
return ( (((uint32_t)((uint8_t *)p_encoded_data)[0]) << 0) |
(((uint32_t)((uint8_t *)p_encoded_data)[1]) << 8) |
(((uint32_t)((uint8_t *)p_encoded_data)[2]) << 16) |
(((uint32_t)((uint8_t *)p_encoded_data)[3]) << 24 ));
}
/** @brief Function for converting the input voltage (in milli volts) into percentage of 3.0 Volts.
*
* @details The calculation is based on a linearized version of the battery's discharge
* curve. 3.0V returns 100% battery level. The limit for power failure is 2.1V and
* is considered to be the lower boundary.
*
* The discharge curve for CR2032 is non-linear. In this model it is split into
* 4 linear sections:
* - Section 1: 3.0V - 2.9V = 100% - 42% (58% drop on 100 mV)
* - Section 2: 2.9V - 2.74V = 42% - 18% (24% drop on 160 mV)
* - Section 3: 2.74V - 2.44V = 18% - 6% (12% drop on 300 mV)
* - Section 4: 2.44V - 2.1V = 6% - 0% (6% drop on 340 mV)
*
* These numbers are by no means accurate. Temperature and
* load in the actual application is not accounted for!
*
* @param[in] mvolts The voltage in mV
*
* @return Battery level in percent.
*/
static __INLINE uint8_t battery_level_in_percent(const uint16_t mvolts)
{
uint8_t battery_level;
if (mvolts >= 3000)
{
battery_level = 100;
}
else if (mvolts > 2900)
{
battery_level = 100 - ((3000 - mvolts) * 58) / 100;
}
else if (mvolts > 2740)
{
battery_level = 42 - ((2900 - mvolts) * 24) / 160;
}
else if (mvolts > 2440)
{
battery_level = 18 - ((2740 - mvolts) * 12) / 300;
}
else if (mvolts > 2100)
{
battery_level = 6 - ((2440 - mvolts) * 6) / 340;
}
else
{
battery_level = 0;
}
return battery_level;
}
/**@brief Function for checking if a pointer value is aligned to a 4 byte boundary.
*
* @param[in] p Pointer value to be checked.
*
* @return TRUE if pointer is aligned to a 4 byte boundary, FALSE otherwise.
*/
static __INLINE bool is_word_aligned(void * p)
{
return (((uintptr_t)p & 0x03) == 0);
}
#endif // APP_UTIL_H__
/** @} */

View File

@ -0,0 +1,632 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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.
*
*/
/**
@addtogroup BLE_COMMON BLE SoftDevice Common
@{
@defgroup ble_api Events, type definitions and API calls
@{
@brief Module independent events, type definitions and API calls for the BLE SoftDevice.
*/
#ifndef BLE_H__
#define BLE_H__
#include "ble_ranges.h"
#include "ble_types.h"
#include "ble_gap.h"
#include "ble_l2cap.h"
#include "ble_gatt.h"
#include "ble_gattc.h"
#include "ble_gatts.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup BLE_COMMON_ENUMERATIONS Enumerations
* @{ */
/**
* @brief Common API SVC numbers.
*/
enum BLE_COMMON_SVCS
{
SD_BLE_ENABLE = BLE_SVC_BASE, /**< Enable and initialize the BLE stack */
SD_BLE_EVT_GET, /**< Get an event from the pending events queue. */
SD_BLE_TX_PACKET_COUNT_GET, /**< Get the total number of available application transmission packets for a particular connection. */
SD_BLE_UUID_VS_ADD, /**< Add a Vendor Specific UUID. */
SD_BLE_UUID_DECODE, /**< Decode UUID bytes. */
SD_BLE_UUID_ENCODE, /**< Encode UUID bytes. */
SD_BLE_VERSION_GET, /**< Get the local version information (company id, Link Layer Version, Link Layer Subversion). */
SD_BLE_USER_MEM_REPLY, /**< User Memory Reply. */
SD_BLE_OPT_SET, /**< Set a BLE option. */
SD_BLE_OPT_GET, /**< Get a BLE option. */
};
/**
* @brief BLE Module Independent Event IDs.
*/
enum BLE_COMMON_EVTS
{
BLE_EVT_TX_COMPLETE = BLE_EVT_BASE, /**< Transmission Complete. @ref ble_evt_tx_complete_t */
BLE_EVT_USER_MEM_REQUEST, /**< User Memory request. @ref ble_evt_user_mem_request_t */
BLE_EVT_USER_MEM_RELEASE /**< User Memory release. @ref ble_evt_user_mem_release_t */
};
/**@brief BLE connection bandwidth types.
* Bandwidth types supported by the SoftDevice in packets per connection interval.
*/
enum BLE_CONN_BWS
{
BLE_CONN_BW_NONE = 0,
BLE_CONN_BW_LOW,
BLE_CONN_BW_MID,
BLE_CONN_BW_HIGH
};
/**@brief Common Option IDs.
* IDs that uniquely identify a common option.
*/
enum BLE_COMMON_OPTS
{
BLE_COMMON_OPT_CONN_BW = BLE_OPT_BASE, /**< Bandwidth configuration @ref ble_common_opt_conn_bw_t */
BLE_COMMON_OPT_PA_LNA /**< PA and LNA options */
};
/** @} */
/** @addtogroup BLE_COMMON_DEFINES Defines
* @{ */
/** @brief Required pointer alignment for BLE Events.
*/
#define BLE_EVTS_PTR_ALIGNMENT 4
/** @defgroup BLE_USER_MEM_TYPES User Memory Types
* @{ */
#define BLE_USER_MEM_TYPE_INVALID 0x00 /**< Invalid User Memory Types. */
#define BLE_USER_MEM_TYPE_GATTS_QUEUED_WRITES 0x01 /**< User Memory for GATTS queued writes. */
/** @} */
/** @defgroup BLE_UUID_VS_COUNTS Vendor Specific UUID counts
* @{
*/
#define BLE_UUID_VS_COUNT_MIN 1 /**< Minimum VS UUID count. */
#define BLE_UUID_VS_COUNT_DEFAULT 0 /**< Use the default VS UUID count (10 for this version of the SoftDevice). */
/** @} */
/** @} */
/** @addtogroup BLE_COMMON_STRUCTURES Structures
* @{ */
/**@brief User Memory Block. */
typedef struct
{
uint8_t *p_mem; /**< Pointer to the start of the user memory block. */
uint16_t len; /**< Length in bytes of the user memory block. */
} ble_user_mem_block_t;
/**
* @brief Event structure for @ref BLE_EVT_TX_COMPLETE.
*/
typedef struct
{
uint8_t count; /**< Number of packets transmitted. */
} ble_evt_tx_complete_t;
/**@brief Event structure for @ref BLE_EVT_USER_MEM_REQUEST. */
typedef struct
{
uint8_t type; /**< User memory type, see @ref BLE_USER_MEM_TYPES. */
} ble_evt_user_mem_request_t;
/**@brief Event structure for @ref BLE_EVT_USER_MEM_RELEASE. */
typedef struct
{
uint8_t type; /**< User memory type, see @ref BLE_USER_MEM_TYPES. */
ble_user_mem_block_t mem_block; /**< User memory block */
} ble_evt_user_mem_release_t;
/**@brief Event structure for events not associated with a specific function module. */
typedef struct
{
uint16_t conn_handle; /**< Connection Handle on which this event occurred. */
union
{
ble_evt_tx_complete_t tx_complete; /**< Transmission Complete. */
ble_evt_user_mem_request_t user_mem_request; /**< User Memory Request Event Parameters. */
ble_evt_user_mem_release_t user_mem_release; /**< User Memory Release Event Parameters. */
} params;
} ble_common_evt_t;
/**@brief BLE Event header. */
typedef struct
{
uint16_t evt_id; /**< Value from a BLE_<module>_EVT series. */
uint16_t evt_len; /**< Length in octets including this header. */
} ble_evt_hdr_t;
/**@brief Common BLE Event type, wrapping the module specific event reports. */
typedef struct
{
ble_evt_hdr_t header; /**< Event header. */
union
{
ble_common_evt_t common_evt; /**< Common Event, evt_id in BLE_EVT_* series. */
ble_gap_evt_t gap_evt; /**< GAP originated event, evt_id in BLE_GAP_EVT_* series. */
ble_l2cap_evt_t l2cap_evt; /**< L2CAP originated event, evt_id in BLE_L2CAP_EVT* series. */
ble_gattc_evt_t gattc_evt; /**< GATT client originated event, evt_id in BLE_GATTC_EVT* series. */
ble_gatts_evt_t gatts_evt; /**< GATT server originated event, evt_id in BLE_GATTS_EVT* series. */
} evt;
} ble_evt_t;
/**
* @brief Version Information.
*/
typedef struct
{
uint8_t version_number; /**< Link Layer Version number for BT 4.1 spec is 7 (https://www.bluetooth.org/en-us/specification/assigned-numbers/link-layer). */
uint16_t company_id; /**< Company ID, Nordic Semiconductor's company ID is 89 (0x0059) (https://www.bluetooth.org/apps/content/Default.aspx?doc_id=49708). */
uint16_t subversion_number; /**< Link Layer Sub Version number, corresponds to the SoftDevice Config ID or Firmware ID (FWID). */
} ble_version_t;
/* @brief: Configuration parameters for the PA and LNA. */
typedef struct
{
uint8_t enable :1; /**< Enable toggling for this amplifier */
uint8_t active_high :1; /**< Set the pin to be active high */
uint8_t gpio_pin :6; /**< The GPIO pin to toggle for this amplifier */
} ble_pa_lna_cfg_t;
/*
* @brief PA & LNA GPIO toggle configuration
*
* This option configures the SoftDevice to toggle pins when the radio is active for use with a power amplifier and/or
* a low noise amplifier.
*
* Toggling the pins is achieved by using two PPI channels and a GPIOTE channel. The hardware channel IDs are provided
* by the application and should be regarded as reserved as long as any PA/LNA toggling is enabled.
*
* @note @ref sd_ble_opt_get is not supported for this option.
* @note This feature is only supported for nRF52, on nRF51 @ref NRF_ERROR_NOT_SUPPORTED will always be returned.
* @note Setting this option while the radio is in use (i.e. any of the roles are active) may have undefined consequences
* and must be avoided by the application.
*
*/
typedef struct
{
ble_pa_lna_cfg_t pa_cfg; /**< Power Amplifier configuration */
ble_pa_lna_cfg_t lna_cfg; /**< Low Noise Amplifier configuration */
uint8_t ppi_ch_id_set; /**< PPI channel used for radio pin setting */
uint8_t ppi_ch_id_clr; /**< PPI channel used for radio pin clearing */
uint8_t gpiote_ch_id; /**< GPIOTE channel used for radio pin toggling */
} ble_common_opt_pa_lna_t;
/**
* @brief BLE connection bandwidth configuration parameters
*/
typedef struct
{
uint8_t conn_bw_tx; /**< Connection bandwidth configuration for transmission, see @ref BLE_CONN_BWS.*/
uint8_t conn_bw_rx; /**< Connection bandwidth configuration for reception, see @ref BLE_CONN_BWS.*/
} ble_conn_bw_t;
/**@brief BLE connection specific bandwidth configuration parameters.
*
* This can be used with @ref sd_ble_opt_set to set the bandwidth configuration to be used when creating connections.
*
* Call @ref sd_ble_opt_set with this option prior to calling @ref sd_ble_gap_adv_start or @ref sd_ble_gap_connect.
*
* The bandwidth configurations set via @ref sd_ble_opt_set are maintained separately for central and peripheral
* connections. The given configurations are used for all future connections of the role indicated in this structure
* unless they are changed by subsequent @ref sd_ble_opt_set calls.
*
* @note When this option is not used, the SoftDevice will use the default options:
* - @ref BLE_CONN_BW_HIGH for @ref BLE_GAP_ROLE_PERIPH connections (both transmission and reception).
* - @ref BLE_CONN_BW_MID for @ref BLE_GAP_ROLE_CENTRAL connections (both transmisison and reception).
* This option allows the application to selectively override these defaults for each role.
*
* @note The global memory pool configuration can be set with the @ref ble_conn_bw_counts_t configuration parameter, which
* is provided to @ref sd_ble_enable.
*
* @note Please refer to SoftDevice Specification for more information on bandwidth configuration.
*
* @mscs
* @mmsc{@ref BLE_COMMON_CONF_BW}
* @endmscs
*
* @retval ::NRF_SUCCESS Set successfully.
* @retval ::BLE_ERROR_INVALID_ROLE The role is invalid.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid bandwidth configuration parameters.
* @retval ::NRF_ERROR_NOT_SUPPORTED If the combination of role and bandwidth configuration is not supported.
*/
typedef struct
{
uint8_t role; /**< BLE role of the connection, see @ref BLE_GAP_ROLES. */
ble_conn_bw_t conn_bw; /**< Bandwidth configuration parameters. */
} ble_common_opt_conn_bw_t;
/**@brief Option structure for common options. */
typedef union
{
ble_common_opt_conn_bw_t conn_bw; /**< Parameters for the connection bandwidth option. */
ble_common_opt_pa_lna_t pa_lna; /**< Parameters for controlling PA and LNA pin toggling. */
} ble_common_opt_t;
/**@brief Common BLE Option type, wrapping the module specific options. */
typedef union
{
ble_common_opt_t common_opt; /**< COMMON options, opt_id in @ref BLE_COMMON_OPTS series. */
ble_gap_opt_t gap_opt; /**< GAP option, opt_id in @ref BLE_GAP_OPTS series. */
} ble_opt_t;
/**
* @brief BLE bandwidth count parameters
*
* These parameters are used to configure the memory pools allocated within the SoftDevice for application packets
* (both transmission and reception) for all connections.
*
* @note The sum of all three counts must add up to the sum of @ref ble_gap_enable_params_t::central_conn_count and
* @ref ble_gap_enable_params_t::periph_conn_count in @ref ble_gap_enable_params_t.
*/
typedef struct {
uint8_t high_count; /**< Total number of high bandwidth TX or RX memory pools available to the application at runtime for all active connections. */
uint8_t mid_count; /**< Total number of medium bandwidth TX or RX memory pools available to the application at runtime for all active connections. */
uint8_t low_count; /**< Total number of low bandwidth TX or RX memory pools available to the application at runtime for all active connections. */
} ble_conn_bw_count_t;
/**
* @brief BLE bandwidth global memory pool configuration parameters
*
* These configuration parameters are used to set the amount of memory dedicated to application packets for
* all connections. The application should specify the most demanding configuration for the intended use.
*
* Please refer to the SoftDevice Specification for more information on bandwidth configuration.
*
* @note Each connection created at runtime requires both a TX and an RX memory pool. By the use of these configuration
* parameters, the application can decide the size and total number of the global memory pools that will be later
* available for connection creation.
*
* @mscs
* @mmsc{@ref BLE_COMMON_CONF_BW}
* @endmscs
*
*/
typedef struct {
ble_conn_bw_count_t tx_counts; /**< Global memory pool configuration for transmission.*/
ble_conn_bw_count_t rx_counts; /**< Global memory pool configuration for reception.*/
} ble_conn_bw_counts_t;
/**
* @brief BLE Common Initialization parameters.
*
* @note If @ref p_conn_bw_counts is NULL the SoftDevice will assume default bandwidth configuration for all connections.
* To fit a custom bandwidth configuration requirement, the application developer may have to specify a custom memory
* pool configuration here. See @ref ble_common_opt_conn_bw_t for bandwidth configuration of individual connections.
* Please refer to the SoftDevice Specification for more information on bandwidth configuration.
*/
typedef struct
{
uint16_t vs_uuid_count; /**< Maximum number of 128-bit, Vendor Specific UUID bases to allocate. */
ble_conn_bw_counts_t *p_conn_bw_counts; /**< Bandwidth configuration parameters or NULL for defaults. */
} ble_common_enable_params_t;
/**
* @brief BLE Initialization parameters.
*/
typedef struct
{
ble_common_enable_params_t common_enable_params; /**< Common init parameters @ref ble_common_enable_params_t. */
ble_gap_enable_params_t gap_enable_params; /**< GAP init parameters @ref ble_gap_enable_params_t. */
ble_gatts_enable_params_t gatts_enable_params; /**< GATTS init parameters @ref ble_gatts_enable_params_t. */
} ble_enable_params_t;
/** @} */
/** @addtogroup BLE_COMMON_FUNCTIONS Functions
* @{ */
/**@brief Enable the BLE stack
*
* @param[in, out] p_ble_enable_params Pointer to ble_enable_params_t
* @param[in, out] p_app_ram_base Pointer to a variable containing the start address of the application RAM region
* (APP_RAM_BASE). On return, this will contain the minimum start address of the application RAM region required by the
* SoftDevice for this configuration. Calling @ref sd_ble_enable() with *p_app_ram_base set to 0 can be used during
* development to find out how much memory a specific configuration will need.
*
* @note The memory requirement for a specific configuration will not increase between SoftDevices with the same major
* version number.
*
* @note At runtime the IC's RAM is split into 2 regions: The SoftDevice RAM region is located between 0x20000000 and
* APP_RAM_BASE-1 and the application's RAM region is located between APP_RAM_BASE and the start of the call stack.
*
* @details This call initializes the BLE stack, no other BLE related function can be called before this one.
*
* @mscs
* @mmsc{@ref BLE_COMMON_ENABLE}
* @endmscs
*
* @retval ::NRF_SUCCESS The BLE stack has been initialized successfully.
* @retval ::NRF_ERROR_INVALID_STATE The BLE stack had already been initialized and cannot be reinitialized.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied.
* @retval ::NRF_ERROR_INVALID_LENGTH The specified Attribute Table size is either too small or not a multiple of 4.
* The minimum acceptable size is defined by @ref BLE_GATTS_ATTR_TAB_SIZE_MIN.
* @retval ::NRF_ERROR_INVALID_PARAM Incorrectly configured VS UUID count or connection count parameters.
* @retval ::NRF_ERROR_NO_MEM The amount of memory assigned to the SoftDevice by *p_app_ram_base is not
* large enough to fit this configuration's memory requirement. Check *p_app_ram_base
* and set the start address of the application RAM region accordingly.
* @retval ::NRF_ERROR_CONN_COUNT The requested number of connections exceeds the maximum supported by the SoftDevice.
* Please refer to the SoftDevice Specification for more information on role configuration.
*/
SVCALL(SD_BLE_ENABLE, uint32_t, sd_ble_enable(ble_enable_params_t * p_ble_enable_params, uint32_t * p_app_ram_base));
/**@brief Get an event from the pending events queue.
*
* @param[out] p_dest Pointer to buffer to be filled in with an event, or NULL to retrieve the event length.
* This buffer <b>must be 4-byte aligned in memory</b>.
* @param[in, out] p_len Pointer the length of the buffer, on return it is filled with the event length.
*
* @details This call allows the application to pull a BLE event from the BLE stack. The application is signaled that
* an event is available from the BLE stack by the triggering of the SD_EVT_IRQn interrupt.
* The application is free to choose whether to call this function from thread mode (main context) or directly from the
* Interrupt Service Routine that maps to SD_EVT_IRQn. In any case however, and because the BLE stack runs at a higher
* priority than the application, this function should be called in a loop (until @ref NRF_ERROR_NOT_FOUND is returned)
* every time SD_EVT_IRQn is raised to ensure that all available events are pulled from the BLE stack. Failure to do so
* could potentially leave events in the internal queue without the application being aware of this fact. Sizing the
* p_dest buffer is equally important, since the application needs to provide all the memory necessary for the event to
* be copied into application memory. If the buffer provided is not large enough to fit the entire contents of the event,
* @ref NRF_ERROR_DATA_SIZE will be returned and the application can then call again with a larger buffer size.
* Please note that because of the variable length nature of some events, sizeof(ble_evt_t) will not always be large
* enough to fit certain events, and so it is the application's responsibility to provide an amount of memory large
* enough so that the relevant event is copied in full. The application may "peek" the event length by providing p_dest
* as a NULL pointer and inspecting the value of *p_len upon return:
*
* \code
* uint16_t len;
* errcode = sd_ble_evt_get(NULL, &len);
* \endcode
*
* @note The pointer supplied must be aligned to the extend defined by @ref BLE_EVTS_PTR_ALIGNMENT
*
* @mscs
* @mmsc{@ref BLE_COMMON_IRQ_EVT_MSC}
* @mmsc{@ref BLE_COMMON_THREAD_EVT_MSC}
* @endmscs
*
* @retval ::NRF_SUCCESS Event pulled and stored into the supplied buffer.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied.
* @retval ::NRF_ERROR_NOT_FOUND No events ready to be pulled.
* @retval ::NRF_ERROR_DATA_SIZE Event ready but could not fit into the supplied buffer.
*/
SVCALL(SD_BLE_EVT_GET, uint32_t, sd_ble_evt_get(uint8_t *p_dest, uint16_t *p_len));
/**@brief Get the total number of available guaranteed application transmission packets for a particular connection.
*
* @details This call allows the application to obtain the total number of guaranteed application transmission packets
* available for a connection. Please note that this does not return the number of free packets, but rather the total
* amount of them for that particular connection. The application has two options to handle transmitting application packets:
* - Use a simple arithmetic calculation: after connection creation time the application should use this function to
* find out the total amount of guaranteed packets available to it and store it in a variable.
* Every time a packet is successfully queued for a transmission on this connection using any of the exposed functions in
* this BLE API, the application should decrement that variable. Conversely, whenever a @ref BLE_EVT_TX_COMPLETE event
* with the conn_handle matching the particular connection is received by the application, it should retrieve the count
* field in such event and add that number to the same variable storing the number of available guaranteed packets. This
* mechanism allows the application to be aware at any time of the number of guaranteed application packets available for
* each of the active connections, and therefore it can know with certainty whether it is possible to send more data or
* it has to wait for a @ref BLE_EVT_TX_COMPLETE event before it proceeds.
* The application can still pursue transmissions when the number of guaranteed application packets available is smaller
* than or equal to zero, but successful queuing of the tranmsission is not guaranteed.
* - Choose to simply not keep track of available packets at all, and instead handle the @ref BLE_ERROR_NO_TX_PACKETS error
* by queueing the packet to be transmitted and try again as soon as a @ref BLE_EVT_TX_COMPLETE event arrives.
*
* The API functions that <b>may</b> consume an application packet depending on the parameters supplied to them can be found below:
* - @ref sd_ble_gattc_write (write without response only)
* - @ref sd_ble_gatts_hvx (notifications only)
* - @ref sd_ble_l2cap_tx (all packets)
*
* @param[in] conn_handle Connection handle.
* @param[out] p_count Pointer to a uint8_t which will contain the number of application transmission packets upon
* successful return.
* @mscs
* @mmsc{@ref BLE_COMMON_APP_BUFF_MSC}
* @endmscs
*
* @retval ::NRF_SUCCESS Number of application transmission packets retrieved successfully.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
*/
SVCALL(SD_BLE_TX_PACKET_COUNT_GET, uint32_t, sd_ble_tx_packet_count_get(uint16_t conn_handle, uint8_t *p_count));
/**@brief Add a Vendor Specific UUID.
*
* @details This call enables the application to add a vendor specific UUID to the BLE stack's table, for later use
* all other modules and APIs. This then allows the application to use the shorter, 24-bit @ref ble_uuid_t format
* when dealing with both 16-bit and 128-bit UUIDs without having to check for lengths and having split code paths.
* The way that this is accomplished is by extending the grouping mechanism that the Bluetooth SIG standard base
* UUID uses for all other 128-bit UUIDs. The type field in the @ref ble_uuid_t structure is an index (relative to
* @ref BLE_UUID_TYPE_VENDOR_BEGIN) to the table populated by multiple calls to this function, and the uuid field
* in the same structure contains the 2 bytes at indices 12 and 13. The number of possible 128-bit UUIDs available to
* the application is therefore the number of Vendor Specific UUIDs added with the help of this function times 65536,
* although restricted to modifying bytes 12 and 13 for each of the entries in the supplied array.
*
* @note Bytes 12 and 13 of the provided UUID will not be used internally, since those are always replaced by
* the 16-bit uuid field in @ref ble_uuid_t.
*
* @note If a UUID is already present in the BLE stack's internal table, the corresponding index will be returned in
* p_uuid_type along with an NRF_SUCCESS error code.
*
* @param[in] p_vs_uuid Pointer to a 16-octet (128-bit) little endian Vendor Specific UUID disregarding
* bytes 12 and 13.
* @param[out] p_uuid_type Pointer to a uint8_t where the type field in @ref ble_uuid_t corresponding to this UUID will be stored.
*
* @retval ::NRF_SUCCESS Successfully added the Vendor Specific UUID.
* @retval ::NRF_ERROR_INVALID_ADDR If p_vs_uuid or p_uuid_type is NULL or invalid.
* @retval ::NRF_ERROR_NO_MEM If there are no more free slots for VS UUIDs.
*/
SVCALL(SD_BLE_UUID_VS_ADD, uint32_t, sd_ble_uuid_vs_add(ble_uuid128_t const *p_vs_uuid, uint8_t *p_uuid_type));
/** @brief Decode little endian raw UUID bytes (16-bit or 128-bit) into a 24 bit @ref ble_uuid_t structure.
*
* @details The raw UUID bytes excluding bytes 12 and 13 (i.e. bytes 0-11 and 14-15) of p_uuid_le are compared
* to the corresponding ones in each entry of the table of vendor specific UUIDs populated with @ref sd_ble_uuid_vs_add
* to look for a match. If there is such a match, bytes 12 and 13 are returned as p_uuid->uuid and the index
* relative to @ref BLE_UUID_TYPE_VENDOR_BEGIN as p_uuid->type.
*
* @note If the UUID length supplied is 2, then the type set by this call will always be @ref BLE_UUID_TYPE_BLE.
*
* @param[in] uuid_le_len Length in bytes of the buffer pointed to by p_uuid_le (must be 2 or 16 bytes).
* @param[in] p_uuid_le Pointer pointing to little endian raw UUID bytes.
* @param[out] p_uuid Pointer to a @ref ble_uuid_t structure to be filled in.
*
* @retval ::NRF_SUCCESS Successfully decoded into the @ref ble_uuid_t structure.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_INVALID_LENGTH Invalid UUID length.
* @retval ::NRF_ERROR_NOT_FOUND For a 128-bit UUID, no match in the populated table of UUIDs.
*/
SVCALL(SD_BLE_UUID_DECODE, uint32_t, sd_ble_uuid_decode(uint8_t uuid_le_len, uint8_t const *p_uuid_le, ble_uuid_t *p_uuid));
/** @brief Encode a @ref ble_uuid_t structure into little endian raw UUID bytes (16-bit or 128-bit).
*
* @note The pointer to the destination buffer p_uuid_le may be NULL, in which case only the validity and size of p_uuid is computed.
*
* @param[in] p_uuid Pointer to a @ref ble_uuid_t structure that will be encoded into bytes.
* @param[out] p_uuid_le_len Pointer to a uint8_t that will be filled with the encoded length (2 or 16 bytes).
* @param[out] p_uuid_le Pointer to a buffer where the little endian raw UUID bytes (2 or 16) will be stored.
*
* @retval ::NRF_SUCCESS Successfully encoded into the buffer.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid UUID type.
*/
SVCALL(SD_BLE_UUID_ENCODE, uint32_t, sd_ble_uuid_encode(ble_uuid_t const *p_uuid, uint8_t *p_uuid_le_len, uint8_t *p_uuid_le));
/**@brief Get Version Information.
*
* @details This call allows the application to get the BLE stack version information.
*
* @param[out] p_version Pointer to a ble_version_t structure to be filled in.
*
* @retval ::NRF_SUCCESS Version information stored successfully.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_BUSY The BLE stack is busy (typically doing a locally-initiated disconnection procedure).
*/
SVCALL(SD_BLE_VERSION_GET, uint32_t, sd_ble_version_get(ble_version_t *p_version));
/**@brief Provide a user memory block.
*
* @note This call can only be used as a response to a @ref BLE_EVT_USER_MEM_REQUEST event issued to the application.
*
* @param[in] conn_handle Connection handle.
* @param[in,out] p_block Pointer to a user memory block structure.
*
* @mscs
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_PEER_CANCEL_MSC}
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC}
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC}
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC}
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_NOAUTH_MSC}
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC}
* @endmscs
*
* @retval ::NRF_SUCCESS Successfully queued a response to the peer.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection state or no execute write request pending.
* @retval ::NRF_ERROR_BUSY The BLE stack is busy. Retry at later time.
*/
SVCALL(SD_BLE_USER_MEM_REPLY, uint32_t, sd_ble_user_mem_reply(uint16_t conn_handle, ble_user_mem_block_t const *p_block));
/**@brief Set a BLE option.
*
* @details This call allows the application to set the value of an option.
*
* @mscs
* @mmsc{@ref BLE_GAP_PERIPH_BONDING_STATIC_PK_MSC}
* @mmsc{@ref BLE_COMMON_CONF_BW}
* @endmscs
*
* @param[in] opt_id Option ID, see @ref BLE_COMMON_OPTS and @ref BLE_GAP_OPTS.
* @param[in] p_opt Pointer to a ble_opt_t structure containing the option value.
*
* @retval ::NRF_SUCCESS Option set successfully.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints.
* @retval ::NRF_ERROR_INVALID_STATE Unable to set the parameter at this time.
* @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed.
*/
SVCALL(SD_BLE_OPT_SET, uint32_t, sd_ble_opt_set(uint32_t opt_id, ble_opt_t const *p_opt));
/**@brief Get a BLE option.
*
* @details This call allows the application to retrieve the value of an option.
*
* @param[in] opt_id Option ID, see @ref BLE_COMMON_OPTS and @ref BLE_GAP_OPTS.
* @param[out] p_opt Pointer to a ble_opt_t structure to be filled in.
*
* @retval ::NRF_SUCCESS Option retrieved successfully.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints.
* @retval ::NRF_ERROR_INVALID_STATE Unable to retrieve the parameter at this time.
* @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed.
* @retval ::NRF_ERROR_NOT_SUPPORTED This option is not supported.
*
*/
SVCALL(SD_BLE_OPT_GET, uint32_t, sd_ble_opt_get(uint32_t opt_id, ble_opt_t *p_opt));
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* BLE_H__ */
/**
@}
@}
*/

View File

@ -0,0 +1,90 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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.
*
*/
/**
@addtogroup BLE_COMMON
@{
@addtogroup nrf_error
@{
@ingroup BLE_COMMON
@}
@defgroup ble_err General error codes
@{
@brief General error code definitions for the BLE API.
@ingroup BLE_COMMON
*/
#ifndef NRF_BLE_ERR_H__
#define NRF_BLE_ERR_H__
#include "nrf_error.h"
#ifdef __cplusplus
extern "C" {
#endif
/* @defgroup BLE_ERRORS Error Codes
* @{ */
#define BLE_ERROR_NOT_ENABLED (NRF_ERROR_STK_BASE_NUM+0x001) /**< @ref sd_ble_enable has not been called. */
#define BLE_ERROR_INVALID_CONN_HANDLE (NRF_ERROR_STK_BASE_NUM+0x002) /**< Invalid connection handle. */
#define BLE_ERROR_INVALID_ATTR_HANDLE (NRF_ERROR_STK_BASE_NUM+0x003) /**< Invalid attribute handle. */
#define BLE_ERROR_NO_TX_PACKETS (NRF_ERROR_STK_BASE_NUM+0x004) /**< Not enough application packets available on this connection. */
#define BLE_ERROR_INVALID_ROLE (NRF_ERROR_STK_BASE_NUM+0x005) /**< Invalid role. */
/** @} */
/** @defgroup BLE_ERROR_SUBRANGES Module specific error code subranges
* @brief Assignment of subranges for module specific error codes.
* @note For specific error codes, see ble_<module>.h or ble_error_<module>.h.
* @{ */
#define NRF_L2CAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x100) /**< L2CAP specific errors. */
#define NRF_GAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x200) /**< GAP specific errors. */
#define NRF_GATTC_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x300) /**< GATT client specific errors. */
#define NRF_GATTS_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x400) /**< GATT server specific errors. */
/** @} */
#ifdef __cplusplus
}
#endif
#endif
/**
@}
@}
*/

View File

@ -0,0 +1,212 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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.
*
*/
/**
@addtogroup BLE_GATT Generic Attribute Profile (GATT) Common
@{
@brief Common definitions and prototypes for the GATT interfaces.
*/
#ifndef BLE_GATT_H__
#define BLE_GATT_H__
#include "ble_types.h"
#include "ble_ranges.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup BLE_GATT_DEFINES Defines
* @{ */
/** @brief Default MTU size. */
#define GATT_MTU_SIZE_DEFAULT 23
/** @brief Only the default MTU size of 23 is currently supported. */
#define GATT_RX_MTU 23
/**@brief Invalid Attribute Handle. */
#define BLE_GATT_HANDLE_INVALID 0x0000
/**@brief First Attribute Handle. */
#define BLE_GATT_HANDLE_START 0x0001
/**@brief Last Attribute Handle. */
#define BLE_GATT_HANDLE_END 0xFFFF
/** @defgroup BLE_GATT_TIMEOUT_SOURCES GATT Timeout sources
* @{ */
#define BLE_GATT_TIMEOUT_SRC_PROTOCOL 0x00 /**< ATT Protocol timeout. */
/** @} */
/** @defgroup BLE_GATT_WRITE_OPS GATT Write operations
* @{ */
#define BLE_GATT_OP_INVALID 0x00 /**< Invalid Operation. */
#define BLE_GATT_OP_WRITE_REQ 0x01 /**< Write Request. */
#define BLE_GATT_OP_WRITE_CMD 0x02 /**< Write Command. */
#define BLE_GATT_OP_SIGN_WRITE_CMD 0x03 /**< Signed Write Command. */
#define BLE_GATT_OP_PREP_WRITE_REQ 0x04 /**< Prepare Write Request. */
#define BLE_GATT_OP_EXEC_WRITE_REQ 0x05 /**< Execute Write Request. */
/** @} */
/** @defgroup BLE_GATT_EXEC_WRITE_FLAGS GATT Execute Write flags
* @{ */
#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL 0x00
#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE 0x01
/** @} */
/** @defgroup BLE_GATT_HVX_TYPES GATT Handle Value operations
* @{ */
#define BLE_GATT_HVX_INVALID 0x00 /**< Invalid Operation. */
#define BLE_GATT_HVX_NOTIFICATION 0x01 /**< Handle Value Notification. */
#define BLE_GATT_HVX_INDICATION 0x02 /**< Handle Value Indication. */
/** @} */
/** @defgroup BLE_GATT_STATUS_CODES GATT Status Codes
* @{ */
#define BLE_GATT_STATUS_SUCCESS 0x0000 /**< Success. */
#define BLE_GATT_STATUS_UNKNOWN 0x0001 /**< Unknown or not applicable status. */
#define BLE_GATT_STATUS_ATTERR_INVALID 0x0100 /**< ATT Error: Invalid Error Code. */
#define BLE_GATT_STATUS_ATTERR_INVALID_HANDLE 0x0101 /**< ATT Error: Invalid Attribute Handle. */
#define BLE_GATT_STATUS_ATTERR_READ_NOT_PERMITTED 0x0102 /**< ATT Error: Read not permitted. */
#define BLE_GATT_STATUS_ATTERR_WRITE_NOT_PERMITTED 0x0103 /**< ATT Error: Write not permitted. */
#define BLE_GATT_STATUS_ATTERR_INVALID_PDU 0x0104 /**< ATT Error: Used in ATT as Invalid PDU. */
#define BLE_GATT_STATUS_ATTERR_INSUF_AUTHENTICATION 0x0105 /**< ATT Error: Authenticated link required. */
#define BLE_GATT_STATUS_ATTERR_REQUEST_NOT_SUPPORTED 0x0106 /**< ATT Error: Used in ATT as Request Not Supported. */
#define BLE_GATT_STATUS_ATTERR_INVALID_OFFSET 0x0107 /**< ATT Error: Offset specified was past the end of the attribute. */
#define BLE_GATT_STATUS_ATTERR_INSUF_AUTHORIZATION 0x0108 /**< ATT Error: Used in ATT as Insufficient Authorisation. */
#define BLE_GATT_STATUS_ATTERR_PREPARE_QUEUE_FULL 0x0109 /**< ATT Error: Used in ATT as Prepare Queue Full. */
#define BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND 0x010A /**< ATT Error: Used in ATT as Attribute not found. */
#define BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_LONG 0x010B /**< ATT Error: Attribute cannot be read or written using read/write blob requests. */
#define BLE_GATT_STATUS_ATTERR_INSUF_ENC_KEY_SIZE 0x010C /**< ATT Error: Encryption key size used is insufficient. */
#define BLE_GATT_STATUS_ATTERR_INVALID_ATT_VAL_LENGTH 0x010D /**< ATT Error: Invalid value size. */
#define BLE_GATT_STATUS_ATTERR_UNLIKELY_ERROR 0x010E /**< ATT Error: Very unlikely error. */
#define BLE_GATT_STATUS_ATTERR_INSUF_ENCRYPTION 0x010F /**< ATT Error: Encrypted link required. */
#define BLE_GATT_STATUS_ATTERR_UNSUPPORTED_GROUP_TYPE 0x0110 /**< ATT Error: Attribute type is not a supported grouping attribute. */
#define BLE_GATT_STATUS_ATTERR_INSUF_RESOURCES 0x0111 /**< ATT Error: Encrypted link required. */
#define BLE_GATT_STATUS_ATTERR_RFU_RANGE1_BEGIN 0x0112 /**< ATT Error: Reserved for Future Use range #1 begin. */
#define BLE_GATT_STATUS_ATTERR_RFU_RANGE1_END 0x017F /**< ATT Error: Reserved for Future Use range #1 end. */
#define BLE_GATT_STATUS_ATTERR_APP_BEGIN 0x0180 /**< ATT Error: Application range begin. */
#define BLE_GATT_STATUS_ATTERR_APP_END 0x019F /**< ATT Error: Application range end. */
#define BLE_GATT_STATUS_ATTERR_RFU_RANGE2_BEGIN 0x01A0 /**< ATT Error: Reserved for Future Use range #2 begin. */
#define BLE_GATT_STATUS_ATTERR_RFU_RANGE2_END 0x01DF /**< ATT Error: Reserved for Future Use range #2 end. */
#define BLE_GATT_STATUS_ATTERR_RFU_RANGE3_BEGIN 0x01E0 /**< ATT Error: Reserved for Future Use range #3 begin. */
#define BLE_GATT_STATUS_ATTERR_RFU_RANGE3_END 0x01FC /**< ATT Error: Reserved for Future Use range #3 end. */
#define BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR 0x01FD /**< ATT Common Profile and Service Error: Client Characteristic Configuration Descriptor improperly configured. */
#define BLE_GATT_STATUS_ATTERR_CPS_PROC_ALR_IN_PROG 0x01FE /**< ATT Common Profile and Service Error: Procedure Already in Progress. */
#define BLE_GATT_STATUS_ATTERR_CPS_OUT_OF_RANGE 0x01FF /**< ATT Common Profile and Service Error: Out Of Range. */
/** @} */
/** @defgroup BLE_GATT_CPF_FORMATS Characteristic Presentation Formats
* @note Found at http://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml
* @{ */
#define BLE_GATT_CPF_FORMAT_RFU 0x00 /**< Reserved For Future Use. */
#define BLE_GATT_CPF_FORMAT_BOOLEAN 0x01 /**< Boolean. */
#define BLE_GATT_CPF_FORMAT_2BIT 0x02 /**< Unsigned 2-bit integer. */
#define BLE_GATT_CPF_FORMAT_NIBBLE 0x03 /**< Unsigned 4-bit integer. */
#define BLE_GATT_CPF_FORMAT_UINT8 0x04 /**< Unsigned 8-bit integer. */
#define BLE_GATT_CPF_FORMAT_UINT12 0x05 /**< Unsigned 12-bit integer. */
#define BLE_GATT_CPF_FORMAT_UINT16 0x06 /**< Unsigned 16-bit integer. */
#define BLE_GATT_CPF_FORMAT_UINT24 0x07 /**< Unsigned 24-bit integer. */
#define BLE_GATT_CPF_FORMAT_UINT32 0x08 /**< Unsigned 32-bit integer. */
#define BLE_GATT_CPF_FORMAT_UINT48 0x09 /**< Unsigned 48-bit integer. */
#define BLE_GATT_CPF_FORMAT_UINT64 0x0A /**< Unsigned 64-bit integer. */
#define BLE_GATT_CPF_FORMAT_UINT128 0x0B /**< Unsigned 128-bit integer. */
#define BLE_GATT_CPF_FORMAT_SINT8 0x0C /**< Signed 2-bit integer. */
#define BLE_GATT_CPF_FORMAT_SINT12 0x0D /**< Signed 12-bit integer. */
#define BLE_GATT_CPF_FORMAT_SINT16 0x0E /**< Signed 16-bit integer. */
#define BLE_GATT_CPF_FORMAT_SINT24 0x0F /**< Signed 24-bit integer. */
#define BLE_GATT_CPF_FORMAT_SINT32 0x10 /**< Signed 32-bit integer. */
#define BLE_GATT_CPF_FORMAT_SINT48 0x11 /**< Signed 48-bit integer. */
#define BLE_GATT_CPF_FORMAT_SINT64 0x12 /**< Signed 64-bit integer. */
#define BLE_GATT_CPF_FORMAT_SINT128 0x13 /**< Signed 128-bit integer. */
#define BLE_GATT_CPF_FORMAT_FLOAT32 0x14 /**< IEEE-754 32-bit floating point. */
#define BLE_GATT_CPF_FORMAT_FLOAT64 0x15 /**< IEEE-754 64-bit floating point. */
#define BLE_GATT_CPF_FORMAT_SFLOAT 0x16 /**< IEEE-11073 16-bit SFLOAT. */
#define BLE_GATT_CPF_FORMAT_FLOAT 0x17 /**< IEEE-11073 32-bit FLOAT. */
#define BLE_GATT_CPF_FORMAT_DUINT16 0x18 /**< IEEE-20601 format. */
#define BLE_GATT_CPF_FORMAT_UTF8S 0x19 /**< UTF-8 string. */
#define BLE_GATT_CPF_FORMAT_UTF16S 0x1A /**< UTF-16 string. */
#define BLE_GATT_CPF_FORMAT_STRUCT 0x1B /**< Opaque Structure. */
/** @} */
/** @defgroup BLE_GATT_CPF_NAMESPACES GATT Bluetooth Namespaces
* @{
*/
#define BLE_GATT_CPF_NAMESPACE_BTSIG 0x01 /**< Bluetooth SIG defined Namespace. */
#define BLE_GATT_CPF_NAMESPACE_DESCRIPTION_UNKNOWN 0x0000 /**< Namespace Description Unknown. */
/** @} */
/** @} */
/** @addtogroup BLE_GATT_STRUCTURES Structures
* @{ */
/**@brief GATT Characteristic Properties. */
typedef struct
{
/* Standard properties */
uint8_t broadcast :1; /**< Broadcasting of the value permitted. */
uint8_t read :1; /**< Reading the value permitted. */
uint8_t write_wo_resp :1; /**< Writing the value with Write Command permitted. */
uint8_t write :1; /**< Writing the value with Write Request permitted. */
uint8_t notify :1; /**< Notications of the value permitted. */
uint8_t indicate :1; /**< Indications of the value permitted. */
uint8_t auth_signed_wr :1; /**< Writing the value with Signed Write Command permitted. */
} ble_gatt_char_props_t;
/**@brief GATT Characteristic Extended Properties. */
typedef struct
{
/* Extended properties */
uint8_t reliable_wr :1; /**< Writing the value with Queued Write operations permitted. */
uint8_t wr_aux :1; /**< Writing the Characteristic User Description descriptor permitted. */
} ble_gatt_char_ext_props_t;
#ifdef __cplusplus
}
#endif
#endif // BLE_GATT_H__
/** @} */
/**
@}
@}
*/

View File

@ -0,0 +1,569 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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.
*
*/
/**
@addtogroup BLE_GATTC Generic Attribute Profile (GATT) Client
@{
@brief Definitions and prototypes for the GATT Client interface.
*/
#ifndef BLE_GATTC_H__
#define BLE_GATTC_H__
#include "ble_gatt.h"
#include "ble_types.h"
#include "ble_ranges.h"
#include "nrf_svc.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup BLE_GATTC_ENUMERATIONS Enumerations
* @{ */
/**@brief GATTC API SVC numbers. */
enum BLE_GATTC_SVCS
{
SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER = BLE_GATTC_SVC_BASE, /**< Primary Service Discovery. */
SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, /**< Relationship Discovery. */
SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, /**< Characteristic Discovery. */
SD_BLE_GATTC_DESCRIPTORS_DISCOVER, /**< Characteristic Descriptor Discovery. */
SD_BLE_GATTC_ATTR_INFO_DISCOVER, /**< Attribute Information Discovery. */
SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, /**< Read Characteristic Value by UUID. */
SD_BLE_GATTC_READ, /**< Generic read. */
SD_BLE_GATTC_CHAR_VALUES_READ, /**< Read multiple Characteristic Values. */
SD_BLE_GATTC_WRITE, /**< Generic write. */
SD_BLE_GATTC_HV_CONFIRM, /**< Handle Value Confirmation. */
};
/**
* @brief GATT Client Event IDs.
*/
enum BLE_GATTC_EVTS
{
BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP = BLE_GATTC_EVT_BASE, /**< Primary Service Discovery Response event. \n See @ref ble_gattc_evt_prim_srvc_disc_rsp_t. */
BLE_GATTC_EVT_REL_DISC_RSP, /**< Relationship Discovery Response event. \n See @ref ble_gattc_evt_rel_disc_rsp_t. */
BLE_GATTC_EVT_CHAR_DISC_RSP, /**< Characteristic Discovery Response event. \n See @ref ble_gattc_evt_char_disc_rsp_t. */
BLE_GATTC_EVT_DESC_DISC_RSP, /**< Descriptor Discovery Response event. \n See @ref ble_gattc_evt_desc_disc_rsp_t. */
BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, /**< Attribute Information Response event. \n See @ref ble_gattc_evt_attr_info_disc_rsp_t. */
BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP, /**< Read By UUID Response event. \n See @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t. */
BLE_GATTC_EVT_READ_RSP, /**< Read Response event. \n See @ref ble_gattc_evt_read_rsp_t. */
BLE_GATTC_EVT_CHAR_VALS_READ_RSP, /**< Read multiple Response event. \n See @ref ble_gattc_evt_char_vals_read_rsp_t. */
BLE_GATTC_EVT_WRITE_RSP, /**< Write Response event. \n See @ref ble_gattc_evt_write_rsp_t. */
BLE_GATTC_EVT_HVX, /**< Handle Value Notification or Indication event. \n Confirm indication with @ref sd_ble_gattc_hv_confirm. \n See @ref ble_gattc_evt_hvx_t. */
BLE_GATTC_EVT_TIMEOUT /**< Timeout event. \n See @ref ble_gattc_evt_timeout_t. */
};
/** @} */
/** @addtogroup BLE_GATTC_DEFINES Defines
* @{ */
/** @defgroup BLE_ERRORS_GATTC SVC return values specific to GATTC
* @{ */
#define BLE_ERROR_GATTC_PROC_NOT_PERMITTED (NRF_GATTC_ERR_BASE + 0x000) /**< Procedure not Permitted. */
/** @} */
/** @defgroup BLE_GATTC_ATTR_INFO_FORMAT Attribute Information Formats
* @{ */
#define BLE_GATTC_ATTR_INFO_FORMAT_16BIT 1 /**< 16-bit Attribute Information Format. */
#define BLE_GATTC_ATTR_INFO_FORMAT_128BIT 2 /**< 128-bit Attribute Information Format. */
/** @} */
/** @} */
/** @addtogroup BLE_GATTC_STRUCTURES Structures
* @{ */
/**@brief Operation Handle Range. */
typedef struct
{
uint16_t start_handle; /**< Start Handle. */
uint16_t end_handle; /**< End Handle. */
} ble_gattc_handle_range_t;
/**@brief GATT service. */
typedef struct
{
ble_uuid_t uuid; /**< Service UUID. */
ble_gattc_handle_range_t handle_range; /**< Service Handle Range. */
} ble_gattc_service_t;
/**@brief GATT include. */
typedef struct
{
uint16_t handle; /**< Include Handle. */
ble_gattc_service_t included_srvc; /**< Handle of the included service. */
} ble_gattc_include_t;
/**@brief GATT characteristic. */
typedef struct
{
ble_uuid_t uuid; /**< Characteristic UUID. */
ble_gatt_char_props_t char_props; /**< Characteristic Properties. */
uint8_t char_ext_props : 1; /**< Extended properties present. */
uint16_t handle_decl; /**< Handle of the Characteristic Declaration. */
uint16_t handle_value; /**< Handle of the Characteristic Value. */
} ble_gattc_char_t;
/**@brief GATT descriptor. */
typedef struct
{
uint16_t handle; /**< Descriptor Handle. */
ble_uuid_t uuid; /**< Descriptor UUID. */
} ble_gattc_desc_t;
/**@brief Write Parameters. */
typedef struct
{
uint8_t write_op; /**< Write Operation to be performed, see @ref BLE_GATT_WRITE_OPS. */
uint8_t flags; /**< Flags, see @ref BLE_GATT_EXEC_WRITE_FLAGS. */
uint16_t handle; /**< Handle to the attribute to be written. */
uint16_t offset; /**< Offset in bytes. @note For WRITE_CMD and WRITE_REQ, offset must be 0. */
uint16_t len; /**< Length of data in bytes. */
uint8_t *p_value; /**< Pointer to the value data. */
} ble_gattc_write_params_t;
/**@brief Attribute Information. */
typedef struct
{
uint16_t handle; /**< Attribute handle. */
union {
ble_uuid_t uuid16; /**< 16-bit Attribute UUID. */
ble_uuid128_t uuid128; /**< 128-bit Attribute UUID. */
} info;
} ble_gattc_attr_info_t;
/**@brief Event structure for @ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP. */
typedef struct
{
uint16_t count; /**< Service count. */
ble_gattc_service_t services[1]; /**< Service data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
} ble_gattc_evt_prim_srvc_disc_rsp_t;
/**@brief Event structure for @ref BLE_GATTC_EVT_REL_DISC_RSP. */
typedef struct
{
uint16_t count; /**< Include count. */
ble_gattc_include_t includes[1]; /**< Include data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
} ble_gattc_evt_rel_disc_rsp_t;
/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_DISC_RSP. */
typedef struct
{
uint16_t count; /**< Characteristic count. */
ble_gattc_char_t chars[1]; /**< Characteristic data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
} ble_gattc_evt_char_disc_rsp_t;
/**@brief Event structure for @ref BLE_GATTC_EVT_DESC_DISC_RSP. */
typedef struct
{
uint16_t count; /**< Descriptor count. */
ble_gattc_desc_t descs[1]; /**< Descriptor data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
} ble_gattc_evt_desc_disc_rsp_t;
/**@brief Event structure for @ref BLE_GATTC_EVT_ATTR_INFO_DISC_RSP. */
typedef struct
{
uint16_t count; /**< Attribute count. */
uint8_t format; /**< Attribute information format, see @ref BLE_GATTC_ATTR_INFO_FORMAT. */
ble_gattc_attr_info_t attr_info[1]; /**< Attribute information. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
} ble_gattc_evt_attr_info_disc_rsp_t;
/**@brief GATT read by UUID handle value pair. */
typedef struct
{
uint16_t handle; /**< Attribute Handle. */
uint8_t *p_value; /**< Pointer to value, variable length (length available as value_len in @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t).
Please note that this pointer is absolute to the memory provided by the user when retrieving the event,
so it will effectively point to a location inside the handle_value array. */
} ble_gattc_handle_value_t;
/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP. */
typedef struct
{
uint16_t count; /**< Handle-Value Pair Count. */
uint16_t value_len; /**< Length of the value in Handle-Value(s) list. */
ble_gattc_handle_value_t handle_value[1]; /**< Handle-Value(s) list. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
} ble_gattc_evt_char_val_by_uuid_read_rsp_t;
/**@brief Event structure for @ref BLE_GATTC_EVT_READ_RSP. */
typedef struct
{
uint16_t handle; /**< Attribute Handle. */
uint16_t offset; /**< Offset of the attribute data. */
uint16_t len; /**< Attribute data length. */
uint8_t data[1]; /**< Attribute data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
} ble_gattc_evt_read_rsp_t;
/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP. */
typedef struct
{
uint16_t len; /**< Concatenated Attribute values length. */
uint8_t values[1]; /**< Attribute values. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
} ble_gattc_evt_char_vals_read_rsp_t;
/**@brief Event structure for @ref BLE_GATTC_EVT_WRITE_RSP. */
typedef struct
{
uint16_t handle; /**< Attribute Handle. */
uint8_t write_op; /**< Type of write operation, see @ref BLE_GATT_WRITE_OPS. */
uint16_t offset; /**< Data offset. */
uint16_t len; /**< Data length. */
uint8_t data[1]; /**< Data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
} ble_gattc_evt_write_rsp_t;
/**@brief Event structure for @ref BLE_GATTC_EVT_HVX. */
typedef struct
{
uint16_t handle; /**< Handle to which the HVx operation applies. */
uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */
uint16_t len; /**< Attribute data length. */
uint8_t data[1]; /**< Attribute data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
} ble_gattc_evt_hvx_t;
/**@brief Event structure for @ref BLE_GATTC_EVT_TIMEOUT. */
typedef struct
{
uint8_t src; /**< Timeout source, see @ref BLE_GATT_TIMEOUT_SOURCES. */
} ble_gattc_evt_timeout_t;
/**@brief GATTC event structure. */
typedef struct
{
uint16_t conn_handle; /**< Connection Handle on which event occured. */
uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */
uint16_t error_handle; /**< In case of error: The handle causing the error. In all other cases @ref BLE_GATT_HANDLE_INVALID. */
union
{
ble_gattc_evt_prim_srvc_disc_rsp_t prim_srvc_disc_rsp; /**< Primary Service Discovery Response Event Parameters. */
ble_gattc_evt_rel_disc_rsp_t rel_disc_rsp; /**< Relationship Discovery Response Event Parameters. */
ble_gattc_evt_char_disc_rsp_t char_disc_rsp; /**< Characteristic Discovery Response Event Parameters. */
ble_gattc_evt_desc_disc_rsp_t desc_disc_rsp; /**< Descriptor Discovery Response Event Parameters. */
ble_gattc_evt_char_val_by_uuid_read_rsp_t char_val_by_uuid_read_rsp; /**< Characteristic Value Read by UUID Response Event Parameters. */
ble_gattc_evt_read_rsp_t read_rsp; /**< Read Response Event Parameters. */
ble_gattc_evt_char_vals_read_rsp_t char_vals_read_rsp; /**< Characteristic Values Read Response Event Parameters. */
ble_gattc_evt_write_rsp_t write_rsp; /**< Write Response Event Parameters. */
ble_gattc_evt_hvx_t hvx; /**< Handle Value Notification/Indication Event Parameters. */
ble_gattc_evt_timeout_t timeout; /**< Timeout Event Parameters. */
ble_gattc_evt_attr_info_disc_rsp_t attr_info_disc_rsp; /**< Attribute Information Discovery Event Parameters. */
} params; /**< Event Parameters. @note Only valid if @ref gatt_status == @ref BLE_GATT_STATUS_SUCCESS. */
} ble_gattc_evt_t;
/** @} */
/** @addtogroup BLE_GATTC_FUNCTIONS Functions
* @{ */
/**@brief Initiate or continue a GATT Primary Service Discovery procedure.
*
* @details This function initiates or resumes a Primary Service discovery procedure, starting from the supplied handle.
* If the last service has not been reached, this function must be called again with an updated start handle value to continue the search.
*
* @note If any of the discovered services have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with
* type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event.
*
* @events
* @event{@ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP}
* @endevents
*
* @mscs
* @mmsc{@ref BLE_GATTC_PRIM_SRVC_DISC_MSC}
* @endmscs
*
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
* @param[in] start_handle Handle to start searching from.
* @param[in] p_srvc_uuid Pointer to the service UUID to be found. If it is NULL, all primary services will be returned.
*
* @retval ::NRF_SUCCESS Successfully started or resumed the Primary Service Discovery procedure.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
* @retval ::NRF_ERROR_BUSY Client procedure already in progress.
*/
SVCALL(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER, uint32_t, sd_ble_gattc_primary_services_discover(uint16_t conn_handle, uint16_t start_handle, ble_uuid_t const *p_srvc_uuid));
/**@brief Initiate or continue a GATT Relationship Discovery procedure.
*
* @details This function initiates or resumes the Find Included Services sub-procedure. If the last included service has not been reached,
* this must be called again with an updated handle range to continue the search.
*
* @events
* @event{@ref BLE_GATTC_EVT_REL_DISC_RSP}
* @endevents
*
* @mscs
* @mmsc{@ref BLE_GATTC_REL_DISC_MSC}
* @endmscs
*
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
* @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on.
*
* @retval ::NRF_SUCCESS Successfully started or resumed the Relationship Discovery procedure.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
* @retval ::NRF_ERROR_BUSY Client procedure already in progress.
*/
SVCALL(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, uint32_t, sd_ble_gattc_relationships_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range));
/**@brief Initiate or continue a GATT Characteristic Discovery procedure.
*
* @details This function initiates or resumes a Characteristic discovery procedure. If the last Characteristic has not been reached,
* this must be called again with an updated handle range to continue the discovery.
*
* @note If any of the discovered characteristics have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with
* type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event.
*
* @events
* @event{@ref BLE_GATTC_EVT_CHAR_DISC_RSP}
* @endevents
*
* @mscs
* @mmsc{@ref BLE_GATTC_CHAR_DISC_MSC}
* @endmscs
*
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
* @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on.
*
* @retval ::NRF_SUCCESS Successfully started or resumed the Characteristic Discovery procedure.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_BUSY Client procedure already in progress.
*/
SVCALL(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, uint32_t, sd_ble_gattc_characteristics_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range));
/**@brief Initiate or continue a GATT Characteristic Descriptor Discovery procedure.
*
* @details This function initiates or resumes a Characteristic Descriptor discovery procedure. If the last Descriptor has not been reached,
* this must be called again with an updated handle range to continue the discovery.
*
* @events
* @event{BLE_GATTC_EVT_DESC_DISC_RSP}
* @endevents
*
* @mscs
* @mmsc{@ref BLE_GATTC_DESC_DISC_MSC}
* @endmscs
*
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
* @param[in] p_handle_range A pointer to the range of handles of the Characteristic to perform this procedure on.
*
* @retval ::NRF_SUCCESS Successfully started or resumed the Descriptor Discovery procedure.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_BUSY Client procedure already in progress.
*/
SVCALL(SD_BLE_GATTC_DESCRIPTORS_DISCOVER, uint32_t, sd_ble_gattc_descriptors_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range));
/**@brief Initiate or continue a GATT Read using Characteristic UUID procedure.
*
* @details This function initiates or resumes a Read using Characteristic UUID procedure. If the last Characteristic has not been reached,
* this must be called again with an updated handle range to continue the discovery.
*
* @events
* @event{BLE_GATTC_EVT_DESC_DISC_RSP}
* @endevents
*
* @mscs
* @mmsc{@ref BLE_GATTC_READ_UUID_MSC}
* @endmscs
*
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
* @param[in] p_uuid Pointer to a Characteristic value UUID to read.
* @param[in] p_handle_range A pointer to the range of handles to perform this procedure on.
*
* @retval ::NRF_SUCCESS Successfully started or resumed the Read using Characteristic UUID procedure.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_BUSY Client procedure already in progress.
*/
SVCALL(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, uint32_t, sd_ble_gattc_char_value_by_uuid_read(uint16_t conn_handle, ble_uuid_t const *p_uuid, ble_gattc_handle_range_t const *p_handle_range));
/**@brief Initiate or continue a GATT Read (Long) Characteristic or Descriptor procedure.
*
* @details This function initiates or resumes a GATT Read (Long) Characteristic or Descriptor procedure. If the Characteristic or Descriptor
* to be read is longer than ATT_MTU - 1, this function must be called multiple times with appropriate offset to read the
* complete value.
*
* @events
* @event{@ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP}
* @endevents
*
* @mscs
* @mmsc{@ref BLE_GATTC_VALUE_READ_MSC}
* @endmscs
*
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
* @param[in] handle The handle of the attribute to be read.
* @param[in] offset Offset into the attribute value to be read.
*
* @retval ::NRF_SUCCESS Successfully started or resumed the Read (Long) procedure.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
* @retval ::NRF_ERROR_BUSY Client procedure already in progress.
*/
SVCALL(SD_BLE_GATTC_READ, uint32_t, sd_ble_gattc_read(uint16_t conn_handle, uint16_t handle, uint16_t offset));
/**@brief Initiate a GATT Read Multiple Characteristic Values procedure.
*
* @details This function initiates a GATT Read Multiple Characteristic Values procedure.
*
* @events
* @event{@ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP}
* @endevents
*
* @mscs
* @mmsc{@ref BLE_GATTC_READ_MULT_MSC}
* @endmscs
*
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
* @param[in] p_handles A pointer to the handle(s) of the attribute(s) to be read.
* @param[in] handle_count The number of handles in p_handles.
*
* @retval ::NRF_SUCCESS Successfully started the Read Multiple Characteristic Values procedure.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_BUSY Client procedure already in progress.
*/
SVCALL(SD_BLE_GATTC_CHAR_VALUES_READ, uint32_t, sd_ble_gattc_char_values_read(uint16_t conn_handle, uint16_t const *p_handles, uint16_t handle_count));
/**@brief Perform a Write (Characteristic Value or Descriptor, with or without response, signed or not, long or reliable) procedure.
*
* @details This function can perform all write procedures described in GATT.
*
* @note It is important to note that a write without response will <b>consume an application buffer</b>, and will therefore
* generate a @ref BLE_EVT_TX_COMPLETE event when the packet has been transmitted. A write (with response) on the other hand will use the
* standard client internal buffer and thus will only generate a @ref BLE_GATTC_EVT_WRITE_RSP event as soon as the write response
* has been received from the peer. Please see the documentation of @ref sd_ble_tx_packet_count_get for more details.
*
* @events
* @event{@ref BLE_GATTC_EVT_WRITE_RSP, Generated when using write request or queued writes.}
* @endevents
*
* @mscs
* @mmsc{@ref BLE_GATTC_VALUE_WRITE_MSC}
* @mmsc{@ref BLE_GATTC_VALUE_LONG_WRITE_MSC}
* @mmsc{@ref BLE_GATTC_VALUE_RELIABLE_WRITE_MSC}
* @mmsc{@ref BLE_COMMON_APP_BUFF_MSC}
* @endmscs
*
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
* @param[in] p_write_params A pointer to a write parameters structure.
*
* @retval ::NRF_SUCCESS Successfully started the Write procedure.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
* @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied.
* @retval ::NRF_ERROR_BUSY Procedure already in progress.
* @retval ::BLE_ERROR_NO_TX_PACKETS No available application packets for this connection.
*/
SVCALL(SD_BLE_GATTC_WRITE, uint32_t, sd_ble_gattc_write(uint16_t conn_handle, ble_gattc_write_params_t const *p_write_params));
/**@brief Send a Handle Value Confirmation to the GATT Server.
*
* @mscs
* @mmsc{@ref BLE_GATTC_HVI_MSC}
* @endmscs
*
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
* @param[in] handle The handle of the attribute in the indication.
*
* @retval ::NRF_SUCCESS Successfully queued the Handle Value Confirmation for transmission.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no Indication pending to be confirmed.
* @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle.
*/
SVCALL(SD_BLE_GATTC_HV_CONFIRM, uint32_t, sd_ble_gattc_hv_confirm(uint16_t conn_handle, uint16_t handle));
/**@brief Discovers information about a range of attributes on a GATT server.
*
* @events
* @event{@ref BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, Generated when information about a range of attributes has been received.}
* @endevents
*
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
* @param[in] p_handle_range The range of handles to request information about.
*
* @retval ::NRF_SUCCESS Successfully started an attribute information discovery procedure.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle.
* @retval ::NRF_ERROR_INVALID_STATE Invalid connection state
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_BUSY Client procedure already in progress.
*/
SVCALL(SD_BLE_GATTC_ATTR_INFO_DISCOVER, uint32_t, sd_ble_gattc_attr_info_discover(uint16_t conn_handle, ble_gattc_handle_range_t const * p_handle_range));
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* BLE_GATTC_H__ */
/**
@}
@}
*/

View File

@ -0,0 +1,722 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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.
*
*/
/**
@addtogroup BLE_GATTS Generic Attribute Profile (GATT) Server
@{
@brief Definitions and prototypes for the GATTS interface.
*/
#ifndef BLE_GATTS_H__
#define BLE_GATTS_H__
#include "ble_types.h"
#include "ble_ranges.h"
#include "ble_l2cap.h"
#include "ble_gap.h"
#include "ble_gatt.h"
#include "nrf_svc.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup BLE_GATTS_ENUMERATIONS Enumerations
* @{ */
/**
* @brief GATTS API SVC numbers.
*/
enum BLE_GATTS_SVCS
{
SD_BLE_GATTS_SERVICE_ADD = BLE_GATTS_SVC_BASE, /**< Add a service. */
SD_BLE_GATTS_INCLUDE_ADD, /**< Add an included service. */
SD_BLE_GATTS_CHARACTERISTIC_ADD, /**< Add a characteristic. */
SD_BLE_GATTS_DESCRIPTOR_ADD, /**< Add a generic attribute. */
SD_BLE_GATTS_VALUE_SET, /**< Set an attribute value. */
SD_BLE_GATTS_VALUE_GET, /**< Get an attribute value. */
SD_BLE_GATTS_HVX, /**< Handle Value Notification or Indication. */
SD_BLE_GATTS_SERVICE_CHANGED, /**< Perform a Service Changed Indication to one or more peers. */
SD_BLE_GATTS_RW_AUTHORIZE_REPLY, /**< Reply to an authorization request for a read or write operation on one or more attributes. */
SD_BLE_GATTS_SYS_ATTR_SET, /**< Set the persistent system attributes for a connection. */
SD_BLE_GATTS_SYS_ATTR_GET, /**< Retrieve the persistent system attributes. */
SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, /**< Retrieve the first valid user handle. */
SD_BLE_GATTS_ATTR_GET /**< Retrieve the UUID and/or metadata of an attribute. */
};
/**
* @brief GATT Server Event IDs.
*/
enum BLE_GATTS_EVTS
{
BLE_GATTS_EVT_WRITE = BLE_GATTS_EVT_BASE, /**< Write operation performed. \n See @ref ble_gatts_evt_write_t. */
BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST, /**< Read/Write Authorization request. \n Reply with @ref sd_ble_gatts_rw_authorize_reply. \n See @ref ble_gatts_evt_rw_authorize_request_t. */
BLE_GATTS_EVT_SYS_ATTR_MISSING, /**< A persistent system attribute access is pending. \n Respond with @ref sd_ble_gatts_sys_attr_set. \n See @ref ble_gatts_evt_sys_attr_missing_t. */
BLE_GATTS_EVT_HVC, /**< Handle Value Confirmation. \n See @ref ble_gatts_evt_hvc_t. */
BLE_GATTS_EVT_SC_CONFIRM, /**< Service Changed Confirmation. No additional event structure applies. */
BLE_GATTS_EVT_TIMEOUT /**< Peer failed to resonpond to an ATT request in time. \n See @ref ble_gatts_evt_timeout_t. */
};
/** @} */
/** @addtogroup BLE_GATTS_DEFINES Defines
* @{ */
/** @defgroup BLE_ERRORS_GATTS SVC return values specific to GATTS
* @{ */
#define BLE_ERROR_GATTS_INVALID_ATTR_TYPE (NRF_GATTS_ERR_BASE + 0x000) /**< Invalid attribute type. */
#define BLE_ERROR_GATTS_SYS_ATTR_MISSING (NRF_GATTS_ERR_BASE + 0x001) /**< System Attributes missing. */
/** @} */
/** @defgroup BLE_GATTS_ATTR_LENS_MAX Maximum attribute lengths
* @{ */
#define BLE_GATTS_FIX_ATTR_LEN_MAX (510) /**< Maximum length for fixed length Attribute Values. */
#define BLE_GATTS_VAR_ATTR_LEN_MAX (512) /**< Maximum length for variable length Attribute Values. */
/** @} */
/** @defgroup BLE_GATTS_SRVC_TYPES GATT Server Service Types
* @{ */
#define BLE_GATTS_SRVC_TYPE_INVALID 0x00 /**< Invalid Service Type. */
#define BLE_GATTS_SRVC_TYPE_PRIMARY 0x01 /**< Primary Service. */
#define BLE_GATTS_SRVC_TYPE_SECONDARY 0x02 /**< Secondary Type. */
/** @} */
/** @defgroup BLE_GATTS_ATTR_TYPES GATT Server Attribute Types
* @{ */
#define BLE_GATTS_ATTR_TYPE_INVALID 0x00 /**< Invalid Attribute Type. */
#define BLE_GATTS_ATTR_TYPE_PRIM_SRVC_DECL 0x01 /**< Primary Service Declaration. */
#define BLE_GATTS_ATTR_TYPE_SEC_SRVC_DECL 0x02 /**< Secondary Service Declaration. */
#define BLE_GATTS_ATTR_TYPE_INC_DECL 0x03 /**< Include Declaration. */
#define BLE_GATTS_ATTR_TYPE_CHAR_DECL 0x04 /**< Characteristic Declaration. */
#define BLE_GATTS_ATTR_TYPE_CHAR_VAL 0x05 /**< Characteristic Value. */
#define BLE_GATTS_ATTR_TYPE_DESC 0x06 /**< Descriptor. */
#define BLE_GATTS_ATTR_TYPE_OTHER 0x07 /**< Other, non-GATT specific type. */
/** @} */
/** @defgroup BLE_GATTS_OPS GATT Server Operations
* @{ */
#define BLE_GATTS_OP_INVALID 0x00 /**< Invalid Operation. */
#define BLE_GATTS_OP_WRITE_REQ 0x01 /**< Write Request. */
#define BLE_GATTS_OP_WRITE_CMD 0x02 /**< Write Command. */
#define BLE_GATTS_OP_SIGN_WRITE_CMD 0x03 /**< Signed Write Command. */
#define BLE_GATTS_OP_PREP_WRITE_REQ 0x04 /**< Prepare Write Request. */
#define BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL 0x05 /**< Execute Write Request: Cancel all prepared writes. */
#define BLE_GATTS_OP_EXEC_WRITE_REQ_NOW 0x06 /**< Execute Write Request: Immediately execute all prepared writes. */
/** @} */
/** @defgroup BLE_GATTS_VLOCS GATT Value Locations
* @{ */
#define BLE_GATTS_VLOC_INVALID 0x00 /**< Invalid Location. */
#define BLE_GATTS_VLOC_STACK 0x01 /**< Attribute Value is located in stack memory, no user memory is required. */
#define BLE_GATTS_VLOC_USER 0x02 /**< Attribute Value is located in user memory. This requires the user to maintain a valid buffer through the lifetime of the attribute, since the stack
will read and write directly to the memory using the pointer provided in the APIs. There are no alignment requirements for the buffer. */
/** @} */
/** @defgroup BLE_GATTS_AUTHORIZE_TYPES GATT Server Authorization Types
* @{ */
#define BLE_GATTS_AUTHORIZE_TYPE_INVALID 0x00 /**< Invalid Type. */
#define BLE_GATTS_AUTHORIZE_TYPE_READ 0x01 /**< Authorize a Read Operation. */
#define BLE_GATTS_AUTHORIZE_TYPE_WRITE 0x02 /**< Authorize a Write Request Operation. */
/** @} */
/** @defgroup BLE_GATTS_SYS_ATTR_FLAGS System Attribute Flags
* @{ */
#define BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS (1 << 0) /**< Restrict system attributes to system services only. */
#define BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS (1 << 1) /**< Restrict system attributes to user services only. */
/** @} */
/** @defgroup BLE_GATTS_ATTR_TAB_SIZE Attribute Table size
* @{
*/
#define BLE_GATTS_ATTR_TAB_SIZE_MIN 216 /**< Minimum Attribute Table size */
#define BLE_GATTS_ATTR_TAB_SIZE_DEFAULT 0x0000 /**< Default Attribute Table size (0x580 bytes for this version of the SoftDevice). */
/** @} */
/** @} */
/** @addtogroup BLE_GATTS_STRUCTURES Structures
* @{ */
/**
* @brief BLE GATTS initialization parameters.
*/
typedef struct
{
uint8_t service_changed:1; /**< Include the Service Changed characteristic in the Attribute Table. */
uint32_t attr_tab_size; /**< Attribute Table size in bytes. The size must be a multiple of 4. @ref BLE_GATTS_ATTR_TAB_SIZE_DEFAULT is used to set the default size. */
} ble_gatts_enable_params_t;
/**@brief Attribute metadata. */
typedef struct
{
ble_gap_conn_sec_mode_t read_perm; /**< Read permissions. */
ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */
uint8_t vlen :1; /**< Variable length attribute. */
uint8_t vloc :2; /**< Value location, see @ref BLE_GATTS_VLOCS.*/
uint8_t rd_auth :1; /**< Read authorization and value will be requested from the application on every read operation. */
uint8_t wr_auth :1; /**< Write authorization will be requested from the application on every Write Request operation (but not Write Command). */
} ble_gatts_attr_md_t;
/**@brief GATT Attribute. */
typedef struct
{
ble_uuid_t *p_uuid; /**< Pointer to the attribute UUID. */
ble_gatts_attr_md_t *p_attr_md; /**< Pointer to the attribute metadata structure. */
uint16_t init_len; /**< Initial attribute value length in bytes. */
uint16_t init_offs; /**< Initial attribute value offset in bytes. If different from zero, the first init_offs bytes of the attribute value will be left uninitialized. */
uint16_t max_len; /**< Maximum attribute value length in bytes, see @ref BLE_GATTS_ATTR_LENS_MAX for maximum values. */
uint8_t* p_value; /**< Pointer to the attribute data. Please note that if the @ref BLE_GATTS_VLOC_USER value location is selected in the attribute metadata, this will have to point to a buffer
that remains valid through the lifetime of the attribute. This excludes usage of automatic variables that may go out of scope or any other temporary location.
The stack may access that memory directly without the application's knowledge. For writable characteristics, this value must not be a location in flash memory.*/
} ble_gatts_attr_t;
/**@brief GATT Attribute Value. */
typedef struct
{
uint16_t len; /**< Length in bytes to be written or read. Length in bytes written or read after successful return.*/
uint16_t offset; /**< Attribute value offset. */
uint8_t *p_value; /**< Pointer to where value is stored or will be stored.
If value is stored in user memory, only the attribute length is updated when p_value == NULL.
Set to NULL when reading to obtain the complete length of the attribute value */
} ble_gatts_value_t;
/**@brief GATT Characteristic Presentation Format. */
typedef struct
{
uint8_t format; /**< Format of the value, see @ref BLE_GATT_CPF_FORMATS. */
int8_t exponent; /**< Exponent for integer data types. */
uint16_t unit; /**< Unit from Bluetooth Assigned Numbers. */
uint8_t name_space; /**< Namespace from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */
uint16_t desc; /**< Namespace description from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */
} ble_gatts_char_pf_t;
/**@brief GATT Characteristic metadata. */
typedef struct
{
ble_gatt_char_props_t char_props; /**< Characteristic Properties. */
ble_gatt_char_ext_props_t char_ext_props; /**< Characteristic Extended Properties. */
uint8_t *p_char_user_desc; /**< Pointer to a UTF-8 encoded string (non-NULL terminated), NULL if the descriptor is not required. */
uint16_t char_user_desc_max_size; /**< The maximum size in bytes of the user description descriptor. */
uint16_t char_user_desc_size; /**< The size of the user description, must be smaller or equal to char_user_desc_max_size. */
ble_gatts_char_pf_t* p_char_pf; /**< Pointer to a presentation format structure or NULL if the CPF descriptor is not required. */
ble_gatts_attr_md_t* p_user_desc_md; /**< Attribute metadata for the User Description descriptor, or NULL for default values. */
ble_gatts_attr_md_t* p_cccd_md; /**< Attribute metadata for the Client Characteristic Configuration Descriptor, or NULL for default values. */
ble_gatts_attr_md_t* p_sccd_md; /**< Attribute metadata for the Server Characteristic Configuration Descriptor, or NULL for default values. */
} ble_gatts_char_md_t;
/**@brief GATT Characteristic Definition Handles. */
typedef struct
{
uint16_t value_handle; /**< Handle to the characteristic value. */
uint16_t user_desc_handle; /**< Handle to the User Description descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */
uint16_t cccd_handle; /**< Handle to the Client Characteristic Configuration Descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */
uint16_t sccd_handle; /**< Handle to the Server Characteristic Configuration Descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */
} ble_gatts_char_handles_t;
/**@brief GATT HVx parameters. */
typedef struct
{
uint16_t handle; /**< Characteristic Value Handle. */
uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */
uint16_t offset; /**< Offset within the attribute value. */
uint16_t *p_len; /**< Length in bytes to be written, length in bytes written after successful return. */
uint8_t *p_data; /**< Actual data content, use NULL to use the current attribute value. */
} ble_gatts_hvx_params_t;
/**@brief GATT Authorization parameters. */
typedef struct
{
uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */
uint8_t update : 1; /**< If set, data supplied in p_data will be used to update the attribute value.
Please note that for @ref BLE_GATTS_OP_WRITE_REQ operations this bit must always be set,
as the data to be written needs to be stored and later provided by the application. */
uint16_t offset; /**< Offset of the attribute value being updated. */
uint16_t len; /**< Length in bytes of the value in p_data pointer, see @ref BLE_GATTS_ATTR_LENS_MAX. */
const uint8_t *p_data; /**< Pointer to new value used to update the attribute value. */
} ble_gatts_authorize_params_t;
/**@brief GATT Read or Write Authorize Reply parameters. */
typedef struct
{
uint8_t type; /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */
union {
ble_gatts_authorize_params_t read; /**< Read authorization parameters. */
ble_gatts_authorize_params_t write; /**< Write authorization parameters. */
} params; /**< Reply Parameters. */
} ble_gatts_rw_authorize_reply_params_t;
/**@brief Event structure for @ref BLE_GATTS_EVT_WRITE. */
typedef struct
{
uint16_t handle; /**< Attribute Handle. */
ble_uuid_t uuid; /**< Attribute UUID. */
uint8_t op; /**< Type of write operation, see @ref BLE_GATTS_OPS. */
uint8_t auth_required; /**< Writing operation deferred due to authorization requirement. Application may use @ref sd_ble_gatts_value_set to finalise the writing operation. */
uint16_t offset; /**< Offset for the write operation. */
uint16_t len; /**< Length of the received data. */
uint8_t data[1]; /**< Received data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
} ble_gatts_evt_write_t;
/**@brief Event substructure for authorized read requests, see @ref ble_gatts_evt_rw_authorize_request_t. */
typedef struct
{
uint16_t handle; /**< Attribute Handle. */
ble_uuid_t uuid; /**< Attribute UUID. */
uint16_t offset; /**< Offset for the read operation. */
} ble_gatts_evt_read_t;
/**@brief Event structure for @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST. */
typedef struct
{
uint8_t type; /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */
union {
ble_gatts_evt_read_t read; /**< Attribute Read Parameters. */
ble_gatts_evt_write_t write; /**< Attribute Write Parameters. */
} request; /**< Request Parameters. */
} ble_gatts_evt_rw_authorize_request_t;
/**@brief Event structure for @ref BLE_GATTS_EVT_SYS_ATTR_MISSING. */
typedef struct
{
uint8_t hint; /**< Hint (currently unused). */
} ble_gatts_evt_sys_attr_missing_t;
/**@brief Event structure for @ref BLE_GATTS_EVT_HVC. */
typedef struct
{
uint16_t handle; /**< Attribute Handle. */
} ble_gatts_evt_hvc_t;
/**@brief Event structure for @ref BLE_GATTS_EVT_TIMEOUT. */
typedef struct
{
uint8_t src; /**< Timeout source, see @ref BLE_GATT_TIMEOUT_SOURCES. */
} ble_gatts_evt_timeout_t;
/**@brief GATT Server event callback event structure. */
typedef struct
{
uint16_t conn_handle; /**< Connection Handle on which the event occurred. */
union
{
ble_gatts_evt_write_t write; /**< Write Event Parameters. */
ble_gatts_evt_rw_authorize_request_t authorize_request; /**< Read or Write Authorize Request Parameters. */
ble_gatts_evt_sys_attr_missing_t sys_attr_missing; /**< System attributes missing. */
ble_gatts_evt_hvc_t hvc; /**< Handle Value Confirmation Event Parameters. */
ble_gatts_evt_timeout_t timeout; /**< Timeout Event. */
} params; /**< Event Parameters. */
} ble_gatts_evt_t;
/** @} */
/** @addtogroup BLE_GATTS_FUNCTIONS Functions
* @{ */
/**@brief Add a service declaration to the Attribute Table.
*
* @note Secondary Services are only relevant in the context of the entity that references them, it is therefore forbidden to
* add a secondary service declaration that is not referenced by another service later in the Attribute Table.
*
* @mscs
* @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC}
* @endmscs
*
* @param[in] type Toggles between primary and secondary services, see @ref BLE_GATTS_SRVC_TYPES.
* @param[in] p_uuid Pointer to service UUID.
* @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored.
*
* @retval ::NRF_SUCCESS Successfully added a service declaration.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, Vendor Specific UUIDs need to be present in the table.
* @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack.
* @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
*/
SVCALL(SD_BLE_GATTS_SERVICE_ADD, uint32_t, sd_ble_gatts_service_add(uint8_t type, ble_uuid_t const *p_uuid, uint16_t *p_handle));
/**@brief Add an include declaration to the Attribute Table.
*
* @note It is currently only possible to add an include declaration to the last added service (i.e. only sequential population is supported at this time).
*
* @note The included service must already be present in the Attribute Table prior to this call.
*
* @mscs
* @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC}
* @endmscs
*
* @param[in] service_handle Handle of the service where the included service is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially.
* @param[in] inc_srvc_handle Handle of the included service.
* @param[out] p_include_handle Pointer to a 16-bit word where the assigned handle will be stored.
*
* @retval ::NRF_SUCCESS Successfully added an include declaration.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, handle values need to match previously added services.
* @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
* @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, self inclusions are not allowed.
* @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
* @retval ::NRF_ERROR_NOT_FOUND Attribute not found.
*/
SVCALL(SD_BLE_GATTS_INCLUDE_ADD, uint32_t, sd_ble_gatts_include_add(uint16_t service_handle, uint16_t inc_srvc_handle, uint16_t *p_include_handle));
/**@brief Add a characteristic declaration, a characteristic value declaration and optional characteristic descriptor declarations to the Attribute Table.
*
* @note It is currently only possible to add a characteristic to the last added service (i.e. only sequential population is supported at this time).
*
* @note Several restrictions apply to the parameters, such as matching permissions between the user description descriptor and the writeable auxiliaries bits,
* readable (no security) and writeable (selectable) CCCDs and SCCDs and valid presentation format values.
*
* @note If no metadata is provided for the optional descriptors, their permissions will be derived from the characteristic permissions.
*
* @mscs
* @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC}
* @endmscs
*
* @param[in] service_handle Handle of the service where the characteristic is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially.
* @param[in] p_char_md Characteristic metadata.
* @param[in] p_attr_char_value Pointer to the attribute structure corresponding to the characteristic value.
* @param[out] p_handles Pointer to the structure where the assigned handles will be stored.
*
* @retval ::NRF_SUCCESS Successfully added a characteristic.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, service handle, Vendor Specific UUIDs, lengths, and permissions need to adhere to the constraints.
* @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a service context is required.
* @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack.
* @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
* @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX.
*/
SVCALL(SD_BLE_GATTS_CHARACTERISTIC_ADD, uint32_t, sd_ble_gatts_characteristic_add(uint16_t service_handle, ble_gatts_char_md_t const *p_char_md, ble_gatts_attr_t const *p_attr_char_value, ble_gatts_char_handles_t *p_handles));
/**@brief Add a descriptor to the Attribute Table.
*
* @note It is currently only possible to add a descriptor to the last added characteristic (i.e. only sequential population is supported at this time).
*
* @mscs
* @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC}
* @endmscs
*
* @param[in] char_handle Handle of the characteristic where the descriptor is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially.
* @param[in] p_attr Pointer to the attribute structure.
* @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored.
*
* @retval ::NRF_SUCCESS Successfully added a descriptor.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, characteristic handle, Vendor Specific UUIDs, lengths, and permissions need to adhere to the constraints.
* @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a characteristic context is required.
* @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack.
* @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
* @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX.
*/
SVCALL(SD_BLE_GATTS_DESCRIPTOR_ADD, uint32_t, sd_ble_gatts_descriptor_add(uint16_t char_handle, ble_gatts_attr_t const *p_attr, uint16_t *p_handle));
/**@brief Set the value of a given attribute.
*
* @note Values other than system attributes can be set at any time, regardless of wheter any active connections exist.
*
* @mscs
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC}
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC}
* @endmscs
*
* @param[in] conn_handle Connection handle. If the value does not belong to a system attribute then @ref BLE_CONN_HANDLE_INVALID can be used.
* @param[in] handle Attribute handle.
* @param[in,out] p_value Attribute value information.
*
* @retval ::NRF_SUCCESS Successfully set the value of the attribute.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
* @retval ::NRF_ERROR_NOT_FOUND Attribute not found.
* @retval ::NRF_ERROR_FORBIDDEN Forbidden handle supplied, certain attributes are not modifiable by the application.
* @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
* @retval ::BLE_ERROR_GATTS_INVALID_ATTR_TYPE @ref BLE_CONN_HANDLE_INVALID supplied on a system attribute.
*/
SVCALL(SD_BLE_GATTS_VALUE_SET, uint32_t, sd_ble_gatts_value_set(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value));
/**@brief Get the value of a given attribute.
*
* @note If the attribute value is longer than the size of the supplied buffer,
* p_len will return the total attribute value length (excluding offset),
* and not the number of bytes actually returned in p_data.
* The application may use this information to allocate a suitable buffer size.
*
* @note When retrieving system attribute values with this function, the connection handle
* may refer to an already disconnected connection. Refer to the documentation of
* @ref sd_ble_gatts_sys_attr_get for further information.
*
* @param[in] conn_handle Connection handle. If the value does not belong to a system attribute then @ref BLE_CONN_HANDLE_INVALID can be used.
* @param[in] handle Attribute handle.
* @param[in,out] p_value Attribute value information.
*
* @retval ::NRF_SUCCESS Successfully retrieved the value of the attribute.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_NOT_FOUND Attribute not found.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid attribute offset supplied.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
* @retval ::BLE_ERROR_GATTS_INVALID_ATTR_TYPE @ref BLE_CONN_HANDLE_INVALID supplied on a system attribute.
*/
SVCALL(SD_BLE_GATTS_VALUE_GET, uint32_t, sd_ble_gatts_value_get(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value));
/**@brief Notify or Indicate an attribute value.
*
* @details This function checks for the relevant Client Characteristic Configuration descriptor value to verify that the relevant operation
* (notification or indication) has been enabled by the client. It is also able to update the attribute value before issuing the PDU, so that
* the application can atomically perform a value update and a server initiated transaction with a single API call.
* If the application chooses to indicate an attribute value, a @ref BLE_GATTS_EVT_HVC event will be issued as soon as the confirmation arrives from
* the peer.
*
* @note The local attribute value may be updated even if an outgoing packet is not sent to the peer due to an error during execution.
* When receiveing the error codes @ref NRF_ERROR_INVALID_STATE, @ref NRF_ERROR_BUSY, @ref BLE_ERROR_GATTS_SYS_ATTR_MISSING and
* @ref BLE_ERROR_NO_TX_PACKETS the Attribute Table has been updated.
* The caller can check whether the value has been updated by looking at the contents of *(p_hvx_params->p_len).
*
* @note It is important to note that a notification will <b>consume an application buffer</b>, and will therefore
* generate a @ref BLE_EVT_TX_COMPLETE event when the packet has been transmitted. An indication on the other hand will use the
* standard server internal buffer and thus will only generate a @ref BLE_GATTS_EVT_HVC event as soon as the confirmation
* has been received from the peer. Please see the documentation of @ref sd_ble_tx_packet_count_get for more details.
*
* @events
* @event{@ref BLE_EVT_TX_COMPLETE, Transmission complete.}
* @event{@ref BLE_GATTS_EVT_HVC, Confirmation received from peer.}
* @endevents
*
* @mscs
* @mmsc{@ref BLE_GATTS_HVX_SYS_ATTRS_MISSING_MSC}
* @mmsc{@ref BLE_GATTS_HVN_MSC}
* @mmsc{@ref BLE_GATTS_HVI_MSC}
* @mmsc{@ref BLE_GATTS_HVX_DISABLED_MSC}
* @mmsc{@ref BLE_COMMON_APP_BUFF_MSC}
* @endmscs
*
* @param[in] conn_handle Connection handle.
* @param[in] p_hvx_params Pointer to an HVx parameters structure. If the p_data member contains a non-NULL pointer the attribute value will be updated with
* the contents pointed by it before sending the notification or indication.
*
* @retval ::NRF_SUCCESS Successfully queued a notification or indication for transmission, and optionally updated the attribute value.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or notifications and/or indications not enabled in the CCCD.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
* @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied. Only attributes added directly by the application are available to notify and indicate.
* @retval ::BLE_ERROR_GATTS_INVALID_ATTR_TYPE Invalid attribute type(s) supplied, only characteristic values may be notified and indicated.
* @retval ::NRF_ERROR_NOT_FOUND Attribute not found.
* @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied.
* @retval ::NRF_ERROR_BUSY Procedure already in progress.
* @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value.
* @retval ::BLE_ERROR_NO_TX_PACKETS No available application packets for this connection, applies only to notifications.
*/
SVCALL(SD_BLE_GATTS_HVX, uint32_t, sd_ble_gatts_hvx(uint16_t conn_handle, ble_gatts_hvx_params_t const *p_hvx_params));
/**@brief Indicate the Service Changed attribute value.
*
* @details This call will send a Handle Value Indication to one or more peers connected to inform them that the Attribute
* Table layout has changed. As soon as the peer has confirmed the indication, a @ref BLE_GATTS_EVT_SC_CONFIRM event will
* be issued.
*
* @note Some of the restrictions and limitations that apply to @ref sd_ble_gatts_hvx also apply here.
*
* @events
* @event{@ref BLE_GATTS_EVT_SC_CONFIRM, Confirmation of attribute table change received from peer.}
* @endevents
*
* @mscs
* @mmsc{@ref BLE_GATTS_SC_MSC}
* @endmscs
*
* @param[in] conn_handle Connection handle.
* @param[in] start_handle Start of affected attribute handle range.
* @param[in] end_handle End of affected attribute handle range.
*
* @retval ::NRF_SUCCESS Successfully queued the Service Changed indication for transmission.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_NOT_SUPPORTED Service Changed not enabled at initialization. See @ref sd_ble_enable and @ref ble_gatts_enable_params_t.
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or notifications and/or indications not enabled in the CCCD.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
* @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied, handles must be in the range populated by the application.
* @retval ::NRF_ERROR_BUSY Procedure already in progress.
* @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value.
*/
SVCALL(SD_BLE_GATTS_SERVICE_CHANGED, uint32_t, sd_ble_gatts_service_changed(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle));
/**@brief Respond to a Read/Write authorization request.
*
* @note This call should only be used as a response to a @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event issued to the application.
*
* @mscs
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC}
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC}
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC}
* @mmsc{@ref BLE_GATTS_READ_REQ_AUTH_MSC}
* @mmsc{@ref BLE_GATTS_WRITE_REQ_AUTH_MSC}
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC}
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_PEER_CANCEL_MSC}
* @endmscs
*
* @param[in] conn_handle Connection handle.
* @param[in] p_rw_authorize_reply_params Pointer to a structure with the attribute provided by the application.
*
* @retval ::NRF_SUCCESS Successfully queued a response to the peer, and in the case of a write operation, Attribute Table updated.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no authorization request pending.
* @retval ::NRF_ERROR_INVALID_PARAM Authorization op invalid,
* handle supplied does not match requested handle,
* or invalid data to be written provided by the application.
* @retval ::NRF_ERROR_BUSY The stack is busy. Retry at later time.
*/
SVCALL(SD_BLE_GATTS_RW_AUTHORIZE_REPLY, uint32_t, sd_ble_gatts_rw_authorize_reply(uint16_t conn_handle, ble_gatts_rw_authorize_reply_params_t const *p_rw_authorize_reply_params));
/**@brief Update persistent system attribute information.
*
* @details Supply information about persistent system attributes to the stack,
* previously obtained using @ref sd_ble_gatts_sys_attr_get.
* This call is only allowed for active connections, and is usually
* made immediately after a connection is established with an known bonded device,
* often as a response to a @ref BLE_GATTS_EVT_SYS_ATTR_MISSING.
*
* p_sysattrs may point directly to the application's stored copy of the system attributes
* obtained using @ref sd_ble_gatts_sys_attr_get.
* If the pointer is NULL, the system attribute info is initialized, assuming that
* the application does not have any previously saved system attribute data for this device.
*
* @note The state of persistent system attributes is reset upon connection establishment and then remembered for its duration.
*
* @note If this call returns with an error code different from @ref NRF_SUCCESS, the storage of persistent system attributes may have been completed only partially.
* This means that the state of the attribute table is undefined, and the application should either provide a new set of attributes using this same call or
* reset the SoftDevice to return to a known state.
*
* @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be modified.
* @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user services will be modified.
*
* @mscs
* @mmsc{@ref BLE_GATTS_HVX_SYS_ATTRS_MISSING_MSC}
* @mmsc{@ref BLE_GATTS_SYS_ATTRS_UNK_PEER_MSC}
* @mmsc{@ref BLE_GATTS_SYS_ATTRS_BONDED_PEER_MSC}
* @endmscs
*
* @param[in] conn_handle Connection handle.
* @param[in] p_sys_attr_data Pointer to a saved copy of system attributes supplied to the stack, or NULL.
* @param[in] len Size of data pointed by p_sys_attr_data, in octets.
* @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS
*
* @retval ::NRF_SUCCESS Successfully set the system attribute information.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
* @retval ::NRF_ERROR_INVALID_DATA Invalid data supplied, the data should be exactly the same as retrieved with @ref sd_ble_gatts_sys_attr_get.
* @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
* @retval ::NRF_ERROR_BUSY The stack is busy. Retry at later time.
*/
SVCALL(SD_BLE_GATTS_SYS_ATTR_SET, uint32_t, sd_ble_gatts_sys_attr_set(uint16_t conn_handle, uint8_t const *p_sys_attr_data, uint16_t len, uint32_t flags));
/**@brief Retrieve persistent system attribute information from the stack.
*
* @details This call is used to retrieve information about values to be stored perisistently by the application
* during the lifetime of a connection or after it has been terminated. When a new connection is established with the same bonded device,
* the system attribute information retrieved with this function should be restored using using @ref sd_ble_gatts_sys_attr_set.
* If retrieved after disconnection, the data should be read before a new connection established. The connection handle for
* the previous, now disconnected, connection will remain valid until a new one is created to allow this API call to refer to it.
* Connection handles belonging to active connections can be used as well, but care should be taken since the system attributes
* may be written to at any time by the peer during a connection's lifetime.
*
* @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be returned.
* @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user services will be returned.
*
* @mscs
* @mmsc{@ref BLE_GATTS_SYS_ATTRS_BONDED_PEER_MSC}
* @endmscs
*
* @param[in] conn_handle Connection handle of the recently terminated connection.
* @param[out] p_sys_attr_data Pointer to a buffer where updated information about system attributes will be filled in. The format of the data is described
* in @ref BLE_GATTS_SYS_ATTRS_FORMAT. NULL can be provided to obtain the length of the data.
* @param[in,out] p_len Size of application buffer if p_sys_attr_data is not NULL. Unconditially updated to actual length of system attribute data.
* @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS
*
* @retval ::NRF_SUCCESS Successfully retrieved the system attribute information.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_DATA_SIZE The system attribute information did not fit into the provided buffer.
* @retval ::NRF_ERROR_NOT_FOUND No system attributes found.
*/
SVCALL(SD_BLE_GATTS_SYS_ATTR_GET, uint32_t, sd_ble_gatts_sys_attr_get(uint16_t conn_handle, uint8_t *p_sys_attr_data, uint16_t *p_len, uint32_t flags));
/**@brief Retrieve the first valid user attribute handle.
*
* @param[out] p_handle Pointer to an integer where the handle will be stored.
*
* @retval ::NRF_SUCCESS Successfully retrieved the handle.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
*/
SVCALL(SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, uint32_t, sd_ble_gatts_initial_user_handle_get(uint16_t *p_handle));
/**@brief Retrieve the attribute UUID and/or metadata.
*
* @param[in] handle Attribute handle
* @param[out] p_uuid UUID of the attribute. Use NULL to omit this field.
* @param[out] p_md Metadata of the attribute. Use NULL to omit this field.
*
* @retval ::NRF_SUCCESS Successfully retrieved the attribute metadata,
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameters supplied. Returned when both @c p_uuid and @c p_md are NULL.
* @retval ::NRF_ERROR_NOT_FOUND Attribute was not found.
*/
SVCALL(SD_BLE_GATTS_ATTR_GET, uint32_t, sd_ble_gatts_attr_get(uint16_t handle, ble_uuid_t * p_uuid, ble_gatts_attr_md_t * p_md));
/** @} */
#ifdef __cplusplus
}
#endif
#endif // BLE_GATTS_H__
/**
@}
*/

View File

@ -0,0 +1,131 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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.
*
*/
/**
@addtogroup BLE_COMMON
@{
*/
#ifndef BLE_HCI_H__
#define BLE_HCI_H__
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup BLE_HCI_STATUS_CODES Bluetooth status codes
* @{ */
#define BLE_HCI_STATUS_CODE_SUCCESS 0x00 /**< Success. */
#define BLE_HCI_STATUS_CODE_UNKNOWN_BTLE_COMMAND 0x01 /**< Unknown BLE Command. */
#define BLE_HCI_STATUS_CODE_UNKNOWN_CONNECTION_IDENTIFIER 0x02 /**< Unknown Connection Identifier. */
/*0x03 Hardware Failure
0x04 Page Timeout
*/
#define BLE_HCI_AUTHENTICATION_FAILURE 0x05 /**< Authentication Failure. */
#define BLE_HCI_STATUS_CODE_PIN_OR_KEY_MISSING 0x06 /**< Pin or Key missing. */
#define BLE_HCI_MEMORY_CAPACITY_EXCEEDED 0x07 /**< Memory Capacity Exceeded. */
#define BLE_HCI_CONNECTION_TIMEOUT 0x08 /**< Connection Timeout. */
/*0x09 Connection Limit Exceeded
0x0A Synchronous Connection Limit To A Device Exceeded
0x0B ACL Connection Already Exists*/
#define BLE_HCI_STATUS_CODE_COMMAND_DISALLOWED 0x0C /**< Command Disallowed. */
/*0x0D Connection Rejected due to Limited Resources
0x0E Connection Rejected Due To Security Reasons
0x0F Connection Rejected due to Unacceptable BD_ADDR
0x10 Connection Accept Timeout Exceeded
0x11 Unsupported Feature or Parameter Value*/
#define BLE_HCI_STATUS_CODE_INVALID_BTLE_COMMAND_PARAMETERS 0x12 /**< Invalid BLE Command Parameters. */
#define BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION 0x13 /**< Remote User Terminated Connection. */
#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES 0x14 /**< Remote Device Terminated Connection due to low resources.*/
#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF 0x15 /**< Remote Device Terminated Connection due to power off. */
#define BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION 0x16 /**< Local Host Terminated Connection. */
/*
0x17 Repeated Attempts
0x18 Pairing Not Allowed
0x19 Unknown LMP PDU
*/
#define BLE_HCI_UNSUPPORTED_REMOTE_FEATURE 0x1A /**< Unsupported Remote Feature. */
/*
0x1B SCO Offset Rejected
0x1C SCO Interval Rejected
0x1D SCO Air Mode Rejected*/
#define BLE_HCI_STATUS_CODE_INVALID_LMP_PARAMETERS 0x1E /**< Invalid LMP Parameters. */
#define BLE_HCI_STATUS_CODE_UNSPECIFIED_ERROR 0x1F /**< Unspecified Error. */
/*0x20 Unsupported LMP Parameter Value
0x21 Role Change Not Allowed
*/
#define BLE_HCI_STATUS_CODE_LMP_RESPONSE_TIMEOUT 0x22 /**< LMP Response Timeout. */
/*0x23 LMP Error Transaction Collision*/
#define BLE_HCI_STATUS_CODE_LMP_PDU_NOT_ALLOWED 0x24 /**< LMP PDU Not Allowed. */
/*0x25 Encryption Mode Not Acceptable
0x26 Link Key Can Not be Changed
0x27 Requested QoS Not Supported
*/
#define BLE_HCI_INSTANT_PASSED 0x28 /**< Instant Passed. */
#define BLE_HCI_PAIRING_WITH_UNIT_KEY_UNSUPPORTED 0x29 /**< Pairing with Unit Key Unsupported. */
#define BLE_HCI_DIFFERENT_TRANSACTION_COLLISION 0x2A /**< Different Transaction Collision. */
/*
0x2B Reserved
0x2C QoS Unacceptable Parameter
0x2D QoS Rejected
0x2E Channel Classification Not Supported
0x2F Insufficient Security
0x30 Parameter Out Of Mandatory Range
0x31 Reserved
0x32 Role Switch Pending
0x33 Reserved
0x34 Reserved Slot Violation
0x35 Role Switch Failed
0x36 Extended Inquiry Response Too Large
0x37 Secure Simple Pairing Not Supported By Host.
0x38 Host Busy - Pairing
0x39 Connection Rejected due to No Suitable Channel Found*/
#define BLE_HCI_CONTROLLER_BUSY 0x3A /**< Controller Busy. */
#define BLE_HCI_CONN_INTERVAL_UNACCEPTABLE 0x3B /**< Connection Interval Unacceptable. */
#define BLE_HCI_DIRECTED_ADVERTISER_TIMEOUT 0x3C /**< Directed Adverisement Timeout. */
#define BLE_HCI_CONN_TERMINATED_DUE_TO_MIC_FAILURE 0x3D /**< Connection Terminated due to MIC Failure. */
#define BLE_HCI_CONN_FAILED_TO_BE_ESTABLISHED 0x3E /**< Connection Failed to be Established. */
/** @} */
#ifdef __cplusplus
}
#endif
#endif // BLE_HCI_H__
/** @} */

View File

@ -0,0 +1,202 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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.
*
*/
/**
@addtogroup BLE_L2CAP Logical Link Control and Adaptation Protocol (L2CAP)
@{
@brief Definitions and prototypes for the L2CAP interface.
*/
#ifndef BLE_L2CAP_H__
#define BLE_L2CAP_H__
#include "ble_types.h"
#include "ble_ranges.h"
#include "ble_err.h"
#include "nrf_svc.h"
#ifdef __cplusplus
extern "C" {
#endif
/**@addtogroup BLE_L2CAP_ENUMERATIONS Enumerations
* @{ */
/**@brief L2CAP API SVC numbers. */
enum BLE_L2CAP_SVCS
{
SD_BLE_L2CAP_CID_REGISTER = BLE_L2CAP_SVC_BASE, /**< Register a CID. */
SD_BLE_L2CAP_CID_UNREGISTER, /**< Unregister a CID. */
SD_BLE_L2CAP_TX /**< Transmit a packet. */
};
/**@brief L2CAP Event IDs. */
enum BLE_L2CAP_EVTS
{
BLE_L2CAP_EVT_RX = BLE_L2CAP_EVT_BASE /**< L2CAP packet received. */
};
/** @} */
/**@addtogroup BLE_L2CAP_DEFINES Defines
* @{ */
/**@defgroup BLE_ERRORS_L2CAP SVC return values specific to L2CAP
* @{ */
#define BLE_ERROR_L2CAP_CID_IN_USE (NRF_L2CAP_ERR_BASE + 0x000) /**< CID already in use. */
/** @} */
/**@brief Default L2CAP MTU. */
#define BLE_L2CAP_MTU_DEF (23)
/**@brief Invalid Channel Identifier. */
#define BLE_L2CAP_CID_INVALID (0x0000)
/**@brief Dynamic Channel Identifier base. */
#define BLE_L2CAP_CID_DYN_BASE (0x0040)
/**@brief Maximum amount of dynamic CIDs. */
#define BLE_L2CAP_CID_DYN_MAX (8)
/** @} */
/**@addtogroup BLE_L2CAP_STRUCTURES Structures
* @{ */
/**@brief Packet header format for L2CAP transmission. */
typedef struct
{
uint16_t len; /**< Length of valid info in data member. */
uint16_t cid; /**< Channel ID on which packet is transmitted. */
} ble_l2cap_header_t;
/**@brief L2CAP Received packet event report. */
typedef struct
{
ble_l2cap_header_t header; /**< L2CAP packet header. */
uint8_t data[1]; /**< Packet data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
} ble_l2cap_evt_rx_t;
/**@brief L2CAP event callback event structure. */
typedef struct
{
uint16_t conn_handle; /**< Connection Handle on which event occured. */
union
{
ble_l2cap_evt_rx_t rx; /**< RX Event parameters. */
} params; /**< Event Parameters. */
} ble_l2cap_evt_t;
/** @} */
/**@addtogroup BLE_L2CAP_FUNCTIONS Functions
* @{ */
/**@brief Register a CID with L2CAP.
*
* @details This registers a higher protocol layer with the L2CAP multiplexer, and is requried prior to all operations on the CID.
*
* @mscs
* @mmsc{@ref BLE_L2CAP_API_MSC}
* @endmscs
*
* @param[in] cid L2CAP CID.
*
* @retval ::NRF_SUCCESS Successfully registered a CID with the L2CAP layer.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, CID must be above @ref BLE_L2CAP_CID_DYN_BASE.
* @retval ::BLE_ERROR_L2CAP_CID_IN_USE L2CAP CID already in use.
* @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
*/
SVCALL(SD_BLE_L2CAP_CID_REGISTER, uint32_t, sd_ble_l2cap_cid_register(uint16_t cid));
/**@brief Unregister a CID with L2CAP.
*
* @details This unregisters a previously registerd higher protocol layer with the L2CAP multiplexer.
*
* @mscs
* @mmsc{@ref BLE_L2CAP_API_MSC}
* @endmscs
*
* @param[in] cid L2CAP CID.
*
* @retval ::NRF_SUCCESS Successfully unregistered the CID.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
* @retval ::NRF_ERROR_NOT_FOUND CID not previously registered.
*/
SVCALL(SD_BLE_L2CAP_CID_UNREGISTER, uint32_t, sd_ble_l2cap_cid_unregister(uint16_t cid));
/**@brief Transmit an L2CAP packet.
*
* @note It is important to note that a call to this function will <b>consume an application packet</b>, and will therefore
* generate a @ref BLE_EVT_TX_COMPLETE event when the packet has been transmitted.
* Please see the documentation of @ref sd_ble_tx_packet_count_get for more details.
*
* @events
* @event{@ref BLE_EVT_TX_COMPLETE}
* @event{@ref BLE_L2CAP_EVT_RX}
* @endevents
*
* @mscs
* @mmsc{@ref BLE_L2CAP_API_MSC}
* @endmscs
*
* @param[in] conn_handle Connection Handle.
* @param[in] p_header Pointer to a packet header containing length and CID.
* @param[in] p_data Pointer to the data to be transmitted.
*
* @retval ::NRF_SUCCESS Successfully queued an L2CAP packet for transmission.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, CIDs must be registered beforehand with @ref sd_ble_l2cap_cid_register.
* @retval ::NRF_ERROR_NOT_FOUND CID not found.
* @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
* @retval ::BLE_ERROR_NO_TX_PACKETS Not enough application packets available.
* @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, see @ref BLE_L2CAP_MTU_DEF.
*/
SVCALL(SD_BLE_L2CAP_TX, uint32_t, sd_ble_l2cap_tx(uint16_t conn_handle, ble_l2cap_header_t const *p_header, uint8_t const *p_data));
/** @} */
#ifdef __cplusplus
}
#endif
#endif // BLE_L2CAP_H__
/**
@}
*/

View File

@ -0,0 +1,126 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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.
*
*/
/**
@addtogroup BLE_COMMON
@{
@defgroup ble_ranges Module specific SVC, event and option number subranges
@{
@brief Definition of SVC, event and option number subranges for each API module.
@note
SVCs, event and option numbers are split into subranges for each API module.
Each module receives its entire allocated range of SVC calls, whether implemented or not,
but return BLE_ERROR_NOT_SUPPORTED for unimplemented or undefined calls in its range.
Note that the symbols BLE_<module>_SVC_LAST is the end of the allocated SVC range,
rather than the last SVC function call actually defined and implemented.
Specific SVC, event and option values are defined in each module's ble_<module>.h file,
which defines names of each individual SVC code based on the range start value.
*/
#ifndef BLE_RANGES_H__
#define BLE_RANGES_H__
#ifdef __cplusplus
extern "C" {
#endif
#define BLE_SVC_BASE 0x60 /**< Common BLE SVC base. */
#define BLE_SVC_LAST 0x6B /**< Total: 12. */
#define BLE_RESERVED_SVC_BASE 0x6C /**< Reserved BLE SVC base. */
#define BLE_RESERVED_SVC_LAST 0x6F /**< Total: 4. */
#define BLE_GAP_SVC_BASE 0x70 /**< GAP BLE SVC base. */
#define BLE_GAP_SVC_LAST 0x8F /**< Total: 32. */
#define BLE_GATTC_SVC_BASE 0x90 /**< GATTC BLE SVC base. */
#define BLE_GATTC_SVC_LAST 0x9F /**< Total: 32. */
#define BLE_GATTS_SVC_BASE 0xA0 /**< GATTS BLE SVC base. */
#define BLE_GATTS_SVC_LAST 0xAF /**< Total: 16. */
#define BLE_L2CAP_SVC_BASE 0xB0 /**< L2CAP BLE SVC base. */
#define BLE_L2CAP_SVC_LAST 0xBF /**< Total: 16. */
#define BLE_EVT_INVALID 0x00 /**< Invalid BLE Event. */
#define BLE_EVT_BASE 0x01 /**< Common BLE Event base. */
#define BLE_EVT_LAST 0x0F /**< Total: 15. */
#define BLE_GAP_EVT_BASE 0x10 /**< GAP BLE Event base. */
#define BLE_GAP_EVT_LAST 0x2F /**< Total: 32. */
#define BLE_GATTC_EVT_BASE 0x30 /**< GATTC BLE Event base. */
#define BLE_GATTC_EVT_LAST 0x4F /**< Total: 32. */
#define BLE_GATTS_EVT_BASE 0x50 /**< GATTS BLE Event base. */
#define BLE_GATTS_EVT_LAST 0x6F /**< Total: 32. */
#define BLE_L2CAP_EVT_BASE 0x70 /**< L2CAP BLE Event base. */
#define BLE_L2CAP_EVT_LAST 0x8F /**< Total: 32. */
#define BLE_OPT_INVALID 0x00 /**< Invalid BLE Option. */
#define BLE_OPT_BASE 0x01 /**< Common BLE Option base. */
#define BLE_OPT_LAST 0x1F /**< Total: 31. */
#define BLE_GAP_OPT_BASE 0x20 /**< GAP BLE Option base. */
#define BLE_GAP_OPT_LAST 0x3F /**< Total: 32. */
#define BLE_GATTC_OPT_BASE 0x40 /**< GATTC BLE Option base. */
#define BLE_GATTC_OPT_LAST 0x5F /**< Total: 32. */
#define BLE_GATTS_OPT_BASE 0x60 /**< GATTS BLE Option base. */
#define BLE_GATTS_OPT_LAST 0x7F /**< Total: 32. */
#define BLE_L2CAP_OPT_BASE 0x80 /**< L2CAP BLE Option base. */
#define BLE_L2CAP_OPT_LAST 0x9F /**< Total: 32. */
#ifdef __cplusplus
}
#endif
#endif /* BLE_RANGES_H__ */
/**
@}
@}
*/

View File

@ -0,0 +1,205 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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.
*
*/
/**
@addtogroup BLE_COMMON
@{
@defgroup ble_types Common types and macro definitions
@{
@brief Common types and macro definitions for the BLE SoftDevice.
*/
#ifndef BLE_TYPES_H__
#define BLE_TYPES_H__
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup BLE_TYPES_DEFINES Defines
* @{ */
/** @defgroup BLE_CONN_HANDLES BLE Connection Handles
* @{ */
#define BLE_CONN_HANDLE_INVALID 0xFFFF /**< Invalid Connection Handle. */
#define BLE_CONN_HANDLE_ALL 0xFFFE /**< Applies to all Connection Handles. */
/** @} */
/** @defgroup BLE_UUID_VALUES Assigned Values for BLE UUIDs
* @{ */
/* Generic UUIDs, applicable to all services */
#define BLE_UUID_UNKNOWN 0x0000 /**< Reserved UUID. */
#define BLE_UUID_SERVICE_PRIMARY 0x2800 /**< Primary Service. */
#define BLE_UUID_SERVICE_SECONDARY 0x2801 /**< Secondary Service. */
#define BLE_UUID_SERVICE_INCLUDE 0x2802 /**< Include. */
#define BLE_UUID_CHARACTERISTIC 0x2803 /**< Characteristic. */
#define BLE_UUID_DESCRIPTOR_CHAR_EXT_PROP 0x2900 /**< Characteristic Extended Properties Descriptor. */
#define BLE_UUID_DESCRIPTOR_CHAR_USER_DESC 0x2901 /**< Characteristic User Description Descriptor. */
#define BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG 0x2902 /**< Client Characteristic Configuration Descriptor. */
#define BLE_UUID_DESCRIPTOR_SERVER_CHAR_CONFIG 0x2903 /**< Server Characteristic Configuration Descriptor. */
#define BLE_UUID_DESCRIPTOR_CHAR_PRESENTATION_FORMAT 0x2904 /**< Characteristic Presentation Format Descriptor. */
#define BLE_UUID_DESCRIPTOR_CHAR_AGGREGATE_FORMAT 0x2905 /**< Characteristic Aggregate Format Descriptor. */
/* GATT specific UUIDs */
#define BLE_UUID_GATT 0x1801 /**< Generic Attribute Profile. */
#define BLE_UUID_GATT_CHARACTERISTIC_SERVICE_CHANGED 0x2A05 /**< Service Changed Characteristic. */
/* GAP specific UUIDs */
#define BLE_UUID_GAP 0x1800 /**< Generic Access Profile. */
#define BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME 0x2A00 /**< Device Name Characteristic. */
#define BLE_UUID_GAP_CHARACTERISTIC_APPEARANCE 0x2A01 /**< Appearance Characteristic. */
#define BLE_UUID_GAP_CHARACTERISTIC_PPF 0x2A02 /**< Peripheral Privacy Flag Characteristic. */
#define BLE_UUID_GAP_CHARACTERISTIC_RECONN_ADDR 0x2A03 /**< Reconnection Address Characteristic. */
#define BLE_UUID_GAP_CHARACTERISTIC_PPCP 0x2A04 /**< Peripheral Preferred Connection Parameters Characteristic. */
/** @} */
/** @defgroup BLE_UUID_TYPES Types of UUID
* @{ */
#define BLE_UUID_TYPE_UNKNOWN 0x00 /**< Invalid UUID type. */
#define BLE_UUID_TYPE_BLE 0x01 /**< Bluetooth SIG UUID (16-bit). */
#define BLE_UUID_TYPE_VENDOR_BEGIN 0x02 /**< Vendor UUID types start at this index (128-bit). */
/** @} */
/** @defgroup BLE_APPEARANCES Bluetooth Appearance values
* @note Retrieved from http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml
* @{ */
#define BLE_APPEARANCE_UNKNOWN 0 /**< Unknown. */
#define BLE_APPEARANCE_GENERIC_PHONE 64 /**< Generic Phone. */
#define BLE_APPEARANCE_GENERIC_COMPUTER 128 /**< Generic Computer. */
#define BLE_APPEARANCE_GENERIC_WATCH 192 /**< Generic Watch. */
#define BLE_APPEARANCE_WATCH_SPORTS_WATCH 193 /**< Watch: Sports Watch. */
#define BLE_APPEARANCE_GENERIC_CLOCK 256 /**< Generic Clock. */
#define BLE_APPEARANCE_GENERIC_DISPLAY 320 /**< Generic Display. */
#define BLE_APPEARANCE_GENERIC_REMOTE_CONTROL 384 /**< Generic Remote Control. */
#define BLE_APPEARANCE_GENERIC_EYE_GLASSES 448 /**< Generic Eye-glasses. */
#define BLE_APPEARANCE_GENERIC_TAG 512 /**< Generic Tag. */
#define BLE_APPEARANCE_GENERIC_KEYRING 576 /**< Generic Keyring. */
#define BLE_APPEARANCE_GENERIC_MEDIA_PLAYER 640 /**< Generic Media Player. */
#define BLE_APPEARANCE_GENERIC_BARCODE_SCANNER 704 /**< Generic Barcode Scanner. */
#define BLE_APPEARANCE_GENERIC_THERMOMETER 768 /**< Generic Thermometer. */
#define BLE_APPEARANCE_THERMOMETER_EAR 769 /**< Thermometer: Ear. */
#define BLE_APPEARANCE_GENERIC_HEART_RATE_SENSOR 832 /**< Generic Heart rate Sensor. */
#define BLE_APPEARANCE_HEART_RATE_SENSOR_HEART_RATE_BELT 833 /**< Heart Rate Sensor: Heart Rate Belt. */
#define BLE_APPEARANCE_GENERIC_BLOOD_PRESSURE 896 /**< Generic Blood Pressure. */
#define BLE_APPEARANCE_BLOOD_PRESSURE_ARM 897 /**< Blood Pressure: Arm. */
#define BLE_APPEARANCE_BLOOD_PRESSURE_WRIST 898 /**< Blood Pressure: Wrist. */
#define BLE_APPEARANCE_GENERIC_HID 960 /**< Human Interface Device (HID). */
#define BLE_APPEARANCE_HID_KEYBOARD 961 /**< Keyboard (HID Subtype). */
#define BLE_APPEARANCE_HID_MOUSE 962 /**< Mouse (HID Subtype). */
#define BLE_APPEARANCE_HID_JOYSTICK 963 /**< Joystiq (HID Subtype). */
#define BLE_APPEARANCE_HID_GAMEPAD 964 /**< Gamepad (HID Subtype). */
#define BLE_APPEARANCE_HID_DIGITIZERSUBTYPE 965 /**< Digitizer Tablet (HID Subtype). */
#define BLE_APPEARANCE_HID_CARD_READER 966 /**< Card Reader (HID Subtype). */
#define BLE_APPEARANCE_HID_DIGITAL_PEN 967 /**< Digital Pen (HID Subtype). */
#define BLE_APPEARANCE_HID_BARCODE 968 /**< Barcode Scanner (HID Subtype). */
#define BLE_APPEARANCE_GENERIC_GLUCOSE_METER 1024 /**< Generic Glucose Meter. */
#define BLE_APPEARANCE_GENERIC_RUNNING_WALKING_SENSOR 1088 /**< Generic Running Walking Sensor. */
#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_IN_SHOE 1089 /**< Running Walking Sensor: In-Shoe. */
#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_SHOE 1090 /**< Running Walking Sensor: On-Shoe. */
#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_HIP 1091 /**< Running Walking Sensor: On-Hip. */
#define BLE_APPEARANCE_GENERIC_CYCLING 1152 /**< Generic Cycling. */
#define BLE_APPEARANCE_CYCLING_CYCLING_COMPUTER 1153 /**< Cycling: Cycling Computer. */
#define BLE_APPEARANCE_CYCLING_SPEED_SENSOR 1154 /**< Cycling: Speed Sensor. */
#define BLE_APPEARANCE_CYCLING_CADENCE_SENSOR 1155 /**< Cycling: Cadence Sensor. */
#define BLE_APPEARANCE_CYCLING_POWER_SENSOR 1156 /**< Cycling: Power Sensor. */
#define BLE_APPEARANCE_CYCLING_SPEED_CADENCE_SENSOR 1157 /**< Cycling: Speed and Cadence Sensor. */
#define BLE_APPEARANCE_GENERIC_PULSE_OXIMETER 3136 /**< Generic Pulse Oximeter. */
#define BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP 3137 /**< Fingertip (Pulse Oximeter subtype). */
#define BLE_APPEARANCE_PULSE_OXIMETER_WRIST_WORN 3138 /**< Wrist Worn(Pulse Oximeter subtype). */
#define BLE_APPEARANCE_GENERIC_WEIGHT_SCALE 3200 /**< Generic Weight Scale. */
#define BLE_APPEARANCE_GENERIC_OUTDOOR_SPORTS_ACT 5184 /**< Generic Outdoor Sports Activity. */
#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_DISP 5185 /**< Location Display Device (Outdoor Sports Activity subtype). */
#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_DISP 5186 /**< Location and Navigation Display Device (Outdoor Sports Activity subtype). */
#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_POD 5187 /**< Location Pod (Outdoor Sports Activity subtype). */
#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_POD 5188 /**< Location and Navigation Pod (Outdoor Sports Activity subtype). */
/** @} */
/** @brief Set .type and .uuid fields of ble_uuid_struct to specified uuid value. */
#define BLE_UUID_BLE_ASSIGN(instance, value) do {\
instance.type = BLE_UUID_TYPE_BLE; \
instance.uuid = value;} while(0)
/** @brief Copy type and uuid members from src to dst ble_uuid_t pointer. Both pointers must be valid/non-null. */
#define BLE_UUID_COPY_PTR(dst, src) do {\
(dst)->type = (src)->type; \
(dst)->uuid = (src)->uuid;} while(0)
/** @brief Copy type and uuid members from src to dst ble_uuid_t struct. */
#define BLE_UUID_COPY_INST(dst, src) do {\
(dst).type = (src).type; \
(dst).uuid = (src).uuid;} while(0)
/** @brief Compare for equality both type and uuid members of two (valid, non-null) ble_uuid_t pointers. */
#define BLE_UUID_EQ(p_uuid1, p_uuid2) \
(((p_uuid1)->type == (p_uuid2)->type) && ((p_uuid1)->uuid == (p_uuid2)->uuid))
/** @brief Compare for difference both type and uuid members of two (valid, non-null) ble_uuid_t pointers. */
#define BLE_UUID_NEQ(p_uuid1, p_uuid2) \
(((p_uuid1)->type != (p_uuid2)->type) || ((p_uuid1)->uuid != (p_uuid2)->uuid))
/** @} */
/** @addtogroup BLE_TYPES_STRUCTURES Structures
* @{ */
/** @brief 128 bit UUID values. */
typedef struct
{
uint8_t uuid128[16]; /**< Little-Endian UUID bytes. */
} ble_uuid128_t;
/** @brief Bluetooth Low Energy UUID type, encapsulates both 16-bit and 128-bit UUIDs. */
typedef struct
{
uint16_t uuid; /**< 16-bit UUID value or octets 12-13 of 128-bit UUID. */
uint8_t type; /**< UUID type, see @ref BLE_UUID_TYPES. If type is @ref BLE_UUID_TYPE_UNKNOWN, the value of uuid is undefined. */
} ble_uuid_t;
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* BLE_TYPES_H__ */
/**
@}
@}
*/

View File

@ -0,0 +1,199 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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.
*
*/
/**
@defgroup nrf_mbr_api Master Boot Record API
@{
@brief APIs for updating SoftDevice and BootLoader
*/
/* Header guard */
#ifndef NRF_MBR_H__
#define NRF_MBR_H__
#include "nrf_svc.h"
#include <stdint.h>
#ifndef NRF51
#error "This header file shall only be included for nRF51 projects"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup NRF_MBR_DEFINES Defines
* @{ */
/**@brief MBR SVC Base number. */
#define MBR_SVC_BASE (0x18)
/**@brief Page size in words. */
#define PAGE_SIZE_IN_WORDS 256
/** @} */
/** @brief The size that must be reserved for the MBR when a softdevice is written to flash.
This is the offset where the first byte of the softdevice hex file is written.*/
#define MBR_SIZE (0x1000)
/** @addtogroup NRF_MBR_ENUMS Enumerations
* @{ */
/**@brief nRF Master Boot Record API SVC numbers. */
enum NRF_MBR_SVCS
{
SD_MBR_COMMAND = MBR_SVC_BASE, /**< ::sd_mbr_command */
};
/**@brief Possible values for ::sd_mbr_command_t.command */
enum NRF_MBR_COMMANDS
{
SD_MBR_COMMAND_COPY_BL, /**< Copy a new BootLoader. @see sd_mbr_command_copy_bl_t */
SD_MBR_COMMAND_COPY_SD, /**< Copy a new SoftDevice. @see ::sd_mbr_command_copy_sd_t*/
SD_MBR_COMMAND_INIT_SD, /**< Init forwarding interrupts to SD, and run reset function in SD*/
SD_MBR_COMMAND_COMPARE, /**< This command works like memcmp. @see ::sd_mbr_command_compare_t*/
SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET, /**< Start forwarding all exception to this address @see ::sd_mbr_command_vector_table_base_set_t*/
};
/** @} */
/** @addtogroup NRF_MBR_TYPES Types
* @{ */
/**@brief This command copies part of a new SoftDevice
* The destination area is erased before copying.
* If dst is in the middle of a flash page, that whole flash page will be erased.
* If (dst+len) is in the middle of a flash page, that whole flash page will be erased.
*
* The user of this function is responsible for setting the PROTENSET registers.
*
* @retval ::NRF_SUCCESS indicates that the contents of the memory blocks where copied correctly.
* @retval ::NRF_ERROR_INTERNAL indicates that the contents of the memory blocks where not verified correctly after copying.
*/
typedef struct
{
uint32_t *src; /**< Pointer to the source of data to be copied.*/
uint32_t *dst; /**< Pointer to the destination where the content is to be copied.*/
uint32_t len; /**< Number of 32 bit words to copy. Must be a multiple of @ref PAGE_SIZE_IN_WORDS words.*/
} sd_mbr_command_copy_sd_t;
/**@brief This command works like memcmp, but takes the length in words.
*
* @retval ::NRF_SUCCESS indicates that the contents of both memory blocks are equal.
* @retval ::NRF_ERROR_NULL indicates that the contents of the memory blocks are not equal.
*/
typedef struct
{
uint32_t *ptr1; /**< Pointer to block of memory. */
uint32_t *ptr2; /**< Pointer to block of memory. */
uint32_t len; /**< Number of 32 bit words to compare.*/
} sd_mbr_command_compare_t;
/**@brief This command copies a new BootLoader.
* With this command, destination of BootLoader is always the address written in NRF_UICR->BOOTADDR.
*
* Destination is erased by this function.
* If (destination+bl_len) is in the middle of a flash page, that whole flash page will be erased.
*
* This function will use PROTENSET to protect the flash that is not intended to be written.
*
* On Success, this function will not return. It will start the new BootLoader from reset-vector as normal.
*
* @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen.
* @retval ::NRF_ERROR_FORBIDDEN if NRF_UICR->BOOTADDR is not set.
* @retval ::NRF_ERROR_INVALID_LENGTH if parameters attempts to read or write outside flash area.
*/
typedef struct
{
uint32_t *bl_src; /**< Pointer to the source of the Bootloader to be be copied.*/
uint32_t bl_len; /**< Number of 32 bit words to copy for BootLoader. */
} sd_mbr_command_copy_bl_t;
/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the MBR
*
* Once this function has been called, this address is where the MBR will start to forward interrupts to after a reset.
*
* To restore default forwarding this function should be called with @param address set to 0.
* The MBR will then start forwarding to interrupts to the address in NFR_UICR->BOOTADDR or to the SoftDevice if the BOOTADDR is not set.
*
* @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen.
* @retval ::NRF_ERROR_INVALID_ADDR if parameter address is outside of the flash size.
*/
typedef struct
{
uint32_t address; /**< The base address of the interrupt vector table for forwarded interrupts.*/
} sd_mbr_command_vector_table_base_set_t;
typedef struct
{
uint32_t command; /**< type of command to be issued see @ref NRF_MBR_COMMANDS. */
union
{
sd_mbr_command_copy_sd_t copy_sd; /**< Parameters for copy SoftDevice.*/
sd_mbr_command_copy_bl_t copy_bl; /**< Parameters for copy BootLoader.*/
sd_mbr_command_compare_t compare; /**< Parameters for verify.*/
sd_mbr_command_vector_table_base_set_t base_set; /**< Parameters for vector table base set.*/
} params;
} sd_mbr_command_t;
/** @} */
/** @addtogroup NRF_MBR_FUNCTIONS Functions
* @{ */
/**@brief Issue Master Boot Record commands
*
* Commands used when updating a SoftDevice and bootloader.
*
* @param[in] param Pointer to a struct describing the command.
*
*@note for retvals see ::sd_mbr_command_copy_sd_t ::sd_mbr_command_copy_bl_t ::sd_mbr_command_compare_t
*/
SVCALL(SD_MBR_COMMAND, uint32_t, sd_mbr_command(sd_mbr_command_t* param));
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRF_MBR_H__
/**
@}
*/

View File

@ -0,0 +1,87 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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.
*
*/
/**
@defgroup nrf_error SoftDevice Global Error Codes
@{
@brief Global Error definitions
*/
/* Header guard */
#ifndef NRF_ERROR_H__
#define NRF_ERROR_H__
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup NRF_ERRORS_BASE Error Codes Base number definitions
* @{ */
#define NRF_ERROR_BASE_NUM (0x0) ///< Global error base
#define NRF_ERROR_SDM_BASE_NUM (0x1000) ///< SDM error base
#define NRF_ERROR_SOC_BASE_NUM (0x2000) ///< SoC error base
#define NRF_ERROR_STK_BASE_NUM (0x3000) ///< STK error base
/** @} */
#define NRF_SUCCESS (NRF_ERROR_BASE_NUM + 0) ///< Successful command
#define NRF_ERROR_SVC_HANDLER_MISSING (NRF_ERROR_BASE_NUM + 1) ///< SVC handler is missing
#define NRF_ERROR_SOFTDEVICE_NOT_ENABLED (NRF_ERROR_BASE_NUM + 2) ///< SoftDevice has not been enabled
#define NRF_ERROR_INTERNAL (NRF_ERROR_BASE_NUM + 3) ///< Internal Error
#define NRF_ERROR_NO_MEM (NRF_ERROR_BASE_NUM + 4) ///< No Memory for operation
#define NRF_ERROR_NOT_FOUND (NRF_ERROR_BASE_NUM + 5) ///< Not found
#define NRF_ERROR_NOT_SUPPORTED (NRF_ERROR_BASE_NUM + 6) ///< Not supported
#define NRF_ERROR_INVALID_PARAM (NRF_ERROR_BASE_NUM + 7) ///< Invalid Parameter
#define NRF_ERROR_INVALID_STATE (NRF_ERROR_BASE_NUM + 8) ///< Invalid state, operation disallowed in this state
#define NRF_ERROR_INVALID_LENGTH (NRF_ERROR_BASE_NUM + 9) ///< Invalid Length
#define NRF_ERROR_INVALID_FLAGS (NRF_ERROR_BASE_NUM + 10) ///< Invalid Flags
#define NRF_ERROR_INVALID_DATA (NRF_ERROR_BASE_NUM + 11) ///< Invalid Data
#define NRF_ERROR_DATA_SIZE (NRF_ERROR_BASE_NUM + 12) ///< Invalid Data size
#define NRF_ERROR_TIMEOUT (NRF_ERROR_BASE_NUM + 13) ///< Operation timed out
#define NRF_ERROR_NULL (NRF_ERROR_BASE_NUM + 14) ///< Null Pointer
#define NRF_ERROR_FORBIDDEN (NRF_ERROR_BASE_NUM + 15) ///< Forbidden Operation
#define NRF_ERROR_INVALID_ADDR (NRF_ERROR_BASE_NUM + 16) ///< Bad Memory Address
#define NRF_ERROR_BUSY (NRF_ERROR_BASE_NUM + 17) ///< Busy
#define NRF_ERROR_CONN_COUNT (NRF_ERROR_BASE_NUM + 18) ///< Maximum connection count exceeded.
#define NRF_ERROR_RESOURCES (NRF_ERROR_BASE_NUM + 19) ///< Not enough resources for operation
#ifdef __cplusplus
}
#endif
#endif // NRF_ERROR_H__
/**
@}
*/

View File

@ -16,6 +16,10 @@
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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
@ -29,43 +33,35 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
@addtogroup nrf_sdm_api
@{
@defgroup nrf_sdm_error SoftDevice Manager Error Codes
@{
#ifndef SYSTEM_NRF52_H
#define SYSTEM_NRF52_H
@brief Error definitions for the SDM API
*/
/* Header guard */
#ifndef NRF_ERROR_SDM_H__
#define NRF_ERROR_SDM_H__
#include "nrf_error.h"
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
/**
* Initialize the system
*
* @param none
* @return none
*
* @brief Setup the microcontroller system.
* Initialize the System and update the SystemCoreClock variable.
*/
extern void SystemInit (void);
/**
* Update SystemCoreClock variable
*
* @param none
* @return none
*
* @brief Updates the SystemCoreClock with current core Clock
* retrieved from cpu registers.
*/
extern void SystemCoreClockUpdate (void);
#define NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN (NRF_ERROR_SDM_BASE_NUM + 0) ///< Unknown lfclk source.
#define NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION (NRF_ERROR_SDM_BASE_NUM + 1) ///< Incorrect interrupt configuration (can be caused by using illegal priority levels, or having enabled SoftDevice interrupts).
#define NRF_ERROR_SDM_INCORRECT_CLENR0 (NRF_ERROR_SDM_BASE_NUM + 2) ///< Incorrect CLENR0 (can be caused by erronous SoftDevice flashing).
#ifdef __cplusplus
}
#endif
#endif // NRF_ERROR_SDM_H__
#endif /* SYSTEM_NRF52_H */
/**
@}
@}
*/

View File

@ -0,0 +1,82 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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.
*
*/
/**
@addtogroup nrf_soc_api
@{
@defgroup nrf_soc_error SoC Library Error Codes
@{
@brief Error definitions for the SoC library
*/
/* Header guard */
#ifndef NRF_ERROR_SOC_H__
#define NRF_ERROR_SOC_H__
#include "nrf_error.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Mutex Errors */
#define NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN (NRF_ERROR_SOC_BASE_NUM + 0) ///< Mutex already taken
/* NVIC errors */
#define NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE (NRF_ERROR_SOC_BASE_NUM + 1) ///< NVIC interrupt not available
#define NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED (NRF_ERROR_SOC_BASE_NUM + 2) ///< NVIC interrupt priority not allowed
#define NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 3) ///< NVIC should not return
/* Power errors */
#define NRF_ERROR_SOC_POWER_MODE_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 4) ///< Power mode unknown
#define NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 5) ///< Power POF threshold unknown
#define NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 6) ///< Power off should not return
/* Rand errors */
#define NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES (NRF_ERROR_SOC_BASE_NUM + 7) ///< RAND not enough values
/* PPI errors */
#define NRF_ERROR_SOC_PPI_INVALID_CHANNEL (NRF_ERROR_SOC_BASE_NUM + 8) ///< Invalid PPI Channel
#define NRF_ERROR_SOC_PPI_INVALID_GROUP (NRF_ERROR_SOC_BASE_NUM + 9) ///< Invalid PPI Group
#ifdef __cplusplus
}
#endif
#endif // NRF_ERROR_SOC_H__
/**
@}
@}
*/

View File

@ -0,0 +1,483 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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.
*
*/
/**
* @defgroup nrf_nvic_api SoftDevice NVIC API
* @{
*
* @note In order to use this module, the following code has to be added to a .c file:
* \code
* nrf_nvic_state_t nrf_nvic_state;
* \endcode
*
* @note Definitions and declarations starting with __ (double underscore) in this header file are
* not intended for direct use by the application.
*
* @brief APIs for the accessing NVIC when using a SoftDevice.
*
*/
#ifndef NRF_NVIC_H__
#define NRF_NVIC_H__
#include <stdint.h>
#include "nrf.h"
#include "nrf_error_soc.h"
#ifdef __cplusplus
extern "C" {
#endif
/**@addtogroup NRF_NVIC_DEFINES Defines
* @{ */
/**@defgroup NRF_NVIC_ISER_DEFINES SoftDevice NVIC internal definitions
* @{ */
#define __NRF_NVIC_NVMC_IRQn (30) /**< The peripheral ID of the NVMC. IRQ numbers are used to identify peripherals, but the NVMC doesn't have an IRQ number in the MDK. */
#ifdef NRF51
#define __NRF_NVIC_ISER_COUNT (1) /**< The number of ISER/ICER registers in the NVIC that are used. */
/**@brief Interrupts used by the SoftDevice. */
#define __NRF_NVIC_SD_IRQS_0 ((uint32_t)( \
(1U << POWER_CLOCK_IRQn) \
| (1U << RADIO_IRQn) \
| (1U << RTC0_IRQn) \
| (1U << TIMER0_IRQn) \
| (1U << RNG_IRQn) \
| (1U << ECB_IRQn) \
| (1U << CCM_AAR_IRQn) \
| (1U << TEMP_IRQn) \
| (1U << __NRF_NVIC_NVMC_IRQn) \
| (1U << (uint32_t)SWI4_IRQn) \
| (1U << (uint32_t)SWI5_IRQn) \
))
/**@brief Interrupts available for to application. */
#define __NRF_NVIC_APP_IRQS_0 (~__NRF_NVIC_SD_IRQS_0)
#endif
#ifdef NRF52
#define __NRF_NVIC_ISER_COUNT (2) /**< The number of ISER/ICER registers in the NVIC that are used. */
/**@brief Interrupts used by the SoftDevice. */
#define __NRF_NVIC_SD_IRQS_0 ((uint32_t)( \
(1U << POWER_CLOCK_IRQn) \
| (1U << RADIO_IRQn) \
| (1U << RTC0_IRQn) \
| (1U << TIMER0_IRQn) \
| (1U << RNG_IRQn) \
| (1U << ECB_IRQn) \
| (1U << CCM_AAR_IRQn) \
| (1U << TEMP_IRQn) \
| (1U << __NRF_NVIC_NVMC_IRQn) \
| (1U << (uint32_t)SWI4_EGU4_IRQn) \
| (1U << (uint32_t)SWI5_EGU5_IRQn) \
))
#define __NRF_NVIC_SD_IRQS_1 ((uint32_t)0)
/**@brief Interrupts available for to application. */
#define __NRF_NVIC_APP_IRQS_0 (~__NRF_NVIC_SD_IRQS_0)
#define __NRF_NVIC_APP_IRQS_1 (~__NRF_NVIC_SD_IRQS_1)
#endif
/**@} */
/**@} */
/**@addtogroup NRF_NVIC_VARIABLES Variables
* @{ */
/**@brief Type representing the state struct for the SoftDevice NVIC module. */
typedef struct
{
uint32_t volatile __irq_masks[__NRF_NVIC_ISER_COUNT]; /**< IRQs enabled by the application in the NVIC. */
uint32_t volatile __cr_flag; /**< Non-zero if already in a critical region */
} nrf_nvic_state_t;
/**@brief Variable keeping the state for the SoftDevice NVIC module. This must be declared in an
* application source file. */
extern nrf_nvic_state_t nrf_nvic_state;
/**@} */
/**@addtogroup NRF_NVIC_INTERNAL_FUNCTIONS SoftDevice NVIC internal functions
* @{ */
/**@brief Disables IRQ interrupts globally, including the SoftDevice's interrupts.
*
* @retval The value of PRIMASK prior to disabling the interrupts.
*/
static inline int __sd_nvic_irq_disable(void)
{
int pm = __get_PRIMASK();
__disable_irq();
return pm;
}
/**@brief Enables IRQ interrupts globally, including the SoftDevice's interrupts.
*/
static inline void __sd_nvic_irq_enable(void)
{
__enable_irq();
}
/**@brief Checks if IRQn is available to application
* @param[in] IRQn irq to check
*
* @retval 1 (true) if the irq to check is available to the application
*/
static inline uint32_t __sd_nvic_app_accessible_irq(IRQn_Type IRQn)
{
if (IRQn < 32)
{
return ((1UL<<IRQn) & __NRF_NVIC_APP_IRQS_0) != 0;
}
#ifdef NRF52
else if (IRQn < 64)
{
return ((1UL<<(IRQn-32)) & __NRF_NVIC_APP_IRQS_1) != 0;
}
#endif
else
{
return 1;
}
}
/**@brief Checks if IRQn is available to application
* @param[in] priority priority to check
*
* @retval 1 (true) if the priority to check is available to the application
*/
static inline uint32_t __sd_nvic_is_app_accessible_priority(uint32_t priority)
{
if(priority >= (1 << __NVIC_PRIO_BITS))
{
return 0;
}
#ifdef NRF51
if( priority == 0
|| priority == 2
)
{
return 0;
}
#endif
#ifdef NRF52
if( priority == 0
|| priority == 1
|| priority == 4
|| priority == 5
)
{
return 0;
}
#endif
return 1;
}
/**@} */
/**@addtogroup NRF_NVIC_FUNCTIONS SoftDevice NVIC public functions
* @{ */
/**@brief Enable External Interrupt.
* @note Corresponds to NVIC_EnableIRQ in CMSIS.
*
* @pre IRQn is valid and not reserved by the stack.
*
* @param[in] IRQn See the NVIC_EnableIRQ documentation in CMSIS.
*
* @retval ::NRF_SUCCESS The interrupt was enabled.
* @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application.
* @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt has a priority not available for the application.
*/
static inline uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn)
{
if (!__sd_nvic_app_accessible_irq(IRQn))
{
return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
}
if (!__sd_nvic_is_app_accessible_priority(NVIC_GetPriority(IRQn)))
{
return NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED;
}
if (nrf_nvic_state.__cr_flag)
{
nrf_nvic_state.__irq_masks[(uint32_t)((int32_t)IRQn) >> 5] |= (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F));
}
else
{
NVIC_EnableIRQ(IRQn);
}
return NRF_SUCCESS;
}
/**@brief Disable External Interrupt.
* @note Corresponds to NVIC_DisableIRQ in CMSIS.
*
* @pre IRQn is valid and not reserved by the stack.
*
* @param[in] IRQn See the NVIC_DisableIRQ documentation in CMSIS.
*
* @retval ::NRF_SUCCESS The interrupt was disabled.
* @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application.
*/
static inline uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn)
{
if (!__sd_nvic_app_accessible_irq(IRQn))
{
return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
}
if (nrf_nvic_state.__cr_flag)
{
nrf_nvic_state.__irq_masks[(uint32_t)((int32_t)IRQn) >> 5] &= ~(1UL << ((uint32_t)(IRQn) & 0x1F));
}
else
{
NVIC_DisableIRQ(IRQn);
}
return NRF_SUCCESS;
}
/**@brief Get Pending Interrupt.
* @note Corresponds to NVIC_GetPendingIRQ in CMSIS.
*
* @pre IRQn is valid and not reserved by the stack.
*
* @param[in] IRQn See the NVIC_GetPendingIRQ documentation in CMSIS.
* @param[out] p_pending_irq Return value from NVIC_GetPendingIRQ.
*
* @retval ::NRF_SUCCESS The interrupt is available for the application.
* @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application.
*/
static inline uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq)
{
if (__sd_nvic_app_accessible_irq(IRQn))
{
*p_pending_irq = NVIC_GetPendingIRQ(IRQn);
return NRF_SUCCESS;
}
else
{
return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
}
}
/**@brief Set Pending Interrupt.
* @note Corresponds to NVIC_SetPendingIRQ in CMSIS.
*
* @pre IRQn is valid and not reserved by the stack.
*
* @param[in] IRQn See the NVIC_SetPendingIRQ documentation in CMSIS.
*
* @retval ::NRF_SUCCESS The interrupt is set pending.
* @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application.
*/
static inline uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn)
{
if (__sd_nvic_app_accessible_irq(IRQn))
{
NVIC_SetPendingIRQ(IRQn);
return NRF_SUCCESS;
}
else
{
return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
}
}
/**@brief Clear Pending Interrupt.
* @note Corresponds to NVIC_ClearPendingIRQ in CMSIS.
*
* @pre IRQn is valid and not reserved by the stack.
*
* @param[in] IRQn See the NVIC_ClearPendingIRQ documentation in CMSIS.
*
* @retval ::NRF_SUCCESS The interrupt pending flag is cleared.
* @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application.
*/
static inline uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn)
{
if (__sd_nvic_app_accessible_irq(IRQn))
{
NVIC_ClearPendingIRQ(IRQn);
return NRF_SUCCESS;
}
else
{
return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
}
}
/**@brief Set Interrupt Priority.
* @note Corresponds to NVIC_SetPriority in CMSIS.
*
* @pre IRQn is valid and not reserved by the stack.
* @pre Priority is valid and not reserved by the stack.
*
* @param[in] IRQn See the NVIC_SetPriority documentation in CMSIS.
* @param[in] priority A valid IRQ priority for use by the application.
*
* @retval ::NRF_SUCCESS The interrupt and priority level is available for the application.
* @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application.
* @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt priority is not available for the application.
*/
static inline uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if (!__sd_nvic_app_accessible_irq(IRQn))
{
return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
}
if (!__sd_nvic_is_app_accessible_priority(priority))
{
return NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED;
}
NVIC_SetPriority(IRQn, (uint32_t)priority);
return NRF_SUCCESS;
}
/**@brief Get Interrupt Priority.
* @note Corresponds to NVIC_GetPriority in CMSIS.
*
* @pre IRQn is valid and not reserved by the stack.
*
* @param[in] IRQn See the NVIC_GetPriority documentation in CMSIS.
* @param[out] p_priority Return value from NVIC_GetPriority.
*
* @retval ::NRF_SUCCESS The interrupt priority is returned in p_priority.
* @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE - IRQn is not available for the application.
*/
static inline uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, uint32_t * p_priority)
{
if (__sd_nvic_app_accessible_irq(IRQn))
{
*p_priority = (NVIC_GetPriority(IRQn) & 0xFF);
return NRF_SUCCESS;
}
else
{
return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
}
}
/**@brief System Reset.
* @note Corresponds to NVIC_SystemReset in CMSIS.
*
* @retval ::NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN
*/
static inline uint32_t sd_nvic_SystemReset(void)
{
NVIC_SystemReset();
return NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN;
}
/**@brief Enters critical region.
*
* @post Application interrupts will be disabled.
* @note sd_nvic_critical_region_enter() and ::sd_nvic_critical_region_exit() must be called in matching pairs inside each
* execution context
* @sa sd_nvic_critical_region_exit
*
* @retval ::NRF_SUCCESS
*/
static inline uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region)
{
int was_masked = __sd_nvic_irq_disable();
if (!nrf_nvic_state.__cr_flag)
{
nrf_nvic_state.__cr_flag = 1;
nrf_nvic_state.__irq_masks[0] = ( NVIC->ICER[0] & __NRF_NVIC_APP_IRQS_0 );
NVIC->ICER[0] = __NRF_NVIC_APP_IRQS_0;
#ifdef NRF52
nrf_nvic_state.__irq_masks[1] = ( NVIC->ICER[1] & __NRF_NVIC_APP_IRQS_1 );
NVIC->ICER[1] = __NRF_NVIC_APP_IRQS_1;
#endif
*p_is_nested_critical_region = 0;
}
else
{
*p_is_nested_critical_region = 1;
}
if (!was_masked)
{
__sd_nvic_irq_enable();
}
return NRF_SUCCESS;
}
/**@brief Exit critical region.
*
* @pre Application has entered a critical region using ::sd_nvic_critical_region_enter.
* @post If not in a nested critical region, the application interrupts will restored to the state before ::sd_nvic_critical_region_enter was called.
*
* @param[in] is_nested_critical_region If this is set to 1, the critical region won't be exited. @sa sd_nvic_critical_region_enter.
*
* @retval ::NRF_SUCCESS
*/
static inline uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region)
{
if (nrf_nvic_state.__cr_flag && (is_nested_critical_region == 0))
{
int was_masked = __sd_nvic_irq_disable();
NVIC->ISER[0] = nrf_nvic_state.__irq_masks[0];
#ifdef NRF52
NVIC->ISER[1] = nrf_nvic_state.__irq_masks[1];
#endif
nrf_nvic_state.__cr_flag = 0;
if (!was_masked)
{
__sd_nvic_irq_enable();
}
}
return NRF_SUCCESS;
}
/**@} */
#ifdef __cplusplus
}
#endif
#endif // NRF_NVIC_H__
/**@} */

View File

@ -0,0 +1,23 @@
/* 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.
*
*/
#ifndef NRF_SD_DEF_H__
#define NRF_SD_DEF_H__
#include <stdint.h>
#define SD_PPI_CHANNELS_USED 0xFFF0C000uL /**< PPI channels utilized by SotfDevice (not available to the application). */
#define SD_PPI_GROUPS_USED 0x0000000CuL /**< PPI groups utilized by SoftDevice (not available to the application). */
#define SD_TIMERS_USED 0x00000001uL /**< Timers used by SoftDevice. */
#define SD_SWI_USED 0x0000003CuL /**< Software interrupts used by SoftDevice */
#endif /* NRF_SD_DEF_H__ */

View File

@ -0,0 +1,271 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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.
*
*/
/**
@defgroup nrf_sdm_api SoftDevice Manager API
@{
@brief APIs for SoftDevice management.
*/
/* Header guard */
#ifndef NRF_SDM_H__
#define NRF_SDM_H__
#include "nrf_svc.h"
#include "nrf.h"
#include "nrf_soc.h"
#include "nrf_error_sdm.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup NRF_SDM_DEFINES Defines
* @{ */
#ifdef NRFSOC_DOXYGEN
//Stuff defined elsewere, to satisfy doxygen
#define MBR_SIZE 0
#warning test
#endif
/** @brief SoftDevice Manager SVC Base number. */
#define SDM_SVC_BASE 0x10
/** @brief Defines the SoftDevice Information Structure location (address) as an offset from
the start of the softdevice (without MBR)*/
#define SOFTDEVICE_INFO_STRUCT_OFFSET (0x2000)
/** @brief Defines the absolute Softdevice information structure location (address)*/
#define SOFTDEVICE_INFO_STRUCT_ADDRESS (SOFTDEVICE_INFO_STRUCT_OFFSET + MBR_SIZE)
/** @brief Defines the offset for Softdevice size value relative to Softdevice base address*/
#define SD_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x08)
/** @brief Defines the offset for FWID value relative to Softdevice base address*/
#define SD_FWID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x0C)
/** @brief Defines a macro for retreiving the actual Softdevice size value from a given base address
use @ref MBR_SIZE when Softdevice is installed just above the MBR (the usual case)*/
#define SD_SIZE_GET(baseaddr) (*((uint32_t *) ((baseaddr) + SD_SIZE_OFFSET)))
/** @brief Defines a macro for retreiving the actual FWID value from a given base address
use @ref MBR_SIZE when Softdevice is installed just above the MBR (the usual case)*/
#define SD_FWID_GET(baseaddr) ((*((uint32_t *) ((baseaddr) + SD_FWID_OFFSET))) & 0xFFFF)
/**@defgroup NRF_FAULT_ID_RANGES Fault ID ranges
* @{ */
#define NRF_FAULT_ID_SD_RANGE_START 0x00000000 /**< SoftDevice ID range start. */
#define NRF_FAULT_ID_APP_RANGE_START 0x00001000 /**< Application ID range start. */
/**@} */
/**@defgroup NRF_FAULT_IDS Fault ID types
* @{ */
#define NRF_FAULT_ID_SD_ASSERT (NRF_FAULT_ID_SD_RANGE_START + 1) /**< SoftDevice assertion. The info parameter will be set to 0x00000000. */
#define NRF_FAULT_ID_APP_MEMACC (NRF_FAULT_ID_APP_RANGE_START + 1) /**< Application invalid memory access. The info parameter will contain the address in memory that was accessed. */
/**@} */
/** @} */
/** @addtogroup NRF_SDM_ENUMS Enumerations
* @{ */
/**@brief nRF SoftDevice Manager API SVC numbers. */
enum NRF_SD_SVCS
{
SD_SOFTDEVICE_ENABLE = SDM_SVC_BASE, /**< ::sd_softdevice_enable */
SD_SOFTDEVICE_DISABLE, /**< ::sd_softdevice_disable */
SD_SOFTDEVICE_IS_ENABLED, /**< ::sd_softdevice_is_enabled */
SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, /**< ::sd_softdevice_vector_table_base_set */
SVC_SDM_LAST /**< Placeholder for last SDM SVC */
};
/** @} */
/** @addtogroup NRF_SDM_DEFINES Defines
* @{ */
/**@defgroup NRF_CLOCK_LF_XTAL_ACCURACY Clock accuracy * @{ */
#define NRF_CLOCK_LF_XTAL_ACCURACY_250_PPM (0) /* Default */
#define NRF_CLOCK_LF_XTAL_ACCURACY_500_PPM (1)
#define NRF_CLOCK_LF_XTAL_ACCURACY_150_PPM (2)
#define NRF_CLOCK_LF_XTAL_ACCURACY_100_PPM (3)
#define NRF_CLOCK_LF_XTAL_ACCURACY_75_PPM (4)
#define NRF_CLOCK_LF_XTAL_ACCURACY_50_PPM (5)
#define NRF_CLOCK_LF_XTAL_ACCURACY_30_PPM (6)
#define NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM (7)
/** @} */
/**@defgroup NRF_CLOCK_LF_SRC Possible lfclk oscillator sources * @{ */
#define NRF_CLOCK_LF_SRC_RC (0) /**< LFCLK RC oscillator. */
#define NRF_CLOCK_LF_SRC_XTAL (1) /**< LFCLK crystal oscillator. */
#define NRF_CLOCK_LF_SRC_SYNTH (2) /**< LFCLK Synthesized from HFCLK. */
/** @} */
/** @} */
/** @addtogroup NRF_SDM_TYPES Types
* @{ */
/**@brief Type representing lfclk oscillator source. */
typedef struct
{
uint8_t source; /**< LF oscillator clock source, see @ref NRF_CLOCK_LF_SRC. */
uint8_t rc_ctiv; /**< Only for NRF_CLOCK_LF_SRC_RC: Calibration timer interval in 1/4 second
units (nRF51: 1-64, nRF52: 1-32).
@note To avoid excessive clock drift, 0.5 degrees Celsius is the
maximum temperature change allowed in one calibration timer
interval. The interval should be selected to ensure this.
@note Must be 0 if source is not NRF_CLOCK_LF_SRC_RC. */
uint8_t rc_temp_ctiv; /**< Only for NRF_CLOCK_LF_SRC_RC: How often (in number of calibration
intervals) the RC oscillator shall be calibrated if the temperature
hasn't changed.
0: Always calibrate even if the temperature hasn't changed.
1: Only calibrate if the temperature has changed (nRF51 only).
2-33: Check the temperature and only calibrate if it has changed,
however calibration will take place every rc_temp_ctiv
intervals in any case.
@note Must be 0 if source is not NRF_CLOCK_LF_SRC_RC.
@note For nRF52, the application must ensure calibration at least once
every 8 seconds to ensure +/-250ppm clock stability. The
recommended configuration for NRF_CLOCK_LF_SRC_RC on nRF52 is
rc_ctiv=16 and rc_temp_ctiv=2. This will ensure calibration at
least once every 8 seconds and for temperature changes of 0.5
degrees Celsius every 4 seconds. See the Product Specification
for the nRF52 device being used for more information.*/
uint8_t xtal_accuracy; /**< External crystal clock accuracy used in the LL to compute timing windows.
@note For the NRF_CLOCK_LF_SRC_RC clock source this parameter is ignored. */
} nrf_clock_lf_cfg_t;
/**@brief Fault Handler type.
*
* When certain unrecoverable errors occur within the application or SoftDevice the fault handler will be called back.
* The protocol stack will be in an undefined state when this happens and the only way to recover will be to
* perform a reset, using e.g. CMSIS NVIC_SystemReset().
*
* @note This callback is executed in HardFault context, thus SVC functions cannot be called from the fault callback.
*
* @param[in] id Fault identifier. See @ref NRF_FAULT_IDS.
* @param[in] pc The program counter of the instruction that triggered the fault.
* @param[in] info Optional additional information regarding the fault. Refer to each Fault identifier for details.
*/
typedef void (*nrf_fault_handler_t)(uint32_t id, uint32_t pc, uint32_t info);
/** @} */
/** @addtogroup NRF_SDM_FUNCTIONS Functions
* @{ */
/**@brief Enables the SoftDevice and by extension the protocol stack.
*
* @note Some care must be taken if a low frequency clock source is already running when calling this function:
* If the LF clock has a different source then the one currently running, it will be stopped. Then, the new
* clock source will be started.
*
* @note This function has no effect when returning with an error.
*
* @post If return code is ::NRF_SUCCESS
* - SoC library and protocol stack APIs are made available.
* - A portion of RAM will be unavailable (see relevant SDS documentation).
* - Some peripherals will be unavailable or available only through the SoC API (see relevant SDS documentation).
* - Interrupts will not arrive from protected peripherals or interrupts.
* - nrf_nvic_ functions must be used instead of CMSIS NVIC_ functions for reliable usage of the SoftDevice.
* - Interrupt latency may be affected by the SoftDevice (see relevant SDS documentation).
* - Chosen low frequency clock source will be running.
*
* @param p_clock_lf_cfg Low frequency clock source and accuracy.
If NULL the clock will be configured as an rc source with rc_ctiv = 16 and .rc_temp_ctiv = 2
In the case of XTAL source, the PPM accuracy of the chosen clock source must be greater than or equal to the actual characteristics of your XTAL clock.
* @param fault_handler Callback to be invoked in case of fault.
*
* @retval ::NRF_SUCCESS
* @retval ::NRF_ERROR_INVALID_STATE SoftDevice is already enabled, and the clock source and fault handler cannot be updated.
* @retval ::NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION SoftDevice interrupt is already enabled, or an enabled interrupt has an illegal priority level.
* @retval ::NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN Unknown low frequency clock source selected.
*/
SVCALL(SD_SOFTDEVICE_ENABLE, uint32_t, sd_softdevice_enable(nrf_clock_lf_cfg_t const * p_clock_lf_cfg, nrf_fault_handler_t fault_handler));
/**@brief Disables the SoftDevice and by extension the protocol stack.
*
* Idempotent function to disable the SoftDevice.
*
* @post SoC library and protocol stack APIs are made unavailable.
* @post All interrupts that was protected by the SoftDevice will be disabled and initialized to priority 0 (highest).
* @post All peripherals used by the SoftDevice will be reset to default values.
* @post All of RAM become available.
* @post All interrupts are forwarded to the application.
* @post LFCLK source chosen in ::sd_softdevice_enable will be left running.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_SOFTDEVICE_DISABLE, uint32_t, sd_softdevice_disable(void));
/**@brief Check if the SoftDevice is enabled.
*
* @param[out] p_softdevice_enabled If the SoftDevice is enabled: 1 else 0.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_SOFTDEVICE_IS_ENABLED, uint32_t, sd_softdevice_is_enabled(uint8_t * p_softdevice_enabled));
/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the SoftDevice
*
* This function is only intended to be called when a bootloader is enabled.
*
* @param[in] address The base address of the interrupt vector table for forwarded interrupts.
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, uint32_t, sd_softdevice_vector_table_base_set(uint32_t address));
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRF_SDM_H__
/**
@}
*/

View File

@ -0,0 +1,908 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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.
*
*/
/**
* @defgroup nrf_soc_api SoC Library API
* @{
*
* @brief APIs for the SoC library.
*
*/
#ifndef NRF_SOC_H__
#define NRF_SOC_H__
#include <stdint.h>
#include <stdbool.h>
#include "nrf_svc.h"
#include "nrf.h"
#include "nrf_error_soc.h"
#ifdef __cplusplus
extern "C" {
#endif
/**@addtogroup NRF_SOC_DEFINES Defines
* @{ */
/**@brief The number of the lowest SVC number reserved for the SoC library. */
#define SOC_SVC_BASE (0x20)
#define SOC_SVC_BASE_NOT_AVAILABLE (0x2B)
/**@brief Guranteed time for application to process radio inactive notification. */
#define NRF_RADIO_NOTIFICATION_INACTIVE_GUARANTEED_TIME_US (62)
/**@brief The minimum allowed timeslot extension time. */
#define NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US (200)
#define SOC_ECB_KEY_LENGTH (16) /**< ECB key length. */
#define SOC_ECB_CLEARTEXT_LENGTH (16) /**< ECB cleartext length. */
#define SOC_ECB_CIPHERTEXT_LENGTH (SOC_ECB_CLEARTEXT_LENGTH) /**< ECB ciphertext length. */
#ifdef NRF51
#define SD_EVT_IRQn (SWI2_IRQn) /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */
#define SD_EVT_IRQHandler (SWI2_IRQHandler) /**< SoftDevice Event IRQ handler. Used for both protocol events and SoC events. */
#define RADIO_NOTIFICATION_IRQn (SWI1_IRQn) /**< The radio notification IRQ number. */
#define RADIO_NOTIFICATION_IRQHandler (SWI1_IRQHandler) /**< The radio notification IRQ handler. */
#endif
#ifdef NRF52
#define SD_EVT_IRQn (SWI2_EGU2_IRQn) /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */
#define SD_EVT_IRQHandler (SWI2_EGU2_IRQHandler) /**< SoftDevice Event IRQ handler. Used for both protocol events and SoC events. */
#define RADIO_NOTIFICATION_IRQn (SWI1_EGU1_IRQn) /**< The radio notification IRQ number. */
#define RADIO_NOTIFICATION_IRQHandler (SWI1_EGU1_IRQHandler) /**< The radio notification IRQ handler. */
#endif
#define NRF_RADIO_LENGTH_MIN_US (100) /**< The shortest allowed radio timeslot, in microseconds. */
#define NRF_RADIO_LENGTH_MAX_US (100000) /**< The longest allowed radio timeslot, in microseconds. */
#define NRF_RADIO_DISTANCE_MAX_US (128000000UL - 1UL) /**< The longest timeslot distance, in microseconds, allowed for the distance parameter (see @ref nrf_radio_request_normal_t) in the request. */
#define NRF_RADIO_EARLIEST_TIMEOUT_MAX_US (128000000UL - 1UL) /**< The longest timeout, in microseconds, allowed when requesting the earliest possible timeslot. */
#define NRF_RADIO_START_JITTER_US (2) /**< The maximum jitter in @ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START relative to the requested start time. */
/**@} */
/**@addtogroup NRF_SOC_ENUMS Enumerations
* @{ */
/**@brief The SVC numbers used by the SVC functions in the SoC library. */
enum NRF_SOC_SVCS
{
SD_PPI_CHANNEL_ENABLE_GET = SOC_SVC_BASE,
SD_PPI_CHANNEL_ENABLE_SET,
SD_PPI_CHANNEL_ENABLE_CLR,
SD_PPI_CHANNEL_ASSIGN,
SD_PPI_GROUP_TASK_ENABLE,
SD_PPI_GROUP_TASK_DISABLE,
SD_PPI_GROUP_ASSIGN,
SD_PPI_GROUP_GET,
SD_FLASH_PAGE_ERASE,
SD_FLASH_WRITE,
SD_FLASH_PROTECT,
SD_MUTEX_NEW = SOC_SVC_BASE_NOT_AVAILABLE,
SD_MUTEX_ACQUIRE,
SD_MUTEX_RELEASE,
SD_RFU_1,
SD_RFU_2,
SD_RFU_3,
SD_RFU_4,
SD_RFU_5,
SD_RFU_6,
SD_RFU_7,
SD_RFU_8,
SD_RFU_9,
SD_RFU_10,
SD_RAND_APPLICATION_POOL_CAPACITY_GET,
SD_RAND_APPLICATION_BYTES_AVAILABLE_GET,
SD_RAND_APPLICATION_VECTOR_GET,
SD_POWER_MODE_SET,
SD_POWER_SYSTEM_OFF,
SD_POWER_RESET_REASON_GET,
SD_POWER_RESET_REASON_CLR,
SD_POWER_POF_ENABLE,
SD_POWER_POF_THRESHOLD_SET,
SD_POWER_RAMON_SET,
SD_POWER_RAMON_CLR,
SD_POWER_RAMON_GET,
SD_POWER_GPREGRET_SET,
SD_POWER_GPREGRET_CLR,
SD_POWER_GPREGRET_GET,
SD_POWER_DCDC_MODE_SET,
SD_APP_EVT_WAIT,
SD_CLOCK_HFCLK_REQUEST,
SD_CLOCK_HFCLK_RELEASE,
SD_CLOCK_HFCLK_IS_RUNNING,
SD_RADIO_NOTIFICATION_CFG_SET,
SD_ECB_BLOCK_ENCRYPT,
SD_ECB_BLOCKS_ENCRYPT,
SD_RADIO_SESSION_OPEN,
SD_RADIO_SESSION_CLOSE,
SD_RADIO_REQUEST,
SD_EVT_GET,
SD_TEMP_GET,
SVC_SOC_LAST
};
/**@brief Possible values of a ::nrf_mutex_t. */
enum NRF_MUTEX_VALUES
{
NRF_MUTEX_FREE,
NRF_MUTEX_TAKEN
};
/**@brief Power modes. */
enum NRF_POWER_MODES
{
NRF_POWER_MODE_CONSTLAT, /**< Constant latency mode. See power management in the reference manual. */
NRF_POWER_MODE_LOWPWR /**< Low power mode. See power management in the reference manual. */
};
/**@brief Power failure thresholds */
enum NRF_POWER_THRESHOLDS
{
NRF_POWER_THRESHOLD_V21, /**< 2.1 Volts power failure threshold. */
NRF_POWER_THRESHOLD_V23, /**< 2.3 Volts power failure threshold. */
NRF_POWER_THRESHOLD_V25, /**< 2.5 Volts power failure threshold. */
NRF_POWER_THRESHOLD_V27 /**< 2.7 Volts power failure threshold. */
};
/**@brief DC/DC converter modes. */
enum NRF_POWER_DCDC_MODES
{
NRF_POWER_DCDC_DISABLE, /**< The DCDC is disabled. */
NRF_POWER_DCDC_ENABLE /**< The DCDC is enabled. */
};
/**@brief Radio notification distances. */
enum NRF_RADIO_NOTIFICATION_DISTANCES
{
NRF_RADIO_NOTIFICATION_DISTANCE_NONE = 0, /**< The event does not have a notification. */
NRF_RADIO_NOTIFICATION_DISTANCE_800US, /**< The distance from the active notification to start of radio activity. */
NRF_RADIO_NOTIFICATION_DISTANCE_1740US, /**< The distance from the active notification to start of radio activity. */
NRF_RADIO_NOTIFICATION_DISTANCE_2680US, /**< The distance from the active notification to start of radio activity. */
NRF_RADIO_NOTIFICATION_DISTANCE_3620US, /**< The distance from the active notification to start of radio activity. */
NRF_RADIO_NOTIFICATION_DISTANCE_4560US, /**< The distance from the active notification to start of radio activity. */
NRF_RADIO_NOTIFICATION_DISTANCE_5500US /**< The distance from the active notification to start of radio activity. */
};
/**@brief Radio notification types. */
enum NRF_RADIO_NOTIFICATION_TYPES
{
NRF_RADIO_NOTIFICATION_TYPE_NONE = 0, /**< The event does not have a radio notification signal. */
NRF_RADIO_NOTIFICATION_TYPE_INT_ON_ACTIVE, /**< Using interrupt for notification when the radio will be enabled. */
NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE, /**< Using interrupt for notification when the radio has been disabled. */
NRF_RADIO_NOTIFICATION_TYPE_INT_ON_BOTH, /**< Using interrupt for notification both when the radio will be enabled and disabled. */
};
/**@brief The Radio signal callback types. */
enum NRF_RADIO_CALLBACK_SIGNAL_TYPE
{
NRF_RADIO_CALLBACK_SIGNAL_TYPE_START, /**< This signal indicates the start of the radio timeslot. */
NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0, /**< This signal indicates the NRF_TIMER0 interrupt. */
NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO, /**< This signal indicates the NRF_RADIO interrupt. */
NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_FAILED, /**< This signal indicates extend action failed. */
NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED /**< This signal indicates extend action succeeded. */
};
/**@brief The actions requested by the signal callback.
*
* This code gives the SOC instructions about what action to take when the signal callback has
* returned.
*/
enum NRF_RADIO_SIGNAL_CALLBACK_ACTION
{
NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE, /**< Return without action. */
NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND, /**< Request an extension of the current timeslot (maximum execution time for this action is when the extension succeeded). */
NRF_RADIO_SIGNAL_CALLBACK_ACTION_END, /**< End the current radio timeslot. */
NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END /**< Request a new radio timeslot and end the current timeslot. */
};
/**@brief Radio timeslot high frequency clock source configuration. */
enum NRF_RADIO_HFCLK_CFG
{
NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED, /**< The SoftDevice will guarantee that the high frequency clock source is the
external crystal for the whole duration of the timeslot. This should be the
preferred option for events that use the radio or require high timing accuracy. */
NRF_RADIO_HFCLK_CFG_NO_GUARANTEE /**< This configuration allows for earlier and tighter scheduling of timeslots.
The RC oscillator may be the clock source in part or for the whole duration of the timeslot.
The RC oscillator's accuracy must therefore be taken into consideration.
@note If the application will use the radio peripheral in timeslots with this configuration,
it must make sure that the crystal is running and stable before starting the radio. */
};
/**@brief Radio timeslot priorities. */
enum NRF_RADIO_PRIORITY
{
NRF_RADIO_PRIORITY_HIGH, /**< High (equal priority as the normal connection priority of the SoftDevice stack(s)). */
NRF_RADIO_PRIORITY_NORMAL, /**< Normal (equal priority as the priority of secondary activites of the SoftDevice stack(s)). */
};
/**@brief Radio timeslot request type. */
enum NRF_RADIO_REQUEST_TYPE
{
NRF_RADIO_REQ_TYPE_EARLIEST, /**< Request radio timeslot as early as possible. This should always be used for the first request in a session. */
NRF_RADIO_REQ_TYPE_NORMAL /**< Normal radio timeslot request. */
};
/**@brief SoC Events. */
enum NRF_SOC_EVTS
{
NRF_EVT_HFCLKSTARTED, /**< Event indicating that the HFCLK has started. */
NRF_EVT_POWER_FAILURE_WARNING, /**< Event indicating that a power failure warning has occurred. */
NRF_EVT_FLASH_OPERATION_SUCCESS, /**< Event indicating that the ongoing flash operation has completed successfully. */
NRF_EVT_FLASH_OPERATION_ERROR, /**< Event indicating that the ongoing flash operation has timed out with an error. */
NRF_EVT_RADIO_BLOCKED, /**< Event indicating that a radio timeslot was blocked. */
NRF_EVT_RADIO_CANCELED, /**< Event indicating that a radio timeslot was canceled by SoftDevice. */
NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN, /**< Event indicating that a radio timeslot signal callback handler return was invalid. */
NRF_EVT_RADIO_SESSION_IDLE, /**< Event indicating that a radio timeslot session is idle. */
NRF_EVT_RADIO_SESSION_CLOSED, /**< Event indicating that a radio timeslot session is closed. */
NRF_EVT_NUMBER_OF_EVTS
};
/**@} */
/**@addtogroup NRF_SOC_STRUCTURES Structures
* @{ */
/**@brief Represents a mutex for use with the nrf_mutex functions.
* @note Accessing the value directly is not safe, use the mutex functions!
*/
typedef volatile uint8_t nrf_mutex_t;
/**@brief Parameters for a request for a timeslot as early as possible. */
typedef struct
{
uint8_t hfclk; /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */
uint8_t priority; /**< The radio timeslot priority, see @ref NRF_RADIO_PRIORITY. */
uint32_t length_us; /**< The radio timeslot length (in the range 100 to 100,000] microseconds). */
uint32_t timeout_us; /**< Longest acceptable delay until the start of the requested timeslot (up to @ref NRF_RADIO_EARLIEST_TIMEOUT_MAX_US microseconds). */
} nrf_radio_request_earliest_t;
/**@brief Parameters for a normal radio timeslot request. */
typedef struct
{
uint8_t hfclk; /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */
uint8_t priority; /**< The radio timeslot priority, see @ref NRF_RADIO_PRIORITY. */
uint32_t distance_us; /**< Distance from the start of the previous radio timeslot (up to @ref NRF_RADIO_DISTANCE_MAX_US microseconds). */
uint32_t length_us; /**< The radio timeslot length (in the range [100..100,000] microseconds). */
} nrf_radio_request_normal_t;
/**@brief Radio timeslot request parameters. */
typedef struct
{
uint8_t request_type; /**< Type of request, see @ref NRF_RADIO_REQUEST_TYPE. */
union
{
nrf_radio_request_earliest_t earliest; /**< Parameters for requesting a radio timeslot as early as possible. */
nrf_radio_request_normal_t normal; /**< Parameters for requesting a normal radio timeslot. */
} params;
} nrf_radio_request_t;
/**@brief Return parameters of the radio timeslot signal callback. */
typedef struct
{
uint8_t callback_action; /**< The action requested by the application when returning from the signal callback, see @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION. */
union
{
struct
{
nrf_radio_request_t * p_next; /**< The request parameters for the next radio timeslot. */
} request; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END. */
struct
{
uint32_t length_us; /**< Requested extension of the radio timeslot duration (microseconds) (for minimum time see @ref NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US). */
} extend; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND. */
} params;
} nrf_radio_signal_callback_return_param_t;
/**@brief The radio timeslot signal callback type.
*
* @note In case of invalid return parameters, the radio timeslot will automatically end
* immediately after returning from the signal callback and the
* @ref NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN event will be sent.
* @note The returned struct pointer must remain valid after the signal callback
* function returns. For instance, this means that it must not point to a stack variable.
*
* @param[in] signal_type Type of signal, see @ref NRF_RADIO_CALLBACK_SIGNAL_TYPE.
*
* @return Pointer to structure containing action requested by the application.
*/
typedef nrf_radio_signal_callback_return_param_t * (*nrf_radio_signal_callback_t) (uint8_t signal_type);
/**@brief AES ECB parameter typedefs */
typedef uint8_t soc_ecb_key_t[SOC_ECB_KEY_LENGTH];
typedef uint8_t soc_ecb_cleartext_t[SOC_ECB_CLEARTEXT_LENGTH];
typedef uint8_t soc_ecb_ciphertext_t[SOC_ECB_CIPHERTEXT_LENGTH];
/**@brief AES ECB data structure */
typedef struct
{
soc_ecb_key_t key; /**< Encryption key. */
soc_ecb_cleartext_t cleartext; /**< Cleartext data. */
soc_ecb_ciphertext_t ciphertext; /**< Ciphertext data. */
} nrf_ecb_hal_data_t;
/**@brief AES ECB block. Used to provide multiple blocks in a single call
to @ref sd_ecb_blocks_encrypt.*/
typedef struct
{
soc_ecb_key_t* p_key; /**< Pointer to the Encryption key. */
soc_ecb_cleartext_t* p_cleartext; /**< Pointer to the Cleartext data. */
soc_ecb_ciphertext_t* p_ciphertext; /**< Pointer to the Ciphertext data. */
} nrf_ecb_hal_data_block_t;
/**@} */
/**@addtogroup NRF_SOC_FUNCTIONS Functions
* @{ */
/**@brief Initialize a mutex.
*
* @param[in] p_mutex Pointer to the mutex to initialize.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_MUTEX_NEW, uint32_t, sd_mutex_new(nrf_mutex_t * p_mutex));
/**@brief Attempt to acquire a mutex.
*
* @param[in] p_mutex Pointer to the mutex to acquire.
*
* @retval ::NRF_SUCCESS The mutex was successfully acquired.
* @retval ::NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN The mutex could not be acquired.
*/
SVCALL(SD_MUTEX_ACQUIRE, uint32_t, sd_mutex_acquire(nrf_mutex_t * p_mutex));
/**@brief Release a mutex.
*
* @param[in] p_mutex Pointer to the mutex to release.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_MUTEX_RELEASE, uint32_t, sd_mutex_release(nrf_mutex_t * p_mutex));
/**@brief Query the capacity of the application random pool.
*
* @param[out] p_pool_capacity The capacity of the pool.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_RAND_APPLICATION_POOL_CAPACITY_GET, uint32_t, sd_rand_application_pool_capacity_get(uint8_t * p_pool_capacity));
/**@brief Get number of random bytes available to the application.
*
* @param[out] p_bytes_available The number of bytes currently available in the pool.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_RAND_APPLICATION_BYTES_AVAILABLE_GET, uint32_t, sd_rand_application_bytes_available_get(uint8_t * p_bytes_available));
/**@brief Get random bytes from the application pool.
*
* @param[out] p_buff Pointer to unit8_t buffer for storing the bytes.
* @param[in] length Number of bytes to take from pool and place in p_buff.
*
* @retval ::NRF_SUCCESS The requested bytes were written to p_buff.
* @retval ::NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES No bytes were written to the buffer, because there were not enough bytes available.
*/
SVCALL(SD_RAND_APPLICATION_VECTOR_GET, uint32_t, sd_rand_application_vector_get(uint8_t * p_buff, uint8_t length));
/**@brief Gets the reset reason register.
*
* @param[out] p_reset_reason Contents of the NRF_POWER->RESETREAS register.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_POWER_RESET_REASON_GET, uint32_t, sd_power_reset_reason_get(uint32_t * p_reset_reason));
/**@brief Clears the bits of the reset reason register.
*
* @param[in] reset_reason_clr_msk Contains the bits to clear from the reset reason register.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_POWER_RESET_REASON_CLR, uint32_t, sd_power_reset_reason_clr(uint32_t reset_reason_clr_msk));
/**@brief Sets the power mode when in CPU sleep.
*
* @param[in] power_mode The power mode to use when in CPU sleep, see @ref NRF_POWER_MODES. @sa sd_app_evt_wait
*
* @retval ::NRF_SUCCESS The power mode was set.
* @retval ::NRF_ERROR_SOC_POWER_MODE_UNKNOWN The power mode was unknown.
*/
SVCALL(SD_POWER_MODE_SET, uint32_t, sd_power_mode_set(uint8_t power_mode));
/**@brief Puts the chip in System OFF mode.
*
* @retval ::NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN
*/
SVCALL(SD_POWER_SYSTEM_OFF, uint32_t, sd_power_system_off(void));
/**@brief Enables or disables the power-fail comparator.
*
* Enabling this will give a softdevice event (NRF_EVT_POWER_FAILURE_WARNING) when the power failure warning occurs.
* The event can be retrieved with sd_evt_get();
*
* @param[in] pof_enable True if the power-fail comparator should be enabled, false if it should be disabled.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_POWER_POF_ENABLE, uint32_t, sd_power_pof_enable(uint8_t pof_enable));
/**@brief Sets the power-fail threshold value.
*
* @param[in] threshold The power-fail threshold value to use, see @ref NRF_POWER_THRESHOLDS.
*
* @retval ::NRF_SUCCESS The power failure threshold was set.
* @retval ::NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN The power failure threshold is unknown.
*/
SVCALL(SD_POWER_POF_THRESHOLD_SET, uint32_t, sd_power_pof_threshold_set(uint8_t threshold));
/**@brief Sets bits in the NRF_POWER->RAMON register.
*
* @param[in] ramon Contains the bits needed to be set in the NRF_POWER->RAMON register.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_POWER_RAMON_SET, uint32_t, sd_power_ramon_set(uint32_t ramon));
/**@brief Clears bits in the NRF_POWER->RAMON register.
*
* @param ramon Contains the bits needed to be cleared in the NRF_POWER->RAMON register.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_POWER_RAMON_CLR, uint32_t, sd_power_ramon_clr(uint32_t ramon));
/**@brief Get contents of NRF_POWER->RAMON register, indicates power status of ram blocks.
*
* @param[out] p_ramon Content of NRF_POWER->RAMON register.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_POWER_RAMON_GET, uint32_t, sd_power_ramon_get(uint32_t * p_ramon));
/**@brief Set bits in the NRF_POWER->GPREGRET register.
*
* @param[in] gpregret_msk Bits to be set in the GPREGRET register.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_POWER_GPREGRET_SET, uint32_t, sd_power_gpregret_set(uint32_t gpregret_msk));
/**@brief Clear bits in the NRF_POWER->GPREGRET register.
*
* @param[in] gpregret_msk Bits to be clear in the GPREGRET register.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_POWER_GPREGRET_CLR, uint32_t, sd_power_gpregret_clr(uint32_t gpregret_msk));
/**@brief Get contents of the NRF_POWER->GPREGRET register.
*
* @param[out] p_gpregret Contents of the GPREGRET register.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_POWER_GPREGRET_GET, uint32_t, sd_power_gpregret_get(uint32_t *p_gpregret));
/**@brief Sets the DCDC mode.
*
* Enable or disable the DCDC peripheral.
*
* @param[in] dcdc_mode The mode of the DCDC, see @ref NRF_POWER_DCDC_MODES.
*
* @retval ::NRF_SUCCESS
* @retval ::NRF_ERROR_INVALID_PARAM The DCDC mode is invalid.
*/
SVCALL(SD_POWER_DCDC_MODE_SET, uint32_t, sd_power_dcdc_mode_set(uint8_t dcdc_mode));
/**@brief Request the high frequency crystal oscillator.
*
* Will start the high frequency crystal oscillator, the startup time of the crystal varies
* and the ::sd_clock_hfclk_is_running function can be polled to check if it has started.
*
* @see sd_clock_hfclk_is_running
* @see sd_clock_hfclk_release
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_CLOCK_HFCLK_REQUEST, uint32_t, sd_clock_hfclk_request(void));
/**@brief Releases the high frequency crystal oscillator.
*
* Will stop the high frequency crystal oscillator, this happens immediately.
*
* @see sd_clock_hfclk_is_running
* @see sd_clock_hfclk_request
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_CLOCK_HFCLK_RELEASE, uint32_t, sd_clock_hfclk_release(void));
/**@brief Checks if the high frequency crystal oscillator is running.
*
* @see sd_clock_hfclk_request
* @see sd_clock_hfclk_release
*
* @param[out] p_is_running 1 if the external crystal oscillator is running, 0 if not.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_CLOCK_HFCLK_IS_RUNNING, uint32_t, sd_clock_hfclk_is_running(uint32_t * p_is_running));
/**@brief Waits for an application event.
*
* An application event is either an application interrupt or a pended interrupt when the
* interrupt is disabled. When the interrupt is enabled it will be taken immediately since
* this function will wait in thread mode, then the execution will return in the application's
* main thread. When an interrupt is disabled and gets pended it will return to the application's
* thread main. The application must ensure that the pended flag is cleared using
* ::sd_nvic_ClearPendingIRQ in order to sleep using this function. This is only necessary for
* disabled interrupts, as the interrupt handler will clear the pending flag automatically for
* enabled interrupts.
*
* In order to wake up from disabled interrupts, the SEVONPEND flag has to be set in the Cortex-M0
* System Control Register (SCR). @sa CMSIS_SCB
*
* @note If an application interrupt has happened since the last time sd_app_evt_wait was
* called this function will return immediately and not go to sleep. This is to avoid race
* conditions that can occur when a flag is updated in the interrupt handler and processed
* in the main loop.
*
* @post An application interrupt has happened or a interrupt pending flag is set.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_APP_EVT_WAIT, uint32_t, sd_app_evt_wait(void));
/**@brief Get PPI channel enable register contents.
*
* @param[out] p_channel_enable The contents of the PPI CHEN register.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_PPI_CHANNEL_ENABLE_GET, uint32_t, sd_ppi_channel_enable_get(uint32_t * p_channel_enable));
/**@brief Set PPI channel enable register.
*
* @param[in] channel_enable_set_msk Mask containing the bits to set in the PPI CHEN register.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_PPI_CHANNEL_ENABLE_SET, uint32_t, sd_ppi_channel_enable_set(uint32_t channel_enable_set_msk));
/**@brief Clear PPI channel enable register.
*
* @param[in] channel_enable_clr_msk Mask containing the bits to clear in the PPI CHEN register.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_PPI_CHANNEL_ENABLE_CLR, uint32_t, sd_ppi_channel_enable_clr(uint32_t channel_enable_clr_msk));
/**@brief Assign endpoints to a PPI channel.
*
* @param[in] channel_num Number of the PPI channel to assign.
* @param[in] evt_endpoint Event endpoint of the PPI channel.
* @param[in] task_endpoint Task endpoint of the PPI channel.
*
* @retval ::NRF_ERROR_SOC_PPI_INVALID_CHANNEL The channel number is invalid.
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_PPI_CHANNEL_ASSIGN, uint32_t, sd_ppi_channel_assign(uint8_t channel_num, const volatile void * evt_endpoint, const volatile void * task_endpoint));
/**@brief Task to enable a channel group.
*
* @param[in] group_num Number of the channel group.
*
* @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_PPI_GROUP_TASK_ENABLE, uint32_t, sd_ppi_group_task_enable(uint8_t group_num));
/**@brief Task to disable a channel group.
*
* @param[in] group_num Number of the PPI group.
*
* @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid.
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_PPI_GROUP_TASK_DISABLE, uint32_t, sd_ppi_group_task_disable(uint8_t group_num));
/**@brief Assign PPI channels to a channel group.
*
* @param[in] group_num Number of the channel group.
* @param[in] channel_msk Mask of the channels to assign to the group.
*
* @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid.
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_PPI_GROUP_ASSIGN, uint32_t, sd_ppi_group_assign(uint8_t group_num, uint32_t channel_msk));
/**@brief Gets the PPI channels of a channel group.
*
* @param[in] group_num Number of the channel group.
* @param[out] p_channel_msk Mask of the channels assigned to the group.
*
* @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid.
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_PPI_GROUP_GET, uint32_t, sd_ppi_group_get(uint8_t group_num, uint32_t * p_channel_msk));
/**@brief Configures the Radio Notification signal.
*
* @note
* - The notification signal latency depends on the interrupt priority settings of SWI used
* for notification signal.
* - To ensure that the radio notification signal behaves in a consistent way, always
* configure radio notifications when there is no protocol stack or other SoftDevice
* activity in progress. It is recommended that the radio notification signal is
* configured directly after the SoftDevice has been enabled.
* - In the period between the ACTIVE signal and the start of the Radio Event, the SoftDevice
* will interrupt the application to do Radio Event preparation.
* - Using the Radio Notification feature may limit the bandwidth, as the SoftDevice may have
* to shorten the connection events to have time for the Radio Notification signals.
*
* @param[in] type Type of notification signal, see @ref NRF_RADIO_NOTIFICATION_TYPES.
* @ref NRF_RADIO_NOTIFICATION_TYPE_NONE shall be used to turn off radio
* notification. Using @ref NRF_RADIO_NOTIFICATION_DISTANCE_NONE is
* recommended (but not required) to be used with
* @ref NRF_RADIO_NOTIFICATION_TYPE_NONE.
*
* @param[in] distance Distance between the notification signal and start of radio activity, see @ref NRF_RADIO_NOTIFICATION_DISTANCES.
* This parameter is ignored when @ref NRF_RADIO_NOTIFICATION_TYPE_NONE or
* @ref NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE is used.
*
* @retval ::NRF_ERROR_INVALID_PARAM The group number is invalid.
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_RADIO_NOTIFICATION_CFG_SET, uint32_t, sd_radio_notification_cfg_set(uint8_t type, uint8_t distance));
/**@brief Encrypts a block according to the specified parameters.
*
* 128-bit AES encryption.
*
* @note:
* - The application may set the SEVONPEND bit in the SCR to 1 to make the SoftDevice sleep while
* the ECB is running. The SEVONPEND bit should only be cleared (set to 0) from application
* main or low interrupt level.
*
* @param[in, out] p_ecb_data Pointer to the ECB parameters' struct (two input
* parameters and one output parameter).
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_ECB_BLOCK_ENCRYPT, uint32_t, sd_ecb_block_encrypt(nrf_ecb_hal_data_t * p_ecb_data));
/**@brief Encrypts multiple data blocks provided as an array of data block structures.
*
* @details: Performs 128-bit AES encryption on multiple data blocks
*
* @note:
* - The application may set the SEVONPEND bit in the SCR to 1 to make the SoftDevice sleep while
* the ECB is running. The SEVONPEND bit should only be cleared (set to 0) from application
* main or low interrupt level.
*
* @param[in] block_count Count of blocks in the p_data_blocks array.
* @param[in,out] p_data_blocks Pointer to the first entry in a contiguous array of
* @ref nrf_ecb_hal_data_block_t structures.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_ECB_BLOCKS_ENCRYPT, uint32_t, sd_ecb_blocks_encrypt(uint8_t block_count, nrf_ecb_hal_data_block_t * p_data_blocks));
/**@brief Gets any pending events generated by the SoC API.
*
* The application should keep calling this function to get events, until ::NRF_ERROR_NOT_FOUND is returned.
*
* @param[out] p_evt_id Set to one of the values in @ref NRF_SOC_EVTS, if any events are pending.
*
* @retval ::NRF_SUCCESS An event was pending. The event id is written in the p_evt_id parameter.
* @retval ::NRF_ERROR_NOT_FOUND No pending events.
*/
SVCALL(SD_EVT_GET, uint32_t, sd_evt_get(uint32_t * p_evt_id));
/**@brief Get the temperature measured on the chip
*
* This function will block until the temperature measurement is done.
* It takes around 50us from call to return.
*
* @param[out] p_temp Result of temperature measurement. Die temperature in 0.25 degrees celsius.
*
* @retval ::NRF_SUCCESS A temperature measurement was done, and the temperature was written to temp
*/
SVCALL(SD_TEMP_GET, uint32_t, sd_temp_get(int32_t * p_temp));
/**@brief Flash Write
*
* Commands to write a buffer to flash
*
* If the SoftDevice is enabled:
* This call initiates the flash access command, and its completion will be communicated to the
* application with exactly one of the following events:
* - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed.
* - @ref NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started.
*
* If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the
* write has been completed
*
* @note
* - This call takes control over the radio and the CPU during flash erase and write to make sure that
* they will not interfere with the flash access. This means that all interrupts will be blocked
* for a predictable time (depending on the NVMC specification in nRF51 Series Reference Manual
* and the command parameters).
*
*
* @param[in] p_dst Pointer to start of flash location to be written.
* @param[in] p_src Pointer to buffer with data to be written.
* @param[in] size Number of 32-bit words to write. Maximum size is 256 32-bit words for nRF51 and 1024 for nRF52.
*
* @retval ::NRF_ERROR_INVALID_ADDR Tried to write to a non existing flash address, or p_dst or p_src was unaligned.
* @retval ::NRF_ERROR_BUSY The previous command has not yet completed.
* @retval ::NRF_ERROR_INVALID_LENGTH Size was 0, or higher than the maximum allowed size.
* @retval ::NRF_ERROR_FORBIDDEN Tried to write to or read from protected location.
* @retval ::NRF_SUCCESS The command was accepted.
*/
SVCALL(SD_FLASH_WRITE, uint32_t, sd_flash_write(uint32_t * const p_dst, uint32_t const * const p_src, uint32_t size));
/**@brief Flash Erase page
*
* Commands to erase a flash page
* If the SoftDevice is enabled:
* This call initiates the flash access command, and its completion will be communicated to the
* application with exactly one of the following events:
* - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed.
* - @ref NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started.
*
* If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the
* erase has been completed
*
* @note
* - This call takes control over the radio and the CPU during flash erase and write to make sure that
* they will not interfere with the flash access. This means that all interrupts will be blocked
* for a predictable time (depending on the NVMC specification in nRF51 Series Reference Manual
* and the command parameters).
*
*
* @param[in] page_number Pagenumber of the page to erase
* @retval ::NRF_ERROR_INTERNAL If a new session could not be opened due to an internal error.
* @retval ::NRF_ERROR_INVALID_ADDR Tried to erase to a non existing flash page.
* @retval ::NRF_ERROR_BUSY The previous command has not yet completed.
* @retval ::NRF_ERROR_FORBIDDEN Tried to erase a protected page.
* @retval ::NRF_SUCCESS The command was accepted.
*/
SVCALL(SD_FLASH_PAGE_ERASE, uint32_t, sd_flash_page_erase(uint32_t page_number));
/**@brief Flash Protection set
*
* Commands to set the flash protection configuration registers.
On nRF51 this sets the PROTENSETx registers of the MPU peripheral.
On nRF52 this sets the CONFIGx registers of the BPROT peripheral.
*
* @note To read the values read them directly. They are only write-protected.
*
* @param[in] block_cfg0 Value to be written to the configuration register.
* @param[in] block_cfg1 Value to be written to the configuration register.
* @param[in] block_cfg2 Value to be written to the configuration register (ignored on nRF51).
* @param[in] block_cfg3 Value to be written to the configuration register (ignored on nRF51).
*
* @retval ::NRF_ERROR_FORBIDDEN Tried to protect the SoftDevice.
* @retval ::NRF_SUCCESS Values successfully written to configuration registers.
*/
SVCALL(SD_FLASH_PROTECT, uint32_t, sd_flash_protect(uint32_t block_cfg0, uint32_t block_cfg1, uint32_t block_cfg2, uint32_t block_cfg3));
/**@brief Opens a session for radio timeslot requests.
*
* @note Only one session can be open at a time.
* @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) will be called when the radio timeslot
* starts. From this point the NRF_RADIO and NRF_TIMER0 peripherals can be freely accessed
* by the application.
* @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0) is called whenever the NRF_TIMER0
* interrupt occurs.
* @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO) is called whenever the NRF_RADIO
* interrupt occurs.
* @note p_radio_signal_callback() will be called at ARM interrupt priority level 0. This
* implies that none of the sd_* API calls can be used from p_radio_signal_callback().
*
* @param[in] p_radio_signal_callback The signal callback.
*
* @retval ::NRF_ERROR_INVALID_ADDR p_radio_signal_callback is an invalid function pointer.
* @retval ::NRF_ERROR_BUSY If session cannot be opened.
* @retval ::NRF_ERROR_INTERNAL If a new session could not be opened due to an internal error.
* @retval ::NRF_SUCCESS Otherwise.
*/
SVCALL(SD_RADIO_SESSION_OPEN, uint32_t, sd_radio_session_open(nrf_radio_signal_callback_t p_radio_signal_callback));
/**@brief Closes a session for radio timeslot requests.
*
* @note Any current radio timeslot will be finished before the session is closed.
* @note If a radio timeslot is scheduled when the session is closed, it will be canceled.
* @note The application cannot consider the session closed until the @ref NRF_EVT_RADIO_SESSION_CLOSED
* event is received.
*
* @retval ::NRF_ERROR_FORBIDDEN If session not opened.
* @retval ::NRF_ERROR_BUSY If session is currently being closed.
* @retval ::NRF_SUCCESS Otherwise.
*/
SVCALL(SD_RADIO_SESSION_CLOSE, uint32_t, sd_radio_session_close(void));
/**@brief Requests a radio timeslot.
*
* @note The request type is determined by p_request->request_type, and can be one of @ref NRF_RADIO_REQ_TYPE_EARLIEST
* and @ref NRF_RADIO_REQ_TYPE_NORMAL. The first request in a session must always be of type @ref NRF_RADIO_REQ_TYPE_EARLIEST.
* @note For a normal request (@ref NRF_RADIO_REQ_TYPE_NORMAL), the start time of a radio timeslot is specified by
* p_request->distance_us and is given relative to the start of the previous timeslot.
* @note A too small p_request->distance_us will lead to a @ref NRF_EVT_RADIO_BLOCKED event.
* @note Timeslots scheduled too close will lead to a @ref NRF_EVT_RADIO_BLOCKED event.
* @note See the SoftDevice Specification for more on radio timeslot scheduling, distances and lengths.
* @note If an opportunity for the first radio timeslot is not found before 100ms after the call to this
* function, it is not scheduled, and instead a @ref NRF_EVT_RADIO_BLOCKED event is sent.
* The application may then try to schedule the first radio timeslot again.
* @note Successful requests will result in nrf_radio_signal_callback_t(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START).
* Unsuccessful requests will result in a @ref NRF_EVT_RADIO_BLOCKED event, see @ref NRF_SOC_EVTS.
* @note The jitter in the start time of the radio timeslots is +/- @ref NRF_RADIO_START_JITTER_US us.
* @note The nrf_radio_signal_callback_t(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) call has a latency relative to the
* specified radio timeslot start, but this does not affect the actual start time of the timeslot.
* @note NRF_TIMER0 is reset at the start of the radio timeslot, and is clocked at 1MHz from the high frequency
* (16 MHz) clock source. If p_request->hfclk_force_xtal is true, the high frequency clock is
* guaranteed to be clocked from the external crystal.
* @note The SoftDevice will neither access the NRF_RADIO peripheral nor the NRF_TIMER0 peripheral
* during the radio timeslot.
*
* @param[in] p_request Pointer to the request parameters.
*
* @retval ::NRF_ERROR_FORBIDDEN If session not opened or the session is not IDLE.
* @retval ::NRF_ERROR_INVALID_ADDR If the p_request pointer is invalid.
* @retval ::NRF_ERROR_INVALID_PARAM If the parameters of p_request are not valid.
* @retval ::NRF_SUCCESS Otherwise.
*/
SVCALL(SD_RADIO_REQUEST, uint32_t, sd_radio_request(nrf_radio_request_t * p_request ));
/**@} */
#ifdef __cplusplus
}
#endif
#endif // NRF_SOC_H__
/**@} */

View File

@ -0,0 +1,88 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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.
*
*/
#ifndef NRF_SVC__
#define NRF_SVC__
#include "stdint.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef SVCALL_AS_NORMAL_FUNCTION
#define SVCALL(number, return_type, signature) return_type signature
#else
#ifndef SVCALL
#if defined (__CC_ARM)
#define SVCALL(number, return_type, signature) return_type __svc(number) signature
#elif defined (__GNUC__)
#ifdef __cplusplus
#define GCC_CAST_CPP (uint8_t)
#else
#define GCC_CAST_CPP
#endif
#define SVCALL(number, return_type, signature) \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \
__attribute__((naked)) \
__attribute__((unused)) \
static return_type signature \
{ \
__asm( \
"svc %0\n" \
"bx r14" : : "I" (GCC_CAST_CPP number) : "r0" \
); \
} \
_Pragma("GCC diagnostic pop")
#elif defined (__ICCARM__)
#define PRAGMA(x) _Pragma(#x)
#define SVCALL(number, return_type, signature) \
PRAGMA(swi_number = (number)) \
__swi return_type signature;
#else
#define SVCALL(number, return_type, signature) return_type signature
#endif
#endif // SVCALL
#endif // SVCALL_AS_NORMAL_FUNCTION
#ifdef __cplusplus
}
#endif
#endif // NRF_SVC__

View File

@ -0,0 +1,632 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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.
*
*/
/**
@addtogroup BLE_COMMON BLE SoftDevice Common
@{
@defgroup ble_api Events, type definitions and API calls
@{
@brief Module independent events, type definitions and API calls for the BLE SoftDevice.
*/
#ifndef BLE_H__
#define BLE_H__
#include "ble_ranges.h"
#include "ble_types.h"
#include "ble_gap.h"
#include "ble_l2cap.h"
#include "ble_gatt.h"
#include "ble_gattc.h"
#include "ble_gatts.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup BLE_COMMON_ENUMERATIONS Enumerations
* @{ */
/**
* @brief Common API SVC numbers.
*/
enum BLE_COMMON_SVCS
{
SD_BLE_ENABLE = BLE_SVC_BASE, /**< Enable and initialize the BLE stack */
SD_BLE_EVT_GET, /**< Get an event from the pending events queue. */
SD_BLE_TX_PACKET_COUNT_GET, /**< Get the total number of available application transmission packets for a particular connection. */
SD_BLE_UUID_VS_ADD, /**< Add a Vendor Specific UUID. */
SD_BLE_UUID_DECODE, /**< Decode UUID bytes. */
SD_BLE_UUID_ENCODE, /**< Encode UUID bytes. */
SD_BLE_VERSION_GET, /**< Get the local version information (company id, Link Layer Version, Link Layer Subversion). */
SD_BLE_USER_MEM_REPLY, /**< User Memory Reply. */
SD_BLE_OPT_SET, /**< Set a BLE option. */
SD_BLE_OPT_GET, /**< Get a BLE option. */
};
/**
* @brief BLE Module Independent Event IDs.
*/
enum BLE_COMMON_EVTS
{
BLE_EVT_TX_COMPLETE = BLE_EVT_BASE, /**< Transmission Complete. @ref ble_evt_tx_complete_t */
BLE_EVT_USER_MEM_REQUEST, /**< User Memory request. @ref ble_evt_user_mem_request_t */
BLE_EVT_USER_MEM_RELEASE /**< User Memory release. @ref ble_evt_user_mem_release_t */
};
/**@brief BLE connection bandwidth types.
* Bandwidth types supported by the SoftDevice in packets per connection interval.
*/
enum BLE_CONN_BWS
{
BLE_CONN_BW_NONE = 0,
BLE_CONN_BW_LOW,
BLE_CONN_BW_MID,
BLE_CONN_BW_HIGH
};
/**@brief Common Option IDs.
* IDs that uniquely identify a common option.
*/
enum BLE_COMMON_OPTS
{
BLE_COMMON_OPT_CONN_BW = BLE_OPT_BASE, /**< Bandwidth configuration @ref ble_common_opt_conn_bw_t */
BLE_COMMON_OPT_PA_LNA /**< PA and LNA options */
};
/** @} */
/** @addtogroup BLE_COMMON_DEFINES Defines
* @{ */
/** @brief Required pointer alignment for BLE Events.
*/
#define BLE_EVTS_PTR_ALIGNMENT 4
/** @defgroup BLE_USER_MEM_TYPES User Memory Types
* @{ */
#define BLE_USER_MEM_TYPE_INVALID 0x00 /**< Invalid User Memory Types. */
#define BLE_USER_MEM_TYPE_GATTS_QUEUED_WRITES 0x01 /**< User Memory for GATTS queued writes. */
/** @} */
/** @defgroup BLE_UUID_VS_COUNTS Vendor Specific UUID counts
* @{
*/
#define BLE_UUID_VS_COUNT_MIN 1 /**< Minimum VS UUID count. */
#define BLE_UUID_VS_COUNT_DEFAULT 0 /**< Use the default VS UUID count (10 for this version of the SoftDevice). */
/** @} */
/** @} */
/** @addtogroup BLE_COMMON_STRUCTURES Structures
* @{ */
/**@brief User Memory Block. */
typedef struct
{
uint8_t *p_mem; /**< Pointer to the start of the user memory block. */
uint16_t len; /**< Length in bytes of the user memory block. */
} ble_user_mem_block_t;
/**
* @brief Event structure for @ref BLE_EVT_TX_COMPLETE.
*/
typedef struct
{
uint8_t count; /**< Number of packets transmitted. */
} ble_evt_tx_complete_t;
/**@brief Event structure for @ref BLE_EVT_USER_MEM_REQUEST. */
typedef struct
{
uint8_t type; /**< User memory type, see @ref BLE_USER_MEM_TYPES. */
} ble_evt_user_mem_request_t;
/**@brief Event structure for @ref BLE_EVT_USER_MEM_RELEASE. */
typedef struct
{
uint8_t type; /**< User memory type, see @ref BLE_USER_MEM_TYPES. */
ble_user_mem_block_t mem_block; /**< User memory block */
} ble_evt_user_mem_release_t;
/**@brief Event structure for events not associated with a specific function module. */
typedef struct
{
uint16_t conn_handle; /**< Connection Handle on which this event occurred. */
union
{
ble_evt_tx_complete_t tx_complete; /**< Transmission Complete. */
ble_evt_user_mem_request_t user_mem_request; /**< User Memory Request Event Parameters. */
ble_evt_user_mem_release_t user_mem_release; /**< User Memory Release Event Parameters. */
} params;
} ble_common_evt_t;
/**@brief BLE Event header. */
typedef struct
{
uint16_t evt_id; /**< Value from a BLE_<module>_EVT series. */
uint16_t evt_len; /**< Length in octets including this header. */
} ble_evt_hdr_t;
/**@brief Common BLE Event type, wrapping the module specific event reports. */
typedef struct
{
ble_evt_hdr_t header; /**< Event header. */
union
{
ble_common_evt_t common_evt; /**< Common Event, evt_id in BLE_EVT_* series. */
ble_gap_evt_t gap_evt; /**< GAP originated event, evt_id in BLE_GAP_EVT_* series. */
ble_l2cap_evt_t l2cap_evt; /**< L2CAP originated event, evt_id in BLE_L2CAP_EVT* series. */
ble_gattc_evt_t gattc_evt; /**< GATT client originated event, evt_id in BLE_GATTC_EVT* series. */
ble_gatts_evt_t gatts_evt; /**< GATT server originated event, evt_id in BLE_GATTS_EVT* series. */
} evt;
} ble_evt_t;
/**
* @brief Version Information.
*/
typedef struct
{
uint8_t version_number; /**< Link Layer Version number for BT 4.1 spec is 7 (https://www.bluetooth.org/en-us/specification/assigned-numbers/link-layer). */
uint16_t company_id; /**< Company ID, Nordic Semiconductor's company ID is 89 (0x0059) (https://www.bluetooth.org/apps/content/Default.aspx?doc_id=49708). */
uint16_t subversion_number; /**< Link Layer Sub Version number, corresponds to the SoftDevice Config ID or Firmware ID (FWID). */
} ble_version_t;
/* @brief: Configuration parameters for the PA and LNA. */
typedef struct
{
uint8_t enable :1; /**< Enable toggling for this amplifier */
uint8_t active_high :1; /**< Set the pin to be active high */
uint8_t gpio_pin :6; /**< The GPIO pin to toggle for this amplifier */
} ble_pa_lna_cfg_t;
/*
* @brief PA & LNA GPIO toggle configuration
*
* This option configures the SoftDevice to toggle pins when the radio is active for use with a power amplifier and/or
* a low noise amplifier.
*
* Toggling the pins is achieved by using two PPI channels and a GPIOTE channel. The hardware channel IDs are provided
* by the application and should be regarded as reserved as long as any PA/LNA toggling is enabled.
*
* @note @ref sd_ble_opt_get is not supported for this option.
* @note This feature is only supported for nRF52, on nRF51 @ref NRF_ERROR_NOT_SUPPORTED will always be returned.
* @note Setting this option while the radio is in use (i.e. any of the roles are active) may have undefined consequences
* and must be avoided by the application.
*
*/
typedef struct
{
ble_pa_lna_cfg_t pa_cfg; /**< Power Amplifier configuration */
ble_pa_lna_cfg_t lna_cfg; /**< Low Noise Amplifier configuration */
uint8_t ppi_ch_id_set; /**< PPI channel used for radio pin setting */
uint8_t ppi_ch_id_clr; /**< PPI channel used for radio pin clearing */
uint8_t gpiote_ch_id; /**< GPIOTE channel used for radio pin toggling */
} ble_common_opt_pa_lna_t;
/**
* @brief BLE connection bandwidth configuration parameters
*/
typedef struct
{
uint8_t conn_bw_tx; /**< Connection bandwidth configuration for transmission, see @ref BLE_CONN_BWS.*/
uint8_t conn_bw_rx; /**< Connection bandwidth configuration for reception, see @ref BLE_CONN_BWS.*/
} ble_conn_bw_t;
/**@brief BLE connection specific bandwidth configuration parameters.
*
* This can be used with @ref sd_ble_opt_set to set the bandwidth configuration to be used when creating connections.
*
* Call @ref sd_ble_opt_set with this option prior to calling @ref sd_ble_gap_adv_start or @ref sd_ble_gap_connect.
*
* The bandwidth configurations set via @ref sd_ble_opt_set are maintained separately for central and peripheral
* connections. The given configurations are used for all future connections of the role indicated in this structure
* unless they are changed by subsequent @ref sd_ble_opt_set calls.
*
* @note When this option is not used, the SoftDevice will use the default options:
* - @ref BLE_CONN_BW_HIGH for @ref BLE_GAP_ROLE_PERIPH connections (both transmission and reception).
* - @ref BLE_CONN_BW_MID for @ref BLE_GAP_ROLE_CENTRAL connections (both transmisison and reception).
* This option allows the application to selectively override these defaults for each role.
*
* @note The global memory pool configuration can be set with the @ref ble_conn_bw_counts_t configuration parameter, which
* is provided to @ref sd_ble_enable.
*
* @note Please refer to SoftDevice Specification for more information on bandwidth configuration.
*
* @mscs
* @mmsc{@ref BLE_COMMON_CONF_BW}
* @endmscs
*
* @retval ::NRF_SUCCESS Set successfully.
* @retval ::BLE_ERROR_INVALID_ROLE The role is invalid.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid bandwidth configuration parameters.
* @retval ::NRF_ERROR_NOT_SUPPORTED If the combination of role and bandwidth configuration is not supported.
*/
typedef struct
{
uint8_t role; /**< BLE role of the connection, see @ref BLE_GAP_ROLES. */
ble_conn_bw_t conn_bw; /**< Bandwidth configuration parameters. */
} ble_common_opt_conn_bw_t;
/**@brief Option structure for common options. */
typedef union
{
ble_common_opt_conn_bw_t conn_bw; /**< Parameters for the connection bandwidth option. */
ble_common_opt_pa_lna_t pa_lna; /**< Parameters for controlling PA and LNA pin toggling. */
} ble_common_opt_t;
/**@brief Common BLE Option type, wrapping the module specific options. */
typedef union
{
ble_common_opt_t common_opt; /**< COMMON options, opt_id in @ref BLE_COMMON_OPTS series. */
ble_gap_opt_t gap_opt; /**< GAP option, opt_id in @ref BLE_GAP_OPTS series. */
} ble_opt_t;
/**
* @brief BLE bandwidth count parameters
*
* These parameters are used to configure the memory pools allocated within the SoftDevice for application packets
* (both transmission and reception) for all connections.
*
* @note The sum of all three counts must add up to the sum of @ref ble_gap_enable_params_t::central_conn_count and
* @ref ble_gap_enable_params_t::periph_conn_count in @ref ble_gap_enable_params_t.
*/
typedef struct {
uint8_t high_count; /**< Total number of high bandwidth TX or RX memory pools available to the application at runtime for all active connections. */
uint8_t mid_count; /**< Total number of medium bandwidth TX or RX memory pools available to the application at runtime for all active connections. */
uint8_t low_count; /**< Total number of low bandwidth TX or RX memory pools available to the application at runtime for all active connections. */
} ble_conn_bw_count_t;
/**
* @brief BLE bandwidth global memory pool configuration parameters
*
* These configuration parameters are used to set the amount of memory dedicated to application packets for
* all connections. The application should specify the most demanding configuration for the intended use.
*
* Please refer to the SoftDevice Specification for more information on bandwidth configuration.
*
* @note Each connection created at runtime requires both a TX and an RX memory pool. By the use of these configuration
* parameters, the application can decide the size and total number of the global memory pools that will be later
* available for connection creation.
*
* @mscs
* @mmsc{@ref BLE_COMMON_CONF_BW}
* @endmscs
*
*/
typedef struct {
ble_conn_bw_count_t tx_counts; /**< Global memory pool configuration for transmission.*/
ble_conn_bw_count_t rx_counts; /**< Global memory pool configuration for reception.*/
} ble_conn_bw_counts_t;
/**
* @brief BLE Common Initialization parameters.
*
* @note If @ref p_conn_bw_counts is NULL the SoftDevice will assume default bandwidth configuration for all connections.
* To fit a custom bandwidth configuration requirement, the application developer may have to specify a custom memory
* pool configuration here. See @ref ble_common_opt_conn_bw_t for bandwidth configuration of individual connections.
* Please refer to the SoftDevice Specification for more information on bandwidth configuration.
*/
typedef struct
{
uint16_t vs_uuid_count; /**< Maximum number of 128-bit, Vendor Specific UUID bases to allocate. */
ble_conn_bw_counts_t *p_conn_bw_counts; /**< Bandwidth configuration parameters or NULL for defaults. */
} ble_common_enable_params_t;
/**
* @brief BLE Initialization parameters.
*/
typedef struct
{
ble_common_enable_params_t common_enable_params; /**< Common init parameters @ref ble_common_enable_params_t. */
ble_gap_enable_params_t gap_enable_params; /**< GAP init parameters @ref ble_gap_enable_params_t. */
ble_gatts_enable_params_t gatts_enable_params; /**< GATTS init parameters @ref ble_gatts_enable_params_t. */
} ble_enable_params_t;
/** @} */
/** @addtogroup BLE_COMMON_FUNCTIONS Functions
* @{ */
/**@brief Enable the BLE stack
*
* @param[in, out] p_ble_enable_params Pointer to ble_enable_params_t
* @param[in, out] p_app_ram_base Pointer to a variable containing the start address of the application RAM region
* (APP_RAM_BASE). On return, this will contain the minimum start address of the application RAM region required by the
* SoftDevice for this configuration. Calling @ref sd_ble_enable() with *p_app_ram_base set to 0 can be used during
* development to find out how much memory a specific configuration will need.
*
* @note The memory requirement for a specific configuration will not increase between SoftDevices with the same major
* version number.
*
* @note At runtime the IC's RAM is split into 2 regions: The SoftDevice RAM region is located between 0x20000000 and
* APP_RAM_BASE-1 and the application's RAM region is located between APP_RAM_BASE and the start of the call stack.
*
* @details This call initializes the BLE stack, no other BLE related function can be called before this one.
*
* @mscs
* @mmsc{@ref BLE_COMMON_ENABLE}
* @endmscs
*
* @retval ::NRF_SUCCESS The BLE stack has been initialized successfully.
* @retval ::NRF_ERROR_INVALID_STATE The BLE stack had already been initialized and cannot be reinitialized.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied.
* @retval ::NRF_ERROR_INVALID_LENGTH The specified Attribute Table size is either too small or not a multiple of 4.
* The minimum acceptable size is defined by @ref BLE_GATTS_ATTR_TAB_SIZE_MIN.
* @retval ::NRF_ERROR_INVALID_PARAM Incorrectly configured VS UUID count or connection count parameters.
* @retval ::NRF_ERROR_NO_MEM The amount of memory assigned to the SoftDevice by *p_app_ram_base is not
* large enough to fit this configuration's memory requirement. Check *p_app_ram_base
* and set the start address of the application RAM region accordingly.
* @retval ::NRF_ERROR_CONN_COUNT The requested number of connections exceeds the maximum supported by the SoftDevice.
* Please refer to the SoftDevice Specification for more information on role configuration.
*/
SVCALL(SD_BLE_ENABLE, uint32_t, sd_ble_enable(ble_enable_params_t * p_ble_enable_params, uint32_t * p_app_ram_base));
/**@brief Get an event from the pending events queue.
*
* @param[out] p_dest Pointer to buffer to be filled in with an event, or NULL to retrieve the event length.
* This buffer <b>must be 4-byte aligned in memory</b>.
* @param[in, out] p_len Pointer the length of the buffer, on return it is filled with the event length.
*
* @details This call allows the application to pull a BLE event from the BLE stack. The application is signaled that
* an event is available from the BLE stack by the triggering of the SD_EVT_IRQn interrupt.
* The application is free to choose whether to call this function from thread mode (main context) or directly from the
* Interrupt Service Routine that maps to SD_EVT_IRQn. In any case however, and because the BLE stack runs at a higher
* priority than the application, this function should be called in a loop (until @ref NRF_ERROR_NOT_FOUND is returned)
* every time SD_EVT_IRQn is raised to ensure that all available events are pulled from the BLE stack. Failure to do so
* could potentially leave events in the internal queue without the application being aware of this fact. Sizing the
* p_dest buffer is equally important, since the application needs to provide all the memory necessary for the event to
* be copied into application memory. If the buffer provided is not large enough to fit the entire contents of the event,
* @ref NRF_ERROR_DATA_SIZE will be returned and the application can then call again with a larger buffer size.
* Please note that because of the variable length nature of some events, sizeof(ble_evt_t) will not always be large
* enough to fit certain events, and so it is the application's responsibility to provide an amount of memory large
* enough so that the relevant event is copied in full. The application may "peek" the event length by providing p_dest
* as a NULL pointer and inspecting the value of *p_len upon return:
*
* \code
* uint16_t len;
* errcode = sd_ble_evt_get(NULL, &len);
* \endcode
*
* @note The pointer supplied must be aligned to the extend defined by @ref BLE_EVTS_PTR_ALIGNMENT
*
* @mscs
* @mmsc{@ref BLE_COMMON_IRQ_EVT_MSC}
* @mmsc{@ref BLE_COMMON_THREAD_EVT_MSC}
* @endmscs
*
* @retval ::NRF_SUCCESS Event pulled and stored into the supplied buffer.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied.
* @retval ::NRF_ERROR_NOT_FOUND No events ready to be pulled.
* @retval ::NRF_ERROR_DATA_SIZE Event ready but could not fit into the supplied buffer.
*/
SVCALL(SD_BLE_EVT_GET, uint32_t, sd_ble_evt_get(uint8_t *p_dest, uint16_t *p_len));
/**@brief Get the total number of available guaranteed application transmission packets for a particular connection.
*
* @details This call allows the application to obtain the total number of guaranteed application transmission packets
* available for a connection. Please note that this does not return the number of free packets, but rather the total
* amount of them for that particular connection. The application has two options to handle transmitting application packets:
* - Use a simple arithmetic calculation: after connection creation time the application should use this function to
* find out the total amount of guaranteed packets available to it and store it in a variable.
* Every time a packet is successfully queued for a transmission on this connection using any of the exposed functions in
* this BLE API, the application should decrement that variable. Conversely, whenever a @ref BLE_EVT_TX_COMPLETE event
* with the conn_handle matching the particular connection is received by the application, it should retrieve the count
* field in such event and add that number to the same variable storing the number of available guaranteed packets. This
* mechanism allows the application to be aware at any time of the number of guaranteed application packets available for
* each of the active connections, and therefore it can know with certainty whether it is possible to send more data or
* it has to wait for a @ref BLE_EVT_TX_COMPLETE event before it proceeds.
* The application can still pursue transmissions when the number of guaranteed application packets available is smaller
* than or equal to zero, but successful queuing of the tranmsission is not guaranteed.
* - Choose to simply not keep track of available packets at all, and instead handle the @ref BLE_ERROR_NO_TX_PACKETS error
* by queueing the packet to be transmitted and try again as soon as a @ref BLE_EVT_TX_COMPLETE event arrives.
*
* The API functions that <b>may</b> consume an application packet depending on the parameters supplied to them can be found below:
* - @ref sd_ble_gattc_write (write without response only)
* - @ref sd_ble_gatts_hvx (notifications only)
* - @ref sd_ble_l2cap_tx (all packets)
*
* @param[in] conn_handle Connection handle.
* @param[out] p_count Pointer to a uint8_t which will contain the number of application transmission packets upon
* successful return.
* @mscs
* @mmsc{@ref BLE_COMMON_APP_BUFF_MSC}
* @endmscs
*
* @retval ::NRF_SUCCESS Number of application transmission packets retrieved successfully.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
*/
SVCALL(SD_BLE_TX_PACKET_COUNT_GET, uint32_t, sd_ble_tx_packet_count_get(uint16_t conn_handle, uint8_t *p_count));
/**@brief Add a Vendor Specific UUID.
*
* @details This call enables the application to add a vendor specific UUID to the BLE stack's table, for later use
* all other modules and APIs. This then allows the application to use the shorter, 24-bit @ref ble_uuid_t format
* when dealing with both 16-bit and 128-bit UUIDs without having to check for lengths and having split code paths.
* The way that this is accomplished is by extending the grouping mechanism that the Bluetooth SIG standard base
* UUID uses for all other 128-bit UUIDs. The type field in the @ref ble_uuid_t structure is an index (relative to
* @ref BLE_UUID_TYPE_VENDOR_BEGIN) to the table populated by multiple calls to this function, and the uuid field
* in the same structure contains the 2 bytes at indices 12 and 13. The number of possible 128-bit UUIDs available to
* the application is therefore the number of Vendor Specific UUIDs added with the help of this function times 65536,
* although restricted to modifying bytes 12 and 13 for each of the entries in the supplied array.
*
* @note Bytes 12 and 13 of the provided UUID will not be used internally, since those are always replaced by
* the 16-bit uuid field in @ref ble_uuid_t.
*
* @note If a UUID is already present in the BLE stack's internal table, the corresponding index will be returned in
* p_uuid_type along with an NRF_SUCCESS error code.
*
* @param[in] p_vs_uuid Pointer to a 16-octet (128-bit) little endian Vendor Specific UUID disregarding
* bytes 12 and 13.
* @param[out] p_uuid_type Pointer to a uint8_t where the type field in @ref ble_uuid_t corresponding to this UUID will be stored.
*
* @retval ::NRF_SUCCESS Successfully added the Vendor Specific UUID.
* @retval ::NRF_ERROR_INVALID_ADDR If p_vs_uuid or p_uuid_type is NULL or invalid.
* @retval ::NRF_ERROR_NO_MEM If there are no more free slots for VS UUIDs.
*/
SVCALL(SD_BLE_UUID_VS_ADD, uint32_t, sd_ble_uuid_vs_add(ble_uuid128_t const *p_vs_uuid, uint8_t *p_uuid_type));
/** @brief Decode little endian raw UUID bytes (16-bit or 128-bit) into a 24 bit @ref ble_uuid_t structure.
*
* @details The raw UUID bytes excluding bytes 12 and 13 (i.e. bytes 0-11 and 14-15) of p_uuid_le are compared
* to the corresponding ones in each entry of the table of vendor specific UUIDs populated with @ref sd_ble_uuid_vs_add
* to look for a match. If there is such a match, bytes 12 and 13 are returned as p_uuid->uuid and the index
* relative to @ref BLE_UUID_TYPE_VENDOR_BEGIN as p_uuid->type.
*
* @note If the UUID length supplied is 2, then the type set by this call will always be @ref BLE_UUID_TYPE_BLE.
*
* @param[in] uuid_le_len Length in bytes of the buffer pointed to by p_uuid_le (must be 2 or 16 bytes).
* @param[in] p_uuid_le Pointer pointing to little endian raw UUID bytes.
* @param[out] p_uuid Pointer to a @ref ble_uuid_t structure to be filled in.
*
* @retval ::NRF_SUCCESS Successfully decoded into the @ref ble_uuid_t structure.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_INVALID_LENGTH Invalid UUID length.
* @retval ::NRF_ERROR_NOT_FOUND For a 128-bit UUID, no match in the populated table of UUIDs.
*/
SVCALL(SD_BLE_UUID_DECODE, uint32_t, sd_ble_uuid_decode(uint8_t uuid_le_len, uint8_t const *p_uuid_le, ble_uuid_t *p_uuid));
/** @brief Encode a @ref ble_uuid_t structure into little endian raw UUID bytes (16-bit or 128-bit).
*
* @note The pointer to the destination buffer p_uuid_le may be NULL, in which case only the validity and size of p_uuid is computed.
*
* @param[in] p_uuid Pointer to a @ref ble_uuid_t structure that will be encoded into bytes.
* @param[out] p_uuid_le_len Pointer to a uint8_t that will be filled with the encoded length (2 or 16 bytes).
* @param[out] p_uuid_le Pointer to a buffer where the little endian raw UUID bytes (2 or 16) will be stored.
*
* @retval ::NRF_SUCCESS Successfully encoded into the buffer.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid UUID type.
*/
SVCALL(SD_BLE_UUID_ENCODE, uint32_t, sd_ble_uuid_encode(ble_uuid_t const *p_uuid, uint8_t *p_uuid_le_len, uint8_t *p_uuid_le));
/**@brief Get Version Information.
*
* @details This call allows the application to get the BLE stack version information.
*
* @param[out] p_version Pointer to a ble_version_t structure to be filled in.
*
* @retval ::NRF_SUCCESS Version information stored successfully.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_BUSY The BLE stack is busy (typically doing a locally-initiated disconnection procedure).
*/
SVCALL(SD_BLE_VERSION_GET, uint32_t, sd_ble_version_get(ble_version_t *p_version));
/**@brief Provide a user memory block.
*
* @note This call can only be used as a response to a @ref BLE_EVT_USER_MEM_REQUEST event issued to the application.
*
* @param[in] conn_handle Connection handle.
* @param[in,out] p_block Pointer to a user memory block structure.
*
* @mscs
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_PEER_CANCEL_MSC}
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC}
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC}
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC}
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_NOAUTH_MSC}
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC}
* @endmscs
*
* @retval ::NRF_SUCCESS Successfully queued a response to the peer.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection state or no execute write request pending.
* @retval ::NRF_ERROR_BUSY The BLE stack is busy. Retry at later time.
*/
SVCALL(SD_BLE_USER_MEM_REPLY, uint32_t, sd_ble_user_mem_reply(uint16_t conn_handle, ble_user_mem_block_t const *p_block));
/**@brief Set a BLE option.
*
* @details This call allows the application to set the value of an option.
*
* @mscs
* @mmsc{@ref BLE_GAP_PERIPH_BONDING_STATIC_PK_MSC}
* @mmsc{@ref BLE_COMMON_CONF_BW}
* @endmscs
*
* @param[in] opt_id Option ID, see @ref BLE_COMMON_OPTS and @ref BLE_GAP_OPTS.
* @param[in] p_opt Pointer to a ble_opt_t structure containing the option value.
*
* @retval ::NRF_SUCCESS Option set successfully.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints.
* @retval ::NRF_ERROR_INVALID_STATE Unable to set the parameter at this time.
* @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed.
*/
SVCALL(SD_BLE_OPT_SET, uint32_t, sd_ble_opt_set(uint32_t opt_id, ble_opt_t const *p_opt));
/**@brief Get a BLE option.
*
* @details This call allows the application to retrieve the value of an option.
*
* @param[in] opt_id Option ID, see @ref BLE_COMMON_OPTS and @ref BLE_GAP_OPTS.
* @param[out] p_opt Pointer to a ble_opt_t structure to be filled in.
*
* @retval ::NRF_SUCCESS Option retrieved successfully.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints.
* @retval ::NRF_ERROR_INVALID_STATE Unable to retrieve the parameter at this time.
* @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed.
* @retval ::NRF_ERROR_NOT_SUPPORTED This option is not supported.
*
*/
SVCALL(SD_BLE_OPT_GET, uint32_t, sd_ble_opt_get(uint32_t opt_id, ble_opt_t *p_opt));
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* BLE_H__ */
/**
@}
@}
*/

View File

@ -0,0 +1,90 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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.
*
*/
/**
@addtogroup BLE_COMMON
@{
@addtogroup nrf_error
@{
@ingroup BLE_COMMON
@}
@defgroup ble_err General error codes
@{
@brief General error code definitions for the BLE API.
@ingroup BLE_COMMON
*/
#ifndef NRF_BLE_ERR_H__
#define NRF_BLE_ERR_H__
#include "nrf_error.h"
#ifdef __cplusplus
extern "C" {
#endif
/* @defgroup BLE_ERRORS Error Codes
* @{ */
#define BLE_ERROR_NOT_ENABLED (NRF_ERROR_STK_BASE_NUM+0x001) /**< @ref sd_ble_enable has not been called. */
#define BLE_ERROR_INVALID_CONN_HANDLE (NRF_ERROR_STK_BASE_NUM+0x002) /**< Invalid connection handle. */
#define BLE_ERROR_INVALID_ATTR_HANDLE (NRF_ERROR_STK_BASE_NUM+0x003) /**< Invalid attribute handle. */
#define BLE_ERROR_NO_TX_PACKETS (NRF_ERROR_STK_BASE_NUM+0x004) /**< Not enough application packets available on this connection. */
#define BLE_ERROR_INVALID_ROLE (NRF_ERROR_STK_BASE_NUM+0x005) /**< Invalid role. */
/** @} */
/** @defgroup BLE_ERROR_SUBRANGES Module specific error code subranges
* @brief Assignment of subranges for module specific error codes.
* @note For specific error codes, see ble_<module>.h or ble_error_<module>.h.
* @{ */
#define NRF_L2CAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x100) /**< L2CAP specific errors. */
#define NRF_GAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x200) /**< GAP specific errors. */
#define NRF_GATTC_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x300) /**< GATT client specific errors. */
#define NRF_GATTS_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x400) /**< GATT server specific errors. */
/** @} */
#ifdef __cplusplus
}
#endif
#endif
/**
@}
@}
*/

View File

@ -0,0 +1,212 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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.
*
*/
/**
@addtogroup BLE_GATT Generic Attribute Profile (GATT) Common
@{
@brief Common definitions and prototypes for the GATT interfaces.
*/
#ifndef BLE_GATT_H__
#define BLE_GATT_H__
#include "ble_types.h"
#include "ble_ranges.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup BLE_GATT_DEFINES Defines
* @{ */
/** @brief Default MTU size. */
#define GATT_MTU_SIZE_DEFAULT 23
/** @brief Only the default MTU size of 23 is currently supported. */
#define GATT_RX_MTU 23
/**@brief Invalid Attribute Handle. */
#define BLE_GATT_HANDLE_INVALID 0x0000
/**@brief First Attribute Handle. */
#define BLE_GATT_HANDLE_START 0x0001
/**@brief Last Attribute Handle. */
#define BLE_GATT_HANDLE_END 0xFFFF
/** @defgroup BLE_GATT_TIMEOUT_SOURCES GATT Timeout sources
* @{ */
#define BLE_GATT_TIMEOUT_SRC_PROTOCOL 0x00 /**< ATT Protocol timeout. */
/** @} */
/** @defgroup BLE_GATT_WRITE_OPS GATT Write operations
* @{ */
#define BLE_GATT_OP_INVALID 0x00 /**< Invalid Operation. */
#define BLE_GATT_OP_WRITE_REQ 0x01 /**< Write Request. */
#define BLE_GATT_OP_WRITE_CMD 0x02 /**< Write Command. */
#define BLE_GATT_OP_SIGN_WRITE_CMD 0x03 /**< Signed Write Command. */
#define BLE_GATT_OP_PREP_WRITE_REQ 0x04 /**< Prepare Write Request. */
#define BLE_GATT_OP_EXEC_WRITE_REQ 0x05 /**< Execute Write Request. */
/** @} */
/** @defgroup BLE_GATT_EXEC_WRITE_FLAGS GATT Execute Write flags
* @{ */
#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL 0x00
#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE 0x01
/** @} */
/** @defgroup BLE_GATT_HVX_TYPES GATT Handle Value operations
* @{ */
#define BLE_GATT_HVX_INVALID 0x00 /**< Invalid Operation. */
#define BLE_GATT_HVX_NOTIFICATION 0x01 /**< Handle Value Notification. */
#define BLE_GATT_HVX_INDICATION 0x02 /**< Handle Value Indication. */
/** @} */
/** @defgroup BLE_GATT_STATUS_CODES GATT Status Codes
* @{ */
#define BLE_GATT_STATUS_SUCCESS 0x0000 /**< Success. */
#define BLE_GATT_STATUS_UNKNOWN 0x0001 /**< Unknown or not applicable status. */
#define BLE_GATT_STATUS_ATTERR_INVALID 0x0100 /**< ATT Error: Invalid Error Code. */
#define BLE_GATT_STATUS_ATTERR_INVALID_HANDLE 0x0101 /**< ATT Error: Invalid Attribute Handle. */
#define BLE_GATT_STATUS_ATTERR_READ_NOT_PERMITTED 0x0102 /**< ATT Error: Read not permitted. */
#define BLE_GATT_STATUS_ATTERR_WRITE_NOT_PERMITTED 0x0103 /**< ATT Error: Write not permitted. */
#define BLE_GATT_STATUS_ATTERR_INVALID_PDU 0x0104 /**< ATT Error: Used in ATT as Invalid PDU. */
#define BLE_GATT_STATUS_ATTERR_INSUF_AUTHENTICATION 0x0105 /**< ATT Error: Authenticated link required. */
#define BLE_GATT_STATUS_ATTERR_REQUEST_NOT_SUPPORTED 0x0106 /**< ATT Error: Used in ATT as Request Not Supported. */
#define BLE_GATT_STATUS_ATTERR_INVALID_OFFSET 0x0107 /**< ATT Error: Offset specified was past the end of the attribute. */
#define BLE_GATT_STATUS_ATTERR_INSUF_AUTHORIZATION 0x0108 /**< ATT Error: Used in ATT as Insufficient Authorisation. */
#define BLE_GATT_STATUS_ATTERR_PREPARE_QUEUE_FULL 0x0109 /**< ATT Error: Used in ATT as Prepare Queue Full. */
#define BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND 0x010A /**< ATT Error: Used in ATT as Attribute not found. */
#define BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_LONG 0x010B /**< ATT Error: Attribute cannot be read or written using read/write blob requests. */
#define BLE_GATT_STATUS_ATTERR_INSUF_ENC_KEY_SIZE 0x010C /**< ATT Error: Encryption key size used is insufficient. */
#define BLE_GATT_STATUS_ATTERR_INVALID_ATT_VAL_LENGTH 0x010D /**< ATT Error: Invalid value size. */
#define BLE_GATT_STATUS_ATTERR_UNLIKELY_ERROR 0x010E /**< ATT Error: Very unlikely error. */
#define BLE_GATT_STATUS_ATTERR_INSUF_ENCRYPTION 0x010F /**< ATT Error: Encrypted link required. */
#define BLE_GATT_STATUS_ATTERR_UNSUPPORTED_GROUP_TYPE 0x0110 /**< ATT Error: Attribute type is not a supported grouping attribute. */
#define BLE_GATT_STATUS_ATTERR_INSUF_RESOURCES 0x0111 /**< ATT Error: Encrypted link required. */
#define BLE_GATT_STATUS_ATTERR_RFU_RANGE1_BEGIN 0x0112 /**< ATT Error: Reserved for Future Use range #1 begin. */
#define BLE_GATT_STATUS_ATTERR_RFU_RANGE1_END 0x017F /**< ATT Error: Reserved for Future Use range #1 end. */
#define BLE_GATT_STATUS_ATTERR_APP_BEGIN 0x0180 /**< ATT Error: Application range begin. */
#define BLE_GATT_STATUS_ATTERR_APP_END 0x019F /**< ATT Error: Application range end. */
#define BLE_GATT_STATUS_ATTERR_RFU_RANGE2_BEGIN 0x01A0 /**< ATT Error: Reserved for Future Use range #2 begin. */
#define BLE_GATT_STATUS_ATTERR_RFU_RANGE2_END 0x01DF /**< ATT Error: Reserved for Future Use range #2 end. */
#define BLE_GATT_STATUS_ATTERR_RFU_RANGE3_BEGIN 0x01E0 /**< ATT Error: Reserved for Future Use range #3 begin. */
#define BLE_GATT_STATUS_ATTERR_RFU_RANGE3_END 0x01FC /**< ATT Error: Reserved for Future Use range #3 end. */
#define BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR 0x01FD /**< ATT Common Profile and Service Error: Client Characteristic Configuration Descriptor improperly configured. */
#define BLE_GATT_STATUS_ATTERR_CPS_PROC_ALR_IN_PROG 0x01FE /**< ATT Common Profile and Service Error: Procedure Already in Progress. */
#define BLE_GATT_STATUS_ATTERR_CPS_OUT_OF_RANGE 0x01FF /**< ATT Common Profile and Service Error: Out Of Range. */
/** @} */
/** @defgroup BLE_GATT_CPF_FORMATS Characteristic Presentation Formats
* @note Found at http://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml
* @{ */
#define BLE_GATT_CPF_FORMAT_RFU 0x00 /**< Reserved For Future Use. */
#define BLE_GATT_CPF_FORMAT_BOOLEAN 0x01 /**< Boolean. */
#define BLE_GATT_CPF_FORMAT_2BIT 0x02 /**< Unsigned 2-bit integer. */
#define BLE_GATT_CPF_FORMAT_NIBBLE 0x03 /**< Unsigned 4-bit integer. */
#define BLE_GATT_CPF_FORMAT_UINT8 0x04 /**< Unsigned 8-bit integer. */
#define BLE_GATT_CPF_FORMAT_UINT12 0x05 /**< Unsigned 12-bit integer. */
#define BLE_GATT_CPF_FORMAT_UINT16 0x06 /**< Unsigned 16-bit integer. */
#define BLE_GATT_CPF_FORMAT_UINT24 0x07 /**< Unsigned 24-bit integer. */
#define BLE_GATT_CPF_FORMAT_UINT32 0x08 /**< Unsigned 32-bit integer. */
#define BLE_GATT_CPF_FORMAT_UINT48 0x09 /**< Unsigned 48-bit integer. */
#define BLE_GATT_CPF_FORMAT_UINT64 0x0A /**< Unsigned 64-bit integer. */
#define BLE_GATT_CPF_FORMAT_UINT128 0x0B /**< Unsigned 128-bit integer. */
#define BLE_GATT_CPF_FORMAT_SINT8 0x0C /**< Signed 2-bit integer. */
#define BLE_GATT_CPF_FORMAT_SINT12 0x0D /**< Signed 12-bit integer. */
#define BLE_GATT_CPF_FORMAT_SINT16 0x0E /**< Signed 16-bit integer. */
#define BLE_GATT_CPF_FORMAT_SINT24 0x0F /**< Signed 24-bit integer. */
#define BLE_GATT_CPF_FORMAT_SINT32 0x10 /**< Signed 32-bit integer. */
#define BLE_GATT_CPF_FORMAT_SINT48 0x11 /**< Signed 48-bit integer. */
#define BLE_GATT_CPF_FORMAT_SINT64 0x12 /**< Signed 64-bit integer. */
#define BLE_GATT_CPF_FORMAT_SINT128 0x13 /**< Signed 128-bit integer. */
#define BLE_GATT_CPF_FORMAT_FLOAT32 0x14 /**< IEEE-754 32-bit floating point. */
#define BLE_GATT_CPF_FORMAT_FLOAT64 0x15 /**< IEEE-754 64-bit floating point. */
#define BLE_GATT_CPF_FORMAT_SFLOAT 0x16 /**< IEEE-11073 16-bit SFLOAT. */
#define BLE_GATT_CPF_FORMAT_FLOAT 0x17 /**< IEEE-11073 32-bit FLOAT. */
#define BLE_GATT_CPF_FORMAT_DUINT16 0x18 /**< IEEE-20601 format. */
#define BLE_GATT_CPF_FORMAT_UTF8S 0x19 /**< UTF-8 string. */
#define BLE_GATT_CPF_FORMAT_UTF16S 0x1A /**< UTF-16 string. */
#define BLE_GATT_CPF_FORMAT_STRUCT 0x1B /**< Opaque Structure. */
/** @} */
/** @defgroup BLE_GATT_CPF_NAMESPACES GATT Bluetooth Namespaces
* @{
*/
#define BLE_GATT_CPF_NAMESPACE_BTSIG 0x01 /**< Bluetooth SIG defined Namespace. */
#define BLE_GATT_CPF_NAMESPACE_DESCRIPTION_UNKNOWN 0x0000 /**< Namespace Description Unknown. */
/** @} */
/** @} */
/** @addtogroup BLE_GATT_STRUCTURES Structures
* @{ */
/**@brief GATT Characteristic Properties. */
typedef struct
{
/* Standard properties */
uint8_t broadcast :1; /**< Broadcasting of the value permitted. */
uint8_t read :1; /**< Reading the value permitted. */
uint8_t write_wo_resp :1; /**< Writing the value with Write Command permitted. */
uint8_t write :1; /**< Writing the value with Write Request permitted. */
uint8_t notify :1; /**< Notications of the value permitted. */
uint8_t indicate :1; /**< Indications of the value permitted. */
uint8_t auth_signed_wr :1; /**< Writing the value with Signed Write Command permitted. */
} ble_gatt_char_props_t;
/**@brief GATT Characteristic Extended Properties. */
typedef struct
{
/* Extended properties */
uint8_t reliable_wr :1; /**< Writing the value with Queued Write operations permitted. */
uint8_t wr_aux :1; /**< Writing the Characteristic User Description descriptor permitted. */
} ble_gatt_char_ext_props_t;
#ifdef __cplusplus
}
#endif
#endif // BLE_GATT_H__
/** @} */
/**
@}
@}
*/

View File

@ -0,0 +1,569 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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.
*
*/
/**
@addtogroup BLE_GATTC Generic Attribute Profile (GATT) Client
@{
@brief Definitions and prototypes for the GATT Client interface.
*/
#ifndef BLE_GATTC_H__
#define BLE_GATTC_H__
#include "ble_gatt.h"
#include "ble_types.h"
#include "ble_ranges.h"
#include "nrf_svc.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup BLE_GATTC_ENUMERATIONS Enumerations
* @{ */
/**@brief GATTC API SVC numbers. */
enum BLE_GATTC_SVCS
{
SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER = BLE_GATTC_SVC_BASE, /**< Primary Service Discovery. */
SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, /**< Relationship Discovery. */
SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, /**< Characteristic Discovery. */
SD_BLE_GATTC_DESCRIPTORS_DISCOVER, /**< Characteristic Descriptor Discovery. */
SD_BLE_GATTC_ATTR_INFO_DISCOVER, /**< Attribute Information Discovery. */
SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, /**< Read Characteristic Value by UUID. */
SD_BLE_GATTC_READ, /**< Generic read. */
SD_BLE_GATTC_CHAR_VALUES_READ, /**< Read multiple Characteristic Values. */
SD_BLE_GATTC_WRITE, /**< Generic write. */
SD_BLE_GATTC_HV_CONFIRM, /**< Handle Value Confirmation. */
};
/**
* @brief GATT Client Event IDs.
*/
enum BLE_GATTC_EVTS
{
BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP = BLE_GATTC_EVT_BASE, /**< Primary Service Discovery Response event. \n See @ref ble_gattc_evt_prim_srvc_disc_rsp_t. */
BLE_GATTC_EVT_REL_DISC_RSP, /**< Relationship Discovery Response event. \n See @ref ble_gattc_evt_rel_disc_rsp_t. */
BLE_GATTC_EVT_CHAR_DISC_RSP, /**< Characteristic Discovery Response event. \n See @ref ble_gattc_evt_char_disc_rsp_t. */
BLE_GATTC_EVT_DESC_DISC_RSP, /**< Descriptor Discovery Response event. \n See @ref ble_gattc_evt_desc_disc_rsp_t. */
BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, /**< Attribute Information Response event. \n See @ref ble_gattc_evt_attr_info_disc_rsp_t. */
BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP, /**< Read By UUID Response event. \n See @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t. */
BLE_GATTC_EVT_READ_RSP, /**< Read Response event. \n See @ref ble_gattc_evt_read_rsp_t. */
BLE_GATTC_EVT_CHAR_VALS_READ_RSP, /**< Read multiple Response event. \n See @ref ble_gattc_evt_char_vals_read_rsp_t. */
BLE_GATTC_EVT_WRITE_RSP, /**< Write Response event. \n See @ref ble_gattc_evt_write_rsp_t. */
BLE_GATTC_EVT_HVX, /**< Handle Value Notification or Indication event. \n Confirm indication with @ref sd_ble_gattc_hv_confirm. \n See @ref ble_gattc_evt_hvx_t. */
BLE_GATTC_EVT_TIMEOUT /**< Timeout event. \n See @ref ble_gattc_evt_timeout_t. */
};
/** @} */
/** @addtogroup BLE_GATTC_DEFINES Defines
* @{ */
/** @defgroup BLE_ERRORS_GATTC SVC return values specific to GATTC
* @{ */
#define BLE_ERROR_GATTC_PROC_NOT_PERMITTED (NRF_GATTC_ERR_BASE + 0x000) /**< Procedure not Permitted. */
/** @} */
/** @defgroup BLE_GATTC_ATTR_INFO_FORMAT Attribute Information Formats
* @{ */
#define BLE_GATTC_ATTR_INFO_FORMAT_16BIT 1 /**< 16-bit Attribute Information Format. */
#define BLE_GATTC_ATTR_INFO_FORMAT_128BIT 2 /**< 128-bit Attribute Information Format. */
/** @} */
/** @} */
/** @addtogroup BLE_GATTC_STRUCTURES Structures
* @{ */
/**@brief Operation Handle Range. */
typedef struct
{
uint16_t start_handle; /**< Start Handle. */
uint16_t end_handle; /**< End Handle. */
} ble_gattc_handle_range_t;
/**@brief GATT service. */
typedef struct
{
ble_uuid_t uuid; /**< Service UUID. */
ble_gattc_handle_range_t handle_range; /**< Service Handle Range. */
} ble_gattc_service_t;
/**@brief GATT include. */
typedef struct
{
uint16_t handle; /**< Include Handle. */
ble_gattc_service_t included_srvc; /**< Handle of the included service. */
} ble_gattc_include_t;
/**@brief GATT characteristic. */
typedef struct
{
ble_uuid_t uuid; /**< Characteristic UUID. */
ble_gatt_char_props_t char_props; /**< Characteristic Properties. */
uint8_t char_ext_props : 1; /**< Extended properties present. */
uint16_t handle_decl; /**< Handle of the Characteristic Declaration. */
uint16_t handle_value; /**< Handle of the Characteristic Value. */
} ble_gattc_char_t;
/**@brief GATT descriptor. */
typedef struct
{
uint16_t handle; /**< Descriptor Handle. */
ble_uuid_t uuid; /**< Descriptor UUID. */
} ble_gattc_desc_t;
/**@brief Write Parameters. */
typedef struct
{
uint8_t write_op; /**< Write Operation to be performed, see @ref BLE_GATT_WRITE_OPS. */
uint8_t flags; /**< Flags, see @ref BLE_GATT_EXEC_WRITE_FLAGS. */
uint16_t handle; /**< Handle to the attribute to be written. */
uint16_t offset; /**< Offset in bytes. @note For WRITE_CMD and WRITE_REQ, offset must be 0. */
uint16_t len; /**< Length of data in bytes. */
uint8_t *p_value; /**< Pointer to the value data. */
} ble_gattc_write_params_t;
/**@brief Attribute Information. */
typedef struct
{
uint16_t handle; /**< Attribute handle. */
union {
ble_uuid_t uuid16; /**< 16-bit Attribute UUID. */
ble_uuid128_t uuid128; /**< 128-bit Attribute UUID. */
} info;
} ble_gattc_attr_info_t;
/**@brief Event structure for @ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP. */
typedef struct
{
uint16_t count; /**< Service count. */
ble_gattc_service_t services[1]; /**< Service data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
} ble_gattc_evt_prim_srvc_disc_rsp_t;
/**@brief Event structure for @ref BLE_GATTC_EVT_REL_DISC_RSP. */
typedef struct
{
uint16_t count; /**< Include count. */
ble_gattc_include_t includes[1]; /**< Include data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
} ble_gattc_evt_rel_disc_rsp_t;
/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_DISC_RSP. */
typedef struct
{
uint16_t count; /**< Characteristic count. */
ble_gattc_char_t chars[1]; /**< Characteristic data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
} ble_gattc_evt_char_disc_rsp_t;
/**@brief Event structure for @ref BLE_GATTC_EVT_DESC_DISC_RSP. */
typedef struct
{
uint16_t count; /**< Descriptor count. */
ble_gattc_desc_t descs[1]; /**< Descriptor data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
} ble_gattc_evt_desc_disc_rsp_t;
/**@brief Event structure for @ref BLE_GATTC_EVT_ATTR_INFO_DISC_RSP. */
typedef struct
{
uint16_t count; /**< Attribute count. */
uint8_t format; /**< Attribute information format, see @ref BLE_GATTC_ATTR_INFO_FORMAT. */
ble_gattc_attr_info_t attr_info[1]; /**< Attribute information. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
} ble_gattc_evt_attr_info_disc_rsp_t;
/**@brief GATT read by UUID handle value pair. */
typedef struct
{
uint16_t handle; /**< Attribute Handle. */
uint8_t *p_value; /**< Pointer to value, variable length (length available as value_len in @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t).
Please note that this pointer is absolute to the memory provided by the user when retrieving the event,
so it will effectively point to a location inside the handle_value array. */
} ble_gattc_handle_value_t;
/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP. */
typedef struct
{
uint16_t count; /**< Handle-Value Pair Count. */
uint16_t value_len; /**< Length of the value in Handle-Value(s) list. */
ble_gattc_handle_value_t handle_value[1]; /**< Handle-Value(s) list. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
} ble_gattc_evt_char_val_by_uuid_read_rsp_t;
/**@brief Event structure for @ref BLE_GATTC_EVT_READ_RSP. */
typedef struct
{
uint16_t handle; /**< Attribute Handle. */
uint16_t offset; /**< Offset of the attribute data. */
uint16_t len; /**< Attribute data length. */
uint8_t data[1]; /**< Attribute data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
} ble_gattc_evt_read_rsp_t;
/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP. */
typedef struct
{
uint16_t len; /**< Concatenated Attribute values length. */
uint8_t values[1]; /**< Attribute values. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
} ble_gattc_evt_char_vals_read_rsp_t;
/**@brief Event structure for @ref BLE_GATTC_EVT_WRITE_RSP. */
typedef struct
{
uint16_t handle; /**< Attribute Handle. */
uint8_t write_op; /**< Type of write operation, see @ref BLE_GATT_WRITE_OPS. */
uint16_t offset; /**< Data offset. */
uint16_t len; /**< Data length. */
uint8_t data[1]; /**< Data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
} ble_gattc_evt_write_rsp_t;
/**@brief Event structure for @ref BLE_GATTC_EVT_HVX. */
typedef struct
{
uint16_t handle; /**< Handle to which the HVx operation applies. */
uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */
uint16_t len; /**< Attribute data length. */
uint8_t data[1]; /**< Attribute data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
} ble_gattc_evt_hvx_t;
/**@brief Event structure for @ref BLE_GATTC_EVT_TIMEOUT. */
typedef struct
{
uint8_t src; /**< Timeout source, see @ref BLE_GATT_TIMEOUT_SOURCES. */
} ble_gattc_evt_timeout_t;
/**@brief GATTC event structure. */
typedef struct
{
uint16_t conn_handle; /**< Connection Handle on which event occured. */
uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */
uint16_t error_handle; /**< In case of error: The handle causing the error. In all other cases @ref BLE_GATT_HANDLE_INVALID. */
union
{
ble_gattc_evt_prim_srvc_disc_rsp_t prim_srvc_disc_rsp; /**< Primary Service Discovery Response Event Parameters. */
ble_gattc_evt_rel_disc_rsp_t rel_disc_rsp; /**< Relationship Discovery Response Event Parameters. */
ble_gattc_evt_char_disc_rsp_t char_disc_rsp; /**< Characteristic Discovery Response Event Parameters. */
ble_gattc_evt_desc_disc_rsp_t desc_disc_rsp; /**< Descriptor Discovery Response Event Parameters. */
ble_gattc_evt_char_val_by_uuid_read_rsp_t char_val_by_uuid_read_rsp; /**< Characteristic Value Read by UUID Response Event Parameters. */
ble_gattc_evt_read_rsp_t read_rsp; /**< Read Response Event Parameters. */
ble_gattc_evt_char_vals_read_rsp_t char_vals_read_rsp; /**< Characteristic Values Read Response Event Parameters. */
ble_gattc_evt_write_rsp_t write_rsp; /**< Write Response Event Parameters. */
ble_gattc_evt_hvx_t hvx; /**< Handle Value Notification/Indication Event Parameters. */
ble_gattc_evt_timeout_t timeout; /**< Timeout Event Parameters. */
ble_gattc_evt_attr_info_disc_rsp_t attr_info_disc_rsp; /**< Attribute Information Discovery Event Parameters. */
} params; /**< Event Parameters. @note Only valid if @ref gatt_status == @ref BLE_GATT_STATUS_SUCCESS. */
} ble_gattc_evt_t;
/** @} */
/** @addtogroup BLE_GATTC_FUNCTIONS Functions
* @{ */
/**@brief Initiate or continue a GATT Primary Service Discovery procedure.
*
* @details This function initiates or resumes a Primary Service discovery procedure, starting from the supplied handle.
* If the last service has not been reached, this function must be called again with an updated start handle value to continue the search.
*
* @note If any of the discovered services have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with
* type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event.
*
* @events
* @event{@ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP}
* @endevents
*
* @mscs
* @mmsc{@ref BLE_GATTC_PRIM_SRVC_DISC_MSC}
* @endmscs
*
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
* @param[in] start_handle Handle to start searching from.
* @param[in] p_srvc_uuid Pointer to the service UUID to be found. If it is NULL, all primary services will be returned.
*
* @retval ::NRF_SUCCESS Successfully started or resumed the Primary Service Discovery procedure.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
* @retval ::NRF_ERROR_BUSY Client procedure already in progress.
*/
SVCALL(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER, uint32_t, sd_ble_gattc_primary_services_discover(uint16_t conn_handle, uint16_t start_handle, ble_uuid_t const *p_srvc_uuid));
/**@brief Initiate or continue a GATT Relationship Discovery procedure.
*
* @details This function initiates or resumes the Find Included Services sub-procedure. If the last included service has not been reached,
* this must be called again with an updated handle range to continue the search.
*
* @events
* @event{@ref BLE_GATTC_EVT_REL_DISC_RSP}
* @endevents
*
* @mscs
* @mmsc{@ref BLE_GATTC_REL_DISC_MSC}
* @endmscs
*
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
* @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on.
*
* @retval ::NRF_SUCCESS Successfully started or resumed the Relationship Discovery procedure.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
* @retval ::NRF_ERROR_BUSY Client procedure already in progress.
*/
SVCALL(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, uint32_t, sd_ble_gattc_relationships_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range));
/**@brief Initiate or continue a GATT Characteristic Discovery procedure.
*
* @details This function initiates or resumes a Characteristic discovery procedure. If the last Characteristic has not been reached,
* this must be called again with an updated handle range to continue the discovery.
*
* @note If any of the discovered characteristics have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with
* type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event.
*
* @events
* @event{@ref BLE_GATTC_EVT_CHAR_DISC_RSP}
* @endevents
*
* @mscs
* @mmsc{@ref BLE_GATTC_CHAR_DISC_MSC}
* @endmscs
*
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
* @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on.
*
* @retval ::NRF_SUCCESS Successfully started or resumed the Characteristic Discovery procedure.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_BUSY Client procedure already in progress.
*/
SVCALL(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, uint32_t, sd_ble_gattc_characteristics_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range));
/**@brief Initiate or continue a GATT Characteristic Descriptor Discovery procedure.
*
* @details This function initiates or resumes a Characteristic Descriptor discovery procedure. If the last Descriptor has not been reached,
* this must be called again with an updated handle range to continue the discovery.
*
* @events
* @event{BLE_GATTC_EVT_DESC_DISC_RSP}
* @endevents
*
* @mscs
* @mmsc{@ref BLE_GATTC_DESC_DISC_MSC}
* @endmscs
*
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
* @param[in] p_handle_range A pointer to the range of handles of the Characteristic to perform this procedure on.
*
* @retval ::NRF_SUCCESS Successfully started or resumed the Descriptor Discovery procedure.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_BUSY Client procedure already in progress.
*/
SVCALL(SD_BLE_GATTC_DESCRIPTORS_DISCOVER, uint32_t, sd_ble_gattc_descriptors_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range));
/**@brief Initiate or continue a GATT Read using Characteristic UUID procedure.
*
* @details This function initiates or resumes a Read using Characteristic UUID procedure. If the last Characteristic has not been reached,
* this must be called again with an updated handle range to continue the discovery.
*
* @events
* @event{BLE_GATTC_EVT_DESC_DISC_RSP}
* @endevents
*
* @mscs
* @mmsc{@ref BLE_GATTC_READ_UUID_MSC}
* @endmscs
*
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
* @param[in] p_uuid Pointer to a Characteristic value UUID to read.
* @param[in] p_handle_range A pointer to the range of handles to perform this procedure on.
*
* @retval ::NRF_SUCCESS Successfully started or resumed the Read using Characteristic UUID procedure.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_BUSY Client procedure already in progress.
*/
SVCALL(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, uint32_t, sd_ble_gattc_char_value_by_uuid_read(uint16_t conn_handle, ble_uuid_t const *p_uuid, ble_gattc_handle_range_t const *p_handle_range));
/**@brief Initiate or continue a GATT Read (Long) Characteristic or Descriptor procedure.
*
* @details This function initiates or resumes a GATT Read (Long) Characteristic or Descriptor procedure. If the Characteristic or Descriptor
* to be read is longer than ATT_MTU - 1, this function must be called multiple times with appropriate offset to read the
* complete value.
*
* @events
* @event{@ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP}
* @endevents
*
* @mscs
* @mmsc{@ref BLE_GATTC_VALUE_READ_MSC}
* @endmscs
*
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
* @param[in] handle The handle of the attribute to be read.
* @param[in] offset Offset into the attribute value to be read.
*
* @retval ::NRF_SUCCESS Successfully started or resumed the Read (Long) procedure.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
* @retval ::NRF_ERROR_BUSY Client procedure already in progress.
*/
SVCALL(SD_BLE_GATTC_READ, uint32_t, sd_ble_gattc_read(uint16_t conn_handle, uint16_t handle, uint16_t offset));
/**@brief Initiate a GATT Read Multiple Characteristic Values procedure.
*
* @details This function initiates a GATT Read Multiple Characteristic Values procedure.
*
* @events
* @event{@ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP}
* @endevents
*
* @mscs
* @mmsc{@ref BLE_GATTC_READ_MULT_MSC}
* @endmscs
*
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
* @param[in] p_handles A pointer to the handle(s) of the attribute(s) to be read.
* @param[in] handle_count The number of handles in p_handles.
*
* @retval ::NRF_SUCCESS Successfully started the Read Multiple Characteristic Values procedure.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_BUSY Client procedure already in progress.
*/
SVCALL(SD_BLE_GATTC_CHAR_VALUES_READ, uint32_t, sd_ble_gattc_char_values_read(uint16_t conn_handle, uint16_t const *p_handles, uint16_t handle_count));
/**@brief Perform a Write (Characteristic Value or Descriptor, with or without response, signed or not, long or reliable) procedure.
*
* @details This function can perform all write procedures described in GATT.
*
* @note It is important to note that a write without response will <b>consume an application buffer</b>, and will therefore
* generate a @ref BLE_EVT_TX_COMPLETE event when the packet has been transmitted. A write (with response) on the other hand will use the
* standard client internal buffer and thus will only generate a @ref BLE_GATTC_EVT_WRITE_RSP event as soon as the write response
* has been received from the peer. Please see the documentation of @ref sd_ble_tx_packet_count_get for more details.
*
* @events
* @event{@ref BLE_GATTC_EVT_WRITE_RSP, Generated when using write request or queued writes.}
* @endevents
*
* @mscs
* @mmsc{@ref BLE_GATTC_VALUE_WRITE_MSC}
* @mmsc{@ref BLE_GATTC_VALUE_LONG_WRITE_MSC}
* @mmsc{@ref BLE_GATTC_VALUE_RELIABLE_WRITE_MSC}
* @mmsc{@ref BLE_COMMON_APP_BUFF_MSC}
* @endmscs
*
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
* @param[in] p_write_params A pointer to a write parameters structure.
*
* @retval ::NRF_SUCCESS Successfully started the Write procedure.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
* @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied.
* @retval ::NRF_ERROR_BUSY Procedure already in progress.
* @retval ::BLE_ERROR_NO_TX_PACKETS No available application packets for this connection.
*/
SVCALL(SD_BLE_GATTC_WRITE, uint32_t, sd_ble_gattc_write(uint16_t conn_handle, ble_gattc_write_params_t const *p_write_params));
/**@brief Send a Handle Value Confirmation to the GATT Server.
*
* @mscs
* @mmsc{@ref BLE_GATTC_HVI_MSC}
* @endmscs
*
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
* @param[in] handle The handle of the attribute in the indication.
*
* @retval ::NRF_SUCCESS Successfully queued the Handle Value Confirmation for transmission.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no Indication pending to be confirmed.
* @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle.
*/
SVCALL(SD_BLE_GATTC_HV_CONFIRM, uint32_t, sd_ble_gattc_hv_confirm(uint16_t conn_handle, uint16_t handle));
/**@brief Discovers information about a range of attributes on a GATT server.
*
* @events
* @event{@ref BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, Generated when information about a range of attributes has been received.}
* @endevents
*
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
* @param[in] p_handle_range The range of handles to request information about.
*
* @retval ::NRF_SUCCESS Successfully started an attribute information discovery procedure.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle.
* @retval ::NRF_ERROR_INVALID_STATE Invalid connection state
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_BUSY Client procedure already in progress.
*/
SVCALL(SD_BLE_GATTC_ATTR_INFO_DISCOVER, uint32_t, sd_ble_gattc_attr_info_discover(uint16_t conn_handle, ble_gattc_handle_range_t const * p_handle_range));
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* BLE_GATTC_H__ */
/**
@}
@}
*/

View File

@ -0,0 +1,722 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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.
*
*/
/**
@addtogroup BLE_GATTS Generic Attribute Profile (GATT) Server
@{
@brief Definitions and prototypes for the GATTS interface.
*/
#ifndef BLE_GATTS_H__
#define BLE_GATTS_H__
#include "ble_types.h"
#include "ble_ranges.h"
#include "ble_l2cap.h"
#include "ble_gap.h"
#include "ble_gatt.h"
#include "nrf_svc.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup BLE_GATTS_ENUMERATIONS Enumerations
* @{ */
/**
* @brief GATTS API SVC numbers.
*/
enum BLE_GATTS_SVCS
{
SD_BLE_GATTS_SERVICE_ADD = BLE_GATTS_SVC_BASE, /**< Add a service. */
SD_BLE_GATTS_INCLUDE_ADD, /**< Add an included service. */
SD_BLE_GATTS_CHARACTERISTIC_ADD, /**< Add a characteristic. */
SD_BLE_GATTS_DESCRIPTOR_ADD, /**< Add a generic attribute. */
SD_BLE_GATTS_VALUE_SET, /**< Set an attribute value. */
SD_BLE_GATTS_VALUE_GET, /**< Get an attribute value. */
SD_BLE_GATTS_HVX, /**< Handle Value Notification or Indication. */
SD_BLE_GATTS_SERVICE_CHANGED, /**< Perform a Service Changed Indication to one or more peers. */
SD_BLE_GATTS_RW_AUTHORIZE_REPLY, /**< Reply to an authorization request for a read or write operation on one or more attributes. */
SD_BLE_GATTS_SYS_ATTR_SET, /**< Set the persistent system attributes for a connection. */
SD_BLE_GATTS_SYS_ATTR_GET, /**< Retrieve the persistent system attributes. */
SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, /**< Retrieve the first valid user handle. */
SD_BLE_GATTS_ATTR_GET /**< Retrieve the UUID and/or metadata of an attribute. */
};
/**
* @brief GATT Server Event IDs.
*/
enum BLE_GATTS_EVTS
{
BLE_GATTS_EVT_WRITE = BLE_GATTS_EVT_BASE, /**< Write operation performed. \n See @ref ble_gatts_evt_write_t. */
BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST, /**< Read/Write Authorization request. \n Reply with @ref sd_ble_gatts_rw_authorize_reply. \n See @ref ble_gatts_evt_rw_authorize_request_t. */
BLE_GATTS_EVT_SYS_ATTR_MISSING, /**< A persistent system attribute access is pending. \n Respond with @ref sd_ble_gatts_sys_attr_set. \n See @ref ble_gatts_evt_sys_attr_missing_t. */
BLE_GATTS_EVT_HVC, /**< Handle Value Confirmation. \n See @ref ble_gatts_evt_hvc_t. */
BLE_GATTS_EVT_SC_CONFIRM, /**< Service Changed Confirmation. No additional event structure applies. */
BLE_GATTS_EVT_TIMEOUT /**< Peer failed to resonpond to an ATT request in time. \n See @ref ble_gatts_evt_timeout_t. */
};
/** @} */
/** @addtogroup BLE_GATTS_DEFINES Defines
* @{ */
/** @defgroup BLE_ERRORS_GATTS SVC return values specific to GATTS
* @{ */
#define BLE_ERROR_GATTS_INVALID_ATTR_TYPE (NRF_GATTS_ERR_BASE + 0x000) /**< Invalid attribute type. */
#define BLE_ERROR_GATTS_SYS_ATTR_MISSING (NRF_GATTS_ERR_BASE + 0x001) /**< System Attributes missing. */
/** @} */
/** @defgroup BLE_GATTS_ATTR_LENS_MAX Maximum attribute lengths
* @{ */
#define BLE_GATTS_FIX_ATTR_LEN_MAX (510) /**< Maximum length for fixed length Attribute Values. */
#define BLE_GATTS_VAR_ATTR_LEN_MAX (512) /**< Maximum length for variable length Attribute Values. */
/** @} */
/** @defgroup BLE_GATTS_SRVC_TYPES GATT Server Service Types
* @{ */
#define BLE_GATTS_SRVC_TYPE_INVALID 0x00 /**< Invalid Service Type. */
#define BLE_GATTS_SRVC_TYPE_PRIMARY 0x01 /**< Primary Service. */
#define BLE_GATTS_SRVC_TYPE_SECONDARY 0x02 /**< Secondary Type. */
/** @} */
/** @defgroup BLE_GATTS_ATTR_TYPES GATT Server Attribute Types
* @{ */
#define BLE_GATTS_ATTR_TYPE_INVALID 0x00 /**< Invalid Attribute Type. */
#define BLE_GATTS_ATTR_TYPE_PRIM_SRVC_DECL 0x01 /**< Primary Service Declaration. */
#define BLE_GATTS_ATTR_TYPE_SEC_SRVC_DECL 0x02 /**< Secondary Service Declaration. */
#define BLE_GATTS_ATTR_TYPE_INC_DECL 0x03 /**< Include Declaration. */
#define BLE_GATTS_ATTR_TYPE_CHAR_DECL 0x04 /**< Characteristic Declaration. */
#define BLE_GATTS_ATTR_TYPE_CHAR_VAL 0x05 /**< Characteristic Value. */
#define BLE_GATTS_ATTR_TYPE_DESC 0x06 /**< Descriptor. */
#define BLE_GATTS_ATTR_TYPE_OTHER 0x07 /**< Other, non-GATT specific type. */
/** @} */
/** @defgroup BLE_GATTS_OPS GATT Server Operations
* @{ */
#define BLE_GATTS_OP_INVALID 0x00 /**< Invalid Operation. */
#define BLE_GATTS_OP_WRITE_REQ 0x01 /**< Write Request. */
#define BLE_GATTS_OP_WRITE_CMD 0x02 /**< Write Command. */
#define BLE_GATTS_OP_SIGN_WRITE_CMD 0x03 /**< Signed Write Command. */
#define BLE_GATTS_OP_PREP_WRITE_REQ 0x04 /**< Prepare Write Request. */
#define BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL 0x05 /**< Execute Write Request: Cancel all prepared writes. */
#define BLE_GATTS_OP_EXEC_WRITE_REQ_NOW 0x06 /**< Execute Write Request: Immediately execute all prepared writes. */
/** @} */
/** @defgroup BLE_GATTS_VLOCS GATT Value Locations
* @{ */
#define BLE_GATTS_VLOC_INVALID 0x00 /**< Invalid Location. */
#define BLE_GATTS_VLOC_STACK 0x01 /**< Attribute Value is located in stack memory, no user memory is required. */
#define BLE_GATTS_VLOC_USER 0x02 /**< Attribute Value is located in user memory. This requires the user to maintain a valid buffer through the lifetime of the attribute, since the stack
will read and write directly to the memory using the pointer provided in the APIs. There are no alignment requirements for the buffer. */
/** @} */
/** @defgroup BLE_GATTS_AUTHORIZE_TYPES GATT Server Authorization Types
* @{ */
#define BLE_GATTS_AUTHORIZE_TYPE_INVALID 0x00 /**< Invalid Type. */
#define BLE_GATTS_AUTHORIZE_TYPE_READ 0x01 /**< Authorize a Read Operation. */
#define BLE_GATTS_AUTHORIZE_TYPE_WRITE 0x02 /**< Authorize a Write Request Operation. */
/** @} */
/** @defgroup BLE_GATTS_SYS_ATTR_FLAGS System Attribute Flags
* @{ */
#define BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS (1 << 0) /**< Restrict system attributes to system services only. */
#define BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS (1 << 1) /**< Restrict system attributes to user services only. */
/** @} */
/** @defgroup BLE_GATTS_ATTR_TAB_SIZE Attribute Table size
* @{
*/
#define BLE_GATTS_ATTR_TAB_SIZE_MIN 216 /**< Minimum Attribute Table size */
#define BLE_GATTS_ATTR_TAB_SIZE_DEFAULT 0x0000 /**< Default Attribute Table size (0x580 bytes for this version of the SoftDevice). */
/** @} */
/** @} */
/** @addtogroup BLE_GATTS_STRUCTURES Structures
* @{ */
/**
* @brief BLE GATTS initialization parameters.
*/
typedef struct
{
uint8_t service_changed:1; /**< Include the Service Changed characteristic in the Attribute Table. */
uint32_t attr_tab_size; /**< Attribute Table size in bytes. The size must be a multiple of 4. @ref BLE_GATTS_ATTR_TAB_SIZE_DEFAULT is used to set the default size. */
} ble_gatts_enable_params_t;
/**@brief Attribute metadata. */
typedef struct
{
ble_gap_conn_sec_mode_t read_perm; /**< Read permissions. */
ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */
uint8_t vlen :1; /**< Variable length attribute. */
uint8_t vloc :2; /**< Value location, see @ref BLE_GATTS_VLOCS.*/
uint8_t rd_auth :1; /**< Read authorization and value will be requested from the application on every read operation. */
uint8_t wr_auth :1; /**< Write authorization will be requested from the application on every Write Request operation (but not Write Command). */
} ble_gatts_attr_md_t;
/**@brief GATT Attribute. */
typedef struct
{
ble_uuid_t *p_uuid; /**< Pointer to the attribute UUID. */
ble_gatts_attr_md_t *p_attr_md; /**< Pointer to the attribute metadata structure. */
uint16_t init_len; /**< Initial attribute value length in bytes. */
uint16_t init_offs; /**< Initial attribute value offset in bytes. If different from zero, the first init_offs bytes of the attribute value will be left uninitialized. */
uint16_t max_len; /**< Maximum attribute value length in bytes, see @ref BLE_GATTS_ATTR_LENS_MAX for maximum values. */
uint8_t* p_value; /**< Pointer to the attribute data. Please note that if the @ref BLE_GATTS_VLOC_USER value location is selected in the attribute metadata, this will have to point to a buffer
that remains valid through the lifetime of the attribute. This excludes usage of automatic variables that may go out of scope or any other temporary location.
The stack may access that memory directly without the application's knowledge. For writable characteristics, this value must not be a location in flash memory.*/
} ble_gatts_attr_t;
/**@brief GATT Attribute Value. */
typedef struct
{
uint16_t len; /**< Length in bytes to be written or read. Length in bytes written or read after successful return.*/
uint16_t offset; /**< Attribute value offset. */
uint8_t *p_value; /**< Pointer to where value is stored or will be stored.
If value is stored in user memory, only the attribute length is updated when p_value == NULL.
Set to NULL when reading to obtain the complete length of the attribute value */
} ble_gatts_value_t;
/**@brief GATT Characteristic Presentation Format. */
typedef struct
{
uint8_t format; /**< Format of the value, see @ref BLE_GATT_CPF_FORMATS. */
int8_t exponent; /**< Exponent for integer data types. */
uint16_t unit; /**< Unit from Bluetooth Assigned Numbers. */
uint8_t name_space; /**< Namespace from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */
uint16_t desc; /**< Namespace description from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */
} ble_gatts_char_pf_t;
/**@brief GATT Characteristic metadata. */
typedef struct
{
ble_gatt_char_props_t char_props; /**< Characteristic Properties. */
ble_gatt_char_ext_props_t char_ext_props; /**< Characteristic Extended Properties. */
uint8_t *p_char_user_desc; /**< Pointer to a UTF-8 encoded string (non-NULL terminated), NULL if the descriptor is not required. */
uint16_t char_user_desc_max_size; /**< The maximum size in bytes of the user description descriptor. */
uint16_t char_user_desc_size; /**< The size of the user description, must be smaller or equal to char_user_desc_max_size. */
ble_gatts_char_pf_t* p_char_pf; /**< Pointer to a presentation format structure or NULL if the CPF descriptor is not required. */
ble_gatts_attr_md_t* p_user_desc_md; /**< Attribute metadata for the User Description descriptor, or NULL for default values. */
ble_gatts_attr_md_t* p_cccd_md; /**< Attribute metadata for the Client Characteristic Configuration Descriptor, or NULL for default values. */
ble_gatts_attr_md_t* p_sccd_md; /**< Attribute metadata for the Server Characteristic Configuration Descriptor, or NULL for default values. */
} ble_gatts_char_md_t;
/**@brief GATT Characteristic Definition Handles. */
typedef struct
{
uint16_t value_handle; /**< Handle to the characteristic value. */
uint16_t user_desc_handle; /**< Handle to the User Description descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */
uint16_t cccd_handle; /**< Handle to the Client Characteristic Configuration Descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */
uint16_t sccd_handle; /**< Handle to the Server Characteristic Configuration Descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */
} ble_gatts_char_handles_t;
/**@brief GATT HVx parameters. */
typedef struct
{
uint16_t handle; /**< Characteristic Value Handle. */
uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */
uint16_t offset; /**< Offset within the attribute value. */
uint16_t *p_len; /**< Length in bytes to be written, length in bytes written after successful return. */
uint8_t *p_data; /**< Actual data content, use NULL to use the current attribute value. */
} ble_gatts_hvx_params_t;
/**@brief GATT Authorization parameters. */
typedef struct
{
uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */
uint8_t update : 1; /**< If set, data supplied in p_data will be used to update the attribute value.
Please note that for @ref BLE_GATTS_OP_WRITE_REQ operations this bit must always be set,
as the data to be written needs to be stored and later provided by the application. */
uint16_t offset; /**< Offset of the attribute value being updated. */
uint16_t len; /**< Length in bytes of the value in p_data pointer, see @ref BLE_GATTS_ATTR_LENS_MAX. */
const uint8_t *p_data; /**< Pointer to new value used to update the attribute value. */
} ble_gatts_authorize_params_t;
/**@brief GATT Read or Write Authorize Reply parameters. */
typedef struct
{
uint8_t type; /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */
union {
ble_gatts_authorize_params_t read; /**< Read authorization parameters. */
ble_gatts_authorize_params_t write; /**< Write authorization parameters. */
} params; /**< Reply Parameters. */
} ble_gatts_rw_authorize_reply_params_t;
/**@brief Event structure for @ref BLE_GATTS_EVT_WRITE. */
typedef struct
{
uint16_t handle; /**< Attribute Handle. */
ble_uuid_t uuid; /**< Attribute UUID. */
uint8_t op; /**< Type of write operation, see @ref BLE_GATTS_OPS. */
uint8_t auth_required; /**< Writing operation deferred due to authorization requirement. Application may use @ref sd_ble_gatts_value_set to finalise the writing operation. */
uint16_t offset; /**< Offset for the write operation. */
uint16_t len; /**< Length of the received data. */
uint8_t data[1]; /**< Received data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
} ble_gatts_evt_write_t;
/**@brief Event substructure for authorized read requests, see @ref ble_gatts_evt_rw_authorize_request_t. */
typedef struct
{
uint16_t handle; /**< Attribute Handle. */
ble_uuid_t uuid; /**< Attribute UUID. */
uint16_t offset; /**< Offset for the read operation. */
} ble_gatts_evt_read_t;
/**@brief Event structure for @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST. */
typedef struct
{
uint8_t type; /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */
union {
ble_gatts_evt_read_t read; /**< Attribute Read Parameters. */
ble_gatts_evt_write_t write; /**< Attribute Write Parameters. */
} request; /**< Request Parameters. */
} ble_gatts_evt_rw_authorize_request_t;
/**@brief Event structure for @ref BLE_GATTS_EVT_SYS_ATTR_MISSING. */
typedef struct
{
uint8_t hint; /**< Hint (currently unused). */
} ble_gatts_evt_sys_attr_missing_t;
/**@brief Event structure for @ref BLE_GATTS_EVT_HVC. */
typedef struct
{
uint16_t handle; /**< Attribute Handle. */
} ble_gatts_evt_hvc_t;
/**@brief Event structure for @ref BLE_GATTS_EVT_TIMEOUT. */
typedef struct
{
uint8_t src; /**< Timeout source, see @ref BLE_GATT_TIMEOUT_SOURCES. */
} ble_gatts_evt_timeout_t;
/**@brief GATT Server event callback event structure. */
typedef struct
{
uint16_t conn_handle; /**< Connection Handle on which the event occurred. */
union
{
ble_gatts_evt_write_t write; /**< Write Event Parameters. */
ble_gatts_evt_rw_authorize_request_t authorize_request; /**< Read or Write Authorize Request Parameters. */
ble_gatts_evt_sys_attr_missing_t sys_attr_missing; /**< System attributes missing. */
ble_gatts_evt_hvc_t hvc; /**< Handle Value Confirmation Event Parameters. */
ble_gatts_evt_timeout_t timeout; /**< Timeout Event. */
} params; /**< Event Parameters. */
} ble_gatts_evt_t;
/** @} */
/** @addtogroup BLE_GATTS_FUNCTIONS Functions
* @{ */
/**@brief Add a service declaration to the Attribute Table.
*
* @note Secondary Services are only relevant in the context of the entity that references them, it is therefore forbidden to
* add a secondary service declaration that is not referenced by another service later in the Attribute Table.
*
* @mscs
* @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC}
* @endmscs
*
* @param[in] type Toggles between primary and secondary services, see @ref BLE_GATTS_SRVC_TYPES.
* @param[in] p_uuid Pointer to service UUID.
* @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored.
*
* @retval ::NRF_SUCCESS Successfully added a service declaration.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, Vendor Specific UUIDs need to be present in the table.
* @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack.
* @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
*/
SVCALL(SD_BLE_GATTS_SERVICE_ADD, uint32_t, sd_ble_gatts_service_add(uint8_t type, ble_uuid_t const *p_uuid, uint16_t *p_handle));
/**@brief Add an include declaration to the Attribute Table.
*
* @note It is currently only possible to add an include declaration to the last added service (i.e. only sequential population is supported at this time).
*
* @note The included service must already be present in the Attribute Table prior to this call.
*
* @mscs
* @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC}
* @endmscs
*
* @param[in] service_handle Handle of the service where the included service is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially.
* @param[in] inc_srvc_handle Handle of the included service.
* @param[out] p_include_handle Pointer to a 16-bit word where the assigned handle will be stored.
*
* @retval ::NRF_SUCCESS Successfully added an include declaration.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, handle values need to match previously added services.
* @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
* @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, self inclusions are not allowed.
* @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
* @retval ::NRF_ERROR_NOT_FOUND Attribute not found.
*/
SVCALL(SD_BLE_GATTS_INCLUDE_ADD, uint32_t, sd_ble_gatts_include_add(uint16_t service_handle, uint16_t inc_srvc_handle, uint16_t *p_include_handle));
/**@brief Add a characteristic declaration, a characteristic value declaration and optional characteristic descriptor declarations to the Attribute Table.
*
* @note It is currently only possible to add a characteristic to the last added service (i.e. only sequential population is supported at this time).
*
* @note Several restrictions apply to the parameters, such as matching permissions between the user description descriptor and the writeable auxiliaries bits,
* readable (no security) and writeable (selectable) CCCDs and SCCDs and valid presentation format values.
*
* @note If no metadata is provided for the optional descriptors, their permissions will be derived from the characteristic permissions.
*
* @mscs
* @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC}
* @endmscs
*
* @param[in] service_handle Handle of the service where the characteristic is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially.
* @param[in] p_char_md Characteristic metadata.
* @param[in] p_attr_char_value Pointer to the attribute structure corresponding to the characteristic value.
* @param[out] p_handles Pointer to the structure where the assigned handles will be stored.
*
* @retval ::NRF_SUCCESS Successfully added a characteristic.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, service handle, Vendor Specific UUIDs, lengths, and permissions need to adhere to the constraints.
* @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a service context is required.
* @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack.
* @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
* @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX.
*/
SVCALL(SD_BLE_GATTS_CHARACTERISTIC_ADD, uint32_t, sd_ble_gatts_characteristic_add(uint16_t service_handle, ble_gatts_char_md_t const *p_char_md, ble_gatts_attr_t const *p_attr_char_value, ble_gatts_char_handles_t *p_handles));
/**@brief Add a descriptor to the Attribute Table.
*
* @note It is currently only possible to add a descriptor to the last added characteristic (i.e. only sequential population is supported at this time).
*
* @mscs
* @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC}
* @endmscs
*
* @param[in] char_handle Handle of the characteristic where the descriptor is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially.
* @param[in] p_attr Pointer to the attribute structure.
* @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored.
*
* @retval ::NRF_SUCCESS Successfully added a descriptor.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, characteristic handle, Vendor Specific UUIDs, lengths, and permissions need to adhere to the constraints.
* @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a characteristic context is required.
* @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack.
* @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
* @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX.
*/
SVCALL(SD_BLE_GATTS_DESCRIPTOR_ADD, uint32_t, sd_ble_gatts_descriptor_add(uint16_t char_handle, ble_gatts_attr_t const *p_attr, uint16_t *p_handle));
/**@brief Set the value of a given attribute.
*
* @note Values other than system attributes can be set at any time, regardless of wheter any active connections exist.
*
* @mscs
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC}
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC}
* @endmscs
*
* @param[in] conn_handle Connection handle. If the value does not belong to a system attribute then @ref BLE_CONN_HANDLE_INVALID can be used.
* @param[in] handle Attribute handle.
* @param[in,out] p_value Attribute value information.
*
* @retval ::NRF_SUCCESS Successfully set the value of the attribute.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
* @retval ::NRF_ERROR_NOT_FOUND Attribute not found.
* @retval ::NRF_ERROR_FORBIDDEN Forbidden handle supplied, certain attributes are not modifiable by the application.
* @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
* @retval ::BLE_ERROR_GATTS_INVALID_ATTR_TYPE @ref BLE_CONN_HANDLE_INVALID supplied on a system attribute.
*/
SVCALL(SD_BLE_GATTS_VALUE_SET, uint32_t, sd_ble_gatts_value_set(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value));
/**@brief Get the value of a given attribute.
*
* @note If the attribute value is longer than the size of the supplied buffer,
* p_len will return the total attribute value length (excluding offset),
* and not the number of bytes actually returned in p_data.
* The application may use this information to allocate a suitable buffer size.
*
* @note When retrieving system attribute values with this function, the connection handle
* may refer to an already disconnected connection. Refer to the documentation of
* @ref sd_ble_gatts_sys_attr_get for further information.
*
* @param[in] conn_handle Connection handle. If the value does not belong to a system attribute then @ref BLE_CONN_HANDLE_INVALID can be used.
* @param[in] handle Attribute handle.
* @param[in,out] p_value Attribute value information.
*
* @retval ::NRF_SUCCESS Successfully retrieved the value of the attribute.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_NOT_FOUND Attribute not found.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid attribute offset supplied.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
* @retval ::BLE_ERROR_GATTS_INVALID_ATTR_TYPE @ref BLE_CONN_HANDLE_INVALID supplied on a system attribute.
*/
SVCALL(SD_BLE_GATTS_VALUE_GET, uint32_t, sd_ble_gatts_value_get(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value));
/**@brief Notify or Indicate an attribute value.
*
* @details This function checks for the relevant Client Characteristic Configuration descriptor value to verify that the relevant operation
* (notification or indication) has been enabled by the client. It is also able to update the attribute value before issuing the PDU, so that
* the application can atomically perform a value update and a server initiated transaction with a single API call.
* If the application chooses to indicate an attribute value, a @ref BLE_GATTS_EVT_HVC event will be issued as soon as the confirmation arrives from
* the peer.
*
* @note The local attribute value may be updated even if an outgoing packet is not sent to the peer due to an error during execution.
* When receiveing the error codes @ref NRF_ERROR_INVALID_STATE, @ref NRF_ERROR_BUSY, @ref BLE_ERROR_GATTS_SYS_ATTR_MISSING and
* @ref BLE_ERROR_NO_TX_PACKETS the Attribute Table has been updated.
* The caller can check whether the value has been updated by looking at the contents of *(p_hvx_params->p_len).
*
* @note It is important to note that a notification will <b>consume an application buffer</b>, and will therefore
* generate a @ref BLE_EVT_TX_COMPLETE event when the packet has been transmitted. An indication on the other hand will use the
* standard server internal buffer and thus will only generate a @ref BLE_GATTS_EVT_HVC event as soon as the confirmation
* has been received from the peer. Please see the documentation of @ref sd_ble_tx_packet_count_get for more details.
*
* @events
* @event{@ref BLE_EVT_TX_COMPLETE, Transmission complete.}
* @event{@ref BLE_GATTS_EVT_HVC, Confirmation received from peer.}
* @endevents
*
* @mscs
* @mmsc{@ref BLE_GATTS_HVX_SYS_ATTRS_MISSING_MSC}
* @mmsc{@ref BLE_GATTS_HVN_MSC}
* @mmsc{@ref BLE_GATTS_HVI_MSC}
* @mmsc{@ref BLE_GATTS_HVX_DISABLED_MSC}
* @mmsc{@ref BLE_COMMON_APP_BUFF_MSC}
* @endmscs
*
* @param[in] conn_handle Connection handle.
* @param[in] p_hvx_params Pointer to an HVx parameters structure. If the p_data member contains a non-NULL pointer the attribute value will be updated with
* the contents pointed by it before sending the notification or indication.
*
* @retval ::NRF_SUCCESS Successfully queued a notification or indication for transmission, and optionally updated the attribute value.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or notifications and/or indications not enabled in the CCCD.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
* @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied. Only attributes added directly by the application are available to notify and indicate.
* @retval ::BLE_ERROR_GATTS_INVALID_ATTR_TYPE Invalid attribute type(s) supplied, only characteristic values may be notified and indicated.
* @retval ::NRF_ERROR_NOT_FOUND Attribute not found.
* @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied.
* @retval ::NRF_ERROR_BUSY Procedure already in progress.
* @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value.
* @retval ::BLE_ERROR_NO_TX_PACKETS No available application packets for this connection, applies only to notifications.
*/
SVCALL(SD_BLE_GATTS_HVX, uint32_t, sd_ble_gatts_hvx(uint16_t conn_handle, ble_gatts_hvx_params_t const *p_hvx_params));
/**@brief Indicate the Service Changed attribute value.
*
* @details This call will send a Handle Value Indication to one or more peers connected to inform them that the Attribute
* Table layout has changed. As soon as the peer has confirmed the indication, a @ref BLE_GATTS_EVT_SC_CONFIRM event will
* be issued.
*
* @note Some of the restrictions and limitations that apply to @ref sd_ble_gatts_hvx also apply here.
*
* @events
* @event{@ref BLE_GATTS_EVT_SC_CONFIRM, Confirmation of attribute table change received from peer.}
* @endevents
*
* @mscs
* @mmsc{@ref BLE_GATTS_SC_MSC}
* @endmscs
*
* @param[in] conn_handle Connection handle.
* @param[in] start_handle Start of affected attribute handle range.
* @param[in] end_handle End of affected attribute handle range.
*
* @retval ::NRF_SUCCESS Successfully queued the Service Changed indication for transmission.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_NOT_SUPPORTED Service Changed not enabled at initialization. See @ref sd_ble_enable and @ref ble_gatts_enable_params_t.
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or notifications and/or indications not enabled in the CCCD.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
* @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied, handles must be in the range populated by the application.
* @retval ::NRF_ERROR_BUSY Procedure already in progress.
* @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value.
*/
SVCALL(SD_BLE_GATTS_SERVICE_CHANGED, uint32_t, sd_ble_gatts_service_changed(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle));
/**@brief Respond to a Read/Write authorization request.
*
* @note This call should only be used as a response to a @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event issued to the application.
*
* @mscs
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC}
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC}
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC}
* @mmsc{@ref BLE_GATTS_READ_REQ_AUTH_MSC}
* @mmsc{@ref BLE_GATTS_WRITE_REQ_AUTH_MSC}
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC}
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_PEER_CANCEL_MSC}
* @endmscs
*
* @param[in] conn_handle Connection handle.
* @param[in] p_rw_authorize_reply_params Pointer to a structure with the attribute provided by the application.
*
* @retval ::NRF_SUCCESS Successfully queued a response to the peer, and in the case of a write operation, Attribute Table updated.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no authorization request pending.
* @retval ::NRF_ERROR_INVALID_PARAM Authorization op invalid,
* handle supplied does not match requested handle,
* or invalid data to be written provided by the application.
* @retval ::NRF_ERROR_BUSY The stack is busy. Retry at later time.
*/
SVCALL(SD_BLE_GATTS_RW_AUTHORIZE_REPLY, uint32_t, sd_ble_gatts_rw_authorize_reply(uint16_t conn_handle, ble_gatts_rw_authorize_reply_params_t const *p_rw_authorize_reply_params));
/**@brief Update persistent system attribute information.
*
* @details Supply information about persistent system attributes to the stack,
* previously obtained using @ref sd_ble_gatts_sys_attr_get.
* This call is only allowed for active connections, and is usually
* made immediately after a connection is established with an known bonded device,
* often as a response to a @ref BLE_GATTS_EVT_SYS_ATTR_MISSING.
*
* p_sysattrs may point directly to the application's stored copy of the system attributes
* obtained using @ref sd_ble_gatts_sys_attr_get.
* If the pointer is NULL, the system attribute info is initialized, assuming that
* the application does not have any previously saved system attribute data for this device.
*
* @note The state of persistent system attributes is reset upon connection establishment and then remembered for its duration.
*
* @note If this call returns with an error code different from @ref NRF_SUCCESS, the storage of persistent system attributes may have been completed only partially.
* This means that the state of the attribute table is undefined, and the application should either provide a new set of attributes using this same call or
* reset the SoftDevice to return to a known state.
*
* @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be modified.
* @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user services will be modified.
*
* @mscs
* @mmsc{@ref BLE_GATTS_HVX_SYS_ATTRS_MISSING_MSC}
* @mmsc{@ref BLE_GATTS_SYS_ATTRS_UNK_PEER_MSC}
* @mmsc{@ref BLE_GATTS_SYS_ATTRS_BONDED_PEER_MSC}
* @endmscs
*
* @param[in] conn_handle Connection handle.
* @param[in] p_sys_attr_data Pointer to a saved copy of system attributes supplied to the stack, or NULL.
* @param[in] len Size of data pointed by p_sys_attr_data, in octets.
* @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS
*
* @retval ::NRF_SUCCESS Successfully set the system attribute information.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
* @retval ::NRF_ERROR_INVALID_DATA Invalid data supplied, the data should be exactly the same as retrieved with @ref sd_ble_gatts_sys_attr_get.
* @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
* @retval ::NRF_ERROR_BUSY The stack is busy. Retry at later time.
*/
SVCALL(SD_BLE_GATTS_SYS_ATTR_SET, uint32_t, sd_ble_gatts_sys_attr_set(uint16_t conn_handle, uint8_t const *p_sys_attr_data, uint16_t len, uint32_t flags));
/**@brief Retrieve persistent system attribute information from the stack.
*
* @details This call is used to retrieve information about values to be stored perisistently by the application
* during the lifetime of a connection or after it has been terminated. When a new connection is established with the same bonded device,
* the system attribute information retrieved with this function should be restored using using @ref sd_ble_gatts_sys_attr_set.
* If retrieved after disconnection, the data should be read before a new connection established. The connection handle for
* the previous, now disconnected, connection will remain valid until a new one is created to allow this API call to refer to it.
* Connection handles belonging to active connections can be used as well, but care should be taken since the system attributes
* may be written to at any time by the peer during a connection's lifetime.
*
* @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be returned.
* @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user services will be returned.
*
* @mscs
* @mmsc{@ref BLE_GATTS_SYS_ATTRS_BONDED_PEER_MSC}
* @endmscs
*
* @param[in] conn_handle Connection handle of the recently terminated connection.
* @param[out] p_sys_attr_data Pointer to a buffer where updated information about system attributes will be filled in. The format of the data is described
* in @ref BLE_GATTS_SYS_ATTRS_FORMAT. NULL can be provided to obtain the length of the data.
* @param[in,out] p_len Size of application buffer if p_sys_attr_data is not NULL. Unconditially updated to actual length of system attribute data.
* @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS
*
* @retval ::NRF_SUCCESS Successfully retrieved the system attribute information.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_DATA_SIZE The system attribute information did not fit into the provided buffer.
* @retval ::NRF_ERROR_NOT_FOUND No system attributes found.
*/
SVCALL(SD_BLE_GATTS_SYS_ATTR_GET, uint32_t, sd_ble_gatts_sys_attr_get(uint16_t conn_handle, uint8_t *p_sys_attr_data, uint16_t *p_len, uint32_t flags));
/**@brief Retrieve the first valid user attribute handle.
*
* @param[out] p_handle Pointer to an integer where the handle will be stored.
*
* @retval ::NRF_SUCCESS Successfully retrieved the handle.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
*/
SVCALL(SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, uint32_t, sd_ble_gatts_initial_user_handle_get(uint16_t *p_handle));
/**@brief Retrieve the attribute UUID and/or metadata.
*
* @param[in] handle Attribute handle
* @param[out] p_uuid UUID of the attribute. Use NULL to omit this field.
* @param[out] p_md Metadata of the attribute. Use NULL to omit this field.
*
* @retval ::NRF_SUCCESS Successfully retrieved the attribute metadata,
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameters supplied. Returned when both @c p_uuid and @c p_md are NULL.
* @retval ::NRF_ERROR_NOT_FOUND Attribute was not found.
*/
SVCALL(SD_BLE_GATTS_ATTR_GET, uint32_t, sd_ble_gatts_attr_get(uint16_t handle, ble_uuid_t * p_uuid, ble_gatts_attr_md_t * p_md));
/** @} */
#ifdef __cplusplus
}
#endif
#endif // BLE_GATTS_H__
/**
@}
*/

View File

@ -0,0 +1,131 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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.
*
*/
/**
@addtogroup BLE_COMMON
@{
*/
#ifndef BLE_HCI_H__
#define BLE_HCI_H__
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup BLE_HCI_STATUS_CODES Bluetooth status codes
* @{ */
#define BLE_HCI_STATUS_CODE_SUCCESS 0x00 /**< Success. */
#define BLE_HCI_STATUS_CODE_UNKNOWN_BTLE_COMMAND 0x01 /**< Unknown BLE Command. */
#define BLE_HCI_STATUS_CODE_UNKNOWN_CONNECTION_IDENTIFIER 0x02 /**< Unknown Connection Identifier. */
/*0x03 Hardware Failure
0x04 Page Timeout
*/
#define BLE_HCI_AUTHENTICATION_FAILURE 0x05 /**< Authentication Failure. */
#define BLE_HCI_STATUS_CODE_PIN_OR_KEY_MISSING 0x06 /**< Pin or Key missing. */
#define BLE_HCI_MEMORY_CAPACITY_EXCEEDED 0x07 /**< Memory Capacity Exceeded. */
#define BLE_HCI_CONNECTION_TIMEOUT 0x08 /**< Connection Timeout. */
/*0x09 Connection Limit Exceeded
0x0A Synchronous Connection Limit To A Device Exceeded
0x0B ACL Connection Already Exists*/
#define BLE_HCI_STATUS_CODE_COMMAND_DISALLOWED 0x0C /**< Command Disallowed. */
/*0x0D Connection Rejected due to Limited Resources
0x0E Connection Rejected Due To Security Reasons
0x0F Connection Rejected due to Unacceptable BD_ADDR
0x10 Connection Accept Timeout Exceeded
0x11 Unsupported Feature or Parameter Value*/
#define BLE_HCI_STATUS_CODE_INVALID_BTLE_COMMAND_PARAMETERS 0x12 /**< Invalid BLE Command Parameters. */
#define BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION 0x13 /**< Remote User Terminated Connection. */
#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES 0x14 /**< Remote Device Terminated Connection due to low resources.*/
#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF 0x15 /**< Remote Device Terminated Connection due to power off. */
#define BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION 0x16 /**< Local Host Terminated Connection. */
/*
0x17 Repeated Attempts
0x18 Pairing Not Allowed
0x19 Unknown LMP PDU
*/
#define BLE_HCI_UNSUPPORTED_REMOTE_FEATURE 0x1A /**< Unsupported Remote Feature. */
/*
0x1B SCO Offset Rejected
0x1C SCO Interval Rejected
0x1D SCO Air Mode Rejected*/
#define BLE_HCI_STATUS_CODE_INVALID_LMP_PARAMETERS 0x1E /**< Invalid LMP Parameters. */
#define BLE_HCI_STATUS_CODE_UNSPECIFIED_ERROR 0x1F /**< Unspecified Error. */
/*0x20 Unsupported LMP Parameter Value
0x21 Role Change Not Allowed
*/
#define BLE_HCI_STATUS_CODE_LMP_RESPONSE_TIMEOUT 0x22 /**< LMP Response Timeout. */
/*0x23 LMP Error Transaction Collision*/
#define BLE_HCI_STATUS_CODE_LMP_PDU_NOT_ALLOWED 0x24 /**< LMP PDU Not Allowed. */
/*0x25 Encryption Mode Not Acceptable
0x26 Link Key Can Not be Changed
0x27 Requested QoS Not Supported
*/
#define BLE_HCI_INSTANT_PASSED 0x28 /**< Instant Passed. */
#define BLE_HCI_PAIRING_WITH_UNIT_KEY_UNSUPPORTED 0x29 /**< Pairing with Unit Key Unsupported. */
#define BLE_HCI_DIFFERENT_TRANSACTION_COLLISION 0x2A /**< Different Transaction Collision. */
/*
0x2B Reserved
0x2C QoS Unacceptable Parameter
0x2D QoS Rejected
0x2E Channel Classification Not Supported
0x2F Insufficient Security
0x30 Parameter Out Of Mandatory Range
0x31 Reserved
0x32 Role Switch Pending
0x33 Reserved
0x34 Reserved Slot Violation
0x35 Role Switch Failed
0x36 Extended Inquiry Response Too Large
0x37 Secure Simple Pairing Not Supported By Host.
0x38 Host Busy - Pairing
0x39 Connection Rejected due to No Suitable Channel Found*/
#define BLE_HCI_CONTROLLER_BUSY 0x3A /**< Controller Busy. */
#define BLE_HCI_CONN_INTERVAL_UNACCEPTABLE 0x3B /**< Connection Interval Unacceptable. */
#define BLE_HCI_DIRECTED_ADVERTISER_TIMEOUT 0x3C /**< Directed Adverisement Timeout. */
#define BLE_HCI_CONN_TERMINATED_DUE_TO_MIC_FAILURE 0x3D /**< Connection Terminated due to MIC Failure. */
#define BLE_HCI_CONN_FAILED_TO_BE_ESTABLISHED 0x3E /**< Connection Failed to be Established. */
/** @} */
#ifdef __cplusplus
}
#endif
#endif // BLE_HCI_H__
/** @} */

View File

@ -0,0 +1,202 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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.
*
*/
/**
@addtogroup BLE_L2CAP Logical Link Control and Adaptation Protocol (L2CAP)
@{
@brief Definitions and prototypes for the L2CAP interface.
*/
#ifndef BLE_L2CAP_H__
#define BLE_L2CAP_H__
#include "ble_types.h"
#include "ble_ranges.h"
#include "ble_err.h"
#include "nrf_svc.h"
#ifdef __cplusplus
extern "C" {
#endif
/**@addtogroup BLE_L2CAP_ENUMERATIONS Enumerations
* @{ */
/**@brief L2CAP API SVC numbers. */
enum BLE_L2CAP_SVCS
{
SD_BLE_L2CAP_CID_REGISTER = BLE_L2CAP_SVC_BASE, /**< Register a CID. */
SD_BLE_L2CAP_CID_UNREGISTER, /**< Unregister a CID. */
SD_BLE_L2CAP_TX /**< Transmit a packet. */
};
/**@brief L2CAP Event IDs. */
enum BLE_L2CAP_EVTS
{
BLE_L2CAP_EVT_RX = BLE_L2CAP_EVT_BASE /**< L2CAP packet received. */
};
/** @} */
/**@addtogroup BLE_L2CAP_DEFINES Defines
* @{ */
/**@defgroup BLE_ERRORS_L2CAP SVC return values specific to L2CAP
* @{ */
#define BLE_ERROR_L2CAP_CID_IN_USE (NRF_L2CAP_ERR_BASE + 0x000) /**< CID already in use. */
/** @} */
/**@brief Default L2CAP MTU. */
#define BLE_L2CAP_MTU_DEF (23)
/**@brief Invalid Channel Identifier. */
#define BLE_L2CAP_CID_INVALID (0x0000)
/**@brief Dynamic Channel Identifier base. */
#define BLE_L2CAP_CID_DYN_BASE (0x0040)
/**@brief Maximum amount of dynamic CIDs. */
#define BLE_L2CAP_CID_DYN_MAX (8)
/** @} */
/**@addtogroup BLE_L2CAP_STRUCTURES Structures
* @{ */
/**@brief Packet header format for L2CAP transmission. */
typedef struct
{
uint16_t len; /**< Length of valid info in data member. */
uint16_t cid; /**< Channel ID on which packet is transmitted. */
} ble_l2cap_header_t;
/**@brief L2CAP Received packet event report. */
typedef struct
{
ble_l2cap_header_t header; /**< L2CAP packet header. */
uint8_t data[1]; /**< Packet data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
} ble_l2cap_evt_rx_t;
/**@brief L2CAP event callback event structure. */
typedef struct
{
uint16_t conn_handle; /**< Connection Handle on which event occured. */
union
{
ble_l2cap_evt_rx_t rx; /**< RX Event parameters. */
} params; /**< Event Parameters. */
} ble_l2cap_evt_t;
/** @} */
/**@addtogroup BLE_L2CAP_FUNCTIONS Functions
* @{ */
/**@brief Register a CID with L2CAP.
*
* @details This registers a higher protocol layer with the L2CAP multiplexer, and is requried prior to all operations on the CID.
*
* @mscs
* @mmsc{@ref BLE_L2CAP_API_MSC}
* @endmscs
*
* @param[in] cid L2CAP CID.
*
* @retval ::NRF_SUCCESS Successfully registered a CID with the L2CAP layer.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, CID must be above @ref BLE_L2CAP_CID_DYN_BASE.
* @retval ::BLE_ERROR_L2CAP_CID_IN_USE L2CAP CID already in use.
* @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
*/
SVCALL(SD_BLE_L2CAP_CID_REGISTER, uint32_t, sd_ble_l2cap_cid_register(uint16_t cid));
/**@brief Unregister a CID with L2CAP.
*
* @details This unregisters a previously registerd higher protocol layer with the L2CAP multiplexer.
*
* @mscs
* @mmsc{@ref BLE_L2CAP_API_MSC}
* @endmscs
*
* @param[in] cid L2CAP CID.
*
* @retval ::NRF_SUCCESS Successfully unregistered the CID.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
* @retval ::NRF_ERROR_NOT_FOUND CID not previously registered.
*/
SVCALL(SD_BLE_L2CAP_CID_UNREGISTER, uint32_t, sd_ble_l2cap_cid_unregister(uint16_t cid));
/**@brief Transmit an L2CAP packet.
*
* @note It is important to note that a call to this function will <b>consume an application packet</b>, and will therefore
* generate a @ref BLE_EVT_TX_COMPLETE event when the packet has been transmitted.
* Please see the documentation of @ref sd_ble_tx_packet_count_get for more details.
*
* @events
* @event{@ref BLE_EVT_TX_COMPLETE}
* @event{@ref BLE_L2CAP_EVT_RX}
* @endevents
*
* @mscs
* @mmsc{@ref BLE_L2CAP_API_MSC}
* @endmscs
*
* @param[in] conn_handle Connection Handle.
* @param[in] p_header Pointer to a packet header containing length and CID.
* @param[in] p_data Pointer to the data to be transmitted.
*
* @retval ::NRF_SUCCESS Successfully queued an L2CAP packet for transmission.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, CIDs must be registered beforehand with @ref sd_ble_l2cap_cid_register.
* @retval ::NRF_ERROR_NOT_FOUND CID not found.
* @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
* @retval ::BLE_ERROR_NO_TX_PACKETS Not enough application packets available.
* @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, see @ref BLE_L2CAP_MTU_DEF.
*/
SVCALL(SD_BLE_L2CAP_TX, uint32_t, sd_ble_l2cap_tx(uint16_t conn_handle, ble_l2cap_header_t const *p_header, uint8_t const *p_data));
/** @} */
#ifdef __cplusplus
}
#endif
#endif // BLE_L2CAP_H__
/**
@}
*/

View File

@ -0,0 +1,126 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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.
*
*/
/**
@addtogroup BLE_COMMON
@{
@defgroup ble_ranges Module specific SVC, event and option number subranges
@{
@brief Definition of SVC, event and option number subranges for each API module.
@note
SVCs, event and option numbers are split into subranges for each API module.
Each module receives its entire allocated range of SVC calls, whether implemented or not,
but return BLE_ERROR_NOT_SUPPORTED for unimplemented or undefined calls in its range.
Note that the symbols BLE_<module>_SVC_LAST is the end of the allocated SVC range,
rather than the last SVC function call actually defined and implemented.
Specific SVC, event and option values are defined in each module's ble_<module>.h file,
which defines names of each individual SVC code based on the range start value.
*/
#ifndef BLE_RANGES_H__
#define BLE_RANGES_H__
#ifdef __cplusplus
extern "C" {
#endif
#define BLE_SVC_BASE 0x60 /**< Common BLE SVC base. */
#define BLE_SVC_LAST 0x6B /**< Total: 12. */
#define BLE_RESERVED_SVC_BASE 0x6C /**< Reserved BLE SVC base. */
#define BLE_RESERVED_SVC_LAST 0x6F /**< Total: 4. */
#define BLE_GAP_SVC_BASE 0x70 /**< GAP BLE SVC base. */
#define BLE_GAP_SVC_LAST 0x8F /**< Total: 32. */
#define BLE_GATTC_SVC_BASE 0x90 /**< GATTC BLE SVC base. */
#define BLE_GATTC_SVC_LAST 0x9F /**< Total: 32. */
#define BLE_GATTS_SVC_BASE 0xA0 /**< GATTS BLE SVC base. */
#define BLE_GATTS_SVC_LAST 0xAF /**< Total: 16. */
#define BLE_L2CAP_SVC_BASE 0xB0 /**< L2CAP BLE SVC base. */
#define BLE_L2CAP_SVC_LAST 0xBF /**< Total: 16. */
#define BLE_EVT_INVALID 0x00 /**< Invalid BLE Event. */
#define BLE_EVT_BASE 0x01 /**< Common BLE Event base. */
#define BLE_EVT_LAST 0x0F /**< Total: 15. */
#define BLE_GAP_EVT_BASE 0x10 /**< GAP BLE Event base. */
#define BLE_GAP_EVT_LAST 0x2F /**< Total: 32. */
#define BLE_GATTC_EVT_BASE 0x30 /**< GATTC BLE Event base. */
#define BLE_GATTC_EVT_LAST 0x4F /**< Total: 32. */
#define BLE_GATTS_EVT_BASE 0x50 /**< GATTS BLE Event base. */
#define BLE_GATTS_EVT_LAST 0x6F /**< Total: 32. */
#define BLE_L2CAP_EVT_BASE 0x70 /**< L2CAP BLE Event base. */
#define BLE_L2CAP_EVT_LAST 0x8F /**< Total: 32. */
#define BLE_OPT_INVALID 0x00 /**< Invalid BLE Option. */
#define BLE_OPT_BASE 0x01 /**< Common BLE Option base. */
#define BLE_OPT_LAST 0x1F /**< Total: 31. */
#define BLE_GAP_OPT_BASE 0x20 /**< GAP BLE Option base. */
#define BLE_GAP_OPT_LAST 0x3F /**< Total: 32. */
#define BLE_GATTC_OPT_BASE 0x40 /**< GATTC BLE Option base. */
#define BLE_GATTC_OPT_LAST 0x5F /**< Total: 32. */
#define BLE_GATTS_OPT_BASE 0x60 /**< GATTS BLE Option base. */
#define BLE_GATTS_OPT_LAST 0x7F /**< Total: 32. */
#define BLE_L2CAP_OPT_BASE 0x80 /**< L2CAP BLE Option base. */
#define BLE_L2CAP_OPT_LAST 0x9F /**< Total: 32. */
#ifdef __cplusplus
}
#endif
#endif /* BLE_RANGES_H__ */
/**
@}
@}
*/

View File

@ -0,0 +1,205 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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.
*
*/
/**
@addtogroup BLE_COMMON
@{
@defgroup ble_types Common types and macro definitions
@{
@brief Common types and macro definitions for the BLE SoftDevice.
*/
#ifndef BLE_TYPES_H__
#define BLE_TYPES_H__
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup BLE_TYPES_DEFINES Defines
* @{ */
/** @defgroup BLE_CONN_HANDLES BLE Connection Handles
* @{ */
#define BLE_CONN_HANDLE_INVALID 0xFFFF /**< Invalid Connection Handle. */
#define BLE_CONN_HANDLE_ALL 0xFFFE /**< Applies to all Connection Handles. */
/** @} */
/** @defgroup BLE_UUID_VALUES Assigned Values for BLE UUIDs
* @{ */
/* Generic UUIDs, applicable to all services */
#define BLE_UUID_UNKNOWN 0x0000 /**< Reserved UUID. */
#define BLE_UUID_SERVICE_PRIMARY 0x2800 /**< Primary Service. */
#define BLE_UUID_SERVICE_SECONDARY 0x2801 /**< Secondary Service. */
#define BLE_UUID_SERVICE_INCLUDE 0x2802 /**< Include. */
#define BLE_UUID_CHARACTERISTIC 0x2803 /**< Characteristic. */
#define BLE_UUID_DESCRIPTOR_CHAR_EXT_PROP 0x2900 /**< Characteristic Extended Properties Descriptor. */
#define BLE_UUID_DESCRIPTOR_CHAR_USER_DESC 0x2901 /**< Characteristic User Description Descriptor. */
#define BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG 0x2902 /**< Client Characteristic Configuration Descriptor. */
#define BLE_UUID_DESCRIPTOR_SERVER_CHAR_CONFIG 0x2903 /**< Server Characteristic Configuration Descriptor. */
#define BLE_UUID_DESCRIPTOR_CHAR_PRESENTATION_FORMAT 0x2904 /**< Characteristic Presentation Format Descriptor. */
#define BLE_UUID_DESCRIPTOR_CHAR_AGGREGATE_FORMAT 0x2905 /**< Characteristic Aggregate Format Descriptor. */
/* GATT specific UUIDs */
#define BLE_UUID_GATT 0x1801 /**< Generic Attribute Profile. */
#define BLE_UUID_GATT_CHARACTERISTIC_SERVICE_CHANGED 0x2A05 /**< Service Changed Characteristic. */
/* GAP specific UUIDs */
#define BLE_UUID_GAP 0x1800 /**< Generic Access Profile. */
#define BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME 0x2A00 /**< Device Name Characteristic. */
#define BLE_UUID_GAP_CHARACTERISTIC_APPEARANCE 0x2A01 /**< Appearance Characteristic. */
#define BLE_UUID_GAP_CHARACTERISTIC_PPF 0x2A02 /**< Peripheral Privacy Flag Characteristic. */
#define BLE_UUID_GAP_CHARACTERISTIC_RECONN_ADDR 0x2A03 /**< Reconnection Address Characteristic. */
#define BLE_UUID_GAP_CHARACTERISTIC_PPCP 0x2A04 /**< Peripheral Preferred Connection Parameters Characteristic. */
/** @} */
/** @defgroup BLE_UUID_TYPES Types of UUID
* @{ */
#define BLE_UUID_TYPE_UNKNOWN 0x00 /**< Invalid UUID type. */
#define BLE_UUID_TYPE_BLE 0x01 /**< Bluetooth SIG UUID (16-bit). */
#define BLE_UUID_TYPE_VENDOR_BEGIN 0x02 /**< Vendor UUID types start at this index (128-bit). */
/** @} */
/** @defgroup BLE_APPEARANCES Bluetooth Appearance values
* @note Retrieved from http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml
* @{ */
#define BLE_APPEARANCE_UNKNOWN 0 /**< Unknown. */
#define BLE_APPEARANCE_GENERIC_PHONE 64 /**< Generic Phone. */
#define BLE_APPEARANCE_GENERIC_COMPUTER 128 /**< Generic Computer. */
#define BLE_APPEARANCE_GENERIC_WATCH 192 /**< Generic Watch. */
#define BLE_APPEARANCE_WATCH_SPORTS_WATCH 193 /**< Watch: Sports Watch. */
#define BLE_APPEARANCE_GENERIC_CLOCK 256 /**< Generic Clock. */
#define BLE_APPEARANCE_GENERIC_DISPLAY 320 /**< Generic Display. */
#define BLE_APPEARANCE_GENERIC_REMOTE_CONTROL 384 /**< Generic Remote Control. */
#define BLE_APPEARANCE_GENERIC_EYE_GLASSES 448 /**< Generic Eye-glasses. */
#define BLE_APPEARANCE_GENERIC_TAG 512 /**< Generic Tag. */
#define BLE_APPEARANCE_GENERIC_KEYRING 576 /**< Generic Keyring. */
#define BLE_APPEARANCE_GENERIC_MEDIA_PLAYER 640 /**< Generic Media Player. */
#define BLE_APPEARANCE_GENERIC_BARCODE_SCANNER 704 /**< Generic Barcode Scanner. */
#define BLE_APPEARANCE_GENERIC_THERMOMETER 768 /**< Generic Thermometer. */
#define BLE_APPEARANCE_THERMOMETER_EAR 769 /**< Thermometer: Ear. */
#define BLE_APPEARANCE_GENERIC_HEART_RATE_SENSOR 832 /**< Generic Heart rate Sensor. */
#define BLE_APPEARANCE_HEART_RATE_SENSOR_HEART_RATE_BELT 833 /**< Heart Rate Sensor: Heart Rate Belt. */
#define BLE_APPEARANCE_GENERIC_BLOOD_PRESSURE 896 /**< Generic Blood Pressure. */
#define BLE_APPEARANCE_BLOOD_PRESSURE_ARM 897 /**< Blood Pressure: Arm. */
#define BLE_APPEARANCE_BLOOD_PRESSURE_WRIST 898 /**< Blood Pressure: Wrist. */
#define BLE_APPEARANCE_GENERIC_HID 960 /**< Human Interface Device (HID). */
#define BLE_APPEARANCE_HID_KEYBOARD 961 /**< Keyboard (HID Subtype). */
#define BLE_APPEARANCE_HID_MOUSE 962 /**< Mouse (HID Subtype). */
#define BLE_APPEARANCE_HID_JOYSTICK 963 /**< Joystiq (HID Subtype). */
#define BLE_APPEARANCE_HID_GAMEPAD 964 /**< Gamepad (HID Subtype). */
#define BLE_APPEARANCE_HID_DIGITIZERSUBTYPE 965 /**< Digitizer Tablet (HID Subtype). */
#define BLE_APPEARANCE_HID_CARD_READER 966 /**< Card Reader (HID Subtype). */
#define BLE_APPEARANCE_HID_DIGITAL_PEN 967 /**< Digital Pen (HID Subtype). */
#define BLE_APPEARANCE_HID_BARCODE 968 /**< Barcode Scanner (HID Subtype). */
#define BLE_APPEARANCE_GENERIC_GLUCOSE_METER 1024 /**< Generic Glucose Meter. */
#define BLE_APPEARANCE_GENERIC_RUNNING_WALKING_SENSOR 1088 /**< Generic Running Walking Sensor. */
#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_IN_SHOE 1089 /**< Running Walking Sensor: In-Shoe. */
#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_SHOE 1090 /**< Running Walking Sensor: On-Shoe. */
#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_HIP 1091 /**< Running Walking Sensor: On-Hip. */
#define BLE_APPEARANCE_GENERIC_CYCLING 1152 /**< Generic Cycling. */
#define BLE_APPEARANCE_CYCLING_CYCLING_COMPUTER 1153 /**< Cycling: Cycling Computer. */
#define BLE_APPEARANCE_CYCLING_SPEED_SENSOR 1154 /**< Cycling: Speed Sensor. */
#define BLE_APPEARANCE_CYCLING_CADENCE_SENSOR 1155 /**< Cycling: Cadence Sensor. */
#define BLE_APPEARANCE_CYCLING_POWER_SENSOR 1156 /**< Cycling: Power Sensor. */
#define BLE_APPEARANCE_CYCLING_SPEED_CADENCE_SENSOR 1157 /**< Cycling: Speed and Cadence Sensor. */
#define BLE_APPEARANCE_GENERIC_PULSE_OXIMETER 3136 /**< Generic Pulse Oximeter. */
#define BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP 3137 /**< Fingertip (Pulse Oximeter subtype). */
#define BLE_APPEARANCE_PULSE_OXIMETER_WRIST_WORN 3138 /**< Wrist Worn(Pulse Oximeter subtype). */
#define BLE_APPEARANCE_GENERIC_WEIGHT_SCALE 3200 /**< Generic Weight Scale. */
#define BLE_APPEARANCE_GENERIC_OUTDOOR_SPORTS_ACT 5184 /**< Generic Outdoor Sports Activity. */
#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_DISP 5185 /**< Location Display Device (Outdoor Sports Activity subtype). */
#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_DISP 5186 /**< Location and Navigation Display Device (Outdoor Sports Activity subtype). */
#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_POD 5187 /**< Location Pod (Outdoor Sports Activity subtype). */
#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_POD 5188 /**< Location and Navigation Pod (Outdoor Sports Activity subtype). */
/** @} */
/** @brief Set .type and .uuid fields of ble_uuid_struct to specified uuid value. */
#define BLE_UUID_BLE_ASSIGN(instance, value) do {\
instance.type = BLE_UUID_TYPE_BLE; \
instance.uuid = value;} while(0)
/** @brief Copy type and uuid members from src to dst ble_uuid_t pointer. Both pointers must be valid/non-null. */
#define BLE_UUID_COPY_PTR(dst, src) do {\
(dst)->type = (src)->type; \
(dst)->uuid = (src)->uuid;} while(0)
/** @brief Copy type and uuid members from src to dst ble_uuid_t struct. */
#define BLE_UUID_COPY_INST(dst, src) do {\
(dst).type = (src).type; \
(dst).uuid = (src).uuid;} while(0)
/** @brief Compare for equality both type and uuid members of two (valid, non-null) ble_uuid_t pointers. */
#define BLE_UUID_EQ(p_uuid1, p_uuid2) \
(((p_uuid1)->type == (p_uuid2)->type) && ((p_uuid1)->uuid == (p_uuid2)->uuid))
/** @brief Compare for difference both type and uuid members of two (valid, non-null) ble_uuid_t pointers. */
#define BLE_UUID_NEQ(p_uuid1, p_uuid2) \
(((p_uuid1)->type != (p_uuid2)->type) || ((p_uuid1)->uuid != (p_uuid2)->uuid))
/** @} */
/** @addtogroup BLE_TYPES_STRUCTURES Structures
* @{ */
/** @brief 128 bit UUID values. */
typedef struct
{
uint8_t uuid128[16]; /**< Little-Endian UUID bytes. */
} ble_uuid128_t;
/** @brief Bluetooth Low Energy UUID type, encapsulates both 16-bit and 128-bit UUIDs. */
typedef struct
{
uint16_t uuid; /**< 16-bit UUID value or octets 12-13 of 128-bit UUID. */
uint8_t type; /**< UUID type, see @ref BLE_UUID_TYPES. If type is @ref BLE_UUID_TYPE_UNKNOWN, the value of uuid is undefined. */
} ble_uuid_t;
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* BLE_TYPES_H__ */
/**
@}
@}
*/

View File

@ -0,0 +1,217 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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.
*
*/
/**
@defgroup nrf_mbr_api Master Boot Record API
@{
@brief APIs for updating SoftDevice and BootLoader
*/
/* Header guard */
#ifndef NRF_MBR_H__
#define NRF_MBR_H__
#include "nrf_svc.h"
#include <stdint.h>
#ifndef NRF52
#error "This header file shall only be included for nRF52 projects"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup NRF_MBR_DEFINES Defines
* @{ */
/**@brief MBR SVC Base number. */
#define MBR_SVC_BASE (0x18)
/**@brief Page size in words. */
#define MBR_PAGE_SIZE_IN_WORDS (1024)
/** @brief The size that must be reserved for the MBR when a softdevice is written to flash.
This is the offset where the first byte of the softdevice hex file is written.*/
#define MBR_SIZE (0x1000)
/** @} */
/** @addtogroup NRF_MBR_ENUMS Enumerations
* @{ */
/**@brief nRF Master Boot Record API SVC numbers. */
enum NRF_MBR_SVCS
{
SD_MBR_COMMAND = MBR_SVC_BASE, /**< ::sd_mbr_command */
};
/**@brief Possible values for ::sd_mbr_command_t.command */
enum NRF_MBR_COMMANDS
{
SD_MBR_COMMAND_COPY_BL, /**< Copy a new BootLoader. @see sd_mbr_command_copy_bl_t */
SD_MBR_COMMAND_COPY_SD, /**< Copy a new SoftDevice. @see ::sd_mbr_command_copy_sd_t*/
SD_MBR_COMMAND_INIT_SD, /**< Init forwarding interrupts to SD, and run reset function in SD*/
SD_MBR_COMMAND_COMPARE, /**< This command works like memcmp. @see ::sd_mbr_command_compare_t*/
SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET, /**< Start forwarding all exception to this address @see ::sd_mbr_command_vector_table_base_set_t*/
};
/** @} */
/** @addtogroup NRF_MBR_TYPES Types
* @{ */
/**@brief This command copies part of a new SoftDevice
* The destination area is erased before copying.
* If dst is in the middle of a flash page, that whole flash page will be erased.
* If (dst+len) is in the middle of a flash page, that whole flash page will be erased.
*
* The user of this function is responsible for setting the BPROT registers.
*
* @retval ::NRF_SUCCESS indicates that the contents of the memory blocks where copied correctly.
* @retval ::NRF_ERROR_INTERNAL indicates that the contents of the memory blocks where not verified correctly after copying.
*/
typedef struct
{
uint32_t *src; /**< Pointer to the source of data to be copied.*/
uint32_t *dst; /**< Pointer to the destination where the content is to be copied.*/
uint32_t len; /**< Number of 32 bit words to copy. Must be a multiple of @ref MBR_PAGE_SIZE_IN_WORDS words.*/
} sd_mbr_command_copy_sd_t;
/**@brief This command works like memcmp, but takes the length in words.
*
* @retval ::NRF_SUCCESS indicates that the contents of both memory blocks are equal.
* @retval ::NRF_ERROR_NULL indicates that the contents of the memory blocks are not equal.
*/
typedef struct
{
uint32_t *ptr1; /**< Pointer to block of memory. */
uint32_t *ptr2; /**< Pointer to block of memory. */
uint32_t len; /**< Number of 32 bit words to compare.*/
} sd_mbr_command_compare_t;
/**@brief This command copies a new BootLoader.
* With this command, destination of BootLoader is always the address written in NRF_UICR->BOOTADDR.
*
* Destination is erased by this function.
* If (destination+bl_len) is in the middle of a flash page, that whole flash page will be erased.
*
* This function will use PROTENSET to protect the flash that is not intended to be written.
*
* On Success, this function will not return. It will start the new BootLoader from reset-vector as normal.
*
* @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen.
* @retval ::NRF_ERROR_FORBIDDEN if NRF_UICR->BOOTADDR is not set.
* @retval ::NRF_ERROR_INVALID_LENGTH if parameters attempts to read or write outside flash area.
* @retval ::NRF_ERROR_NO_MEM if no parameter page is provided (see sds for more info)
*/
typedef struct
{
uint32_t *bl_src; /**< Pointer to the source of the Bootloader to be be copied.*/
uint32_t bl_len; /**< Number of 32 bit words to copy for BootLoader. */
} sd_mbr_command_copy_bl_t;
/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the MBR
*
* Once this function has been called, this address is where the MBR will start to forward interrupts to after a reset.
*
* To restore default forwarding this function should be called with @param address set to 0.
* The MBR will then start forwarding to interrupts to the address in NFR_UICR->BOOTADDR or to the SoftDevice if the BOOTADDR is not set.
*
* On Success, this function will not return. It will reset the device.
*
* @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen.
* @retval ::NRF_ERROR_INVALID_ADDR if parameter address is outside of the flash size.
* @retval ::NRF_ERROR_NO_MEM if no parameter page is provided (see sds for more info)
*/
typedef struct
{
uint32_t address; /**< The base address of the interrupt vector table for forwarded interrupts.*/
} sd_mbr_command_vector_table_base_set_t;
typedef struct
{
uint32_t command; /**< type of command to be issued see @ref NRF_MBR_COMMANDS. */
union
{
sd_mbr_command_copy_sd_t copy_sd; /**< Parameters for copy SoftDevice.*/
sd_mbr_command_compare_t compare; /**< Parameters for verify.*/
sd_mbr_command_copy_bl_t copy_bl; /**< Parameters for copy BootLoader. Requires parameter page. */
sd_mbr_command_vector_table_base_set_t base_set; /**< Parameters for vector table base set. Requires parameter page.*/
} params;
} sd_mbr_command_t;
/** @} */
/** @addtogroup NRF_MBR_FUNCTIONS Functions
* @{ */
/**@brief Issue Master Boot Record commands
*
* Commands used when updating a SoftDevice and bootloader.
*
* The SD_MBR_COMMAND_COPY_BL and SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET requires parameters to be
* retained by the MBR when resetting the IC. This is done in a separate flash page
* provided by the application. The uicr register UICR.NRFFW[1] must be set
* to an address corresponding to a page in the application flash space. This page will be cleared
* by the MBR and used to store the command before reset. When the UICR.NRFFW[1] field is set
* the page it refers to must not be used by the application. If the UICR.NRFFW[1] is set to
* 0xFFFFFFFF (the default) MBR commands which use flash will be unavailable and return
* NRF_ERROR_NO_MEM.
*
* @param[in] param Pointer to a struct describing the command.
*
* @note for retvals see ::sd_mbr_command_copy_sd_t ::sd_mbr_command_copy_bl_t ::sd_mbr_command_compare_t ::sd_mbr_command_vector_table_base_set_t
*
* @retval NRF_ERROR_NO_MEM if UICR.NRFFW[1] is not set (i.e. is 0xFFFFFFFF).
* @retval NRF_ERROR_INVALID_PARAM if an invalid command is given.
*/
SVCALL(SD_MBR_COMMAND, uint32_t, sd_mbr_command(sd_mbr_command_t* param));
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRF_MBR_H__
/**
@}
*/

View File

@ -0,0 +1,87 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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.
*
*/
/**
@defgroup nrf_error SoftDevice Global Error Codes
@{
@brief Global Error definitions
*/
/* Header guard */
#ifndef NRF_ERROR_H__
#define NRF_ERROR_H__
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup NRF_ERRORS_BASE Error Codes Base number definitions
* @{ */
#define NRF_ERROR_BASE_NUM (0x0) ///< Global error base
#define NRF_ERROR_SDM_BASE_NUM (0x1000) ///< SDM error base
#define NRF_ERROR_SOC_BASE_NUM (0x2000) ///< SoC error base
#define NRF_ERROR_STK_BASE_NUM (0x3000) ///< STK error base
/** @} */
#define NRF_SUCCESS (NRF_ERROR_BASE_NUM + 0) ///< Successful command
#define NRF_ERROR_SVC_HANDLER_MISSING (NRF_ERROR_BASE_NUM + 1) ///< SVC handler is missing
#define NRF_ERROR_SOFTDEVICE_NOT_ENABLED (NRF_ERROR_BASE_NUM + 2) ///< SoftDevice has not been enabled
#define NRF_ERROR_INTERNAL (NRF_ERROR_BASE_NUM + 3) ///< Internal Error
#define NRF_ERROR_NO_MEM (NRF_ERROR_BASE_NUM + 4) ///< No Memory for operation
#define NRF_ERROR_NOT_FOUND (NRF_ERROR_BASE_NUM + 5) ///< Not found
#define NRF_ERROR_NOT_SUPPORTED (NRF_ERROR_BASE_NUM + 6) ///< Not supported
#define NRF_ERROR_INVALID_PARAM (NRF_ERROR_BASE_NUM + 7) ///< Invalid Parameter
#define NRF_ERROR_INVALID_STATE (NRF_ERROR_BASE_NUM + 8) ///< Invalid state, operation disallowed in this state
#define NRF_ERROR_INVALID_LENGTH (NRF_ERROR_BASE_NUM + 9) ///< Invalid Length
#define NRF_ERROR_INVALID_FLAGS (NRF_ERROR_BASE_NUM + 10) ///< Invalid Flags
#define NRF_ERROR_INVALID_DATA (NRF_ERROR_BASE_NUM + 11) ///< Invalid Data
#define NRF_ERROR_DATA_SIZE (NRF_ERROR_BASE_NUM + 12) ///< Invalid Data size
#define NRF_ERROR_TIMEOUT (NRF_ERROR_BASE_NUM + 13) ///< Operation timed out
#define NRF_ERROR_NULL (NRF_ERROR_BASE_NUM + 14) ///< Null Pointer
#define NRF_ERROR_FORBIDDEN (NRF_ERROR_BASE_NUM + 15) ///< Forbidden Operation
#define NRF_ERROR_INVALID_ADDR (NRF_ERROR_BASE_NUM + 16) ///< Bad Memory Address
#define NRF_ERROR_BUSY (NRF_ERROR_BASE_NUM + 17) ///< Busy
#define NRF_ERROR_CONN_COUNT (NRF_ERROR_BASE_NUM + 18) ///< Maximum connection count exceeded.
#define NRF_ERROR_RESOURCES (NRF_ERROR_BASE_NUM + 19) ///< Not enough resources for operation
#ifdef __cplusplus
}
#endif
#endif // NRF_ERROR_H__
/**
@}
*/

View File

@ -16,6 +16,10 @@
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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
@ -29,39 +33,35 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
@addtogroup nrf_sdm_api
@{
@defgroup nrf_sdm_error SoftDevice Manager Error Codes
@{
#ifndef NRF_H
#define NRF_H
@brief Error definitions for the SDM API
*/
/* MDK version */
#define MDK_MAJOR_VERSION 8
#define MDK_MINOR_VERSION 5
#define MDK_MICRO_VERSION 0
/* Header guard */
#ifndef NRF_ERROR_SDM_H__
#define NRF_ERROR_SDM_H__
#if defined(_WIN32)
/* Do not include nrf51 specific files when building for PC host */
#elif defined(__unix)
/* Do not include nrf51 specific files when building for PC host */
#elif defined(__APPLE__)
/* Do not include nrf51 specific files when building for PC host */
#else
#include "nrf_error.h"
/* Family selection for family includes. */
#if defined (NRF51)
#include "nrf51.h"
#include "nrf51_bitfields.h"
#include "nrf51_deprecated.h"
#elif defined (NRF52)
#include "nrf52.h"
#include "nrf52_bitfields.h"
#include "nrf51_to_nrf52.h"
#include "nrf52_name_change.h"
#else
#error "Device family must be defined. See nrf.h."
#endif /* NRF51, NRF52 */
#ifdef __cplusplus
extern "C" {
#endif
#include "compiler_abstraction.h"
#define NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN (NRF_ERROR_SDM_BASE_NUM + 0) ///< Unknown lfclk source.
#define NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION (NRF_ERROR_SDM_BASE_NUM + 1) ///< Incorrect interrupt configuration (can be caused by using illegal priority levels, or having enabled SoftDevice interrupts).
#define NRF_ERROR_SDM_INCORRECT_CLENR0 (NRF_ERROR_SDM_BASE_NUM + 2) ///< Incorrect CLENR0 (can be caused by erronous SoftDevice flashing).
#endif /* _WIN32 || __unix || __APPLE__ */
#ifdef __cplusplus
}
#endif
#endif // NRF_ERROR_SDM_H__
#endif /* NRF_H */
/**
@}
@}
*/

View File

@ -0,0 +1,82 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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.
*
*/
/**
@addtogroup nrf_soc_api
@{
@defgroup nrf_soc_error SoC Library Error Codes
@{
@brief Error definitions for the SoC library
*/
/* Header guard */
#ifndef NRF_ERROR_SOC_H__
#define NRF_ERROR_SOC_H__
#include "nrf_error.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Mutex Errors */
#define NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN (NRF_ERROR_SOC_BASE_NUM + 0) ///< Mutex already taken
/* NVIC errors */
#define NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE (NRF_ERROR_SOC_BASE_NUM + 1) ///< NVIC interrupt not available
#define NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED (NRF_ERROR_SOC_BASE_NUM + 2) ///< NVIC interrupt priority not allowed
#define NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 3) ///< NVIC should not return
/* Power errors */
#define NRF_ERROR_SOC_POWER_MODE_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 4) ///< Power mode unknown
#define NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 5) ///< Power POF threshold unknown
#define NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 6) ///< Power off should not return
/* Rand errors */
#define NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES (NRF_ERROR_SOC_BASE_NUM + 7) ///< RAND not enough values
/* PPI errors */
#define NRF_ERROR_SOC_PPI_INVALID_CHANNEL (NRF_ERROR_SOC_BASE_NUM + 8) ///< Invalid PPI Channel
#define NRF_ERROR_SOC_PPI_INVALID_GROUP (NRF_ERROR_SOC_BASE_NUM + 9) ///< Invalid PPI Group
#ifdef __cplusplus
}
#endif
#endif // NRF_ERROR_SOC_H__
/**
@}
@}
*/

View File

@ -0,0 +1,483 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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.
*
*/
/**
* @defgroup nrf_nvic_api SoftDevice NVIC API
* @{
*
* @note In order to use this module, the following code has to be added to a .c file:
* \code
* nrf_nvic_state_t nrf_nvic_state;
* \endcode
*
* @note Definitions and declarations starting with __ (double underscore) in this header file are
* not intended for direct use by the application.
*
* @brief APIs for the accessing NVIC when using a SoftDevice.
*
*/
#ifndef NRF_NVIC_H__
#define NRF_NVIC_H__
#include <stdint.h>
#include "nrf.h"
#include "nrf_error_soc.h"
#ifdef __cplusplus
extern "C" {
#endif
/**@addtogroup NRF_NVIC_DEFINES Defines
* @{ */
/**@defgroup NRF_NVIC_ISER_DEFINES SoftDevice NVIC internal definitions
* @{ */
#define __NRF_NVIC_NVMC_IRQn (30) /**< The peripheral ID of the NVMC. IRQ numbers are used to identify peripherals, but the NVMC doesn't have an IRQ number in the MDK. */
#ifdef NRF51
#define __NRF_NVIC_ISER_COUNT (1) /**< The number of ISER/ICER registers in the NVIC that are used. */
/**@brief Interrupts used by the SoftDevice. */
#define __NRF_NVIC_SD_IRQS_0 ((uint32_t)( \
(1U << POWER_CLOCK_IRQn) \
| (1U << RADIO_IRQn) \
| (1U << RTC0_IRQn) \
| (1U << TIMER0_IRQn) \
| (1U << RNG_IRQn) \
| (1U << ECB_IRQn) \
| (1U << CCM_AAR_IRQn) \
| (1U << TEMP_IRQn) \
| (1U << __NRF_NVIC_NVMC_IRQn) \
| (1U << (uint32_t)SWI4_IRQn) \
| (1U << (uint32_t)SWI5_IRQn) \
))
/**@brief Interrupts available for to application. */
#define __NRF_NVIC_APP_IRQS_0 (~__NRF_NVIC_SD_IRQS_0)
#endif
#ifdef NRF52
#define __NRF_NVIC_ISER_COUNT (2) /**< The number of ISER/ICER registers in the NVIC that are used. */
/**@brief Interrupts used by the SoftDevice. */
#define __NRF_NVIC_SD_IRQS_0 ((uint32_t)( \
(1U << POWER_CLOCK_IRQn) \
| (1U << RADIO_IRQn) \
| (1U << RTC0_IRQn) \
| (1U << TIMER0_IRQn) \
| (1U << RNG_IRQn) \
| (1U << ECB_IRQn) \
| (1U << CCM_AAR_IRQn) \
| (1U << TEMP_IRQn) \
| (1U << __NRF_NVIC_NVMC_IRQn) \
| (1U << (uint32_t)SWI4_EGU4_IRQn) \
| (1U << (uint32_t)SWI5_EGU5_IRQn) \
))
#define __NRF_NVIC_SD_IRQS_1 ((uint32_t)0)
/**@brief Interrupts available for to application. */
#define __NRF_NVIC_APP_IRQS_0 (~__NRF_NVIC_SD_IRQS_0)
#define __NRF_NVIC_APP_IRQS_1 (~__NRF_NVIC_SD_IRQS_1)
#endif
/**@} */
/**@} */
/**@addtogroup NRF_NVIC_VARIABLES Variables
* @{ */
/**@brief Type representing the state struct for the SoftDevice NVIC module. */
typedef struct
{
uint32_t volatile __irq_masks[__NRF_NVIC_ISER_COUNT]; /**< IRQs enabled by the application in the NVIC. */
uint32_t volatile __cr_flag; /**< Non-zero if already in a critical region */
} nrf_nvic_state_t;
/**@brief Variable keeping the state for the SoftDevice NVIC module. This must be declared in an
* application source file. */
extern nrf_nvic_state_t nrf_nvic_state;
/**@} */
/**@addtogroup NRF_NVIC_INTERNAL_FUNCTIONS SoftDevice NVIC internal functions
* @{ */
/**@brief Disables IRQ interrupts globally, including the SoftDevice's interrupts.
*
* @retval The value of PRIMASK prior to disabling the interrupts.
*/
static inline int __sd_nvic_irq_disable(void)
{
int pm = __get_PRIMASK();
__disable_irq();
return pm;
}
/**@brief Enables IRQ interrupts globally, including the SoftDevice's interrupts.
*/
static inline void __sd_nvic_irq_enable(void)
{
__enable_irq();
}
/**@brief Checks if IRQn is available to application
* @param[in] IRQn irq to check
*
* @retval 1 (true) if the irq to check is available to the application
*/
static inline uint32_t __sd_nvic_app_accessible_irq(IRQn_Type IRQn)
{
if (IRQn < 32)
{
return ((1UL<<IRQn) & __NRF_NVIC_APP_IRQS_0) != 0;
}
#ifdef NRF52
else if (IRQn < 64)
{
return ((1UL<<(IRQn-32)) & __NRF_NVIC_APP_IRQS_1) != 0;
}
#endif
else
{
return 1;
}
}
/**@brief Checks if IRQn is available to application
* @param[in] priority priority to check
*
* @retval 1 (true) if the priority to check is available to the application
*/
static inline uint32_t __sd_nvic_is_app_accessible_priority(uint32_t priority)
{
if(priority >= (1 << __NVIC_PRIO_BITS))
{
return 0;
}
#ifdef NRF51
if( priority == 0
|| priority == 2
)
{
return 0;
}
#endif
#ifdef NRF52
if( priority == 0
|| priority == 1
|| priority == 4
|| priority == 5
)
{
return 0;
}
#endif
return 1;
}
/**@} */
/**@addtogroup NRF_NVIC_FUNCTIONS SoftDevice NVIC public functions
* @{ */
/**@brief Enable External Interrupt.
* @note Corresponds to NVIC_EnableIRQ in CMSIS.
*
* @pre IRQn is valid and not reserved by the stack.
*
* @param[in] IRQn See the NVIC_EnableIRQ documentation in CMSIS.
*
* @retval ::NRF_SUCCESS The interrupt was enabled.
* @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application.
* @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt has a priority not available for the application.
*/
static inline uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn)
{
if (!__sd_nvic_app_accessible_irq(IRQn))
{
return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
}
if (!__sd_nvic_is_app_accessible_priority(NVIC_GetPriority(IRQn)))
{
return NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED;
}
if (nrf_nvic_state.__cr_flag)
{
nrf_nvic_state.__irq_masks[(uint32_t)((int32_t)IRQn) >> 5] |= (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F));
}
else
{
NVIC_EnableIRQ(IRQn);
}
return NRF_SUCCESS;
}
/**@brief Disable External Interrupt.
* @note Corresponds to NVIC_DisableIRQ in CMSIS.
*
* @pre IRQn is valid and not reserved by the stack.
*
* @param[in] IRQn See the NVIC_DisableIRQ documentation in CMSIS.
*
* @retval ::NRF_SUCCESS The interrupt was disabled.
* @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application.
*/
static inline uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn)
{
if (!__sd_nvic_app_accessible_irq(IRQn))
{
return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
}
if (nrf_nvic_state.__cr_flag)
{
nrf_nvic_state.__irq_masks[(uint32_t)((int32_t)IRQn) >> 5] &= ~(1UL << ((uint32_t)(IRQn) & 0x1F));
}
else
{
NVIC_DisableIRQ(IRQn);
}
return NRF_SUCCESS;
}
/**@brief Get Pending Interrupt.
* @note Corresponds to NVIC_GetPendingIRQ in CMSIS.
*
* @pre IRQn is valid and not reserved by the stack.
*
* @param[in] IRQn See the NVIC_GetPendingIRQ documentation in CMSIS.
* @param[out] p_pending_irq Return value from NVIC_GetPendingIRQ.
*
* @retval ::NRF_SUCCESS The interrupt is available for the application.
* @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application.
*/
static inline uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq)
{
if (__sd_nvic_app_accessible_irq(IRQn))
{
*p_pending_irq = NVIC_GetPendingIRQ(IRQn);
return NRF_SUCCESS;
}
else
{
return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
}
}
/**@brief Set Pending Interrupt.
* @note Corresponds to NVIC_SetPendingIRQ in CMSIS.
*
* @pre IRQn is valid and not reserved by the stack.
*
* @param[in] IRQn See the NVIC_SetPendingIRQ documentation in CMSIS.
*
* @retval ::NRF_SUCCESS The interrupt is set pending.
* @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application.
*/
static inline uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn)
{
if (__sd_nvic_app_accessible_irq(IRQn))
{
NVIC_SetPendingIRQ(IRQn);
return NRF_SUCCESS;
}
else
{
return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
}
}
/**@brief Clear Pending Interrupt.
* @note Corresponds to NVIC_ClearPendingIRQ in CMSIS.
*
* @pre IRQn is valid and not reserved by the stack.
*
* @param[in] IRQn See the NVIC_ClearPendingIRQ documentation in CMSIS.
*
* @retval ::NRF_SUCCESS The interrupt pending flag is cleared.
* @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application.
*/
static inline uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn)
{
if (__sd_nvic_app_accessible_irq(IRQn))
{
NVIC_ClearPendingIRQ(IRQn);
return NRF_SUCCESS;
}
else
{
return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
}
}
/**@brief Set Interrupt Priority.
* @note Corresponds to NVIC_SetPriority in CMSIS.
*
* @pre IRQn is valid and not reserved by the stack.
* @pre Priority is valid and not reserved by the stack.
*
* @param[in] IRQn See the NVIC_SetPriority documentation in CMSIS.
* @param[in] priority A valid IRQ priority for use by the application.
*
* @retval ::NRF_SUCCESS The interrupt and priority level is available for the application.
* @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application.
* @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt priority is not available for the application.
*/
static inline uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if (!__sd_nvic_app_accessible_irq(IRQn))
{
return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
}
if (!__sd_nvic_is_app_accessible_priority(priority))
{
return NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED;
}
NVIC_SetPriority(IRQn, (uint32_t)priority);
return NRF_SUCCESS;
}
/**@brief Get Interrupt Priority.
* @note Corresponds to NVIC_GetPriority in CMSIS.
*
* @pre IRQn is valid and not reserved by the stack.
*
* @param[in] IRQn See the NVIC_GetPriority documentation in CMSIS.
* @param[out] p_priority Return value from NVIC_GetPriority.
*
* @retval ::NRF_SUCCESS The interrupt priority is returned in p_priority.
* @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE - IRQn is not available for the application.
*/
static inline uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, uint32_t * p_priority)
{
if (__sd_nvic_app_accessible_irq(IRQn))
{
*p_priority = (NVIC_GetPriority(IRQn) & 0xFF);
return NRF_SUCCESS;
}
else
{
return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
}
}
/**@brief System Reset.
* @note Corresponds to NVIC_SystemReset in CMSIS.
*
* @retval ::NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN
*/
static inline uint32_t sd_nvic_SystemReset(void)
{
NVIC_SystemReset();
return NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN;
}
/**@brief Enters critical region.
*
* @post Application interrupts will be disabled.
* @note sd_nvic_critical_region_enter() and ::sd_nvic_critical_region_exit() must be called in matching pairs inside each
* execution context
* @sa sd_nvic_critical_region_exit
*
* @retval ::NRF_SUCCESS
*/
static inline uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region)
{
int was_masked = __sd_nvic_irq_disable();
if (!nrf_nvic_state.__cr_flag)
{
nrf_nvic_state.__cr_flag = 1;
nrf_nvic_state.__irq_masks[0] = ( NVIC->ICER[0] & __NRF_NVIC_APP_IRQS_0 );
NVIC->ICER[0] = __NRF_NVIC_APP_IRQS_0;
#ifdef NRF52
nrf_nvic_state.__irq_masks[1] = ( NVIC->ICER[1] & __NRF_NVIC_APP_IRQS_1 );
NVIC->ICER[1] = __NRF_NVIC_APP_IRQS_1;
#endif
*p_is_nested_critical_region = 0;
}
else
{
*p_is_nested_critical_region = 1;
}
if (!was_masked)
{
__sd_nvic_irq_enable();
}
return NRF_SUCCESS;
}
/**@brief Exit critical region.
*
* @pre Application has entered a critical region using ::sd_nvic_critical_region_enter.
* @post If not in a nested critical region, the application interrupts will restored to the state before ::sd_nvic_critical_region_enter was called.
*
* @param[in] is_nested_critical_region If this is set to 1, the critical region won't be exited. @sa sd_nvic_critical_region_enter.
*
* @retval ::NRF_SUCCESS
*/
static inline uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region)
{
if (nrf_nvic_state.__cr_flag && (is_nested_critical_region == 0))
{
int was_masked = __sd_nvic_irq_disable();
NVIC->ISER[0] = nrf_nvic_state.__irq_masks[0];
#ifdef NRF52
NVIC->ISER[1] = nrf_nvic_state.__irq_masks[1];
#endif
nrf_nvic_state.__cr_flag = 0;
if (!was_masked)
{
__sd_nvic_irq_enable();
}
}
return NRF_SUCCESS;
}
/**@} */
#ifdef __cplusplus
}
#endif
#endif // NRF_NVIC_H__
/**@} */

View File

@ -0,0 +1,23 @@
/* 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.
*
*/
#ifndef NRF_SD_DEF_H__
#define NRF_SD_DEF_H__
#include <stdint.h>
#define SD_PPI_CHANNELS_USED 0xFFF0C000uL /**< PPI channels utilized by SotfDevice (not available to the application). */
#define SD_PPI_GROUPS_USED 0x0000000CuL /**< PPI groups utilized by SoftDevice (not available to the application). */
#define SD_TIMERS_USED 0x00000001uL /**< Timers used by SoftDevice. */
#define SD_SWI_USED 0x0000003CuL /**< Software interrupts used by SoftDevice */
#endif /* NRF_SD_DEF_H__ */

View File

@ -0,0 +1,271 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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.
*
*/
/**
@defgroup nrf_sdm_api SoftDevice Manager API
@{
@brief APIs for SoftDevice management.
*/
/* Header guard */
#ifndef NRF_SDM_H__
#define NRF_SDM_H__
#include "nrf_svc.h"
#include "nrf.h"
#include "nrf_soc.h"
#include "nrf_error_sdm.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup NRF_SDM_DEFINES Defines
* @{ */
#ifdef NRFSOC_DOXYGEN
//Stuff defined elsewere, to satisfy doxygen
#define MBR_SIZE 0
#warning test
#endif
/** @brief SoftDevice Manager SVC Base number. */
#define SDM_SVC_BASE 0x10
/** @brief Defines the SoftDevice Information Structure location (address) as an offset from
the start of the softdevice (without MBR)*/
#define SOFTDEVICE_INFO_STRUCT_OFFSET (0x2000)
/** @brief Defines the absolute Softdevice information structure location (address)*/
#define SOFTDEVICE_INFO_STRUCT_ADDRESS (SOFTDEVICE_INFO_STRUCT_OFFSET + MBR_SIZE)
/** @brief Defines the offset for Softdevice size value relative to Softdevice base address*/
#define SD_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x08)
/** @brief Defines the offset for FWID value relative to Softdevice base address*/
#define SD_FWID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x0C)
/** @brief Defines a macro for retreiving the actual Softdevice size value from a given base address
use @ref MBR_SIZE when Softdevice is installed just above the MBR (the usual case)*/
#define SD_SIZE_GET(baseaddr) (*((uint32_t *) ((baseaddr) + SD_SIZE_OFFSET)))
/** @brief Defines a macro for retreiving the actual FWID value from a given base address
use @ref MBR_SIZE when Softdevice is installed just above the MBR (the usual case)*/
#define SD_FWID_GET(baseaddr) ((*((uint32_t *) ((baseaddr) + SD_FWID_OFFSET))) & 0xFFFF)
/**@defgroup NRF_FAULT_ID_RANGES Fault ID ranges
* @{ */
#define NRF_FAULT_ID_SD_RANGE_START 0x00000000 /**< SoftDevice ID range start. */
#define NRF_FAULT_ID_APP_RANGE_START 0x00001000 /**< Application ID range start. */
/**@} */
/**@defgroup NRF_FAULT_IDS Fault ID types
* @{ */
#define NRF_FAULT_ID_SD_ASSERT (NRF_FAULT_ID_SD_RANGE_START + 1) /**< SoftDevice assertion. The info parameter will be set to 0x00000000. */
#define NRF_FAULT_ID_APP_MEMACC (NRF_FAULT_ID_APP_RANGE_START + 1) /**< Application invalid memory access. The info parameter will contain the address in memory that was accessed. */
/**@} */
/** @} */
/** @addtogroup NRF_SDM_ENUMS Enumerations
* @{ */
/**@brief nRF SoftDevice Manager API SVC numbers. */
enum NRF_SD_SVCS
{
SD_SOFTDEVICE_ENABLE = SDM_SVC_BASE, /**< ::sd_softdevice_enable */
SD_SOFTDEVICE_DISABLE, /**< ::sd_softdevice_disable */
SD_SOFTDEVICE_IS_ENABLED, /**< ::sd_softdevice_is_enabled */
SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, /**< ::sd_softdevice_vector_table_base_set */
SVC_SDM_LAST /**< Placeholder for last SDM SVC */
};
/** @} */
/** @addtogroup NRF_SDM_DEFINES Defines
* @{ */
/**@defgroup NRF_CLOCK_LF_XTAL_ACCURACY Clock accuracy * @{ */
#define NRF_CLOCK_LF_XTAL_ACCURACY_250_PPM (0) /* Default */
#define NRF_CLOCK_LF_XTAL_ACCURACY_500_PPM (1)
#define NRF_CLOCK_LF_XTAL_ACCURACY_150_PPM (2)
#define NRF_CLOCK_LF_XTAL_ACCURACY_100_PPM (3)
#define NRF_CLOCK_LF_XTAL_ACCURACY_75_PPM (4)
#define NRF_CLOCK_LF_XTAL_ACCURACY_50_PPM (5)
#define NRF_CLOCK_LF_XTAL_ACCURACY_30_PPM (6)
#define NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM (7)
/** @} */
/**@defgroup NRF_CLOCK_LF_SRC Possible lfclk oscillator sources * @{ */
#define NRF_CLOCK_LF_SRC_RC (0) /**< LFCLK RC oscillator. */
#define NRF_CLOCK_LF_SRC_XTAL (1) /**< LFCLK crystal oscillator. */
#define NRF_CLOCK_LF_SRC_SYNTH (2) /**< LFCLK Synthesized from HFCLK. */
/** @} */
/** @} */
/** @addtogroup NRF_SDM_TYPES Types
* @{ */
/**@brief Type representing lfclk oscillator source. */
typedef struct
{
uint8_t source; /**< LF oscillator clock source, see @ref NRF_CLOCK_LF_SRC. */
uint8_t rc_ctiv; /**< Only for NRF_CLOCK_LF_SRC_RC: Calibration timer interval in 1/4 second
units (nRF51: 1-64, nRF52: 1-32).
@note To avoid excessive clock drift, 0.5 degrees Celsius is the
maximum temperature change allowed in one calibration timer
interval. The interval should be selected to ensure this.
@note Must be 0 if source is not NRF_CLOCK_LF_SRC_RC. */
uint8_t rc_temp_ctiv; /**< Only for NRF_CLOCK_LF_SRC_RC: How often (in number of calibration
intervals) the RC oscillator shall be calibrated if the temperature
hasn't changed.
0: Always calibrate even if the temperature hasn't changed.
1: Only calibrate if the temperature has changed (nRF51 only).
2-33: Check the temperature and only calibrate if it has changed,
however calibration will take place every rc_temp_ctiv
intervals in any case.
@note Must be 0 if source is not NRF_CLOCK_LF_SRC_RC.
@note For nRF52, the application must ensure calibration at least once
every 8 seconds to ensure +/-250ppm clock stability. The
recommended configuration for NRF_CLOCK_LF_SRC_RC on nRF52 is
rc_ctiv=16 and rc_temp_ctiv=2. This will ensure calibration at
least once every 8 seconds and for temperature changes of 0.5
degrees Celsius every 4 seconds. See the Product Specification
for the nRF52 device being used for more information.*/
uint8_t xtal_accuracy; /**< External crystal clock accuracy used in the LL to compute timing windows.
@note For the NRF_CLOCK_LF_SRC_RC clock source this parameter is ignored. */
} nrf_clock_lf_cfg_t;
/**@brief Fault Handler type.
*
* When certain unrecoverable errors occur within the application or SoftDevice the fault handler will be called back.
* The protocol stack will be in an undefined state when this happens and the only way to recover will be to
* perform a reset, using e.g. CMSIS NVIC_SystemReset().
*
* @note This callback is executed in HardFault context, thus SVC functions cannot be called from the fault callback.
*
* @param[in] id Fault identifier. See @ref NRF_FAULT_IDS.
* @param[in] pc The program counter of the instruction that triggered the fault.
* @param[in] info Optional additional information regarding the fault. Refer to each Fault identifier for details.
*/
typedef void (*nrf_fault_handler_t)(uint32_t id, uint32_t pc, uint32_t info);
/** @} */
/** @addtogroup NRF_SDM_FUNCTIONS Functions
* @{ */
/**@brief Enables the SoftDevice and by extension the protocol stack.
*
* @note Some care must be taken if a low frequency clock source is already running when calling this function:
* If the LF clock has a different source then the one currently running, it will be stopped. Then, the new
* clock source will be started.
*
* @note This function has no effect when returning with an error.
*
* @post If return code is ::NRF_SUCCESS
* - SoC library and protocol stack APIs are made available.
* - A portion of RAM will be unavailable (see relevant SDS documentation).
* - Some peripherals will be unavailable or available only through the SoC API (see relevant SDS documentation).
* - Interrupts will not arrive from protected peripherals or interrupts.
* - nrf_nvic_ functions must be used instead of CMSIS NVIC_ functions for reliable usage of the SoftDevice.
* - Interrupt latency may be affected by the SoftDevice (see relevant SDS documentation).
* - Chosen low frequency clock source will be running.
*
* @param p_clock_lf_cfg Low frequency clock source and accuracy.
If NULL the clock will be configured as an rc source with rc_ctiv = 16 and .rc_temp_ctiv = 2
In the case of XTAL source, the PPM accuracy of the chosen clock source must be greater than or equal to the actual characteristics of your XTAL clock.
* @param fault_handler Callback to be invoked in case of fault.
*
* @retval ::NRF_SUCCESS
* @retval ::NRF_ERROR_INVALID_STATE SoftDevice is already enabled, and the clock source and fault handler cannot be updated.
* @retval ::NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION SoftDevice interrupt is already enabled, or an enabled interrupt has an illegal priority level.
* @retval ::NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN Unknown low frequency clock source selected.
*/
SVCALL(SD_SOFTDEVICE_ENABLE, uint32_t, sd_softdevice_enable(nrf_clock_lf_cfg_t const * p_clock_lf_cfg, nrf_fault_handler_t fault_handler));
/**@brief Disables the SoftDevice and by extension the protocol stack.
*
* Idempotent function to disable the SoftDevice.
*
* @post SoC library and protocol stack APIs are made unavailable.
* @post All interrupts that was protected by the SoftDevice will be disabled and initialized to priority 0 (highest).
* @post All peripherals used by the SoftDevice will be reset to default values.
* @post All of RAM become available.
* @post All interrupts are forwarded to the application.
* @post LFCLK source chosen in ::sd_softdevice_enable will be left running.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_SOFTDEVICE_DISABLE, uint32_t, sd_softdevice_disable(void));
/**@brief Check if the SoftDevice is enabled.
*
* @param[out] p_softdevice_enabled If the SoftDevice is enabled: 1 else 0.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_SOFTDEVICE_IS_ENABLED, uint32_t, sd_softdevice_is_enabled(uint8_t * p_softdevice_enabled));
/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the SoftDevice
*
* This function is only intended to be called when a bootloader is enabled.
*
* @param[in] address The base address of the interrupt vector table for forwarded interrupts.
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, uint32_t, sd_softdevice_vector_table_base_set(uint32_t address));
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRF_SDM_H__
/**
@}
*/

View File

@ -0,0 +1,908 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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.
*
*/
/**
* @defgroup nrf_soc_api SoC Library API
* @{
*
* @brief APIs for the SoC library.
*
*/
#ifndef NRF_SOC_H__
#define NRF_SOC_H__
#include <stdint.h>
#include <stdbool.h>
#include "nrf_svc.h"
#include "nrf.h"
#include "nrf_error_soc.h"
#ifdef __cplusplus
extern "C" {
#endif
/**@addtogroup NRF_SOC_DEFINES Defines
* @{ */
/**@brief The number of the lowest SVC number reserved for the SoC library. */
#define SOC_SVC_BASE (0x20)
#define SOC_SVC_BASE_NOT_AVAILABLE (0x2B)
/**@brief Guranteed time for application to process radio inactive notification. */
#define NRF_RADIO_NOTIFICATION_INACTIVE_GUARANTEED_TIME_US (62)
/**@brief The minimum allowed timeslot extension time. */
#define NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US (200)
#define SOC_ECB_KEY_LENGTH (16) /**< ECB key length. */
#define SOC_ECB_CLEARTEXT_LENGTH (16) /**< ECB cleartext length. */
#define SOC_ECB_CIPHERTEXT_LENGTH (SOC_ECB_CLEARTEXT_LENGTH) /**< ECB ciphertext length. */
#ifdef NRF51
#define SD_EVT_IRQn (SWI2_IRQn) /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */
#define SD_EVT_IRQHandler (SWI2_IRQHandler) /**< SoftDevice Event IRQ handler. Used for both protocol events and SoC events. */
#define RADIO_NOTIFICATION_IRQn (SWI1_IRQn) /**< The radio notification IRQ number. */
#define RADIO_NOTIFICATION_IRQHandler (SWI1_IRQHandler) /**< The radio notification IRQ handler. */
#endif
#ifdef NRF52
#define SD_EVT_IRQn (SWI2_EGU2_IRQn) /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */
#define SD_EVT_IRQHandler (SWI2_EGU2_IRQHandler) /**< SoftDevice Event IRQ handler. Used for both protocol events and SoC events. */
#define RADIO_NOTIFICATION_IRQn (SWI1_EGU1_IRQn) /**< The radio notification IRQ number. */
#define RADIO_NOTIFICATION_IRQHandler (SWI1_EGU1_IRQHandler) /**< The radio notification IRQ handler. */
#endif
#define NRF_RADIO_LENGTH_MIN_US (100) /**< The shortest allowed radio timeslot, in microseconds. */
#define NRF_RADIO_LENGTH_MAX_US (100000) /**< The longest allowed radio timeslot, in microseconds. */
#define NRF_RADIO_DISTANCE_MAX_US (128000000UL - 1UL) /**< The longest timeslot distance, in microseconds, allowed for the distance parameter (see @ref nrf_radio_request_normal_t) in the request. */
#define NRF_RADIO_EARLIEST_TIMEOUT_MAX_US (128000000UL - 1UL) /**< The longest timeout, in microseconds, allowed when requesting the earliest possible timeslot. */
#define NRF_RADIO_START_JITTER_US (2) /**< The maximum jitter in @ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START relative to the requested start time. */
/**@} */
/**@addtogroup NRF_SOC_ENUMS Enumerations
* @{ */
/**@brief The SVC numbers used by the SVC functions in the SoC library. */
enum NRF_SOC_SVCS
{
SD_PPI_CHANNEL_ENABLE_GET = SOC_SVC_BASE,
SD_PPI_CHANNEL_ENABLE_SET,
SD_PPI_CHANNEL_ENABLE_CLR,
SD_PPI_CHANNEL_ASSIGN,
SD_PPI_GROUP_TASK_ENABLE,
SD_PPI_GROUP_TASK_DISABLE,
SD_PPI_GROUP_ASSIGN,
SD_PPI_GROUP_GET,
SD_FLASH_PAGE_ERASE,
SD_FLASH_WRITE,
SD_FLASH_PROTECT,
SD_MUTEX_NEW = SOC_SVC_BASE_NOT_AVAILABLE,
SD_MUTEX_ACQUIRE,
SD_MUTEX_RELEASE,
SD_RFU_1,
SD_RFU_2,
SD_RFU_3,
SD_RFU_4,
SD_RFU_5,
SD_RFU_6,
SD_RFU_7,
SD_RFU_8,
SD_RFU_9,
SD_RFU_10,
SD_RAND_APPLICATION_POOL_CAPACITY_GET,
SD_RAND_APPLICATION_BYTES_AVAILABLE_GET,
SD_RAND_APPLICATION_VECTOR_GET,
SD_POWER_MODE_SET,
SD_POWER_SYSTEM_OFF,
SD_POWER_RESET_REASON_GET,
SD_POWER_RESET_REASON_CLR,
SD_POWER_POF_ENABLE,
SD_POWER_POF_THRESHOLD_SET,
SD_POWER_RAMON_SET,
SD_POWER_RAMON_CLR,
SD_POWER_RAMON_GET,
SD_POWER_GPREGRET_SET,
SD_POWER_GPREGRET_CLR,
SD_POWER_GPREGRET_GET,
SD_POWER_DCDC_MODE_SET,
SD_APP_EVT_WAIT,
SD_CLOCK_HFCLK_REQUEST,
SD_CLOCK_HFCLK_RELEASE,
SD_CLOCK_HFCLK_IS_RUNNING,
SD_RADIO_NOTIFICATION_CFG_SET,
SD_ECB_BLOCK_ENCRYPT,
SD_ECB_BLOCKS_ENCRYPT,
SD_RADIO_SESSION_OPEN,
SD_RADIO_SESSION_CLOSE,
SD_RADIO_REQUEST,
SD_EVT_GET,
SD_TEMP_GET,
SVC_SOC_LAST
};
/**@brief Possible values of a ::nrf_mutex_t. */
enum NRF_MUTEX_VALUES
{
NRF_MUTEX_FREE,
NRF_MUTEX_TAKEN
};
/**@brief Power modes. */
enum NRF_POWER_MODES
{
NRF_POWER_MODE_CONSTLAT, /**< Constant latency mode. See power management in the reference manual. */
NRF_POWER_MODE_LOWPWR /**< Low power mode. See power management in the reference manual. */
};
/**@brief Power failure thresholds */
enum NRF_POWER_THRESHOLDS
{
NRF_POWER_THRESHOLD_V21, /**< 2.1 Volts power failure threshold. */
NRF_POWER_THRESHOLD_V23, /**< 2.3 Volts power failure threshold. */
NRF_POWER_THRESHOLD_V25, /**< 2.5 Volts power failure threshold. */
NRF_POWER_THRESHOLD_V27 /**< 2.7 Volts power failure threshold. */
};
/**@brief DC/DC converter modes. */
enum NRF_POWER_DCDC_MODES
{
NRF_POWER_DCDC_DISABLE, /**< The DCDC is disabled. */
NRF_POWER_DCDC_ENABLE /**< The DCDC is enabled. */
};
/**@brief Radio notification distances. */
enum NRF_RADIO_NOTIFICATION_DISTANCES
{
NRF_RADIO_NOTIFICATION_DISTANCE_NONE = 0, /**< The event does not have a notification. */
NRF_RADIO_NOTIFICATION_DISTANCE_800US, /**< The distance from the active notification to start of radio activity. */
NRF_RADIO_NOTIFICATION_DISTANCE_1740US, /**< The distance from the active notification to start of radio activity. */
NRF_RADIO_NOTIFICATION_DISTANCE_2680US, /**< The distance from the active notification to start of radio activity. */
NRF_RADIO_NOTIFICATION_DISTANCE_3620US, /**< The distance from the active notification to start of radio activity. */
NRF_RADIO_NOTIFICATION_DISTANCE_4560US, /**< The distance from the active notification to start of radio activity. */
NRF_RADIO_NOTIFICATION_DISTANCE_5500US /**< The distance from the active notification to start of radio activity. */
};
/**@brief Radio notification types. */
enum NRF_RADIO_NOTIFICATION_TYPES
{
NRF_RADIO_NOTIFICATION_TYPE_NONE = 0, /**< The event does not have a radio notification signal. */
NRF_RADIO_NOTIFICATION_TYPE_INT_ON_ACTIVE, /**< Using interrupt for notification when the radio will be enabled. */
NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE, /**< Using interrupt for notification when the radio has been disabled. */
NRF_RADIO_NOTIFICATION_TYPE_INT_ON_BOTH, /**< Using interrupt for notification both when the radio will be enabled and disabled. */
};
/**@brief The Radio signal callback types. */
enum NRF_RADIO_CALLBACK_SIGNAL_TYPE
{
NRF_RADIO_CALLBACK_SIGNAL_TYPE_START, /**< This signal indicates the start of the radio timeslot. */
NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0, /**< This signal indicates the NRF_TIMER0 interrupt. */
NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO, /**< This signal indicates the NRF_RADIO interrupt. */
NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_FAILED, /**< This signal indicates extend action failed. */
NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED /**< This signal indicates extend action succeeded. */
};
/**@brief The actions requested by the signal callback.
*
* This code gives the SOC instructions about what action to take when the signal callback has
* returned.
*/
enum NRF_RADIO_SIGNAL_CALLBACK_ACTION
{
NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE, /**< Return without action. */
NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND, /**< Request an extension of the current timeslot (maximum execution time for this action is when the extension succeeded). */
NRF_RADIO_SIGNAL_CALLBACK_ACTION_END, /**< End the current radio timeslot. */
NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END /**< Request a new radio timeslot and end the current timeslot. */
};
/**@brief Radio timeslot high frequency clock source configuration. */
enum NRF_RADIO_HFCLK_CFG
{
NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED, /**< The SoftDevice will guarantee that the high frequency clock source is the
external crystal for the whole duration of the timeslot. This should be the
preferred option for events that use the radio or require high timing accuracy. */
NRF_RADIO_HFCLK_CFG_NO_GUARANTEE /**< This configuration allows for earlier and tighter scheduling of timeslots.
The RC oscillator may be the clock source in part or for the whole duration of the timeslot.
The RC oscillator's accuracy must therefore be taken into consideration.
@note If the application will use the radio peripheral in timeslots with this configuration,
it must make sure that the crystal is running and stable before starting the radio. */
};
/**@brief Radio timeslot priorities. */
enum NRF_RADIO_PRIORITY
{
NRF_RADIO_PRIORITY_HIGH, /**< High (equal priority as the normal connection priority of the SoftDevice stack(s)). */
NRF_RADIO_PRIORITY_NORMAL, /**< Normal (equal priority as the priority of secondary activites of the SoftDevice stack(s)). */
};
/**@brief Radio timeslot request type. */
enum NRF_RADIO_REQUEST_TYPE
{
NRF_RADIO_REQ_TYPE_EARLIEST, /**< Request radio timeslot as early as possible. This should always be used for the first request in a session. */
NRF_RADIO_REQ_TYPE_NORMAL /**< Normal radio timeslot request. */
};
/**@brief SoC Events. */
enum NRF_SOC_EVTS
{
NRF_EVT_HFCLKSTARTED, /**< Event indicating that the HFCLK has started. */
NRF_EVT_POWER_FAILURE_WARNING, /**< Event indicating that a power failure warning has occurred. */
NRF_EVT_FLASH_OPERATION_SUCCESS, /**< Event indicating that the ongoing flash operation has completed successfully. */
NRF_EVT_FLASH_OPERATION_ERROR, /**< Event indicating that the ongoing flash operation has timed out with an error. */
NRF_EVT_RADIO_BLOCKED, /**< Event indicating that a radio timeslot was blocked. */
NRF_EVT_RADIO_CANCELED, /**< Event indicating that a radio timeslot was canceled by SoftDevice. */
NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN, /**< Event indicating that a radio timeslot signal callback handler return was invalid. */
NRF_EVT_RADIO_SESSION_IDLE, /**< Event indicating that a radio timeslot session is idle. */
NRF_EVT_RADIO_SESSION_CLOSED, /**< Event indicating that a radio timeslot session is closed. */
NRF_EVT_NUMBER_OF_EVTS
};
/**@} */
/**@addtogroup NRF_SOC_STRUCTURES Structures
* @{ */
/**@brief Represents a mutex for use with the nrf_mutex functions.
* @note Accessing the value directly is not safe, use the mutex functions!
*/
typedef volatile uint8_t nrf_mutex_t;
/**@brief Parameters for a request for a timeslot as early as possible. */
typedef struct
{
uint8_t hfclk; /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */
uint8_t priority; /**< The radio timeslot priority, see @ref NRF_RADIO_PRIORITY. */
uint32_t length_us; /**< The radio timeslot length (in the range 100 to 100,000] microseconds). */
uint32_t timeout_us; /**< Longest acceptable delay until the start of the requested timeslot (up to @ref NRF_RADIO_EARLIEST_TIMEOUT_MAX_US microseconds). */
} nrf_radio_request_earliest_t;
/**@brief Parameters for a normal radio timeslot request. */
typedef struct
{
uint8_t hfclk; /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */
uint8_t priority; /**< The radio timeslot priority, see @ref NRF_RADIO_PRIORITY. */
uint32_t distance_us; /**< Distance from the start of the previous radio timeslot (up to @ref NRF_RADIO_DISTANCE_MAX_US microseconds). */
uint32_t length_us; /**< The radio timeslot length (in the range [100..100,000] microseconds). */
} nrf_radio_request_normal_t;
/**@brief Radio timeslot request parameters. */
typedef struct
{
uint8_t request_type; /**< Type of request, see @ref NRF_RADIO_REQUEST_TYPE. */
union
{
nrf_radio_request_earliest_t earliest; /**< Parameters for requesting a radio timeslot as early as possible. */
nrf_radio_request_normal_t normal; /**< Parameters for requesting a normal radio timeslot. */
} params;
} nrf_radio_request_t;
/**@brief Return parameters of the radio timeslot signal callback. */
typedef struct
{
uint8_t callback_action; /**< The action requested by the application when returning from the signal callback, see @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION. */
union
{
struct
{
nrf_radio_request_t * p_next; /**< The request parameters for the next radio timeslot. */
} request; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END. */
struct
{
uint32_t length_us; /**< Requested extension of the radio timeslot duration (microseconds) (for minimum time see @ref NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US). */
} extend; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND. */
} params;
} nrf_radio_signal_callback_return_param_t;
/**@brief The radio timeslot signal callback type.
*
* @note In case of invalid return parameters, the radio timeslot will automatically end
* immediately after returning from the signal callback and the
* @ref NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN event will be sent.
* @note The returned struct pointer must remain valid after the signal callback
* function returns. For instance, this means that it must not point to a stack variable.
*
* @param[in] signal_type Type of signal, see @ref NRF_RADIO_CALLBACK_SIGNAL_TYPE.
*
* @return Pointer to structure containing action requested by the application.
*/
typedef nrf_radio_signal_callback_return_param_t * (*nrf_radio_signal_callback_t) (uint8_t signal_type);
/**@brief AES ECB parameter typedefs */
typedef uint8_t soc_ecb_key_t[SOC_ECB_KEY_LENGTH];
typedef uint8_t soc_ecb_cleartext_t[SOC_ECB_CLEARTEXT_LENGTH];
typedef uint8_t soc_ecb_ciphertext_t[SOC_ECB_CIPHERTEXT_LENGTH];
/**@brief AES ECB data structure */
typedef struct
{
soc_ecb_key_t key; /**< Encryption key. */
soc_ecb_cleartext_t cleartext; /**< Cleartext data. */
soc_ecb_ciphertext_t ciphertext; /**< Ciphertext data. */
} nrf_ecb_hal_data_t;
/**@brief AES ECB block. Used to provide multiple blocks in a single call
to @ref sd_ecb_blocks_encrypt.*/
typedef struct
{
soc_ecb_key_t* p_key; /**< Pointer to the Encryption key. */
soc_ecb_cleartext_t* p_cleartext; /**< Pointer to the Cleartext data. */
soc_ecb_ciphertext_t* p_ciphertext; /**< Pointer to the Ciphertext data. */
} nrf_ecb_hal_data_block_t;
/**@} */
/**@addtogroup NRF_SOC_FUNCTIONS Functions
* @{ */
/**@brief Initialize a mutex.
*
* @param[in] p_mutex Pointer to the mutex to initialize.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_MUTEX_NEW, uint32_t, sd_mutex_new(nrf_mutex_t * p_mutex));
/**@brief Attempt to acquire a mutex.
*
* @param[in] p_mutex Pointer to the mutex to acquire.
*
* @retval ::NRF_SUCCESS The mutex was successfully acquired.
* @retval ::NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN The mutex could not be acquired.
*/
SVCALL(SD_MUTEX_ACQUIRE, uint32_t, sd_mutex_acquire(nrf_mutex_t * p_mutex));
/**@brief Release a mutex.
*
* @param[in] p_mutex Pointer to the mutex to release.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_MUTEX_RELEASE, uint32_t, sd_mutex_release(nrf_mutex_t * p_mutex));
/**@brief Query the capacity of the application random pool.
*
* @param[out] p_pool_capacity The capacity of the pool.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_RAND_APPLICATION_POOL_CAPACITY_GET, uint32_t, sd_rand_application_pool_capacity_get(uint8_t * p_pool_capacity));
/**@brief Get number of random bytes available to the application.
*
* @param[out] p_bytes_available The number of bytes currently available in the pool.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_RAND_APPLICATION_BYTES_AVAILABLE_GET, uint32_t, sd_rand_application_bytes_available_get(uint8_t * p_bytes_available));
/**@brief Get random bytes from the application pool.
*
* @param[out] p_buff Pointer to unit8_t buffer for storing the bytes.
* @param[in] length Number of bytes to take from pool and place in p_buff.
*
* @retval ::NRF_SUCCESS The requested bytes were written to p_buff.
* @retval ::NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES No bytes were written to the buffer, because there were not enough bytes available.
*/
SVCALL(SD_RAND_APPLICATION_VECTOR_GET, uint32_t, sd_rand_application_vector_get(uint8_t * p_buff, uint8_t length));
/**@brief Gets the reset reason register.
*
* @param[out] p_reset_reason Contents of the NRF_POWER->RESETREAS register.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_POWER_RESET_REASON_GET, uint32_t, sd_power_reset_reason_get(uint32_t * p_reset_reason));
/**@brief Clears the bits of the reset reason register.
*
* @param[in] reset_reason_clr_msk Contains the bits to clear from the reset reason register.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_POWER_RESET_REASON_CLR, uint32_t, sd_power_reset_reason_clr(uint32_t reset_reason_clr_msk));
/**@brief Sets the power mode when in CPU sleep.
*
* @param[in] power_mode The power mode to use when in CPU sleep, see @ref NRF_POWER_MODES. @sa sd_app_evt_wait
*
* @retval ::NRF_SUCCESS The power mode was set.
* @retval ::NRF_ERROR_SOC_POWER_MODE_UNKNOWN The power mode was unknown.
*/
SVCALL(SD_POWER_MODE_SET, uint32_t, sd_power_mode_set(uint8_t power_mode));
/**@brief Puts the chip in System OFF mode.
*
* @retval ::NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN
*/
SVCALL(SD_POWER_SYSTEM_OFF, uint32_t, sd_power_system_off(void));
/**@brief Enables or disables the power-fail comparator.
*
* Enabling this will give a softdevice event (NRF_EVT_POWER_FAILURE_WARNING) when the power failure warning occurs.
* The event can be retrieved with sd_evt_get();
*
* @param[in] pof_enable True if the power-fail comparator should be enabled, false if it should be disabled.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_POWER_POF_ENABLE, uint32_t, sd_power_pof_enable(uint8_t pof_enable));
/**@brief Sets the power-fail threshold value.
*
* @param[in] threshold The power-fail threshold value to use, see @ref NRF_POWER_THRESHOLDS.
*
* @retval ::NRF_SUCCESS The power failure threshold was set.
* @retval ::NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN The power failure threshold is unknown.
*/
SVCALL(SD_POWER_POF_THRESHOLD_SET, uint32_t, sd_power_pof_threshold_set(uint8_t threshold));
/**@brief Sets bits in the NRF_POWER->RAMON register.
*
* @param[in] ramon Contains the bits needed to be set in the NRF_POWER->RAMON register.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_POWER_RAMON_SET, uint32_t, sd_power_ramon_set(uint32_t ramon));
/**@brief Clears bits in the NRF_POWER->RAMON register.
*
* @param ramon Contains the bits needed to be cleared in the NRF_POWER->RAMON register.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_POWER_RAMON_CLR, uint32_t, sd_power_ramon_clr(uint32_t ramon));
/**@brief Get contents of NRF_POWER->RAMON register, indicates power status of ram blocks.
*
* @param[out] p_ramon Content of NRF_POWER->RAMON register.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_POWER_RAMON_GET, uint32_t, sd_power_ramon_get(uint32_t * p_ramon));
/**@brief Set bits in the NRF_POWER->GPREGRET register.
*
* @param[in] gpregret_msk Bits to be set in the GPREGRET register.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_POWER_GPREGRET_SET, uint32_t, sd_power_gpregret_set(uint32_t gpregret_msk));
/**@brief Clear bits in the NRF_POWER->GPREGRET register.
*
* @param[in] gpregret_msk Bits to be clear in the GPREGRET register.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_POWER_GPREGRET_CLR, uint32_t, sd_power_gpregret_clr(uint32_t gpregret_msk));
/**@brief Get contents of the NRF_POWER->GPREGRET register.
*
* @param[out] p_gpregret Contents of the GPREGRET register.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_POWER_GPREGRET_GET, uint32_t, sd_power_gpregret_get(uint32_t *p_gpregret));
/**@brief Sets the DCDC mode.
*
* Enable or disable the DCDC peripheral.
*
* @param[in] dcdc_mode The mode of the DCDC, see @ref NRF_POWER_DCDC_MODES.
*
* @retval ::NRF_SUCCESS
* @retval ::NRF_ERROR_INVALID_PARAM The DCDC mode is invalid.
*/
SVCALL(SD_POWER_DCDC_MODE_SET, uint32_t, sd_power_dcdc_mode_set(uint8_t dcdc_mode));
/**@brief Request the high frequency crystal oscillator.
*
* Will start the high frequency crystal oscillator, the startup time of the crystal varies
* and the ::sd_clock_hfclk_is_running function can be polled to check if it has started.
*
* @see sd_clock_hfclk_is_running
* @see sd_clock_hfclk_release
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_CLOCK_HFCLK_REQUEST, uint32_t, sd_clock_hfclk_request(void));
/**@brief Releases the high frequency crystal oscillator.
*
* Will stop the high frequency crystal oscillator, this happens immediately.
*
* @see sd_clock_hfclk_is_running
* @see sd_clock_hfclk_request
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_CLOCK_HFCLK_RELEASE, uint32_t, sd_clock_hfclk_release(void));
/**@brief Checks if the high frequency crystal oscillator is running.
*
* @see sd_clock_hfclk_request
* @see sd_clock_hfclk_release
*
* @param[out] p_is_running 1 if the external crystal oscillator is running, 0 if not.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_CLOCK_HFCLK_IS_RUNNING, uint32_t, sd_clock_hfclk_is_running(uint32_t * p_is_running));
/**@brief Waits for an application event.
*
* An application event is either an application interrupt or a pended interrupt when the
* interrupt is disabled. When the interrupt is enabled it will be taken immediately since
* this function will wait in thread mode, then the execution will return in the application's
* main thread. When an interrupt is disabled and gets pended it will return to the application's
* thread main. The application must ensure that the pended flag is cleared using
* ::sd_nvic_ClearPendingIRQ in order to sleep using this function. This is only necessary for
* disabled interrupts, as the interrupt handler will clear the pending flag automatically for
* enabled interrupts.
*
* In order to wake up from disabled interrupts, the SEVONPEND flag has to be set in the Cortex-M0
* System Control Register (SCR). @sa CMSIS_SCB
*
* @note If an application interrupt has happened since the last time sd_app_evt_wait was
* called this function will return immediately and not go to sleep. This is to avoid race
* conditions that can occur when a flag is updated in the interrupt handler and processed
* in the main loop.
*
* @post An application interrupt has happened or a interrupt pending flag is set.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_APP_EVT_WAIT, uint32_t, sd_app_evt_wait(void));
/**@brief Get PPI channel enable register contents.
*
* @param[out] p_channel_enable The contents of the PPI CHEN register.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_PPI_CHANNEL_ENABLE_GET, uint32_t, sd_ppi_channel_enable_get(uint32_t * p_channel_enable));
/**@brief Set PPI channel enable register.
*
* @param[in] channel_enable_set_msk Mask containing the bits to set in the PPI CHEN register.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_PPI_CHANNEL_ENABLE_SET, uint32_t, sd_ppi_channel_enable_set(uint32_t channel_enable_set_msk));
/**@brief Clear PPI channel enable register.
*
* @param[in] channel_enable_clr_msk Mask containing the bits to clear in the PPI CHEN register.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_PPI_CHANNEL_ENABLE_CLR, uint32_t, sd_ppi_channel_enable_clr(uint32_t channel_enable_clr_msk));
/**@brief Assign endpoints to a PPI channel.
*
* @param[in] channel_num Number of the PPI channel to assign.
* @param[in] evt_endpoint Event endpoint of the PPI channel.
* @param[in] task_endpoint Task endpoint of the PPI channel.
*
* @retval ::NRF_ERROR_SOC_PPI_INVALID_CHANNEL The channel number is invalid.
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_PPI_CHANNEL_ASSIGN, uint32_t, sd_ppi_channel_assign(uint8_t channel_num, const volatile void * evt_endpoint, const volatile void * task_endpoint));
/**@brief Task to enable a channel group.
*
* @param[in] group_num Number of the channel group.
*
* @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_PPI_GROUP_TASK_ENABLE, uint32_t, sd_ppi_group_task_enable(uint8_t group_num));
/**@brief Task to disable a channel group.
*
* @param[in] group_num Number of the PPI group.
*
* @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid.
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_PPI_GROUP_TASK_DISABLE, uint32_t, sd_ppi_group_task_disable(uint8_t group_num));
/**@brief Assign PPI channels to a channel group.
*
* @param[in] group_num Number of the channel group.
* @param[in] channel_msk Mask of the channels to assign to the group.
*
* @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid.
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_PPI_GROUP_ASSIGN, uint32_t, sd_ppi_group_assign(uint8_t group_num, uint32_t channel_msk));
/**@brief Gets the PPI channels of a channel group.
*
* @param[in] group_num Number of the channel group.
* @param[out] p_channel_msk Mask of the channels assigned to the group.
*
* @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid.
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_PPI_GROUP_GET, uint32_t, sd_ppi_group_get(uint8_t group_num, uint32_t * p_channel_msk));
/**@brief Configures the Radio Notification signal.
*
* @note
* - The notification signal latency depends on the interrupt priority settings of SWI used
* for notification signal.
* - To ensure that the radio notification signal behaves in a consistent way, always
* configure radio notifications when there is no protocol stack or other SoftDevice
* activity in progress. It is recommended that the radio notification signal is
* configured directly after the SoftDevice has been enabled.
* - In the period between the ACTIVE signal and the start of the Radio Event, the SoftDevice
* will interrupt the application to do Radio Event preparation.
* - Using the Radio Notification feature may limit the bandwidth, as the SoftDevice may have
* to shorten the connection events to have time for the Radio Notification signals.
*
* @param[in] type Type of notification signal, see @ref NRF_RADIO_NOTIFICATION_TYPES.
* @ref NRF_RADIO_NOTIFICATION_TYPE_NONE shall be used to turn off radio
* notification. Using @ref NRF_RADIO_NOTIFICATION_DISTANCE_NONE is
* recommended (but not required) to be used with
* @ref NRF_RADIO_NOTIFICATION_TYPE_NONE.
*
* @param[in] distance Distance between the notification signal and start of radio activity, see @ref NRF_RADIO_NOTIFICATION_DISTANCES.
* This parameter is ignored when @ref NRF_RADIO_NOTIFICATION_TYPE_NONE or
* @ref NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE is used.
*
* @retval ::NRF_ERROR_INVALID_PARAM The group number is invalid.
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_RADIO_NOTIFICATION_CFG_SET, uint32_t, sd_radio_notification_cfg_set(uint8_t type, uint8_t distance));
/**@brief Encrypts a block according to the specified parameters.
*
* 128-bit AES encryption.
*
* @note:
* - The application may set the SEVONPEND bit in the SCR to 1 to make the SoftDevice sleep while
* the ECB is running. The SEVONPEND bit should only be cleared (set to 0) from application
* main or low interrupt level.
*
* @param[in, out] p_ecb_data Pointer to the ECB parameters' struct (two input
* parameters and one output parameter).
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_ECB_BLOCK_ENCRYPT, uint32_t, sd_ecb_block_encrypt(nrf_ecb_hal_data_t * p_ecb_data));
/**@brief Encrypts multiple data blocks provided as an array of data block structures.
*
* @details: Performs 128-bit AES encryption on multiple data blocks
*
* @note:
* - The application may set the SEVONPEND bit in the SCR to 1 to make the SoftDevice sleep while
* the ECB is running. The SEVONPEND bit should only be cleared (set to 0) from application
* main or low interrupt level.
*
* @param[in] block_count Count of blocks in the p_data_blocks array.
* @param[in,out] p_data_blocks Pointer to the first entry in a contiguous array of
* @ref nrf_ecb_hal_data_block_t structures.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_ECB_BLOCKS_ENCRYPT, uint32_t, sd_ecb_blocks_encrypt(uint8_t block_count, nrf_ecb_hal_data_block_t * p_data_blocks));
/**@brief Gets any pending events generated by the SoC API.
*
* The application should keep calling this function to get events, until ::NRF_ERROR_NOT_FOUND is returned.
*
* @param[out] p_evt_id Set to one of the values in @ref NRF_SOC_EVTS, if any events are pending.
*
* @retval ::NRF_SUCCESS An event was pending. The event id is written in the p_evt_id parameter.
* @retval ::NRF_ERROR_NOT_FOUND No pending events.
*/
SVCALL(SD_EVT_GET, uint32_t, sd_evt_get(uint32_t * p_evt_id));
/**@brief Get the temperature measured on the chip
*
* This function will block until the temperature measurement is done.
* It takes around 50us from call to return.
*
* @param[out] p_temp Result of temperature measurement. Die temperature in 0.25 degrees celsius.
*
* @retval ::NRF_SUCCESS A temperature measurement was done, and the temperature was written to temp
*/
SVCALL(SD_TEMP_GET, uint32_t, sd_temp_get(int32_t * p_temp));
/**@brief Flash Write
*
* Commands to write a buffer to flash
*
* If the SoftDevice is enabled:
* This call initiates the flash access command, and its completion will be communicated to the
* application with exactly one of the following events:
* - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed.
* - @ref NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started.
*
* If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the
* write has been completed
*
* @note
* - This call takes control over the radio and the CPU during flash erase and write to make sure that
* they will not interfere with the flash access. This means that all interrupts will be blocked
* for a predictable time (depending on the NVMC specification in nRF51 Series Reference Manual
* and the command parameters).
*
*
* @param[in] p_dst Pointer to start of flash location to be written.
* @param[in] p_src Pointer to buffer with data to be written.
* @param[in] size Number of 32-bit words to write. Maximum size is 256 32-bit words for nRF51 and 1024 for nRF52.
*
* @retval ::NRF_ERROR_INVALID_ADDR Tried to write to a non existing flash address, or p_dst or p_src was unaligned.
* @retval ::NRF_ERROR_BUSY The previous command has not yet completed.
* @retval ::NRF_ERROR_INVALID_LENGTH Size was 0, or higher than the maximum allowed size.
* @retval ::NRF_ERROR_FORBIDDEN Tried to write to or read from protected location.
* @retval ::NRF_SUCCESS The command was accepted.
*/
SVCALL(SD_FLASH_WRITE, uint32_t, sd_flash_write(uint32_t * const p_dst, uint32_t const * const p_src, uint32_t size));
/**@brief Flash Erase page
*
* Commands to erase a flash page
* If the SoftDevice is enabled:
* This call initiates the flash access command, and its completion will be communicated to the
* application with exactly one of the following events:
* - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed.
* - @ref NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started.
*
* If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the
* erase has been completed
*
* @note
* - This call takes control over the radio and the CPU during flash erase and write to make sure that
* they will not interfere with the flash access. This means that all interrupts will be blocked
* for a predictable time (depending on the NVMC specification in nRF51 Series Reference Manual
* and the command parameters).
*
*
* @param[in] page_number Pagenumber of the page to erase
* @retval ::NRF_ERROR_INTERNAL If a new session could not be opened due to an internal error.
* @retval ::NRF_ERROR_INVALID_ADDR Tried to erase to a non existing flash page.
* @retval ::NRF_ERROR_BUSY The previous command has not yet completed.
* @retval ::NRF_ERROR_FORBIDDEN Tried to erase a protected page.
* @retval ::NRF_SUCCESS The command was accepted.
*/
SVCALL(SD_FLASH_PAGE_ERASE, uint32_t, sd_flash_page_erase(uint32_t page_number));
/**@brief Flash Protection set
*
* Commands to set the flash protection configuration registers.
On nRF51 this sets the PROTENSETx registers of the MPU peripheral.
On nRF52 this sets the CONFIGx registers of the BPROT peripheral.
*
* @note To read the values read them directly. They are only write-protected.
*
* @param[in] block_cfg0 Value to be written to the configuration register.
* @param[in] block_cfg1 Value to be written to the configuration register.
* @param[in] block_cfg2 Value to be written to the configuration register (ignored on nRF51).
* @param[in] block_cfg3 Value to be written to the configuration register (ignored on nRF51).
*
* @retval ::NRF_ERROR_FORBIDDEN Tried to protect the SoftDevice.
* @retval ::NRF_SUCCESS Values successfully written to configuration registers.
*/
SVCALL(SD_FLASH_PROTECT, uint32_t, sd_flash_protect(uint32_t block_cfg0, uint32_t block_cfg1, uint32_t block_cfg2, uint32_t block_cfg3));
/**@brief Opens a session for radio timeslot requests.
*
* @note Only one session can be open at a time.
* @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) will be called when the radio timeslot
* starts. From this point the NRF_RADIO and NRF_TIMER0 peripherals can be freely accessed
* by the application.
* @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0) is called whenever the NRF_TIMER0
* interrupt occurs.
* @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO) is called whenever the NRF_RADIO
* interrupt occurs.
* @note p_radio_signal_callback() will be called at ARM interrupt priority level 0. This
* implies that none of the sd_* API calls can be used from p_radio_signal_callback().
*
* @param[in] p_radio_signal_callback The signal callback.
*
* @retval ::NRF_ERROR_INVALID_ADDR p_radio_signal_callback is an invalid function pointer.
* @retval ::NRF_ERROR_BUSY If session cannot be opened.
* @retval ::NRF_ERROR_INTERNAL If a new session could not be opened due to an internal error.
* @retval ::NRF_SUCCESS Otherwise.
*/
SVCALL(SD_RADIO_SESSION_OPEN, uint32_t, sd_radio_session_open(nrf_radio_signal_callback_t p_radio_signal_callback));
/**@brief Closes a session for radio timeslot requests.
*
* @note Any current radio timeslot will be finished before the session is closed.
* @note If a radio timeslot is scheduled when the session is closed, it will be canceled.
* @note The application cannot consider the session closed until the @ref NRF_EVT_RADIO_SESSION_CLOSED
* event is received.
*
* @retval ::NRF_ERROR_FORBIDDEN If session not opened.
* @retval ::NRF_ERROR_BUSY If session is currently being closed.
* @retval ::NRF_SUCCESS Otherwise.
*/
SVCALL(SD_RADIO_SESSION_CLOSE, uint32_t, sd_radio_session_close(void));
/**@brief Requests a radio timeslot.
*
* @note The request type is determined by p_request->request_type, and can be one of @ref NRF_RADIO_REQ_TYPE_EARLIEST
* and @ref NRF_RADIO_REQ_TYPE_NORMAL. The first request in a session must always be of type @ref NRF_RADIO_REQ_TYPE_EARLIEST.
* @note For a normal request (@ref NRF_RADIO_REQ_TYPE_NORMAL), the start time of a radio timeslot is specified by
* p_request->distance_us and is given relative to the start of the previous timeslot.
* @note A too small p_request->distance_us will lead to a @ref NRF_EVT_RADIO_BLOCKED event.
* @note Timeslots scheduled too close will lead to a @ref NRF_EVT_RADIO_BLOCKED event.
* @note See the SoftDevice Specification for more on radio timeslot scheduling, distances and lengths.
* @note If an opportunity for the first radio timeslot is not found before 100ms after the call to this
* function, it is not scheduled, and instead a @ref NRF_EVT_RADIO_BLOCKED event is sent.
* The application may then try to schedule the first radio timeslot again.
* @note Successful requests will result in nrf_radio_signal_callback_t(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START).
* Unsuccessful requests will result in a @ref NRF_EVT_RADIO_BLOCKED event, see @ref NRF_SOC_EVTS.
* @note The jitter in the start time of the radio timeslots is +/- @ref NRF_RADIO_START_JITTER_US us.
* @note The nrf_radio_signal_callback_t(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) call has a latency relative to the
* specified radio timeslot start, but this does not affect the actual start time of the timeslot.
* @note NRF_TIMER0 is reset at the start of the radio timeslot, and is clocked at 1MHz from the high frequency
* (16 MHz) clock source. If p_request->hfclk_force_xtal is true, the high frequency clock is
* guaranteed to be clocked from the external crystal.
* @note The SoftDevice will neither access the NRF_RADIO peripheral nor the NRF_TIMER0 peripheral
* during the radio timeslot.
*
* @param[in] p_request Pointer to the request parameters.
*
* @retval ::NRF_ERROR_FORBIDDEN If session not opened or the session is not IDLE.
* @retval ::NRF_ERROR_INVALID_ADDR If the p_request pointer is invalid.
* @retval ::NRF_ERROR_INVALID_PARAM If the parameters of p_request are not valid.
* @retval ::NRF_SUCCESS Otherwise.
*/
SVCALL(SD_RADIO_REQUEST, uint32_t, sd_radio_request(nrf_radio_request_t * p_request ));
/**@} */
#ifdef __cplusplus
}
#endif
#endif // NRF_SOC_H__
/**@} */

View File

@ -0,0 +1,88 @@
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software must only be used in a processor manufactured by Nordic
* Semiconductor ASA, or in a processor manufactured by a third party that
* is used in combination with a processor manufactured by Nordic Semiconductor.
*
*
* 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.
*
*/
#ifndef NRF_SVC__
#define NRF_SVC__
#include "stdint.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef SVCALL_AS_NORMAL_FUNCTION
#define SVCALL(number, return_type, signature) return_type signature
#else
#ifndef SVCALL
#if defined (__CC_ARM)
#define SVCALL(number, return_type, signature) return_type __svc(number) signature
#elif defined (__GNUC__)
#ifdef __cplusplus
#define GCC_CAST_CPP (uint8_t)
#else
#define GCC_CAST_CPP
#endif
#define SVCALL(number, return_type, signature) \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \
__attribute__((naked)) \
__attribute__((unused)) \
static return_type signature \
{ \
__asm( \
"svc %0\n" \
"bx r14" : : "I" (GCC_CAST_CPP number) : "r0" \
); \
} \
_Pragma("GCC diagnostic pop")
#elif defined (__ICCARM__)
#define PRAGMA(x) _Pragma(#x)
#define SVCALL(number, return_type, signature) \
PRAGMA(swi_number = (number)) \
__swi return_type signature;
#else
#define SVCALL(number, return_type, signature) return_type signature
#endif
#endif // SVCALL
#endif // SVCALL_AS_NORMAL_FUNCTION
#ifdef __cplusplus
}
#endif
#endif // NRF_SVC__

View File

@ -0,0 +1,566 @@
/* 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.
*/
#include "ble_advdata.h"
#include "ble_advertising.h"
#include "nrf_soc.h"
#include "nrf_log.h"
#include "pstorage.h"
#include "fstorage.h"
#include "sdk_common.h"
#define ADV_LOG(...)
static bool m_advertising_start_pending = false; /**< Flag to keep track of ongoing operations on persistent memory. */
static ble_gap_addr_t m_peer_address; /**< Address of the most recently connected peer, used for direct advertising. */
static ble_advdata_t m_advdata; /**< Used by the initialization function to set name, appearance, and UUIDs and advertising flags visible to peer devices. */
static ble_adv_evt_t m_adv_evt; /**< Advertising event propogated to the main application. The event is either a transaction to a new advertising mode, or a request for whitelist or peer address.. */
static ble_advertising_evt_handler_t m_evt_handler; /**< Handler for the advertising events. Can be initialized as NULL if no handling is implemented on in the main application. */
static ble_advertising_error_handler_t m_error_handler; /**< Handler for the advertising error events. */
static ble_adv_mode_t m_adv_mode_current; /**< Variable to keep track of the current advertising mode. */
static ble_adv_modes_config_t m_adv_modes_config; /**< Struct to keep track of disabled and enabled advertising modes, as well as time-outs and intervals.*/
static ble_gap_whitelist_t m_whitelist; /**< Struct that points to whitelisted addresses. */
static ble_gap_addr_t * mp_whitelist_addr[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; /**< Pointer to a list of addresses. Pointed to by the whitelist */
static ble_gap_irk_t * mp_whitelist_irk[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; /**< Pointer to a list of Identity Resolving Keys (IRK). Pointed to by the whitelist */
static bool m_whitelist_temporarily_disabled = false; /**< Flag to keep track of temporary disabling of the whitelist. */
static bool m_whitelist_reply_expected = false; /**< Flag to verify that whitelist is only set when it is requested. */
static bool m_peer_addr_reply_expected = false; /**< Flag to verify that peer address is only set when requested. */
static ble_advdata_manuf_data_t m_manuf_specific_data; /**< Manufacturer specific data structure*/
static uint8_t m_manuf_data_array[BLE_GAP_ADV_MAX_SIZE]; /**< Array to store the Manufacturer specific data*/
static ble_advdata_service_data_t m_service_data; /**< Service data structure. */
static uint8_t m_service_data_array[BLE_GAP_ADV_MAX_SIZE]; /**< Array to store the service data. */
static ble_advdata_conn_int_t m_slave_conn_int; /**< Connection interval range structure.*/
static int8_t m_tx_power_level; /**< TX power level*/
/**@brief Function for checking that the whitelist has entries.
*/
static bool whitelist_has_entries(ble_gap_whitelist_t const * whitelist)
{
if ((whitelist->addr_count != 0) || (whitelist->irk_count != 0))
{
return true;
}
return false;
}
/**@brief Function for setting the stored peer address back to zero.
*/
static void ble_advertising_peer_address_clear()
{
memset(&m_peer_address, 0, sizeof(m_peer_address));
}
/**@brief Function for checking if an address is non-zero. Used to determine if
*/
static bool peer_address_exists(uint8_t const * address)
{
uint32_t i;
for (i = 0; i < BLE_GAP_ADDR_LEN; i++)
{
if (address[i] != 0)
{
return true;
}
}
return false;
}
uint32_t ble_advertising_init(ble_advdata_t const * p_advdata,
ble_advdata_t const * p_srdata,
ble_adv_modes_config_t const * p_config,
ble_advertising_evt_handler_t const evt_handler,
ble_advertising_error_handler_t const error_handler)
{
uint32_t err_code;
VERIFY_PARAM_NOT_NULL(p_advdata);
VERIFY_PARAM_NOT_NULL(p_config);
m_adv_mode_current = BLE_ADV_MODE_IDLE;
m_evt_handler = evt_handler;
m_error_handler = error_handler;
m_adv_modes_config = *p_config;
ble_advertising_peer_address_clear();
// Prepare Whitelist. Address and IRK double pointers point to allocated arrays.
m_whitelist.pp_addrs = mp_whitelist_addr;
m_whitelist.pp_irks = mp_whitelist_irk;
// Copy and set advertising data.
memset(&m_advdata, 0, sizeof(m_advdata));
// Copy advertising data.
m_advdata.name_type = p_advdata->name_type;
m_advdata.include_appearance = p_advdata->include_appearance;
m_advdata.flags = p_advdata->flags;
m_advdata.short_name_len = p_advdata->short_name_len;
/*
if(p_advdata->uuids_complete != NULL)
{
m_advdata.uuids_complete = p_advdata->uuids_complete;
}
*/
m_advdata.uuids_complete = p_advdata->uuids_complete;
m_advdata.uuids_more_available = p_advdata->uuids_more_available;
m_advdata.uuids_solicited = p_advdata->uuids_solicited;
if(p_advdata->p_manuf_specific_data != NULL)
{
m_advdata.p_manuf_specific_data = &m_manuf_specific_data;
m_manuf_specific_data.data.p_data = m_manuf_data_array;
m_advdata.p_manuf_specific_data->company_identifier =
p_advdata->p_manuf_specific_data->company_identifier;
m_advdata.p_manuf_specific_data->data.size = p_advdata->p_manuf_specific_data->data.size;
for(uint32_t i = 0; i < m_advdata.p_manuf_specific_data->data.size; i++)
{
m_manuf_data_array[i] = p_advdata->p_manuf_specific_data->data.p_data[i];
}
}
if(p_advdata->p_service_data_array != NULL)
{
m_service_data.data.p_data = m_service_data_array;
m_advdata.p_service_data_array = &m_service_data;
m_advdata.p_service_data_array->data.p_data = m_service_data_array;
m_advdata.p_service_data_array->data.size = p_advdata->p_service_data_array->data.size;
m_advdata.p_service_data_array->service_uuid = p_advdata->p_service_data_array->service_uuid;
for(uint32_t i = 0; i < m_advdata.p_service_data_array->data.size; i++)
{
m_service_data_array[i] = p_advdata->p_service_data_array->data.p_data[i];
}
m_advdata.service_data_count = p_advdata->service_data_count;
}
if(p_advdata->p_slave_conn_int != NULL)
{
m_advdata.p_slave_conn_int = &m_slave_conn_int;
m_advdata.p_slave_conn_int->max_conn_interval = p_advdata->p_slave_conn_int->max_conn_interval;
m_advdata.p_slave_conn_int->min_conn_interval = p_advdata->p_slave_conn_int->min_conn_interval;
}
if(p_advdata->p_tx_power_level != NULL)
{
m_advdata.p_tx_power_level = &m_tx_power_level;
m_advdata.p_tx_power_level = p_advdata->p_tx_power_level;
}
err_code = ble_advdata_set(&m_advdata, p_srdata);
return err_code;
}
/** @brief Function to determine if a flash access in in progress. If it is the case, we can not
* start advertising until it is finished. attempted restart
* in @ref ble_advertising_on_sys_evt
*
* @return true if a flash access is in progress, false if not.
*/
static bool flash_access_in_progress()
{
uint32_t err_code;
uint32_t count = 0;
err_code = pstorage_access_status_get(&count);
if ((err_code != NRF_ERROR_INVALID_STATE) && (err_code != NRF_SUCCESS))
{
ADV_LOG("[ADV]: pstorage_access_status_get returned %d.\r\n", err_code);
return true;
}
if (err_code == NRF_ERROR_INVALID_STATE)
{
err_code = fs_queued_op_count_get(&count);
if (err_code != FS_SUCCESS)
{
return false;
}
ADV_LOG("[ADV]: fs_queued_op_count_get gives count %d.\r\n", count);
}
if(count != 0)
{
return true;
}
else
{
return false;
}
}
uint32_t ble_advertising_start(ble_adv_mode_t advertising_mode)
{
uint32_t err_code;
ble_gap_adv_params_t adv_params;
m_adv_mode_current = advertising_mode;
// Verify if there are any pending flash operations. If so, delay starting advertising until
// the flash operations are complete.
if(flash_access_in_progress())
{
m_advertising_start_pending = true;
return NRF_SUCCESS;
}
ADV_LOG("[ADV]: no flash operations in progress, prepare advertising.\r\n");
// Fetch the peer address.
ble_advertising_peer_address_clear();
if ( ((m_adv_modes_config.ble_adv_directed_enabled) && (m_adv_mode_current == BLE_ADV_MODE_DIRECTED))
||((m_adv_modes_config.ble_adv_directed_slow_enabled) && (m_adv_mode_current == BLE_ADV_MODE_DIRECTED))
||((m_adv_modes_config.ble_adv_directed_slow_enabled) && (m_adv_mode_current == BLE_ADV_MODE_DIRECTED_SLOW))
)
{
if (m_evt_handler != NULL)
{
m_peer_addr_reply_expected = true;
m_evt_handler(BLE_ADV_EVT_PEER_ADDR_REQUEST);
}
else
{
m_peer_addr_reply_expected = false;
}
}
// If a mode is disabled, continue to the next mode. I.e fast instead of direct, slow instead of fast, idle instead of slow.
if ( (m_adv_mode_current == BLE_ADV_MODE_DIRECTED)
&&(!m_adv_modes_config.ble_adv_directed_enabled || !peer_address_exists(m_peer_address.addr)))
{
m_adv_mode_current = BLE_ADV_MODE_DIRECTED_SLOW;
}
if ( (m_adv_mode_current == BLE_ADV_MODE_DIRECTED_SLOW)
&&(!m_adv_modes_config.ble_adv_directed_slow_enabled || !peer_address_exists(m_peer_address.addr)))
{
m_adv_mode_current = BLE_ADV_MODE_FAST;
}
if (!m_adv_modes_config.ble_adv_fast_enabled && m_adv_mode_current == BLE_ADV_MODE_FAST)
{
m_adv_mode_current = BLE_ADV_MODE_SLOW;
}
if (!m_adv_modes_config.ble_adv_slow_enabled && m_adv_mode_current == BLE_ADV_MODE_SLOW)
{
m_adv_mode_current = BLE_ADV_MODE_IDLE;
m_adv_evt = BLE_ADV_EVT_IDLE;
}
// Fetch the whitelist.
if ( (m_evt_handler != NULL)
&& (m_adv_mode_current == BLE_ADV_MODE_FAST || m_adv_mode_current == BLE_ADV_MODE_SLOW)
&& (m_adv_modes_config.ble_adv_whitelist_enabled)
&& (!m_whitelist_temporarily_disabled))
{
m_whitelist_reply_expected = true;
m_evt_handler(BLE_ADV_EVT_WHITELIST_REQUEST);
}
else
{
m_whitelist_reply_expected = false;
}
// Initialize advertising parameters with default values.
memset(&adv_params, 0, sizeof(adv_params));
adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND;
adv_params.p_peer_addr = NULL;
adv_params.fp = BLE_GAP_ADV_FP_ANY;
adv_params.p_whitelist = NULL;
// Set advertising parameters and events according to selected advertising mode.
switch (m_adv_mode_current)
{
case BLE_ADV_MODE_DIRECTED:
ADV_LOG("[ADV]: Starting direct advertisement.\r\n");
adv_params.p_peer_addr = &m_peer_address; // Directed advertising.
adv_params.type = BLE_GAP_ADV_TYPE_ADV_DIRECT_IND;
adv_params.timeout = 0;
adv_params.interval = 0;
m_adv_evt = BLE_ADV_EVT_DIRECTED;
break;
case BLE_ADV_MODE_DIRECTED_SLOW:
ADV_LOG("[ADV]: Starting direct advertisement.\r\n");
adv_params.p_peer_addr = &m_peer_address; // Directed advertising.
adv_params.type = BLE_GAP_ADV_TYPE_ADV_DIRECT_IND;
adv_params.timeout = m_adv_modes_config.ble_adv_directed_slow_timeout;
adv_params.interval = m_adv_modes_config.ble_adv_directed_slow_interval;
m_adv_evt = BLE_ADV_EVT_DIRECTED_SLOW;
break;
case BLE_ADV_MODE_FAST:
adv_params.timeout = m_adv_modes_config.ble_adv_fast_timeout;
adv_params.interval = m_adv_modes_config.ble_adv_fast_interval;
if ( whitelist_has_entries(&m_whitelist)
&& m_adv_modes_config.ble_adv_whitelist_enabled
&& !m_whitelist_temporarily_disabled)
{
adv_params.fp = BLE_GAP_ADV_FP_FILTER_CONNREQ;
adv_params.p_whitelist = &m_whitelist;
m_advdata.flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
err_code = ble_advdata_set(&m_advdata, NULL);
VERIFY_SUCCESS(err_code);
m_adv_evt = BLE_ADV_EVT_FAST_WHITELIST;
ADV_LOG("[ADV]: Starting fast advertisement with whitelist.\r\n");
}
else
{
m_adv_evt = BLE_ADV_EVT_FAST;
ADV_LOG("[ADV]: Starting fast advertisement.\r\n");
}
break;
case BLE_ADV_MODE_SLOW:
adv_params.interval = m_adv_modes_config.ble_adv_slow_interval;
adv_params.timeout = m_adv_modes_config.ble_adv_slow_timeout;
if ( whitelist_has_entries(&m_whitelist)
&& m_adv_modes_config.ble_adv_whitelist_enabled
&& !m_whitelist_temporarily_disabled)
{
adv_params.fp = BLE_GAP_ADV_FP_FILTER_CONNREQ;
adv_params.p_whitelist = &m_whitelist;
m_advdata.flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
err_code = ble_advdata_set(&m_advdata, NULL);
VERIFY_SUCCESS(err_code);
m_adv_evt = BLE_ADV_EVT_SLOW_WHITELIST;
ADV_LOG("[ADV]: Starting slow advertisement with whitelist.\r\n");
}
else
{
m_adv_evt = BLE_ADV_EVT_SLOW;
ADV_LOG("[ADV]: Starting slow advertisement.\r\n");
}
break;
default:
break;
}
if (m_adv_mode_current != BLE_ADV_MODE_IDLE)
{
err_code = sd_ble_gap_adv_start(&adv_params);
VERIFY_SUCCESS(err_code);
}
if (m_evt_handler != NULL)
{
m_evt_handler(m_adv_evt);
}
return NRF_SUCCESS;
}
void ble_advertising_on_ble_evt(ble_evt_t const * p_ble_evt)
{
static uint16_t current_slave_link_conn_handle = BLE_CONN_HANDLE_INVALID;
switch (p_ble_evt->header.evt_id)
{
case BLE_GAP_EVT_CONNECTED:
if (p_ble_evt->evt.gap_evt.params.connected.role == BLE_GAP_ROLE_PERIPH)
{
current_slave_link_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
}
break;
// Upon disconnection, whitelist will be activated and direct advertising is started.
case BLE_GAP_EVT_DISCONNECTED:
{
uint32_t err_code;
m_whitelist_temporarily_disabled = false;
if (p_ble_evt->evt.gap_evt.conn_handle == current_slave_link_conn_handle)
{
err_code = ble_advertising_start(BLE_ADV_MODE_DIRECTED);
if ((err_code != NRF_SUCCESS) && (m_error_handler != NULL))
{
m_error_handler(err_code);
}
}
break;
}
// Upon time-out, the next advertising mode is started, i.e. go from fast to slow or from slow to idle.
case BLE_GAP_EVT_TIMEOUT:
if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISING)
{
switch (m_adv_mode_current)
{
case BLE_ADV_MODE_DIRECTED:
ADV_LOG("[ADV]: Timed out from directed advertising.\r\n");
{
uint32_t err_code;
err_code = ble_advertising_start(BLE_ADV_MODE_DIRECTED_SLOW);
if ((err_code != NRF_SUCCESS) && (m_error_handler != NULL))
{
m_error_handler(err_code);
}
}
break;
case BLE_ADV_MODE_DIRECTED_SLOW:
ADV_LOG("[ADV]: Timed out from directed slow advertising.\r\n");
{
uint32_t err_code;
err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
if ((err_code != NRF_SUCCESS) && (m_error_handler != NULL))
{
m_error_handler(err_code);
}
}
break;
case BLE_ADV_MODE_FAST:
{
uint32_t err_code;
m_adv_evt = BLE_ADV_EVT_FAST;
ADV_LOG("[ADV]: Timed out from fast advertising, starting slow advertising.\r\n");
err_code = ble_advertising_start(BLE_ADV_MODE_SLOW);
if ((err_code != NRF_SUCCESS) && (m_error_handler != NULL))
{
m_error_handler(err_code);
}
break;
}
case BLE_ADV_MODE_SLOW:
m_adv_evt = BLE_ADV_EVT_IDLE;
ADV_LOG("[ADV]: Timed out from slow advertising, stopping advertising.\r\n");
if (m_evt_handler != NULL)
{
m_evt_handler(m_adv_evt);
}
break;
default:
// No implementation needed.
break;
}
}
break;
default:
// No implementation needed.
break;
}
}
void ble_advertising_on_sys_evt(uint32_t sys_evt)
{
uint32_t err_code = NRF_SUCCESS;
switch (sys_evt)
{
case NRF_EVT_FLASH_OPERATION_SUCCESS:
// Fall through.
//When a flash operation finishes, advertising no longer needs to be pending.
case NRF_EVT_FLASH_OPERATION_ERROR:
if (m_advertising_start_pending)
{
m_advertising_start_pending = false;
err_code = ble_advertising_start(m_adv_mode_current);
if ((err_code != NRF_SUCCESS) && (m_error_handler != NULL))
{
m_error_handler(err_code);
}
}
break;
default:
// No implementation needed.
break;
}
}
uint32_t ble_advertising_peer_addr_reply(ble_gap_addr_t * p_peer_address)
{
if(m_peer_addr_reply_expected == false)
{
return NRF_ERROR_INVALID_STATE;
}
m_peer_address.addr_type = p_peer_address->addr_type;
for (int i = 0; i < BLE_GAP_ADDR_LEN; i++)
{
m_peer_address.addr[i] = p_peer_address->addr[i];
}
m_peer_addr_reply_expected = false;
return NRF_SUCCESS;
}
uint32_t ble_advertising_whitelist_reply(ble_gap_whitelist_t * p_whitelist)
{
uint32_t i;
if(m_whitelist_reply_expected == false)
{
return NRF_ERROR_INVALID_STATE;
}
m_whitelist.addr_count = p_whitelist->addr_count;
m_whitelist.irk_count = p_whitelist->irk_count;
for (i = 0; i < m_whitelist.irk_count; i++)
{
mp_whitelist_irk[i] = p_whitelist->pp_irks[i];
}
for (i = 0; i < m_whitelist.addr_count; i++)
{
mp_whitelist_addr[i] = p_whitelist->pp_addrs[i];
}
m_whitelist_reply_expected = false;
return NRF_SUCCESS;
}
uint32_t ble_advertising_restart_without_whitelist(void)
{
uint32_t err_code;
if( m_adv_modes_config.ble_adv_whitelist_enabled == BLE_ADV_WHITELIST_ENABLED
&& !m_whitelist_temporarily_disabled)
{
if (m_adv_mode_current != BLE_ADV_MODE_IDLE)
{
err_code = sd_ble_gap_adv_stop();
VERIFY_SUCCESS(err_code);
}
m_whitelist_temporarily_disabled = true;
m_advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
err_code = ble_advdata_set(&m_advdata, NULL);
VERIFY_SUCCESS(err_code);
err_code = ble_advertising_start(m_adv_mode_current);
if ((err_code != NRF_SUCCESS) && (m_error_handler != NULL))
{
m_error_handler(err_code);
}
}
return NRF_SUCCESS;
}

View File

@ -0,0 +1,223 @@
/* 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.
*/
/**@file
*
* @defgroup ble_sdk_lib_advertising Advertising Module
* @{
* @ingroup ble_sdk_lib
* @brief Module for handling connectable BLE advertising.
*
* @details The Advertising Module handles connectable advertising for your application. It can
* be configured with advertising modes to suit most typical use cases.
* Your main application can react to changes in advertising modes
* if an event handler is provided.
*
* @note The Advertising Module supports only applications with a single peripheral link.
*
* The application must propagate BLE stack events to this module by calling
* @ref ble_advertising_on_ble_evt() and system events by calling
* @ref ble_advertising_on_sys_evt().
*
*/
#ifndef BLE_ADVERTISING_H__
#define BLE_ADVERTISING_H__
#include <stdint.h>
#include "ble_gattc.h"
#include "ble.h"
#include "nrf_error.h"
#include "ble_advdata.h"
/**@brief Advertising modes.
*/
typedef enum
{
BLE_ADV_MODE_IDLE, /**< Idle; no connectable advertising is ongoing.*/
BLE_ADV_MODE_DIRECTED, /**< Directed advertising attempts to connect to the most recently disconnected peer. */
BLE_ADV_MODE_DIRECTED_SLOW, /**< Directed advertising (low duty cycle) attempts to connect to the most recently disconnected peer. */
BLE_ADV_MODE_FAST, /**< Fast advertising will connect to any peer device, or filter with a whitelist if one exists. */
BLE_ADV_MODE_SLOW, /**< Slow advertising is similar to fast advertising. By default, it uses a longer advertising interval and time-out than fast advertising. However, these options are defined by the user. */
} ble_adv_mode_t;
/**@brief Advertising events.
*
* @details These events are propagated to the main application if a handler was provided during
* initialization of the Advertising Module. Events for modes that are not used can be
* ignored. Similarly, BLE_ADV_EVT_WHITELIST_REQUEST and BLE_ADV_EVT_PEER_ADDR_REQUEST
* can be ignored if whitelist and direct advertising is not used.
*/
typedef enum
{
BLE_ADV_EVT_IDLE, /**< Idle; no connectable advertising is ongoing.*/
BLE_ADV_EVT_DIRECTED, /**< Direct advertising mode has started. */
BLE_ADV_EVT_DIRECTED_SLOW, /**< Directed advertising (low duty cycle) has started. */
BLE_ADV_EVT_FAST, /**< Fast advertising mode has started. */
BLE_ADV_EVT_SLOW, /**< Slow advertising mode has started.*/
BLE_ADV_EVT_FAST_WHITELIST, /**< Fast advertising mode using the whitelist has started. */
BLE_ADV_EVT_SLOW_WHITELIST, /**< Slow advertising mode using the whitelist has started.*/
BLE_ADV_EVT_WHITELIST_REQUEST, /**< Request a whitelist from the main application. For whitelist advertising to work, the whitelist must be set when this event occurs. */
BLE_ADV_EVT_PEER_ADDR_REQUEST /**< Request a peer address from the main application. For directed advertising to work, the peer address must be set when this event occurs. */
} ble_adv_evt_t;
/**@brief Options for the different advertisement modes.
*
* @details This structure is used to enable or disable advertising modes and to configure time-out
* periods and advertising intervals.
*/
typedef struct
{
bool ble_adv_whitelist_enabled; /**< Enable or disable use of the whitelist. */
bool ble_adv_directed_enabled; /**< Enable or disable direct advertising mode. */
bool ble_adv_directed_slow_enabled; /**< Enable or disable direct advertising mode. */
uint32_t ble_adv_directed_slow_interval; /**< Advertising interval for directed advertising. */
uint32_t ble_adv_directed_slow_timeout; /**< Time-out (number of tries) for direct advertising. */
bool ble_adv_fast_enabled; /**< Enable or disable fast advertising mode. */
uint32_t ble_adv_fast_interval; /**< Advertising interval for fast advertising. */
uint32_t ble_adv_fast_timeout; /**< Time-out (in seconds) for fast advertising. */
bool ble_adv_slow_enabled; /**< Enable or disable slow advertising mode. */
uint32_t ble_adv_slow_interval; /**< Advertising interval for slow advertising. */
uint32_t ble_adv_slow_timeout; /**< Time-out (in seconds) for slow advertising. */
}ble_adv_modes_config_t;
/**@brief BLE advertising event handler type. */
typedef void (*ble_advertising_evt_handler_t) (ble_adv_evt_t const adv_evt);
/**@brief BLE advertising error handler type. */
typedef void (*ble_advertising_error_handler_t) (uint32_t nrf_error);
/**@brief Initialization parameters for the Advertising Module.
* @details This structure is used to pass advertising options, advertising data, and an event handler to the Advertising Module during initialization. */
typedef struct
{
ble_adv_modes_config_t options; /**< Parameters for advertising modes.*/
ble_advdata_t advdata; /**< Advertising data. */
ble_advertising_evt_handler_t evt_handler; /**< Event handler. */
}ble_adv_init_t;
/* Defines to make the mode options easier to set during advertising init.*/
#define BLE_ADV_DIRECTED_ENABLED true
#define BLE_ADV_DIRECTED_DISABLED false
#define BLE_ADV_DIRECTED_SLOW_ENABLED true
#define BLE_ADV_DIRECTED_SLOW_DISABLED false
#define BLE_ADV_FAST_ENABLED true
#define BLE_ADV_FAST_DISABLED false
#define BLE_ADV_SLOW_ENABLED true
#define BLE_ADV_SLOW_DISABLED false
#define BLE_ADV_WHITELIST_ENABLED true
#define BLE_ADV_WHITELIST_DISABLED false
/**@brief Function for handling BLE events.
*
* @details This function must be called from the BLE stack event dispatcher for
* the module to handle BLE events that are relevant for the Advertising Module.
*
* @param[in] p_ble_evt BLE stack event.
*/
void ble_advertising_on_ble_evt(const ble_evt_t * const p_ble_evt);
/**@brief Function for handling system events.
*
* @details This function must be called to handle system events that are relevant
* for the Advertising Module. Specifically, the advertising module can not use the
* softdevice as long as there are pending writes to the flash memory. This
* event handler is designed to delay advertising until there is no flash operation.
*
* @param[in] sys_evt System event.
*/
void ble_advertising_on_sys_evt(uint32_t sys_evt);
/**@brief Function for initializing the Advertising Module.
*
* @details Encodes the required advertising data and passes it to the stack.
* Also builds a structure to be passed to the stack when starting advertising.
* The supplied advertising data is copied to a local structure and is manipulated
* depending on what advertising modes are started in @ref ble_advertising_start.
*
* @param[in] p_advdata Advertising data: name, appearance, discovery flags, and more.
* @param[in] p_srdata Scan response data: Supplement to advertising data.
* @param[in] p_config Select which advertising modes and intervals will be utilized.
* @param[in] evt_handler Event handler that will be called upon advertising events.
* @param[in] error_handler Error handler that will propogate internal errors to the main applications.
*
* @retval NRF_SUCCESS If initialization was successful. Otherwise, an error code is returned.
*/
uint32_t ble_advertising_init(ble_advdata_t const * p_advdata,
ble_advdata_t const * p_srdata,
ble_adv_modes_config_t const * p_config,
ble_advertising_evt_handler_t const evt_handler,
ble_advertising_error_handler_t const error_handler);
/**@brief Function for starting advertising.
*
* @details You can start advertising in any of the advertising modes that you enabled
* during initialization.
*
* @param[in] advertising_mode Advertising mode.
*
* @retval @ref NRF_SUCCESS On success, else an error code indicating reason for failure.
* @retval @ref NRF_ERROR_INVALID_STATE
*/
uint32_t ble_advertising_start(ble_adv_mode_t advertising_mode);
/**@brief Function for setting the peer address.
*
* @details The peer address must be set by the application upon receiving a
* @ref BLE_ADV_EVT_PEER_ADDR_REQUEST event. Without the peer address, the directed
* advertising mode will not be run.
*
* @param[in] p_peer_addr Pointer to a peer address.
*
* @retval @ref NRF_SUCCESS Successfully stored the peer address pointer in the advertising module.
* @retval @ref NRF_ERROR_INVALID_STATE If a reply was not expected.
*/
uint32_t ble_advertising_peer_addr_reply(ble_gap_addr_t * p_peer_addr);
/**@brief Function for setting a whitelist.
*
* @details The whitelist must be set by the application upon receiving a
* @ref BLE_ADV_EVT_WHITELIST_REQUEST event. Without the whitelist, the whitelist
* advertising for fast and slow modes will not be run.
*
* @param[in] p_whitelist Pointer to a whitelist.
*
* @retval @ref NRF_SUCCESS Successfully stored pointers to the whitelist into the advertising module.
* @retval @ref NRF_ERROR_INVALID_STATE If a reply was not expected.
*/
uint32_t ble_advertising_whitelist_reply(ble_gap_whitelist_t * p_whitelist);
/**@brief Function for disabling whitelist advertising.
*
* @details This function temporarily disables whitelist advertising.
* Calling this function resets the current time-out countdown.
*
* @retval @ref NRF_SUCCESS On success, else an error message propogated from the Softdevice.
*/
uint32_t ble_advertising_restart_without_whitelist(void);
/** @} */
#endif // BLE_ADVERTISING_H__
/** @} */

View File

@ -0,0 +1,939 @@
/* 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 "ble_db_discovery.h"
#include <stdlib.h>
#include "ble.h"
#include "nrf_log.h"
#include "sdk_common.h"
#define SRV_DISC_START_HANDLE 0x0001 /**< The start handle value used during service discovery. */
#define DB_DISCOVERY_MAX_USERS BLE_DB_DISCOVERY_MAX_SRV /**< The maximum number of users/registrations allowed by this module. */
#define DB_LOG NRF_LOG_PRINTF_DEBUG /**< A debug logger macro that can be used in this file to do logging information over UART. */
/**@brief Array of structures containing information about the registered application modules. */
static ble_uuid_t m_registered_handlers[DB_DISCOVERY_MAX_USERS];
/**@brief Array of structures containing pending events to be sent to the application modules.
*
* @details Whenever a discovery related event is to be raised to a user module, it will be stored
* in this array first. When all services needed to be discovered have been
* discovered, all pending events will be sent to the corresponding user modules.
**/
static struct
{
ble_db_discovery_evt_t evt; /**< The pending event. */
ble_db_discovery_evt_handler_t evt_handler; /**< The event handler which should be called to raise this event. */
} m_pending_user_evts[DB_DISCOVERY_MAX_USERS];
static ble_db_discovery_evt_handler_t m_evt_handler;
static uint32_t m_pending_usr_evt_index; /**< The index to the pending user event array, pointing to the last added pending user event. */
static uint32_t m_num_of_handlers_reg; /**< The number of handlers registered with the DB Discovery module. */
static bool m_initialized = false; /**< This variable Indicates if the module is initialized or not. */
#define MODULE_INITIALIZED (m_initialized == true)
#include "sdk_macros.h"
/**@brief Function for fetching the event handler provided by a registered application module.
*
* @param[in] srv_uuid UUID of the service.
*
* @retval evt_handler Event handler of the module, registered for the given service UUID.
* @retval NULL If no event handler is found.
*/
static ble_db_discovery_evt_handler_t registered_handler_get(const ble_uuid_t * const p_srv_uuid)
{
uint32_t i;
for (i = 0; i < m_num_of_handlers_reg; i++)
{
if (BLE_UUID_EQ(&(m_registered_handlers[i]), p_srv_uuid))
{
return (m_evt_handler);
}
}
return NULL;
}
/**@brief Function for storing the event handler provided by a registered application module.
*
* @param[in] p_srv_uuid The UUID of the service.
* @param[in] p_evt_handler The event handler provided by the application.
*
* @retval NRF_SUCCESS If the handler was stored or already present in the list.
* @retval NRF_ERROR_NO_MEM If there is no space left to store the handler.
*/
static uint32_t registered_handler_set(const ble_uuid_t * const p_srv_uuid,
ble_db_discovery_evt_handler_t p_evt_handler)
{
if (registered_handler_get(p_srv_uuid) != NULL)
{
return NRF_SUCCESS;
}
if (m_num_of_handlers_reg < DB_DISCOVERY_MAX_USERS)
{
m_registered_handlers[m_num_of_handlers_reg] = *p_srv_uuid;
m_num_of_handlers_reg++;
return NRF_SUCCESS;
}
else
{
return NRF_ERROR_NO_MEM;
}
}
/**@brief Function for sending all pending discovery events to the corresponding user modules.
*/
static void pending_user_evts_send(void)
{
uint32_t i = 0;
for (i = 0; i < m_num_of_handlers_reg; i++)
{
// Pass the event to the corresponding event handler.
m_pending_user_evts[i].evt_handler(&(m_pending_user_evts[i].evt));
}
m_pending_usr_evt_index = 0;
}
/**@brief Function for indicating error to the application.
*
* @details This function will fetch the event handler based on the UUID of the service being
* discovered. (The event handler is registered by the application beforehand).
* The error code is added to the pending events together with the event handler.
* If no event handler was found, then this function will do nothing.
*
* @param[in] p_db_discovery Pointer to the DB discovery structure.
* @param[in] err_code Error code that should be provided to the application.
* @param[in] conn_handle Connection Handle.
*
*/
static void discovery_error_evt_trigger(ble_db_discovery_t * const p_db_discovery,
uint32_t err_code,
uint16_t const conn_handle)
{
ble_db_discovery_evt_handler_t p_evt_handler;
ble_gatt_db_srv_t * p_srv_being_discovered;
p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
p_evt_handler = registered_handler_get(&(p_srv_being_discovered->srv_uuid));
if (p_evt_handler != NULL)
{
ble_db_discovery_evt_t evt;
evt.conn_handle = conn_handle;
evt.evt_type = BLE_DB_DISCOVERY_ERROR;
evt.params.err_code = err_code;
p_evt_handler(&evt);
}
}
/**@brief Function for triggering a Discovery Complete or Service Not Found event to the
* application.
*
* @details This function will fetch the event handler based on the UUID of the service being
* discovered. (The event handler is registered by the application beforehand).
* It then triggers an event indicating the completion of the service discovery.
* If no event handler was found, then this function will do nothing.
*
* @param[in] p_db_discovery Pointer to the DB discovery structure.
* @param[in] is_srv_found Variable to indicate if the service was found at the peer.
* @param[in] conn_handle Connection Handle.
*/
static void discovery_complete_evt_trigger(ble_db_discovery_t * const p_db_discovery,
bool is_srv_found,
uint16_t const conn_handle)
{
ble_db_discovery_evt_handler_t p_evt_handler;
ble_gatt_db_srv_t * p_srv_being_discovered;
p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
p_evt_handler = registered_handler_get(&(p_srv_being_discovered->srv_uuid));
if (p_evt_handler != NULL)
{
if (m_pending_usr_evt_index < DB_DISCOVERY_MAX_USERS)
{
// Insert an event into the pending event list.
m_pending_user_evts[m_pending_usr_evt_index].evt.conn_handle = conn_handle;
m_pending_user_evts[m_pending_usr_evt_index].evt.params.discovered_db =
*p_srv_being_discovered;
if (is_srv_found)
{
m_pending_user_evts[m_pending_usr_evt_index].evt.evt_type =
BLE_DB_DISCOVERY_COMPLETE;
}
else
{
m_pending_user_evts[m_pending_usr_evt_index].evt.evt_type =
BLE_DB_DISCOVERY_SRV_NOT_FOUND;
}
m_pending_user_evts[m_pending_usr_evt_index].evt_handler = p_evt_handler;
m_pending_usr_evt_index++;
if (m_pending_usr_evt_index == m_num_of_handlers_reg)
{
// All registered modules have pending events. Send all pending events to the user
// modules.
pending_user_evts_send();
}
else
{
// Too many events pending. Do nothing. (Ideally this should not happen.)
}
}
}
}
/**@brief Function for handling service discovery completion.
*
* @details This function will be used to determine if there are more services to be discovered,
* and if so, initiate the discovery of the next service.
*
* @param[in] p_db_discovery Pointer to the DB Discovery Structure.
* @param[in] conn_handle Connection Handle.
*/
static void on_srv_disc_completion(ble_db_discovery_t * p_db_discovery,
uint16_t const conn_handle)
{
p_db_discovery->discoveries_count++;
// Check if more services need to be discovered.
if (p_db_discovery->discoveries_count < m_num_of_handlers_reg)
{
// Reset the current characteristic index since a new service discovery is about to start.
p_db_discovery->curr_char_ind = 0;
// Initiate discovery of the next service.
p_db_discovery->curr_srv_ind++;
ble_gatt_db_srv_t * p_srv_being_discovered;
p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
p_srv_being_discovered->srv_uuid = m_registered_handlers[p_db_discovery->curr_srv_ind];
// Reset the characteristic count in the current service to zero since a new service
// discovery is about to start.
p_srv_being_discovered->char_count = 0;
DB_LOG("[DB]: Starting discovery of service with UUID 0x%x for Connection handle %d\r\n",
p_srv_being_discovered->srv_uuid.uuid, conn_handle);
uint32_t err_code;
err_code = sd_ble_gattc_primary_services_discover
(
conn_handle,
SRV_DISC_START_HANDLE,
&(p_srv_being_discovered->srv_uuid)
);
if (err_code != NRF_SUCCESS)
{
p_db_discovery->discovery_in_progress = false;
// Error with discovering the service.
// Indicate the error to the registered user application.
discovery_error_evt_trigger(p_db_discovery, err_code, conn_handle);
m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE;
m_pending_user_evts[0].evt.conn_handle = conn_handle;
// m_evt_handler(&m_pending_user_evts[0].evt);
return;
}
}
else
{
// No more service discovery is needed.
p_db_discovery->discovery_in_progress = false;
m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE;
m_pending_user_evts[0].evt.conn_handle = conn_handle;
//m_evt_handler(&m_pending_user_evts[0].evt);
}
}
/**@brief Function for finding out if a characteristic discovery should be performed after the
* last discovered characteristic.
*
* @details This function is used during the time of database discovery to find out if there is
* a need to do more characteristic discoveries. The value handles of the
* last discovered characteristic is compared with the end handle of the service.
* If the service handle is greater than one of the former characteristic handles,
* it means that a characteristic discovery is required.
*
* @param[in] p_db_discovery The pointer to the DB Discovery structure.
* @param[in] p_after_char The pointer to the last discovered characteristic.
*
* @retval True if a characteristic discovery is required.
* @retval False if a characteristic discovery is NOT required.
*/
static bool is_char_discovery_reqd(ble_db_discovery_t * const p_db_discovery,
ble_gattc_char_t * p_after_char)
{
if (
p_after_char->handle_value <
p_db_discovery->services[p_db_discovery->curr_srv_ind].handle_range.end_handle
)
{
// Handle value of the characteristic being discovered is less than the end handle of
// the service being discovered. There is a possibility of more characteristics being
// present. Hence a characteristic discovery is required.
return true;
}
return false;
}
/**@brief Function to find out if a descriptor discovery is required.
*
* @details This function finds out if there is a possibility of existence of descriptors between
* current characteristic and the next characteristic. If so, this function will compute
* the handle range on which the descriptors may be present and will return it.
* If the current characteristic is the last known characteristic, then this function
* will use the service end handle to find out if the current characteristic can have
* descriptors.
*
* @param[in] p_db_discovery Pointer to the DB Discovery structure.
* @param[in] p_curr_char Pointer to the current characteristic.
* @param[in] p_next_char Pointer to the next characteristic. This should be NULL if the
* caller knows that there is no characteristic after the current
* characteristic at the peer.
* @param[out] p_handle_range Pointer to the handle range in which descriptors may exist at the
* the peer.
*
* @retval True If a descriptor discovery is required.
* @retval False If a descriptor discovery is NOT required.
*/
static bool is_desc_discovery_reqd(ble_db_discovery_t * p_db_discovery,
ble_gatt_db_char_t * p_curr_char,
ble_gatt_db_char_t * p_next_char,
ble_gattc_handle_range_t * p_handle_range)
{
if (p_next_char == NULL)
{
// Current characteristic is the last characteristic in the service. Check if the value
// handle of the current characteristic is equal to the service end handle.
if (
p_curr_char->characteristic.handle_value ==
p_db_discovery->services[p_db_discovery->curr_srv_ind].handle_range.end_handle
)
{
// No descriptors can be present for the current characteristic. p_curr_char is the last
// characteristic with no descriptors.
return false;
}
p_handle_range->start_handle = p_curr_char->characteristic.handle_value + 1;
// Since the current characteristic is the last characteristic in the service, the end
// handle should be the end handle of the service.
p_handle_range->end_handle =
p_db_discovery->services[p_db_discovery->curr_srv_ind].handle_range.end_handle;
return true;
}
// p_next_char != NULL. Check for existence of descriptors between the current and the next
// characteristic.
if ((p_curr_char->characteristic.handle_value + 1) == p_next_char->characteristic.handle_decl)
{
// No descriptors can exist between the two characteristic.
return false;
}
p_handle_range->start_handle = p_curr_char->characteristic.handle_value + 1;
p_handle_range->end_handle = p_next_char->characteristic.handle_decl - 1;
return true;
}
/**@brief Function for performing characteristic discovery.
*
* @param[in] p_db_discovery Pointer to the DB Discovery structure.
* @param[in] conn_handle Connection Handle.
*
* @return NRF_SUCCESS if the SoftDevice was successfully requested to perform the characteristic
* discovery. Otherwise an error code. This function returns the error code returned
* by the SoftDevice API @ref sd_ble_gattc_characteristics_discover.
*/
static uint32_t characteristics_discover(ble_db_discovery_t * const p_db_discovery,
uint16_t const conn_handle)
{
ble_gatt_db_srv_t * p_srv_being_discovered;
ble_gattc_handle_range_t handle_range;
p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
if (p_db_discovery->curr_char_ind != 0)
{
// This is not the first characteristic being discovered. Hence the 'start handle' to be
// used must be computed using the handle_value of the previous characteristic.
ble_gattc_char_t * p_prev_char;
uint8_t prev_char_ind = p_db_discovery->curr_char_ind - 1;
p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
p_prev_char = &(p_srv_being_discovered->charateristics[prev_char_ind].characteristic);
handle_range.start_handle = p_prev_char->handle_value + 1;
}
else
{
// This is the first characteristic of this service being discovered.
handle_range.start_handle = p_srv_being_discovered->handle_range.start_handle;
}
handle_range.end_handle = p_srv_being_discovered->handle_range.end_handle;
return sd_ble_gattc_characteristics_discover(conn_handle, &handle_range);
}
/**@brief Function for performing descriptor discovery, if required.
*
* @details This function will check if descriptor discovery is required and then perform it if
* needed. If no more descriptor discovery is required for the service, then the output
* parameter p_raise_discov_complete is set to true, indicating to the caller that a
* discovery complete event can be triggered to the application.
*
* @param[in] p_db_discovery Pointer to the DB Discovery structure.
* @param[out] p_raise_discov_complete The value pointed to by this pointer will be set to true if
* the Discovery Complete event can be triggered to the
* application.
* @param[in] conn_handle Connection Handle.
*
* @return NRF_SUCCESS if the SoftDevice was successfully requested to perform the descriptor
* discovery, or if no more descriptor discovery is required. Otherwise an error code.
* This function returns the error code returned by the SoftDevice API @ref
* sd_ble_gattc_descriptors_discover.
*/
static uint32_t descriptors_discover(ble_db_discovery_t * const p_db_discovery,
bool * p_raise_discov_complete,
uint16_t const conn_handle)
{
ble_gattc_handle_range_t handle_range;
ble_gatt_db_char_t * p_curr_char_being_discovered;
ble_gatt_db_srv_t * p_srv_being_discovered;
bool is_discovery_reqd = false;
p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
p_curr_char_being_discovered =
&(p_srv_being_discovered->charateristics[p_db_discovery->curr_char_ind]);
if ((p_db_discovery->curr_char_ind + 1) == p_srv_being_discovered->char_count)
{
// This is the last characteristic of this service.
is_discovery_reqd = is_desc_discovery_reqd(p_db_discovery,
p_curr_char_being_discovered,
NULL,
&handle_range);
}
else
{
uint8_t i;
ble_gatt_db_char_t * p_next_char;
for (i = p_db_discovery->curr_char_ind;
i < p_srv_being_discovered->char_count;
i++)
{
if (i == (p_srv_being_discovered->char_count - 1))
{
// The current characteristic is the last characteristic in the service.
p_next_char = NULL;
}
else
{
p_next_char = &(p_srv_being_discovered->charateristics[i + 1]);
}
// Check if it is possible for the current characteristic to have a descriptor.
if (is_desc_discovery_reqd(p_db_discovery,
p_curr_char_being_discovered,
p_next_char,
&handle_range))
{
is_discovery_reqd = true;
break;
}
else
{
// No descriptors can exist.
p_curr_char_being_discovered = p_next_char;
p_db_discovery->curr_char_ind++;
}
}
}
if (!is_discovery_reqd)
{
// No more descriptor discovery required. Discovery is complete.
// This informs the caller that a discovery complete event can be triggered.
*p_raise_discov_complete = true;
return NRF_SUCCESS;
}
*p_raise_discov_complete = false;
return sd_ble_gattc_descriptors_discover(conn_handle, &handle_range);
}
/**@brief Function for handling primary service discovery response.
*
* @details This function will handle the primary service discovery response and start the
* discovery of characteristics within that service.
*
* @param[in] p_db_discovery Pointer to the DB Discovery structure.
* @param[in] p_ble_gattc_evt Pointer to the GATT Client event.
*/
static void on_primary_srv_discovery_rsp(ble_db_discovery_t * const p_db_discovery,
const ble_gattc_evt_t * const p_ble_gattc_evt)
{
ble_gatt_db_srv_t * p_srv_being_discovered;
p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
if (p_ble_gattc_evt->conn_handle != p_db_discovery->conn_handle)
{
return;
}
if (p_ble_gattc_evt->gatt_status == BLE_GATT_STATUS_SUCCESS)
{
uint32_t err_code;
const ble_gattc_evt_prim_srvc_disc_rsp_t * p_prim_srvc_disc_rsp_evt;
DB_LOG("Found service UUID 0x%x\r\n", p_srv_being_discovered->srv_uuid.uuid);
p_prim_srvc_disc_rsp_evt = &(p_ble_gattc_evt->params.prim_srvc_disc_rsp);
p_srv_being_discovered->srv_uuid = p_prim_srvc_disc_rsp_evt->services[0].uuid;
p_srv_being_discovered->handle_range = p_prim_srvc_disc_rsp_evt->services[0].handle_range;
err_code = characteristics_discover(p_db_discovery,
p_ble_gattc_evt->conn_handle);
if (err_code != NRF_SUCCESS)
{
p_db_discovery->discovery_in_progress = false;
// Error with discovering the service.
// Indicate the error to the registered user application.
discovery_error_evt_trigger(p_db_discovery,
err_code,
p_ble_gattc_evt->conn_handle);
m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE;
m_pending_user_evts[0].evt.conn_handle = p_ble_gattc_evt->conn_handle;
//m_evt_handler(&m_pending_user_evts[0].evt);
}
}
else
{
DB_LOG("Service UUID 0x%x Not found\r\n", p_srv_being_discovered->srv_uuid.uuid);
// Trigger Service Not Found event to the application.
discovery_complete_evt_trigger(p_db_discovery,
false,
p_ble_gattc_evt->conn_handle);
on_srv_disc_completion(p_db_discovery,
p_ble_gattc_evt->conn_handle);
}
}
/**@brief Function for handling characteristic discovery response.
*
* @param[in] p_db_discovery Pointer to the DB Discovery structure.
* @param[in] p_ble_gattc_evt Pointer to the GATT Client event.
*/
static void on_characteristic_discovery_rsp(ble_db_discovery_t * const p_db_discovery,
const ble_gattc_evt_t * const p_ble_gattc_evt)
{
uint32_t err_code;
ble_gatt_db_srv_t * p_srv_being_discovered;
bool perform_desc_discov = false;
if (p_ble_gattc_evt->conn_handle != p_db_discovery->conn_handle)
{
return;
}
p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
if (p_ble_gattc_evt->gatt_status == BLE_GATT_STATUS_SUCCESS)
{
const ble_gattc_evt_char_disc_rsp_t * p_char_disc_rsp_evt;
p_char_disc_rsp_evt = &(p_ble_gattc_evt->params.char_disc_rsp);
// Find out the number of characteristics that were previously discovered (in earlier
// characteristic discovery responses, if any).
uint8_t num_chars_prev_disc = p_srv_being_discovered->char_count;
// Find out the number of characteristics that are currently discovered (in the
// characteristic discovery response being handled).
uint8_t num_chars_curr_disc = p_char_disc_rsp_evt->count;
// Check if the total number of discovered characteristics are supported by this module.
if ((num_chars_prev_disc + num_chars_curr_disc) <= BLE_GATT_DB_MAX_CHARS)
{
// Update the characteristics count.
p_srv_being_discovered->char_count += num_chars_curr_disc;
}
else
{
// The number of characteristics discovered at the peer is more than the supported
// maximum. This module will store only the characteristics found up to this point.
p_srv_being_discovered->char_count = BLE_GATT_DB_MAX_CHARS;
}
uint32_t i;
uint32_t j;
for (i = num_chars_prev_disc, j = 0; i < p_srv_being_discovered->char_count; i++, j++)
{
p_srv_being_discovered->charateristics[i].characteristic =
p_char_disc_rsp_evt->chars[j];
p_srv_being_discovered->charateristics[i].cccd_handle = BLE_GATT_HANDLE_INVALID;
}
ble_gattc_char_t * p_last_known_char;
p_last_known_char = &(p_srv_being_discovered->charateristics[i - 1].characteristic);
// If no more characteristic discovery is required, or if the maximum number of supported
// characteristic per service has been reached, descriptor discovery will be performed.
if (
!is_char_discovery_reqd(p_db_discovery, p_last_known_char) ||
(p_srv_being_discovered->char_count == BLE_GATT_DB_MAX_CHARS)
)
{
perform_desc_discov = true;
}
else
{
// Update the current characteristic index.
p_db_discovery->curr_char_ind = p_srv_being_discovered->char_count;
// Perform another round of characteristic discovery.
err_code = characteristics_discover(p_db_discovery,
p_ble_gattc_evt->conn_handle);
if (err_code != NRF_SUCCESS)
{
p_db_discovery->discovery_in_progress = false;
discovery_error_evt_trigger(p_db_discovery,
err_code,
p_ble_gattc_evt->conn_handle);
m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE;
m_pending_user_evts[0].evt.conn_handle = p_ble_gattc_evt->conn_handle;
//m_evt_handler(&m_pending_user_evts[0].evt);
return;
}
}
}
else
{
// The previous characteristic discovery resulted in no characteristics.
// descriptor discovery should be performed.
perform_desc_discov = true;
}
if (perform_desc_discov)
{
bool raise_discov_complete;
p_db_discovery->curr_char_ind = 0;
err_code = descriptors_discover(p_db_discovery,
&raise_discov_complete,
p_ble_gattc_evt->conn_handle);
if (err_code != NRF_SUCCESS)
{
p_db_discovery->discovery_in_progress = false;
discovery_error_evt_trigger(p_db_discovery,
err_code,
p_ble_gattc_evt->conn_handle);
m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE;
m_pending_user_evts[0].evt.conn_handle = p_ble_gattc_evt->conn_handle;
//m_evt_handler(&m_pending_user_evts[0].evt);
return;
}
if (raise_discov_complete)
{
// No more characteristics and descriptors need to be discovered. Discovery is complete.
// Send a discovery complete event to the user application.
DB_LOG("[DB]: Discovery of service with UUID 0x%x completed with success for Connection"
" handle %d\r\n", p_srv_being_discovered->srv_uuid.uuid,
p_ble_gattc_evt->conn_handle);
discovery_complete_evt_trigger(p_db_discovery,
true,
p_ble_gattc_evt->conn_handle);
on_srv_disc_completion(p_db_discovery,
p_ble_gattc_evt->conn_handle);
}
}
}
/**@brief Function for handling descriptor discovery response.
*
* @param[in] p_db_discovery Pointer to the DB Discovery structure.
* @param[in] p_ble_gattc_evt Pointer to the GATT Client event.
*/
static void on_descriptor_discovery_rsp(ble_db_discovery_t * const p_db_discovery,
const ble_gattc_evt_t * const p_ble_gattc_evt)
{
const ble_gattc_evt_desc_disc_rsp_t * p_desc_disc_rsp_evt;
ble_gatt_db_srv_t * p_srv_being_discovered;
if (p_ble_gattc_evt->conn_handle != p_db_discovery->conn_handle)
{
return;
}
p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
p_desc_disc_rsp_evt = &(p_ble_gattc_evt->params.desc_disc_rsp);
ble_gatt_db_char_t * p_char_being_discovered =
&(p_srv_being_discovered->charateristics[p_db_discovery->curr_char_ind]);
if (p_ble_gattc_evt->gatt_status == BLE_GATT_STATUS_SUCCESS)
{
// The descriptor was found at the peer.
// If the descriptor was a CCCD, then the cccd_handle needs to be populated.
uint32_t i;
// Loop through all the descriptors to find the CCCD.
for (i = 0; i < p_desc_disc_rsp_evt->count; i++)
{
if (
p_desc_disc_rsp_evt->descs[i].uuid.uuid ==
BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG
)
{
p_char_being_discovered->cccd_handle = p_desc_disc_rsp_evt->descs[i].handle;
break;
}
}
}
bool raise_discov_complete = false;
if ((p_db_discovery->curr_char_ind + 1) == p_srv_being_discovered->char_count)
{
// No more characteristics and descriptors need to be discovered. Discovery is complete.
// Send a discovery complete event to the user application.
raise_discov_complete = true;
}
else
{
// Begin discovery of descriptors for the next characteristic.
uint32_t err_code;
p_db_discovery->curr_char_ind++;
err_code = descriptors_discover(p_db_discovery,
&raise_discov_complete,
p_ble_gattc_evt->conn_handle);
if (err_code != NRF_SUCCESS)
{
p_db_discovery->discovery_in_progress = false;
// Error with discovering the service.
// Indicate the error to the registered user application.
discovery_error_evt_trigger(p_db_discovery,
err_code,
p_ble_gattc_evt->conn_handle);
m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE;
m_pending_user_evts[0].evt.conn_handle = p_ble_gattc_evt->conn_handle;
return;
}
}
if (raise_discov_complete)
{
DB_LOG("[DB]: Discovery of service with UUID 0x%x completed with success for Connection"
"handle %d\r\n", p_srv_being_discovered->srv_uuid.uuid,
p_ble_gattc_evt->conn_handle);
discovery_complete_evt_trigger(p_db_discovery,
true,
p_ble_gattc_evt->conn_handle);
on_srv_disc_completion(p_db_discovery,
p_ble_gattc_evt->conn_handle);
}
}
uint32_t ble_db_discovery_init(const ble_db_discovery_evt_handler_t evt_handler)
{
uint32_t err_code = NRF_SUCCESS;
VERIFY_PARAM_NOT_NULL(evt_handler);
m_num_of_handlers_reg = 0;
m_initialized = true;
m_pending_usr_evt_index = 0;
m_evt_handler = evt_handler;
return err_code;
}
uint32_t ble_db_discovery_close()
{
m_num_of_handlers_reg = 0;
m_initialized = false;
m_pending_usr_evt_index = 0;
return NRF_SUCCESS;
}
uint32_t ble_db_discovery_evt_register(const ble_uuid_t * const p_uuid)
{
VERIFY_PARAM_NOT_NULL(p_uuid);
VERIFY_MODULE_INITIALIZED();
return registered_handler_set(p_uuid, m_evt_handler);
}
uint32_t ble_db_discovery_start(ble_db_discovery_t * const p_db_discovery,
uint16_t conn_handle)
{
VERIFY_PARAM_NOT_NULL(p_db_discovery);
VERIFY_MODULE_INITIALIZED();
if (m_num_of_handlers_reg == 0)
{
// No user modules were registered. There are no services to discover.
return NRF_ERROR_INVALID_STATE;
}
if (p_db_discovery->discovery_in_progress)
{
return NRF_ERROR_BUSY;
}
p_db_discovery->conn_handle = conn_handle;
ble_gatt_db_srv_t * p_srv_being_discovered;
m_pending_usr_evt_index = 0;
p_db_discovery->discoveries_count = 0;
p_db_discovery->curr_srv_ind = 0;
p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
p_srv_being_discovered->srv_uuid = m_registered_handlers[p_db_discovery->curr_srv_ind];
DB_LOG("[DB]: Starting discovery of service with UUID 0x%x for Connection handle %d\r\n",
p_srv_being_discovered->srv_uuid.uuid, conn_handle);
uint32_t err_code;
err_code = sd_ble_gattc_primary_services_discover(conn_handle,
SRV_DISC_START_HANDLE,
&(p_srv_being_discovered->srv_uuid));
VERIFY_SUCCESS(err_code);
p_db_discovery->discovery_in_progress = true;
return NRF_SUCCESS;
}
/**@brief Function for handling disconnected event.
*
* @param[in] p_db_discovery Pointer to the DB Discovery structure.
* @param[in] p_ble_gattc_evt Pointer to the GAP event.
*/
static void on_disconnected(ble_db_discovery_t * const p_db_discovery,
const ble_gap_evt_t * const p_evt)
{
if (p_evt->conn_handle == p_db_discovery->conn_handle)
{
p_db_discovery->discovery_in_progress = false;
}
}
void ble_db_discovery_on_ble_evt(ble_db_discovery_t * const p_db_discovery,
const ble_evt_t * const p_ble_evt)
{
VERIFY_PARAM_NOT_NULL_VOID(p_db_discovery);
VERIFY_PARAM_NOT_NULL_VOID(p_ble_evt);
VERIFY_MODULE_INITIALIZED_VOID();
switch (p_ble_evt->header.evt_id)
{
case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
on_primary_srv_discovery_rsp(p_db_discovery, &(p_ble_evt->evt.gattc_evt));
break;
case BLE_GATTC_EVT_CHAR_DISC_RSP:
on_characteristic_discovery_rsp(p_db_discovery, &(p_ble_evt->evt.gattc_evt));
break;
case BLE_GATTC_EVT_DESC_DISC_RSP:
on_descriptor_discovery_rsp(p_db_discovery, &(p_ble_evt->evt.gattc_evt));
break;
case BLE_GAP_EVT_DISCONNECTED:
on_disconnected(p_db_discovery, &(p_ble_evt->evt.gap_evt));
break;
default:
break;
}
}

View File

@ -0,0 +1,180 @@
/* 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 ble_sdk_lib_db_discovery Database Discovery
* @{
* @ingroup ble_sdk_lib
* @brief Database discovery module.
*
* @details This module contains the APIs and types exposed by the DB Discovery module. These APIs
* and types can be used by the application to perform discovery of a service and its
* characteristics at the peer server. This module can also be used to discover the
* desired services in multiple remote devices.
*
* @warning The maximum number of characteristics per service that can be discovered by this module
* is determined by the number of characteristics in the service structure defined in
* db_disc_config.h. If the peer has more than the supported number of characteristics, then
* the first found will be discovered and any further characteristics will be ignored. No
* descriptors other than Client Characteristic Configuration Descriptors will be searched
* for at the peer.
*
* @note Presently only one instance of a Primary Service can be discovered by this module. If
* there are multiple instances of the service at the peer, only the first instance
* of it at the peer is fetched and returned to the application.
*
* @note The application must propagate BLE stack events to this module by calling
* ble_db_discovery_on_ble_evt().
*
*/
#ifndef BLE_DB_DISCOVERY_H__
#define BLE_DB_DISCOVERY_H__
#include <stdint.h>
#include "ble_gattc.h"
#include "ble.h"
#include "nrf_error.h"
#include "ble_srv_common.h"
#include "ble_gatt_db.h"
#define BLE_DB_DISCOVERY_MAX_SRV 6 /**< Maximum number of services supported by this module. This also indicates the maximum number of users allowed to be registered to this module. (one user per service). */
/**@brief Type of the DB Discovery event.
*/
typedef enum
{
BLE_DB_DISCOVERY_COMPLETE, /**< Event indicating that the GATT Database discovery is complete. */
BLE_DB_DISCOVERY_ERROR, /**< Event indicating that an internal error has occurred in the DB Discovery module. This could typically be because of the SoftDevice API returning an error code during the DB discover.*/
BLE_DB_DISCOVERY_SRV_NOT_FOUND, /**< Event indicating that the service was not found at the peer.*/
BLE_DB_DISCOVERY_AVAILABLE /**< Event indicating that the DB discovery module is available.*/
} ble_db_discovery_evt_type_t;
/**@brief Structure for holding the information related to the GATT database at the server.
*
* @details This module identifies a remote database. Use one instance of this structure per
* connection.
*
* @warning This structure must be zero-initialized.
*/
typedef struct
{
ble_gatt_db_srv_t services[BLE_DB_DISCOVERY_MAX_SRV]; /**< Information related to the current service being discovered. This is intended for internal use during service discovery.*/
uint8_t srv_count; /**< Number of services at the peers GATT database.*/
uint8_t curr_char_ind; /**< Index of the current characteristic being discovered. This is intended for internal use during service discovery.*/
uint8_t curr_srv_ind; /**< Index of the current service being discovered. This is intended for internal use during service discovery.*/
bool discovery_in_progress; /**< Variable to indicate if there is a service discovery in progress. */
uint8_t discoveries_count; /**< Number of service discoveries made, both successful and unsuccessful. */
uint16_t conn_handle; /**< Connection handle on which the discovery is started*/
} ble_db_discovery_t;
/**@brief Structure containing the event from the DB discovery module to the application.
*/
typedef struct
{
ble_db_discovery_evt_type_t evt_type; /**< Type of event. */
uint16_t conn_handle; /**< Handle of the connection for which this event has occurred. */
union
{
ble_gatt_db_srv_t discovered_db; /**< Structure containing the information about the GATT Database at the server. This will be filled when the event type is @ref BLE_DB_DISCOVERY_COMPLETE.*/
uint32_t err_code; /**< nRF Error code indicating the type of error which occurred in the DB Discovery module. This will be filled when the event type is @ref BLE_DB_DISCOVERY_ERROR. */
} params;
} ble_db_discovery_evt_t;
/**@brief DB Discovery event handler type. */
typedef void (* ble_db_discovery_evt_handler_t)(ble_db_discovery_evt_t * p_evt);
/**@brief Function for initializing the DB Discovery module.
*
* @param[in] evt_handler Event handler to be called by the DB discovery module when any event
* related to discovery of the registered service occurs.
*
* @retval NRF_SUCCESS On successful initialization.
* @retval NRF_ERROR_NULL If the handler was NULL.
*/
uint32_t ble_db_discovery_init(ble_db_discovery_evt_handler_t evt_handler);
/**@brief Function for closing the DB Discovery module.
*
* @details This function will clear up any internal variables and states maintained by the
* module. To re-use the module after calling this function, the function @ref
* ble_db_discovery_init must be called again.
*
* @retval NRF_SUCCESS Operation success.
*/
uint32_t ble_db_discovery_close(void);
/**@brief Function for registering with the DB Discovery module.
*
* @details The application can use this function to inform which service it is interested in
* discovering at the server.
*
* @param[in] p_uuid Pointer to the UUID of the service to be discovered at the server.
*
* @note The total number of services that can be discovered by this module is @ref
* BLE_DB_DISCOVERY_MAX_SRV. This effectively means that the maximum number of
* registrations possible is equal to the @ref BLE_DB_DISCOVERY_MAX_SRV.
*
* @retval NRF_SUCCESS Operation success.
* @retval NRF_ERROR_NULL When a NULL pointer is passed as input.
* @retval NRF_ERROR_INVALID_STATE If this function is called without calling the
* @ref ble_db_discovery_init.
* @retval NRF_ERROR_NO_MEM The maximum number of registrations allowed by this module
* has been reached.
*/
uint32_t ble_db_discovery_evt_register(const ble_uuid_t * const p_uuid);
/**@brief Function for starting the discovery of the GATT database at the server.
*
* @warning p_db_discovery structure must be zero-initialized.
*
* @param[out] p_db_discovery Pointer to the DB Discovery structure.
* @param[in] conn_handle The handle of the connection for which the discovery should be
* started.
*
* @retval NRF_SUCCESS Operation success.
* @retval NRF_ERROR_NULL When a NULL pointer is passed as input.
* @retval NRF_ERROR_INVALID_STATE If this function is called without calling the
* @ref ble_db_discovery_init, or without calling
* @ref ble_db_discovery_evt_register.
* @retval NRF_ERROR_BUSY If a discovery is already in progress for the current
* connection.
*
* @return This API propagates the error code returned by the
* SoftDevice API @ref sd_ble_gattc_primary_services_discover.
*/
uint32_t ble_db_discovery_start(ble_db_discovery_t * const p_db_discovery,
uint16_t conn_handle);
/**@brief Function for handling the Application's BLE Stack events.
*
* @param[in,out] p_db_discovery Pointer to the DB Discovery structure.
* @param[in] p_ble_evt Pointer to the BLE event received.
*/
void ble_db_discovery_on_ble_evt(ble_db_discovery_t * const p_db_discovery,
const ble_evt_t * const p_ble_evt);
#endif // BLE_DB_DISCOVERY_H__
/** @} */

View File

@ -0,0 +1,55 @@
/* 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 "ble_debug_assert_handler.h"
#include <string.h>
#include "nrf.h"
#include "ble_error_log.h"
#include "nordic_common.h"
#define MAX_LENGTH_FILENAME 128 /**< Max length of filename to copy for the debug error handlier. */
// WARNING - DO NOT USE THIS FUNCTION IN END PRODUCT. - WARNING
// WARNING - FOR DEBUG PURPOSES ONLY. - WARNING
void ble_debug_assert_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name)
{
// Copying parameters to static variables because parameters may not be accessible in debugger.
static volatile uint8_t s_file_name[MAX_LENGTH_FILENAME];
static volatile uint16_t s_line_num;
static volatile uint32_t s_error_code;
strncpy((char *)s_file_name, (const char *)p_file_name, MAX_LENGTH_FILENAME - 1);
s_file_name[MAX_LENGTH_FILENAME - 1] = '\0';
s_line_num = line_num;
s_error_code = error_code;
UNUSED_VARIABLE(s_file_name);
UNUSED_VARIABLE(s_line_num);
UNUSED_VARIABLE(s_error_code);
// WARNING: The PRIMASK register is set to disable ALL interrups during writing the error log.
//
// Do not use __disable_irq() in normal operation.
__disable_irq();
// This function will write error code, filename, and line number to the flash.
// In addition, the Cortex-M0 stack memory will also be written to the flash.
//(void) ble_error_log_write(error_code, p_file_name, line_num);
// For debug purposes, this function never returns.
// Attach a debugger for tracing the error cause.
for (;;)
{
// Do nothing.
}
}

View File

@ -0,0 +1,51 @@
/* 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 ble_debug_assert_handler Assert handler for debug purposes
* @{
* @ingroup ble_sdk_lib
* @brief Module for handling of assert during application development when debugging.
*
* @details This module may be used during development of an application to facilitate debugging.
* It contains a function to write file name, line number and the Stack Memory to flash.
* This module is ONLY for debugging purposes and must never be used in final product.
*
*/
#ifndef BLE_DEBUG_ASSERT_HANDLER_H__
#define BLE_DEBUG_ASSERT_HANDLER_H__
#include <stdint.h>
/**@brief Function for handling the Debug assert, which can be called from an error handler.
* To be used only for debugging purposes.
*
*@details This code will copy the filename and line number into local variables for them to always
* be accessible in Keil debugger. The function will also write the ARM Cortex-M0 stack
* memory into flash where it can be retrieved and manually un-winded in order to
* back-trace the location where the error ocured.<br>
* @warning <b>ALL INTERRUPTS WILL BE DISABLED.</b>
*
* @note This function will never return but loop forever for debug purposes.
*
* @param[in] error_code Error code supplied to the handler.
* @param[in] line_num Line number where the original handler is called.
* @param[in] p_file_name Pointer to the file name.
*/
void ble_debug_assert_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name);
#endif /* BLE_DEBUG_ASSERT_HANDLER_H__ */
/** @} */

View File

@ -0,0 +1,643 @@
/* 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 "ble_dtm.h"
#include <stdbool.h>
#include <string.h>
#include "nrf.h"
#define DTM_HEADER_OFFSET 0 /**< Index where the header of the pdu is located. */
#define DTM_HEADER_SIZE 2 /**< Size of PDU header. */
#define DTM_PAYLOAD_MAX_SIZE 37 /**< Maximum payload size allowed during dtm execution. */
#define DTM_LENGTH_OFFSET (DTM_HEADER_OFFSET + 1) /**< Index where the length of the payload is encoded. */
#define DTM_PDU_MAX_MEMORY_SIZE (DTM_HEADER_SIZE + DTM_PAYLOAD_MAX_SIZE) /**< Maximum PDU size allowed during dtm execution. */
/**@details The UART poll cycle in micro seconds.
* Baud rate of 19200 bits / second, and 8 data bits, 1 start/stop bit, no flow control,
* give the time to transmit a byte: 10 bits * 1/19200 = approx: 520 us.
*
* To ensure no loss of bytes, the UART should be polled every 260 us.
*
* @note If UART bit rate is changed, this value should be recalculated as well.
*/
#define UART_POLL_CYCLE 260
#define RX_MODE true /**< Constant defining RX mode for radio during dtm test. */
#define TX_MODE false /**< Constant defining TX mode for radio during dtm test. */
#define PHYS_CH_MAX 39 /**< Maximum number of valid channels in BLE. */
// Values that for now are "constants" - they could be configured by a function setting them,
// but most of these are set by the BLE DTM standard, so changing them is not relevant.
#define RFPHY_TEST_0X0F_REF_PATTERN 0x0f /**< RF-PHY test packet patterns, for the repeated octet packets. */
#define RFPHY_TEST_0X55_REF_PATTERN 0x55 /**< RF-PHY test packet patterns, for the repeated octet packets. */
#define PRBS9_CONTENT {0xff, 0xc1, 0xfb, 0xe8, 0x4c, 0x90, 0x72, 0x8b, \
0xe7, 0xb3, 0x51, 0x89, 0x63, 0xab, 0x23, 0x23, \
0x2, 0x84, 0x18, 0x72, 0xaa, 0x61, 0x2f, 0x3b, \
0x51, 0xa8, 0xe5, 0x37, 0x49, 0xfb, 0xc9, 0xca, \
0xc, 0x18, 0x53, 0x2c, 0xfd} /**< The PRBS9 sequence used as packet payload. */
/**@brief Structure holding the PDU used for transmitting/receiving a PDU.
*/
typedef struct
{
uint8_t content[DTM_HEADER_SIZE + DTM_PAYLOAD_MAX_SIZE]; /**< PDU packet content. */
} pdu_type_t;
/**@brief States used for the DTM test implementation.
*/
typedef enum
{
STATE_UNINITIALIZED, /**< The DTM is uninitialized. */
STATE_IDLE, /**< State when system has just initialized, or current test has completed. */
STATE_TRANSMITTER_TEST, /**< State used when a DTM Transmission test is running. */
STATE_CARRIER_TEST, /**< State used when a DTM Carrier test is running (Vendor specific test). */
STATE_RECEIVER_TEST /**< State used when a DTM Receive test is running. */
} state_t;
// Internal variables set as side effects of commands or events.
static state_t m_state = STATE_UNINITIALIZED; /**< Current machine state. */
static uint16_t m_rx_pkt_count; /**< Number of valid packets received. */
static pdu_type_t m_pdu; /**< PDU to be sent. */
static uint16_t m_event; /**< current command status - initially "ok", may be set if error detected, or to packet count. */
static bool m_new_event; /**< Command has been processed - number of not yet reported event bytes. */
static uint8_t m_packet_length; /**< Payload length of transmitted PDU, bits 2:7 of 16-bit dtm command. */
static dtm_pkt_type_t m_packet_type; /**< Bits 0..1 of 16-bit transmit command, or 0xFFFFFFFF. */
static dtm_freq_t m_phys_ch; /**< 0..39 physical channel number (base 2402 MHz, Interval 2 MHz), bits 8:13 of 16-bit dtm command. */
static uint32_t m_current_time = 0; /**< Counter for interrupts from timer to ensure that the 2 bytes forming a DTM command are received within the time window. */
// Nordic specific configuration values (not defined by BLE standard).
// Definition of initial values found in ble_dtm.h
static int32_t m_tx_power = DEFAULT_TX_POWER; /**< TX power for transmission test, default to maximum value (+4 dBm). */
static NRF_TIMER_Type * mp_timer = DEFAULT_TIMER; /**< Timer to be used. */
static IRQn_Type m_timer_irq = DEFAULT_TIMER_IRQn; /**< which interrupt line to clear on every timeout */
static uint8_t const m_prbs_content[] = PRBS9_CONTENT; /**< Pseudo-random bit sequence defined by the BLE standard. */
static uint8_t m_packetHeaderLFlen = 8; /**< Length of length field in packet Header (in bits). */
static uint8_t m_packetHeaderS0len = 1; /**< Length of S0 field in packet Header (in bytes). */
static uint8_t m_packetHeaderS1len = 0; /**< Length of S1 field in packet Header (in bits). */
static uint8_t m_crcConfSkipAddr = 1; /**< Leave packet address field out of CRC calculation. */
static uint8_t m_static_length = 0; /**< Number of bytes sent in addition to the var.length payload. */
static uint32_t m_balen = 3; /**< Base address length in bytes. */
static uint32_t m_endian = RADIO_PCNF1_ENDIAN_Little; /**< On air endianess of packet, this applies to the S0, LENGTH, S1 and the PAYLOAD fields. */
static uint32_t m_whitening = RADIO_PCNF1_WHITEEN_Disabled; /**< Whitening disabled. */
static uint8_t m_crcLength = RADIO_CRCCNF_LEN_Three; /**< CRC Length (in bytes). */
static uint32_t m_address = 0x71764129; /**< Address. */
static uint32_t m_crc_poly = 0x0000065B; /**< CRC polynomial. */
static uint32_t m_crc_init = 0x00555555; /**< Initial value for CRC calculation. */
static uint8_t m_radio_mode = RADIO_MODE_MODE_Ble_1Mbit; /**< nRF51 specific radio mode vale. */
static uint32_t m_txIntervaluS = 625; /**< Time between start of Tx packets (in uS). */
/**@brief Function for verifying that a received PDU has the expected structure and content.
*/
static bool check_pdu(void)
{
uint8_t k; // Byte pointer for running through PDU payload
uint8_t pattern; // Repeating octet value in payload
dtm_pkt_type_t pdu_packet_type; // Note: PDU packet type is a 4-bit field in HCI, but 2 bits in BLE DTM
uint8_t length;
pdu_packet_type = (dtm_pkt_type_t)(m_pdu.content[DTM_HEADER_OFFSET] & 0x0F);
length = m_pdu.content[DTM_LENGTH_OFFSET];
if ((pdu_packet_type > (dtm_pkt_type_t)PACKET_TYPE_MAX) || (length > DTM_PAYLOAD_MAX_SIZE))
{
return false;
}
if (pdu_packet_type == DTM_PKT_PRBS9)
{
// Payload does not consist of one repeated octet; must compare ir with entire block into
return (memcmp(m_pdu.content+DTM_HEADER_SIZE, m_prbs_content, length) == 0);
}
if (pdu_packet_type == DTM_PKT_0X0F)
{
pattern = RFPHY_TEST_0X0F_REF_PATTERN;
}
else
{
pattern = RFPHY_TEST_0X55_REF_PATTERN;
}
for (k = 0; k < length; k++)
{
// Check repeated pattern filling the PDU payload
if (m_pdu.content[k + 2] != pattern)
{
return false;
}
}
return true;
}
/**@brief Function for turning off the radio after a test.
* Also called after test done, to be ready for next test.
*/
static void radio_reset(void)
{
NRF_PPI->CHENCLR = PPI_CHENCLR_CH0_Msk | PPI_CHENCLR_CH1_Msk;
NRF_RADIO->SHORTS = 0;
NRF_RADIO->EVENTS_DISABLED = 0;
NRF_RADIO->TASKS_DISABLE = 1;
while (NRF_RADIO->EVENTS_DISABLED == 0)
{
// Do nothing
}
NRF_RADIO->EVENTS_DISABLED = 0;
NRF_RADIO->TASKS_RXEN = 0;
NRF_RADIO->TASKS_TXEN = 0;
m_rx_pkt_count = 0;
}
/**@brief Function for initializing the radio for DTM.
*/
static uint32_t radio_init(void)
{
#ifdef NRF51
// Handle BLE Radio tuning parameters from production for DTM if required.
// Only needed for DTM without SoftDevice, as the SoftDevice normally handles this.
// PCN-083.
if ( ((NRF_FICR->OVERRIDEEN) & FICR_OVERRIDEEN_BLE_1MBIT_Msk) == FICR_OVERRIDEEN_BLE_1MBIT_Override)
{
NRF_RADIO->OVERRIDE0 = NRF_FICR->BLE_1MBIT[0];
NRF_RADIO->OVERRIDE1 = NRF_FICR->BLE_1MBIT[1];
NRF_RADIO->OVERRIDE2 = NRF_FICR->BLE_1MBIT[2];
NRF_RADIO->OVERRIDE3 = NRF_FICR->BLE_1MBIT[3];
NRF_RADIO->OVERRIDE4 = NRF_FICR->BLE_1MBIT[4];
}
#endif // NRF51
// Initializing code below is quite generic - for BLE, the values are fixed, and expressions
// are constant. Non-constant values are essentially set in radio_prepare().
if (((m_tx_power & 0x03) != 0) || // tx_power should be a multiple of 4
((m_tx_power & 0xffffff00) != 0) || // Upper 24 bits are required to be zeroed
((int8_t)m_tx_power > 4) || // Max tx_power is +4 dBm
((int8_t)(m_tx_power & 0xff) < -40) || // Min tx_power is -40 dBm
(m_radio_mode > RADIO_MODE_MODE_Ble_1Mbit) // Values 0-2: Proprietary mode, 3 (last valid): BLE
)
{
return DTM_ERROR_ILLEGAL_CONFIGURATION;
}
// Turn off radio before configuring it
radio_reset();
NRF_RADIO->TXPOWER = m_tx_power;
NRF_RADIO->MODE = m_radio_mode << RADIO_MODE_MODE_Pos;
// Set the access address, address0/prefix0 used for both Rx and Tx address
NRF_RADIO->PREFIX0 &= ~RADIO_PREFIX0_AP0_Msk;
NRF_RADIO->PREFIX0 |= (m_address >> 24) & RADIO_PREFIX0_AP0_Msk;
NRF_RADIO->BASE0 = m_address << 8;
NRF_RADIO->RXADDRESSES = RADIO_RXADDRESSES_ADDR0_Enabled << RADIO_RXADDRESSES_ADDR0_Pos;
NRF_RADIO->TXADDRESS = (0x00 << RADIO_TXADDRESS_TXADDRESS_Pos) & RADIO_TXADDRESS_TXADDRESS_Msk;
// Configure CRC calculation
NRF_RADIO->CRCCNF = (m_crcConfSkipAddr << RADIO_CRCCNF_SKIP_ADDR_Pos) |
(m_crcLength << RADIO_CRCCNF_LEN_Pos);
NRF_RADIO->PCNF0 = (m_packetHeaderS1len << RADIO_PCNF0_S1LEN_Pos) |
(m_packetHeaderS0len << RADIO_PCNF0_S0LEN_Pos) |
(m_packetHeaderLFlen << RADIO_PCNF0_LFLEN_Pos);
NRF_RADIO->PCNF1 = (m_whitening << RADIO_PCNF1_WHITEEN_Pos) |
(m_endian << RADIO_PCNF1_ENDIAN_Pos) |
(m_balen << RADIO_PCNF1_BALEN_Pos) |
(m_static_length << RADIO_PCNF1_STATLEN_Pos) |
(DTM_PAYLOAD_MAX_SIZE << RADIO_PCNF1_MAXLEN_Pos);
return DTM_SUCCESS;
}
/**@brief Function for preparing the radio. At start of each test: Turn off RF, clear interrupt flags of RF, initialize the radio
* at given RF channel.
*
*@param[in] rx boolean indicating if radio should be prepared in rx mode (true) or tx mode.
*/
static void radio_prepare(bool rx)
{
#ifdef NRF51
NRF_RADIO->TEST = 0;
#elif defined(NRF52)
NRF_RADIO->MODECNF0 = (RADIO_MODECNF0_RU_Default << RADIO_MODECNF0_RU_Pos) |
(RADIO_MODECNF0_DTX_B1 << RADIO_MODECNF0_DTX_Pos);
#endif // NRF51 / NRF52
NRF_RADIO->CRCPOLY = m_crc_poly;
NRF_RADIO->CRCINIT = m_crc_init;
NRF_RADIO->FREQUENCY = (m_phys_ch << 1) + 2; // Actual frequency (MHz): 2400 + register value
NRF_RADIO->PACKETPTR = (uint32_t)&m_pdu; // Setting packet pointer will start the radio
NRF_RADIO->EVENTS_READY = 0;
NRF_RADIO->SHORTS = (1 << RADIO_SHORTS_READY_START_Pos) | // Shortcut between READY event and START task
(1 << RADIO_SHORTS_END_DISABLE_Pos); // Shortcut between END event and DISABLE task
if (rx)
{
NRF_RADIO->EVENTS_END = 0;
NRF_RADIO->TASKS_RXEN = 1; // shorts will start radio in RX mode when it is ready
}
else // tx
{
NRF_RADIO->TXPOWER = m_tx_power;
}
}
/**@brief Function for terminating the ongoing test (if any) and closing down the radio.
*/
static void dtm_test_done(void)
{
#ifdef NRF51
NRF_RADIO->TEST = 0;
#elif defined(NRF52)
NRF_RADIO->MODECNF0 = (RADIO_MODECNF0_RU_Default << RADIO_MODECNF0_RU_Pos) |
(RADIO_MODECNF0_DTX_B1 << RADIO_MODECNF0_DTX_Pos);
#endif // NRF51 / NRF52
NRF_PPI->CHENCLR = 0x01;
NRF_PPI->CH[0].EEP = 0; // Break connection from timer to radio to stop transmit loop
NRF_PPI->CH[0].TEP = 0;
radio_reset();
m_state = STATE_IDLE;
}
/**@brief Function for configuring the timer for 625us cycle time.
*/
static uint32_t timer_init(void)
{
// Use 16MHz from external crystal
// This could be customized for RC/Xtal, or even to use a 32 kHz crystal
NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
NRF_CLOCK->TASKS_HFCLKSTART = 1;
while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0)
{
// Do nothing while waiting for the clock to start
}
mp_timer->TASKS_STOP = 1; // Stop timer, if it was running
mp_timer->TASKS_CLEAR = 1;
mp_timer->MODE = TIMER_MODE_MODE_Timer; // Timer mode (not counter)
mp_timer->EVENTS_COMPARE[0] = 0; // clean up possible old events
mp_timer->EVENTS_COMPARE[1] = 0;
mp_timer->EVENTS_COMPARE[2] = 0;
mp_timer->EVENTS_COMPARE[3] = 0;
// Timer is polled, but enable the compare0 interrupt in order to wakeup from CPU sleep
mp_timer->INTENSET = TIMER_INTENSET_COMPARE0_Msk;
mp_timer->SHORTS = 1 << TIMER_SHORTS_COMPARE0_CLEAR_Pos; // Clear the count every time timer reaches the CCREG0 count
mp_timer->PRESCALER = 4; // Input clock is 16MHz, timer clock = 2 ^ prescale -> interval 1us
mp_timer->CC[0] = m_txIntervaluS; // 625uS with 1MHz clock to the timer
mp_timer->CC[1] = UART_POLL_CYCLE; // 260uS with 1MHz clock to the timer
mp_timer->TASKS_START = 1; // Start the timer - it will be running continuously
m_current_time = 0;
return DTM_SUCCESS;
}
/**@brief Function for handling vendor specific commands.
* Used when packet type is set to Vendor specific.
* The length field is used for encoding vendor specific command.
* The frequency field is used for encoding vendor specific options to the command.
*
* @param[in] vendor_cmd Vendor specific command to be executed.
* @param[in] vendor_option Vendor specific option to the vendor command.
*
* @return DTM_SUCCESS or one of the DTM_ERROR_ values
*/
static uint32_t dtm_vendor_specific_pkt(uint32_t vendor_cmd, dtm_freq_t vendor_option)
{
switch (vendor_cmd)
{
// nRFgo Studio uses CARRIER_TEST_STUDIO to indicate a continuous carrier without
// a modulated signal.
case CARRIER_TEST:
case CARRIER_TEST_STUDIO:
// Not a packet type, but used to indicate that a continuous carrier signal
// should be transmitted by the radio.
radio_prepare(TX_MODE);
#ifdef NRF51
NRF_RADIO->TEST = (RADIO_TEST_PLL_LOCK_Enabled << RADIO_TEST_PLL_LOCK_Pos) |
(RADIO_TEST_CONST_CARRIER_Enabled << RADIO_TEST_CONST_CARRIER_Pos);
#elif defined(NRF52)
NRF_RADIO->MODECNF0 = (RADIO_MODECNF0_RU_Default << RADIO_MODECNF0_RU_Pos) |
(RADIO_MODECNF0_DTX_B1 << RADIO_MODECNF0_DTX_Pos);
#endif // NRF51 / NRF52
// Shortcut between READY event and START task
NRF_RADIO->SHORTS = 1 << RADIO_SHORTS_READY_START_Pos;
// Shortcut will start radio in Tx mode when it is ready
NRF_RADIO->TASKS_TXEN = 1;
m_state = STATE_CARRIER_TEST;
break;
case SET_TX_POWER:
if (!dtm_set_txpower(vendor_option))
{
return DTM_ERROR_ILLEGAL_CONFIGURATION;
}
break;
case SELECT_TIMER:
if (!dtm_set_timer(vendor_option))
{
return DTM_ERROR_ILLEGAL_CONFIGURATION;
}
break;
}
// Event code is unchanged, successful
return DTM_SUCCESS;
}
uint32_t dtm_init(void)
{
if ((timer_init() != DTM_SUCCESS) || (radio_init() != DTM_SUCCESS))
{
return DTM_ERROR_ILLEGAL_CONFIGURATION;
}
m_new_event = false;
m_state = STATE_IDLE;
// Enable wake-up on event
SCB->SCR |= SCB_SCR_SEVONPEND_Msk;
return DTM_SUCCESS;
}
uint32_t dtm_wait(void)
{
// Enable wake-up on event
SCB->SCR |= SCB_SCR_SEVONPEND_Msk;
for (;;)
{
// Event may be the reception of a packet -
// handle radio first, to give it highest priority:
if (NRF_RADIO->EVENTS_END != 0)
{
NRF_RADIO->EVENTS_END = 0;
NVIC_ClearPendingIRQ(RADIO_IRQn);
if (m_state == STATE_RECEIVER_TEST)
{
NRF_RADIO->TASKS_RXEN = 1;
if ((NRF_RADIO->CRCSTATUS == 1) && check_pdu())
{
// Count the number of successfully received packets
m_rx_pkt_count++;
}
// Note that failing packets are simply ignored (CRC or contents error).
// Zero fill all pdu fields to avoid stray data
memset(&m_pdu, 0, DTM_PDU_MAX_MEMORY_SIZE);
}
// If no RECEIVER_TEST is running, ignore incoming packets (but do clear IRQ!)
}
// Check for timeouts:
if (mp_timer->EVENTS_COMPARE[0] != 0)
{
mp_timer->EVENTS_COMPARE[0] = 0;
}
else if (mp_timer->EVENTS_COMPARE[1] != 0)
{
// Reset timeout event flag for next iteration.
mp_timer->EVENTS_COMPARE[1] = 0;
NVIC_ClearPendingIRQ(m_timer_irq);
return ++m_current_time;
}
// Other events: No processing
}
}
uint32_t dtm_cmd(dtm_cmd_t cmd, dtm_freq_t freq, uint32_t length, dtm_pkt_type_t payload)
{
// Save specified packet in static variable for tx/rx functions to use.
// Note that BLE conformance testers always use full length packets.
m_packet_length = ((uint8_t)length & 0xFF);
m_packet_type = payload;
m_phys_ch = freq;
// Clean out any non-retrieved event that might linger from an earlier test
m_new_event = true;
// Set default event; any error will set it to LE_TEST_STATUS_EVENT_ERROR
m_event = LE_TEST_STATUS_EVENT_SUCCESS;
if (m_state == STATE_UNINITIALIZED)
{
// Application has not explicitly initialized DTM,
return DTM_ERROR_UNINITIALIZED;
}
if (cmd == LE_RESET)
{
// Note that timer will continue running after a reset
dtm_test_done();
return DTM_SUCCESS;
}
if (cmd == LE_TEST_END)
{
if (m_state == STATE_IDLE)
{
// Sequencing error - only rx or tx test may be ended!
m_event = LE_TEST_STATUS_EVENT_ERROR;
return DTM_ERROR_INVALID_STATE;
}
m_event = LE_PACKET_REPORTING_EVENT | m_rx_pkt_count;
dtm_test_done();
return DTM_SUCCESS;
}
if (m_state != STATE_IDLE)
{
// Sequencing error - only TEST_END/RESET are legal while test is running
// Note: State is unchanged; ongoing test not affected
m_event = LE_TEST_STATUS_EVENT_ERROR;
return DTM_ERROR_INVALID_STATE;
}
if (m_phys_ch > PHYS_CH_MAX)
{
// Parameter error
// Note: State is unchanged; ongoing test not affected
m_event = LE_TEST_STATUS_EVENT_ERROR;
return DTM_ERROR_ILLEGAL_CHANNEL;
}
m_rx_pkt_count = 0;
if (cmd == LE_RECEIVER_TEST)
{
// Zero fill all pdu fields to avoid stray data from earlier test run
memset(&m_pdu, 0, DTM_PDU_MAX_MEMORY_SIZE);
radio_prepare(RX_MODE); // Reinitialize "everything"; RF interrupts OFF
m_state = STATE_RECEIVER_TEST;
return DTM_SUCCESS;
}
if (cmd == LE_TRANSMITTER_TEST)
{
if (m_packet_length > DTM_PAYLOAD_MAX_SIZE)
{
// Parameter error
m_event = LE_TEST_STATUS_EVENT_ERROR;
return DTM_ERROR_ILLEGAL_LENGTH;
}
// Note that PDU uses 4 bits even though BLE DTM uses only 2 (the HCI SDU uses all 4)
m_pdu.content[DTM_HEADER_OFFSET] = ((uint8_t)m_packet_type & 0x0F);
m_pdu.content[DTM_LENGTH_OFFSET] = m_packet_length;
switch (m_packet_type)
{
case DTM_PKT_PRBS9:
// Non-repeated, must copy entire pattern to PDU
memcpy(m_pdu.content + DTM_HEADER_SIZE, m_prbs_content, length);
break;
case DTM_PKT_0X0F:
// Bit pattern 00001111 repeated
memset(m_pdu.content + DTM_HEADER_SIZE, RFPHY_TEST_0X0F_REF_PATTERN, length);
break;
case DTM_PKT_0X55:
// Bit pattern 01010101 repeated
memset(m_pdu.content + DTM_HEADER_SIZE, RFPHY_TEST_0X55_REF_PATTERN, length);
break;
case DTM_PKT_VENDORSPECIFIC:
// The length field is for indicating the vendor specific command to execute.
// The frequency field is used for vendor specific options to the command.
return dtm_vendor_specific_pkt(length, freq);
default:
// Parameter error
m_event = LE_TEST_STATUS_EVENT_ERROR;
return DTM_ERROR_ILLEGAL_CONFIGURATION;
}
// Initialize CRC value, set channel:
radio_prepare(TX_MODE);
// Configure PPI so that timer will activate radio every 625 us
NRF_PPI->CH[0].EEP = (uint32_t)&mp_timer->EVENTS_COMPARE[0];
NRF_PPI->CH[0].TEP = (uint32_t)&NRF_RADIO->TASKS_TXEN;
NRF_PPI->CHENSET = 0x01;
m_state = STATE_TRANSMITTER_TEST;
}
return DTM_SUCCESS;
}
bool dtm_event_get(dtm_event_t *p_dtm_event)
{
bool was_new = m_new_event;
// mark the current event as retrieved
m_new_event = false;
*p_dtm_event = m_event;
// return value indicates whether this value was already retrieved.
return was_new;
}
// =================================================================================================
// Configuration functions (only for parameters not definitely determined by the BLE DTM standard).
// These functions return true if successful, false if value could not be set
/**@brief Function for configuring the output power for transmitter test.
This function may be called directly, or through dtm_cmd() specifying
DTM_PKT_VENDORSPECIFIC as payload, SET_TX_POWER as length, and the dBm value as frequency.
*/
bool dtm_set_txpower(uint32_t new_tx_power)
{
// radio->TXPOWER register is 32 bits, low octet a signed value, upper 24 bits zeroed
int8_t new_power8 = (int8_t)(new_tx_power & 0xFF);
if (m_state > STATE_IDLE)
{
// radio must be idle to change the tx power
return false;
}
if ((new_power8 > 4) || (new_power8 < -40))
{
// Parameter outside valid range: nRF radio is restricted to the range -40 dBm to +4 dBm
return false;
}
if (new_tx_power & 0x03)
{
// Parameter error: The nRF51 radio requires settings that are a multiple of 4.
return false;
}
m_tx_power = new_tx_power;
return true;
}
/**@brief Function for selecting a timer resource.
* This function may be called directly, or through dtm_cmd() specifying
* DTM_PKT_VENDORSPECIFIC as payload, SELECT_TIMER as length, and the timer as freq
*
* @param[in] new_timer Timer id for the timer to use: 0, 1, or 2.
*
* @return true if the timer was successfully changed, false otherwise.
*/
bool dtm_set_timer(uint32_t new_timer)
{
if (m_state > STATE_IDLE)
{
return false;
}
if (new_timer == 0)
{
mp_timer = NRF_TIMER0;
m_timer_irq = TIMER0_IRQn;
}
else if (new_timer == 1)
{
mp_timer = NRF_TIMER1;
m_timer_irq = TIMER1_IRQn;
}
else if (new_timer == 2)
{
mp_timer = NRF_TIMER2;
m_timer_irq = TIMER2_IRQn;
}
else
{
// Parameter error: Only TIMER 0, 1, 2 provided by nRF51
return false;
}
// New timer has been selected:
return true;
}
/// @}

View File

@ -0,0 +1,141 @@
/* 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.
*
*/
/** @file
*
* @defgroup ble_sdk_dtmlib_dtm DTM - Direct Test Mode
* @{
* @ingroup ble_sdk_lib
* @brief Module for testing RF/PHY using DTM commands.
*/
#ifndef BLE_DTM_H__
#define BLE_DTM_H__
#include <stdint.h>
#include <stdbool.h>
/**@brief Configuration parameters. */
#define DEFAULT_TX_POWER RADIO_TXPOWER_TXPOWER_0dBm /**< Default Transmission power using in the DTM module. */
#define DEFAULT_TIMER NRF_TIMER0 /**< Default timer used for timing. */
#define DEFAULT_TIMER_IRQn TIMER0_IRQn /**< IRQ used for timer. NOTE: MUST correspond to DEFAULT_TIMER. */
/**@brief BLE DTM command codes. */
typedef uint32_t dtm_cmd_t; /**< DTM command type. */
#define LE_RESET 0 /**< DTM command: Reset device. */
#define LE_RECEIVER_TEST 1 /**< DTM command: Start receive test. */
#define LE_TRANSMITTER_TEST 2 /**< DTM command: Start transmission test. */
#define LE_TEST_END 3 /**< DTM command: End test and send packet report. */
// Configuration options used as parameter 2
// when cmd == LE_TRANSMITTER_TEST and payload == DTM_PKT_VENDORSPECIFIC
// Configuration value, if any, is supplied in parameter 3
#define CARRIER_TEST 0 /**< Length=0 indicates a constant, unmodulated carrier until LE_TEST_END or LE_RESET */
#define CARRIER_TEST_STUDIO 1 /**< nRFgo Studio uses value 1 in length field, to indicate a constant, unmodulated carrier until LE_TEST_END or LE_RESET */
#define SET_TX_POWER 2 /**< Set transmission power, value -40..+4 dBm in steps of 4 */
#define SELECT_TIMER 3 /**< Select on of the 16 MHz timers 0, 1 or 2 */
#define LE_PACKET_REPORTING_EVENT 0x8000 /**< DTM Packet reporting event, returned by the device to the tester. */
#define LE_TEST_STATUS_EVENT_SUCCESS 0x0000 /**< DTM Status event, indicating success. */
#define LE_TEST_STATUS_EVENT_ERROR 0x0001 /**< DTM Status event, indicating an error. */
#define DTM_PKT_PRBS9 0x00 /**< Bit pattern PRBS9. */
#define DTM_PKT_0X0F 0x01 /**< Bit pattern 11110000 (LSB is the leftmost bit). */
#define DTM_PKT_0X55 0x02 /**< Bit pattern 10101010 (LSB is the leftmost bit). */
#define DTM_PKT_VENDORSPECIFIC 0xFFFFFFFF /**< Vendor specific. Nordic: Continuous carrier test, or configuration. */
/**@brief Return codes from dtm_cmd(). */
#define DTM_SUCCESS 0x00 /**< Indicate that the DTM function completed with success. */
#define DTM_ERROR_ILLEGAL_CHANNEL 0x01 /**< Physical channel number must be in the range 0..39. */
#define DTM_ERROR_INVALID_STATE 0x02 /**< Sequencing error: Command is not valid now. */
#define DTM_ERROR_ILLEGAL_LENGTH 0x03 /**< Payload size must be in the range 0..37. */
#define DTM_ERROR_ILLEGAL_CONFIGURATION 0x04 /**< Parameter out of range (legal range is function dependent). */
#define DTM_ERROR_UNINITIALIZED 0x05 /**< DTM module has not been initialized by the application. */
// Note: DTM_PKT_VENDORSPECIFIC, is not a packet type
#define PACKET_TYPE_MAX DTM_PKT_0X55 /**< Highest value allowed as DTM Packet type. */
/** @brief BLE DTM event type. */
typedef uint32_t dtm_event_t; /**< Type for handling DTM event. */
/** @brief BLE DTM frequency type. */
typedef uint32_t dtm_freq_t; /**< Physical channel, valid range: 0..39. */
/**@brief BLE DTM packet types. */
typedef uint32_t dtm_pkt_type_t; /**< Type for holding the requested DTM payload type.*/
/**@brief Function for initializing or re-initializing DTM module
*
* @return DTM_SUCCESS on successful initialization of the DTM module.
*/
uint32_t dtm_init(void);
/**@brief Function for giving control to dtmlib for handling timer and radio events.
* Will return to caller at 625us intervals or whenever another event than radio occurs
* (such as UART input). Function will put MCU to sleep between events.
*
* @return Time counter, incremented every 625 us.
*/
uint32_t dtm_wait(void);
/**@brief Function for calling when a complete command has been prepared by the Tester.
*
* @param[in] cmd One of the DTM_CMD values (bits 14:15 in the 16-bit UART format).
* @param[in] freq Phys. channel no - actual frequency = (2402 + freq * 2) MHz (bits 8:13 in
* the 16-bit UART format).
* @param[in] length Payload length, 0..37 (bits 2:7 in the 16-bit UART format).
* @param[in] payload One of the DTM_PKT values (bits 0:1 in the 16-bit UART format).
*
* @return DTM_SUCCESS or one of the DTM_ERROR_ values
*/
uint32_t dtm_cmd(dtm_cmd_t cmd, dtm_freq_t freq, uint32_t length, dtm_pkt_type_t payload);
/**@brief Function for reading the result of a DTM command
*
* @param[out] p_dtm_event Pointer to buffer for 16 bit event code according to DTM standard.
*
* @return true: new event, false: no event since last call, this event has been read earlier
*/
bool dtm_event_get(dtm_event_t * p_dtm_event);
/**@brief Function for configuring the timer to use.
*
* @note Must be called when no DTM test is running.
*
* @param[in] new_timer Index (0..2) of timer to be used by the DTM library
*
* @return true: success, new timer was selected, false: parameter error
*/
bool dtm_set_timer(uint32_t new_timer);
/**@brief Function for configuring the transmit power.
*
* @note Must be called when no DTM test is running.
*
* @param[in] new_tx_power New output level, +4..-40, in steps of 4.
*
* @return true: tx power setting changed, false: parameter error
*/
bool dtm_set_txpower(uint32_t new_tx_power);
#endif // BLE_DTM_H__
/** @} */

View File

@ -0,0 +1,58 @@
/* 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 <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <nrf.h>
#include "ble_error_log.h"
#include "app_util.h"
#include "app_error.h"
#include "nrf_gpio.h"
#include "pstorage.h"
// Made static to avoid the error_log to go on the stack.
static ble_error_log_data_t m_ble_error_log; /**< . */
//lint -esym(526,__Vectors)
extern uint32_t * __Vectors; /**< The initialization vector holds the address to __initial_sp that will be used when fetching the stack. */
static void fetch_stack(ble_error_log_data_t * error_log)
{
uint32_t * p_stack;
uint32_t * initial_sp;
uint32_t length;
initial_sp = (uint32_t *) __Vectors;
p_stack = (uint32_t *) GET_SP();
length = ((uint32_t) initial_sp) - ((uint32_t) p_stack);
memcpy(error_log->stack_info,
p_stack,
(length > STACK_DUMP_LENGTH) ? STACK_DUMP_LENGTH : length);
}
uint32_t ble_error_log_write(uint32_t err_code, const uint8_t * p_message, uint16_t line_number)
{
m_ble_error_log.failure = true;
m_ble_error_log.err_code = err_code;
m_ble_error_log.line_number = line_number;
strncpy((char *)m_ble_error_log.message, (const char *)p_message, ERROR_MESSAGE_LENGTH - 1);
m_ble_error_log.message[ERROR_MESSAGE_LENGTH - 1] = '\0';
fetch_stack(&m_ble_error_log);
// Write to flash removed, to be redone.
return NRF_SUCCESS;
}

View File

@ -0,0 +1,69 @@
/* 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.
*
*/
/** @file
*
* @defgroup ble_error_log_module Error Log Module
* @{
* @ingroup ble_sdk_lib
* @brief Module for writing error and stack to flash memory.
*
* @details It contains functions for writing an error code, line number, filename/message and
* the stack to the flash during an error, e.g. in the assert handler.
*
*/
#ifndef BLE_ERROR_LOG_H__
#define BLE_ERROR_LOG_H__
#include <stdint.h>
#include <stdbool.h>
#include "ble_flash.h"
#define ERROR_MESSAGE_LENGTH 128 /**< Length of error message to stored. */
#define STACK_DUMP_LENGTH 256 /**< Length of stack to be stored at max: 64 entries of 4 bytes each. */
#define FLASH_PAGE_ERROR_LOG (BLE_FLASH_PAGE_END - 2) /**< Address in flash where stack trace can be stored. */
/**@brief Error Log Data structure.
*
* @details The structure contains the error, message/filename, line number as well as the current
* stack, at the time where an error occured.
*/
typedef struct
{
uint16_t failure; /**< Indication that a major failure has occurred during last execution of the application. */
uint16_t line_number; /**< Line number indicating at which line the failure occurred. */
uint32_t err_code; /**< Error code when failure occurred. */
uint8_t message[ERROR_MESSAGE_LENGTH]; /**< Will just use the first 128 bytes of filename to store for debugging purposes. */
uint32_t stack_info[STACK_DUMP_LENGTH / 4]; /**< Will contain stack information, can be manually unwinded for debug purposes. */
} ble_error_log_data_t;
/**@brief Function for writing the file name/message, line number, and current program stack
* to flash.
*
* @note This function will force the writing to flash, and disregard any radio communication.
* USE THIS FUNCTION WITH CARE.
*
* @param[in] err_code Error code to be logged.
* @param[in] p_message Message to be written to the flash together with stack dump, usually
* the file name where the error occured.
* @param[in] line_number Line number where the error occured.
*
* @return NRF_SUCCESS on successful writing of the error log.
*
*/
uint32_t ble_error_log_write(uint32_t err_code, const uint8_t * p_message, uint16_t line_number);
#endif /* BLE_ERROR_LOG_H__ */
/** @} */

View File

@ -0,0 +1,56 @@
/* 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 "ble_racp.h"
#include <stdlib.h>
void ble_racp_decode(uint8_t data_len, uint8_t * p_data, ble_racp_value_t * p_racp_val)
{
p_racp_val->opcode = 0xFF;
p_racp_val->operator = 0xFF;
p_racp_val->operand_len = 0;
p_racp_val->p_operand = NULL;
if (data_len > 0)
{
p_racp_val->opcode = p_data[0];
}
if (data_len > 1)
{
p_racp_val->operator = p_data[1]; //lint !e415
}
if (data_len > 2)
{
p_racp_val->operand_len = data_len - 2;
p_racp_val->p_operand = &p_data[2]; //lint !e416
}
}
uint8_t ble_racp_encode(const ble_racp_value_t * p_racp_val, uint8_t * p_data)
{
uint8_t len = 0;
int i;
if (p_data != NULL)
{
p_data[len++] = p_racp_val->opcode;
p_data[len++] = p_racp_val->operator;
for (i = 0; i < p_racp_val->operand_len; i++)
{
p_data[len++] = p_racp_val->p_operand[i];
}
}
return len;
}

View File

@ -0,0 +1,96 @@
/* 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.
*/
/** @file
*
* @defgroup ble_sdk_lib_racp Record Access Control Point
* @{
* @ingroup ble_sdk_lib
* @brief Record Access Control Point library.
*/
#ifndef BLE_RACP_H__
#define BLE_RACP_H__
#include <stdint.h>
#include <stdbool.h>
#include "ble.h"
#include "ble_types.h"
#include "ble.h"
/**@brief Record Access Control Point opcodes. */
#define RACP_OPCODE_RESERVED 0 /**< Record Access Control Point opcode - Reserved for future use. */
#define RACP_OPCODE_REPORT_RECS 1 /**< Record Access Control Point opcode - Report stored records. */
#define RACP_OPCODE_DELETE_RECS 2 /**< Record Access Control Point opcode - Delete stored records. */
#define RACP_OPCODE_ABORT_OPERATION 3 /**< Record Access Control Point opcode - Abort operation. */
#define RACP_OPCODE_REPORT_NUM_RECS 4 /**< Record Access Control Point opcode - Report number of stored records. */
#define RACP_OPCODE_NUM_RECS_RESPONSE 5 /**< Record Access Control Point opcode - Number of stored records response. */
#define RACP_OPCODE_RESPONSE_CODE 6 /**< Record Access Control Point opcode - Response code. */
/**@brief Record Access Control Point operators. */
#define RACP_OPERATOR_NULL 0 /**< Record Access Control Point operator - Null. */
#define RACP_OPERATOR_ALL 1 /**< Record Access Control Point operator - All records. */
#define RACP_OPERATOR_LESS_OR_EQUAL 2 /**< Record Access Control Point operator - Less than or equal to. */
#define RACP_OPERATOR_GREATER_OR_EQUAL 3 /**< Record Access Control Point operator - Greater than or equal to. */
#define RACP_OPERATOR_RANGE 4 /**< Record Access Control Point operator - Within range of (inclusive). */
#define RACP_OPERATOR_FIRST 5 /**< Record Access Control Point operator - First record (i.e. oldest record). */
#define RACP_OPERATOR_LAST 6 /**< Record Access Control Point operator - Last record (i.e. most recent record). */
#define RACP_OPERATOR_RFU_START 7 /**< Record Access Control Point operator - Start of Reserved for Future Use area. */
/**@brief Record Access Control Point response codes. */
#define RACP_RESPONSE_RESERVED 0 /**< Record Access Control Point response code - Reserved for future use. */
#define RACP_RESPONSE_SUCCESS 1 /**< Record Access Control Point response code - Successful operation. */
#define RACP_RESPONSE_OPCODE_UNSUPPORTED 2 /**< Record Access Control Point response code - Unsupported op code received. */
#define RACP_RESPONSE_INVALID_OPERATOR 3 /**< Record Access Control Point response code - Operator not valid for service. */
#define RACP_RESPONSE_OPERATOR_UNSUPPORTED 4 /**< Record Access Control Point response code - Unsupported operator. */
#define RACP_RESPONSE_INVALID_OPERAND 5 /**< Record Access Control Point response code - Operand not valid for service. */
#define RACP_RESPONSE_NO_RECORDS_FOUND 6 /**< Record Access Control Point response code - No matching records found. */
#define RACP_RESPONSE_ABORT_FAILED 7 /**< Record Access Control Point response code - Abort could not be completed. */
#define RACP_RESPONSE_PROCEDURE_NOT_DONE 8 /**< Record Access Control Point response code - Procedure could not be completed. */
#define RACP_RESPONSE_OPERAND_UNSUPPORTED 9 /**< Record Access Control Point response code - Unsupported operand. */
/**@brief Record Access Control Point value structure. */
typedef struct
{
uint8_t opcode; /**< Op Code. */
uint8_t operator; /**< Operator. */
uint8_t operand_len; /**< Length of the operand. */
uint8_t * p_operand; /**< Pointer to the operand. */
} ble_racp_value_t;
/**@brief Function for decoding a Record Access Control Point write.
*
* @details This call decodes a write to the Record Access Control Point.
*
* @param[in] data_len Length of data in received write.
* @param[in] p_data Pointer to received data.
* @param[out] p_racp_val Pointer to decoded Record Access Control Point write.
* @note This does not do a data copy. It assumes the data pointed to by
* p_data is persistant until no longer needed.
*/
void ble_racp_decode(uint8_t data_len, uint8_t * p_data, ble_racp_value_t * p_racp_val);
/**@brief Function for encoding a Record Access Control Point response.
*
* @details This call encodes a response from the Record Access Control Point response.
*
* @param[in] p_racp_val Pointer to Record Access Control Point to encode.
* @param[out] p_data Pointer to where encoded data is written.
* NOTE! It is calling routines respsonsibility to make sure.
*
* @return Length of encoded data.
*/
uint8_t ble_racp_encode(const ble_racp_value_t * p_racp_val, uint8_t * p_data);
#endif // BLE_RACP_H__
/** @} */

View File

@ -0,0 +1,812 @@
/* 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.
*/
/* Disclaimer: This client implementation of the Apple Notification Center Service can and will be changed at any time by Nordic Semiconductor ASA.
* Server implementations such as the ones found in iOS can be changed at any time by Apple and may cause this client implementation to stop working.
*/
#include "ble_ancs_c.h"
#include "ble_err.h"
#include "ble_srv_common.h"
#include "nrf_assert.h"
#include "device_manager.h"
#include "ble_db_discovery.h"
#include "app_error.h"
#include "app_trace.h"
#include "sdk_common.h"
#define BLE_ANCS_NOTIF_EVT_ID_INDEX 0 /**< Index of the Event ID field when parsing notifications. */
#define BLE_ANCS_NOTIF_FLAGS_INDEX 1 /**< Index of the Flags field when parsing notifications. */
#define BLE_ANCS_NOTIF_CATEGORY_ID_INDEX 2 /**< Index of the Category ID field when parsing notifications. */
#define BLE_ANCS_NOTIF_CATEGORY_CNT_INDEX 3 /**< Index of the Category Count field when parsing notifications. */
#define BLE_ANCS_NOTIF_NOTIF_UID 4 /**< Index of the Notification UID field when patsin notifications. */
#define ANCS_LOG NRF_LOG_PRINTF_DEBUG /**< Debug logger macro that will be used in this file to do logging of important information over UART. */
#define START_HANDLE_DISCOVER 0x0001 /**< Value of start handle during discovery. */
#define TX_BUFFER_MASK 0x07 /**< TX buffer mask. Must be a mask of contiguous zeroes followed by a contiguous sequence of ones: 000...111. */
#define TX_BUFFER_SIZE (TX_BUFFER_MASK + 1) /**< Size of send buffer, which is 1 higher than the mask. */
#define WRITE_MESSAGE_LENGTH 20 /**< Length of the write message for CCCD/control point. */
#define BLE_CCCD_NOTIFY_BIT_MASK 0x0001 /**< Enable notification bit. */
#define BLE_ANCS_MAX_DISCOVERED_CENTRALS DEVICE_MANAGER_MAX_BONDS /**< Maximum number of discovered services that can be stored in the flash. This number should be identical to maximum number of bonded peer devices. */
#define TIME_STRING_LEN 15 /**< Unicode Technical Standard (UTS) #35 date format pattern "yyyyMMdd'T'HHmmSS" + "'\0'". */
#define DISCOVERED_SERVICE_DB_SIZE \
CEIL_DIV(sizeof(ble_ancs_c_service_t) * BLE_ANCS_MAX_DISCOVERED_CENTRALS, sizeof(uint32_t)) /**< Size of bonded peer's database in word size (4 byte). */
/**@brief ANCS request types.
*/
typedef enum
{
READ_REQ = 1, /**< Type identifying that this tx_message is a read request. */
WRITE_REQ /**< Type identifying that this tx_message is a write request. */
} ancs_tx_request_t;
/**@brief Structure for writing a message to the central, i.e. Control Point or CCCD.
*/
typedef struct
{
uint8_t gattc_value[WRITE_MESSAGE_LENGTH]; /**< The message to write. */
ble_gattc_write_params_t gattc_params; /**< GATTC parameters for this message. */
} write_params_t;
/**@brief Structure for holding data to be transmitted to the connected master.
*/
typedef struct
{
uint16_t conn_handle; /**< Connection handle to be used when transmitting this message. */
ancs_tx_request_t type; /**< Type of this message, i.e. read or write message. */
union
{
uint16_t read_handle; /**< Read request message. */
write_params_t write_req; /**< Write request message. */
} req;
} tx_message_t;
static tx_message_t m_tx_buffer[TX_BUFFER_SIZE]; /**< Transmit buffer for messages to be transmitted to the Notification Provider. */
static uint32_t m_tx_insert_index = 0; /**< Current index in the transmit buffer where the next message should be inserted. */
static uint32_t m_tx_index = 0; /**< Current index in the transmit buffer from where the next message to be transmitted resides. */
/**@brief 128-bit service UUID for the Apple Notification Center Service.
*/
const ble_uuid128_t ble_ancs_base_uuid128 =
{
{
// 7905F431-B5CE-4E99-A40F-4B1E122D00D0
0xd0, 0x00, 0x2d, 0x12, 0x1e, 0x4b, 0x0f, 0xa4,
0x99, 0x4e, 0xce, 0xb5, 0x31, 0xf4, 0x05, 0x79
}
};
/**@brief 128-bit control point UUID.
*/
const ble_uuid128_t ble_ancs_cp_base_uuid128 =
{
{
// 69d1d8f3-45e1-49a8-9821-9BBDFDAAD9D9
0xd9, 0xd9, 0xaa, 0xfd, 0xbd, 0x9b, 0x21, 0x98,
0xa8, 0x49, 0xe1, 0x45, 0xf3, 0xd8, 0xd1, 0x69
}
};
/**@brief 128-bit notification source UUID.
*/
const ble_uuid128_t ble_ancs_ns_base_uuid128 =
{
{
// 9FBF120D-6301-42D9-8C58-25E699A21DBD
0xbd, 0x1d, 0xa2, 0x99, 0xe6, 0x25, 0x58, 0x8c,
0xd9, 0x42, 0x01, 0x63, 0x0d, 0x12, 0xbf, 0x9f
}
};
/**@brief 128-bit data source UUID.
*/
const ble_uuid128_t ble_ancs_ds_base_uuid128 =
{
{
// 22EAC6E9-24D6-4BB5-BE44-B36ACE7C7BFB
0xfb, 0x7b, 0x7c, 0xce, 0x6a, 0xb3, 0x44, 0xbe,
0xb5, 0x4b, 0xd6, 0x24, 0xe9, 0xc6, 0xea, 0x22
}
};
/**@brief Function for handling Disconnected event received from the SoftDevice.
*
* @details This function check if the disconnect event is happening on the link
* associated with the current instance of the module, if so it will set its
* conn_handle to invalid.
*
* @param[in] p_ancs Pointer to the ANCS client structure.
* @param[in] p_ble_evt Pointer to the BLE event received.
*/
static void on_disconnected(ble_ancs_c_t * p_ancs, const ble_evt_t * p_ble_evt)
{
if (p_ancs->conn_handle == p_ble_evt->evt.gap_evt.conn_handle)
{
p_ancs->conn_handle = BLE_CONN_HANDLE_INVALID;
}
}
void ble_ancs_c_on_db_disc_evt(ble_ancs_c_t * p_ancs, ble_db_discovery_evt_t * p_evt)
{
ANCS_LOG("[ANCS]: Database Discovery handler called with event 0x%x\r\n", p_evt->evt_type);
ble_ancs_c_evt_t evt;
ble_gatt_db_char_t * p_chars;
p_chars = p_evt->params.discovered_db.charateristics;
// Check if the ANCS Service was discovered.
if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE &&
p_evt->params.discovered_db.srv_uuid.uuid == ANCS_UUID_SERVICE &&
p_evt->params.discovered_db.srv_uuid.type == p_ancs->service.service.uuid.type)
{
// Find the handles of the ANCS characteristic.
uint32_t i;
for (i = 0; i < p_evt->params.discovered_db.char_count; i++)
{
switch (p_chars[i].characteristic.uuid.uuid)
{
case ANCS_UUID_CHAR_CONTROL_POINT:
ANCS_LOG("[ANCS]: Control Point Characteristic found.\n\r");
memcpy(&evt.service.control_point_char,
&p_chars[i].characteristic,
sizeof(ble_gattc_char_t));
break;
case ANCS_UUID_CHAR_DATA_SOURCE:
ANCS_LOG("[ANCS]: Data Source Characteristic found.\n\r");
memcpy(&evt.service.data_source_char,
&p_chars[i].characteristic,
sizeof(ble_gattc_char_t));
evt.service.data_source_cccd.handle = p_chars[i].cccd_handle;
break;
case ANCS_UUID_CHAR_NOTIFICATION_SOURCE:
ANCS_LOG("[ANCS]: Notification point Characteristic found.\n\r");
memcpy(&evt.service.notif_source_char,
&p_chars[i].characteristic,
sizeof(ble_gattc_char_t));
evt.service.notif_source_cccd.handle = p_chars[i].cccd_handle;
break;
default:
break;
}
}
evt.evt_type = BLE_ANCS_C_EVT_DISCOVERY_COMPLETE;
evt.conn_handle = p_evt->conn_handle;
p_ancs->evt_handler(&evt);
}
else
{
evt.evt_type = BLE_ANCS_C_EVT_DISCOVERY_FAILED;
p_ancs->evt_handler(&evt);
}
}
/**@brief Function for passing any pending request from the buffer to the stack.
*/
static void tx_buffer_process(void)
{
if (m_tx_index != m_tx_insert_index)
{
uint32_t err_code;
if (m_tx_buffer[m_tx_index].type == READ_REQ)
{
err_code = sd_ble_gattc_read(m_tx_buffer[m_tx_index].conn_handle,
m_tx_buffer[m_tx_index].req.read_handle,
0);
}
else
{
err_code = sd_ble_gattc_write(m_tx_buffer[m_tx_index].conn_handle,
&m_tx_buffer[m_tx_index].req.write_req.gattc_params);
}
if (err_code == NRF_SUCCESS)
{
++m_tx_index;
m_tx_index &= TX_BUFFER_MASK;
}
}
}
/**@brief Function for parsing command id and notification id.
* Used in the @ref parse_get_notif_attrs_response state machine.
*
* @details UID and command ID will be received only once at the beginning of the first
* GATTC notification of a new attribute request for a given iOS notification.
*
* @param[in] p_ancs Pointer to an ANCS instance to which the event belongs.
* @param[in] p_data_src Pointer to data that was received from the Notification Provider.
* @param[in] index Pointer to an index that helps us keep track of the current data to be parsed.
*
* @return The next parse state.
*/
static ble_ancs_c_parse_state_t command_id_and_notif_parse(ble_ancs_c_t * p_ancs,
const uint8_t * p_data_src,
uint32_t * index)
{
ble_ancs_c_command_id_values_t command_id;
command_id = (ble_ancs_c_command_id_values_t) p_data_src[(*index)++];
if(command_id != BLE_ANCS_COMMAND_ID_GET_NOTIF_ATTRIBUTES)
{
ANCS_LOG("[ANCS]: Invalid Command ID");
return DONE;
}
p_ancs->evt.attr.notif_uid = uint32_decode(&p_data_src[*index]);
*index += sizeof(uint32_t);
return ATTR_ID;
}
/**@brief Function for parsing the id of an iOS attribute.
* Used in the @ref parse_get_notif_attrs_response state machine.
*
* @details We only request attributes that are registered with @ref ble_ancs_c_attr_add
* once they have been reveiced we stop parsing.
*
* @param[in] p_ancs Pointer to an ANCS instance to which the event belongs.
* @param[in] p_data_src Pointer to data that was received from the Notification Provider.
* @param[in] index Pointer to an index that helps us keep track of the current data to be parsed.
*
* @return The next parse state.
*/
static ble_ancs_c_parse_state_t attr_id_parse(ble_ancs_c_t * p_ancs,
const uint8_t * p_data_src,
uint32_t * index)
{
p_ancs->evt.attr.attr_id = (ble_ancs_c_notif_attr_id_values_t) p_data_src[(*index)++];
p_ancs->evt.attr.p_attr_data = p_ancs->ancs_attr_list[p_ancs->evt.attr.attr_id].p_attr_data;
if (p_ancs->expected_number_of_attrs == 0)
{
ANCS_LOG("[ANCS]: All requested attributes received\n\r");
// (*index)++;
return DONE;
}
else if (p_ancs->ancs_attr_list[p_ancs->evt.attr.attr_id].get == true)
{
ANCS_LOG("[ANCS]: Attribute ID %i \n\r", p_ancs->evt.attr.attr_id);
return ATTR_LEN1;
}
else
{
p_ancs->expected_number_of_attrs--;
return ATTR_ID;
}
}
/**@brief Function for parsing the length of an iOS attribute.
* Used in the @ref parse_get_notif_attrs_response state machine.
*
* @details The Length is 2 bytes. Since there is a chance we reveice the bytes in two different
* GATTC notifications, we parse only the first byte here and then set the state machine
* ready to parse the next byte.
*
* @param[in] p_ancs Pointer to an ANCS instance to which the event belongs.
* @param[in] p_data_src Pointer to data that was received from the Notification Provider.
* @param[in] index Pointer to an index that helps us keep track of the current data to be parsed.
*
* @return The next parse state.
*/
static ble_ancs_c_parse_state_t attr_len1_parse(ble_ancs_c_t * p_ancs, const uint8_t * p_data_src, uint32_t * index)
{
p_ancs->evt.attr.attr_len = p_data_src[(*index)++];
return ATTR_LEN2;
}
/**@brief Function for parsing the length of an iOS attribute.
* Used in the @ref parse_get_notif_attrs_response state machine.
*
* @details Second byte of the length field. If the length is zero, it means that the attribute is not
* present and the state machine is set to parse the next attribute.
*
* @param[in] p_ancs Pointer to an ANCS instance to which the event belongs.
* @param[in] p_data_src Pointer to data that was received from the Notification Provider.
* @param[in] index Pointer to an index that helps us keep track of the current data to be parsed.
*
* @return The next parse state.
*/
static ble_ancs_c_parse_state_t attr_len2_parse(ble_ancs_c_t * p_ancs, const uint8_t * p_data_src, uint32_t * index)
{
p_ancs->evt.attr.attr_len |= (p_data_src[(*index)++] << 8);
p_ancs->current_attr_index = 0;
if (p_ancs->evt.attr.attr_len != 0)
{
return ATTR_DATA;
}
else
{
ANCS_LOG("[ANCS]: Attribute LEN %i \n\r", p_ancs->evt.attr.attr_len);
p_ancs->evt.evt_type = BLE_ANCS_C_EVT_NOTIF_ATTRIBUTE;
p_ancs->evt_handler(&p_ancs->evt);
return ATTR_ID;
}
}
/**@brief Function for parsing the data of an iOS attribute.
* Used in the @ref parse_get_notif_attrs_response state machine.
*
* @details Read the data of the attribute into our local buffer.
*
* @param[in] p_ancs Pointer to an ANCS instance to which the event belongs.
* @param[in] p_data_src Pointer to data that was received from the Notification Provider.
* @param[in] index Pointer to an index that helps us keep track of the current data to be parsed.
*
* @return The next parse state.
*/
static ble_ancs_c_parse_state_t attr_data_parse(ble_ancs_c_t * p_ancs, const uint8_t * p_data_src, uint32_t * index)
{
// We have not reached the end of the attribute, nor our max allocated internal size.
// Proceed with copying data over to our buffer.
if ( (p_ancs->current_attr_index < p_ancs->ancs_attr_list[p_ancs->evt.attr.attr_id].attr_len)
&& (p_ancs->current_attr_index < p_ancs->evt.attr.attr_len))
{
p_ancs->evt.attr.p_attr_data[p_ancs->current_attr_index++] = p_data_src[(*index)++];
}
// We have reached the end of the attribute, or our max allocated internal size.
// Stop copying data over to our buffer. NUL-terminate at the current index.
if ( (p_ancs->current_attr_index == p_ancs->evt.attr.attr_len) ||
(p_ancs->current_attr_index == p_ancs->ancs_attr_list[p_ancs->evt.attr.attr_id].attr_len))
{
p_ancs->evt.attr.p_attr_data[p_ancs->current_attr_index] = '\0';
// If our max buffer size is smaller than the remaining attribute data, we must
// increase index to skip the data until the start of the next attribute.
if (p_ancs->current_attr_index < p_ancs->evt.attr.attr_len)
{
(*index) += (p_ancs->evt.attr.attr_len - p_ancs->current_attr_index);
}
ANCS_LOG("[ANCS]: Attribute finished!\n\r");
p_ancs->evt.evt_type = BLE_ANCS_C_EVT_NOTIF_ATTRIBUTE;
p_ancs->evt_handler(&p_ancs->evt);
return ATTR_ID;
}
return ATTR_DATA;
}
/**@brief Function for parsing received notification attribute response data.
*
* @details The data that comes from the Notification Provider can be much longer than what
* would fit in a single GATTC notification. Therefore, this function relies on a
* state-oriented switch case.
* UID and command ID will be received only once at the beginning of the first
* GATTC notification of a new attribute request for a given iOS notification.
* After this, we can loop several ATTR_ID > LENGTH > DATA > ATTR_ID > LENGTH > DATA until
* we have received all attributes we wanted as a Notification Consumer.
* The Notification Provider can also simply stop sending attributes.
*
* |1 Byte | 4 Bytes |1 Byte |2 Bytes | X Bytes |1 Bytes| 2 Bytes| X Bytes
* +--------+-------------+-------+--------+- - - - - - - - - - +-------+--------+- - - - - - -
* | CMD_ID | NOTIF_UID |ATTR_ID| LENGTH | DATA |ATTR_ID| LENGTH | DATA
* +--------+-------------+-------+--------+- - - - - - - - - - +-------+--------+- - - - - - -
*
* @param[in] p_ancs Pointer to an ANCS instance to which the event belongs.
* @param[in] p_data_src Pointer to data that was received from the Notification Provider.
* @param[in] hvx_len Length of the data that was received from the Notification Provider.
*/
static void parse_get_notif_attrs_response(ble_ancs_c_t * p_ancs,
const uint8_t * p_data_src,
const uint16_t hvx_data_len)
{
uint32_t index;
for (index = 0; index < hvx_data_len;)
{
switch (p_ancs->parse_state)
{
case COMMAND_ID_AND_NOTIF_UID:
p_ancs->parse_state = command_id_and_notif_parse(p_ancs, p_data_src, &index);
break;
case ATTR_ID:
p_ancs->parse_state = attr_id_parse(p_ancs, p_data_src, &index);
break;
case ATTR_LEN1:
p_ancs->parse_state = attr_len1_parse(p_ancs, p_data_src, &index);
break;
case ATTR_LEN2:
p_ancs->parse_state = attr_len2_parse(p_ancs, p_data_src, &index);
break;
case ATTR_DATA:
p_ancs->parse_state = attr_data_parse(p_ancs, p_data_src, &index);
break;
case DONE:
ANCS_LOG("[ANCS]: State: Done \n\r");
index = hvx_data_len;
break;
default:
// Default case will never trigger intentionally. Go to the DONE state to minimize the consequences.
p_ancs->parse_state = DONE;
break;
}
}
}
/**@brief Function for checking if data in an iOS notification is out of bounds.
*
* @param[in] notif An iOS notification.
*
* @retval NRF_SUCCESS If the notification is within bounds.
* @retval NRF_ERROR_INVALID_PARAM If the notification is out of bounds.
*/
static uint32_t ble_ancs_verify_notification_format(const ble_ancs_c_evt_notif_t * notif)
{
if( (notif->evt_id >= BLE_ANCS_NB_OF_EVT_ID)
|| (notif->category_id >= BLE_ANCS_NB_OF_CATEGORY_ID))
{
return NRF_ERROR_INVALID_PARAM;
}
return NRF_SUCCESS;
}
/**@brief Function for receiving and validating notifications received from the Notification Provider.
*
* @param[in] p_ancs Pointer to an ANCS instance to which the event belongs.
* @param[in] p_data_src Pointer to data that was received from the Notification Provider.
* @param[in] hvx_len Length of the data that was received by the Notification Provider.
*/
static void parse_notif(const ble_ancs_c_t * p_ancs,
const uint8_t * p_data_src,
const uint16_t hvx_data_len)
{
ble_ancs_c_evt_t ancs_evt;
uint32_t err_code;
if (hvx_data_len != BLE_ANCS_NOTIFICATION_DATA_LENGTH)
{
ancs_evt.evt_type = BLE_ANCS_C_EVT_INVALID_NOTIF;
p_ancs->evt_handler(&ancs_evt);
}
/*lint --e{415} --e{416} -save suppress Warning 415: possible access out of bond */
ancs_evt.notif.evt_id =
(ble_ancs_c_evt_id_values_t) p_data_src[BLE_ANCS_NOTIF_EVT_ID_INDEX];
ancs_evt.notif.evt_flags.silent =
(p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_SILENT) & 0x01;
ancs_evt.notif.evt_flags.important =
(p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_IMPORTANT) & 0x01;
ancs_evt.notif.evt_flags.pre_existing =
(p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_PREEXISTING) & 0x01;
ancs_evt.notif.evt_flags.positive_action =
(p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_POSITIVE_ACTION) & 0x01;
ancs_evt.notif.evt_flags.negative_action =
(p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_NEGATIVE_ACTION) & 0x01;
ancs_evt.notif.category_id =
(ble_ancs_c_category_id_values_t) p_data_src[BLE_ANCS_NOTIF_CATEGORY_ID_INDEX];
ancs_evt.notif.category_count = p_data_src[BLE_ANCS_NOTIF_CATEGORY_CNT_INDEX];
ancs_evt.notif.notif_uid = uint32_decode(&p_data_src[BLE_ANCS_NOTIF_NOTIF_UID]);
/*lint -restore*/
err_code = ble_ancs_verify_notification_format(&ancs_evt.notif);
if (err_code == NRF_SUCCESS)
{
ancs_evt.evt_type = BLE_ANCS_C_EVT_NOTIF;
}
else
{
ancs_evt.evt_type = BLE_ANCS_C_EVT_INVALID_NOTIF;
}
p_ancs->evt_handler(&ancs_evt);
}
/**@brief Function for receiving and validating notifications received from the Notification Provider.
*
* @param[in] p_ancs Pointer to an ANCS instance to which the event belongs.
* @param[in] p_ble_evt Bluetooth stack event.
*/
static void on_evt_gattc_notif(ble_ancs_c_t * p_ancs, const ble_evt_t * p_ble_evt)
{
const ble_gattc_evt_hvx_t * p_notif = &p_ble_evt->evt.gattc_evt.params.hvx;
if(p_ble_evt->evt.gattc_evt.conn_handle != p_ancs->conn_handle)
{
return;
}
if (p_notif->handle == p_ancs->service.notif_source_char.handle_value)
{
parse_notif(p_ancs, p_notif->data, p_notif->len);
}
else if (p_notif->handle == p_ancs->service.data_source_char.handle_value)
{
parse_get_notif_attrs_response(p_ancs, p_notif->data, p_notif->len);
}
else
{
// No applicable action.
}
}
/**@brief Function for handling write response events.
*
* @param[in] p_ancs_c Pointer to the Battery Service Client Structure.
* @param[in] p_ble_evt Pointer to the SoftDevice event.
*/
static void on_write_rsp(ble_ancs_c_t * p_ancs, const ble_evt_t * p_ble_evt)
{
// Check if the event if on the link for this instance
if (p_ancs->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle)
{
return;
}
// Check if there is any message to be sent across to the peer and send it.
tx_buffer_process();
}
void ble_ancs_c_on_ble_evt(ble_ancs_c_t * p_ancs, const ble_evt_t * p_ble_evt)
{
uint16_t evt = p_ble_evt->header.evt_id;
switch (evt)
{
case BLE_GATTC_EVT_WRITE_RSP:
on_write_rsp(p_ancs, p_ble_evt);
break;
case BLE_GATTC_EVT_HVX:
on_evt_gattc_notif(p_ancs, p_ble_evt);
break;
case BLE_GAP_EVT_DISCONNECTED:
on_disconnected(p_ancs, p_ble_evt);
break;
default:
break;
}
}
uint32_t ble_ancs_c_init(ble_ancs_c_t * p_ancs, const ble_ancs_c_init_t * p_ancs_init)
{
uint32_t err_code;
//Verify that the parameters needed for to initialize this instance of ANCS are not NULL.
VERIFY_PARAM_NOT_NULL(p_ancs);
VERIFY_PARAM_NOT_NULL(p_ancs_init);
VERIFY_PARAM_NOT_NULL(p_ancs_init->evt_handler);
p_ancs->parse_state = COMMAND_ID_AND_NOTIF_UID;
p_ancs->p_data_dest = NULL;
p_ancs->current_attr_index = 0;
p_ancs->evt_handler = p_ancs_init->evt_handler;
p_ancs->error_handler = p_ancs_init->error_handler;
p_ancs->conn_handle = BLE_CONN_HANDLE_INVALID;
p_ancs->service.data_source_cccd.uuid.uuid = BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG;
p_ancs->service.notif_source_cccd.uuid.uuid = BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG;
// Make sure instance of service is clear. GATT handles inside the service and characteristics are set to @ref BLE_GATT_HANDLE_INVALID.
memset(&p_ancs->service, 0, sizeof(ble_ancs_c_service_t));
memset(m_tx_buffer, 0, TX_BUFFER_SIZE);
// Assign UUID types.
err_code = sd_ble_uuid_vs_add(&ble_ancs_base_uuid128, &p_ancs->service.service.uuid.type);
VERIFY_SUCCESS(err_code);
err_code = sd_ble_uuid_vs_add(&ble_ancs_cp_base_uuid128, &p_ancs->service.control_point_char.uuid.type);
VERIFY_SUCCESS(err_code);
err_code = sd_ble_uuid_vs_add(&ble_ancs_ns_base_uuid128, &p_ancs->service.notif_source_char.uuid.type);
VERIFY_SUCCESS(err_code);
err_code = sd_ble_uuid_vs_add(&ble_ancs_ds_base_uuid128, &p_ancs->service.data_source_char.uuid.type);
VERIFY_SUCCESS(err_code);
// Assign UUID to the service.
p_ancs->service.service.uuid.uuid = ANCS_UUID_SERVICE;
p_ancs->service.service.uuid.type = p_ancs->service.service.uuid.type;
return ble_db_discovery_evt_register(&p_ancs->service.service.uuid);
}
/**@brief Function for creating a TX message for writing a CCCD.
*
* @param[in] conn_handle Connection handle on which to perform the configuration.
* @param[in] handle_cccd Handle of the CCCD.
* @param[in] enable Enable or disable GATTC notifications.
*
* @retval NRF_SUCCESS If the message was created successfully.
* @retval NRF_ERROR_INVALID_PARAM If one of the input parameters was invalid.
*/
static uint32_t cccd_configure(const uint16_t conn_handle, const uint16_t handle_cccd, bool enable)
{
tx_message_t * p_msg;
uint16_t cccd_val = enable ? BLE_CCCD_NOTIFY_BIT_MASK : 0;
p_msg = &m_tx_buffer[m_tx_insert_index++];
m_tx_insert_index &= TX_BUFFER_MASK;
p_msg->req.write_req.gattc_params.handle = handle_cccd;
p_msg->req.write_req.gattc_params.len = 2;
p_msg->req.write_req.gattc_params.p_value = p_msg->req.write_req.gattc_value;
p_msg->req.write_req.gattc_params.offset = 0;
p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ;
p_msg->req.write_req.gattc_value[0] = LSB_16(cccd_val);
p_msg->req.write_req.gattc_value[1] = MSB_16(cccd_val);
p_msg->conn_handle = conn_handle;
p_msg->type = WRITE_REQ;
tx_buffer_process();
return NRF_SUCCESS;
}
uint32_t ble_ancs_c_notif_source_notif_enable(const ble_ancs_c_t * p_ancs)
{
ANCS_LOG("[ANCS]: Enable Notification Source notifications. writing to handle: %i \n\r",
p_ancs->service.notif_source_cccd.handle);
return cccd_configure(p_ancs->conn_handle, p_ancs->service.notif_source_cccd.handle, true);
}
uint32_t ble_ancs_c_notif_source_notif_disable(const ble_ancs_c_t * p_ancs)
{
return cccd_configure(p_ancs->conn_handle, p_ancs->service.notif_source_cccd.handle, false);
}
uint32_t ble_ancs_c_data_source_notif_enable(const ble_ancs_c_t * p_ancs)
{
ANCS_LOG("[ANCS]: Enable Data Source notifications. Writing to handle: %i \n\r",
p_ancs->service.data_source_cccd.handle);
return cccd_configure(p_ancs->conn_handle, p_ancs->service.data_source_cccd.handle, true);
}
uint32_t ble_ancs_c_data_source_notif_disable(const ble_ancs_c_t * p_ancs)
{
return cccd_configure(p_ancs->conn_handle, p_ancs->service.data_source_cccd.handle, false);
}
uint32_t ble_ancs_get_notif_attrs(ble_ancs_c_t * p_ancs,
const uint32_t p_uid)
{
tx_message_t * p_msg;
uint32_t index = 0;
p_ancs->number_of_requested_attr = 0;
p_msg = &m_tx_buffer[m_tx_insert_index++];
m_tx_insert_index &= TX_BUFFER_MASK;
p_msg->req.write_req.gattc_params.handle = p_ancs->service.control_point_char.handle_value;
p_msg->req.write_req.gattc_params.p_value = p_msg->req.write_req.gattc_value;
p_msg->req.write_req.gattc_params.offset = 0;
p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ;
//Encode Command ID.
p_msg->req.write_req.gattc_value[index++] = BLE_ANCS_COMMAND_ID_GET_NOTIF_ATTRIBUTES;
//Encode Notification UID.
index += uint32_encode(p_uid, &p_msg->req.write_req.gattc_value[index]);
//Encode Attribute ID.
for (uint32_t attr = 0; attr < BLE_ANCS_NB_OF_ATTRS; attr++)
{
if (p_ancs->ancs_attr_list[attr].get == true)
{
p_msg->req.write_req.gattc_value[index++] = attr;
if ((attr == BLE_ANCS_NOTIF_ATTR_ID_TITLE) ||
(attr == BLE_ANCS_NOTIF_ATTR_ID_SUBTITLE) ||
(attr == BLE_ANCS_NOTIF_ATTR_ID_MESSAGE))
{
//Encode Length field, only applicable for Title, Subtitle and Message
index += uint16_encode(p_ancs->ancs_attr_list[attr].attr_len,
&p_msg->req.write_req.gattc_value[index]);
}
p_ancs->number_of_requested_attr++;
}
}
p_msg->req.write_req.gattc_params.len = index;
p_msg->conn_handle = p_ancs->conn_handle;
p_msg->type = WRITE_REQ;
p_ancs->expected_number_of_attrs = p_ancs->number_of_requested_attr;
tx_buffer_process();
return NRF_SUCCESS;
}
uint32_t ble_ancs_c_attr_add(ble_ancs_c_t * p_ancs,
const ble_ancs_c_notif_attr_id_values_t id,
uint8_t * p_data,
const uint16_t len)
{
VERIFY_PARAM_NOT_NULL(p_data);
if((len == 0) || (len > BLE_ANCS_ATTR_DATA_MAX))
{
return NRF_ERROR_INVALID_LENGTH;
}
p_ancs->ancs_attr_list[id].get = true;
p_ancs->ancs_attr_list[id].attr_len = len;
p_ancs->ancs_attr_list[id].p_attr_data = p_data;
return NRF_SUCCESS;
}
uint32_t ble_ancs_c_request_attrs(ble_ancs_c_t * p_ancs,
const ble_ancs_c_evt_notif_t * p_notif)
{
uint32_t err_code;
err_code = ble_ancs_verify_notification_format(p_notif);
VERIFY_SUCCESS(err_code);
err_code = ble_ancs_get_notif_attrs(p_ancs, p_notif->notif_uid);
p_ancs->parse_state = COMMAND_ID_AND_NOTIF_UID;
VERIFY_SUCCESS(err_code);
return NRF_SUCCESS;
}
uint32_t ble_ancs_c_handles_assign(ble_ancs_c_t * p_ancs,
const uint16_t conn_handle,
const ble_ancs_c_service_t * p_peer_handles)
{
VERIFY_PARAM_NOT_NULL(p_ancs);
p_ancs->conn_handle = conn_handle;
if(p_peer_handles != NULL)
{
p_ancs->service.control_point_char.handle_value = p_peer_handles->control_point_char.handle_value;
p_ancs->service.data_source_cccd.handle = p_peer_handles->data_source_cccd.handle;
p_ancs->service.data_source_char.handle_value = p_peer_handles->data_source_char.handle_value;
p_ancs->service.notif_source_cccd.handle = p_peer_handles->notif_source_cccd.handle;
p_ancs->service.notif_source_char.handle_value = p_peer_handles->notif_source_char.handle_value;
}
return NRF_SUCCESS;
}

View File

@ -0,0 +1,419 @@
/* 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.
*/
/** @file
*
* @defgroup ble_sdk_srv_ancs_c Apple Notification Service client
* @{
* @ingroup ble_sdk_srv
*
* @brief Apple Notification Center Service Client Module.
*
* @details Disclaimer: This client implementation of the Apple Notification Center Service can
* be changed at any time by Nordic Semiconductor ASA. Server implementations such as the
* ones found in iOS can be changed at any time by Apple and may cause this client
* implementation to stop working.
*
* This module implements the Apple Notification Center Service (ANCS) client.
* This client can be used as a Notification Consumer (NC) that receives data
* notifications from a Notification Provider (NP). The NP is typically an iOS
* device acting as a server. For terminology and up-to-date specs, see
* http://developer.apple.com.
*
* The term "notification" is used in two different meanings:
* - An <i>iOS notification</i> is the data received from the Notification Provider.
* - A <i>GATTC notification</i> is a way to transfer data with <i>Bluetooth</i> Smart.
* In this module, we receive iOS notifications using GATTC notifications.
* We use the full term (iOS notification or GATTC notification) where required to avoid confusion.
*
* Upon initializing the module, you must add the different iOS notification attributes you
* would like to receive for iOS notifications. @ref ble_ancs_c_attr_add.
*
* Once a connection is established with a central device, the module does a service discovery to
* discover the ANVS server handles. If this succeeds (@ref BLE_ANCS_C_EVT_DISCOVERY_COMPLETE)
* The handles for the CTS server are part of the @ref ble_ancs_c_evt_t structure and must be
* assigned to a ANCS_C instance using the @ref ble_ancs_c_handles_assign function. For more
* information about service discovery, see the ble_discovery module documentation
* @ref lib_ble_db_discovery.
*
* The application can now subscribe to iOS notifications using
* @ref ble_ancs_c_notif_source_notif_enable. They arrive in the @ref BLE_ANCS_C_EVT_NOTIF event.
* @ref ble_ancs_c_request_attrs can be used to request attributes for the notifications. They
* arrive in the @ref BLE_ANCS_C_EVT_NOTIF_ATTRIBUTE event.
*
* @msc
* hscale = "1.5";
* Application, ANCS_C;
* |||;
* Application=>ANCS_C [label = "ble_ancs_c_attr_add(attribute)"];
* Application=>ANCS_C [label = "ble_ancs_c_init(ancs_instance, event_handler)"];
* ...;
* Application<<=ANCS_C [label = "BLE_ANCS_C_EVT_DISCOVERY_COMPLETE"];
* Application=>ANCS_C [label = "ble_ancs_c_handles_assign(ancs_instance, conn_handle, service_handles)"];
* Application=>ANCS_C [label = "ble_ancs_c_notif_source_notif_enable(ancs_instance)"];
* Application=>ANCS_C [label = "ble_ancs_c_data_source_notif_enable(ancs_instance)"];
* |||;
* ...;
* |||;
* Application<<=ANCS_C [label = "BLE_ANCS_C_EVT_NOTIF"];
* |||;
* ...;
* |||;
* Application=>ANCS_C [label = "ble_ancs_c_request_attrs(attr_id, buffer)"];
* Application<<=ANCS_C [label = "BLE_ANCS_C_EVT_NOTIF_ATTRIBUTE"];
* |||;
* @endmsc
*
* @note The application must propagate BLE stack events to this module
* by calling ble_ancs_c_on_ble_evt() from the @ref softdevice_handler callback.
*/
#ifndef BLE_ANCS_C_H__
#define BLE_ANCS_C_H__
#include "ble_types.h"
#include "ble_srv_common.h"
#include "device_manager.h"
#include "ble_db_discovery.h"
#define BLE_ANCS_ATTR_DATA_MAX 32 /**< Maximum data length of an iOS notification attribute. */
#define BLE_ANCS_NB_OF_CATEGORY_ID 12 /**< Number of iOS notification categories: Other, Incoming Call, Missed Call, Voice Mail, Social, Schedule, Email, News, Health And Fitness, Business And Finance, Location, Entertainment. */
#define BLE_ANCS_NB_OF_ATTRS 8 /**< Number of iOS notification attributes: AppIdentifier, Title, Subtitle, Message, MessageSize, Date, PositiveActionLabel, NegativeActionLabel. */
#define BLE_ANCS_NB_OF_EVT_ID 3 /**< Number of iOS notification events: Added, Modified, Removed.*/
/** @brief Length of the iOS notification data.
*
* @details 8 bytes:
* Event ID |Event flags |Category ID |Category count|Notification UID
* ---------|------------|------------|--------------|----------------
* 1 byte | 1 byte | 1 byte | 1 byte | 4 bytes
*/
#define BLE_ANCS_NOTIFICATION_DATA_LENGTH 8
#define ANCS_UUID_SERVICE 0xF431 /**< 16-bit service UUID for the Apple Notification Center Service. */
#define ANCS_UUID_CHAR_CONTROL_POINT 0xD8F3 /**< 16-bit control point UUID. */
#define ANCS_UUID_CHAR_DATA_SOURCE 0xC6E9 /**< 16-bit data source UUID. */
#define ANCS_UUID_CHAR_NOTIFICATION_SOURCE 0x120D /**< 16-bit notification source UUID. */
#define BLE_ANCS_EVENT_FLAG_SILENT 0 /**< 0b.......1 Silent: First (LSB) bit is set. All flags can be active at the same time.*/
#define BLE_ANCS_EVENT_FLAG_IMPORTANT 1 /**< 0b......1. Important: Second (LSB) bit is set. All flags can be active at the same time.*/
#define BLE_ANCS_EVENT_FLAG_PREEXISTING 2 /**< 0b.....1.. Pre-existing: Third (LSB) bit is set. All flags can be active at the same time.*/
#define BLE_ANCS_EVENT_FLAG_POSITIVE_ACTION 3 /**< 0b....1... Positive action: Fourth (LSB) bit is set. All flags can be active at the same time.*/
#define BLE_ANCS_EVENT_FLAG_NEGATIVE_ACTION 4 /**< 0b...1.... Negative action: Fifth (LSB) bit is set. All flags can be active at the same time. */
/**@brief Event types that are passed from client to application on an event. */
typedef enum
{
BLE_ANCS_C_EVT_DISCOVERY_COMPLETE, /**< A successful connection has been established and the service was found on the connected peer. */
BLE_ANCS_C_EVT_DISCOVERY_FAILED, /**< It was not possible to discover the service or characteristics of the connected peer. */
BLE_ANCS_C_EVT_NOTIF, /**< An iOS notification was received on the notification source control point. */
BLE_ANCS_C_EVT_INVALID_NOTIF, /**< An iOS notification was received on the notification source control point, but the format is invalid. */
BLE_ANCS_C_EVT_NOTIF_ATTRIBUTE /**< A received iOS notification attribute has been parsed. */
} ble_ancs_c_evt_type_t;
/**@brief Category IDs for iOS notifications. */
typedef enum
{
BLE_ANCS_CATEGORY_ID_OTHER, /**< The iOS notification belongs to the "other" category. */
BLE_ANCS_CATEGORY_ID_INCOMING_CALL, /**< The iOS notification belongs to the "Incoming Call" category. */
BLE_ANCS_CATEGORY_ID_MISSED_CALL, /**< The iOS notification belongs to the "Missed Call" category. */
BLE_ANCS_CATEGORY_ID_VOICE_MAIL, /**< The iOS notification belongs to the "Voice Mail" category. */
BLE_ANCS_CATEGORY_ID_SOCIAL, /**< The iOS notification belongs to the "Social" category. */
BLE_ANCS_CATEGORY_ID_SCHEDULE, /**< The iOS notification belongs to the "Schedule" category. */
BLE_ANCS_CATEGORY_ID_EMAIL, /**< The iOS notification belongs to the "E-mail" category. */
BLE_ANCS_CATEGORY_ID_NEWS, /**< The iOS notification belongs to the "News" category. */
BLE_ANCS_CATEGORY_ID_HEALTH_AND_FITNESS, /**< The iOS notification belongs to the "Health and Fitness" category. */
BLE_ANCS_CATEGORY_ID_BUSINESS_AND_FINANCE, /**< The iOS notification belongs to the "Buisness and Finance" category. */
BLE_ANCS_CATEGORY_ID_LOCATION, /**< The iOS notification belongs to the "Location" category. */
BLE_ANCS_CATEGORY_ID_ENTERTAINMENT /**< The iOS notification belongs to the "Entertainment" category. */
} ble_ancs_c_category_id_values_t;
/**@brief Event IDs for iOS notifications. */
typedef enum
{
BLE_ANCS_EVENT_ID_NOTIFICATION_ADDED, /**< The iOS notification was added. */
BLE_ANCS_EVENT_ID_NOTIFICATION_MODIFIED, /**< The iOS notification was modified. */
BLE_ANCS_EVENT_ID_NOTIFICATION_REMOVED /**< The iOS notification was removed. */
} ble_ancs_c_evt_id_values_t;
/**@brief Control point command IDs that the Notification Consumer can send to the Notification Provider. */
typedef enum
{
BLE_ANCS_COMMAND_ID_GET_NOTIF_ATTRIBUTES, /**< Requests attributes to be sent from the NP to the NC for a given notification. */
BLE_ANCS_COMMAND_ID_GET_APP_ATTRIBUTES, /**< Requests attributes to be sent from the NP to the NC for a given iOS App. */
BLE_ANCS_COMMAND_ID_GET_PERFORM_NOTIF_ACTION, /**< Requests an action to be performed on a given notification, for example dismiss an alarm. */
} ble_ancs_c_command_id_values_t;
/**@brief IDs for iOS notification attributes. */
typedef enum
{
BLE_ANCS_NOTIF_ATTR_ID_APP_IDENTIFIER, /**< Identifies that the attribute data is of an "App Identifier" type. */
BLE_ANCS_NOTIF_ATTR_ID_TITLE, /**< Identifies that the attribute data is a "Title". */
BLE_ANCS_NOTIF_ATTR_ID_SUBTITLE, /**< Identifies that the attribute data is a "Subtitle". */
BLE_ANCS_NOTIF_ATTR_ID_MESSAGE, /**< Identifies that the attribute data is a "Message". */
BLE_ANCS_NOTIF_ATTR_ID_MESSAGE_SIZE, /**< Identifies that the attribute data is a "Message Size". */
BLE_ANCS_NOTIF_ATTR_ID_DATE, /**< Identifies that the attribute data is a "Date". */
BLE_ANCS_NOTIF_ATTR_ID_POSITIVE_ACTION_LABEL, /**< The notification has a "Positive action" that can be executed associated with it. */
BLE_ANCS_NOTIF_ATTR_ID_NEGATIVE_ACTION_LABEL, /**< The notification has a "Negative action" that can be executed associated with it. */
} ble_ancs_c_notif_attr_id_values_t;
/**@brief Flags for iOS notifications. */
typedef struct
{
uint8_t silent : 1; /**< If this flag is set, the notification has a low priority. */
uint8_t important : 1; /**< If this flag is set, the notification has a high priority. */
uint8_t pre_existing : 1; /**< If this flag is set, the notification is pre-existing. */
uint8_t positive_action : 1; /**< If this flag is set, the notification has a positive action that can be taken. */
uint8_t negative_action : 1; /**< If this flag is set, the notification has a negative action that can be taken. */
} ble_ancs_c_notif_flags_t;
/**@brief Parsing states for received iOS notification attributes.
*/
typedef enum
{
COMMAND_ID_AND_NOTIF_UID, /**< Parsing the command ID and the notification UID. */
ATTR_ID, /**< Parsing attribute ID. */
ATTR_LEN1, /**< Parsing the LSB of the attribute length. */
ATTR_LEN2, /**< Parsing the MSB of the attribute length. */
ATTR_DATA, /**< Parsing the attribute data. */
DONE /**< Parsing is done. */
} ble_ancs_c_parse_state_t;
/**@brief iOS notification structure. */
typedef struct
{
ble_ancs_c_evt_id_values_t evt_id; /**< Whether the notification was added, removed, or modified. */
ble_ancs_c_notif_flags_t evt_flags; /**< Bitmask to signal if a special condition applies to the notification, for example, "Silent" or "Important". */
ble_ancs_c_category_id_values_t category_id; /**< Classification of the notification type, for example, email or location. */
uint8_t category_count; /**< Current number of active notifications for this category ID. */
uint32_t notif_uid; /**< Notification UID. */
} ble_ancs_c_evt_notif_t;
/**@brief iOS notification attribute structure for incomming attributes. */
typedef struct
{
uint32_t notif_uid; /**< UID of the notification that the attribute belongs to.*/
uint16_t attr_len; /**< Length of the received attribute data. */
ble_ancs_c_notif_attr_id_values_t attr_id; /**< Classification of the attribute type, for example, title or date. */
uint8_t * p_attr_data; /**< Pointer to where the memory is allocated for storing incoming attributes. */
} ble_ancs_c_evt_notif_attr_t;
/**@brief iOS notification attribute content wanted by our application. */
typedef struct
{
bool get; /**< Boolean to determine if this attribute will be requested from the Notification Provider. */
ble_ancs_c_notif_attr_id_values_t attr_id; /**< Attribute ID: AppIdentifier(0), Title(1), Subtitle(2), Message(3), MessageSize(4), Date(5), PositiveActionLabel(6), NegativeActionLabel(7). */
uint16_t attr_len; /**< Length of the attribute. If more data is received from the Notification Provider, all data beyond this length is discarded. */
uint8_t * p_attr_data; /**< Pointer to where the memory is allocated for storing incoming attributes. */
} ble_ancs_c_attr_list_t;
/**@brief Structure used for holding the Apple Notification Center Service found during the
discovery process.
*/
typedef struct
{
ble_gattc_service_t service; /**< The GATT Service holding the discovered Apple Notification Center Service. (0xF431). */
ble_gattc_char_t control_point_char; /**< ANCS Control Point Characteristic. Allows interaction with the peer (0xD8F3). */
ble_gattc_char_t notif_source_char; /**< ANCS Notification Source Characteristic. Keeps track of arrival, modification, and removal of notifications (0x120D). */
ble_gattc_desc_t notif_source_cccd; /**< ANCS Notification Source Characteristic Descriptor. Enables or Disables GATT notifications */
ble_gattc_char_t data_source_char; /**< ANCS Data Source Characteristic, where attribute data for the notifications is received from peer (0xC6E9). */
ble_gattc_desc_t data_source_cccd; /**< ANCS Data Source Characteristic Descriptor. Enables or Disables GATT notifications */
} ble_ancs_c_service_t;
/**@brief ANCS client module event structure.
*
* @details The structure contains the event that should be handled by the main application.
*/
typedef struct
{
ble_ancs_c_evt_type_t evt_type; /**< Type of event.*/
uint16_t conn_handle; /**< Connection handle on which the ANCS service was discovered on the peer device. This will be filled if the evt_type is @ref BLE_ANCS_C_EVT_DISCOVERY_COMPLETE.*/
ble_ancs_c_evt_notif_t notif; /**< iOS notification. Will be filled if evt_type is @ref BLE_ANCS_C_EVT_NOTIF. */
ble_ancs_c_evt_notif_attr_t attr; /**< Currently received attribute for a given notification. Will be filled if the evt_type is @ref BLE_ANCS_C_EVT_NOTIF_ATTRIBUTE. */
ble_ancs_c_service_t service; /**< Info on the discovered Alert Notification Service discovered. This will be filled if the evt_type is @ref BLE_ANCS_C_EVT_DISCOVERY_COMPLETE.*/
uint32_t error_code; /**< Additional status or error code if the event was caused by a stack error or GATT status, for example, during service discovery. */
} ble_ancs_c_evt_t;
/**@brief iOS notification event handler type. */
typedef void (*ble_ancs_c_evt_handler_t) (ble_ancs_c_evt_t * p_evt);
/**@brief iOS notification structure, which contains various status information for the client. */
typedef struct
{
ble_ancs_c_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Apple Notification client application. */
ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */
uint16_t conn_handle; /**< Handle of the current connection. Set with @ref ble_ancs_c_handles_assign when connected. */
ble_ancs_c_service_t service; /**< Struct to store the different handles and UUIDs related to the service. */
ble_ancs_c_attr_list_t ancs_attr_list[BLE_ANCS_NB_OF_ATTRS]; /**< For all attributes; contains whether they should be requested upon attribute request and the length and buffer of where to store attribute data. */
uint32_t number_of_requested_attr; /**< The number of attributes that will be requested upon a iOS notification attribute request is made. */
uint32_t expected_number_of_attrs; /**< The number of attributes expected upon receiving attributes. Keeps track of when to stop reading incoming attributes. */
ble_ancs_c_parse_state_t parse_state; /**< ANCS notification attribute parsing state. */
uint8_t * p_data_dest; /**< Attribute that the parsed data will be copied into. */
uint16_t current_attr_index; /**< Variable to keep track of how much (for a given attribute) we are done parsing. */
ble_ancs_c_evt_t evt; /**< The event is filled with several iteration of the parse_get_notif_attrs_response function when requesting iOS notification attributes. So we must allocate memory for it here.*/
} ble_ancs_c_t;
/**@brief Apple Notification client init structure, which contains all options and data needed for
* initialization of the client.*/
typedef struct
{
ble_ancs_c_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Battery Service. */
ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */
} ble_ancs_c_init_t;
/**@brief Apple Notification Center Service UUIDs. */
extern const ble_uuid128_t ble_ancs_base_uuid128; /**< Service UUID. */
extern const ble_uuid128_t ble_ancs_cp_base_uuid128; /**< Control point UUID. */
extern const ble_uuid128_t ble_ancs_ns_base_uuid128; /**< Notification source UUID. */
extern const ble_uuid128_t ble_ancs_ds_base_uuid128; /**< Data source UUID. */
/**@brief Function for handling the application's BLE Stack events.
*
* @details Handles all events from the BLE stack that are of interest to the ANCS client.
*
* @param[in] p_ancs ANCS client structure.
* @param[in] p_ble_evt Event received from the BLE stack.
*/
void ble_ancs_c_on_ble_evt(ble_ancs_c_t * p_ancs, const ble_evt_t * p_ble_evt);
/**@brief Function for handling events from the database discovery module.
*
* @details This function will handle an event from the database discovery module, and determine
* if it relates to the discovery of ANCS at the peer. If so, it will
* call the application's event handler indicating that ANCS has been
* discovered at the peer. It also populates the event with the service related
* information before providing it to the application.
*
* @param[in] p_ancs Pointer to the ANCS client structure.
* @param[in] p_evt Pointer to the event received from the database discovery module.
*/
void ble_ancs_c_on_db_disc_evt(ble_ancs_c_t * p_ancs, ble_db_discovery_evt_t * p_evt);
/**@brief Function for initializing the ANCS client.
*
* @param[out] p_ancs ANCS client structure. This structure must be
* supplied by the application. It is initialized by this function
* and will later be used to identify this particular client instance.
* @param[in] p_ancs_init Information needed to initialize the client.
*
* @retval NRF_SUCCESS If the client was initialized successfully. Otherwise, an error code is returned.
*/
uint32_t ble_ancs_c_init(ble_ancs_c_t * p_ancs, const ble_ancs_c_init_t * p_ancs_init);
/**@brief Function for writing to the CCCD to enable notifications from the Apple Notification Service.
*
* @param[in] p_ancs iOS notification structure. This structure must be supplied by
* the application. It identifies the particular client instance to use.
*
* @retval NRF_SUCCESS If writing to the CCCD was successful. Otherwise, an error code is returned.
*/
uint32_t ble_ancs_c_notif_source_notif_enable(const ble_ancs_c_t * p_ancs);
/**@brief Function for writing to the CCCD to enable data source notifications from the ANCS.
*
* @param[in] p_ancs iOS notification structure. This structure must be supplied by
* the application. It identifies the particular client instance to use.
*
* @retval NRF_SUCCESS If writing to the CCCD was successful. Otherwise, an error code is returned.
*/
uint32_t ble_ancs_c_data_source_notif_enable(const ble_ancs_c_t * p_ancs);
/**@brief Function for writing to the CCCD to disable notifications from the ANCS.
*
* @param[in] p_ancs iOS notification structure. This structure must be supplied by
* the application. It identifies the particular client instance to use.
*
* @retval NRF_SUCCESS If writing to the CCCD was successful. Otherwise, an error code is returned.
*/
uint32_t ble_ancs_c_notif_source_notif_disable(const ble_ancs_c_t * p_ancs);
/**@brief Function for writing to the CCCD to disable data source notifications from the ANCS.
*
* @param[in] p_ancs iOS notification structure. This structure must be supplied by
* the application. It identifies the particular client instance to use.
*
* @retval NRF_SUCCESS If writing to the CCCD was successful. Otherwise, an error code is returned.
*/
uint32_t ble_ancs_c_data_source_notif_disable(const ble_ancs_c_t * p_ancs);
/**@brief Function for registering attributes that will be requested if ble_ancs_c_request_attrs
* is called.
*
* @param[in] p_ancs ANCS client instance on which the attribute will be registered.
* @param[in] id ID of the attribute that will be added.
* @param[in] p_data Pointer to a buffer where the data of the attribute can be stored.
* @param[in] len Length of the buffer where the data of the attribute can be stored.
* @retval NRF_SUCCESS If all operations were successful. Otherwise, an error code is returned.
*/
uint32_t ble_ancs_c_attr_add(ble_ancs_c_t * p_ancs,
const ble_ancs_c_notif_attr_id_values_t id,
uint8_t * p_data,
const uint16_t len);
/**@brief Function for requesting attributes for a notification.
*
* @param[in] p_ancs iOS notification structure. This structure must be supplied by
* the application. It identifies the particular client instance to use.
* @param[in] p_notif Pointer to the notification whose attributes will be requested from
* the Notification Provider.
*
* @retval NRF_SUCCESS If all operations were successful. Otherwise, an error code is returned.
*/
uint32_t ble_ancs_c_request_attrs(ble_ancs_c_t * p_ancs,
const ble_ancs_c_evt_notif_t * p_notif);
/**@brief Function for assigning handle to a this instance of ancs_c.
*
* @details Call this function when a link has been established with a peer to
* associate this link to this instance of the module. This makes it
* possible to handle several link and associate each link to a particular
* instance of this module. The connection handle and attribute handles will be
* provided from the discovery event @ref BLE_ANCS_C_EVT_DISCOVERY_COMPLETE.
*
* @param[in] p_ancs Pointer to the ANCS client structure instance to associate with these
* handles.
* @param[in] conn_handle Connection handle to associated with the given ANCS Instance.
* @param[in] p_service Attribute handles on the ANCS server that you want this ANCS client to
* interact with.
*
* @retval NRF_SUCCESS If the operation was successful.
* @retval NRF_ERROR_NULL If a p_ancs was a NULL pointer.
*/
uint32_t ble_ancs_c_handles_assign(ble_ancs_c_t * p_ancs, const uint16_t conn_handle, const ble_ancs_c_service_t * p_service);
#endif // BLE_ANCS_C_H__
/** @} */

View File

@ -0,0 +1,544 @@
/* 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.
*/
/* Attention!
* To maintain compliance with Nordic Semiconductor ASAs Bluetooth profile
* qualification listings, this section of source code must not be modified.
*/
#include "ble_ans_c.h"
#include <string.h>
#include <stdbool.h>
#include "ble_err.h"
#include "ble_srv_common.h"
#include "nordic_common.h"
#include "nrf_assert.h"
#include "ble_db_discovery.h"
#define NOTIFICATION_DATA_LENGTH 2 /**< The mandatory length of notification data. After the mandatory data, the optional message is located. */
#define READ_DATA_LENGTH_MIN 1 /**< Minimum data length in a valid Alert Notification Read Response message. */
#define TX_BUFFER_MASK 0x07 /**< TX Buffer mask, must be a mask of contiguous zeroes, followed by contiguous sequence of ones: 000...111. */
#define TX_BUFFER_SIZE (TX_BUFFER_MASK + 1) /**< Size of send buffer, which is 1 higher than the mask. */
#define WRITE_MESSAGE_LENGTH 2 /**< Length of the write message for CCCD/control point. */
typedef enum
{
READ_REQ = 1, /**< Type identifying that this tx_message is a read request. */
WRITE_REQ /**< Type identifying that this tx_message is a write request. */
} ans_tx_request_t;
/**@brief Structure for writing a message to the central, i.e. Control Point or CCCD.
*/
typedef struct
{
uint8_t gattc_value[WRITE_MESSAGE_LENGTH]; /**< The message to write. */
ble_gattc_write_params_t gattc_params; /**< GATTC parameters for this message. */
} write_params_t;
/**@brief Structure for holding data to be transmitted to the connected central.
*/
typedef struct
{
uint16_t conn_handle; /**< Connection handle to be used when transmitting this message. */
ans_tx_request_t type; /**< Type of this message, i.e. read or write message. */
union
{
uint16_t read_handle; /**< Read request message. */
write_params_t write_req; /**< Write request message. */
} req;
} tx_message_t;
static tx_message_t m_tx_buffer[TX_BUFFER_SIZE]; /**< Transmit buffer for messages to be transmitted to the central. */
static uint32_t m_tx_insert_index = 0; /**< Current index in the transmit buffer where next message should be inserted. */
static uint32_t m_tx_index = 0; /**< Current index in the transmit buffer from where the next message to be transmitted resides. */
/**@brief Function for passing any pending request from the buffer to the stack.
*/
static void tx_buffer_process(void)
{
if (m_tx_index != m_tx_insert_index)
{
uint32_t err_code;
if (m_tx_buffer[m_tx_index].type == READ_REQ)
{
err_code = sd_ble_gattc_read(m_tx_buffer[m_tx_index].conn_handle,
m_tx_buffer[m_tx_index].req.read_handle,
0);
}
else
{
err_code = sd_ble_gattc_write(m_tx_buffer[m_tx_index].conn_handle,
&m_tx_buffer[m_tx_index].req.write_req.gattc_params);
}
if (err_code == NRF_SUCCESS)
{
++m_tx_index;
m_tx_index &= TX_BUFFER_MASK;
}
}
}
/** @brief Function for copying a characteristic.
*/
static void char_set(ble_gattc_char_t * p_dest_char, const ble_gattc_char_t * p_source_char)
{
memcpy(p_dest_char, p_source_char, sizeof(ble_gattc_char_t));
}
static void char_cccd_set(ble_gattc_desc_t * p_cccd, const uint16_t cccd_handle)
{
p_cccd->handle = cccd_handle;
}
/** @brief Function to check that all handles required by the client to use the server are present.
*/
static bool is_valid_ans_srv_discovered(const ble_ans_c_service_t * p_srv)
{
if ((p_srv->alert_notif_ctrl_point.handle_value == BLE_GATT_HANDLE_INVALID) ||
(p_srv->suported_new_alert_cat.handle_value == BLE_GATT_HANDLE_INVALID) ||
(p_srv->suported_unread_alert_cat.handle_value == BLE_GATT_HANDLE_INVALID) ||
(p_srv->new_alert.handle_value == BLE_GATT_HANDLE_INVALID) ||
(p_srv->unread_alert_status.handle_value == BLE_GATT_HANDLE_INVALID) ||
(p_srv->new_alert_cccd.handle == BLE_GATT_HANDLE_INVALID) ||
(p_srv->unread_alert_cccd.handle == BLE_GATT_HANDLE_INVALID)
)
{
// At least one required characteristic is missing on the server side.
return false;
}
return true;
}
void ble_ans_c_on_db_disc_evt(ble_ans_c_t * p_ans, const ble_db_discovery_evt_t * p_evt)
{
ble_ans_c_evt_t evt;
memset(&evt, 0, sizeof(ble_ans_c_evt_t));
evt.conn_handle = p_evt->conn_handle;
evt.evt_type = BLE_ANS_C_EVT_DISCOVERY_FAILED;
// Check if the Alert Notification Service was discovered.
if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE
&&
p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_ALERT_NOTIFICATION_SERVICE
&&
p_evt->params.discovered_db.srv_uuid.type == BLE_UUID_TYPE_BLE)
{
// Find the characteristics inside the service.
for (uint8_t i = 0; i < p_evt->params.discovered_db.char_count; i++)
{
const ble_gatt_db_char_t * p_char = &(p_evt->params.discovered_db.charateristics[i]);
switch (p_char->characteristic.uuid.uuid)
{
case BLE_UUID_ALERT_NOTIFICATION_CONTROL_POINT_CHAR:
NRF_LOG_PRINTF("[ANS] Found Ctrlpt \n\r");
char_set(&evt.data.service.alert_notif_ctrl_point, &p_char->characteristic);
break;
case BLE_UUID_UNREAD_ALERT_CHAR:
NRF_LOG_PRINTF("[ANS] Found Unread Alert \n\r");
char_set(&evt.data.service.unread_alert_status, &p_char->characteristic);
char_cccd_set(&evt.data.service.unread_alert_cccd,
p_char->cccd_handle);
break;
case BLE_UUID_NEW_ALERT_CHAR:
NRF_LOG_PRINTF("[ANS] Found New Alert \n\r");
char_set(&evt.data.service.new_alert, &p_char->characteristic);
char_cccd_set(&evt.data.service.new_alert_cccd,
p_char->cccd_handle);
break;
case BLE_UUID_SUPPORTED_UNREAD_ALERT_CATEGORY_CHAR:
NRF_LOG_PRINTF("[ANS] Found supported unread alert category \n\r");
char_set(&evt.data.service.suported_unread_alert_cat, &p_char->characteristic);
break;
case BLE_UUID_SUPPORTED_NEW_ALERT_CATEGORY_CHAR:
NRF_LOG_PRINTF("[ANS] Found supported new alert category \n\r");
char_set(&evt.data.service.suported_new_alert_cat, &p_char->characteristic);
break;
default:
// No implementation needed.
break;
}
}
if (is_valid_ans_srv_discovered(&evt.data.service))
{
evt.evt_type = BLE_ANS_C_EVT_DISCOVERY_COMPLETE;
}
}
p_ans->evt_handler(&evt);
}
/**@brief Function for receiving and validating notifications received from the central.
*/
static void event_notify(ble_ans_c_t * p_ans, const ble_evt_t * p_ble_evt)
{
uint32_t message_length;
ble_ans_c_evt_t event;
ble_ans_alert_notification_t * p_alert = &event.data.alert;
const ble_gattc_evt_hvx_t * p_notification = &p_ble_evt->evt.gattc_evt.params.hvx;
// Message is not valid -> ignore.
event.evt_type = BLE_ANS_C_EVT_NOTIFICATION;
if (p_notification->len < NOTIFICATION_DATA_LENGTH)
{
return;
}
message_length = p_notification->len - NOTIFICATION_DATA_LENGTH;
if (p_notification->handle == p_ans->service.new_alert.handle_value)
{
BLE_UUID_COPY_INST(event.uuid, p_ans->service.new_alert.uuid);
}
else if (p_notification->handle == p_ans->service.unread_alert_status.handle_value)
{
BLE_UUID_COPY_INST(event.uuid, p_ans->service.unread_alert_status.uuid);
}
else
{
// Nothing to process.
return;
}
p_alert->alert_category = p_notification->data[0];
p_alert->alert_category_count = p_notification->data[1]; //lint !e415
p_alert->alert_msg_length = (message_length > p_ans->message_buffer_size)
? p_ans->message_buffer_size
: message_length;
p_alert->p_alert_msg_buf = p_ans->p_message_buffer;
memcpy(p_alert->p_alert_msg_buf,
&p_notification->data[NOTIFICATION_DATA_LENGTH],
p_alert->alert_msg_length); //lint !e416
p_ans->evt_handler(&event);
}
/**@brief Function for handling write response events.
*/
static void event_write_rsp(ble_ans_c_t * p_ans, const ble_evt_t * p_ble_evt)
{
tx_buffer_process();
}
/**@brief Function for validating and passing the response to the application,
* when a read response is received.
*/
static void event_read_rsp(ble_ans_c_t * p_ans, const ble_evt_t * p_ble_evt)
{
ble_ans_c_evt_t event;
const ble_gattc_evt_read_rsp_t * p_response;
p_response = &p_ble_evt->evt.gattc_evt.params.read_rsp;
event.evt_type = BLE_ANS_C_EVT_READ_RESP;
if (p_response->len < READ_DATA_LENGTH_MIN)
{
tx_buffer_process();
return;
}
if (p_response->handle == p_ans->service.suported_new_alert_cat.handle_value)
{
BLE_UUID_COPY_INST(event.uuid, p_ans->service.suported_new_alert_cat.uuid);
}
else if (p_response->handle == p_ans->service.suported_unread_alert_cat.handle_value)
{
BLE_UUID_COPY_INST(event.uuid, p_ans->service.suported_unread_alert_cat.uuid);
}
else
{
// Bad response, ignore.
tx_buffer_process();
return;
}
event.data.settings = *(ble_ans_alert_settings_t *)(p_response->data);
if (p_response->len == READ_DATA_LENGTH_MIN)
{
// Those must default to 0, if they are not returned by central.
event.data.settings.ans_high_prioritized_alert_support = 0;
event.data.settings.ans_instant_message_support = 0;
}
p_ans->evt_handler(&event);
tx_buffer_process();
}
/**@brief Function for disconnecting and cleaning the current service.
*/
static void event_disconnect(ble_ans_c_t * p_ans, ble_evt_t const * p_ble_evt)
{
if (p_ans->conn_handle == p_ble_evt->evt.gap_evt.conn_handle)
{
p_ans->conn_handle = BLE_CONN_HANDLE_INVALID;
// Clearing all data for the service will also set all handle values to @ref BLE_GATT_HANDLE_INVALID
memset(&p_ans->service, 0, sizeof(ble_ans_c_service_t));
// There was a valid instance of IAS on the peer. Send an event to the
// application, so that it can do any clean up related to this module.
ble_ans_c_evt_t evt;
evt.evt_type = BLE_ANS_C_EVT_DISCONN_COMPLETE;
p_ans->evt_handler(&evt);
}
}
/**@brief Function for handling of BLE stack events.
*/
void ble_ans_c_on_ble_evt(ble_ans_c_t * p_ans, const ble_evt_t * p_ble_evt)
{
switch (p_ble_evt->header.evt_id)
{
case BLE_GATTC_EVT_HVX:
event_notify(p_ans, p_ble_evt);
break;
case BLE_GATTC_EVT_WRITE_RSP:
event_write_rsp(p_ans, p_ble_evt);
break;
case BLE_GATTC_EVT_READ_RSP:
event_read_rsp(p_ans, p_ble_evt);
break;
case BLE_GAP_EVT_DISCONNECTED:
event_disconnect(p_ans, p_ble_evt);
break;
}
}
uint32_t ble_ans_c_init(ble_ans_c_t * p_ans, const ble_ans_c_init_t * p_ans_init)
{
VERIFY_PARAM_NOT_NULL(p_ans);
VERIFY_PARAM_NOT_NULL(p_ans_init);
VERIFY_PARAM_NOT_NULL(p_ans_init->evt_handler);
// clear all handles
memset(p_ans, 0, sizeof(ble_ans_c_t));
memset(m_tx_buffer, 0, TX_BUFFER_SIZE);
p_ans->conn_handle = BLE_CONN_HANDLE_INVALID;
p_ans->evt_handler = p_ans_init->evt_handler;
p_ans->error_handler = p_ans_init->error_handler;
p_ans->message_buffer_size = p_ans_init->message_buffer_size;
p_ans->p_message_buffer = p_ans_init->p_message_buffer;
BLE_UUID_BLE_ASSIGN(p_ans->service.service.uuid, BLE_UUID_ALERT_NOTIFICATION_SERVICE);
BLE_UUID_BLE_ASSIGN(p_ans->service.new_alert.uuid, BLE_UUID_NEW_ALERT_CHAR);
BLE_UUID_BLE_ASSIGN(p_ans->service.alert_notif_ctrl_point.uuid,
BLE_UUID_ALERT_NOTIFICATION_CONTROL_POINT_CHAR);
BLE_UUID_BLE_ASSIGN(p_ans->service.unread_alert_status.uuid, BLE_UUID_UNREAD_ALERT_CHAR);
BLE_UUID_BLE_ASSIGN(p_ans->service.suported_new_alert_cat.uuid,
BLE_UUID_SUPPORTED_NEW_ALERT_CATEGORY_CHAR);
BLE_UUID_BLE_ASSIGN(p_ans->service.suported_unread_alert_cat.uuid,
BLE_UUID_SUPPORTED_UNREAD_ALERT_CATEGORY_CHAR);
BLE_UUID_BLE_ASSIGN(p_ans->service.new_alert_cccd.uuid, BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG);
BLE_UUID_BLE_ASSIGN(p_ans->service.unread_alert_cccd.uuid,
BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG);
return ble_db_discovery_evt_register(&p_ans->service.service.uuid);
}
/**@brief Function for creating a TX message for writing a CCCD.
*/
static uint32_t cccd_configure(uint16_t conn_handle, uint16_t handle_cccd, bool enable)
{
tx_message_t * p_msg;
uint16_t cccd_val = enable ? BLE_GATT_HVX_NOTIFICATION : 0;
p_msg = &m_tx_buffer[m_tx_insert_index++];
m_tx_insert_index &= TX_BUFFER_MASK;
p_msg->req.write_req.gattc_params.handle = handle_cccd;
p_msg->req.write_req.gattc_params.len = WRITE_MESSAGE_LENGTH;
p_msg->req.write_req.gattc_params.p_value = p_msg->req.write_req.gattc_value;
p_msg->req.write_req.gattc_params.offset = 0;
p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ;
p_msg->req.write_req.gattc_value[0] = LSB_16(cccd_val);
p_msg->req.write_req.gattc_value[1] = MSB_16(cccd_val);
p_msg->conn_handle = conn_handle;
p_msg->type = WRITE_REQ;
tx_buffer_process();
return NRF_SUCCESS;
}
uint32_t ble_ans_c_enable_notif_new_alert(const ble_ans_c_t * p_ans)
{
if (p_ans->conn_handle == BLE_CONN_HANDLE_INVALID)
{
return NRF_ERROR_INVALID_STATE;
}
else
{
return cccd_configure(p_ans->conn_handle,
p_ans->service.new_alert_cccd.handle,
true);
}
}
uint32_t ble_ans_c_disable_notif_new_alert(const ble_ans_c_t * p_ans)
{
return cccd_configure(p_ans->conn_handle,
p_ans->service.new_alert_cccd.handle,
false);
}
uint32_t ble_ans_c_enable_notif_unread_alert(const ble_ans_c_t * p_ans)
{
if ( p_ans->conn_handle == BLE_CONN_HANDLE_INVALID)
{
return NRF_ERROR_INVALID_STATE;
}
return cccd_configure(p_ans->conn_handle,
p_ans->service.unread_alert_cccd.handle,
true);
}
uint32_t ble_ans_c_disable_notif_unread_alert(const ble_ans_c_t * p_ans)
{
return cccd_configure(p_ans->conn_handle,
p_ans->service.unread_alert_cccd.handle,
false);
}
uint32_t ble_ans_c_control_point_write(const ble_ans_c_t * p_ans,
const ble_ans_control_point_t * p_control_point)
{
tx_message_t * p_msg;
p_msg = &m_tx_buffer[m_tx_insert_index++];
m_tx_insert_index &= TX_BUFFER_MASK;
p_msg->req.write_req.gattc_params.handle = p_ans->service.alert_notif_ctrl_point.handle_value;
p_msg->req.write_req.gattc_params.len = WRITE_MESSAGE_LENGTH;
p_msg->req.write_req.gattc_params.p_value = p_msg->req.write_req.gattc_value;
p_msg->req.write_req.gattc_params.offset = 0;
p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ;
p_msg->req.write_req.gattc_value[0] = p_control_point->command;
p_msg->req.write_req.gattc_value[1] = p_control_point->category;
p_msg->conn_handle = p_ans->conn_handle;
p_msg->type = WRITE_REQ;
tx_buffer_process();
return NRF_SUCCESS;
}
uint32_t ble_ans_c_new_alert_read(const ble_ans_c_t * p_ans)
{
tx_message_t * msg;
msg = &m_tx_buffer[m_tx_insert_index++];
m_tx_insert_index &= TX_BUFFER_MASK;
msg->req.read_handle = p_ans->service.suported_new_alert_cat.handle_value;
msg->conn_handle = p_ans->conn_handle;
msg->type = READ_REQ;
tx_buffer_process();
return NRF_SUCCESS;
}
uint32_t ble_ans_c_unread_alert_read(const ble_ans_c_t * p_ans)
{
tx_message_t * msg;
msg = &m_tx_buffer[m_tx_insert_index++];
m_tx_insert_index &= TX_BUFFER_MASK;
msg->req.read_handle = p_ans->service.suported_unread_alert_cat.handle_value;
msg->conn_handle = p_ans->conn_handle;
msg->type = READ_REQ;
tx_buffer_process();
return NRF_SUCCESS;
}
uint32_t ble_ans_c_new_alert_notify(const ble_ans_c_t * p_ans, ble_ans_category_id_t category_id)
{
ble_ans_control_point_t control_point;
control_point.command = ANS_NOTIFY_NEW_INCOMING_ALERT_IMMEDIATELY;
control_point.category = category_id;
return ble_ans_c_control_point_write(p_ans, &control_point);
}
uint32_t ble_ans_c_unread_alert_notify(const ble_ans_c_t * p_ans, ble_ans_category_id_t category_id)
{
ble_ans_control_point_t control_point;
control_point.command = ANS_NOTIFY_UNREAD_CATEGORY_STATUS_IMMEDIATELY;
control_point.category = category_id;
return ble_ans_c_control_point_write(p_ans, &control_point);
}
uint32_t ble_ans_c_handles_assign(ble_ans_c_t * p_ans,
const uint16_t conn_handle,
const ble_ans_c_service_t * p_peer_handles)
{
VERIFY_PARAM_NOT_NULL(p_ans);
if (!is_valid_ans_srv_discovered(p_peer_handles))
{
return NRF_ERROR_INVALID_PARAM;
}
p_ans->conn_handle = conn_handle;
if (p_peer_handles != NULL)
{
// Copy the handles from the discovered characteristics over to the provided client instance.
char_set(&p_ans->service.alert_notif_ctrl_point, &p_peer_handles->alert_notif_ctrl_point);
char_set(&p_ans->service.suported_new_alert_cat, &p_peer_handles->suported_new_alert_cat);
char_set(&p_ans->service.suported_unread_alert_cat, &p_peer_handles->suported_unread_alert_cat);
char_set(&p_ans->service.new_alert, &p_peer_handles->new_alert);
char_cccd_set(&p_ans->service.new_alert_cccd, p_peer_handles->new_alert_cccd.handle);
char_set(&p_ans->service.unread_alert_status, &p_peer_handles->unread_alert_status);
char_cccd_set(&p_ans->service.unread_alert_cccd, p_peer_handles->unread_alert_cccd.handle);
}
return NRF_SUCCESS;
}

View File

@ -0,0 +1,348 @@
/* 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.
*/
/** @file
*
* @defgroup ble_sdk_srv_ans_c Alert Notification Service Client
* @{
* @ingroup ble_sdk_srv
* @brief Alert Notification module.
*
* @details This module implements the Alert Notification Client according to the
* Alert Notification Profile.
*
* @note The application must propagate BLE stack events to the Alert Notification Client module
* by calling ble_ans_c_on_ble_evt() from the @ref softdevice_handler callback.
*
* @note Attention!
* To maintain compliance with Nordic Semiconductor ASA Bluetooth profile
* qualification listings, this section of source code must not be modified.
*/
#ifndef BLE_ANS_C_H__
#define BLE_ANS_C_H__
#include "ble.h"
#include "ble_gatts.h"
#include "ble_types.h"
#include "sdk_common.h"
#include "ble_srv_common.h"
#include "ble_db_discovery.h"
// Forward declaration of the ble_ans_c_t type.
typedef struct ble_ans_c_s ble_ans_c_t;
/** Alerts types as defined in the alert category id; UUID: 0x2A43. */
typedef enum
{
ANS_TYPE_SIMPLE_ALERT = 0, /**< General text alert or non-text alert.*/
ANS_TYPE_EMAIL = 1, /**< Alert when email messages arrives.*/
ANS_TYPE_NEWS = 2, /**< News feeds such as RSS, Atom.*/
ANS_TYPE_NOTIFICATION_CALL = 3, /**< Incoming call.*/
ANS_TYPE_MISSED_CALL = 4, /**< Missed call.*/
ANS_TYPE_SMS_MMS = 5, /**< SMS/MMS message arrives.*/
ANS_TYPE_VOICE_MAIL = 6, /**< Voice mail.*/
ANS_TYPE_SCHEDULE = 7, /**< Alert occurred on calendar, planner.*/
ANS_TYPE_HIGH_PRIORITIZED_ALERT = 8, /**< Alert that should be handled as high priority.*/
ANS_TYPE_INSTANT_MESSAGE = 9, /**< Alert for incoming instant messages.*/
ANS_TYPE_ALL_ALERTS = 0xFF /**< Identifies All Alerts. */
} ble_ans_category_id_t;
/** Alerts notification control point commands as defined in the Alert Notification Specification;
* UUID: 0x2A44.
*/
typedef enum
{
ANS_ENABLE_NEW_INCOMING_ALERT_NOTIFICATION = 0, /**< Enable New Incoming Alert Notification.*/
ANS_ENABLE_UNREAD_CATEGORY_STATUS_NOTIFICATION = 1, /**< Enable Unread Category Status Notification.*/
ANS_DISABLE_NEW_INCOMING_ALERT_NOTIFICATION = 2, /**< Disable New Incoming Alert Notification.*/
ANS_DISABLE_UNREAD_CATEGORY_STATUS_NOTIFICATION = 3, /**< Disable Unread Category Status Notification.*/
ANS_NOTIFY_NEW_INCOMING_ALERT_IMMEDIATELY = 4, /**< Notify New Incoming Alert immediately.*/
ANS_NOTIFY_UNREAD_CATEGORY_STATUS_IMMEDIATELY = 5, /**< Notify Unread Category Status immediately.*/
} ble_ans_command_id_t;
/**@brief Alert Notification Event types that are passed from client to application on an event. */
typedef enum
{
BLE_ANS_C_EVT_DISCOVERY_COMPLETE, /**< A successful connection has been established and the characteristics of the server has been fetched. */
BLE_ANS_C_EVT_DISCOVERY_FAILED, /**< It was not possible to discover service or characteristics of the connected peer. */
BLE_ANS_C_EVT_DISCONN_COMPLETE, /**< The connection has been taken down. */
BLE_ANS_C_EVT_NOTIFICATION, /**< A valid Alert Notification has been received from the server.*/
BLE_ANS_C_EVT_READ_RESP, /**< A read response has been received from the server.*/
BLE_ANS_C_EVT_WRITE_RESP /**< A write response has been received from the server.*/
} ble_ans_c_evt_type_t;
/**@brief Alert Notification Control Point structure. */
typedef struct
{
ble_ans_command_id_t command; /**< The command to be written to the control point, see @ref ble_ans_command_id_t. */
ble_ans_category_id_t category; /**< The category for the control point for which the command applies, see @ref ble_ans_category_id_t. */
} ble_ans_control_point_t;
/**@brief Alert Notification Setting structure containing the supported alerts in the service.
*
*@details
* The structure contains bit fields describing which alerts that are supported:
* 0 = Unsupported
* 1 = Supported
*/
typedef struct
{
uint8_t ans_simple_alert_support : 1; /**< Support for General text alert or non-text alert.*/
uint8_t ans_email_support : 1; /**< Support for Alert when email messages arrives.*/
uint8_t ans_news_support : 1; /**< Support for News feeds such as RSS, Atom.*/
uint8_t ans_notification_call_support : 1; /**< Support for Incoming call.*/
uint8_t ans_missed_call_support : 1; /**< Support for Missed call.*/
uint8_t ans_sms_mms_support : 1; /**< Support for SMS/MMS message arrives.*/
uint8_t ans_voice_mail_support : 1; /**< Support for Voice mail.*/
uint8_t ans_schedule_support : 1; /**< Support for Alert occurred on calendar, planner.*/
uint8_t ans_high_prioritized_alert_support : 1; /**< Support for Alert that should be handled as high priority.*/
uint8_t ans_instant_message_support : 1; /**< Support for Alert for incoming instant messages.*/
uint8_t reserved : 6; /**< Reserved for future use. */
} ble_ans_alert_settings_t;
/**@brief Alert Notification structure
*/
typedef struct
{
uint8_t alert_category; /**< Alert category to which this alert belongs.*/
uint8_t alert_category_count; /**< Number of alerts in the category. */
uint32_t alert_msg_length; /**< Length of optional text message send by the server. */
uint8_t * p_alert_msg_buf; /**< Pointer to buffer containing the optional text message. */
} ble_ans_alert_notification_t;
/**@brief Struct to hold information on the Alert Notification Service if found on the server.
*/
typedef struct
{
ble_gattc_service_t service; /**< The GATT service holding the discovered Alert Notification Service. */
ble_gattc_char_t alert_notif_ctrl_point; /**< Characteristic for the Alert Notification Control Point. @ref BLE_UUID_ALERT_NOTIFICATION_CONTROL_POINT_CHAR */
ble_gattc_char_t suported_new_alert_cat; /**< Characteristic for the Supported New Alert category. @ref BLE_UUID_SUPPORTED_NEW_ALERT_CATEGORY_CHAR */
ble_gattc_char_t suported_unread_alert_cat; /**< Characteristic for the Unread Alert category. @ref BLE_UUID_SUPPORTED_UNREAD_ALERT_CATEGORY_CHAR */
ble_gattc_char_t new_alert; /**< Characteristic for the New Alert Notification. @ref BLE_UUID_NEW_ALERT_CHAR */
ble_gattc_desc_t new_alert_cccd; /**< Characteristic Descriptor for New Alert Category. Enables or Disables GATT notifications */
ble_gattc_char_t unread_alert_status; /**< Characteristic for the Unread Alert Notification. @ref BLE_UUID_UNREAD_ALERT_CHAR */
ble_gattc_desc_t unread_alert_cccd; /**< Characteristic Descriptor for Unread Alert Category. Enables or Disables GATT notifications */
} ble_ans_c_service_t;
/**@brief Alert Notification Event structure
*
* @details The structure contains the event that should be handled, as well as
* additional information.
*/
typedef struct
{
ble_ans_c_evt_type_t evt_type; /**< Type of event. */
uint16_t conn_handle; /**< Connection handle on which the ANS service was discovered on the peer device. This will be filled if the evt_type is @ref BLE_ANS_C_EVT_DISCOVERY_COMPLETE.*/
ble_uuid_t uuid; /**< UUID of the event in case of an alert or notification. */
union
{
ble_ans_alert_settings_t settings; /**< Setting returned from server on read request. */
ble_ans_alert_notification_t alert; /**< Alert Notification data sent by the server. */
uint32_t error_code; /**< Additional status/error code if the event was caused by a stack error or gatt status, e.g. during service discovery. */
ble_ans_c_service_t service; /**< Info on the discovered Alert Notification Service discovered. This will be filled if the evt_type is @ref BLE_ANS_C_EVT_DISCOVERY_COMPLETE.*/
} data;
} ble_ans_c_evt_t;
/**@brief Alert Notification event handler type. */
typedef void (*ble_ans_c_evt_handler_t) (ble_ans_c_evt_t * p_evt);
/**@brief Alert Notification structure. This contains various status information for the client. */
struct ble_ans_c_s
{
ble_ans_c_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Alert Notification Client Application. */
ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */
uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection). */
uint8_t central_handle; /**< Handle for the currently connected central if peer is bonded. */
uint8_t service_handle; /**< Handle to the service in the database to use for this instance. */
uint32_t message_buffer_size; /**< Size of message buffer to hold the additional text messages received on notifications. */
uint8_t * p_message_buffer; /**< Pointer to the buffer to be used for additional text message handling. */
ble_ans_c_service_t service; /**< Struct to store the different handles and UUIDs related to the service. */
};
/**@brief Alert Notification init structure. This contains all options and data needed for
* initialization of the client.*/
typedef struct
{
ble_ans_c_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Battery Service. */
ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */
uint32_t message_buffer_size; /**< Size of buffer to handle messages. */
uint8_t * p_message_buffer; /**< Pointer to buffer for passing messages. */
} ble_ans_c_init_t;
/**@brief Function for handling events from the database discovery module.
*
* @details Call this function when getting a callback event from the DB discovery modue.
* This function will handle an event from the database discovery module, and determine
* if it relates to the discovery of heart rate service at the peer. If so, it will
* call the application's event handler indicating that the heart rate service has been
* discovered at the peer. It also populates the event with the service related
* information before providing it to the application.
*
* @param[in] p_ans Pointer to the Alert Notification client structure instance that will handle
* the discovery.
* @param[in] p_evt Pointer to the event received from the database discovery module.
*/
void ble_ans_c_on_db_disc_evt(ble_ans_c_t * p_ans, const ble_db_discovery_evt_t * p_evt);
/**@brief Function for handling the Application's BLE Stack events.
*
* @details Handles all events from the BLE stack of interest to the Alert Notification Client.
*
* @param[in] p_ans Alert Notification Client structure.
* @param[in] p_ble_evt Event received from the BLE stack.
*/
void ble_ans_c_on_ble_evt(ble_ans_c_t * p_ans, const ble_evt_t * p_ble_evt);
/**@brief Function for initializing the Alert Notification Client.
*
* @param[out] p_ans Alert Notification Client structure. This structure will have to be
* supplied by the application. It will be initialized by this function,
* and will later be used to identify this particular client instance.
* @param[in] p_ans_init Information needed to initialize the client.
*
* @return NRF_SUCCESS on successful initialization of client, otherwise an error code.
*/
uint32_t ble_ans_c_init(ble_ans_c_t * p_ans, const ble_ans_c_init_t * p_ans_init);
/**@brief Function for writing the to CCCD to enable new alert notifications from the Alert Notification Service.
*
* @param[in] p_ans Alert Notification structure. This structure will have to be supplied by
* the application. It identifies the particular client instance to use.
*
* @return NRF_SUCCESS on successful writing of the CCCD, otherwise an error code.
*/
uint32_t ble_ans_c_enable_notif_new_alert(const ble_ans_c_t * p_ans);
/**@brief Function for writing to the CCCD to enable unread alert notifications from the Alert Notification Service.
*
* @param[in] p_ans Alert Notification structure. This structure will have to be supplied by
* the application. It identifies the particular client instance to use.
*
* @return NRF_SUCCESS on successful writing of the CCCD, otherwise an error code.
*/
uint32_t ble_ans_c_enable_notif_unread_alert(const ble_ans_c_t * p_ans);
/**@brief Function for writing to the CCCD to disable new alert notifications from the Alert Notification Service.
*
* @param[in] p_ans Alert Notification structure. This structure will have to be supplied by
* the application. It identifies the particular client instance to use.
*
* @return NRF_SUCCESS on successful writing of the CCCD, otherwise an error code.
*/
uint32_t ble_ans_c_disable_notif_new_alert(const ble_ans_c_t * p_ans);
/**@brief Function for writing to the CCCD to disable unread alert notifications from the Alert Notification Service.
*
* @param[in] p_ans Alert Notification structure. This structure will have to be supplied by
* the application. It identifies the particular client instance to use.
*
* @return NRF_SUCCESS on successful writing of the CCCD, otherwise an error code.
*/
uint32_t ble_ans_c_disable_notif_unread_alert(const ble_ans_c_t * p_ans);
/**@brief Function for writing to the Alert Notification Control Point to specify alert notification behavior in the
* Alert Notification Service on the Central.
*
* @param[in] p_ans Alert Notification structure. This structure will have to be
* supplied by the application. It identifies the particular client
* instance to use.
* @param[in] p_control_point Alert Notification Control Point structure. This structure
* specifies the values to write to the Alert Notification Control
* Point, UUID 0x2A44.
*
* @return NRF_SUCCESS on successful writing of the Control Point, otherwise an error code.
*/
uint32_t ble_ans_c_control_point_write(const ble_ans_c_t * p_ans,
const ble_ans_control_point_t * p_control_point);
/**@brief Function for reading the Supported New Alert characteristic value of the service.
* The value describes the alerts supported in the central.
*
* @param[in] p_ans Alert Notification structure. This structure will have to be supplied by
* the application. It identifies the particular client instance to use.
*
* @return NRF_SUCCESS on successful transmission of the read request, otherwise an error code.
*/
uint32_t ble_ans_c_new_alert_read(const ble_ans_c_t * p_ans);
/**@brief Function for reading the Supported Unread Alert characteristic value of the service.
* The value describes the alerts supported in the central.
*
* @param[in] p_ans Alert Notification structure. This structure will have to be supplied by
* the application. It identifies the particular client instance to use.
*
* @return NRF_SUCCESS on successful transmission of the read request, otherwise an error code.
*/
uint32_t ble_ans_c_unread_alert_read(const ble_ans_c_t * p_ans);
/**@brief Function for requesting the peer to notify the New Alert characteristics immediately.
*
* @param[in] p_ans Alert Notification structure. This structure will have to be supplied by
* the application. It identifies the particular client instance to use.
* @param[in] category The category ID for which the peer should notify the client.
*
* @return NRF_SUCCESS on successful transmission of the read request, otherwise an error code.
*/
uint32_t ble_ans_c_new_alert_notify(const ble_ans_c_t * p_ans, ble_ans_category_id_t category);
/**@brief Function for requesting the peer to notify the Unread Alert characteristics immediately.
*
* @param[in] p_ans Alert Notification structure. This structure will have to be supplied by
* the application. It identifies the particular client instance to use.
* @param[in] category The category ID for which the peer should notify the client.
*
* @return NRF_SUCCESS on successful transmission of the read request, otherwise an error code.
*/
uint32_t ble_ans_c_unread_alert_notify(const ble_ans_c_t * p_ans, ble_ans_category_id_t category);
/**@brief Function for assigning a handles to a an instance of ans_c.
*
* @details Call this function when a link has been established with a peer to
* associate this link to an instance of the module. This makes it
* possible to handle several link and associate each link to a particular
* instance of the ans_c module. The connection handle and attribute handles will be
* provided from the discovery event @ref BLE_ANS_C_EVT_DISCOVERY_COMPLETE.
*
* @param[in] p_ans Pointer to the Alert Notification client structure instance to
* associate with the handles.
* @param[in] conn_handle Connection handle to associated with the given Alert Notification Client
* Instance.
* @param[in] p_peer_handles Attribute handles on the ANS server that you want this ANS client to
* interact with.
*
*/
uint32_t ble_ans_c_handles_assign(ble_ans_c_t * p_ans,
const uint16_t conn_handle,
const ble_ans_c_service_t * p_peer_handles);
#endif // BLE_ANS_C_H__
/** @} */

View File

@ -0,0 +1,316 @@
/* 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.
*
*/
/* Attention!
* To maintain compliance with Nordic Semiconductor ASAs Bluetooth profile
* qualification listings, this section of source code must not be modified.
*/
#include "ble_bas.h"
#include <string.h>
#include "nordic_common.h"
#include "ble_srv_common.h"
#include "app_util.h"
#define INVALID_BATTERY_LEVEL 255
/**@brief Function for handling the Connect event.
*
* @param[in] p_bas Battery Service structure.
* @param[in] p_ble_evt Event received from the BLE stack.
*/
static void on_connect(ble_bas_t * p_bas, ble_evt_t * p_ble_evt)
{
p_bas->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
}
/**@brief Function for handling the Disconnect event.
*
* @param[in] p_bas Battery Service structure.
* @param[in] p_ble_evt Event received from the BLE stack.
*/
static void on_disconnect(ble_bas_t * p_bas, ble_evt_t * p_ble_evt)
{
UNUSED_PARAMETER(p_ble_evt);
p_bas->conn_handle = BLE_CONN_HANDLE_INVALID;
}
/**@brief Function for handling the Write event.
*
* @param[in] p_bas Battery Service structure.
* @param[in] p_ble_evt Event received from the BLE stack.
*/
static void on_write(ble_bas_t * p_bas, ble_evt_t * p_ble_evt)
{
if (p_bas->is_notification_supported)
{
ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
if (
(p_evt_write->handle == p_bas->battery_level_handles.cccd_handle)
&&
(p_evt_write->len == 2)
)
{
// CCCD written, call application event handler
if (p_bas->evt_handler != NULL)
{
ble_bas_evt_t evt;
if (ble_srv_is_notification_enabled(p_evt_write->data))
{
evt.evt_type = BLE_BAS_EVT_NOTIFICATION_ENABLED;
}
else
{
evt.evt_type = BLE_BAS_EVT_NOTIFICATION_DISABLED;
}
p_bas->evt_handler(p_bas, &evt);
}
}
}
}
void ble_bas_on_ble_evt(ble_bas_t * p_bas, ble_evt_t * p_ble_evt)
{
if (p_bas == NULL || p_ble_evt == NULL)
{
return;
}
switch (p_ble_evt->header.evt_id)
{
case BLE_GAP_EVT_CONNECTED:
on_connect(p_bas, p_ble_evt);
break;
case BLE_GAP_EVT_DISCONNECTED:
on_disconnect(p_bas, p_ble_evt);
break;
case BLE_GATTS_EVT_WRITE:
on_write(p_bas, p_ble_evt);
break;
default:
// No implementation needed.
break;
}
}
/**@brief Function for adding the Battery Level characteristic.
*
* @param[in] p_bas Battery Service structure.
* @param[in] p_bas_init Information needed to initialize the service.
*
* @return NRF_SUCCESS on success, otherwise an error code.
*/
static uint32_t battery_level_char_add(ble_bas_t * p_bas, const ble_bas_init_t * p_bas_init)
{
uint32_t err_code;
ble_gatts_char_md_t char_md;
ble_gatts_attr_md_t cccd_md;
ble_gatts_attr_t attr_char_value;
ble_uuid_t ble_uuid;
ble_gatts_attr_md_t attr_md;
uint8_t initial_battery_level;
uint8_t encoded_report_ref[BLE_SRV_ENCODED_REPORT_REF_LEN];
uint8_t init_len;
// Add Battery Level characteristic
if (p_bas->is_notification_supported)
{
memset(&cccd_md, 0, sizeof(cccd_md));
// According to BAS_SPEC_V10, the read operation on cccd should be possible without
// authentication.
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
cccd_md.write_perm = p_bas_init->battery_level_char_attr_md.cccd_write_perm;
cccd_md.vloc = BLE_GATTS_VLOC_STACK;
}
memset(&char_md, 0, sizeof(char_md));
char_md.char_props.read = 1;
char_md.char_props.notify = (p_bas->is_notification_supported) ? 1 : 0;
char_md.p_char_user_desc = NULL;
char_md.p_char_pf = NULL;
char_md.p_user_desc_md = NULL;
char_md.p_cccd_md = (p_bas->is_notification_supported) ? &cccd_md : NULL;
char_md.p_sccd_md = NULL;
BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_BATTERY_LEVEL_CHAR);
memset(&attr_md, 0, sizeof(attr_md));
attr_md.read_perm = p_bas_init->battery_level_char_attr_md.read_perm;
attr_md.write_perm = p_bas_init->battery_level_char_attr_md.write_perm;
attr_md.vloc = BLE_GATTS_VLOC_STACK;
attr_md.rd_auth = 0;
attr_md.wr_auth = 0;
attr_md.vlen = 0;
initial_battery_level = p_bas_init->initial_batt_level;
memset(&attr_char_value, 0, sizeof(attr_char_value));
attr_char_value.p_uuid = &ble_uuid;
attr_char_value.p_attr_md = &attr_md;
attr_char_value.init_len = sizeof(uint8_t);
attr_char_value.init_offs = 0;
attr_char_value.max_len = sizeof(uint8_t);
attr_char_value.p_value = &initial_battery_level;
err_code = sd_ble_gatts_characteristic_add(p_bas->service_handle, &char_md,
&attr_char_value,
&p_bas->battery_level_handles);
if (err_code != NRF_SUCCESS)
{
return err_code;
}
if (p_bas_init->p_report_ref != NULL)
{
// Add Report Reference descriptor
BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_REPORT_REF_DESCR);
memset(&attr_md, 0, sizeof(attr_md));
attr_md.read_perm = p_bas_init->battery_level_report_read_perm;
BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm);
attr_md.vloc = BLE_GATTS_VLOC_STACK;
attr_md.rd_auth = 0;
attr_md.wr_auth = 0;
attr_md.vlen = 0;
init_len = ble_srv_report_ref_encode(encoded_report_ref, p_bas_init->p_report_ref);
memset(&attr_char_value, 0, sizeof(attr_char_value));
attr_char_value.p_uuid = &ble_uuid;
attr_char_value.p_attr_md = &attr_md;
attr_char_value.init_len = init_len;
attr_char_value.init_offs = 0;
attr_char_value.max_len = attr_char_value.init_len;
attr_char_value.p_value = encoded_report_ref;
err_code = sd_ble_gatts_descriptor_add(p_bas->battery_level_handles.value_handle,
&attr_char_value,
&p_bas->report_ref_handle);
if (err_code != NRF_SUCCESS)
{
return err_code;
}
}
else
{
p_bas->report_ref_handle = BLE_GATT_HANDLE_INVALID;
}
return NRF_SUCCESS;
}
uint32_t ble_bas_init(ble_bas_t * p_bas, const ble_bas_init_t * p_bas_init)
{
if (p_bas == NULL || p_bas_init == NULL)
{
return NRF_ERROR_NULL;
}
uint32_t err_code;
ble_uuid_t ble_uuid;
// Initialize service structure
p_bas->evt_handler = p_bas_init->evt_handler;
p_bas->conn_handle = BLE_CONN_HANDLE_INVALID;
p_bas->is_notification_supported = p_bas_init->support_notification;
p_bas->battery_level_last = INVALID_BATTERY_LEVEL;
// Add service
BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_BATTERY_SERVICE);
err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &p_bas->service_handle);
if (err_code != NRF_SUCCESS)
{
return err_code;
}
// Add battery level characteristic
return battery_level_char_add(p_bas, p_bas_init);
}
uint32_t ble_bas_battery_level_update(ble_bas_t * p_bas, uint8_t battery_level)
{
if (p_bas == NULL)
{
return NRF_ERROR_NULL;
}
uint32_t err_code = NRF_SUCCESS;
ble_gatts_value_t gatts_value;
if (battery_level != p_bas->battery_level_last)
{
// Initialize value struct.
memset(&gatts_value, 0, sizeof(gatts_value));
gatts_value.len = sizeof(uint8_t);
gatts_value.offset = 0;
gatts_value.p_value = &battery_level;
// Update database.
err_code = sd_ble_gatts_value_set(p_bas->conn_handle,
p_bas->battery_level_handles.value_handle,
&gatts_value);
if (err_code == NRF_SUCCESS)
{
// Save new battery value.
p_bas->battery_level_last = battery_level;
}
else
{
return err_code;
}
// Send value if connected and notifying.
if ((p_bas->conn_handle != BLE_CONN_HANDLE_INVALID) && p_bas->is_notification_supported)
{
ble_gatts_hvx_params_t hvx_params;
memset(&hvx_params, 0, sizeof(hvx_params));
hvx_params.handle = p_bas->battery_level_handles.value_handle;
hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
hvx_params.offset = gatts_value.offset;
hvx_params.p_len = &gatts_value.len;
hvx_params.p_data = gatts_value.p_value;
err_code = sd_ble_gatts_hvx(p_bas->conn_handle, &hvx_params);
}
else
{
err_code = NRF_ERROR_INVALID_STATE;
}
}
return err_code;
}

View File

@ -0,0 +1,133 @@
/* 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.
*
*/
/** @file
*
* @defgroup ble_sdk_srv_bas Battery Service
* @{
* @ingroup ble_sdk_srv
* @brief Battery Service module.
*
* @details This module implements the Battery Service with the Battery Level characteristic.
* During initialization it adds the Battery Service and Battery Level characteristic
* to the BLE stack database. Optionally it can also add a Report Reference descriptor
* to the Battery Level characteristic (used when including the Battery Service in
* the HID service).
*
* If specified, the module will support notification of the Battery Level characteristic
* through the ble_bas_battery_level_update() function.
* If an event handler is supplied by the application, the Battery Service will
* generate Battery Service events to the application.
*
* @note The application must propagate BLE stack events to the Battery Service module by calling
* ble_bas_on_ble_evt() from the @ref softdevice_handler callback.
*
* @note Attention!
* To maintain compliance with Nordic Semiconductor ASA Bluetooth profile
* qualification listings, this section of source code must not be modified.
*/
#ifndef BLE_BAS_H__
#define BLE_BAS_H__
#include <stdint.h>
#include <stdbool.h>
#include "ble.h"
#include "ble_srv_common.h"
/**@brief Battery Service event type. */
typedef enum
{
BLE_BAS_EVT_NOTIFICATION_ENABLED, /**< Battery value notification enabled event. */
BLE_BAS_EVT_NOTIFICATION_DISABLED /**< Battery value notification disabled event. */
} ble_bas_evt_type_t;
/**@brief Battery Service event. */
typedef struct
{
ble_bas_evt_type_t evt_type; /**< Type of event. */
} ble_bas_evt_t;
// Forward declaration of the ble_bas_t type.
typedef struct ble_bas_s ble_bas_t;
/**@brief Battery Service event handler type. */
typedef void (*ble_bas_evt_handler_t) (ble_bas_t * p_bas, ble_bas_evt_t * p_evt);
/**@brief Battery Service init structure. This contains all options and data needed for
* initialization of the service.*/
typedef struct
{
ble_bas_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Battery Service. */
bool support_notification; /**< TRUE if notification of Battery Level measurement is supported. */
ble_srv_report_ref_t * p_report_ref; /**< If not NULL, a Report Reference descriptor with the specified value will be added to the Battery Level characteristic */
uint8_t initial_batt_level; /**< Initial battery level */
ble_srv_cccd_security_mode_t battery_level_char_attr_md; /**< Initial security level for battery characteristics attribute */
ble_gap_conn_sec_mode_t battery_level_report_read_perm; /**< Initial security level for battery report read attribute */
} ble_bas_init_t;
/**@brief Battery Service structure. This contains various status information for the service. */
struct ble_bas_s
{
ble_bas_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Battery Service. */
uint16_t service_handle; /**< Handle of Battery Service (as provided by the BLE stack). */
ble_gatts_char_handles_t battery_level_handles; /**< Handles related to the Battery Level characteristic. */
uint16_t report_ref_handle; /**< Handle of the Report Reference descriptor. */
uint8_t battery_level_last; /**< Last Battery Level measurement passed to the Battery Service. */
uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection). */
bool is_notification_supported; /**< TRUE if notification of Battery Level is supported. */
};
/**@brief Function for initializing the Battery Service.
*
* @param[out] p_bas Battery Service structure. This structure will have to be supplied by
* the application. It will be initialized by this function, and will later
* be used to identify this particular service instance.
* @param[in] p_bas_init Information needed to initialize the service.
*
* @return NRF_SUCCESS on successful initialization of service, otherwise an error code.
*/
uint32_t ble_bas_init(ble_bas_t * p_bas, const ble_bas_init_t * p_bas_init);
/**@brief Function for handling the Application's BLE Stack events.
*
* @details Handles all events from the BLE stack of interest to the Battery Service.
*
* @note For the requirements in the BAS specification to be fulfilled,
* ble_bas_battery_level_update() must be called upon reconnection if the
* battery level has changed while the service has been disconnected from a bonded
* client.
*
* @param[in] p_bas Battery Service structure.
* @param[in] p_ble_evt Event received from the BLE stack.
*/
void ble_bas_on_ble_evt(ble_bas_t * p_bas, ble_evt_t * p_ble_evt);
/**@brief Function for updating the battery level.
*
* @details The application calls this function after having performed a battery measurement. If
* notification has been enabled, the battery level characteristic is sent to the client.
*
* @note For the requirements in the BAS specification to be fulfilled,
* this function must be called upon reconnection if the battery level has changed
* while the service has been disconnected from a bonded client.
*
* @param[in] p_bas Battery Service structure.
* @param[in] battery_level New battery measurement value (in percent of full capacity).
*
* @return NRF_SUCCESS on success, otherwise an error code.
*/
uint32_t ble_bas_battery_level_update(ble_bas_t * p_bas, uint8_t battery_level);
#endif // BLE_BAS_H__
/** @} */

View File

@ -0,0 +1,370 @@
/*
* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is confidential property of Nordic Semiconductor. The use,
* copying, transfer or disclosure of such information is prohibited except by express written
* agreement with Nordic Semiconductor.
*
*/
#include "ble_bas_c.h"
#include "ble_db_discovery.h"
#include "ble_types.h"
#include "ble_srv_common.h"
#include "ble_gattc.h"
#include "app_trace.h"
#include "sdk_common.h"
#define LOG app_trace_log /**< Debug logger macro that will be used in this file to do logging of important information over UART. */
#define TX_BUFFER_MASK 0x07 /**< TX Buffer mask, must be a mask of contiguous zeroes, followed by contiguous sequence of ones: 000...111. */
#define TX_BUFFER_SIZE (TX_BUFFER_MASK + 1) /**< Size of the send buffer, which is 1 higher than the mask. */
#define WRITE_MESSAGE_LENGTH BLE_CCCD_VALUE_LEN /**< Length of the write message for CCCD. */
typedef enum
{
READ_REQ, /**< Type identifying that this tx_message is a read request. */
WRITE_REQ /**< Type identifying that this tx_message is a write request. */
} tx_request_t;
/**@brief Structure for writing a message to the peer, i.e. CCCD.
*/
typedef struct
{
uint8_t gattc_value[WRITE_MESSAGE_LENGTH]; /**< The message to write. */
ble_gattc_write_params_t gattc_params; /**< The GATTC parameters for this message. */
} write_params_t;
/**@brief Structure for holding the data that will be transmitted to the connected central.
*/
typedef struct
{
uint16_t conn_handle; /**< Connection handle to be used when transmitting this message. */
tx_request_t type; /**< Type of message. (read or write). */
union
{
uint16_t read_handle; /**< Read request handle. */
write_params_t write_req; /**< Write request message. */
} req;
} tx_message_t;
static tx_message_t m_tx_buffer[TX_BUFFER_SIZE]; /**< Transmit buffer for the messages that will be transmitted to the central. */
static uint32_t m_tx_insert_index = 0; /**< Current index in the transmit buffer where the next message should be inserted. */
static uint32_t m_tx_index = 0; /**< Current index in the transmit buffer containing the next message to be transmitted. */
/**@brief Function for passing any pending request from the buffer to the stack.
*/
static void tx_buffer_process(void)
{
if (m_tx_index != m_tx_insert_index)
{
uint32_t err_code;
if (m_tx_buffer[m_tx_index].type == READ_REQ)
{
err_code = sd_ble_gattc_read(m_tx_buffer[m_tx_index].conn_handle,
m_tx_buffer[m_tx_index].req.read_handle,
0);
}
else
{
err_code = sd_ble_gattc_write(m_tx_buffer[m_tx_index].conn_handle,
&m_tx_buffer[m_tx_index].req.write_req.gattc_params);
}
if (err_code == NRF_SUCCESS)
{
LOG("[BAS_C]: SD Read/Write API returns Success..\r\n");
m_tx_index++;
m_tx_index &= TX_BUFFER_MASK;
}
else
{
LOG("[BAS_C]: SD Read/Write API returns error. This message sending will be "
"attempted again..\r\n");
}
}
}
/**@brief Function for handling write response events.
*
* @param[in] p_bas_c Pointer to the Battery Service Client Structure.
* @param[in] p_ble_evt Pointer to the SoftDevice event.
*/
static void on_write_rsp(ble_bas_c_t * p_bas_c, const ble_evt_t * p_ble_evt)
{
// Check if the event if on the link for this instance
if (p_bas_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle)
{
return;
}
// Check if there is any message to be sent across to the peer and send it.
tx_buffer_process();
}
/**@brief Function for handling read response events.
*
* @details This function will validate the read response and raise the appropriate
* event to the application.
*
* @param[in] p_bas_c Pointer to the Battery Service Client Structure.
* @param[in] p_ble_evt Pointer to the SoftDevice event.
*/
static void on_read_rsp(ble_bas_c_t * p_bas_c, const ble_evt_t * p_ble_evt)
{
const ble_gattc_evt_read_rsp_t * p_response;
// Check if the event if on the link for this instance
if (p_bas_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle)
{
return;
}
p_response = &p_ble_evt->evt.gattc_evt.params.read_rsp;
if (p_response->handle == p_bas_c->peer_bas_db.bl_handle)
{
ble_bas_c_evt_t evt;
evt.conn_handle = p_ble_evt->evt.gattc_evt.conn_handle;
evt.evt_type = BLE_BAS_C_EVT_BATT_READ_RESP;
evt.params.battery_level = p_response->data[0];
p_bas_c->evt_handler(p_bas_c, &evt);
}
// Check if there is any buffered transmissions and send them.
tx_buffer_process();
}
/**@brief Function for handling Handle Value Notification received from the SoftDevice.
*
* @details This function will handle the Handle Value Notification received from the SoftDevice
* and checks if it is a notification of the Battery Level measurement from the peer. If
* so, this function will decode the battery level measurement and send it to the
* application.
*
* @param[in] p_ble_bas_c Pointer to the Battery Service Client structure.
* @param[in] p_ble_evt Pointer to the BLE event received.
*/
static void on_hvx(ble_bas_c_t * p_ble_bas_c, const ble_evt_t * p_ble_evt)
{
// Check if the event if on the link for this instance
if (p_ble_bas_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle)
{
return;
}
// Check if this notification is a battery level notification.
if (p_ble_evt->evt.gattc_evt.params.hvx.handle == p_ble_bas_c->peer_bas_db.bl_handle)
{
if (p_ble_evt->evt.gattc_evt.params.hvx.len == 1)
{
ble_bas_c_evt_t ble_bas_c_evt;
ble_bas_c_evt.conn_handle = p_ble_evt->evt.gattc_evt.conn_handle;
ble_bas_c_evt.evt_type = BLE_BAS_C_EVT_BATT_NOTIFICATION;
ble_bas_c_evt.params.battery_level = p_ble_evt->evt.gattc_evt.params.hvx.data[0];
p_ble_bas_c->evt_handler(p_ble_bas_c, &ble_bas_c_evt);
}
}
}
void ble_bas_on_db_disc_evt(ble_bas_c_t * p_ble_bas_c, const ble_db_discovery_evt_t * p_evt)
{
// Check if the Battery Service was discovered.
if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE
&&
p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_BATTERY_SERVICE
&&
p_evt->params.discovered_db.srv_uuid.type == BLE_UUID_TYPE_BLE)
{
// Find the CCCD Handle of the Battery Level characteristic.
uint8_t i;
ble_bas_c_evt_t evt;
evt.evt_type = BLE_BAS_C_EVT_DISCOVERY_COMPLETE;
evt.conn_handle = p_evt->conn_handle;
for (i = 0; i < p_evt->params.discovered_db.char_count; i++)
{
if (p_evt->params.discovered_db.charateristics[i].characteristic.uuid.uuid ==
BLE_UUID_BATTERY_LEVEL_CHAR)
{
// Found Battery Level characteristic. Store CCCD handle and break.
evt.params.bas_db.bl_cccd_handle =
p_evt->params.discovered_db.charateristics[i].cccd_handle;
evt.params.bas_db.bl_handle =
p_evt->params.discovered_db.charateristics[i].characteristic.handle_value;
break;
}
}
LOG("[BAS_C]: Battery Service discovered at peer.\r\n");
//If the instance has been assigned prior to db_discovery, assign the db_handles
if(p_ble_bas_c->conn_handle != BLE_CONN_HANDLE_INVALID)
{
if ((p_ble_bas_c->peer_bas_db.bl_cccd_handle == BLE_GATT_HANDLE_INVALID)&&
(p_ble_bas_c->peer_bas_db.bl_handle == BLE_GATT_HANDLE_INVALID))
{
p_ble_bas_c->peer_bas_db = evt.params.bas_db;
}
}
p_ble_bas_c->evt_handler(p_ble_bas_c, &evt);
}
else
{
LOG("[BAS_C]: Battery Service discovery failure at peer. \r\n");
}
}
/**@brief Function for creating a message for writing to the CCCD.
*/
static uint32_t cccd_configure(uint16_t conn_handle, uint16_t handle_cccd, bool notification_enable)
{
LOG("[BAS_C]: Configuring CCCD. CCCD Handle = %d, Connection Handle = %d\r\n",
handle_cccd,conn_handle);
tx_message_t * p_msg;
uint16_t cccd_val = notification_enable ? BLE_GATT_HVX_NOTIFICATION : 0;
p_msg = &m_tx_buffer[m_tx_insert_index++];
m_tx_insert_index &= TX_BUFFER_MASK;
p_msg->req.write_req.gattc_params.handle = handle_cccd;
p_msg->req.write_req.gattc_params.len = WRITE_MESSAGE_LENGTH;
p_msg->req.write_req.gattc_params.p_value = p_msg->req.write_req.gattc_value;
p_msg->req.write_req.gattc_params.offset = 0;
p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ;
p_msg->req.write_req.gattc_value[0] = LSB_16(cccd_val);
p_msg->req.write_req.gattc_value[1] = MSB_16(cccd_val);
p_msg->conn_handle = conn_handle;
p_msg->type = WRITE_REQ;
tx_buffer_process();
return NRF_SUCCESS;
}
uint32_t ble_bas_c_init(ble_bas_c_t * p_ble_bas_c, ble_bas_c_init_t * p_ble_bas_c_init)
{
VERIFY_PARAM_NOT_NULL(p_ble_bas_c);
VERIFY_PARAM_NOT_NULL(p_ble_bas_c_init);
ble_uuid_t bas_uuid;
bas_uuid.type = BLE_UUID_TYPE_BLE;
bas_uuid.uuid = BLE_UUID_BATTERY_SERVICE;
p_ble_bas_c->conn_handle = BLE_CONN_HANDLE_INVALID;
p_ble_bas_c->peer_bas_db.bl_cccd_handle = BLE_GATT_HANDLE_INVALID;
p_ble_bas_c->peer_bas_db.bl_handle = BLE_GATT_HANDLE_INVALID;
p_ble_bas_c->evt_handler = p_ble_bas_c_init->evt_handler;
return ble_db_discovery_evt_register(&bas_uuid);
}
/**@brief Function for handling Disconnected event received from the SoftDevice.
*
* @details This function check if the disconnect event is happening on the link
* associated with the current instance of the module, if so it will set its
* conn_handle to invalid.
*
* @param[in] p_ble_bas_c Pointer to the Battery Service Client structure.
* @param[in] p_ble_evt Pointer to the BLE event received.
*/
static void on_disconnected(ble_bas_c_t * p_ble_bas_c, const ble_evt_t * p_ble_evt)
{
if (p_ble_bas_c->conn_handle == p_ble_evt->evt.gap_evt.conn_handle)
{
p_ble_bas_c->conn_handle = BLE_CONN_HANDLE_INVALID;
p_ble_bas_c->peer_bas_db.bl_cccd_handle = BLE_GATT_HANDLE_INVALID;
p_ble_bas_c->peer_bas_db.bl_handle = BLE_GATT_HANDLE_INVALID;
}
}
void ble_bas_c_on_ble_evt(ble_bas_c_t * p_ble_bas_c, const ble_evt_t * p_ble_evt)
{
if ((p_ble_bas_c == NULL) || (p_ble_evt == NULL))
{
return;
}
switch (p_ble_evt->header.evt_id)
{
case BLE_GATTC_EVT_HVX:
on_hvx(p_ble_bas_c, p_ble_evt);
break;
case BLE_GATTC_EVT_WRITE_RSP:
on_write_rsp(p_ble_bas_c, p_ble_evt);
break;
case BLE_GATTC_EVT_READ_RSP:
on_read_rsp(p_ble_bas_c, p_ble_evt);
break;
case BLE_GAP_EVT_DISCONNECTED:
on_disconnected(p_ble_bas_c, p_ble_evt);
break;
default:
break;
}
}
uint32_t ble_bas_c_bl_notif_enable(ble_bas_c_t * p_ble_bas_c)
{
VERIFY_PARAM_NOT_NULL(p_ble_bas_c);
if (p_ble_bas_c->conn_handle == BLE_CONN_HANDLE_INVALID)
{
return NRF_ERROR_INVALID_STATE;
}
return cccd_configure(p_ble_bas_c->conn_handle, p_ble_bas_c->peer_bas_db.bl_cccd_handle, true);
}
uint32_t ble_bas_c_bl_read(ble_bas_c_t * p_ble_bas_c)
{
VERIFY_PARAM_NOT_NULL(p_ble_bas_c);
if (p_ble_bas_c->conn_handle == BLE_CONN_HANDLE_INVALID)
{
return NRF_ERROR_INVALID_STATE;
}
tx_message_t * msg;
msg = &m_tx_buffer[m_tx_insert_index++];
m_tx_insert_index &= TX_BUFFER_MASK;
msg->req.read_handle = p_ble_bas_c->peer_bas_db.bl_handle;
msg->conn_handle = p_ble_bas_c->conn_handle;
msg->type = READ_REQ;
tx_buffer_process();
return NRF_SUCCESS;
}
uint32_t ble_bas_c_handles_assign(ble_bas_c_t * p_ble_bas_c,
uint16_t conn_handle,
ble_bas_c_db_t * p_peer_handles)
{
VERIFY_PARAM_NOT_NULL(p_ble_bas_c);
p_ble_bas_c->conn_handle = conn_handle;
if (p_peer_handles != NULL)
{
p_ble_bas_c->peer_bas_db = *p_peer_handles;
}
return NRF_SUCCESS;
}

View File

@ -0,0 +1,212 @@
/*
* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is confidential property of Nordic Semiconductor. The use,
* copying, transfer or disclosure of such information is prohibited except by express written
* agreement with Nordic Semiconductor.
*
*/
/**@file
*
* @defgroup ble_sdk_srv_bas_c Battery Service Client
* @{
* @ingroup ble_sdk_srv
* @brief Battery Service Client module.
*
* @details This module contains APIs to read and interact with the Battery Service of a remote
* device.
*
* @note The application must propagate BLE stack events to this module by calling
* ble_hrs_c_on_ble_evt().
*
*/
#ifndef BLE_BAS_C_H__
#define BLE_BAS_C_H__
#include <stdint.h>
#include "ble.h"
#include "ble_db_discovery.h"
/**
* @defgroup bas_c_enums Enumerations
* @{
*/
/**@brief Battery Service Client event type. */
typedef enum
{
BLE_BAS_C_EVT_DISCOVERY_COMPLETE, /**< Event indicating that the Battery Service has been discovered at the peer. */
BLE_BAS_C_EVT_BATT_NOTIFICATION, /**< Event indicating that a notification of the Battery Level characteristic has been received from the peer. */
BLE_BAS_C_EVT_BATT_READ_RESP /**< Event indicating that a read response on Battery Level characteristic has been received from peer. */
} ble_bas_c_evt_type_t;
/** @} */
/**
* @defgroup bas_c_structs Structures
* @{
*/
/**@brief Structure containing the handles related to the Battery Service found on the peer. */
typedef struct
{
uint16_t bl_cccd_handle; /**< Handle of the CCCD of the Battery Level characteristic. */
uint16_t bl_handle; /**< Handle of the Battery Level characteristic as provided by the SoftDevice. */
} ble_bas_c_db_t;
/**@brief Battery Service Client Event structure. */
typedef struct
{
ble_bas_c_evt_type_t evt_type; /**< Event Type. */
uint16_t conn_handle; /**< Connection handle relevent to this event.*/
union
{
ble_bas_c_db_t bas_db; /**< Battery Service related handles found on the peer device. This will be filled if the evt_type is @ref BLE_BAS_C_EVT_DISCOVERY_COMPLETE.*/
uint8_t battery_level; /**< Battery level received from peer. This field will be used for the events @ref BLE_BAS_C_EVT_BATT_NOTIFICATION and @ref BLE_BAS_C_EVT_BATT_READ_RESP.*/
} params;
} ble_bas_c_evt_t;
/** @} */
/**
* @defgroup bas_c_types Types
* @{
*/
// Forward declaration of the ble_bas_t type.
typedef struct ble_bas_c_s ble_bas_c_t;
/**@brief Event handler type.
*
* @details This is the type of the event handler that should be provided by the application
* of this module in order to receive events.
*/
typedef void (* ble_bas_c_evt_handler_t) (ble_bas_c_t * p_bas_bas_c, ble_bas_c_evt_t * p_evt);
/** @} */
/**
* @addtogroup bas_c_structs
* @{
*/
/**@brief Battery Service Client structure.
*/
struct ble_bas_c_s
{
uint16_t conn_handle; /**< Connection handle as provided by the SoftDevice. */
ble_bas_c_db_t peer_bas_db; /**< Handles related to BAS on the peer*/
ble_bas_c_evt_handler_t evt_handler; /**< Application event handler to be called when there is an event related to the Battery service. */
};
/**@brief Battery Service Client initialization structure.
*/
typedef struct
{
ble_bas_c_evt_handler_t evt_handler; /**< Event handler to be called by the Battery Service Client module whenever there is an event related to the Battery Service. */
} ble_bas_c_init_t;
/** @} */
/**
* @defgroup bas_c_functions Functions
* @{
*/
/**@brief Function for initializing the Battery Service Client module.
*
* @details This function will initialize the module and set up Database Discovery to discover
* the Battery Service. After calling this function, call @ref ble_db_discovery_start
* to start discovery once a link with a peer has been established.
*
* @param[out] p_ble_bas_c Pointer to the Battery Service client structure.
* @param[in] p_ble_bas_c_init Pointer to the Battery Service initialization structure containing
* the initialization information.
*
* @retval NRF_SUCCESS Operation success.
* @retval NRF_ERROR_NULL A parameter is NULL.
* Otherwise, an error code returned by @ref ble_db_discovery_evt_register.
*/
uint32_t ble_bas_c_init(ble_bas_c_t * p_ble_bas_c, ble_bas_c_init_t * p_ble_bas_c_init);
/**@brief Function for handling BLE events from the SoftDevice.
*
* @details This function will handle the BLE events received from the SoftDevice. If the BLE
* event is relevant for the Battery Service Client module, then it is used to update
* interval variables and, if necessary, send events to the application.
*
* @note This function must be called by the application.
*
* @param[in] p_ble_bas_c Pointer to the Battery Service client structure.
* @param[in] p_ble_evt Pointer to the BLE event.
*/
void ble_bas_c_on_ble_evt(ble_bas_c_t * p_ble_bas_c, const ble_evt_t * p_ble_evt);
/**@brief Function for enabling notifications on the Battery Level characteristic.
*
* @details This function will enable to notification of the Battery Level characteristic at the
* peer by writing to the CCCD of the Battery Level Characteristic.
*
* @param p_ble_bas_c Pointer to the Battery Service client structure.
*
* @retval NRF_SUCCESS If the SoftDevice has been requested to write to the CCCD of the peer.
* NRF_ERROR_NULL Parameter is NULL.
* Otherwise, an error code returned by the SoftDevice API @ref
* sd_ble_gattc_write.
*/
uint32_t ble_bas_c_bl_notif_enable(ble_bas_c_t * p_ble_bas_c);
/**@brief Function for reading the Battery Level characteristic.
*
* @param p_ble_bas_c Pointer to the Battery Service client structure.
*
* @retval NRF_SUCCESS If the read request was successfully queued to be sent to peer.
*/
uint32_t ble_bas_c_bl_read(ble_bas_c_t * p_ble_bas_c);
/**@brief Function for handling events from the database discovery module.
*
* @details Call this function when getting a callback event from the DB discovery modue.
* This function will handle an event from the database discovery module, and determine
* if it relates to the discovery of Battery service at the peer. If so, it will
* call the application's event handler indicating that the Battery service has been
* discovered at the peer. It also populates the event with the service related
* information before providing it to the application.
*
* @param p_ble_bas_c Pointer to the Battery Service client structure.
* @param[in] p_evt Pointer to the event received from the database discovery module.
*
*/
void ble_bas_on_db_disc_evt(ble_bas_c_t * p_ble_bas_c, const ble_db_discovery_evt_t * p_evt);
/**@brief Function for assigning handles to a this instance of bas_c.
*
* @details Call this function when a link has been established with a peer to
* associate this link to this instance of the module. This makes it
* possible to handle several link and associate each link to a particular
* instance of this module. The connection handle and attribute handles will be
* provided from the discovery event @ref BLE_BAS_C_EVT_DISCOVERY_COMPLETE.
*
* @param[in] p_ble_bas_c Pointer to the Battery client structure instance to associate.
* @param[in] conn_handle Connection handle to associated with the given Battery Client Instance.
* @param[in] p_peer_handles Attribute handles on the BAS server you want this BAS client to
* interact with.
*/
uint32_t ble_bas_c_handles_assign(ble_bas_c_t * p_ble_bas_c,
uint16_t conn_handle,
ble_bas_c_db_t * p_peer_handles);
/** @} */ // End tag for Function group.
#endif // BLE_BAS_C_H__
/** @} */ // End tag for the file.

Some files were not shown because too many files have changed in this diff Show More