[nRF52840] Add SoftDevice support. Changes in nrf_drv_radio802154. (#1914)

* [nRF52840] Add SoftDevice support. Changes in nrf_drv_radio802154.

* Fix alignment in Makefile.am
This commit is contained in:
Łukasz Duda
2017-06-21 00:13:10 -07:00
committed by Jonathan Hui
parent 9905c3fee1
commit 49e7977d84
83 changed files with 19391 additions and 2279 deletions
+175 -82
View File
@@ -1,5 +1,5 @@
#
# Copyright (c) 2016, The OpenThread Authors.
# Copyright (c) 2016-2017, The OpenThread Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -28,114 +28,207 @@
include $(abs_top_nlbuild_autotools_dir)/automake/pre.am
lib_LIBRARIES = \
libopenthread-nrf52840.a \
libopenthread-nrf52840-sdk.a \
lib_LIBRARIES = \
libopenthread-nrf52840.a \
libopenthread-nrf52840-sdk.a \
libopenthread-nrf52840-softdevice-sdk.a \
$(NULL)
COMMONCPPFLAGS = \
-DCONFIG_GPIO_AS_PINRESET \
-DNRF52 \
-DNRF52840_XXAA \
-I$(top_srcdir)/include \
-I$(top_srcdir)/examples/platforms \
-I$(top_srcdir)/src/core \
-I$(srcdir) \
-I$(top_srcdir)/third_party/NordicSemiconductor \
-I$(top_srcdir)/third_party/NordicSemiconductor/cmsis \
-I$(top_srcdir)/third_party/NordicSemiconductor/device \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers \
-I$(top_srcdir)/third_party/NordicSemiconductor/hal \
-I$(top_srcdir)/third_party/NordicSemiconductor/segger_rtt \
COMMONCPPFLAGS = \
-DCONFIG_GPIO_AS_PINRESET \
-DNRF52840_XXAA \
-I$(top_srcdir)/include \
-I$(top_srcdir)/examples/platforms \
-I$(top_srcdir)/src/core \
-I$(srcdir) \
-I$(top_srcdir)/third_party/NordicSemiconductor \
-I$(top_srcdir)/third_party/NordicSemiconductor/cmsis \
-I$(top_srcdir)/third_party/NordicSemiconductor/device \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/clock \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/raal \
-I$(top_srcdir)/third_party/NordicSemiconductor/hal \
-I$(top_srcdir)/third_party/NordicSemiconductor/segger_rtt \
$(NULL)
PLATFORM_SOURCES = \
alarm.c \
flash.c \
logging.c \
misc.c \
platform.c \
radio.c \
random.c \
uart.c \
platform-config.h \
platform-nrf5.h \
PLATFORM_SOURCES = \
alarm.c \
flash.c \
logging.c \
misc.c \
platform.c \
uart.c \
platform-config.h \
platform-nrf5.h \
radio.c \
random.c \
$(NULL)
SINGLEPHY_SOURCES = \
flash_nosd.c \
@top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_notification_direct.c \
@top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_priority_drop_direct.c \
@top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_request_direct.c \
@top_builddir@/third_party/NordicSemiconductor/drivers/radio/raal/single_phy/single_phy.c \
$(NULL)
SINGLEPHY_CPPFLAGS = \
-DRAAL_SINGLE_PHY=1 \
$(NULL)
SOFTDEVICE_SOURCES = \
flash_sd.c \
softdevice.c \
softdevice.h \
@top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_notification_swi.c \
@top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_priority_drop_swi.c \
@top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_request_swi.c \
@top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_swi.c \
@top_builddir@/third_party/NordicSemiconductor/drivers/radio/raal/softdevice/nrf_raal_softdevice.c \
$(NULL)
SOFTDEVICE_CPPFLAGS = \
-I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/raal/softdevice \
-I$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers \
-DSOFTDEVICE_PRESENT \
-DS140 \
-DRAAL_SOFTDEVICE=1 \
$(NULL)
if OPENTHREAD_ENABLE_DIAG
PLATFORM_SOURCES += \
diag.c \
PLATFORM_SOURCES += \
diag.c \
$(NULL)
endif
NORDICSEMI_SOURCES = \
@top_builddir@/third_party/NordicSemiconductor/hal/nrf_nvmc.c \
@top_builddir@/third_party/NordicSemiconductor/device/system_nrf52840.c \
@top_builddir@/third_party/NordicSemiconductor/drivers/nrf_drv_radio802154.c \
@top_builddir@/third_party/NordicSemiconductor/segger_rtt/SEGGER_RTT.c \
@top_builddir@/third_party/NordicSemiconductor/segger_rtt/SEGGER_RTT_Conf.h \
@top_builddir@/third_party/NordicSemiconductor/device/gcc_startup_nrf52840.S \
NORDICSEMI_SOURCES = \
@top_builddir@/third_party/NordicSemiconductor/hal/nrf_nvmc.c \
@top_builddir@/third_party/NordicSemiconductor/device/system_nrf52840.c \
@top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154.c \
@top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_ack_pending_bit.c \
@top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_critical_section.c \
@top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_debug.c \
@top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_fsm.c \
@top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_pib.c \
@top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_rx_buffer.c \
@top_builddir@/third_party/NordicSemiconductor/segger_rtt/SEGGER_RTT.c \
@top_builddir@/third_party/NordicSemiconductor/segger_rtt/SEGGER_RTT_Conf.h \
@top_builddir@/third_party/NordicSemiconductor/device/gcc_startup_nrf52840.S \
$(NULL)
libopenthread_nrf52840_a_CPPFLAGS = \
$(COMMONCPPFLAGS) \
libopenthread_nrf52840_a_CPPFLAGS = \
$(COMMONCPPFLAGS) \
$(SINGLEPHY_CPPFLAGS) \
$(NULL)
libopenthread_nrf52840_a_SOURCES = \
$(PLATFORM_SOURCES) \
$(NORDICSEMI_SOURCES) \
@top_builddir@/third_party/NordicSemiconductor/drivers/nrf_drv_clock.c \
libopenthread_nrf52840_a_SOURCES = \
$(PLATFORM_SOURCES) \
$(NORDICSEMI_SOURCES) \
$(SINGLEPHY_SOURCES) \
@top_builddir@/third_party/NordicSemiconductor/drivers/clock/nrf_drv_clock.c \
$(NULL)
libopenthread_nrf52840_sdk_a_CPPFLAGS = \
$(COMMONCPPFLAGS) \
libopenthread_nrf52840_sdk_a_CPPFLAGS = \
$(COMMONCPPFLAGS) \
$(SINGLEPHY_CPPFLAGS) \
$(NULL)
libopenthread_nrf52840_sdk_a_SOURCES = \
$(PLATFORM_SOURCES) \
$(NORDICSEMI_SOURCES) \
libopenthread_nrf52840_sdk_a_SOURCES = \
$(PLATFORM_SOURCES) \
$(NORDICSEMI_SOURCES) \
$(SINGLEPHY_SOURCES) \
$(NULL)
noinst_HEADERS = \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/arm_math.h \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/cmsis_armcc_V6.h \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/cmsis_armcc.h \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/cmsis_gcc.h \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/core_cm4.h \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/core_cmFunc.h \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/core_cmInstr.h \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/core_cmSimd.h \
$(top_srcdir)/third_party/NordicSemiconductor/device/compiler_abstraction.h \
$(top_srcdir)/third_party/NordicSemiconductor/device/nrf.h \
$(top_srcdir)/third_party/NordicSemiconductor/device/nrf51_to_nrf52.h \
$(top_srcdir)/third_party/NordicSemiconductor/device/nrf51_to_nrf52840.h \
$(top_srcdir)/third_party/NordicSemiconductor/device/nrf52_to_nrf52840.h \
$(top_srcdir)/third_party/NordicSemiconductor/device/nrf52840_bitfields.h \
$(top_srcdir)/third_party/NordicSemiconductor/device/nrf52840_peripherals.h \
$(top_srcdir)/third_party/NordicSemiconductor/device/system_nrf52840.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/nrf_drv_clock.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/nrf_drv_radio802154.h \
$(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_assert.h \
$(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_clock.h \
$(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_egu.h \
$(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_nvmc.h \
$(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_peripherals.h \
$(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_radio.h \
$(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_rng.h \
$(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_uart.h \
$(top_srcdir)/third_party/NordicSemiconductor/segger_rtt/SEGGER_RTT.h \
libopenthread_nrf52840_softdevice_sdk_a_CPPFLAGS = \
$(COMMONCPPFLAGS) \
$(SOFTDEVICE_CPPFLAGS) \
$(NULL)
PRETTY_FILES = \
$(PLATFORM_SOURCES) \
libopenthread_nrf52840_softdevice_sdk_a_SOURCES = \
$(PLATFORM_SOURCES) \
$(NORDICSEMI_SOURCES) \
$(SOFTDEVICE_SOURCES) \
$(NULL)
Dash = -
noinst_HEADERS = \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/arm_math.h \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/cmsis_armcc_V6.h \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/cmsis_armcc.h \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/cmsis_gcc.h \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/core_cm4.h \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/core_cmFunc.h \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/core_cmInstr.h \
$(top_srcdir)/third_party/NordicSemiconductor/cmsis/core_cmSimd.h \
$(top_srcdir)/third_party/NordicSemiconductor/device/compiler_abstraction.h \
$(top_srcdir)/third_party/NordicSemiconductor/device/nrf.h \
$(top_srcdir)/third_party/NordicSemiconductor/device/nrf51_to_nrf52.h \
$(top_srcdir)/third_party/NordicSemiconductor/device/nrf51_to_nrf52840.h \
$(top_srcdir)/third_party/NordicSemiconductor/device/nrf52_to_nrf52840.h \
$(top_srcdir)/third_party/NordicSemiconductor/device/nrf52840_bitfields.h \
$(top_srcdir)/third_party/NordicSemiconductor/device/nrf52840_peripherals.h \
$(top_srcdir)/third_party/NordicSemiconductor/device/system_nrf52840.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/clock/nrf_drv_clock.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_ack_pending_bit.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_config.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_const.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_critical_section.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_debug.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_fsm.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_notification.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_pib.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_priority_drop.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_procedures_duration.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_request.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_drv_radio802154_rx_buffer.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/raal/nrf_raal_api.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/raal/nrf_raal_config.h \
$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/raal/softdevice/nrf_raal_softdevice.h \
$(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_assert.h \
$(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_clock.h \
$(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_gpio.h \
$(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_gpiote.h \
$(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_egu.h \
$(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_nvmc.h \
$(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_peripherals.h \
$(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_ppi.h \
$(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_radio.h \
$(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_rng.h \
$(top_srcdir)/third_party/NordicSemiconductor/hal/nrf_uart.h \
$(top_srcdir)/third_party/NordicSemiconductor/segger_rtt/SEGGER_RTT.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble_err.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble_gap.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble_gatt.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble_gattc.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble_gatts.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble_hci.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble_l2cap.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble_ranges.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/ble_types.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/nrf_error.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/nrf_error_sdm.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/nrf_error_soc.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/nrf_nvic.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/nrf_sdm.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/nrf_soc.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/nrf_svc.h \
$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers/nrf52/nrf_mbr.h \
$(NULL)
libopenthread_nrf52840_a_LIBADD = \
PRETTY_FILES = \
$(PLATFORM_SOURCES) \
$(NULL)
Dash = -
libopenthread_nrf52840_a_LIBADD = \
$(shell find $(top_builddir)/examples/platforms/utils $(Dash)type f $(Dash)name "*.o")
libopenthread_nrf52840_sdk_a_LIBADD = \
libopenthread_nrf52840_sdk_a_LIBADD = \
$(shell find $(top_builddir)/examples/platforms/utils $(Dash)type f $(Dash)name "*.o")
libopenthread_nrf52840_softdevice_sdk_a_LIBADD = \
$(shell find $(top_builddir)/examples/platforms/utils $(Dash)type f $(Dash)name "*.o")
include $(abs_top_nlbuild_autotools_dir)/automake/post.am
+5 -4
View File
@@ -42,9 +42,10 @@
#include <openthread/platform/usec-alarm.h>
#include "platform-config.h"
#include "cmsis/cmsis_gcc.h"
#include "drivers/nrf_drv_clock.h"
#include "hal/nrf_rtc.h"
#include "cmsis/core_cmFunc.h"
#include <drivers/clock/nrf_drv_clock.h>
#include <hal/nrf_rtc.h>
#include <openthread/config.h>
#include <openthread/types.h>
@@ -414,7 +415,7 @@ void RTC_IRQ_HANDLER(void)
if (nrf_rtc_int_is_enabled(RTC_INSTANCE, sChannelData[i].mCompareInt) &&
nrf_rtc_event_pending(RTC_INSTANCE, sChannelData[i].mCompareEvent))
{
HandleCompareMatch(i, false);
HandleCompareMatch((AlarmIndex)i, false);
}
}
}
@@ -26,4 +26,8 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#define MBEDTLS_SHA256_ALT
#define MBEDTLS_SHA256_ALT
#if defined(__ICCARM__)
_Pragma("diag_suppress=Pe549")
#endif
+5 -6
View File
@@ -35,7 +35,6 @@
#include <utils/flash.h>
#include <utils/code_utils.h>
#include "hal/nrf_nvmc.h"
#include "platform-nrf5.h"
extern uint32_t __flash_data_start;
@@ -70,7 +69,7 @@ otError utilsFlashErasePage(uint32_t aAddress)
otError error = OT_ERROR_NONE;
otEXPECT_ACTION(aAddress < utilsFlashGetSize(), error = OT_ERROR_INVALID_ARGS);
nrf_nvmc_page_erase(mapAddress(aAddress & FLASH_PAGE_ADDR_MASK));
error = nrf5FlashPageErase(mapAddress(aAddress & FLASH_PAGE_ADDR_MASK));
exit:
return error;
@@ -82,7 +81,7 @@ otError utilsFlashStatusWait(uint32_t aTimeout)
if (aTimeout == 0)
{
if (NRF_NVMC->READY == NVMC_READY_READY_Ready)
if (!nrf5FlashIsBusy())
{
error = OT_ERROR_NONE;
}
@@ -93,7 +92,7 @@ otError utilsFlashStatusWait(uint32_t aTimeout)
do
{
if (NRF_NVMC->READY == NVMC_READY_READY_Ready)
if (!nrf5FlashIsBusy())
{
error = OT_ERROR_NONE;
break;
@@ -110,9 +109,9 @@ uint32_t utilsFlashWrite(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
uint32_t result = 0;
otEXPECT(aData);
otEXPECT(aAddress < utilsFlashGetSize());
otEXPECT(aSize);
nrf_nvmc_write_bytes(mapAddress(aAddress), aData, aSize);
result = aSize;
result = nrf5FlashWrite(mapAddress(aAddress), aData, aSize);
exit:
return result;
+56
View File
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2017, The OpenThread Authors.
* 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 the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
#include <stdint.h>
#include <string.h>
#include <assert.h>
#include <openthread/types.h>
#include <utils/code_utils.h>
#include <utils/flash.h>
#include "hal/nrf_nvmc.h"
#include "platform-nrf5.h"
otError nrf5FlashPageErase(uint32_t aAddress)
{
nrf_nvmc_page_erase(aAddress);
return OT_ERROR_NONE;
}
bool nrf5FlashIsBusy(void)
{
return NRF_NVMC->READY != NVMC_READY_READY_Ready;
}
uint32_t nrf5FlashWrite(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
{
nrf_nvmc_write_bytes(aAddress, aData, aSize);
return aSize;
}
+217
View File
@@ -0,0 +1,217 @@
/*
* Copyright (c) 2017, The OpenThread Authors.
* 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 the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
#include <stdint.h>
#include <string.h>
#include <assert.h>
#include <openthread/types.h>
#include <openthread/platform/alarm.h>
#include <utils/code_utils.h>
#include <utils/flash.h>
#include "platform-nrf5.h"
#include "softdevice.h"
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define FLASH_PAGE_SIZE 4096
#define FLASH_TIMEOUT 1000
typedef enum {
FLASH_STATUS_IDLE,
FLASH_STATUS_PENDING,
FLASH_STATUS_SUCCESS,
FLASH_STATUS_FAILED
} SdFlashStatus;
static volatile SdFlashStatus sFlashStatus;
void nrf5SdSocFlashProcess(uint32_t aEvtId)
{
switch (aEvtId)
{
case NRF_EVT_FLASH_OPERATION_SUCCESS:
if (sFlashStatus == FLASH_STATUS_PENDING)
{
sFlashStatus = FLASH_STATUS_SUCCESS;
}
break;
case NRF_EVT_FLASH_OPERATION_ERROR:
if (sFlashStatus == FLASH_STATUS_PENDING)
{
sFlashStatus = FLASH_STATUS_FAILED;
}
break;
default:
break;
}
}
static otError sdFlashSingleWrite(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
{
uint32_t retval;
uint32_t startTime = otPlatAlarmGetNow();
// Expect SotfDevice Flash Complete event.
sFlashStatus = FLASH_STATUS_PENDING;
retval = sd_flash_write((uint32_t *)aAddress, (uint32_t *)aData, aSize);
if (retval == NRF_SUCCESS)
{
// Wait for SoftDevice Flash Complete event.
do
{
if (sFlashStatus != FLASH_STATUS_PENDING)
{
break;
}
}
while (otPlatAlarmGetNow() - startTime < FLASH_TIMEOUT);
if (sFlashStatus != FLASH_STATUS_SUCCESS)
{
retval = NRF_ERROR_INTERNAL;
}
}
sFlashStatus = FLASH_STATUS_IDLE;
return nrf5SdErrorToOtError(retval);
}
otError nrf5FlashPageErase(uint32_t aAddress)
{
uint32_t retval;
uint32_t startTime = otPlatAlarmGetNow();
// Expect SotfDevice Flash Complete event.
sFlashStatus = FLASH_STATUS_PENDING;
retval = sd_flash_page_erase(aAddress / FLASH_PAGE_SIZE);
if (retval == NRF_SUCCESS)
{
// Wait for SoftDevice Flash Complete event.
do
{
if (sFlashStatus != FLASH_STATUS_PENDING)
{
break;
}
}
while (otPlatAlarmGetNow() - startTime < FLASH_TIMEOUT);
if (sFlashStatus != FLASH_STATUS_SUCCESS)
{
retval = NRF_ERROR_INTERNAL;
}
}
sFlashStatus = FLASH_STATUS_IDLE;
return nrf5SdErrorToOtError(retval);
}
bool nrf5FlashIsBusy(void)
{
return sFlashStatus != FLASH_STATUS_IDLE;
}
uint32_t nrf5FlashWrite(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
{
otError error = OT_ERROR_NONE;
uint32_t result = 0;
uint32_t remainder = (aAddress % sizeof(uint32_t));
uint32_t blockSize;
uint32_t blockValue;
otEXPECT(sFlashStatus == FLASH_STATUS_IDLE);
// Check if @p aAddress is aligned to full word size. If not, make additional
// flash write at the beginning.
if (remainder)
{
blockSize = MIN((sizeof(uint32_t) - remainder), aSize);
blockValue = 0xffffffff;
memcpy((uint8_t *)&blockValue + remainder, aData, blockSize);
error = sdFlashSingleWrite(aAddress - remainder,
(uint8_t *)&blockValue,
sizeof(blockValue) / sizeof(uint32_t));
otEXPECT(error == OT_ERROR_NONE);
aAddress += blockSize;
aData += blockSize;
aSize -= blockSize;
result += blockSize;
}
otEXPECT(aSize);
// Store the middle block of data.
remainder = aSize % sizeof(uint32_t);
blockSize = aSize - remainder;
error = sdFlashSingleWrite(aAddress,
aData,
blockSize / sizeof(uint32_t));
otEXPECT(error == OT_ERROR_NONE);
aAddress += blockSize;
aData += blockSize;
aSize -= blockSize;
result += blockSize;
// Store any additional bytes that didn't fit into middle block.
if (remainder)
{
blockValue = 0xffffffff;
memcpy((uint8_t *)&blockValue, aData, remainder);
error = sdFlashSingleWrite(aAddress,
(uint8_t *)&blockValue,
sizeof(blockValue) / sizeof(uint32_t));
otEXPECT(error == OT_ERROR_NONE);
result += remainder;
}
exit:
return result;
}
+3 -3
View File
@@ -146,10 +146,10 @@ void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion,
{
(void) aLogRegion;
otEXPECT(sLogInitialized == true);
char logString[LOG_PARSE_BUFFER_SIZE + 1];
uint16_t length = 0;
char logString[LOG_PARSE_BUFFER_SIZE + 1];
otEXPECT(sLogInitialized == true);
#if (LOG_TIMESTAMP_ENABLE == 1)
length += logTimestamp(logString, LOG_PARSE_BUFFER_SIZE);
+12 -4
View File
@@ -29,7 +29,13 @@
#include <openthread/types.h>
#include <openthread/platform/misc.h>
#include "device/nrf.h"
#include <device/nrf.h>
#include "platform-nrf5.h"
#if SOFTDEVICE_PRESENT
#include "softdevice.h"
#endif
static uint32_t sResetReason;
@@ -45,11 +51,13 @@ __WEAK void nrf5CryptoDeinit(void)
void nrf5MiscInit(void)
{
// Read the reason of last reset.
#if SOFTDEVICE_PRESENT
sd_power_reset_reason_get(&sResetReason);
sd_power_reset_reason_clr(0xFFFFFFFF);
#else
sResetReason = NRF_POWER->RESETREAS;
// Clear the register, as the reasons cumulate over resets.
NRF_POWER->RESETREAS = 0xFFFFFFFF;
#endif // SOFTDEVICE_PRESENT
}
void nrf5MiscDeinit(void)
@@ -40,7 +40,7 @@
#include "hal/nrf_peripherals.h"
#include "hal/nrf_radio.h"
#include <openthread-core-config.h>
#include <openthread/config.h>
/*******************************************************************************
* @section UART Driver Configuration.
@@ -143,4 +143,36 @@ void nrf5CryptoInit(void);
*/
void nrf5CryptoDeinit(void);
/**
* Function for erasing page in flash.
*
*/
otError nrf5FlashPageErase(uint32_t aAddress);
/**
* Function for checking state of flash driver.
*
*/
bool nrf5FlashIsBusy(void);
/**
* Function for writing data into flash.
*
*/
uint32_t nrf5FlashWrite(uint32_t aAddress, uint8_t *aData, uint32_t aSize);
#if SOFTDEVICE_PRESENT
/**
* Function for translating SoftDevice error into OpenThread's one.
*
*/
otError nrf5SdErrorToOtError(uint32_t aSdError);
/**
* Function for processing SoftDevice SoC events in flash module.
*
*/
void nrf5SdSocFlashProcess(uint32_t aEvtId);
#endif // SOFTDEVICE_PRESENT
#endif // PLATFORM_NRF5_H_
@@ -0,0 +1,71 @@
/*
* Copyright (c) 2017, The OpenThread Authors.
* 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 the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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
* This file includes the SoftDevice platform-specific functions.
*
*/
#ifndef PLATFORM_SOFTDEVICE_H_
#define PLATFORM_SOFTDEVICE_H_
#include <stdint.h>
/** @brief RAAL Softdevice default parameters. */
#define PLATFORM_SOFTDEVICE_RAAL_TIMESLOT_DEFAULT_LENGTH 6400
#define PLATFORM_SOFTDEVICE_RAAL_TIMESLOT_DEFAULT_ALLOC_ITERS 5
#define PLATFORM_SOFTDEVICE_RAAL_TIMESLOT_DEFAULT_SAFE_MARGIN 91
#define PLATFORM_SOFTDEVICE_RAAL_TIMESLOT_DEFAULT_TIMEOUT 100000
#define PLATFORM_SOFTDEVICE_RAAL_TIMESLOT_DEFAULT_MAX_LENGTH 120000000
#define PLATFORM_SOFTDEVICE_RAAL_DEFAULT_LF_CLK_ACCURACY_PPM 25
/** @brief RAAL Softdevice configuration parameters. */
typedef struct
{
uint32_t timeslotLength; /**< Timeslot length requested by the module in microseconds. */
uint32_t timeslotTimeout; /**< Longest acceptable delay until the start of the requested timeslot in microseconds. */
uint32_t timeslotMaxLength; /**< Maximum single timeslot length created by extension processing in microseconds. */
uint16_t timeslotAllocIters; /**< Maximum number of iteration of dividing timeslot_length by factor of 2 performed by arbiter. */
uint16_t timeslotSafeMargin; /**< Safe margin before timeslot is finished and nrf_raal_timeslot_ended should be called in microseconds. */
uint16_t lfClkAccuracyPpm; /**< Clock accuracy in ppm unit. */
} PlatformSoftdeviceRaalConfigParams;
/**
* Function for processing SoftDevice SoC events.
*
*/
void PlatformSoftdeviceSocEvtHandler(uint32_t aEvtId);
/**
* Function used to set non-default parameters of Softdevice RAAL.
*
*/
void PlatformSoftdeviceRaalConfig(const PlatformSoftdeviceRaalConfigParams *aConfig);
#endif // PLATFORM_SOFTDEVICE_H_
+8 -8
View File
@@ -34,10 +34,9 @@
#include <openthread/platform/logging.h>
#include "drivers/nrf_drv_clock.h"
#include <drivers/clock/nrf_drv_clock.h>
#include "platform-nrf5.h"
#include <openthread-core-config.h>
#include <openthread/config.h>
void __cxa_pure_virtual(void) { while (1); }
@@ -48,28 +47,29 @@ void PlatformInit(int argc, char *argv[])
(void)argv;
nrf_drv_clock_init();
#if (OPENTHREAD_ENABLE_DEFAULT_LOGGING == 0)
nrf5LogInit();
#endif
nrf5AlarmInit();
nrf5RandomInit();
nrf5UartInit();
nrf5MiscInit();
nrf5CryptoInit();
nrf5RadioInit();
#if (OPENTHREAD_CONFIG_ENABLE_DEFAULT_LOG_OUTPUT == 0)
nrf5LogInit();
#endif
}
void PlatformDeinit(void)
{
#if (OPENTHREAD_CONFIG_ENABLE_DEFAULT_LOG_OUTPUT == 0)
nrf5LogDeinit();
#endif
nrf5RadioDeinit();
nrf5CryptoDeinit();
nrf5MiscDeinit();
nrf5UartDeinit();
nrf5RandomDeinit();
nrf5AlarmDeinit();
#if (OPENTHREAD_ENABLE_DEFAULT_LOGGING == 0)
nrf5LogDeinit();
#endif
}
void PlatformProcessDrivers(otInstance *aInstance)
+21 -10
View File
@@ -50,8 +50,8 @@
#include <openthread/platform/radio.h>
#include <openthread/platform/diag.h>
#include "device/nrf.h"
#include "drivers/nrf_drv_radio802154.h"
#include <device/nrf.h>
#include <nrf_drv_radio802154.h>
#include <openthread-core-config.h>
#include <openthread/config.h>
@@ -70,8 +70,19 @@ static bool sDisabled;
static otRadioFrame sReceivedFrames[RADIO_RX_BUFFERS];
static otRadioFrame sTransmitFrame;
#if defined ( __GNUC__ )
static uint8_t sTransmitPsdu[OT_RADIO_FRAME_MAX_SIZE + 1]
__attribute__((section("nrf_radio_buffer.sTransmiPsdu")));
#elif defined ( __ICCARM__ )
#pragma location="NRF_RADIO_BUFFER"
static uint8_t sTransmitPsdu[OT_RADIO_FRAME_MAX_SIZE + 1];
#endif
static otRadioFrame sAckFrame;
static uint32_t sEnergyDetectionTime;
@@ -121,10 +132,10 @@ static void setPendingEvent(RadioPendingEvents aEvent)
do
{
pendingEvents = __LDREXW(&sPendingEvents);
pendingEvents = __LDREXW((unsigned long volatile *)&sPendingEvents);
pendingEvents |= bitToSet;
}
while (__STREXW(pendingEvents, &sPendingEvents));
while (__STREXW(pendingEvents, (unsigned long volatile *)&sPendingEvents));
}
static void resetPendingEvent(RadioPendingEvents aEvent)
@@ -134,10 +145,10 @@ static void resetPendingEvent(RadioPendingEvents aEvent)
do
{
pendingEvents = __LDREXW(&sPendingEvents);
pendingEvents = __LDREXW((unsigned long volatile *)&sPendingEvents);
pendingEvents &= bitsToRemain;
}
while (__STREXW(pendingEvents, &sPendingEvents));
while (__STREXW(pendingEvents, (unsigned long volatile *)&sPendingEvents));
}
static inline void clearPendingEvents(void)
@@ -153,18 +164,18 @@ static inline void clearPendingEvents(void)
do
{
pendingEvents = __LDREXW(&sPendingEvents);
pendingEvents = __LDREXW((unsigned long volatile *)&sPendingEvents);
pendingEvents &= bitsToRemain;
}
while (__STREXW(pendingEvents, &sPendingEvents));
while (__STREXW(pendingEvents, (unsigned long volatile *)&sPendingEvents));
}
void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64)
{
(void) aInstance;
uint64_t factoryAddress;
factoryAddress = (((uint64_t)NRF_FICR->DEVICEID[0] << 32) | NRF_FICR->DEVICEID[1]);
uint64_t factoryAddress = (uint64_t)NRF_FICR->DEVICEID[0] << 32;
factoryAddress |= NRF_FICR->DEVICEID[1];
memcpy(aIeeeEui64, &factoryAddress, sizeof(factoryAddress));
}
+106 -62
View File
@@ -39,16 +39,21 @@
#include <openthread/platform/random.h>
#include <utils/code_utils.h>
#include "hal/nrf_rng.h"
#include "platform-nrf5.h"
#if SOFTDEVICE_PRESENT
#include "softdevice.h"
#else
#include <hal/nrf_rng.h>
static uint8_t sBuffer[RNG_BUFFER_SIZE];
static volatile uint32_t sReadPosition;
static volatile uint32_t sWritePosition;
static inline uint32_t bufferCount(void)
{
return (sWritePosition - sReadPosition);
uint32_t writePos = sWritePosition;
return writePos - sReadPosition;
}
static inline bool bufferIsEmpty(void)
@@ -115,66 +120,6 @@ static void generatorStop(void)
nrf_rng_task_trigger(NRF_RNG_TASK_STOP);
}
void nrf5RandomInit(void)
{
memset(sBuffer, 0, sizeof(sBuffer));
sReadPosition = 0;
sWritePosition = 0;
NVIC_SetPriority(RNG_IRQn, RNG_IRQ_PRIORITY);
NVIC_ClearPendingIRQ(RNG_IRQn);
NVIC_EnableIRQ(RNG_IRQn);
nrf_rng_error_correction_enable();
nrf_rng_shorts_disable(NRF_RNG_SHORT_VALRDY_STOP_MASK);
generatorStart();
// Wait for the first randomized 4 bytes, to randomize software generator seed.
while (!bufferIsUint32Ready()) ;
uint32_t seed = bufferGetUint32();
srand(seed);
}
void nrf5RandomDeinit(void)
{
generatorStop();
NVIC_DisableIRQ(RNG_IRQn);
NVIC_ClearPendingIRQ(RNG_IRQn);
NVIC_SetPriority(RNG_IRQn, 0);
}
uint32_t otPlatRandomGet(void)
{
return (uint32_t)rand();
}
otError otPlatRandomGetTrue(uint8_t *aOutput, uint16_t aOutputLength)
{
otError error = OT_ERROR_NONE;
otEXPECT_ACTION(aOutput, error = OT_ERROR_INVALID_ARGS);
otEXPECT_ACTION(!bufferIsEmpty(), error = OT_ERROR_FAILED);
uint16_t copyLength = (uint16_t)bufferCount();
if (copyLength > aOutputLength)
{
copyLength = aOutputLength;
}
for (uint32_t i = 0; i < copyLength; i++)
{
aOutput[i] = bufferGet();
}
generatorStart();
exit:
return error;
}
void RNG_IRQHandler(void)
{
if (nrf_rng_event_get(NRF_RNG_EVENT_VALRDY) &&
@@ -190,3 +135,102 @@ void RNG_IRQHandler(void)
}
}
}
#endif // SOFTDEVICE_PRESENT
void nrf5RandomInit(void)
{
uint32_t seed = 0;
#if SOFTDEVICE_PRESENT
uint32_t retval;
do
{
// Wait for the first randomized 4 bytes, to randomize software generator seed.
retval = sd_rand_application_vector_get((uint8_t *)&seed, sizeof(seed));
}
while (retval != NRF_SUCCESS && seed == 0);
#else // SOFTDEVICE_PRESENT
memset(sBuffer, 0, sizeof(sBuffer));
sReadPosition = 0;
sWritePosition = 0;
NVIC_SetPriority(RNG_IRQn, RNG_IRQ_PRIORITY);
NVIC_ClearPendingIRQ(RNG_IRQn);
NVIC_EnableIRQ(RNG_IRQn);
nrf_rng_error_correction_enable();
nrf_rng_shorts_disable(NRF_RNG_SHORT_VALRDY_STOP_MASK);
generatorStart();
// Wait for the first randomized 4 bytes, to randomize software generator seed.
while (!bufferIsUint32Ready()) ;
seed = bufferGetUint32();
#endif // SOFTDEVICE_PRESENT
srand(seed);
}
void nrf5RandomDeinit(void)
{
#ifndef SOFTDEVICE_PRESENT
generatorStop();
NVIC_DisableIRQ(RNG_IRQn);
NVIC_ClearPendingIRQ(RNG_IRQn);
NVIC_SetPriority(RNG_IRQn, 0);
#endif // SOFTDEVICE_PRESENT
}
uint32_t otPlatRandomGet(void)
{
return (uint32_t)rand();
}
otError otPlatRandomGetTrue(uint8_t *aOutput, uint16_t aOutputLength)
{
otError error = OT_ERROR_NONE;
uint8_t copyLength;
uint16_t index = 0;
otEXPECT_ACTION(aOutput && aOutputLength, error = OT_ERROR_INVALID_ARGS);
do
{
#if SOFTDEVICE_PRESENT
sd_rand_application_bytes_available_get(&copyLength);
#else // SOFTDEVICE_PRESENT
copyLength = (uint8_t)bufferCount();
#endif // SOFTDEVICE_PRESENT
if (copyLength > aOutputLength - index)
{
copyLength = aOutputLength - index;
}
if (copyLength > 0)
{
#if SOFTDEVICE_PRESENT
uint32_t retval = sd_rand_application_vector_get(aOutput + index, copyLength);
otEXPECT_ACTION(retval == NRF_SUCCESS, error = OT_ERROR_FAILED);
#else // SOFTDEVICE_PRESENT
for (uint32_t i = 0; i < copyLength; i++)
{
aOutput[i + index] = bufferGet();
}
generatorStart();
#endif // SOFTDEVICE_PRESENT
index += copyLength;
}
}
while (index < aOutputLength);
exit:
return error;
}
+102
View File
@@ -0,0 +1,102 @@
/*
* Copyright (c) 2017, The OpenThread Authors.
* 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 the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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
* This file implements the OpenThread softdevice helper functions.
*
*/
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "softdevice.h"
#include "platform-softdevice.h"
#include "platform-nrf5.h"
#include <openthread/types.h>
#include <nrf_raal_softdevice.h>
otError nrf5SdErrorToOtError(uint32_t aSdError)
{
switch (aSdError)
{
case NRF_SUCCESS:
return OT_ERROR_NONE;
break;
case NRF_ERROR_INVALID_STATE:
case NRF_ERROR_BUSY:
return OT_ERROR_INVALID_STATE;
break;
case NRF_ERROR_INVALID_PARAM:
case NRF_ERROR_INVALID_ADDR:
return OT_ERROR_INVALID_ARGS;
break;
case NRF_ERROR_NO_MEM:
return OT_ERROR_NO_BUFS;
break;
case NRF_ERROR_NOT_FOUND:
return OT_ERROR_NOT_FOUND;
break;
case NRF_ERROR_NOT_SUPPORTED:
return OT_ERROR_NOT_IMPLEMENTED;
break;
default:
return OT_ERROR_FAILED;
break;
}
}
void PlatformSoftdeviceSocEvtHandler(uint32_t aEvtId)
{
nrf5SdSocFlashProcess(aEvtId);
nrf_raal_softdevice_soc_evt_handler(aEvtId);
}
void PlatformSoftdeviceRaalConfig(const PlatformSoftdeviceRaalConfigParams *aConfig)
{
nrf_raal_softdevice_cfg_t cfg;
memset(&cfg, 0, sizeof(cfg));
cfg.timeslot_length = aConfig->timeslotLength;
cfg.timeslot_timeout = aConfig->timeslotTimeout;
cfg.timeslot_max_length = aConfig->timeslotMaxLength;
cfg.timeslot_alloc_iters = aConfig->timeslotAllocIters;
cfg.timeslot_safe_margin = aConfig->timeslotSafeMargin;
cfg.lf_clk_accuracy_ppm = aConfig->lfClkAccuracyPpm;
nrf_raal_softdevice_config(&cfg);
}
+54
View File
@@ -0,0 +1,54 @@
/*
* Copyright (c) 2017, The OpenThread Authors.
* 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 the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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
* This file includes the common SoftDevice headers.
*
*/
#ifndef SOFTDEVICE_H_
#define SOFTDEVICE_H_
#if defined ( __GNUC__ )
_Pragma("GCC diagnostic push")
_Pragma("GCC diagnostic ignored \"-Wreturn-type\"")
_Pragma("GCC diagnostic ignored \"-Wunused-parameter\"")
_Pragma("GCC diagnostic ignored \"-Wpedantic\"")
#endif
#include <nrf_svc.h>
#include <nrf_sdm.h>
#include <nrf_soc.h>
#include <nrf_nvic.h>
#if defined ( __GNUC__ )
_Pragma("GCC diagnostic pop")
#endif
#endif // SOFTDEVICE_H_
+5 -5
View File
@@ -39,9 +39,9 @@
#include <openthread/platform/uart.h>
#include <utils/code_utils.h>
#include "drivers/nrf_drv_clock.h"
#include "hal/nrf_uart.h"
#include "hal/nrf_gpio.h"
#include <drivers/clock/nrf_drv_clock.h>
#include <hal/nrf_uart.h>
#include <hal/nrf_gpio.h>
#include "platform-nrf5.h"
/**
@@ -86,11 +86,11 @@ static __INLINE bool isRxBufferEmpty()
*/
static void processReceive(void)
{
otEXPECT(isRxBufferEmpty() == false);
// Set head position to not be changed during read procedure.
uint16_t head = sReceiveHead;
otEXPECT(isRxBufferEmpty() == false);
// In case head roll back to the beginning of the buffer, notify about left
// bytes from the end of the buffer.
if (head < sReceiveTail)
+13 -11
View File
@@ -1,16 +1,18 @@
Description:
This folder consists of selected components from the Nordic Semiconductor SDK, that are used
in process of build the OpenThread's nRF52840 platform.
This folder consists of selected components from the nRF5 SDK, that are used
in process of building the OpenThread's nRF52840 platform.
SDK URL: http://developer.nordicsemi.com/nRF5_SDK/nRF5_SDK_v12.x.x/nRF5_SDK_12.2.0_f012efa.zip
Version: 12.2.0
nRF5 SDKs used:
- nRF5 SDK 12.2.0: [URL][nrf5-sdk-12-2-0]
- nRF5 SDK 13.0.0: [URL][nrf5-sdk-13-0-0]
Directory consists of following folders:
/cmsis - Core Peripheral Access Layer Headers files
/device - MDK for the nRF52840 chip
/drivers - Drivers for the nRF52840 that are used in the platform
/hal - Hardware Access Layer for the nRF52840 chip
/segger_rtt - Library for the RTT communication
- /cmsis - Core Peripheral Access Layer Headers files (nRF5 SDK 12.2.0)
- /device - MDK for the nRF52840 chip (nRF5 SDK 12.2.0)
- /drivers - Drivers for the nRF52840 that are used in the platform (custom files)
- /hal - Hardware Access Layer for the nRF52840 chip (nRF5 SDK 12.2.0)
- /segger_rtt - Library for the RTT communication (nRF5 SDK 12.2.0)
- /softdevice - SoftDevice s140 headers (nRF5 SDK 13.0.0)
License:
The source code is distrubuted under BSD license.
[nrf5-sdk-12-2-0]: http://developer.nordicsemi.com/nRF5_SDK/nRF5_SDK_v12.x.x/nRF5_SDK_12.2.0_f012efa.zip
[nrf5-sdk-13-0-0]: http://developer.nordicsemi.com/nRF5_SDK/nRF5_SDK_v13.x.x/nRF5_SDK_13.0.0_04a0bfd.zip
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,271 @@
/* Copyright (c) 2017, 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 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.
*
*/
/**
* @file
* This file implements the nrf 802.15.4 radio driver.
*
*/
#include "nrf_drv_radio802154.h"
#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "nrf_drv_radio802154_ack_pending_bit.h"
#include "nrf_drv_radio802154_debug.h"
#include "nrf_drv_radio802154_fsm.h"
#include "nrf_drv_radio802154_notification.h"
#include "nrf_drv_radio802154_pib.h"
#include "nrf_drv_radio802154_priority_drop.h"
#include "nrf_drv_radio802154_request.h"
#include "nrf_drv_radio802154_rx_buffer.h"
#include "hal/nrf_radio.h"
#include "raal/nrf_raal_api.h"
#include <cmsis/core_cmFunc.h>
uint8_t nrf_drv_radio802154_channel_get(void)
{
return nrf_drv_radio802154_pib_channel_get();
}
void nrf_drv_radio802154_ack_tx_power_set(int8_t power)
{
nrf_drv_radio802154_pib_tx_power_set(power);
}
void nrf_drv_radio802154_pan_id_set(const uint8_t * p_pan_id)
{
nrf_drv_radio802154_pib_pan_id_set(p_pan_id);
}
void nrf_drv_radio802154_extended_address_set(const uint8_t * p_extended_address)
{
nrf_drv_radio802154_pib_extended_address_set(p_extended_address);
}
void nrf_drv_radio802154_short_address_set(const uint8_t * p_short_address)
{
nrf_drv_radio802154_pib_short_address_set(p_short_address);
}
void nrf_drv_radio802154_init(void)
{
nrf_drv_radio802154_ack_pending_bit_init();
nrf_drv_radio802154_debug_init();
nrf_drv_radio802154_fsm_init();
nrf_drv_radio802154_notification_init();
nrf_drv_radio802154_pib_init();
nrf_drv_radio802154_priority_drop_init();
nrf_drv_radio802154_request_init();
nrf_drv_radio802154_rx_buffer_init();
nrf_raal_init();
}
void nrf_drv_radio802154_deinit(void)
{
nrf_drv_radio802154_fsm_deinit();
}
nrf_drv_radio802154_state_t nrf_drv_radio802154_state_get(void)
{
switch (nrf_drv_radio802154_fsm_state_get())
{
case RADIO_STATE_DISABLING:
case RADIO_STATE_SLEEP:
return NRF_DRV_RADIO802154_STATE_SLEEP;
case RADIO_STATE_WAITING_TIMESLOT:
case RADIO_STATE_WAITING_RX_FRAME:
case RADIO_STATE_RX_HEADER:
case RADIO_STATE_RX_FRAME:
case RADIO_STATE_TX_ACK:
return NRF_DRV_RADIO802154_STATE_RECEIVE;
case RADIO_STATE_CCA:
case RADIO_STATE_TX_FRAME:
case RADIO_STATE_RX_ACK:
return NRF_DRV_RADIO802154_STATE_TRANSMIT;
case RADIO_STATE_ED:
return NRF_DRV_RADIO802154_STATE_ENERGY_DETECTION;
}
return NRF_DRV_RADIO802154_STATE_INVALID;
}
bool nrf_drv_radio802154_sleep(void)
{
nrf_drv_radio802154_log(EVENT_TRACE_ENTER, FUNCTION_SLEEP);
bool result = true;
switch (nrf_drv_radio802154_fsm_state_get())
{
case RADIO_STATE_DISABLING:
case RADIO_STATE_SLEEP:
break;
case RADIO_STATE_WAITING_TIMESLOT:
case RADIO_STATE_WAITING_RX_FRAME:
case RADIO_STATE_RX_HEADER:
case RADIO_STATE_RX_FRAME:
case RADIO_STATE_TX_ACK:
result = nrf_drv_radio802154_request_sleep();
break;
default:
assert(false);
}
nrf_drv_radio802154_log(EVENT_TRACE_EXIT, FUNCTION_SLEEP);
return result;
}
void nrf_drv_radio802154_receive(uint8_t channel)
{
bool result;
nrf_drv_radio802154_log(EVENT_TRACE_ENTER, FUNCTION_RECEIVE);
result = nrf_drv_radio802154_request_receive(channel);
assert(result == true);
nrf_drv_radio802154_log(EVENT_TRACE_EXIT, FUNCTION_RECEIVE);
}
bool nrf_drv_radio802154_transmit(const uint8_t * p_data, uint8_t channel, int8_t power)
{
bool result;
nrf_drv_radio802154_log(EVENT_TRACE_ENTER, FUNCTION_TRANSMIT);
result = nrf_drv_radio802154_request_transmit(p_data, channel, power);
nrf_drv_radio802154_log(EVENT_TRACE_EXIT, FUNCTION_TRANSMIT);
return result;
}
bool nrf_drv_radio802154_energy_detection(uint8_t channel, uint32_t time_us)
{
bool result;
nrf_drv_radio802154_log(EVENT_TRACE_ENTER, FUNCTION_ENERGY_DETECTION);
result = nrf_drv_radio802154_request_energy_detection(channel, time_us);
nrf_drv_radio802154_log(EVENT_TRACE_EXIT, FUNCTION_ENERGY_DETECTION);
return result;
}
void nrf_drv_radio802154_buffer_free(uint8_t * p_data)
{
rx_buffer_t * p_buffer = (rx_buffer_t *)p_data;
assert(p_buffer->free == false);
nrf_drv_radio802154_log(EVENT_TRACE_ENTER, FUNCTION_BUFFER_FREE);
nrf_drv_radio802154_request_buffer_free(p_data);
nrf_drv_radio802154_log(EVENT_TRACE_EXIT, FUNCTION_BUFFER_FREE);
}
int8_t nrf_drv_radio802154_rssi_last_get(void)
{
uint8_t minus_dbm = nrf_radio_rssi_sample_get();
return - (int8_t)minus_dbm;
}
bool nrf_drv_radio802154_promiscuous_get(void)
{
return nrf_drv_radio802154_pib_promiscuous_get();
}
void nrf_drv_radio802154_promiscuous_set(bool enabled)
{
nrf_drv_radio802154_pib_promiscuous_set(enabled);
}
void nrf_drv_radio802154_auto_ack_set(bool enabled)
{
nrf_drv_radio802154_pib_auto_ack_set(enabled);
}
bool nrf_drv_radio802154_auto_ack_get(void)
{
return nrf_drv_radio802154_pib_auto_ack_get();
}
void nrf_drv_radio802154_auto_pending_bit_set(bool enabled)
{
nrf_drv_radio802154_ack_pending_bit_set(enabled);
}
bool nrf_drv_radio802154_pending_bit_for_addr_set(const uint8_t * p_addr, bool extended)
{
return nrf_drv_radio802154_ack_pending_bit_for_addr_set(p_addr, extended);
}
bool nrf_drv_radio802154_pending_bit_for_addr_clear(const uint8_t * p_addr, bool extended)
{
return nrf_drv_radio802154_ack_pending_bit_for_addr_clear(p_addr, extended);
}
void nrf_drv_radio802154_pending_bit_for_addr_reset(bool extended)
{
nrf_drv_radio802154_ack_pending_bit_for_addr_reset(extended);
}
__WEAK void nrf_drv_radio802154_received(uint8_t * p_data, int8_t power, int8_t lqi)
{
(void) p_data;
(void) power;
(void) lqi;
}
__WEAK void nrf_drv_radio802154_transmitted(uint8_t * p_ack, int8_t power, int8_t lqi)
{
(void) p_ack;
(void) power;
(void) lqi;
}
__WEAK void nrf_drv_radio802154_busy_channel(void)
{
}
__WEAK void nrf_drv_radio802154_energy_detected(int8_t result)
{
(void) result;
}
@@ -1,4 +1,4 @@
/* Copyright (c) 2016, Nordic Semiconductor ASA
/* Copyright (c) 2017, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
*
*/
#ifndef NRF_RADIO802154_H_
#define NRF_RADIO802154_H_
#ifndef NRF_DRV_RADIO802154_H_
#define NRF_DRV_RADIO802154_H_
#include <stdbool.h>
#include <stdint.h>
@@ -185,15 +185,16 @@ bool nrf_drv_radio802154_transmit(const uint8_t *p_data, uint8_t channel, int8_t
/**
* @brief Change radio state to Energy Detection.
*
* @note This function should be called in Receive state. In other states energy detection
* procedure will be scheduled.
* @note This function should be called in Receive state or Sleep state.
* @note If this function is called in Sleep state nrf_drv_radio802154_energy_detected() may be
* called before nrf_drv_radio802154_energy_detection() returns result.
*
* In Energy Detection state radio detects maximum energy for given time. Result of the detection
* is reported to the higher layer by nrf_radio802154_energy_detected() call.
* is reported to the higher layer by nrf_drv_radio802154_energy_detected() call.
*
* @param[in] channel Channel number on which radio will detect energy.
* @param[in] time_us Duration of energy detection procedure. Given value is rounded up to
* multiplication of 10s (128 us).
* multiplication of 8s (128 us).
*
* @return true If the energy detection procedure was scheduled.
* @return false If the driver could not schedule the energy detection procedure.
@@ -218,39 +219,40 @@ bool nrf_drv_radio802154_energy_detection(uint8_t channel, uint32_t time_us);
* @param[in] power RSSI of received frame.
* @param[in] lqi LQI of received frame.
*/
void nrf_drv_radio802154_received(uint8_t * p_data, int8_t power, int8_t lqi);
extern void nrf_drv_radio802154_received(uint8_t * p_data, int8_t power, int8_t lqi);
/**
* @brief Notify that frame was transmitted.
*
* @note If ACK was requested for transmitted frame this function is called after proper ACK is
* received. If ACK was not requested this function is called just after transmission ends.
* received. If ACK was not requested this function is called just after transmission is
* ended.
* @note Buffer pointed by the p_ack pointer is not modified by the radio driver (and can't
* be used to receive a frame) until nrf_drv_radio802154_buffer_free() function is called.
* @note Buffer pointed by the p_ack pointer may be modified by the function handler (and other
* modules) until nrf_drv_radio802154_buffer_free() function is called.
*
* @param[in] p_ack Pointer to received ACK buffer. The first byte in the buffer is length of the
* @param[in] p_ack Pointer to received ACK buffer. Fist byte in the buffer is length of the
* frame and following bytes are the ACK frame itself (after PHR).
* If ACK was not requested @p p_ack is set to NULL.
* @param[in] power RSSI of received ACK frame or 0 if ACK was not requested.
* @param[in] lqi LQI of received ACK frame or 0 if ACK was not requested.
* @param[in] power RSSI of received frame or 0 if ACK was not requested.
* @param[in] lqi LQI of received frame or 0 if ACK was not requested.
*/
void nrf_drv_radio802154_transmitted(uint8_t * p_ack, int8_t power, int8_t lqi);
extern void nrf_drv_radio802154_transmitted(uint8_t * p_ack, int8_t power, int8_t lqi);
/**
* @brief Notify that frame was not transmitted due to busy channel.
*
* This function is called if CCA procedure (performed just before transmission) fails.
*/
void nrf_drv_radio802154_busy_channel(void);
extern void nrf_drv_radio802154_busy_channel(void);
/**
* @brief Notify that Energy Detection procedure finished.
*
* @param[in] result Maximum energy detected during Energy Detection procedure.
*/
void nrf_drv_radio802154_energy_detected(int8_t result);
extern void nrf_drv_radio802154_energy_detected(int8_t result);
/**
@@ -297,6 +299,8 @@ int8_t nrf_drv_radio802154_rssi_last_get(void);
/**
* @brief Enable or disable promiscuous radio mode.
*
* @note Promiscuous mode is disabled by default.
*
* In promiscuous mode driver notifies higher layer that it received any frame (regardless
* frame type or destination address).
* In normal mode (not promiscuous) higher layer is not notified about ACK frames and frames with
@@ -316,12 +320,41 @@ bool nrf_drv_radio802154_promiscuous_get(void);
/**
* @section Setting pending bit in automatically transmitted ACK frames.
* @section Auto ACK management.
*/
/**
* @brief Enable or disable auto ACK procedure.
*
* @note Auto ACK procedure is enabled by default.
*
* If auto ACK procedure is enabled the driver prepares and sends ACK frames automatically
* aTurnaroundTime (192 us) after proper frame is received. The driver sets sequence number in
* the ACK frame and pending bit according to auto pending bit feature settings. When auto ACK
* procedure is enabled the driver notifies the next higher layer about received frame after ACK
* frame is transmitted.
* If auto ACK procedure is disabled the driver does not transmit ACK frames. It notifies the next
* higher layer about received frame when a frame is received. In this mode the next higher layer
* is responsible for sending ACK frame. ACK frames should be sent using
* nrf_drv_radio802154_transmit() function.
*
* @param[in] enabled If auto ACK procedure should be enabled.
*/
void nrf_drv_radio802154_auto_ack_set(bool enabled);
/**
* @brief Check if auto ACK procedure is enabled.
*
* @retval True Auto ACK procedure is enabled.
* @retval False Auto ACK procedure is disabled.
*/
bool nrf_drv_radio802154_auto_ack_get(void);
/**
* @brief Enable or disable setting pending bit in automatically transmitted ACK frames.
*
* @note Setting pending bit in automatically transmitted ACK frames is enabled by default.
*
* Radio driver automatically sends ACK frames in response to unicast frames destined to this node.
* Pending bit in ACK frame can be set or cleared regarding data in pending buffer destined to ACK
* destination.
@@ -372,4 +405,4 @@ void nrf_drv_radio802154_pending_bit_for_addr_reset(bool extended);
}
#endif
#endif /* NRF_RADIO802154_H_ */
#endif /* NRF_DRV_RADIO802154_H_ */
@@ -0,0 +1,238 @@
/* Copyright (c) 2017, 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 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.
*
*/
/**
* @file
* This file implements procedures to set pending bit in nRF 802.15.4 radio driver.
*
*/
#include "nrf_drv_radio802154_ack_pending_bit.h"
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "nrf_drv_radio802154_config.h"
#include "nrf_drv_radio802154_const.h"
#include "hal/nrf_radio.h"
// Maximum number of Short Addresses of nodes for which there is pending data in buffer.
#define NUM_PENDING_SHORT_ADDRESSES RADIO_PENDING_SHORT_ADDRESSES
// Maximum number of Extended Addresses of nodes for which there is pending data in buffer.
#define NUM_PENDING_EXTENDED_ADDRESSES RADIO_PENDING_EXTENDED_ADDRESSES
// Value used to mark Short Address as unused.
#define UNUSED_PENDING_SHORT_ADDRESS ((uint8_t [SHORT_ADDRESS_SIZE]) {0xff, 0xff})
// Value used to mark Extended Address as unused.
#define UNUSED_PENDING_EXTENDED_ADDRESS ((uint8_t [EXTENDED_ADDRESS_SIZE]) {0})
// If pending bit in ACK frame should be set to valid or default value.
static bool m_setting_pending_bit_enabled;
// Array of Short Addresses of nodes for which there is pending data in the buffer.
static uint8_t m_pending_short[NUM_PENDING_SHORT_ADDRESSES][SHORT_ADDRESS_SIZE];
// Array of Extended Addresses of nodes for which there is pending data in the buffer.
static uint8_t m_pending_extended[NUM_PENDING_EXTENDED_ADDRESSES][EXTENDED_ADDRESS_SIZE];
void nrf_drv_radio802154_ack_pending_bit_init(void)
{
memset(m_pending_extended, 0, sizeof(m_pending_extended));
memset(m_pending_short, 0xff, sizeof(m_pending_short));
m_setting_pending_bit_enabled = true;
}
void nrf_drv_radio802154_ack_pending_bit_set(bool enabled)
{
m_setting_pending_bit_enabled = enabled;
}
bool nrf_drv_radio802154_ack_pending_bit_for_addr_set(const uint8_t * p_addr, bool extended)
{
uint8_t * p_empty_slot = NULL;
if (extended)
{
for (uint32_t i = 0; i < NUM_PENDING_EXTENDED_ADDRESSES; i++)
{
if (0 == memcmp(m_pending_extended[i], p_addr, sizeof(m_pending_extended[i])))
{
return true;
}
if (0 == memcmp(m_pending_extended[i], UNUSED_PENDING_EXTENDED_ADDRESS, sizeof(m_pending_extended[i])))
{
p_empty_slot = m_pending_extended[i];
}
}
if (p_empty_slot != NULL)
{
memcpy(p_empty_slot, p_addr, EXTENDED_ADDRESS_SIZE);
return true;
}
}
else
{
for (uint32_t i = 0; i < NUM_PENDING_SHORT_ADDRESSES; i++)
{
if (0 == memcmp(m_pending_short[i], p_addr, sizeof(m_pending_short[i])))
{
return true;
}
if (0 == memcmp(m_pending_short[i], UNUSED_PENDING_SHORT_ADDRESS, sizeof(m_pending_short[i])))
{
p_empty_slot = m_pending_short[i];
}
}
if (p_empty_slot != NULL)
{
memcpy(p_empty_slot, p_addr, SHORT_ADDRESS_SIZE);
return true;
}
}
return false;
}
bool nrf_drv_radio802154_ack_pending_bit_for_addr_clear(const uint8_t * p_addr, bool extended)
{
bool result = false;
if (extended)
{
for (uint32_t i = 0; i < NUM_PENDING_EXTENDED_ADDRESSES; i++)
{
if (0 == memcmp(m_pending_extended[i], p_addr, sizeof(m_pending_extended[i])))
{
memset(m_pending_extended[i], 0, sizeof(m_pending_extended[i]));
result = true;
}
}
}
else
{
for (uint32_t i = 0; i < NUM_PENDING_SHORT_ADDRESSES; i++)
{
if (0 == memcmp(m_pending_short[i], p_addr, sizeof(m_pending_short[i])))
{
memset(m_pending_short[i], 0xff, sizeof(m_pending_short[i]));
result = true;
}
}
}
return result;
}
void nrf_drv_radio802154_ack_pending_bit_for_addr_reset(bool extended)
{
if (extended)
{
memset(m_pending_extended, 0, sizeof(m_pending_extended));
}
else
{
memset(m_pending_short, 0xff, sizeof(m_pending_short));
}
}
bool nrf_drv_radio802154_ack_pending_bit_should_be_set(const uint8_t * p_psdu)
{
const uint8_t * p_src_addr;
uint32_t i;
// If automatic setting of pending bit in ACK frames is disabled the pending bit is always set.
if (!m_setting_pending_bit_enabled)
{
return true;
}
switch (p_psdu[DEST_ADDR_TYPE_OFFSET] & DEST_ADDR_TYPE_MASK)
{
case DEST_ADDR_TYPE_SHORT:
p_src_addr = &p_psdu[SRC_ADDR_OFFSET_SHORT_DST];
break;
case DEST_ADDR_TYPE_EXTENDED:
p_src_addr = &p_psdu[SRC_ADDR_OFFSET_EXTENDED_DST];
break;
default:
return true;
}
if (0 == (p_psdu[PAN_ID_COMPR_OFFSET] & PAN_ID_COMPR_MASK))
{
p_src_addr += 2;
}
switch (p_psdu[SRC_ADDR_TYPE_OFFSET] & SRC_ADDR_TYPE_MASK)
{
case SRC_ADDR_TYPE_SHORT:
for (i = 0; i < NUM_PENDING_SHORT_ADDRESSES; i++)
{
if (nrf_radio_state_get() != NRF_RADIO_STATE_TX_RU)
{
break;
}
if (0 == memcmp(p_src_addr, m_pending_short[i], sizeof(m_pending_short[i])))
{
return true;
}
}
break;
case SRC_ADDR_TYPE_EXTENDED:
for (i = 0; i < NUM_PENDING_EXTENDED_ADDRESSES; i++)
{
if (nrf_radio_state_get() != NRF_RADIO_STATE_TX_RU)
{
break;
}
if (0 == memcmp(p_src_addr, m_pending_extended[i], sizeof(m_pending_extended[i])))
{
return true;
}
}
break;
default:
return true;
}
return false;
}
@@ -0,0 +1,111 @@
/* Copyright (c) 2017, 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 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.
*
*/
/**
* @brief This file implements procedures to set pending bit in nRF 802.15.4 radio driver.
*
*/
#ifndef NRF_DRV_RADIO802154_ACK_PENDING_BIT_H_
#define NRF_DRV_RADIO802154_ACK_PENDING_BIT_H_
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initialize this module.
*/
void nrf_drv_radio802154_ack_pending_bit_init(void);
/**
* @brief Enable or disable procedure of setting pending bit in ACK frame.
*
* @param[in] enabled True if procedure should be enabled, false otherwise.
*/
void nrf_drv_radio802154_ack_pending_bit_set(bool enabled);
/**
* @brief Add address to ACK pending bit list.
*
* ACK frames sent in response to frames with source address matching any address from ACK pending
* bit list will have pending bit set. If source address does not match any of the addresses in the
* list the ACK frame will have pending bit cleared.
*
* @param[in] p_addr Pointer to address that should be added to the list.
* @param[in] extended Indication if @p p_addr is extended or short address.
*
* @retval true Address successfully added to the list.
* @retval false Address was not added to the list (list is full).
*/
bool nrf_drv_radio802154_ack_pending_bit_for_addr_set(const uint8_t * p_addr, bool extended);
/**
* @brief Remove address from ACK pending bit list.
*
* ACK frames sent in response to frames with source address matching any address from ACK pending
* bit list will have pending bit set. If source address does not match any of the addresses in the
* list the ACK frame will have pending bit cleared.
*
* @param[in] p_addr Pointer to address that should be removed from the list.
* @param[in] extended Indication if @p p_addr is extended or short address.
*
* @retval true Address successfully removed from the list.
* @retval false Address was not removed from the list (address is missing in the list).
*/
bool nrf_drv_radio802154_ack_pending_bit_for_addr_clear(const uint8_t * p_addr, bool extended);
/**
* @brief Remove all addresses of given length from ACK pending bit list.
*
* @param[in] extended Indication if all extended or all short addresses should be removed from
* the list.
*/
void nrf_drv_radio802154_ack_pending_bit_for_addr_reset(bool extended);
/**
* @brief Check if pending bit should be set in ACK sent in response to given frame.
*
* @param[in] p_psdu PSDU of frame to which ACK frame is being prepared.
*
* @retval true Pending bit should be set.
* @retval false Pending bit should be cleared.
*/
bool nrf_drv_radio802154_ack_pending_bit_should_be_set(const uint8_t * p_psdu);
#ifdef __cplusplus
}
#endif
#endif /* NRF_DRV_RADIO802154_ACK_PENDING_BIT_H_ */
@@ -0,0 +1,140 @@
/* Copyright (c) 2017, 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 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_DRIVER_RADIO802154_CONFIG_H__
#define NRF_DRIVER_RADIO802154_CONFIG_H__
#include <nrf.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_driver_radio802154_config 802.15.4 driver configuration
* @{
* @ingroup nrf_driver_radio802154
* @brief Configuration of 802.15.4 radio driver for nRF SoC.
*/
/*******************************************************************************
* @section Radio Driver Configuration.
******************************************************************************/
/**
* @def RADIO_CCA_MODE
*
* RADIO CCA Mode.
*
*/
#define RADIO_CCA_MODE NRF_RADIO_CCA_MODE_ED
/**
* @def RADIO_CCA_ED_THRESHOLD
*
* RADIO Energy Detection Threshold.
*
*/
#define RADIO_CCA_ED_THRESHOLD 0x2D
/**
* @def RADIO_CCA_CORR_THRESHOLD
*
* RADIO Correlator Threshold.
*
*/
#define RADIO_CCA_CORR_THRESHOLD 0x2D
/**
* @def RADIO_CCA_CORR_LIMIT
*
* RADIO Correlator limit.
*
*/
#define RADIO_CCA_CORR_LIMIT 0x02
/**
* @def RADIO_IRQ_PRIORITY
*
* RADIO Interrupt priority.
*
*/
#define RADIO_IRQ_PRIORITY 0
/**
* @def RADIO_PENDING_SHORT_ADDRESSES
*
* RADIO Number of slots containing short addresses of nodes for which pending data is stored.
*
*/
#define RADIO_PENDING_SHORT_ADDRESSES 10
/**
* @def RADIO_PENDING_EXTENDED_ADDRESSES
*
* RADIO Number of slots containing extended addresses of nodes for which pending data is stored.
*
*/
#define RADIO_PENDING_EXTENDED_ADDRESSES 10
/**
* @def RADIO_RX_BUFFERS
*
* RADIO Number of buffers in receive queue.
*
*/
#define RADIO_RX_BUFFERS 16
/**
* @def RADIO_SHORT_CCAIDLE_TXEN
*
* RADIO can start transmission using short CCAIDLE->TXEN or using software interrupt handler.
*
*/
#define RADIO_SHORT_CCAIDLE_TXEN 1
// TODO: #ifdef to check direct / SWI notifications
/**
* @def RADIO_NOTIFICATION_SWI_PRIORITY
*
* Priority of software interrupt used to call notification from 802.15.4 driver.
*
*/
#define RADIO_NOTIFICATION_SWI_PRIORITY 6
/**
*@}
**/
#ifdef __cplusplus
}
#endif
#endif // NRF_DRIVER_RADIO802154_CONFIG_H__
@@ -0,0 +1,82 @@
/* Copyright (c) 2017, 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 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.
*
*/
/**
* @brief This module contains constant values definitions used by nRF 802.15.4 driver.
*
*/
#ifndef NRF_DRV_RADIO802154_CONST_H_
#define NRF_DRV_RADIO802154_CONST_H_
#define ACK_HEADER_WITH_PENDING 0x12 // First byte of ACK frame containing pending bit
#define ACK_HEADER_WITHOUT_PENDING 0x02 // First byte of ACK frame without pending bit
#define ACK_LENGTH 5 // Length of ACK frame
#define ACK_REQUEST_BIT (1 << 5) // Ack request bit
#define ACK_REQUEST_OFFSET 1 // Byte containing Ack request bit (+1 for frame length byte)
#define DEST_ADDR_TYPE_EXTENDED 0x0c // Bits containing extended destination address type
#define DEST_ADDR_TYPE_MASK 0x0c // Mask of bits containing destination address type
#define DEST_ADDR_TYPE_OFFSET 2 // Byte containing destination address type (+1 for frame length byte)
#define DEST_ADDR_TYPE_SHORT 0x08 // Bits containing short destination address type
#define DEST_ADDR_OFFSET 5 // Offset of destination address in Data frame
#define DSN_OFFSET 3 // Byte containing DSN value (+1 for frame length byte)
#define FRAME_PENDING_BIT (1 << 4) // Pending bit
#define FRAME_PENDING_OFFSET 1 // Byte containing pending bit (+1 for frame length byte)
#define FRAME_TYPE_ACK 0x02 // Bits containing ACK frame type
#define FRAME_TYPE_BEACON 0x00 // Bits containing Beacon frame type
#define FRAME_TYPE_COMMAND 0x03 // Bits containing Command frame type
#define FRAME_TYPE_DATA 0x01 // Bits containing Data frame type
#define FRAME_TYPE_MASK 0x07 // Mask of bits containing frame type
#define FRAME_TYPE_OFFSET 1 // Byte containing frame type bits (+1 for frame length byte)
#define PAN_ID_COMPR_OFFSET 1 // Byte containing Pan Id compression bit (+1 for frame length byte)
#define PAN_ID_COMPR_MASK 0x40 // Pan Id compression bit
#define PAN_ID_OFFSET 3 // Offset of Pan Id in Data frame
#define SRC_ADDR_TYPE_EXTENDED 0xc0 // Bits containing extended source address type
#define SRC_ADDR_TYPE_MASK 0xc0 // Mask of bits containing source address type
#define SRC_ADDR_TYPE_OFFSET 2 // Byte containing source address type (+1 for frame length byte)
#define SRC_ADDR_TYPE_SHORT 0x80 // Bits containing short source address type
#define SRC_ADDR_OFFSET_SHORT_DST 8 // Offset of source address in Data frame if destination address is short
#define SRC_ADDR_OFFSET_EXTENDED_DST 14 // Offset of source address in Data frame if destination address is extended
#define CRC_LENGTH 2 // Length of CRC in 802.15.4 frames [bytes]
#define CRC_POLYNOMIAL 0x011021 // Polynomial used for CRC calculation in 802.15.4 frames
#define MHMU_MASK 0xff000700 // Mask of known bytes in ACK packet
#define MHMU_PATTERN 0x00000200 // Values of known bytes in ACK packet
#define MHMU_PATTERN_DSN_OFFSET 24 // Offset of DSN in MHMU_PATTER [bits]
#define PAN_ID_SIZE 2 // Size of Pan Id
#define SHORT_ADDRESS_SIZE 2 // Size of Short Mac Address
#define EXTENDED_ADDRESS_SIZE 8 // Size of Extended Mac Address
#define MAX_PACKET_SIZE 127 // Maximal size of radio packet
#endif // NRD_DRV_RADIO802154_CONST_H_
@@ -0,0 +1,114 @@
/* Copyright (c) 2017, 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 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.
*
*/
/**
* @file
* This file implements critical sections used with requests by 802.15.4 driver.
*
*/
#include "nrf_drv_radio802154_critical_section.h"
#include <assert.h>
#include <stdint.h>
#include "nrf_drv_radio802154_debug.h"
#include "nrf_drv_radio802154_fsm.h"
#include "hal/nrf_radio.h"
#include "raal/nrf_raal_api.h"
#include <cmsis/core_cmFunc.h>
#if RAAL_SOFTDEVICE
// When Softdevice is selected as arbiter critical sections should not be nested.
static volatile bool m_in_critical_section;
#endif // RAAL_SOFTDEVICE
void nrf_drv_radio802154_critical_section_enter(void)
{
nrf_drv_radio802154_log(EVENT_TRACE_ENTER, FUNCTION_CRIT_SECT_ENTER);
radio_state_t state;
#if RAAL_SOFTDEVICE
__disable_irq();
__DSB();
__ISB();
assert(!m_in_critical_section);
m_in_critical_section = true;
#endif // RAAL_SOFTDEVICE
nrf_raal_critical_section_enter();
state = nrf_drv_radio802154_fsm_state_get();
if (state != RADIO_STATE_WAITING_TIMESLOT &&
state != RADIO_STATE_SLEEP)
{
NVIC_DisableIRQ(RADIO_IRQn);
#if !RAAL_SOFTDEVICE
__DSB();
__ISB();
#endif // !RAAL_SOFTDEVICE
}
#if RAAL_SOFTDEVICE
__enable_irq();
#endif // RAAL_SOFTDEVICE
nrf_drv_radio802154_log(EVENT_TRACE_EXIT, FUNCTION_CRIT_SECT_ENTER);
}
void nrf_drv_radio802154_critical_section_exit(void)
{
nrf_drv_radio802154_log(EVENT_TRACE_ENTER, FUNCTION_CRIT_SECT_EXIT);
#if RAAL_SOFTDEVICE
assert(m_in_critical_section);
m_in_critical_section = false;
#endif // RAAL_SOFTDEVICE
radio_state_t state;
// RAAL critical section shall be exited before RADIO IRQ handler is enabled. In other case
// RADIO IRQ handler may be called out of timeslot.
nrf_raal_critical_section_exit();
state = nrf_drv_radio802154_fsm_state_get();
if (state != RADIO_STATE_WAITING_TIMESLOT &&
state != RADIO_STATE_SLEEP)
{
NVIC_EnableIRQ(RADIO_IRQn);
}
nrf_drv_radio802154_log(EVENT_TRACE_EXIT, FUNCTION_CRIT_SECT_EXIT);
}
@@ -0,0 +1,66 @@
/* Copyright (c) 2017, 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 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_DRIVER_RADIO802154_CRITICAL_SECTION_H__
#define NRF_DRIVER_RADIO802154_CRITICAL_SECTION_H__
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_driver_radio802154_critical_section 802.15.4 driver critical section
* @{
* @ingroup nrf_driver_radio802154
* @brief Critical section used with requests to the 802.15.4 driver.
*/
/**
* @brief Enter critical section in the 802.15.4 driver.
*/
void nrf_drv_radio802154_critical_section_enter(void);
/**
* @brief Exit critical section in the 802.15.4 driver.
*/
void nrf_drv_radio802154_critical_section_exit(void);
/**
*@}
**/
#ifdef __cplusplus
}
#endif
#endif // NRF_DRIVER_RADIO802154_CRITICAL_SECTION_H__
@@ -0,0 +1,136 @@
/* Copyright (c) 2017, 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 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.
*
*/
/**
* @file
* This file implements debug helpers for the nRF 802.15.4 radio driver.
*
*/
#include "nrf_drv_radio802154_debug.h"
#include <stdint.h>
#include "hal/nrf_gpio.h"
#include "hal/nrf_gpiote.h"
#include "hal/nrf_ppi.h"
#include "nrf.h"
#if ENABLE_DEBUG_LOG
volatile uint32_t nrf_drv_radio802154_debug_log_buffer[NRF_DRV_RADIO802154_DEBUG_LOG_BUFFER_LEN];
volatile uint32_t nrf_drv_radio802154_debug_log_ptr = 0;
#endif
#if ENABLE_DEBUG_GPIO
static void radio_event_gpio_toggle_init(void)
{
nrf_gpio_cfg_output(PIN_DBG_RADIO_EVT_END);
nrf_gpio_cfg_output(PIN_DBG_RADIO_EVT_DISABLED);
nrf_gpio_cfg_output(PIN_DBG_RADIO_EVT_READY);
nrf_gpio_cfg_output(PIN_DBG_RADIO_EVT_FRAMESTART);
nrf_gpio_cfg_output(PIN_DBG_RADIO_EVT_EDEND);
nrf_gpiote_task_configure(0, PIN_DBG_RADIO_EVT_END, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH);
nrf_gpiote_task_configure(1, PIN_DBG_RADIO_EVT_DISABLED, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH);
nrf_gpiote_task_configure(2, PIN_DBG_RADIO_EVT_READY, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH);
nrf_gpiote_task_configure(3, PIN_DBG_RADIO_EVT_FRAMESTART, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH);
nrf_gpiote_task_configure(4, PIN_DBG_RADIO_EVT_EDEND, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH);
nrf_gpiote_task_enable(0);
nrf_gpiote_task_enable(1);
nrf_gpiote_task_enable(2);
nrf_gpiote_task_enable(3);
nrf_gpiote_task_enable(4);
nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL0, (uint32_t) &NRF_RADIO->EVENTS_END, nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_0));
nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL1, (uint32_t) &NRF_RADIO->EVENTS_DISABLED, nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_1));
nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL2, (uint32_t) &NRF_RADIO->EVENTS_READY, nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_2));
nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL3, (uint32_t) &NRF_RADIO->EVENTS_FRAMESTART, nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_3));
nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL4, (uint32_t) &NRF_RADIO->EVENTS_EDEND, nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_4));
nrf_ppi_channel_enable(NRF_PPI_CHANNEL0);
nrf_ppi_channel_enable(NRF_PPI_CHANNEL1);
nrf_ppi_channel_enable(NRF_PPI_CHANNEL2);
nrf_ppi_channel_enable(NRF_PPI_CHANNEL3);
nrf_ppi_channel_enable(NRF_PPI_CHANNEL4);
}
static void raal_simulator_gpio_init(void)
{
#if RAAL_SIMULATOR
nrf_gpio_cfg_output(PIN_DBG_TIMESLOT_ACTIVE);
nrf_gpio_cfg_output(PIN_DBG_RAAL_CRITICAL_SECTION);
#endif
}
static void raal_softdevice_event_gpio_toggle_init(void)
{
#if RAAL_SOFTDEVICE
nrf_gpio_cfg_output(PIN_DBG_TIMESLOT_ACTIVE);
nrf_gpio_cfg_output(PIN_DBG_TIMESLOT_EXTEND_REQ);
nrf_gpio_cfg_output(PIN_DBG_TIMESLOT_SESSION_IDLE);
nrf_gpio_cfg_output(PIN_DBG_TIMESLOT_RADIO_IRQ);
nrf_gpio_cfg_output(PIN_DBG_TIMESLOT_FAILED);
nrf_gpio_cfg_output(PIN_DBG_TIMESLOT_BLOCKED);
nrf_gpio_cfg_output(PIN_DBG_RTC0_EVT_REM);
nrf_gpiote_task_configure(5, PIN_DBG_RTC0_EVT_REM, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH);
nrf_gpiote_task_enable(5);
nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL5, (uint32_t) &NRF_RTC0->EVENTS_COMPARE[1], nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_5));
nrf_ppi_channel_enable(NRF_PPI_CHANNEL5);
#endif // RAAL_SOFTDEVICE
}
#endif // ENABLE_DEBUG_GPIO
void nrf_drv_radio802154_debug_init(void)
{
#if ENABLE_DEBUG_GPIO
radio_event_gpio_toggle_init();
raal_simulator_gpio_init();
raal_softdevice_event_gpio_toggle_init();
#endif // ENABLE_DEBUG_GPIO
}
#if ENABLE_DEBUG_ASSERT
void __assert_func(const char *file, int line, const char *func, const char *cond)
{
(void) file;
(void) line;
(void) func;
(void) cond;
__disable_irq();
while (1);
}
#endif // ENABLE_DEBUG_ASSERT
@@ -0,0 +1,148 @@
/* Copyright (c) 2017, 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 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.
*
*/
/**
* @brief This module contains debug helpers for 802.15.4 radio driver for nRF SoC devices.
*
*/
#ifndef NRF_DRV_RADIO802154_DEBUG_H_
#define NRF_DRV_RADIO802154_DEBUG_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define NRF_DRV_RADIO802154_DEBUG_LOG_BUFFER_LEN 1024
#define EVENT_TRACE_ENTER 0x0001UL
#define EVENT_TRACE_EXIT 0x0002UL
#define EVENT_MUTEX_LOCK 0x0003UL
#define EVENT_MUTEX_UNLOCK 0x0004UL
#define EVENT_SET_STATE 0x0005UL
#define EVENT_RADIO_RESET 0x0006UL
#define FUNCTION_SLEEP 0x0001UL
#define FUNCTION_RECEIVE 0x0002UL
#define FUNCTION_TRANSMIT 0x0003UL
#define FUNCTION_ENERGY_DETECTION 0x0004UL
#define FUNCTION_BUFFER_FREE 0x0005UL
#define FUNCTION_IRQ_HANDLER 0x0100UL
#define FUNCTION_EVENT_FRAMESTART 0x0101UL
#define FUNCTION_EVENT_BCMATCH 0x0102UL
#define FUNCTION_EVENT_END 0x0103UL
#define FUNCTION_EVENT_DISABLED 0x0104UL
#define FUNCTION_EVENT_READY 0x0105UL
#define FUNCTION_EVENT_CCAIDLE 0x0106UL
#define FUNCTION_EVENT_CCABUSY 0x0107UL
#define FUNCTION_EVENT_EDEND 0x0108UL
#define FUNCTION_AUTO_ACK_ABORT 0x0201UL
#define FUNCTION_TIMESLOT_STARTED 0x0202UL
#define FUNCTION_TIMESLOT_ENDED 0x0203UL
#define FUNCTION_CRIT_SECT_ENTER 0x0204UL
#define FUNCTION_CRIT_SECT_EXIT 0x0205UL
#define FUNCTION_RAAL_CRIT_SECT_ENTER 0x0301UL
#define FUNCTION_RAAL_CRIT_SECT_EXIT 0x0302UL
#define FUNCTION_RAAL_CONTINUOUS_ENTER 0x0303UL
#define FUNCTION_RAAL_CONTINUOUS_EXIT 0x0304UL
#define FUNCTION_RAAL_SIG_HANDLER 0x0400UL
#define FUNCTION_RAAL_SIG_EVENT_START 0x0401UL
#define FUNCTION_RAAL_SIG_EVENT_MARGIN 0x0402UL
#define FUNCTION_RAAL_SIG_EVENT_EXTEND 0x0403UL
#define FUNCTION_RAAL_SIG_EVENT_ENDED 0x0404UL
#define PIN_DBG_RADIO_EVT_END 11
#define PIN_DBG_RADIO_EVT_DISABLED 12
#define PIN_DBG_RADIO_EVT_READY 13
#define PIN_DBG_RADIO_EVT_FRAMESTART 14
#define PIN_DBG_RADIO_EVT_EDEND 25
#define PIN_DBG_TIMESLOT_ACTIVE 3
#define PIN_DBG_TIMESLOT_EXTEND_REQ 4
#define PIN_DBG_TIMESLOT_SESSION_IDLE 16
#define PIN_DBG_TIMESLOT_RADIO_IRQ 28
#define PIN_DBG_TIMESLOT_FAILED 29
#define PIN_DBG_TIMESLOT_BLOCKED 30
#define PIN_DBG_RAAL_CRITICAL_SECTION 15
#define PIN_DBG_RTC0_EVT_REM 31
#if ENABLE_DEBUG_LOG
extern volatile uint32_t nrf_drv_radio802154_debug_log_buffer[
NRF_DRV_RADIO802154_DEBUG_LOG_BUFFER_LEN];
extern volatile uint32_t nrf_drv_radio802154_debug_log_ptr;
#define nrf_drv_radio802154_log(EVENT_CODE, EVENT_ARG) \
do { \
uint32_t ptr = nrf_drv_radio802154_debug_log_ptr; \
nrf_drv_radio802154_debug_log_buffer[ptr] = ((EVENT_CODE) | ((EVENT_ARG) << 16)); \
nrf_drv_radio802154_debug_log_ptr = \
ptr < (NRF_DRV_RADIO802154_DEBUG_LOG_BUFFER_LEN - 1) ? ptr + 1 : 0; \
} while (0)
#else // ENABLE_DEBUG_LOG
#define nrf_drv_radio802154_log(EVENT_CODE, EVENT_ARG)
#endif // ENABLE_DEBUG_LOG
#if ENABLE_DEBUG_GPIO
#define nrf_drv_radio802154_pin_set(pin) NRF_P0->OUTSET = (1UL << (pin))
#define nrf_drv_radio802154_pin_clr(pin) NRF_P0->OUTCLR = (1UL << (pin))
#define nrf_drv_radio802154_pin_tgl(pin) do { volatile uint32_t ps = NRF_P0->OUT; \
NRF_P0->OUTSET = (~ps & (1UL << (pin))); \
NRF_P0->OUTCLR = (ps & (1UL << (pin))); \
} while(0);
#else // ENABLE_DEBUG_GPIO
#define nrf_drv_radio802154_pin_set(pin)
#define nrf_drv_radio802154_pin_clr(pin)
#define nrf_drv_radio802154_pin_tgl(pin)
#endif // ENABLE_DEBUG_GPIO
/**
* @brief Initialize debug helpers for nRF 802.15.4 driver.
*/
void nrf_drv_radio802154_debug_init(void);
#ifdef __cplusplus
}
#endif
#endif /* NRF_DRV_RADIO802154_DEBUG_H_ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,178 @@
/* Copyright (c) 2017, 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 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.
*
*/
/**
* @brief This module contains Finite State Machine of nRF 802.15.4 radio driver.
*
*/
#ifndef NRF_DRV_RADIO802154_FSM_H_
#define NRF_DRV_RADIO802154_FSM_H_
#include <stdbool.h>
#include <stdint.h>
#include "nrf_drv_radio802154_rx_buffer.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief States of nRF 802.15.4 driver.
*/
typedef enum
{
// Sleep
RADIO_STATE_DISABLING, // Entering low power (DISABLED) mode
RADIO_STATE_SLEEP, // Low power (DISABLED) mode
// Receive
RADIO_STATE_WAITING_TIMESLOT, // Radio is inactive due to denied time slot
RADIO_STATE_WAITING_RX_FRAME, // Waiting for frame in receiver mode
RADIO_STATE_RX_HEADER, // Received SFD, receiving MAC header
RADIO_STATE_RX_FRAME, // Received MAC destination address, receiving rest of the frame
RADIO_STATE_TX_ACK, // Received frame and transmitting ACK
// Transmit
RADIO_STATE_CCA, // Performing CCA
RADIO_STATE_TX_FRAME, // Transmitting data frame (or beacon)
RADIO_STATE_RX_ACK, // Receiving ACK after transmitted frame
// Energy Detection
RADIO_STATE_ED, // Performing Energy Detection procedure
} radio_state_t;
/**
* @brief Initialize 802.15.4 driver FSM.
*/
void nrf_drv_radio802154_fsm_init(void);
/**
* @brief Deinitialize 802.15.4 driver FSM.
*/
void nrf_drv_radio802154_fsm_deinit(void);
/**
* @brief Get current state of nRF 802.15.4 driver.
*
* @return Current state of the 802.15.4 driver.
*/
radio_state_t nrf_drv_radio802154_fsm_state_get(void);
/***************************************************************************************************
* @section State machine transition requests
**************************************************************************************************/
/**
* @brief Request transition to SLEEP state.
*
* @note This function shall be called from critical section context. It shall not be interrupted
* by RADIO event handler or RAAL notification.
*
* @note This function should be called when the driver is in RECEIVE state.
*
* @retval true Entering SLEEP state succeeded.
* @retval false Entering SLEEP state failed (driver is performing other procedure).
*/
bool nrf_drv_radio802154_fsm_sleep(void);
/**
* @brief Request transition to RECEIVE state.
*
* @note This function shall be called from critical section context. It shall not be interrupted
* by RADIO event handler or RAAL notification.
*
* @note This function should be called when the driver is in SLEEP or TRANSMIT state.
*
* @param[in] channel Channel number that the radio should use to receive frames.
*
* @retval true Entering RECEIVE state succeeded.
* @retval false Entering RECEIVE state failed (driver is performing other procedure).
*/
bool nrf_drv_radio802154_fsm_receive(uint8_t channel);
/**
* @brief Request transition to TRANSMIT state.
*
* @note This function shall be called from critical section context. It shall not be interrupted
* by RADIO event handler or RAAL notification.
*
* @note This function should be called when the driver is in RECEIVE state.
*
* @param[in] p_data Pointer to a frame to transmit.
* @param[in] channel Channel number that the radio should use to transmit the frame.
* @param[in] power Transmission power.
*
* @retval true Entering TRANSMIT state succeeded.
* @retval false Entering TRANSMIT state failed (driver is performing other procedure).
*/
bool nrf_drv_radio802154_fsm_transmit(const uint8_t * p_data, uint8_t channel, int8_t power);
/**
* @brief Request transition to ENERGY_DETECTION state.
*
* @note This function shall be called from critical section context. It shall not be interrupted
* by RADIO event handler or RAAL notification.
*
* @note This function should be called when the driver is in SLEEP or RECEIVE state. When Energy
* detection procedure is finished the driver will transit to RECEIVE state.
*
* @param[in] channel Channel number that the radio should use to perform energy detection.
* @param[in] time_us Minimal time of energy detection procedure.
*
* @retval true Entering ENERGY_DETECTION state succeeded.
* @retval false Entering ENERGY_DETECTION state failed (driver is performing other procedure).
*/
bool nrf_drv_radio802154_fsm_energy_detection(uint8_t channel, uint32_t time_us);
/***************************************************************************************************
* @section State machine notifications
**************************************************************************************************/
/**
* @brief Notify the FSM that higher layer freed a frame buffer.
*
* When there were no free buffers available the FSM does not start receiver. If FSM receives this
* notification in changes internal state to make sure receiver is started if requested.
*
* @note This function shall be called from critical section context. It shall not be interrupted
* by RADIO event handler or RAAL notification.
*
* @param[in] p_buffer Pointer to buffer that has been freed.
*/
void nrf_drv_radio802154_fsm_notify_buffer_free(rx_buffer_t * p_buffer);
#ifdef __cplusplus
}
#endif
#endif /* NRF_DRV_RADIO802154_FSM_H_ */
@@ -0,0 +1,91 @@
/* Copyright (c) 2017, 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 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_DRIVER_RADIO802154_NOTIFICATION_H__
#define NRF_DRIVER_RADIO802154_NOTIFICATION_H__
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_driver_radio802154_notification 802.15.4 driver notification
* @{
* @ingroup nrf_driver_radio802154
* @brief Notifications to the next higher layer triggered from 802.15.4 radio driver.
*/
/**
* @brief Initialize notification module.
*/
void nrf_drv_radio802154_notification_init(void);
/**
* @brief Notify next higher layer that a frame was received.
*
* @param[in] p_data Array of bytes containing PSDU. First byte contains frame length, other contain the frame itself.
* @param[in] power RSSI measured during the frame reception.
* @param[in] lqi LQI indicating measured link quality during the frame reception.
*/
void nrf_drv_radio802154_notify_received(uint8_t * p_data, int8_t power, int8_t lqi);
/**
* @brief Notify next higher layer that a frame was transmitted.
*
* @param[in] p_ack Pointer to buffer containing PSDU of ACK frame. NULL if ACK was not requested.
* @param[in] power RSSI of received frame or 0 if ACK was not requested.
* @param[in] lqi LQI of received frame of 0 if ACK was not requested.
*/
void nrf_drv_radio802154_notify_transmitted(uint8_t * p_ack, int8_t power, int8_t lqi);
/**
* @brief Notify next higher layer that a frame was not transmitted.
*/
void nrf_drv_radio802154_notify_busy_channel(void);
/**
* @brief Notify next higher layer that energy detection procedure ended.
*
* @param[in] result Detected energy level.
*/
void nrf_drv_radio802154_notify_energy_detected(int8_t result);
/**
*@}
**/
#ifdef __cplusplus
}
#endif
#endif // NRF_DRIVER_RADIO802154_NOTIFICATION_H__
@@ -0,0 +1,68 @@
/* Copyright (c) 2017, 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 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.
*
*/
/**
* @file
* This file implements notifications triggered directly by the nrf 802.15.4 radio driver.
*
*/
#include "nrf_drv_radio802154_notification.h"
#include <stdbool.h>
#include <stdint.h>
#include "nrf_drv_radio802154.h"
void nrf_drv_radio802154_notification_init(void)
{
// Intentionally empty
}
void nrf_drv_radio802154_notify_received(uint8_t * p_data, int8_t power, int8_t lqi)
{
nrf_drv_radio802154_received(p_data, power, lqi);
}
void nrf_drv_radio802154_notify_transmitted(uint8_t * p_ack, int8_t power, int8_t lqi)
{
nrf_drv_radio802154_transmitted(p_ack, power, lqi);
}
void nrf_drv_radio802154_notify_busy_channel(void)
{
nrf_drv_radio802154_busy_channel();
}
void nrf_drv_radio802154_notify_energy_detected(int8_t result)
{
nrf_drv_radio802154_energy_detected(result);
}
@@ -0,0 +1,69 @@
/* Copyright (c) 2017, 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 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.
*
*/
/**
* @file
* This file implements notifications triggered by the nrf 802.15.4 radio driver via SWI.
*
*/
#include "nrf_drv_radio802154_notification.h"
#include <stdbool.h>
#include <stdint.h>
#include "nrf_drv_radio802154_swi.h"
#include "raal/nrf_raal_api.h"
void nrf_drv_radio802154_notification_init(void)
{
nrf_drv_radio802154_swi_init();
}
void nrf_drv_radio802154_notify_received(uint8_t * p_data, int8_t power, int8_t lqi)
{
nrf_drv_radio802154_swi_notify_received(p_data, power, lqi);
}
void nrf_drv_radio802154_notify_transmitted(uint8_t * p_ack, int8_t power, int8_t lqi)
{
nrf_drv_radio802154_swi_notify_transmitted(p_ack, power, lqi);
}
void nrf_drv_radio802154_notify_busy_channel(void)
{
nrf_drv_radio802154_swi_notify_busy_channel();
}
void nrf_drv_radio802154_notify_energy_detected(int8_t result)
{
nrf_drv_radio802154_swi_notify_energy_detected(result);
}
@@ -0,0 +1,174 @@
/* Copyright (c) 2017, 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 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.
*
*/
/**
* @file
* This file implements storage of PIB attributes in nRF 802.15.4 radio driver.
*
*/
#include "nrf_drv_radio802154_pib.h"
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "nrf_drv_radio802154_const.h"
#define BROADCAST_ADDRESS ((uint8_t [SHORT_ADDRESS_SIZE]) {0xff, 0xff}) // Broadcast Short Address
typedef struct
{
int8_t tx_power; // Transmit power.
uint8_t pan_id[PAN_ID_SIZE]; // Pan Id of this node.
uint8_t short_addr[SHORT_ADDRESS_SIZE]; // Short Address of this node.
uint8_t extended_addr[EXTENDED_ADDRESS_SIZE]; // Extended Address of this node.
bool promiscuous :1; // Indicating if radio is in promiscuous mode.
bool auto_ack :1; // Indicating if auto ACK procedure is enabled.
uint8_t channel :5; // Channel on which the node receives messages.
} nrf_drv_radio802154_pib_data_t;
static nrf_drv_radio802154_pib_data_t m_data;
void nrf_drv_radio802154_pib_init(void)
{
m_data.promiscuous = false;
m_data.auto_ack = true;
m_data.channel = 11;
memset(m_data.pan_id, 0xff, sizeof(m_data.pan_id));
m_data.short_addr[0] = 0xfe;
m_data.short_addr[1] = 0xff;
memset(m_data.extended_addr, 0, sizeof(m_data.extended_addr));
}
bool nrf_drv_radio802154_pib_promiscuous_get(void)
{
return m_data.promiscuous;
}
void nrf_drv_radio802154_pib_promiscuous_set(bool enabled)
{
m_data.promiscuous = enabled;
}
bool nrf_drv_radio802154_pib_auto_ack_get(void)
{
return m_data.auto_ack;
}
void nrf_drv_radio802154_pib_auto_ack_set(bool enabled)
{
m_data.auto_ack = enabled;
}
uint8_t nrf_drv_radio802154_pib_channel_get(void)
{
return m_data.channel;
}
void nrf_drv_radio802154_pib_channel_set(uint8_t channel)
{
m_data.channel = channel;
}
int8_t nrf_drv_radio802154_pib_tx_power_get(void)
{
return m_data.tx_power;
}
void nrf_drv_radio802154_pib_tx_power_set(int8_t dbm)
{
m_data.tx_power = dbm;
}
void nrf_drv_radio802154_pib_pan_id_set(const uint8_t * p_pan_id)
{
memcpy(m_data.pan_id, p_pan_id, PAN_ID_SIZE);
}
void nrf_drv_radio802154_pib_extended_address_set(const uint8_t * p_extended_address)
{
memcpy(m_data.extended_addr, p_extended_address, EXTENDED_ADDRESS_SIZE);
}
void nrf_drv_radio802154_pib_short_address_set(const uint8_t * p_short_address)
{
memcpy(m_data.short_addr, p_short_address, SHORT_ADDRESS_SIZE);
}
bool nrf_drv_radio802154_pib_dest_addr_matches(const uint8_t * p_psdu)
{
// Check destination PAN Id.
// Note that +1 in PSDU offset is added because first byte in PSDU is length.
if ((0 != memcmp(&p_psdu[PAN_ID_OFFSET + 1], m_data.pan_id, PAN_ID_SIZE)) &&
(0 != memcmp(&p_psdu[PAN_ID_OFFSET + 1], BROADCAST_ADDRESS, PAN_ID_SIZE)))
{
return false;
}
// Check destination address.
switch (p_psdu[DEST_ADDR_TYPE_OFFSET] & DEST_ADDR_TYPE_MASK)
{
case DEST_ADDR_TYPE_SHORT:
{
// Note that +1 in PSDU offset is added because first byte in PSDU is length.
if ((0 != memcmp(&p_psdu[DEST_ADDR_OFFSET + 1],
m_data.short_addr,
SHORT_ADDRESS_SIZE)) &&
(0 != memcmp(&p_psdu[DEST_ADDR_OFFSET + 1],
BROADCAST_ADDRESS,
SHORT_ADDRESS_SIZE)))
{
return false;
}
break;
}
case DEST_ADDR_TYPE_EXTENDED:
{
// Note that +1 in PSDU offset is added because first byte in PSDU is length.
if (0 != memcmp(&p_psdu[DEST_ADDR_OFFSET + 1],
m_data.extended_addr,
sizeof(m_data.extended_addr)))
{
return false;
}
break;
}
default:
return false;
}
return true;
}
@@ -0,0 +1,155 @@
/* Copyright (c) 2017, 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 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.
*
*/
/**
* @brief This file implements storage of PIB attributes in nRF 802.15.4 radio driver.
*
*/
#ifndef NRF_DRV_RADIO802154_PIB_H_
#define NRF_DRV_RADIO802154_PIB_H_
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initialize this module.
*/
void nrf_drv_radio802154_pib_init(void);
/**
* @brief Check if promiscuous mode is enabled.
*
* @retval true If promiscuous mode is enabled.
* @retval false If promiscuous mode is disabled.
*/
bool nrf_drv_radio802154_pib_promiscuous_get(void);
/**
* @brief Enable or disable promiscuous mode.
*
* @param[in] enabled If promiscuous mode should be enabled.
*/
void nrf_drv_radio802154_pib_promiscuous_set(bool enabled);
/**
* @brief Check if auto ACK procedure is enabled.
*
* @retval true If auto ACK procedure is enabled.
* @retval false If auto ACK procedure is disabled.
*/
bool nrf_drv_radio802154_pib_auto_ack_get(void);
/**
* @brief Enable or disable auto ACK procedure.
*
* @param[in] enabled If auto ACK procedure should be enabled.
*/
void nrf_drv_radio802154_pib_auto_ack_set(bool enabled);
/**
* @brief Get currently used channel.
*
* @return Channel number used by the driver.
*/
uint8_t nrf_drv_radio802154_pib_channel_get(void);
/**
* @brief Set channel that will be used by the driver.
*
* @param[in] channel Number of channel used by the driver.
*/
void nrf_drv_radio802154_pib_channel_set(uint8_t channel);
/**
* @brief Get transmit power.
*
* @returns Transmit power [dBm].
*/
int8_t nrf_drv_radio802154_pib_tx_power_get(void);
/**
* @brief Set transmit power used for ACK frames.
*
* @param[in] dbm Transmit power [dBm].
*/
void nrf_drv_radio802154_pib_tx_power_set(int8_t dbm);
/**
* @brief Set PAN Id used by this device.
*
* @param[in] p_pan_id Pointer to PAN Id (2 bytes, little-endian).
*
* This function makes copy of the PAN Id.
*/
void nrf_drv_radio802154_pib_pan_id_set(const uint8_t * p_pan_id);
/**
* @brief Set Extended Address of this device.
*
* @param[in] p_extended_address Pointer to extended address (8 bytes, little-endian).
*
* This function makes copy of the address.
*/
void nrf_drv_radio802154_pib_extended_address_set(const uint8_t * p_extended_address);
/**
* @brief Set Short Address of this device.
*
* @param[in] p_short_address Pointer to short address (2 bytes, little-endian).
*
* This function makes copy of the address.
*/
void nrf_drv_radio802154_pib_short_address_set(const uint8_t * p_short_address);
/**
* @brief Check if destination address in given frame matches address stored in this module or
* broadcast address.
*
* This function is intended to check if received frame is destined to this node.
*
* @param[in] p_psdu Pointer to PSDU of frame to check.
*
* @return If destination address in given PSDU matches address stored in this module or broadcast
* address.
*/
bool nrf_drv_radio802154_pib_dest_addr_matches(const uint8_t * p_psdu);
#ifdef __cplusplus
}
#endif
#endif /* NRF_DRV_RADIO802154_PIB_H_ */
@@ -0,0 +1,67 @@
/* Copyright (c) 2017, 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 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_DRIVER_RADIO802154_PRIORITY_DROP_H__
#define NRF_DRIVER_RADIO802154_PRIORITY_DROP_H__
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_driver_radio802154_priority_drop 802.15.4 driver procedures with lower priority.
* @{
* @ingroup nrf_driver_radio802154
* @brief Internal procedures of 802.15.4 driver that should be called with lower priority than
* the caller's priority.
*/
/**
* @brief Initialize notification module.
*/
void nrf_drv_radio802154_priority_drop_init(void);
/**
* @brief Request discarding of the timeslot.
*
* @note This function should be called through this module to prevent calling it from arbiter context.
*/
void nrf_drv_radio802154_priority_drop_timeslot_exit(void);
/**
*@}
**/
#ifdef __cplusplus
}
#endif
#endif // NRF_DRIVER_RADIO802154_PRIORITY_DROP_H__
@@ -0,0 +1,51 @@
/* Copyright (c) 2017, 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 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.
*
*/
/**
* @file
* This file implements procedures that should be called with lower priority than caller in
* the nrf 802.15.4 radio driver.
*
*/
#include "nrf_drv_radio802154_priority_drop.h"
#include "raal/nrf_raal_api.h"
void nrf_drv_radio802154_priority_drop_init(void)
{
// Intentionally empty
}
void nrf_drv_radio802154_priority_drop_timeslot_exit(void)
{
nrf_raal_continuous_mode_exit();
}
@@ -0,0 +1,51 @@
/* Copyright (c) 2017, 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 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.
*
*/
/**
* @file
* This file implements procedures that should be called with lower priority than caller in
* the nrf 802.15.4 radio driver.
*
*/
#include "nrf_drv_radio802154_priority_drop.h"
#include "nrf_drv_radio802154_swi.h"
void nrf_drv_radio802154_priority_drop_init(void)
{
nrf_drv_radio802154_swi_init();
}
void nrf_drv_radio802154_priority_drop_timeslot_exit(void)
{
nrf_drv_radio802154_swi_timeslot_exit();
}
@@ -0,0 +1,93 @@
/* Copyright (c) 2017, 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 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.
*
*/
/**
* @brief This module contains calculations of 802.15.4 radio driver procedures duration.
*
*/
#ifndef NRF_DRV_RADIO802154_PROCEDURES_DURATION_H_
#define NRF_DRV_RADIO802154_PROCEDURES_DURATION_H_
#include <stdbool.h>
#include <stdint.h>
#define PHY_US_PER_SYMBOL 16
#define PHY_SYMBOLS_PER_OCTET 2
#define PHY_SHR_DURATION 10
#define A_CCA_DURATION 8
#define A_TURNAROUND_TIME 12
#define A_UNIT_BACKOFF_PERIOD 20
#define NUM_OCTETS_IN_ACK 6
#define MAC_ACK_WAIT_DURATION (A_UNIT_BACKOFF_PERIOD + \
A_TURNAROUND_TIME + \
PHY_SHR_DURATION + \
(NUM_OCTETS_IN_ACK * PHY_SYMBOLS_PER_OCTET))
static inline uint16_t nrf_drv_radio802154_tx_duration_get(uint8_t psdu_length, bool ack_requested)
{
// aTurnaroundTime + CCA + aTurnaroundTime + SHR + PHR + PSDU
// if ACK: + macAckWaitDuration
uint16_t result = A_TURNAROUND_TIME + A_CCA_DURATION + A_TURNAROUND_TIME + PHY_SHR_DURATION;
result += (psdu_length + 1) * PHY_SYMBOLS_PER_OCTET;
if (ack_requested)
{
result += MAC_ACK_WAIT_DURATION;
}
result *= PHY_US_PER_SYMBOL;
return result;
}
static inline uint16_t nrf_drv_radio802154_rx_duration_get(uint8_t psdu_length, bool ack_requested)
{
// SHR + PHR + PSDU
// if ACK: + aTurnaroundTime + ACK frame duration + aTurnaroundTime
uint16_t result = PHY_SHR_DURATION + (psdu_length + 1) * PHY_SYMBOLS_PER_OCTET;
if (ack_requested)
{
result += A_TURNAROUND_TIME +
PHY_SHR_DURATION +
(NUM_OCTETS_IN_ACK * PHY_SYMBOLS_PER_OCTET) +
A_TURNAROUND_TIME;
}
result *= PHY_US_PER_SYMBOL;
return result;
}
#endif /* NRF_DRV_RADIO802154_PROCEDURES_DURATION_H_ */
@@ -0,0 +1,109 @@
/* Copyright (c) 2017, 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 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_DRIVER_RADIO802154_REQUEST_H__
#define NRF_DRIVER_RADIO802154_REQUEST_H__
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_driver_radio802154_request 802.15.4 driver request
* @{
* @ingroup nrf_driver_radio802154
* @brief Requests to the driver triggered from the MAC layer.
*/
/**
* @brief Initialize request module.
*/
void nrf_drv_radio802154_request_init(void);
/**
* @brief Request entering sleep state.
*
* @retval true The driver will enter sleep state.
* @retval false The driver cannot enter sleep state due to ongoing operation.
*/
bool nrf_drv_radio802154_request_sleep(void);
/**
* @brief Request entering receive state.
*
* @param[in] channel Channel number used to receive data.
*
* @retval true The driver will enter receive state.
* @retval false The driver cannot enter receive state due to ongoing operation.
*/
bool nrf_drv_radio802154_request_receive(uint8_t channel);
/**
* @brief Request entering transmit state.
*
* @param[in] p_data Pointer to the frame to transmit.
* @param[in] channel Channel number used to transmit the frame.
* @param[in] power Transmitter power used to transmit the frame.
*
* @retval true The driver will enter transmit state.
* @retval false The driver cannot enter transmit state due to ongoing operation.
*/
bool nrf_drv_radio802154_request_transmit(const uint8_t * p_data, uint8_t channel, int8_t power);
/**
* @brief Request entering energy detection state.
*
* @param[in] channel Channel number used to perform energy detection procedure.
* @param[in] time_us Requested duration of energy detection procedure.
*
* @retval true The driver will enter energy detection state.
* @retval false The driver cannot enter energy detection state due to ongoing operation.
*/
bool nrf_drv_radio802154_request_energy_detection(uint8_t channel, uint32_t time_us);
/**
* @brief Request the driver to free given buffer.
*
* @param[in] p_data Pointer to the buffer to free.
*/
void nrf_drv_radio802154_request_buffer_free(uint8_t * p_data);
/**
*@}
**/
#ifdef __cplusplus
}
#endif
#endif // NRF_DRIVER_RADIO802154_REQUEST_H__
@@ -0,0 +1,104 @@
/* Copyright (c) 2017, 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 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.
*
*/
/**
* @file
* This file implements requests to the driver triggered directly by the MAC layer.
*
*/
#include "nrf_drv_radio802154_request.h"
#include <stdbool.h>
#include <stdint.h>
#include "nrf_drv_radio802154_critical_section.h"
#include "nrf_drv_radio802154_fsm.h"
#include "hal/nrf_radio.h"
#include <cmsis/core_cmFunc.h>
void nrf_drv_radio802154_request_init(void)
{
// Intentionally empty
}
bool nrf_drv_radio802154_request_sleep(void)
{
bool result;
nrf_drv_radio802154_critical_section_enter();
result = nrf_drv_radio802154_fsm_sleep();
nrf_drv_radio802154_critical_section_exit();
return result;
}
bool nrf_drv_radio802154_request_receive(uint8_t channel)
{
bool result;
nrf_drv_radio802154_critical_section_enter();
result = nrf_drv_radio802154_fsm_receive(channel);
nrf_drv_radio802154_critical_section_exit();
return result;
}
bool nrf_drv_radio802154_request_transmit(const uint8_t * p_data, uint8_t channel, int8_t power)
{
bool result;
nrf_drv_radio802154_critical_section_enter();
result = nrf_drv_radio802154_fsm_transmit(p_data, channel, power);
nrf_drv_radio802154_critical_section_exit();
return result;
}
bool nrf_drv_radio802154_request_energy_detection(uint8_t channel, uint32_t time_us)
{
bool result;
nrf_drv_radio802154_critical_section_enter();
result = nrf_drv_radio802154_fsm_energy_detection(channel, time_us);
nrf_drv_radio802154_critical_section_exit();
return result;
}
void nrf_drv_radio802154_request_buffer_free(uint8_t * p_data)
{
nrf_drv_radio802154_critical_section_enter();
nrf_drv_radio802154_fsm_notify_buffer_free((rx_buffer_t *)p_data);
nrf_drv_radio802154_critical_section_exit();
}
@@ -0,0 +1,142 @@
/* Copyright (c) 2017, 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 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.
*
*/
/**
* @file
* This file implements requests to the driver triggered by the MAC layer through SWI.
*
*/
#include "nrf_drv_radio802154_request.h"
#include <stdbool.h>
#include <stdint.h>
#include "nrf_drv_radio802154_config.h"
#include "nrf_drv_radio802154_critical_section.h"
#include "nrf_drv_radio802154_debug.h"
#include "nrf_drv_radio802154_fsm.h"
#include "nrf_drv_radio802154_rx_buffer.h"
#include "nrf_drv_radio802154_swi.h"
#include "hal/nrf_radio.h"
#include <cmsis/core_cmFunc.h>
#include <cmsis/core_cm4.h>
static bool active_verctor_priority_is_high(void)
{
uint32_t active_vector_id = (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) >> SCB_ICSR_VECTACTIVE_Pos;
uint32_t active_priority = NVIC_GetPriority((IRQn_Type)active_vector_id);
return active_priority >= RADIO_NOTIFICATION_SWI_PRIORITY;
}
void nrf_drv_radio802154_request_init(void)
{
nrf_drv_radio802154_swi_init();
}
bool nrf_drv_radio802154_request_sleep(void)
{
bool result = false;
if (active_verctor_priority_is_high())
{
nrf_drv_radio802154_critical_section_enter();
result = nrf_drv_radio802154_fsm_sleep();
nrf_drv_radio802154_critical_section_exit();
}
else
{
nrf_drv_radio802154_swi_sleep(&result);
}
return result;
}
bool nrf_drv_radio802154_request_receive(uint8_t channel)
{
bool result = false;
if (active_verctor_priority_is_high())
{
nrf_drv_radio802154_critical_section_enter();
result = nrf_drv_radio802154_fsm_receive(channel);
nrf_drv_radio802154_critical_section_exit();
}
else
{
nrf_drv_radio802154_swi_receive(channel, &result);
}
return result;
}
bool nrf_drv_radio802154_request_transmit(const uint8_t * p_data, uint8_t channel, int8_t power)
{
bool result = false;
if (active_verctor_priority_is_high())
{
nrf_drv_radio802154_critical_section_enter();
result = nrf_drv_radio802154_fsm_transmit(p_data, channel, power);
nrf_drv_radio802154_critical_section_exit();
}
else
{
nrf_drv_radio802154_swi_transmit(p_data, channel, power, &result);
}
return result;
}
bool nrf_drv_radio802154_request_energy_detection(uint8_t channel, uint32_t time_us)
{
bool result = false;
if (active_verctor_priority_is_high())
{
nrf_drv_radio802154_critical_section_enter();
result = nrf_drv_radio802154_fsm_energy_detection(channel, time_us);
nrf_drv_radio802154_critical_section_exit();
}
else
{
nrf_drv_radio802154_swi_energy_detection(channel, time_us, &result);
}
return result;
}
void nrf_drv_radio802154_request_buffer_free(uint8_t * p_data)
{
nrf_drv_radio802154_swi_buffer_free(p_data);
}
@@ -0,0 +1,79 @@
/* Copyright (c) 2017, 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 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.
*
*/
/**
* @file
* This file implements buffer management for frames received by nRF 802.15.4 radio driver.
*
*/
#include "nrf_drv_radio802154_rx_buffer.h"
#include <stddef.h>
#include "nrf_drv_radio802154_config.h"
#if RADIO_RX_BUFFERS < 1
#error Not enough rx buffers in the 802.15.4 radio driver.
#endif
#if defined ( __GNUC__ )
// Receive buffer (EasyDMA cannot address whole RAM. Place buffer in the special section.)
rx_buffer_t nrf_drv_radio802154_rx_buffers[RADIO_RX_BUFFERS]
__attribute__ ((section ("nrf_radio_buffer.nrf_drv_radio802154_rx_buffers")));
#elif defined ( __ICCARM__ )
#pragma location="NRF_RADIO_BUFFER"
static rx_buffer_t nrf_drv_radio802154_rx_buffers[RADIO_RX_BUFFERS];
#endif
void nrf_drv_radio802154_rx_buffer_init(void)
{
for (uint32_t i = 0; i < RADIO_RX_BUFFERS; i++)
{
nrf_drv_radio802154_rx_buffers[i].free = true;
}
}
rx_buffer_t * nrf_drv_radio802154_rx_buffer_free_find(void)
{
for (uint32_t i = 0; i < RADIO_RX_BUFFERS; i++)
{
if (nrf_drv_radio802154_rx_buffers[i].free)
{
return &nrf_drv_radio802154_rx_buffers[i];
}
}
return NULL;
}
@@ -0,0 +1,83 @@
/* Copyright (c) 2017, 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 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.
*
*/
/**
* @brief This module contains buffer for frames received by nRF 802.15.4 radio driver.
*
*/
#ifndef NRF_DRV_RADIO802154_RX_BUFFER_H_
#define NRF_DRV_RADIO802154_RX_BUFFER_H_
#include <stdbool.h>
#include <stdint.h>
#include "nrf_drv_radio802154_const.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Structure containing received frame.
*/
typedef struct
{
uint8_t psdu[MAX_PACKET_SIZE + 1];
bool free; // If this buffer is free or contains a frame.
} rx_buffer_t;
/**
* @brief Array containing all buffers used to receive frame.
*
* This array is in global scope to allow optimizations in FSM module in case there is only
* one buffer provided by this module.
*
*/
extern rx_buffer_t nrf_drv_radio802154_rx_buffers[];
/**
* @brief Initialize buffer for received frames.
*/
void nrf_drv_radio802154_rx_buffer_init(void);
/**
* @brief Get free buffer to receive a frame.
*
* @return Pointer to free buffer of NULL if no free buffer is available.
*/
rx_buffer_t * nrf_drv_radio802154_rx_buffer_free_find(void);
#ifdef __cplusplus
}
#endif
#endif /* NRF_DRV_RADIO802154_RX_BUFFER_H_ */
@@ -0,0 +1,478 @@
/* Copyright (c) 2017, 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 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.
*
*/
/**
* @file
* This file implements SWI manager for nRF 802.15.4 driver.
*
*/
#include "nrf_drv_radio802154_swi.h"
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include "nrf_drv_radio802154.h"
#include "nrf_drv_radio802154_config.h"
#include "nrf_drv_radio802154_critical_section.h"
#include "nrf_drv_radio802154_fsm.h"
#include "nrf_drv_radio802154_rx_buffer.h"
#include "hal/nrf_egu.h"
#include "raal/nrf_raal_api.h"
#define NTF_QUEUE_SIZE (RADIO_RX_BUFFERS + 3) // for each rx buffer, 1 for tx, 1 for channel busy, 1 for energy detection
#define REQ_QUEUE_SIZE 2 // minimal queue size
#define SWI_EGU NRF_EGU3
#define SWI_IRQn SWI3_EGU3_IRQn
#define SWI_IRQHandler SWI3_EGU3_IRQHandler
#define NTF_INT NRF_EGU_INT_TRIGGERED0
#define NTF_TASK NRF_EGU_TASK_TRIGGER0
#define NTF_EVENT NRF_EGU_EVENT_TRIGGERED0
#define TIMESLOT_EXIT_INT NRF_EGU_INT_TRIGGERED1
#define TIMESLOT_EXIT_TASK NRF_EGU_TASK_TRIGGER1
#define TIMESLOT_EXIT_EVENT NRF_EGU_EVENT_TRIGGERED1
#define REQ_INT NRF_EGU_INT_TRIGGERED2
#define REQ_TASK NRF_EGU_TASK_TRIGGER2
#define REQ_EVENT NRF_EGU_EVENT_TRIGGERED2
typedef enum
{
NTF_TYPE_RECEIVED,
NTF_TYPE_TRANSMITTED,
NTF_TYPE_CHANNEL_BUSY,
NTF_TYPE_ENERGY_DETECTED,
} nrf_drv_radio802154_ntf_type_t;
typedef struct
{
nrf_drv_radio802154_ntf_type_t type;
union
{
struct
{
uint8_t * p_psdu;
int8_t power;
int8_t lqi;
} received;
struct
{
uint8_t * p_psdu;
int8_t power;
int8_t lqi;
} transmitted;
struct
{
int8_t result;
} energy_detected;
} data;
} nrf_drv_radio802154_ntf_data_t;
typedef enum
{
REQ_TYPE_SLEEP,
REQ_TYPE_RECEIVE,
REQ_TYPE_TRANSMIT,
REQ_TYPE_ENERGY_DETECTION,
REQ_TYPE_BUFFER_FREE,
} nrf_drv_radio802154_req_type_t;
typedef struct
{
nrf_drv_radio802154_req_type_t type;
union
{
struct
{
bool * p_result;
} sleep;
struct
{
bool * p_result;
uint8_t channel;
} receive;
struct
{
bool * p_result;
const uint8_t * p_data;
uint8_t channel;
int8_t power;
} transmit;
struct
{
bool * p_result;
uint8_t channel;
uint32_t time_us;
} energy_detection;
struct
{
rx_buffer_t * p_data;
} buffer_free;
} data;
} nrf_drv_radio802154_req_data_t;
static nrf_drv_radio802154_ntf_data_t m_ntf_queue[NTF_QUEUE_SIZE];
static uint8_t m_ntf_r_ptr;
static uint8_t m_ntf_w_ptr;
static nrf_drv_radio802154_req_data_t m_req_queue[REQ_QUEUE_SIZE];
static uint8_t m_req_r_ptr;
static uint8_t m_req_w_ptr;
static void queue_ptr_increment(uint8_t * p_ptr, uint8_t queue_size)
{
if (++(*p_ptr) >= queue_size)
{
*p_ptr = 0;
}
}
static bool queue_is_full(uint8_t r_ptr, uint8_t w_ptr, uint8_t queue_size)
{
if (w_ptr == (r_ptr - 1))
{
return true;
}
if ((r_ptr == 0) && (w_ptr == queue_size - 1))
{
return true;
}
return false;
}
static bool queue_is_empty(uint8_t r_ptr, uint8_t w_ptr)
{
return (r_ptr == w_ptr);
}
static void ntf_queue_ptr_increment(uint8_t * p_ptr)
{
queue_ptr_increment(p_ptr, NTF_QUEUE_SIZE);
}
static bool ntf_queue_is_full(void)
{
return queue_is_full(m_ntf_r_ptr, m_ntf_w_ptr, NTF_QUEUE_SIZE);
}
static bool ntf_queue_is_empty(void)
{
return queue_is_empty(m_ntf_r_ptr, m_ntf_w_ptr);
}
static void req_queue_ptr_increment(uint8_t * p_ptr)
{
queue_ptr_increment(p_ptr, REQ_QUEUE_SIZE);
}
static bool req_queue_is_full(void)
{
return queue_is_full(m_req_r_ptr, m_req_w_ptr, REQ_QUEUE_SIZE);
}
static bool req_queue_is_empty(void)
{
return queue_is_empty(m_req_r_ptr, m_req_w_ptr);
}
void nrf_drv_radio802154_swi_init(void)
{
m_ntf_r_ptr = 0;
m_ntf_w_ptr = 0;
nrf_egu_int_enable(SWI_EGU,
NTF_INT |
TIMESLOT_EXIT_INT |
REQ_INT);
NVIC_SetPriority(SWI_IRQn, RADIO_NOTIFICATION_SWI_PRIORITY);
NVIC_ClearPendingIRQ(SWI_IRQn);
NVIC_EnableIRQ(SWI_IRQn);
}
void nrf_drv_radio802154_swi_notify_received(uint8_t * p_data, int8_t power, int8_t lqi)
{
assert(!ntf_queue_is_full());
nrf_drv_radio802154_ntf_data_t * p_slot = &m_ntf_queue[m_ntf_w_ptr];
p_slot->type = NTF_TYPE_RECEIVED;
p_slot->data.received.p_psdu = p_data;
p_slot->data.received.power = power;
p_slot->data.received.lqi = lqi;
ntf_queue_ptr_increment(&m_ntf_w_ptr);
nrf_egu_task_trigger(SWI_EGU, NTF_TASK);
}
void nrf_drv_radio802154_swi_notify_transmitted(uint8_t * p_data, int8_t power, int8_t lqi)
{
assert(!ntf_queue_is_full());
nrf_drv_radio802154_ntf_data_t * p_slot = &m_ntf_queue[m_ntf_w_ptr];
p_slot->type = NTF_TYPE_TRANSMITTED;
p_slot->data.transmitted.p_psdu = p_data;
p_slot->data.transmitted.power = power;
p_slot->data.transmitted.lqi = lqi;
ntf_queue_ptr_increment(&m_ntf_w_ptr);
nrf_egu_task_trigger(SWI_EGU, NTF_TASK);
}
void nrf_drv_radio802154_swi_notify_busy_channel(void)
{
assert(!ntf_queue_is_full());
nrf_drv_radio802154_ntf_data_t * p_slot = &m_ntf_queue[m_ntf_w_ptr];
p_slot->type = NTF_TYPE_CHANNEL_BUSY;
ntf_queue_ptr_increment(&m_ntf_w_ptr);
nrf_egu_task_trigger(SWI_EGU, NTF_TASK);
}
void nrf_drv_radio802154_swi_notify_energy_detected(int8_t result)
{
assert(!ntf_queue_is_full());
nrf_drv_radio802154_ntf_data_t * p_slot = &m_ntf_queue[m_ntf_w_ptr];
p_slot->type = NTF_TYPE_ENERGY_DETECTED;
p_slot->data.energy_detected.result = result;
ntf_queue_ptr_increment(&m_ntf_w_ptr);
nrf_egu_task_trigger(SWI_EGU, NTF_TASK);
}
void nrf_drv_radio802154_swi_timeslot_exit(void)
{
assert(!nrf_egu_event_check(SWI_EGU, TIMESLOT_EXIT_EVENT));
nrf_egu_task_trigger(SWI_EGU, TIMESLOT_EXIT_TASK);
}
void nrf_drv_radio802154_swi_sleep(bool * p_result)
{
nrf_drv_radio802154_critical_section_enter();
assert(!req_queue_is_full());
nrf_drv_radio802154_req_data_t * p_slot = &m_req_queue[m_req_w_ptr];
p_slot->type = REQ_TYPE_SLEEP;
p_slot->data.sleep.p_result = p_result;
req_queue_ptr_increment(&m_req_w_ptr);
nrf_egu_task_trigger(SWI_EGU, REQ_TASK);
nrf_drv_radio802154_critical_section_exit();
}
void nrf_drv_radio802154_swi_receive(uint8_t channel, bool * p_result)
{
nrf_drv_radio802154_critical_section_enter();
assert(!req_queue_is_full());
nrf_drv_radio802154_req_data_t * p_slot = &m_req_queue[m_req_w_ptr];
p_slot->type = REQ_TYPE_RECEIVE;
p_slot->data.receive.channel = channel;
p_slot->data.receive.p_result = p_result;
req_queue_ptr_increment(&m_req_w_ptr);
nrf_egu_task_trigger(SWI_EGU, REQ_TASK);
nrf_drv_radio802154_critical_section_exit();
}
void nrf_drv_radio802154_swi_transmit(const uint8_t * p_data,
uint8_t channel,
int8_t power,
bool * p_result)
{
nrf_drv_radio802154_critical_section_enter();
assert(!req_queue_is_full());
nrf_drv_radio802154_req_data_t * p_slot = &m_req_queue[m_req_w_ptr];
p_slot->type = REQ_TYPE_TRANSMIT;
p_slot->data.transmit.p_data = p_data;
p_slot->data.transmit.channel = channel;
p_slot->data.transmit.power = power;
p_slot->data.transmit.p_result = p_result;
req_queue_ptr_increment(&m_req_w_ptr);
nrf_egu_task_trigger(SWI_EGU, REQ_TASK);
nrf_drv_radio802154_critical_section_exit();
}
void nrf_drv_radio802154_swi_energy_detection(uint8_t channel, uint32_t time_us, bool * p_result)
{
nrf_drv_radio802154_critical_section_enter();
assert(!req_queue_is_full());
nrf_drv_radio802154_req_data_t * p_slot = &m_req_queue[m_req_w_ptr];
p_slot->type = REQ_TYPE_ENERGY_DETECTION;
p_slot->data.energy_detection.channel = channel;
p_slot->data.energy_detection.time_us = time_us;
p_slot->data.energy_detection.p_result = p_result;
req_queue_ptr_increment(&m_req_w_ptr);
nrf_egu_task_trigger(SWI_EGU, REQ_TASK);
nrf_drv_radio802154_critical_section_exit();
}
void nrf_drv_radio802154_swi_buffer_free(uint8_t * p_data)
{
nrf_drv_radio802154_critical_section_enter();
assert(!req_queue_is_full());
nrf_drv_radio802154_req_data_t * p_slot = &m_req_queue[m_req_w_ptr];
p_slot->type = REQ_TYPE_BUFFER_FREE;
p_slot->data.buffer_free.p_data = (rx_buffer_t *)p_data;
req_queue_ptr_increment(&m_req_w_ptr);
nrf_egu_task_trigger(SWI_EGU, REQ_TASK);
nrf_drv_radio802154_critical_section_exit();
}
void SWI_IRQHandler(void)
{
if (nrf_egu_event_check(SWI_EGU, NTF_EVENT))
{
nrf_egu_event_clear(SWI_EGU, NTF_EVENT);
while (!ntf_queue_is_empty())
{
nrf_drv_radio802154_ntf_data_t * p_slot = &m_ntf_queue[m_ntf_r_ptr];
switch (p_slot->type)
{
case NTF_TYPE_RECEIVED:
nrf_drv_radio802154_received(p_slot->data.received.p_psdu,
p_slot->data.received.power,
p_slot->data.received.lqi);
break;
case NTF_TYPE_TRANSMITTED:
nrf_drv_radio802154_transmitted(p_slot->data.transmitted.p_psdu,
p_slot->data.transmitted.power,
p_slot->data.transmitted.lqi);
break;
case NTF_TYPE_CHANNEL_BUSY:
nrf_drv_radio802154_busy_channel();
break;
case NTF_TYPE_ENERGY_DETECTED:
nrf_drv_radio802154_energy_detected(p_slot->data.energy_detected.result);
break;
default:
assert(false);
}
ntf_queue_ptr_increment(&m_ntf_r_ptr);
}
}
if (nrf_egu_event_check(SWI_EGU, TIMESLOT_EXIT_EVENT))
{
nrf_raal_continuous_mode_exit();
nrf_egu_event_clear(SWI_EGU, TIMESLOT_EXIT_EVENT);
}
if (nrf_egu_event_check(SWI_EGU, REQ_EVENT))
{
nrf_egu_event_clear(SWI_EGU, REQ_EVENT);
while (!req_queue_is_empty())
{
nrf_drv_radio802154_req_data_t * p_slot = &m_req_queue[m_req_r_ptr];
switch (p_slot->type)
{
case REQ_TYPE_SLEEP:
*(p_slot->data.sleep.p_result) = nrf_drv_radio802154_fsm_sleep();
break;
case REQ_TYPE_RECEIVE:
*(p_slot->data.receive.p_result) = nrf_drv_radio802154_fsm_receive(
p_slot->data.receive.channel);
break;
case REQ_TYPE_TRANSMIT:
*(p_slot->data.transmit.p_result) = nrf_drv_radio802154_fsm_transmit(
p_slot->data.transmit.p_data,
p_slot->data.transmit.channel,
p_slot->data.transmit.power);
break;
case REQ_TYPE_ENERGY_DETECTION:
*(p_slot->data.energy_detection.p_result) =
nrf_drv_radio802154_fsm_energy_detection(
p_slot->data.energy_detection.channel,
p_slot->data.energy_detection.time_us);
break;
case REQ_TYPE_BUFFER_FREE:
nrf_drv_radio802154_fsm_notify_buffer_free(p_slot->data.buffer_free.p_data);
break;
default:
assert(false);
}
req_queue_ptr_increment(&m_req_r_ptr);
}
}
}
@@ -0,0 +1,142 @@
/* Copyright (c) 2017, 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 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_DRIVER_RADIO802154_SWI_H__
#define NRF_DRIVER_RADIO802154_SWI_H__
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_driver_radio802154_swi 802.15.4 driver SWI management
* @{
* @ingroup nrf_driver_radio802154
* @brief SWI manager for 802.15.4 driver.
*/
/**
* @brief Initialize SWI module.
*/
void nrf_drv_radio802154_swi_init(void);
/**
* @brief Notify next higher layer that a frame was received from SWI priority level.
*
* @param[in] p_data Array of bytes containing PSDU. First byte contains frame length, other contain the frame itself.
* @param[in] power RSSI measured during the frame reception.
* @param[in] lqi LQI indicating measured link quality during the frame reception.
*/
void nrf_drv_radio802154_swi_notify_received(uint8_t * p_data, int8_t power, int8_t lqi);
/**
* @brief Notify next higher layer that a frame was transmitted from SWI priority level.
*
* @param[in] p_ack Pointer to buffer containing PSDU of ACK frame. NULL if ACK was not requested.
* @param[in] power RSSI of received frame or 0 if ACK was not requested.
* @param[in] lqi LQI of received frame of 0 if ACK was not requested.
*/
void nrf_drv_radio802154_swi_notify_transmitted(uint8_t * p_data, int8_t power, int8_t lqi);
/**
* @brief Notify next higher layer that a frame was not transmitted from SWI priority level.
*/
void nrf_drv_radio802154_swi_notify_busy_channel(void);
/**
* @brief Notify next higher layer that energy detection procedure ended from SWI priority level.
*
* @param[in] result Detected energy level.
*/
void nrf_drv_radio802154_swi_notify_energy_detected(int8_t result);
/**
* @brief Request discarding of the timeslot from SWI priority level.
*
* @note This function should be called through notification module to prevent calling it from arbiter context.
*/
void nrf_drv_radio802154_swi_timeslot_exit(void);
/**
* @brief Request entering sleep state from SWI priority.
*
* @param[out] p_result Result of entering sleep state.
*/
void nrf_drv_radio802154_swi_sleep(bool * p_result);
/**
* @brief Request entering receive state from SWI priority.
*
* @param[in] channel Channel number used for receive procedure.
* @param[out] p_result Result of entering receive state.
*/
void nrf_drv_radio802154_swi_receive(uint8_t channel, bool * p_result);
/**
* @biref Request entering transmit state from SWI priority.
*
* @param[in] p_data Pointer to PSDU of the frame to transmit.
* @param[in] channel Channel number used for requested transmission.
* @param[in] power Transmitter power for requested transmission.
* @param[out] p_result Result of entering transmit state.
*/
void nrf_drv_radio802154_swi_transmit(const uint8_t * p_data,
uint8_t channel,
int8_t power,
bool * p_result);
/**
* @brief Request entering energy detection state from SWI priority.
*
* @param[in] channel Channel number used for the energy detection procedure.
* @param[in] time_us Requested duration of energy detection procedure.
* @param[out] p_result Result of entering energy detection state.
*/
void nrf_drv_radio802154_swi_energy_detection(uint8_t channel, uint32_t time_us, bool * p_result);
/**
* @brief Notify FSM that given buffer is not used anymore and can be freed.
*
* @param[in] p_data Pointer to the buffer to free.
*/
void nrf_drv_radio802154_swi_buffer_free(uint8_t * p_data);
/**
*@}
**/
#ifdef __cplusplus
}
#endif
#endif // NRF_DRIVER_RADIO802154_SWI_H__
@@ -0,0 +1,176 @@
/* Copyright (c) 2017, 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 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.
*
*/
/**
* @brief This module defines Radio Arbiter Abstraction Layer interface.
*
*/
#ifndef NRF_RAAL_API_H_
#define NRF_RAAL_API_H_
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_raal Radio Arbiter Abstraction Layer
* @{
* @ingroup nrf_driver_radio802154
* @brief Radio Arbiter Abstraction Layer interface.
*/
/**
* @brief Initialize RAAL.
*
* @note This function shall be called once, before any other function from this module.
*
* Initialize Radio Arbiter Abstraction Layer client.
*
* @note Arbiter starts in inactive mode after initialization. In order to start radio activity
* @p nrf_raal_continuous_mode_enter method should be called.
*
*/
void nrf_raal_init(void);
/**
* @brief Uninitialize RAAL.
*
* Uninitialize Radio Arbiter Abstraction Layer client.
*
*/
void nrf_raal_uninit(void);
/**
* @brief Enter arbiter into continuous radio mode.
*
* In this mode radio arbiter should try to create long continuous timeslots that will give the
* radio driver as much radio time as possible while disturbing the other activities as little
* as possible.
* The arbiter client shall make sure that high frequency clock is enabled in each timeslot.
*
* @note The start of a timeslot will be indicated by @p nrf_raal_timeslot_started call.
*
*/
void nrf_raal_continuous_mode_enter(void);
/**
* @brief Exit arbiter from continous mode.
*
* In this mode radio arbiter will not extend or allocate any more timeslots for radio driver.
*
*/
void nrf_raal_continuous_mode_exit(void);
/**
* @brief Request timeslot for radio communication.
*
* This method should be called only after @p nrf_raal_timeslot_started indicated the start
* of a timeslot.
*
* @param[in] length_us Requested radio timeslot length in microsecond.
*
* @retval TRUE The radio driver now has exclusive access to the RADIO peripheral for the
* full length of the timeslot.
* @retval FALSE Slot cannot be assigned due to other activities.
*
*/
bool nrf_raal_timeslot_request(uint32_t length_us);
/**
* @brief Get left time of currently granted timeslot [us].
*
* @returns Number of microseconds left in currently granted timeslot.
*/
uint32_t nrf_raal_timeslot_us_left_get(void);
/**
* @brief Enter critical section of the module.
*
* When this method is called, the execution of the @nrf_raal_timeslot_ended function is blocked.
*
*/
void nrf_raal_critical_section_enter(void);
/**
* @brief Exit critical section of the module.
*
* When this method is called driver has to expect the execution of the @nrf_raal_timeslot_ended
* function.
*
*/
void nrf_raal_critical_section_exit(void);
/**
* @brief RAAL client calls this method to notify radio driver about the start of a timeslot.
*
* The radio driver now has exclusive access to the peripherals until @p nrf_raal_timeslot_ended
* is called.
*
* @note The high frequency clock must be enabled when this function is called.
* @note The end of the timeslot will be indicated by @p nrf_raal_timeslot_ended function.
*
*/
extern void nrf_raal_timeslot_started(void);
/**
* @brief RAAL client calls this method to notify radio driver about the end of a timeslot.
*
* Depending on the RAAL client configuration, radio driver has NRF_RAAL_MAX_CLEAN_UP_TIME_US
* microseconds to do any clean-up actions on RADIO peripheral and stop using it completely.
* Thus arbiter has to call this function NRF_RAAL_MAX_CLEAN_UP_TIME_US microseconds before
* timeslot is finished.
*
* If RAAL is in the continuous mode, the next timeslot will be indicated again by
* @p nrf_raal_timeslot_started function.
*
* This method shall not be called if @p nrf_raal_continuous_mode_exit has been called. Radio
* driver shall assume that timeslot has been finished after @p nrf_raal_continuous_mode_exit
* call.
*
* @note Because radio driver needs to stop any operation on RADIO peripheral within
* NRF_RAAL_MAX_CLEAN_UP_TIME_US microseconds, this method should be called with high
* interrupt priority level to avoid unwanted delays.
*
*/
extern void nrf_raal_timeslot_ended(void);
/**
*@}
**/
#ifdef __cplusplus
}
#endif
#endif /* NRF_RAAL_API_H_ */
@@ -0,0 +1,90 @@
/* Copyright (c) 2017, 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 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_RAAL_CONFIG_H__
#define NRF_RAAL_CONFIG_H__
#include <nrf.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_raal_config RAAL configuration
* @{
* @ingroup nrf_driver_radio802154
* @brief Configuration of Radio Arbiter Abstraction Layer.
*/
/**
* @def NRF_RAAL_MAX_CLEAN_UP_TIME_US
*
* Maximum time within radio driver needs to do any clean-up actions on RADIO peripheral
* and stop using it completely.
*
*/
#ifndef NRF_RAAL_MAX_CLEAN_UP_TIME_US
#define NRF_RAAL_MAX_CLEAN_UP_TIME_US 100
#endif
/**
* @def NRF_RAAL_HFCLK_START
*
* Macro to request High Frequency Clock start. It may use external driver or OS function.
*
*/
#define NRF_RAAL_HFCLK_START() \
do { \
NRF_CLOCK->TASKS_HFCLKSTART = 1; \
\
while(NRF_CLOCK->HFCLKSTAT != (CLOCK_HFCLKSTAT_SRC_Msk | CLOCK_HFCLKSTAT_STATE_Msk)) {} \
} while(0);
/**
* @def NRF_RAAL_HFCLK_STOP
*
* Macro to release High Frequency Clock. It may use external driver or OS function.
*
*/
#define NRF_RAAL_HFCLK_STOP() \
do { \
NRF_CLOCK->TASKS_HFCLKSTOP = 1; \
} while(0);
/**
*@}
**/
#ifdef __cplusplus
}
#endif
#endif // NRF_RAAL_CONFIG_H__
@@ -0,0 +1,99 @@
/* Copyright (c) 2017, 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 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.
*
*/
/**
* @file
* This file implements the nrf 802.15.4 radio arbiter for single phy.
*
* This arbiter should be used when 802.15.4 is the only wireless protocol used by the application.
*
*/
#include "nrf_raal_api.h"
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include "nrf_raal_config.h"
static bool m_continuous;
void nrf_raal_init(void)
{
m_continuous = false;
}
void nrf_raal_uninit(void)
{
// Intentionally empty.
}
void nrf_raal_continuous_mode_enter(void)
{
assert(!m_continuous);
NRF_RAAL_HFCLK_START();
m_continuous = true;
nrf_raal_timeslot_started();
}
void nrf_raal_continuous_mode_exit(void)
{
assert(m_continuous);
m_continuous = false;
NRF_RAAL_HFCLK_STOP();
}
bool nrf_raal_timeslot_request(uint32_t length_us)
{
(void) length_us;
assert(m_continuous);
return true;
}
uint32_t nrf_raal_timeslot_us_left_get(void)
{
return UINT32_MAX;
}
void nrf_raal_critical_section_enter(void)
{
// Intentionally empty.
}
void nrf_raal_critical_section_exit(void)
{
// Intentionally empty.
}
@@ -0,0 +1,675 @@
/* Copyright (c) 2017, 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 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.
*
*/
/**
* @file
* This file implements the nrf 802.15.4 radio arbiter for softdevice.
*
* This arbiter should be used when 802.15.4 works concurrently with SoftDevice's radio stack.
*
*/
#include "nrf_raal_softdevice.h"
#include <assert.h>
#include <stdbool.h>
#include <string.h>
#include <nrf_raal_api.h>
#include <nrf_drv_radio802154_debug.h>
#include <nrf_drv_clock.h>
#include <softdevice.h>
/**@brief Enable Request and End on timeslot safety interrupt. */
#define ENABLE_REQUEST_AND_END_ON_TIMESLOT_END 0
/**@brief Maximum jitter relative to the start time of START and TIMER0 (safety margin) events . */
#define TIMER_TO_SIGNAL_JITTER_US NRF_RADIO_START_JITTER_US + 6
/**@brief Timer compare channel definitions. */
#define TIMER_CC_EXTEND 0
#define TIMER_CC_EXTEND_INTENSET TIMER_INTENSET_COMPARE0_Msk
#define TIMER_CC_EXTEND_INTENCLR TIMER_INTENCLR_COMPARE0_Pos
#define TIMER_CC_MARGIN 1
#define TIMER_CC_MARGIN_INTENSET TIMER_INTENSET_COMPARE1_Msk
#define TIMER_CC_MARGIN_INTENCLR TIMER_INTENCLR_COMPARE1_Pos
#define TIMER_CC_CAPTURE 2
/**@brief Defines number of microseconds in one second. */
#define US_PER_S 1000000
/**@brief Ceil division helper */
#define DIVIDE_AND_CEIL(A, B) (((A) + (B) - 1) / (B))
/**@brief Defines pending events. */
typedef enum
{
PENDING_EVENT_NONE = 0,
PENDING_EVENT_STARTED,
PENDING_EVENT_ENDED
} pending_events_t;
/**@brief Request parameters. */
static nrf_radio_request_t m_request;
/**@brief Return parameter for SD radio signal handler. */
static nrf_radio_signal_callback_return_param_t m_ret_param;
/**@brief Current configuration of the RAAL. */
static nrf_raal_softdevice_cfg_t m_config;
/**@brief Current timeslot length. */
static uint16_t m_timeslot_length;
/**@brief Defines if RAAL is in continous mode. */
static volatile bool m_continuous = false;
/**@brief Defines if RAAL is currently in a timeslot. */
static volatile bool m_in_timeslot = false;
/**@brief Current iteration process number. */
static volatile uint16_t m_alloc_iters;
/**@brief Defines if module has been initialized. */
static bool m_initialize = false;
/**@breif Defines if Radio Driver entered critical section. */
static volatile bool m_in_critical_section = false;
/**@brief Defines current pending event. */
static volatile pending_events_t m_pending_event = PENDING_EVENT_NONE;
/**@brief Defines RTC0 counter value on timeslot begin. */
static uint32_t m_start_rtc_ticks = 0;
/**@brief External Interrupt from RADIO. */
extern void RADIO_IRQHandler(void);
/**@brief Initialize timeslot internal variables. */
static inline void timeslot_data_init(void)
{
m_alloc_iters = 0;
m_timeslot_length = m_config.timeslot_length;
}
/**@brief Get actual time. */
static inline uint32_t timer_time_get(void)
{
NRF_TIMER0->TASKS_CAPTURE[TIMER_CC_CAPTURE] = 1;
return NRF_TIMER0->CC[TIMER_CC_CAPTURE];
}
/**@brief Enter timeslot critical section. */
static inline void timeslot_critical_section_enter(void)
{
NVIC_DisableIRQ(TIMER0_IRQn);
__DSB();
__ISB();
}
/**@brief Exit timeslot critical section. */
static inline void timeslot_critical_section_exit(void)
{
NVIC_EnableIRQ(TIMER0_IRQn);
}
static inline void timeslot_started_notify(void)
{
if (m_in_timeslot && m_continuous)
{
nrf_raal_timeslot_started();
}
}
static inline void timeslot_ended_notify(void)
{
if (!m_in_timeslot && m_continuous)
{
nrf_raal_timeslot_ended();
}
}
/**@brief Calculate maximal crystal drift. */
static inline uint32_t rtc_drift_calculate(uint32_t timeslot_length)
{
return DIVIDE_AND_CEIL(((uint64_t)timeslot_length * m_config.lf_clk_accuracy_ppm), US_PER_S);
}
/**@brief Prepare earliest timeslot request. */
static void timeslot_request_prepare(void)
{
memset(&m_request, 0, sizeof(m_request));
m_request.request_type = NRF_RADIO_REQ_TYPE_EARLIEST;
m_request.params.earliest.hfclk = NRF_RADIO_HFCLK_CFG_NO_GUARANTEE;
m_request.params.earliest.priority = NRF_RADIO_PRIORITY_NORMAL;
m_request.params.earliest.length_us = m_timeslot_length;
m_request.params.earliest.timeout_us = m_config.timeslot_timeout;
}
/**@brief Request earliest timeslot. */
static void timeslot_request(void)
{
assert(!m_in_timeslot);
timeslot_request_prepare();
sd_radio_request(&m_request);
}
/**@brief Set timer on timeslot started. */
static void timer_start(void)
{
NRF_TIMER0->TASKS_STOP = 1;
NRF_TIMER0->TASKS_CLEAR = 1;
NRF_TIMER0->BITMODE = TIMER_BITMODE_BITMODE_32Bit;
NRF_TIMER0->INTENSET = TIMER_CC_MARGIN_INTENSET;
NRF_TIMER0->CC[TIMER_CC_EXTEND] = 0;
NRF_TIMER0->CC[TIMER_CC_MARGIN] = m_timeslot_length - m_config.timeslot_safe_margin;
NRF_TIMER0->TASKS_START = 1;
NVIC_EnableIRQ(TIMER0_IRQn);
}
/**@brief Reset timer. */
static void timer_reset(void)
{
NRF_TIMER0->TASKS_STOP = 1;
NRF_TIMER0->EVENTS_COMPARE[TIMER_CC_EXTEND] = 0;
NRF_TIMER0->EVENTS_COMPARE[TIMER_CC_MARGIN] = 0;
NVIC_ClearPendingIRQ(TIMER0_IRQn);
}
/**@brief Set timer on extend event. */
static void timer_extend(void)
{
NVIC_ClearPendingIRQ(TIMER0_IRQn);
NRF_TIMER0->INTENSET = TIMER_CC_MARGIN_INTENSET;
NRF_TIMER0->CC[TIMER_CC_MARGIN] += m_timeslot_length;
if (!m_alloc_iters)
{
NRF_TIMER0->INTENSET = TIMER_CC_EXTEND_INTENSET;
NRF_TIMER0->CC[TIMER_CC_EXTEND] += m_timeslot_length;
}
}
/**@brief Eliminate timers jitters. */
static void timer_jitter_adjust(void)
{
// Adjust TIMER0 and RTC0 clocks drifts.
uint32_t timer_ticks = timer_time_get();
uint64_t rtc_ticks = NRF_RTC0->COUNTER;
if (rtc_ticks > m_start_rtc_ticks)
{
rtc_ticks -= m_start_rtc_ticks;
}
else
{
// Overflow detected.
rtc_ticks = RTC_COUNTER_COUNTER_Msk - m_start_rtc_ticks + rtc_ticks;
}
// Adjust RTC0 ticks to TIMER0 resolution. RTC0 works with 32768kHz so first
// multiply with 10^6 (microseconds) and divide by 32768Hz (2^15) to get microseconds.
rtc_ticks = DIVIDE_AND_CEIL((rtc_ticks * US_PER_S), 32768);
// Check if we are still in time.
uint32_t cc_margin = NRF_TIMER0->CC[TIMER_CC_MARGIN];
assert(cc_margin > rtc_ticks + rtc_drift_calculate(cc_margin));
if (rtc_ticks > timer_ticks)
{
NRF_TIMER0->CC[TIMER_CC_MARGIN] -= (rtc_ticks - timer_ticks);
}
else
{
NRF_TIMER0->CC[TIMER_CC_MARGIN] += (timer_ticks - rtc_ticks);
}
// Add safety drift time.
NRF_TIMER0->CC[TIMER_CC_MARGIN] -= rtc_drift_calculate(2 * m_config.timeslot_length) +
TIMER_TO_SIGNAL_JITTER_US;
}
/**@brief Decrease timeslot length. */
static void timeslot_decrease_length(void)
{
m_alloc_iters++;
m_timeslot_length = m_timeslot_length >> 1;
}
/**@brief Extend timeslot. */
static void timeslot_extend(void)
{
if (m_alloc_iters < m_config.timeslot_alloc_iters)
{
timeslot_decrease_length();
// Try to extend right after start.
m_ret_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND;
m_ret_param.params.extend.length_us = m_timeslot_length;
nrf_drv_radio802154_pin_set(PIN_DBG_TIMESLOT_EXTEND_REQ);
}
else
{
timer_jitter_adjust();
}
}
static void timer_irq_handle(void)
{
// Safe margin exceeded.
if (NRF_TIMER0->EVENTS_COMPARE[TIMER_CC_MARGIN])
{
nrf_drv_radio802154_pin_clr(PIN_DBG_TIMESLOT_ACTIVE);
nrf_drv_radio802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_SIG_EVENT_MARGIN);
m_in_timeslot = false;
if (m_in_critical_section)
{
assert(m_pending_event != PENDING_EVENT_ENDED);
if (m_pending_event == PENDING_EVENT_STARTED)
{
m_pending_event = PENDING_EVENT_NONE;
}
else
{
m_pending_event = PENDING_EVENT_ENDED;
}
}
else
{
timeslot_ended_notify();
}
// Ignore any other events.
timer_reset();
#if (ENABLE_REQUEST_AND_END_ON_TIMESLOT_END == 1)
timeslot_data_init();
timeslot_request_prepare();
m_ret_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END;
m_ret_param.params.request.p_next = &m_request;
#else
// Return and wait for NRF_EVT_RADIO_SESSION_IDLE event.
m_ret_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE;
#endif
nrf_drv_radio802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_EVENT_MARGIN);
}
// Extension margin exceeded.
else if (NRF_TIMER0->EVENTS_COMPARE[TIMER_CC_EXTEND])
{
nrf_drv_radio802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_SIG_EVENT_EXTEND);
NRF_TIMER0->INTENCLR = (1 << TIMER_CC_EXTEND_INTENCLR);
NRF_TIMER0->EVENTS_COMPARE[TIMER_CC_EXTEND] = 0;
if (m_continuous &&
NRF_TIMER0->CC[TIMER_CC_EXTEND] + m_config.timeslot_length < m_config.timeslot_max_length)
{
nrf_drv_radio802154_pin_set(PIN_DBG_TIMESLOT_EXTEND_REQ);
m_ret_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND;
m_ret_param.params.extend.length_us = m_config.timeslot_length;
}
else
{
timer_jitter_adjust();
m_ret_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE;
}
nrf_drv_radio802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_EVENT_EXTEND);
}
else
{
// Should not happen.
assert(false);
}
}
/**@brief Signal handler. */
static nrf_radio_signal_callback_return_param_t *signal_handler(uint8_t signal_type)
{
nrf_drv_radio802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_SIG_HANDLER);
// Default response.
m_ret_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE;
if (!m_continuous)
{
nrf_drv_radio802154_pin_clr(PIN_DBG_TIMESLOT_ACTIVE);
nrf_drv_radio802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_SIG_EVENT_ENDED);
m_pending_event = PENDING_EVENT_NONE;
m_in_timeslot = false;
// TODO: Change to NRF_RADIO_SIGNAL_CALLBACK_ACTION_END (KRKNWK-937)
m_ret_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE;
timer_reset();
nrf_drv_radio802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_EVENT_ENDED);
nrf_drv_radio802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_HANDLER);
return &m_ret_param;
}
switch (signal_type)
{
case NRF_RADIO_CALLBACK_SIGNAL_TYPE_START: /**< This signal indicates the start of the radio timeslot. */
{
nrf_drv_radio802154_pin_set(PIN_DBG_TIMESLOT_ACTIVE);
nrf_drv_radio802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_SIG_EVENT_START);
// Ensure HFCLK is running before start is issued.
assert(NRF_CLOCK->HFCLKSTAT == (CLOCK_HFCLKSTAT_SRC_Msk | CLOCK_HFCLKSTAT_STATE_Msk));
m_start_rtc_ticks = NRF_RTC0->COUNTER;
m_in_timeslot = true;
m_alloc_iters = 0;
m_timeslot_length = m_timeslot_length;
timer_start();
if (m_in_critical_section)
{
assert(m_pending_event != PENDING_EVENT_STARTED);
if (m_pending_event == PENDING_EVENT_ENDED)
{
m_pending_event = PENDING_EVENT_NONE;
}
else
{
m_pending_event = PENDING_EVENT_STARTED;
}
}
else
{
timeslot_started_notify();
}
// Try to extend right after start.
m_ret_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND;
m_ret_param.params.extend.length_us = m_timeslot_length;
nrf_drv_radio802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_EVENT_START);
nrf_drv_radio802154_pin_set(PIN_DBG_TIMESLOT_EXTEND_REQ);
break;
}
case NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0: /**< This signal indicates the NRF_TIMER0 interrupt. */
timer_irq_handle();
break;
case NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO: /**< This signal indicates the NRF_RADIO interrupt. */
nrf_drv_radio802154_pin_set(PIN_DBG_TIMESLOT_RADIO_IRQ);
if (m_in_timeslot && !NRF_TIMER0->EVENTS_COMPARE[TIMER_CC_MARGIN])
{
RADIO_IRQHandler();
}
else
{
NVIC_ClearPendingIRQ(RADIO_IRQn);
}
nrf_drv_radio802154_pin_clr(PIN_DBG_TIMESLOT_RADIO_IRQ);
break;
case NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_FAILED: /**< This signal indicates extend action failed. */
nrf_drv_radio802154_pin_clr(PIN_DBG_TIMESLOT_EXTEND_REQ);
nrf_drv_radio802154_pin_tgl(PIN_DBG_TIMESLOT_FAILED);
timeslot_extend();
break;
case NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED: /**< This signal indicates extend action succeeded. */
nrf_drv_radio802154_pin_clr(PIN_DBG_TIMESLOT_EXTEND_REQ);
timer_extend();
if (m_alloc_iters != 0)
{
timeslot_extend();
}
break;
default:
break;
}
nrf_drv_radio802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_HANDLER);
return &m_ret_param;
}
void nrf_raal_softdevice_soc_evt_handler(uint32_t evt_id)
{
switch (evt_id)
{
case NRF_EVT_HFCLKSTARTED:
if (m_continuous)
{
timeslot_request();
}
break;
case NRF_EVT_RADIO_BLOCKED:
case NRF_EVT_RADIO_CANCELED:
{
nrf_drv_radio802154_pin_tgl(PIN_DBG_TIMESLOT_BLOCKED);
assert(!m_in_timeslot);
if (m_continuous)
{
if (m_alloc_iters < m_config.timeslot_alloc_iters)
{
timeslot_decrease_length();
}
timeslot_request();
}
break;
}
case NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN:
assert(false);
break;
case NRF_EVT_RADIO_SESSION_IDLE:
if (m_continuous)
{
nrf_drv_radio802154_pin_tgl(PIN_DBG_TIMESLOT_SESSION_IDLE);
timeslot_data_init();
timeslot_request();
}
break;
case NRF_EVT_RADIO_SESSION_CLOSED:
break;
default:
break;
}
}
void nrf_raal_softdevice_config(const nrf_raal_softdevice_cfg_t * p_cfg)
{
assert(m_initialize);
assert(!m_continuous);
assert(p_cfg);
m_config = *p_cfg;
}
void nrf_raal_init(void)
{
assert(!m_initialize);
m_continuous = false;
m_in_timeslot = false;
m_config.lf_clk_accuracy_ppm = NRF_RAAL_DEFAULT_LF_CLK_ACCURACY_PPM;
m_config.timeslot_length = NRF_RAAL_TIMESLOT_DEFAULT_LENGTH;
m_config.timeslot_alloc_iters = NRF_RAAL_TIMESLOT_DEFAULT_ALLOC_ITERS;
m_config.timeslot_safe_margin = NRF_RAAL_TIMESLOT_DEFAULT_SAFE_MARGIN;
m_config.timeslot_max_length = NRF_RAAL_TIMESLOT_DEFAULT_MAX_LENGTH;
m_config.timeslot_timeout = NRF_RAAL_TIMESLOT_DEFAULT_TIMEOUT;
assert(sd_radio_session_open(signal_handler) == NRF_SUCCESS);
m_initialize = true;
}
void nrf_raal_uninit(void)
{
assert(m_initialize);
assert(sd_radio_session_close() == NRF_SUCCESS);
m_continuous = false;
m_in_timeslot = false;
nrf_drv_radio802154_pin_clr(PIN_DBG_TIMESLOT_ACTIVE);
}
void nrf_raal_continuous_mode_enter(void)
{
nrf_drv_radio802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_CONTINUOUS_ENTER);
assert(m_initialize);
assert(!m_continuous);
m_alloc_iters = 0;
m_timeslot_length = m_config.timeslot_length;
m_continuous = true;
nrf_drv_clock_hfclk_request(NULL);
if (NRF_CLOCK->HFCLKSTAT == (CLOCK_HFCLKSTAT_SRC_Msk | CLOCK_HFCLKSTAT_STATE_Msk))
{
timeslot_request();
}
nrf_drv_radio802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_CONTINUOUS_ENTER);
}
void nrf_raal_continuous_mode_exit(void)
{
nrf_drv_radio802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_CONTINUOUS_EXIT);
assert(m_initialize);
assert(m_continuous);
m_continuous = false;
// Emulate signal interrupt to inform SD about end of m_continuous mode.
if (m_in_timeslot)
{
NVIC_SetPendingIRQ(TIMER0_IRQn);
}
nrf_drv_clock_hfclk_release();
nrf_drv_radio802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_CONTINUOUS_EXIT);
}
bool nrf_raal_timeslot_request(uint32_t length_us)
{
if (!m_continuous || !m_in_timeslot)
{
return false;
}
return timer_time_get() + length_us < NRF_TIMER0->CC[TIMER_CC_MARGIN];
}
uint32_t nrf_raal_timeslot_us_left_get(void)
{
if (!m_continuous || !m_in_timeslot)
{
return 0;
}
return NRF_TIMER0->CC[TIMER_CC_MARGIN] - timer_time_get();
}
void nrf_raal_critical_section_enter(void)
{
nrf_drv_radio802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_CRIT_SECT_ENTER);
assert(!m_in_critical_section);
m_in_critical_section = true;
nrf_drv_radio802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_CRIT_SECT_ENTER);
}
void nrf_raal_critical_section_exit(void)
{
nrf_drv_radio802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_CRIT_SECT_EXIT);
timeslot_critical_section_enter();
assert(m_in_critical_section);
m_in_critical_section = false;
switch (m_pending_event)
{
case PENDING_EVENT_STARTED:
timeslot_started_notify();
break;
case PENDING_EVENT_ENDED:
timeslot_ended_notify();
break;
default:
break;
}
m_pending_event = PENDING_EVENT_NONE;
timeslot_critical_section_exit();
nrf_drv_radio802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_CRIT_SECT_EXIT);
}
@@ -0,0 +1,85 @@
/* Copyright (c) 2017, 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 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.
*
*/
/**
* @brief This module defines Radio Arbiter Abstraction Layer interface.
*
*/
#ifndef NRF_RAAL_SOFTDEVICE_H_
#define NRF_RAAL_SOFTDEVICE_H_
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/** @brief RAAL Softdevice default parameters. */
#define NRF_RAAL_TIMESLOT_DEFAULT_LENGTH 6400
#define NRF_RAAL_TIMESLOT_DEFAULT_ALLOC_ITERS 5
#define NRF_RAAL_TIMESLOT_DEFAULT_SAFE_MARGIN 91
#define NRF_RAAL_TIMESLOT_DEFAULT_TIMEOUT 100000
#define NRF_RAAL_TIMESLOT_DEFAULT_MAX_LENGTH 120000000
#define NRF_RAAL_DEFAULT_LF_CLK_ACCURACY_PPM 25
/** @brief RAAL Softdevice configuration parameters. */
typedef struct
{
uint32_t timeslot_length; /**< Timeslot length requested by the module in microseconds. */
uint32_t timeslot_timeout; /**< Longest acceptable delay until the start of the requested timeslot in microseconds. */
uint32_t timeslot_max_length; /**< Maximum single timeslot length created by extension processing in microseconds. */
uint16_t timeslot_alloc_iters; /**< Maximum number of iteration of dividing timeslot_length by factor of 2 performed by arbiter. */
uint16_t timeslot_safe_margin; /**< Safe margin before timeslot is finished and nrf_raal_timeslot_ended should be called in microseconds. */
uint16_t lf_clk_accuracy_ppm; /**< Clock accuracy in ppm unit. */
} nrf_raal_softdevice_cfg_t;
/**
* @brief Function used to inform RAAL client about Softdevice's SoC events.
*
*/
void nrf_raal_softdevice_soc_evt_handler(uint32_t evt_id);
/**
* @brief Function used to set non-default parameters of RAAL.
*
*/
void nrf_raal_softdevice_config(const nrf_raal_softdevice_cfg_t * p_cfg);
/**
*@}
**/
#ifdef __cplusplus
}
#endif
#endif /* NRF_RAAL_SOFTDEVICE_H_ */
+344 -354
View File
@@ -1,354 +1,344 @@
/* Copyright (c) 2016, 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 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_EGU_H__
#define NRF_EGU_H__
/**
* @defgroup nrf_egu EGU (Event Generator Unit) abstraction
* @{
* @ingroup nrf_drivers
* @brief @tagAPI52 EGU (Event Generator Unit) module functions.
*
*/
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include "nrf_assert.h"
#include "nrf.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @enum nrf_egu_task_t
* @brief EGU tasks.
*/
typedef enum
{
/*lint -save -e30 -esym(628,__INTADDR__)*/
NRF_EGU_TASK_TRIGGER0 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[0]), /**< Trigger 0 for triggering the corresponding TRIGGERED[0] event. */
NRF_EGU_TASK_TRIGGER1 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[1]), /**< Trigger 1 for triggering the corresponding TRIGGERED[1] event. */
NRF_EGU_TASK_TRIGGER2 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[2]), /**< Trigger 2 for triggering the corresponding TRIGGERED[2] event. */
NRF_EGU_TASK_TRIGGER3 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[3]), /**< Trigger 3 for triggering the corresponding TRIGGERED[3] event. */
NRF_EGU_TASK_TRIGGER4 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[4]), /**< Trigger 4 for triggering the corresponding TRIGGERED[4] event. */
NRF_EGU_TASK_TRIGGER5 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[5]), /**< Trigger 5 for triggering the corresponding TRIGGERED[5] event. */
NRF_EGU_TASK_TRIGGER6 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[6]), /**< Trigger 6 for triggering the corresponding TRIGGERED[6] event. */
NRF_EGU_TASK_TRIGGER7 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[7]), /**< Trigger 7 for triggering the corresponding TRIGGERED[7] event. */
NRF_EGU_TASK_TRIGGER8 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[8]), /**< Trigger 8 for triggering the corresponding TRIGGERED[8] event. */
NRF_EGU_TASK_TRIGGER9 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[9]), /**< Trigger 9 for triggering the corresponding TRIGGERED[9] event. */
NRF_EGU_TASK_TRIGGER10 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[10]), /**< Trigger 10 for triggering the corresponding TRIGGERED[10] event. */
NRF_EGU_TASK_TRIGGER11 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[11]), /**< Trigger 11 for triggering the corresponding TRIGGERED[11] event. */
NRF_EGU_TASK_TRIGGER12 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[12]), /**< Trigger 12 for triggering the corresponding TRIGGERED[12] event. */
NRF_EGU_TASK_TRIGGER13 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[13]), /**< Trigger 13 for triggering the corresponding TRIGGERED[13] event. */
NRF_EGU_TASK_TRIGGER14 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[14]), /**< Trigger 14 for triggering the corresponding TRIGGERED[14] event. */
NRF_EGU_TASK_TRIGGER15 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[15]) /**< Trigger 15 for triggering the corresponding TRIGGERED[15] event. */
/*lint -restore*/
} nrf_egu_task_t;
/**
* @enum nrf_egu_event_t
* @brief EGU events.
*/
typedef enum
{
/*lint -save -e30 -esym(628,__INTADDR__)*/
NRF_EGU_EVENT_TRIGGERED0 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[0]), /**< Event number 0 generated by triggering the corresponding TRIGGER[0] task. */
NRF_EGU_EVENT_TRIGGERED1 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[1]), /**< Event number 1 generated by triggering the corresponding TRIGGER[1] task. */
NRF_EGU_EVENT_TRIGGERED2 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[2]), /**< Event number 2 generated by triggering the corresponding TRIGGER[2] task. */
NRF_EGU_EVENT_TRIGGERED3 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[3]), /**< Event number 3 generated by triggering the corresponding TRIGGER[3] task. */
NRF_EGU_EVENT_TRIGGERED4 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[4]), /**< Event number 4 generated by triggering the corresponding TRIGGER[4] task. */
NRF_EGU_EVENT_TRIGGERED5 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[5]), /**< Event number 5 generated by triggering the corresponding TRIGGER[5] task. */
NRF_EGU_EVENT_TRIGGERED6 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[6]), /**< Event number 6 generated by triggering the corresponding TRIGGER[6] task. */
NRF_EGU_EVENT_TRIGGERED7 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[7]), /**< Event number 7 generated by triggering the corresponding TRIGGER[7] task. */
NRF_EGU_EVENT_TRIGGERED8 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[8]), /**< Event number 8 generated by triggering the corresponding TRIGGER[8] task. */
NRF_EGU_EVENT_TRIGGERED9 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[9]), /**< Event number 9 generated by triggering the corresponding TRIGGER[9] task. */
NRF_EGU_EVENT_TRIGGERED10 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[10]), /**< Event number 10 generated by triggering the corresponding TRIGGER[10] task. */
NRF_EGU_EVENT_TRIGGERED11 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[11]), /**< Event number 11 generated by triggering the corresponding TRIGGER[11] task. */
NRF_EGU_EVENT_TRIGGERED12 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[12]), /**< Event number 12 generated by triggering the corresponding TRIGGER[12] task. */
NRF_EGU_EVENT_TRIGGERED13 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[13]), /**< Event number 13 generated by triggering the corresponding TRIGGER[13] task. */
NRF_EGU_EVENT_TRIGGERED14 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[14]), /**< Event number 14 generated by triggering the corresponding TRIGGER[14] task. */
NRF_EGU_EVENT_TRIGGERED15 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[15]) /**< Event number 15 generated by triggering the corresponding TRIGGER[15] task. */
/*lint -restore*/
} nrf_egu_event_t;
/**
* @enum nrf_egu_int_mask_t
* @brief EGU interrupts.
*/
typedef enum
{
NRF_EGU_INT_TRIGGERED0 = EGU_INTENSET_TRIGGERED0_Msk, /**< Interrupt on EVENTS_TRIGGERED[0] event. */
NRF_EGU_INT_TRIGGERED1 = EGU_INTENSET_TRIGGERED1_Msk, /**< Interrupt on EVENTS_TRIGGERED[1] event. */
NRF_EGU_INT_TRIGGERED2 = EGU_INTENSET_TRIGGERED2_Msk, /**< Interrupt on EVENTS_TRIGGERED[2] event. */
NRF_EGU_INT_TRIGGERED3 = EGU_INTENSET_TRIGGERED3_Msk, /**< Interrupt on EVENTS_TRIGGERED[3] event. */
NRF_EGU_INT_TRIGGERED4 = EGU_INTENSET_TRIGGERED4_Msk, /**< Interrupt on EVENTS_TRIGGERED[4] event. */
NRF_EGU_INT_TRIGGERED5 = EGU_INTENSET_TRIGGERED5_Msk, /**< Interrupt on EVENTS_TRIGGERED[5] event. */
NRF_EGU_INT_TRIGGERED6 = EGU_INTENSET_TRIGGERED6_Msk, /**< Interrupt on EVENTS_TRIGGERED[6] event. */
NRF_EGU_INT_TRIGGERED7 = EGU_INTENSET_TRIGGERED7_Msk, /**< Interrupt on EVENTS_TRIGGERED[7] event. */
NRF_EGU_INT_TRIGGERED8 = EGU_INTENSET_TRIGGERED8_Msk, /**< Interrupt on EVENTS_TRIGGERED[8] event. */
NRF_EGU_INT_TRIGGERED9 = EGU_INTENSET_TRIGGERED9_Msk, /**< Interrupt on EVENTS_TRIGGERED[9] event. */
NRF_EGU_INT_TRIGGERED10 = EGU_INTENSET_TRIGGERED10_Msk, /**< Interrupt on EVENTS_TRIGGERED[10] event. */
NRF_EGU_INT_TRIGGERED11 = EGU_INTENSET_TRIGGERED11_Msk, /**< Interrupt on EVENTS_TRIGGERED[11] event. */
NRF_EGU_INT_TRIGGERED12 = EGU_INTENSET_TRIGGERED12_Msk, /**< Interrupt on EVENTS_TRIGGERED[12] event. */
NRF_EGU_INT_TRIGGERED13 = EGU_INTENSET_TRIGGERED13_Msk, /**< Interrupt on EVENTS_TRIGGERED[13] event. */
NRF_EGU_INT_TRIGGERED14 = EGU_INTENSET_TRIGGERED14_Msk, /**< Interrupt on EVENTS_TRIGGERED[14] event. */
NRF_EGU_INT_TRIGGERED15 = EGU_INTENSET_TRIGGERED15_Msk, /**< Interrupt on EVENTS_TRIGGERED[15] event. */
NRF_EGU_INT_ALL = 0xFFFFuL
} nrf_egu_int_mask_t;
/**@brief Function for getting max channel number of given EGU.
*
* @param NRF_EGUx EGU instance.
*
* @returns number of available channels.
*/
__STATIC_INLINE uint32_t nrf_egu_channel_count(NRF_EGU_Type *NRF_EGUx)
{
if (NRF_EGUx == NRF_EGU0)
{
return EGU0_CH_NUM;
}
if (NRF_EGUx == NRF_EGU1)
{
return EGU1_CH_NUM;
}
if (NRF_EGUx == NRF_EGU2)
{
return EGU2_CH_NUM;
}
if (NRF_EGUx == NRF_EGU3)
{
return EGU3_CH_NUM;
}
if (NRF_EGUx == NRF_EGU4)
{
return EGU4_CH_NUM;
}
if (NRF_EGUx == NRF_EGU5)
{
return EGU5_CH_NUM;
}
return 0;
}
/**
* @brief Function for triggering a specific EGU task.
*
* @param NRF_EGUx EGU instance.
* @param egu_task EGU task.
*/
__STATIC_INLINE void nrf_egu_task_trigger(NRF_EGU_Type *NRF_EGUx, nrf_egu_task_t egu_task)
{
*((volatile uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_task)) = 0x1UL;
}
/**
* @brief Function for returning the address of a specific EGU task register.
*
* @param NRF_EGUx EGU instance.
* @param egu_task EGU task.
*/
__STATIC_INLINE uint32_t *nrf_egu_task_address_get(NRF_EGU_Type *NRF_EGUx,
nrf_egu_task_t egu_task)
{
return (uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_task);
}
/**
* @brief Function for returning the address of a specific EGU TRIGGER task register.
*
* @param NRF_EGUx EGU instance.
* @param channel Channel number.
*/
__STATIC_INLINE uint32_t *nrf_egu_task_trigger_addres_get(NRF_EGU_Type *NRF_EGUx,
uint8_t channel)
{
ASSERT(channel < nrf_egu_channel_count(NRF_EGUx));
return (uint32_t *)&NRF_EGUx->TASKS_TRIGGER[channel];
}
/**
* @brief Function for returning the specific EGU TRIGGER task.
*
* @param NRF_EGUx EGU instance.
* @param channel Channel number.
*/
__STATIC_INLINE nrf_egu_task_t nrf_egu_task_trigger_get(NRF_EGU_Type *NRF_EGUx, uint8_t channel)
{
ASSERT(channel < nrf_egu_channel_count(NRF_EGUx));
return (nrf_egu_task_t)((uint32_t) NRF_EGU_TASK_TRIGGER0 + (channel * sizeof(uint32_t)));
}
/**
* @brief Function for returning the state of a specific EGU event.
*
* @param NRF_EGUx EGU instance.
* @param egu_event EGU event to check.
*/
__STATIC_INLINE bool nrf_egu_event_check(NRF_EGU_Type *NRF_EGUx,
nrf_egu_event_t egu_event)
{
return (bool) * (volatile uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_event);
}
/**
* @brief Function for clearing a specific EGU event.
*
* @param NRF_EGUx EGU instance.
* @param egu_event EGU event to clear.
*/
__STATIC_INLINE void nrf_egu_event_clear(NRF_EGU_Type *NRF_EGUx,
nrf_egu_event_t egu_event)
{
*((volatile uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_event)) = 0x0UL;
#if __CORTEX_M == 0x04
volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_event));
(void)dummy;
#endif
}
/**
* @brief Function for returning the address of a specific EGU event register.
*
* @param NRF_EGUx EGU instance.
* @param egu_event EGU event.
*/
__STATIC_INLINE uint32_t *nrf_egu_event_address_get(NRF_EGU_Type *NRF_EGUx,
nrf_egu_event_t egu_event)
{
return (uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_event);
}
/**
* @brief Function for returning the address of a specific EGU TRIGGERED event register.
*
* @param NRF_EGUx EGU instance.
* @param channel Channel number.
*/
__STATIC_INLINE uint32_t *nrf_egu_event_triggered_addres_get(NRF_EGU_Type *NRF_EGUx,
uint8_t channel)
{
ASSERT(channel < nrf_egu_channel_count(NRF_EGUx));
return (uint32_t *)&NRF_EGUx->EVENTS_TRIGGERED[channel];
}
/**
* @brief Function for returning the specific EGU TRIGGERED event.
*
* @param NRF_EGUx EGU instance.
* @param channel Channel number.
*/
__STATIC_INLINE nrf_egu_event_t nrf_egu_event_triggered_get(NRF_EGU_Type *NRF_EGUx,
uint8_t channel)
{
ASSERT(channel < nrf_egu_channel_count(NRF_EGUx));
return (nrf_egu_event_t)((uint32_t) NRF_EGU_EVENT_TRIGGERED0 + (channel * sizeof(uint32_t)));
}
/**
* @brief Function for enabling one or more specific EGU interrupts.
*
* @param NRF_EGUx EGU instance.
* @param egu_int_mask Interrupts to enable.
*/
__STATIC_INLINE void nrf_egu_int_enable(NRF_EGU_Type *NRF_EGUx, uint32_t egu_int_mask)
{
NRF_EGUx->INTENSET = egu_int_mask;
}
/**
* @brief Function for retrieving the state of one or more EGU interrupts.
*
* @param NRF_EGUx EGU instance.
* @param egu_int_mask Interrupts to check.
*
* @retval true If all of the specified interrupts are enabled.
* @retval false If at least one of the specified interrupts is disabled.
*/
__STATIC_INLINE bool nrf_egu_int_enable_check(NRF_EGU_Type *NRF_EGUx, uint32_t egu_int_mask)
{
return (bool)(NRF_EGUx->INTENSET & egu_int_mask);
}
/**
* @brief Function for disabling one or more specific EGU interrupts.
*
* @param NRF_EGUx EGU instance.
* @param egu_int_mask Interrupts to disable.
*/
__STATIC_INLINE void nrf_egu_int_disable(NRF_EGU_Type *NRF_EGUx, uint32_t egu_int_mask)
{
NRF_EGUx->INTENCLR = egu_int_mask;
}
/**
* @brief Function for retrieving one or more specific EGU interrupts.
*
* @param NRF_EGUx EGU instance.
* @param channel Channel number.
*
* @returns EGU interrupt mask.
*/
__STATIC_INLINE nrf_egu_int_mask_t nrf_egu_int_get(NRF_EGU_Type *NRF_EGUx, uint8_t channel)
{
ASSERT(channel < nrf_egu_channel_count(NRF_EGUx));
return (nrf_egu_int_mask_t)((uint32_t)(EGU_INTENSET_TRIGGERED0_Msk << channel));
}
/** @} */
#ifdef __cplusplus
}
#endif
#endif
/* Copyright (c) 2015-2017, 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 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_EGU_H__
#define NRF_EGU_H__
/**
* @defgroup nrf_egu EGU (Event Generator Unit) abstraction
* @{
* @ingroup nrf_drivers
* @brief @tagAPI52 EGU (Event Generator Unit) module functions.
*
*/
#include <assert.h>
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include "nrf.h"
#include "nrf_peripherals.h"
#define ASSERT assert
#ifdef __cplusplus
extern "C" {
#endif
/**
* @enum nrf_egu_task_t
* @brief EGU tasks.
*/
typedef enum
{
/*lint -save -e30 -esym(628,__INTADDR__)*/
NRF_EGU_TASK_TRIGGER0 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[0]), /**< Trigger 0 for triggering the corresponding TRIGGERED[0] event. */
NRF_EGU_TASK_TRIGGER1 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[1]), /**< Trigger 1 for triggering the corresponding TRIGGERED[1] event. */
NRF_EGU_TASK_TRIGGER2 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[2]), /**< Trigger 2 for triggering the corresponding TRIGGERED[2] event. */
NRF_EGU_TASK_TRIGGER3 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[3]), /**< Trigger 3 for triggering the corresponding TRIGGERED[3] event. */
NRF_EGU_TASK_TRIGGER4 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[4]), /**< Trigger 4 for triggering the corresponding TRIGGERED[4] event. */
NRF_EGU_TASK_TRIGGER5 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[5]), /**< Trigger 5 for triggering the corresponding TRIGGERED[5] event. */
NRF_EGU_TASK_TRIGGER6 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[6]), /**< Trigger 6 for triggering the corresponding TRIGGERED[6] event. */
NRF_EGU_TASK_TRIGGER7 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[7]), /**< Trigger 7 for triggering the corresponding TRIGGERED[7] event. */
NRF_EGU_TASK_TRIGGER8 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[8]), /**< Trigger 8 for triggering the corresponding TRIGGERED[8] event. */
NRF_EGU_TASK_TRIGGER9 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[9]), /**< Trigger 9 for triggering the corresponding TRIGGERED[9] event. */
NRF_EGU_TASK_TRIGGER10 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[10]), /**< Trigger 10 for triggering the corresponding TRIGGERED[10] event. */
NRF_EGU_TASK_TRIGGER11 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[11]), /**< Trigger 11 for triggering the corresponding TRIGGERED[11] event. */
NRF_EGU_TASK_TRIGGER12 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[12]), /**< Trigger 12 for triggering the corresponding TRIGGERED[12] event. */
NRF_EGU_TASK_TRIGGER13 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[13]), /**< Trigger 13 for triggering the corresponding TRIGGERED[13] event. */
NRF_EGU_TASK_TRIGGER14 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[14]), /**< Trigger 14 for triggering the corresponding TRIGGERED[14] event. */
NRF_EGU_TASK_TRIGGER15 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[15]) /**< Trigger 15 for triggering the corresponding TRIGGERED[15] event. */
/*lint -restore*/
} nrf_egu_task_t;
/**
* @enum nrf_egu_event_t
* @brief EGU events.
*/
typedef enum
{
/*lint -save -e30 -esym(628,__INTADDR__)*/
NRF_EGU_EVENT_TRIGGERED0 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[0]), /**< Event number 0 generated by triggering the corresponding TRIGGER[0] task. */
NRF_EGU_EVENT_TRIGGERED1 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[1]), /**< Event number 1 generated by triggering the corresponding TRIGGER[1] task. */
NRF_EGU_EVENT_TRIGGERED2 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[2]), /**< Event number 2 generated by triggering the corresponding TRIGGER[2] task. */
NRF_EGU_EVENT_TRIGGERED3 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[3]), /**< Event number 3 generated by triggering the corresponding TRIGGER[3] task. */
NRF_EGU_EVENT_TRIGGERED4 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[4]), /**< Event number 4 generated by triggering the corresponding TRIGGER[4] task. */
NRF_EGU_EVENT_TRIGGERED5 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[5]), /**< Event number 5 generated by triggering the corresponding TRIGGER[5] task. */
NRF_EGU_EVENT_TRIGGERED6 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[6]), /**< Event number 6 generated by triggering the corresponding TRIGGER[6] task. */
NRF_EGU_EVENT_TRIGGERED7 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[7]), /**< Event number 7 generated by triggering the corresponding TRIGGER[7] task. */
NRF_EGU_EVENT_TRIGGERED8 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[8]), /**< Event number 8 generated by triggering the corresponding TRIGGER[8] task. */
NRF_EGU_EVENT_TRIGGERED9 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[9]), /**< Event number 9 generated by triggering the corresponding TRIGGER[9] task. */
NRF_EGU_EVENT_TRIGGERED10 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[10]), /**< Event number 10 generated by triggering the corresponding TRIGGER[10] task. */
NRF_EGU_EVENT_TRIGGERED11 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[11]), /**< Event number 11 generated by triggering the corresponding TRIGGER[11] task. */
NRF_EGU_EVENT_TRIGGERED12 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[12]), /**< Event number 12 generated by triggering the corresponding TRIGGER[12] task. */
NRF_EGU_EVENT_TRIGGERED13 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[13]), /**< Event number 13 generated by triggering the corresponding TRIGGER[13] task. */
NRF_EGU_EVENT_TRIGGERED14 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[14]), /**< Event number 14 generated by triggering the corresponding TRIGGER[14] task. */
NRF_EGU_EVENT_TRIGGERED15 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[15]) /**< Event number 15 generated by triggering the corresponding TRIGGER[15] task. */
/*lint -restore*/
} nrf_egu_event_t;
/**
* @enum nrf_egu_int_mask_t
* @brief EGU interrupts.
*/
typedef enum
{
NRF_EGU_INT_TRIGGERED0 = EGU_INTENSET_TRIGGERED0_Msk, /**< Interrupt on EVENTS_TRIGGERED[0] event. */
NRF_EGU_INT_TRIGGERED1 = EGU_INTENSET_TRIGGERED1_Msk, /**< Interrupt on EVENTS_TRIGGERED[1] event. */
NRF_EGU_INT_TRIGGERED2 = EGU_INTENSET_TRIGGERED2_Msk, /**< Interrupt on EVENTS_TRIGGERED[2] event. */
NRF_EGU_INT_TRIGGERED3 = EGU_INTENSET_TRIGGERED3_Msk, /**< Interrupt on EVENTS_TRIGGERED[3] event. */
NRF_EGU_INT_TRIGGERED4 = EGU_INTENSET_TRIGGERED4_Msk, /**< Interrupt on EVENTS_TRIGGERED[4] event. */
NRF_EGU_INT_TRIGGERED5 = EGU_INTENSET_TRIGGERED5_Msk, /**< Interrupt on EVENTS_TRIGGERED[5] event. */
NRF_EGU_INT_TRIGGERED6 = EGU_INTENSET_TRIGGERED6_Msk, /**< Interrupt on EVENTS_TRIGGERED[6] event. */
NRF_EGU_INT_TRIGGERED7 = EGU_INTENSET_TRIGGERED7_Msk, /**< Interrupt on EVENTS_TRIGGERED[7] event. */
NRF_EGU_INT_TRIGGERED8 = EGU_INTENSET_TRIGGERED8_Msk, /**< Interrupt on EVENTS_TRIGGERED[8] event. */
NRF_EGU_INT_TRIGGERED9 = EGU_INTENSET_TRIGGERED9_Msk, /**< Interrupt on EVENTS_TRIGGERED[9] event. */
NRF_EGU_INT_TRIGGERED10 = EGU_INTENSET_TRIGGERED10_Msk, /**< Interrupt on EVENTS_TRIGGERED[10] event. */
NRF_EGU_INT_TRIGGERED11 = EGU_INTENSET_TRIGGERED11_Msk, /**< Interrupt on EVENTS_TRIGGERED[11] event. */
NRF_EGU_INT_TRIGGERED12 = EGU_INTENSET_TRIGGERED12_Msk, /**< Interrupt on EVENTS_TRIGGERED[12] event. */
NRF_EGU_INT_TRIGGERED13 = EGU_INTENSET_TRIGGERED13_Msk, /**< Interrupt on EVENTS_TRIGGERED[13] event. */
NRF_EGU_INT_TRIGGERED14 = EGU_INTENSET_TRIGGERED14_Msk, /**< Interrupt on EVENTS_TRIGGERED[14] event. */
NRF_EGU_INT_TRIGGERED15 = EGU_INTENSET_TRIGGERED15_Msk, /**< Interrupt on EVENTS_TRIGGERED[15] event. */
NRF_EGU_INT_ALL = 0xFFFFuL
} nrf_egu_int_mask_t;
/**@brief Function for getting max channel number of given EGU.
*
* @param NRF_EGUx EGU instance.
*
* @returns number of available channels.
*/
__STATIC_INLINE uint32_t nrf_egu_channel_count(NRF_EGU_Type * NRF_EGUx)
{
if (NRF_EGUx == NRF_EGU0){
return EGU0_CH_NUM;
}
if (NRF_EGUx == NRF_EGU1){
return EGU1_CH_NUM;
}
if (NRF_EGUx == NRF_EGU2){
return EGU2_CH_NUM;
}
if (NRF_EGUx == NRF_EGU3){
return EGU3_CH_NUM;
}
if (NRF_EGUx == NRF_EGU4){
return EGU4_CH_NUM;
}
if (NRF_EGUx == NRF_EGU5){
return EGU5_CH_NUM;
}
return 0;
}
/**
* @brief Function for triggering a specific EGU task.
*
* @param NRF_EGUx EGU instance.
* @param egu_task EGU task.
*/
__STATIC_INLINE void nrf_egu_task_trigger(NRF_EGU_Type * NRF_EGUx, nrf_egu_task_t egu_task)
{
*((volatile uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_task)) = 0x1UL;
}
/**
* @brief Function for returning the address of a specific EGU task register.
*
* @param NRF_EGUx EGU instance.
* @param egu_task EGU task.
*/
__STATIC_INLINE uint32_t * nrf_egu_task_address_get(NRF_EGU_Type * NRF_EGUx,
nrf_egu_task_t egu_task)
{
return (uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_task);
}
/**
* @brief Function for returning the address of a specific EGU TRIGGER task register.
*
* @param NRF_EGUx EGU instance.
* @param channel Channel number.
*/
__STATIC_INLINE uint32_t * nrf_egu_task_trigger_address_get(NRF_EGU_Type * NRF_EGUx,
uint8_t channel)
{
ASSERT(channel < nrf_egu_channel_count(NRF_EGUx));
return (uint32_t*)&NRF_EGUx->TASKS_TRIGGER[channel];
}
/**
* @brief Function for returning the specific EGU TRIGGER task.
*
* @param NRF_EGUx EGU instance.
* @param channel Channel number.
*/
__STATIC_INLINE nrf_egu_task_t nrf_egu_task_trigger_get(NRF_EGU_Type * NRF_EGUx, uint8_t channel)
{
ASSERT(channel < nrf_egu_channel_count(NRF_EGUx));
return (nrf_egu_task_t)((uint32_t) NRF_EGU_TASK_TRIGGER0 + (channel * sizeof(uint32_t)));
}
/**
* @brief Function for returning the state of a specific EGU event.
*
* @param NRF_EGUx EGU instance.
* @param egu_event EGU event to check.
*/
__STATIC_INLINE bool nrf_egu_event_check(NRF_EGU_Type * NRF_EGUx,
nrf_egu_event_t egu_event)
{
return (bool)*(volatile uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_event);
}
/**
* @brief Function for clearing a specific EGU event.
*
* @param NRF_EGUx EGU instance.
* @param egu_event EGU event to clear.
*/
__STATIC_INLINE void nrf_egu_event_clear(NRF_EGU_Type * NRF_EGUx,
nrf_egu_event_t egu_event)
{
*((volatile uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_event)) = 0x0UL;
#if __CORTEX_M == 0x04
volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_event));
(void)dummy;
#endif
}
/**
* @brief Function for returning the address of a specific EGU event register.
*
* @param NRF_EGUx EGU instance.
* @param egu_event EGU event.
*/
__STATIC_INLINE uint32_t * nrf_egu_event_address_get(NRF_EGU_Type * NRF_EGUx,
nrf_egu_event_t egu_event)
{
return (uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_event);
}
/**
* @brief Function for returning the address of a specific EGU TRIGGERED event register.
*
* @param NRF_EGUx EGU instance.
* @param channel Channel number.
*/
__STATIC_INLINE uint32_t * nrf_egu_event_triggered_address_get(NRF_EGU_Type * NRF_EGUx,
uint8_t channel)
{
ASSERT(channel < nrf_egu_channel_count(NRF_EGUx));
return (uint32_t*)&NRF_EGUx->EVENTS_TRIGGERED[channel];
}
/**
* @brief Function for returning the specific EGU TRIGGERED event.
*
* @param NRF_EGUx EGU instance.
* @param channel Channel number.
*/
__STATIC_INLINE nrf_egu_event_t nrf_egu_event_triggered_get(NRF_EGU_Type * NRF_EGUx,
uint8_t channel)
{
ASSERT(channel < nrf_egu_channel_count(NRF_EGUx));
return (nrf_egu_event_t)((uint32_t) NRF_EGU_EVENT_TRIGGERED0 + (channel * sizeof(uint32_t)));
}
/**
* @brief Function for enabling one or more specific EGU interrupts.
*
* @param NRF_EGUx EGU instance.
* @param egu_int_mask Interrupts to enable.
*/
__STATIC_INLINE void nrf_egu_int_enable(NRF_EGU_Type * NRF_EGUx, uint32_t egu_int_mask)
{
NRF_EGUx->INTENSET = egu_int_mask;
}
/**
* @brief Function for retrieving the state of one or more EGU interrupts.
*
* @param NRF_EGUx EGU instance.
* @param egu_int_mask Interrupts to check.
*
* @retval true If all of the specified interrupts are enabled.
* @retval false If at least one of the specified interrupts is disabled.
*/
__STATIC_INLINE bool nrf_egu_int_enable_check(NRF_EGU_Type * NRF_EGUx, uint32_t egu_int_mask)
{
return (bool)(NRF_EGUx->INTENSET & egu_int_mask);
}
/**
* @brief Function for disabling one or more specific EGU interrupts.
*
* @param NRF_EGUx EGU instance.
* @param egu_int_mask Interrupts to disable.
*/
__STATIC_INLINE void nrf_egu_int_disable(NRF_EGU_Type * NRF_EGUx, uint32_t egu_int_mask)
{
NRF_EGUx->INTENCLR = egu_int_mask;
}
/**
* @brief Function for retrieving one or more specific EGU interrupts.
*
* @param NRF_EGUx EGU instance.
* @param channel Channel number.
*
* @returns EGU interrupt mask.
*/
__STATIC_INLINE nrf_egu_int_mask_t nrf_egu_int_get(NRF_EGU_Type * NRF_EGUx, uint8_t channel)
{
ASSERT(channel < nrf_egu_channel_count(NRF_EGUx));
return (nrf_egu_int_mask_t)((uint32_t) (EGU_INTENSET_TRIGGERED0_Msk << channel));
}
/** @} */
#ifdef __cplusplus
}
#endif
#endif
+421
View File
@@ -0,0 +1,421 @@
/* Copyright (c) 2016, 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 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_GPIOTE_H__
#define NRF_GPIOTE_H__
#include "nrf_peripherals.h"
#include "nrf.h"
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef GPIOTE_CONFIG_PORT_Msk
#define GPIOTE_CONFIG_PORT_PIN_Msk (GPIOTE_CONFIG_PORT_Msk | GPIOTE_CONFIG_PSEL_Msk)
#else
#define GPIOTE_CONFIG_PORT_PIN_Msk GPIOTE_CONFIG_PSEL_Msk
#endif
/**
* @defgroup nrf_gpiote_abs GPIOTE abstraction
* @{
* @ingroup nrf_gpiote
* @brief GPIOTE abstraction for configuration of channels.
*/
/**
* @enum nrf_gpiote_polarity_t
* @brief Polarity for the GPIOTE channel.
*/
typedef enum
{
NRF_GPIOTE_POLARITY_LOTOHI = GPIOTE_CONFIG_POLARITY_LoToHi, ///< Low to high.
NRF_GPIOTE_POLARITY_HITOLO = GPIOTE_CONFIG_POLARITY_HiToLo, ///< High to low.
NRF_GPIOTE_POLARITY_TOGGLE = GPIOTE_CONFIG_POLARITY_Toggle ///< Toggle.
} nrf_gpiote_polarity_t;
/**
* @enum nrf_gpiote_outinit_t
* @brief Initial output value for the GPIOTE channel.
*/
typedef enum
{
NRF_GPIOTE_INITIAL_VALUE_LOW = GPIOTE_CONFIG_OUTINIT_Low, ///< Low to high.
NRF_GPIOTE_INITIAL_VALUE_HIGH = GPIOTE_CONFIG_OUTINIT_High ///< High to low.
} nrf_gpiote_outinit_t;
/**
* @brief Tasks.
*/
typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
{
NRF_GPIOTE_TASKS_OUT_0 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[0]), /**< Out task 0.*/
NRF_GPIOTE_TASKS_OUT_1 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[1]), /**< Out task 1.*/
NRF_GPIOTE_TASKS_OUT_2 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[2]), /**< Out task 2.*/
NRF_GPIOTE_TASKS_OUT_3 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[3]), /**< Out task 3.*/
#if (GPIOTE_CH_NUM > 4) || defined(__SDK_DOXYGEN__)
NRF_GPIOTE_TASKS_OUT_4 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[4]), /**< Out task 4.*/
NRF_GPIOTE_TASKS_OUT_5 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[5]), /**< Out task 5.*/
NRF_GPIOTE_TASKS_OUT_6 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[6]), /**< Out task 6.*/
NRF_GPIOTE_TASKS_OUT_7 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[7]), /**< Out task 7.*/
#endif
#if defined(GPIOTE_FEATURE_SET_PRESENT) || defined(__SDK_DOXYGEN__)
NRF_GPIOTE_TASKS_SET_0 = offsetof(NRF_GPIOTE_Type, TASKS_SET[0]), /**< Set task 0.*/
NRF_GPIOTE_TASKS_SET_1 = offsetof(NRF_GPIOTE_Type, TASKS_SET[1]), /**< Set task 1.*/
NRF_GPIOTE_TASKS_SET_2 = offsetof(NRF_GPIOTE_Type, TASKS_SET[2]), /**< Set task 2.*/
NRF_GPIOTE_TASKS_SET_3 = offsetof(NRF_GPIOTE_Type, TASKS_SET[3]), /**< Set task 3.*/
NRF_GPIOTE_TASKS_SET_4 = offsetof(NRF_GPIOTE_Type, TASKS_SET[4]), /**< Set task 4.*/
NRF_GPIOTE_TASKS_SET_5 = offsetof(NRF_GPIOTE_Type, TASKS_SET[5]), /**< Set task 5.*/
NRF_GPIOTE_TASKS_SET_6 = offsetof(NRF_GPIOTE_Type, TASKS_SET[6]), /**< Set task 6.*/
NRF_GPIOTE_TASKS_SET_7 = offsetof(NRF_GPIOTE_Type, TASKS_SET[7]), /**< Set task 7.*/
#endif
#if defined(GPIOTE_FEATURE_CLR_PRESENT) || defined(__SDK_DOXYGEN__)
NRF_GPIOTE_TASKS_CLR_0 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[0]), /**< Clear task 0.*/
NRF_GPIOTE_TASKS_CLR_1 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[1]), /**< Clear task 1.*/
NRF_GPIOTE_TASKS_CLR_2 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[2]), /**< Clear task 2.*/
NRF_GPIOTE_TASKS_CLR_3 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[3]), /**< Clear task 3.*/
NRF_GPIOTE_TASKS_CLR_4 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[4]), /**< Clear task 4.*/
NRF_GPIOTE_TASKS_CLR_5 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[5]), /**< Clear task 5.*/
NRF_GPIOTE_TASKS_CLR_6 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[6]), /**< Clear task 6.*/
NRF_GPIOTE_TASKS_CLR_7 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[7]), /**< Clear task 7.*/
#endif
/*lint -restore*/
} nrf_gpiote_tasks_t;
/**
* @brief Events.
*/
typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
{
NRF_GPIOTE_EVENTS_IN_0 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[0]), /**< In event 0.*/
NRF_GPIOTE_EVENTS_IN_1 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[1]), /**< In event 1.*/
NRF_GPIOTE_EVENTS_IN_2 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[2]), /**< In event 2.*/
NRF_GPIOTE_EVENTS_IN_3 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[3]), /**< In event 3.*/
#if (GPIOTE_CH_NUM > 4) || defined(__SDK_DOXYGEN__)
NRF_GPIOTE_EVENTS_IN_4 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[4]), /**< In event 4.*/
NRF_GPIOTE_EVENTS_IN_5 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[5]), /**< In event 5.*/
NRF_GPIOTE_EVENTS_IN_6 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[6]), /**< In event 6.*/
NRF_GPIOTE_EVENTS_IN_7 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[7]), /**< In event 7.*/
#endif
NRF_GPIOTE_EVENTS_PORT = offsetof(NRF_GPIOTE_Type, EVENTS_PORT), /**< Port event.*/
/*lint -restore*/
} nrf_gpiote_events_t;
/**
* @enum nrf_gpiote_int_t
* @brief GPIOTE interrupts.
*/
typedef enum
{
NRF_GPIOTE_INT_IN0_MASK = GPIOTE_INTENSET_IN0_Msk, /**< GPIOTE interrupt from IN0. */
NRF_GPIOTE_INT_IN1_MASK = GPIOTE_INTENSET_IN1_Msk, /**< GPIOTE interrupt from IN1. */
NRF_GPIOTE_INT_IN2_MASK = GPIOTE_INTENSET_IN2_Msk, /**< GPIOTE interrupt from IN2. */
NRF_GPIOTE_INT_IN3_MASK = GPIOTE_INTENSET_IN3_Msk, /**< GPIOTE interrupt from IN3. */
#if (GPIOTE_CH_NUM > 4) || defined(__SDK_DOXYGEN__)
NRF_GPIOTE_INT_IN4_MASK = GPIOTE_INTENSET_IN4_Msk, /**< GPIOTE interrupt from IN4. */
NRF_GPIOTE_INT_IN5_MASK = GPIOTE_INTENSET_IN5_Msk, /**< GPIOTE interrupt from IN5. */
NRF_GPIOTE_INT_IN6_MASK = GPIOTE_INTENSET_IN6_Msk, /**< GPIOTE interrupt from IN6. */
NRF_GPIOTE_INT_IN7_MASK = GPIOTE_INTENSET_IN7_Msk, /**< GPIOTE interrupt from IN7. */
#endif
NRF_GPIOTE_INT_PORT_MASK = (int)GPIOTE_INTENSET_PORT_Msk, /**< GPIOTE interrupt from PORT event. */
} nrf_gpiote_int_t;
#define NRF_GPIOTE_INT_IN_MASK (NRF_GPIOTE_INT_IN0_MASK | NRF_GPIOTE_INT_IN1_MASK |\
NRF_GPIOTE_INT_IN2_MASK | NRF_GPIOTE_INT_IN3_MASK)
#if (GPIOTE_CH_NUM > 4)
#undef NRF_GPIOTE_INT_IN_MASK
#define NRF_GPIOTE_INT_IN_MASK (NRF_GPIOTE_INT_IN0_MASK | NRF_GPIOTE_INT_IN1_MASK |\
NRF_GPIOTE_INT_IN2_MASK | NRF_GPIOTE_INT_IN3_MASK |\
NRF_GPIOTE_INT_IN4_MASK | NRF_GPIOTE_INT_IN5_MASK |\
NRF_GPIOTE_INT_IN6_MASK | NRF_GPIOTE_INT_IN7_MASK)
#endif
/**
* @brief Function for activating a specific GPIOTE task.
*
* @param[in] task Task.
*/
__STATIC_INLINE void nrf_gpiote_task_set(nrf_gpiote_tasks_t task);
/**
* @brief Function for getting the address of a specific GPIOTE task.
*
* @param[in] task Task.
*
* @returns Address.
*/
__STATIC_INLINE uint32_t nrf_gpiote_task_addr_get(nrf_gpiote_tasks_t task);
/**
* @brief Function for getting the state of a specific GPIOTE event.
*
* @param[in] event Event.
*/
__STATIC_INLINE bool nrf_gpiote_event_is_set(nrf_gpiote_events_t event);
/**
* @brief Function for clearing a specific GPIOTE event.
*
* @param[in] event Event.
*/
__STATIC_INLINE void nrf_gpiote_event_clear(nrf_gpiote_events_t event);
/**
* @brief Function for getting the address of a specific GPIOTE event.
*
* @param[in] event Event.
*
* @return Address
*/
__STATIC_INLINE uint32_t nrf_gpiote_event_addr_get(nrf_gpiote_events_t event);
/**@brief Function for enabling interrupts.
*
* @param[in] mask Interrupt mask to be enabled.
*/
__STATIC_INLINE void nrf_gpiote_int_enable(uint32_t mask);
/**@brief Function for disabling interrupts.
*
* @param[in] mask Interrupt mask to be disabled.
*/
__STATIC_INLINE void nrf_gpiote_int_disable(uint32_t mask);
/**@brief Function for checking if interrupts are enabled.
*
* @param[in] mask Mask of interrupt flags to check.
*
* @return Mask with enabled interrupts.
*/
__STATIC_INLINE uint32_t nrf_gpiote_int_is_enabled(uint32_t mask);
/**@brief Function for enabling a GPIOTE event.
*
* @param[in] idx Task-Event index.
*/
__STATIC_INLINE void nrf_gpiote_event_enable(uint32_t idx);
/**@brief Function for disabling a GPIOTE event.
*
* @param[in] idx Task-Event index.
*/
__STATIC_INLINE void nrf_gpiote_event_disable(uint32_t idx);
/**@brief Function for configuring a GPIOTE event.
*
* @param[in] idx Task-Event index.
* @param[in] pin Pin associated with event.
* @param[in] polarity Transition that should generate an event.
*/
__STATIC_INLINE void nrf_gpiote_event_configure(uint32_t idx, uint32_t pin,
nrf_gpiote_polarity_t polarity);
/**@brief Function for getting the pin associated with a GPIOTE event.
*
* @param[in] idx Task-Event index.
*
* @return Pin number.
*/
__STATIC_INLINE uint32_t nrf_gpiote_event_pin_get(uint32_t idx);
/**@brief Function for getting the polarity associated with a GPIOTE event.
*
* @param[in] idx Task-Event index.
*
* @return Polarity.
*/
__STATIC_INLINE nrf_gpiote_polarity_t nrf_gpiote_event_polarity_get(uint32_t idx);
/**@brief Function for enabling a GPIOTE task.
*
* @param[in] idx Task-Event index.
*/
__STATIC_INLINE void nrf_gpiote_task_enable(uint32_t idx);
/**@brief Function for disabling a GPIOTE task.
*
* @param[in] idx Task-Event index.
*/
__STATIC_INLINE void nrf_gpiote_task_disable(uint32_t idx);
/**@brief Function for configuring a GPIOTE task.
* @note Function is not configuring mode field so task is disabled after this function is called.
*
* @param[in] idx Task-Event index.
* @param[in] pin Pin associated with event.
* @param[in] polarity Transition that should generate an event.
* @param[in] init_val Initial value of the pin.
*/
__STATIC_INLINE void nrf_gpiote_task_configure(uint32_t idx, uint32_t pin,
nrf_gpiote_polarity_t polarity,
nrf_gpiote_outinit_t init_val);
/**@brief Function for forcing a specific state on the pin connected to GPIOTE.
*
* @param[in] idx Task-Event index.
* @param[in] init_val Pin state.
*/
__STATIC_INLINE void nrf_gpiote_task_force(uint32_t idx, nrf_gpiote_outinit_t init_val);
/**@brief Function for resetting a GPIOTE task event configuration to the default state.
*
* @param[in] idx Task-Event index.
*/
__STATIC_INLINE void nrf_gpiote_te_default(uint32_t idx);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_gpiote_task_set(nrf_gpiote_tasks_t task)
{
*(__IO uint32_t *)((uint32_t)NRF_GPIOTE + task) = 0x1UL;
}
__STATIC_INLINE uint32_t nrf_gpiote_task_addr_get(nrf_gpiote_tasks_t task)
{
return ((uint32_t)NRF_GPIOTE + task);
}
__STATIC_INLINE bool nrf_gpiote_event_is_set(nrf_gpiote_events_t event)
{
return (*(uint32_t *)nrf_gpiote_event_addr_get(event) == 0x1UL) ? true : false;
}
__STATIC_INLINE void nrf_gpiote_event_clear(nrf_gpiote_events_t event)
{
*(uint32_t *)nrf_gpiote_event_addr_get(event) = 0;
#if __CORTEX_M == 0x04
volatile uint32_t dummy = *((volatile uint32_t *)nrf_gpiote_event_addr_get(event));
(void)dummy;
#endif
}
__STATIC_INLINE uint32_t nrf_gpiote_event_addr_get(nrf_gpiote_events_t event)
{
return ((uint32_t)NRF_GPIOTE + event);
}
__STATIC_INLINE void nrf_gpiote_int_enable(uint32_t mask)
{
NRF_GPIOTE->INTENSET = mask;
}
__STATIC_INLINE void nrf_gpiote_int_disable(uint32_t mask)
{
NRF_GPIOTE->INTENCLR = mask;
}
__STATIC_INLINE uint32_t nrf_gpiote_int_is_enabled(uint32_t mask)
{
return (NRF_GPIOTE->INTENSET & mask);
}
__STATIC_INLINE void nrf_gpiote_event_enable(uint32_t idx)
{
NRF_GPIOTE->CONFIG[idx] |= GPIOTE_CONFIG_MODE_Event;
}
__STATIC_INLINE void nrf_gpiote_event_disable(uint32_t idx)
{
NRF_GPIOTE->CONFIG[idx] &= ~GPIOTE_CONFIG_MODE_Event;
}
__STATIC_INLINE void nrf_gpiote_event_configure(uint32_t idx, uint32_t pin, nrf_gpiote_polarity_t polarity)
{
NRF_GPIOTE->CONFIG[idx] &= ~(GPIOTE_CONFIG_PORT_PIN_Msk | GPIOTE_CONFIG_POLARITY_Msk);
NRF_GPIOTE->CONFIG[idx] |= ((pin << GPIOTE_CONFIG_PSEL_Pos) & GPIOTE_CONFIG_PORT_PIN_Msk) |
((polarity << GPIOTE_CONFIG_POLARITY_Pos) & GPIOTE_CONFIG_POLARITY_Msk);
}
__STATIC_INLINE uint32_t nrf_gpiote_event_pin_get(uint32_t idx)
{
return ((NRF_GPIOTE->CONFIG[idx] & GPIOTE_CONFIG_PORT_PIN_Msk) >> GPIOTE_CONFIG_PSEL_Pos);
}
__STATIC_INLINE nrf_gpiote_polarity_t nrf_gpiote_event_polarity_get(uint32_t idx)
{
return (nrf_gpiote_polarity_t)((NRF_GPIOTE->CONFIG[idx] & GPIOTE_CONFIG_POLARITY_Msk) >> GPIOTE_CONFIG_POLARITY_Pos);
}
__STATIC_INLINE void nrf_gpiote_task_enable(uint32_t idx)
{
uint32_t final_config = NRF_GPIOTE->CONFIG[idx] | GPIOTE_CONFIG_MODE_Task;
#ifdef NRF51
/* Workaround for the OUTINIT PAN. When nrf_gpiote_task_config() is called a glitch happens
on the GPIO if the GPIO in question is already assigned to GPIOTE and the pin is in the
correct state in GPIOTE but not in the OUT register. */
/* Configure channel to not existing, not connected to the pin, and configure as a tasks that will set it to proper level */
NRF_GPIOTE->CONFIG[idx] = final_config | (((31) << GPIOTE_CONFIG_PSEL_Pos) & GPIOTE_CONFIG_PORT_PIN_Msk);
__NOP();
__NOP();
__NOP();
#endif
NRF_GPIOTE->CONFIG[idx] = final_config;
}
__STATIC_INLINE void nrf_gpiote_task_disable(uint32_t idx)
{
NRF_GPIOTE->CONFIG[idx] &= ~GPIOTE_CONFIG_MODE_Task;
}
__STATIC_INLINE void nrf_gpiote_task_configure(uint32_t idx, uint32_t pin,
nrf_gpiote_polarity_t polarity,
nrf_gpiote_outinit_t init_val)
{
NRF_GPIOTE->CONFIG[idx] &= ~(GPIOTE_CONFIG_PORT_PIN_Msk |
GPIOTE_CONFIG_POLARITY_Msk |
GPIOTE_CONFIG_OUTINIT_Msk);
NRF_GPIOTE->CONFIG[idx] |= ((pin << GPIOTE_CONFIG_PSEL_Pos) & GPIOTE_CONFIG_PORT_PIN_Msk) |
((polarity << GPIOTE_CONFIG_POLARITY_Pos) & GPIOTE_CONFIG_POLARITY_Msk) |
((init_val << GPIOTE_CONFIG_OUTINIT_Pos) & GPIOTE_CONFIG_OUTINIT_Msk);
}
__STATIC_INLINE void nrf_gpiote_task_force(uint32_t idx, nrf_gpiote_outinit_t init_val)
{
NRF_GPIOTE->CONFIG[idx] = (NRF_GPIOTE->CONFIG[idx] & ~GPIOTE_CONFIG_OUTINIT_Msk)
| ((init_val << GPIOTE_CONFIG_OUTINIT_Pos) & GPIOTE_CONFIG_OUTINIT_Msk);
}
__STATIC_INLINE void nrf_gpiote_te_default(uint32_t idx)
{
NRF_GPIOTE->CONFIG[idx] = 0;
}
#endif //SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
#ifdef __cplusplus
}
#endif
#endif
+10 -9
View File
@@ -4,16 +4,16 @@
* 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 its
* contributors 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
@@ -45,7 +45,7 @@
#include "nrf51822_peripherals.h"
#endif
#ifdef NRF52832
#ifdef NRF52832_XXAA
#include "nrf52832_peripherals.h"
#endif
@@ -57,3 +57,4 @@
/*lint --flb "Leave library region" */
#endif /* NRF_PERIPHERALS_H */
+430
View File
@@ -0,0 +1,430 @@
/* Copyright (c) 2016, 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 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_PPI_H__
#define NRF_PPI_H__
#include <stddef.h>
#include "nrf.h"
#include "nrf_peripherals.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_ppi_hal PPI HAL
* @{
* @ingroup nrf_ppi
* @brief Hardware access layer for setting up Programmable Peripheral Interconnect (PPI) channels.
*/
#define NRF_PPI_TASK_SET (1UL)
/**
* @enum nrf_ppi_channel_t
* @brief PPI channels.
*/
typedef enum
{
NRF_PPI_CHANNEL0 = PPI_CHEN_CH0_Pos, /**< Channel 0. */
NRF_PPI_CHANNEL1 = PPI_CHEN_CH1_Pos, /**< Channel 1. */
NRF_PPI_CHANNEL2 = PPI_CHEN_CH2_Pos, /**< Channel 2. */
NRF_PPI_CHANNEL3 = PPI_CHEN_CH3_Pos, /**< Channel 3. */
NRF_PPI_CHANNEL4 = PPI_CHEN_CH4_Pos, /**< Channel 4. */
NRF_PPI_CHANNEL5 = PPI_CHEN_CH5_Pos, /**< Channel 5. */
NRF_PPI_CHANNEL6 = PPI_CHEN_CH6_Pos, /**< Channel 6. */
NRF_PPI_CHANNEL7 = PPI_CHEN_CH7_Pos, /**< Channel 7. */
NRF_PPI_CHANNEL8 = PPI_CHEN_CH8_Pos, /**< Channel 8. */
NRF_PPI_CHANNEL9 = PPI_CHEN_CH9_Pos, /**< Channel 9. */
NRF_PPI_CHANNEL10 = PPI_CHEN_CH10_Pos, /**< Channel 10. */
NRF_PPI_CHANNEL11 = PPI_CHEN_CH11_Pos, /**< Channel 11. */
NRF_PPI_CHANNEL12 = PPI_CHEN_CH12_Pos, /**< Channel 12. */
NRF_PPI_CHANNEL13 = PPI_CHEN_CH13_Pos, /**< Channel 13. */
NRF_PPI_CHANNEL14 = PPI_CHEN_CH14_Pos, /**< Channel 14. */
NRF_PPI_CHANNEL15 = PPI_CHEN_CH15_Pos, /**< Channel 15. */
#if (PPI_CH_NUM > 16) || defined(__SDK_DOXYGEN__)
NRF_PPI_CHANNEL16 = PPI_CHEN_CH16_Pos, /**< Channel 16. */
NRF_PPI_CHANNEL17 = PPI_CHEN_CH17_Pos, /**< Channel 17. */
NRF_PPI_CHANNEL18 = PPI_CHEN_CH18_Pos, /**< Channel 18. */
NRF_PPI_CHANNEL19 = PPI_CHEN_CH19_Pos, /**< Channel 19. */
#endif
NRF_PPI_CHANNEL20 = PPI_CHEN_CH20_Pos, /**< Channel 20. */
NRF_PPI_CHANNEL21 = PPI_CHEN_CH21_Pos, /**< Channel 21. */
NRF_PPI_CHANNEL22 = PPI_CHEN_CH22_Pos, /**< Channel 22. */
NRF_PPI_CHANNEL23 = PPI_CHEN_CH23_Pos, /**< Channel 23. */
NRF_PPI_CHANNEL24 = PPI_CHEN_CH24_Pos, /**< Channel 24. */
NRF_PPI_CHANNEL25 = PPI_CHEN_CH25_Pos, /**< Channel 25. */
NRF_PPI_CHANNEL26 = PPI_CHEN_CH26_Pos, /**< Channel 26. */
NRF_PPI_CHANNEL27 = PPI_CHEN_CH27_Pos, /**< Channel 27. */
NRF_PPI_CHANNEL28 = PPI_CHEN_CH28_Pos, /**< Channel 28. */
NRF_PPI_CHANNEL29 = PPI_CHEN_CH29_Pos, /**< Channel 29. */
NRF_PPI_CHANNEL30 = PPI_CHEN_CH30_Pos, /**< Channel 30. */
NRF_PPI_CHANNEL31 = PPI_CHEN_CH31_Pos /**< Channel 31. */
} nrf_ppi_channel_t;
/**
* @enum nrf_ppi_channel_group_t
* @brief PPI channel groups.
*/
typedef enum
{
NRF_PPI_CHANNEL_GROUP0 = 0, /**< Channel group 0. */
NRF_PPI_CHANNEL_GROUP1 = 1, /**< Channel group 1. */
NRF_PPI_CHANNEL_GROUP2 = 2, /**< Channel group 2. */
NRF_PPI_CHANNEL_GROUP3 = 3, /**< Channel group 3. */
#if (PPI_GROUP_NUM > 4) || defined(__SDK_DOXYGEN__)
NRF_PPI_CHANNEL_GROUP4 = 4, /**< Channel group 4. */
NRF_PPI_CHANNEL_GROUP5 = 5 /**< Channel group 5. */
#endif
} nrf_ppi_channel_group_t;
/**
* @enum nrf_ppi_channel_include_t
* @brief Definition of which PPI channels belong to a group.
*/
typedef enum
{
NRF_PPI_CHANNEL_EXCLUDE = PPI_CHG_CH0_Excluded, /**< Channel excluded from a group. */
NRF_PPI_CHANNEL_INCLUDE = PPI_CHG_CH0_Included /**< Channel included in a group. */
} nrf_ppi_channel_include_t;
/**
* @enum nrf_ppi_channel_enable_t
* @brief Definition if a PPI channel is enabled.
*/
typedef enum
{
NRF_PPI_CHANNEL_DISABLED = PPI_CHEN_CH0_Disabled, /**< Channel disabled. */
NRF_PPI_CHANNEL_ENABLED = PPI_CHEN_CH0_Enabled /**< Channel enabled. */
} nrf_ppi_channel_enable_t;
/**
* @enum nrf_ppi_task_t
* @brief PPI tasks.
*/
typedef enum
{
/*lint -save -e30 -esym(628,__INTADDR__)*/
NRF_PPI_TASK_CHG0_EN = offsetof(NRF_PPI_Type, TASKS_CHG[0].EN), /**< Task for enabling channel group 0 */
NRF_PPI_TASK_CHG0_DIS = offsetof(NRF_PPI_Type, TASKS_CHG[0].DIS), /**< Task for disabling channel group 0 */
NRF_PPI_TASK_CHG1_EN = offsetof(NRF_PPI_Type, TASKS_CHG[1].EN), /**< Task for enabling channel group 1 */
NRF_PPI_TASK_CHG1_DIS = offsetof(NRF_PPI_Type, TASKS_CHG[1].DIS), /**< Task for disabling channel group 1 */
NRF_PPI_TASK_CHG2_EN = offsetof(NRF_PPI_Type, TASKS_CHG[2].EN), /**< Task for enabling channel group 2 */
NRF_PPI_TASK_CHG2_DIS = offsetof(NRF_PPI_Type, TASKS_CHG[2].DIS), /**< Task for disabling channel group 2 */
NRF_PPI_TASK_CHG3_EN = offsetof(NRF_PPI_Type, TASKS_CHG[3].EN), /**< Task for enabling channel group 3 */
NRF_PPI_TASK_CHG3_DIS = offsetof(NRF_PPI_Type, TASKS_CHG[3].DIS), /**< Task for disabling channel group 3 */
#if (PPI_GROUP_NUM > 4) || defined(__SDK_DOXYGEN__)
NRF_PPI_TASK_CHG4_EN = offsetof(NRF_PPI_Type, TASKS_CHG[4].EN), /**< Task for enabling channel group 4 */
NRF_PPI_TASK_CHG4_DIS = offsetof(NRF_PPI_Type, TASKS_CHG[4].DIS), /**< Task for disabling channel group 4 */
NRF_PPI_TASK_CHG5_EN = offsetof(NRF_PPI_Type, TASKS_CHG[5].EN), /**< Task for enabling channel group 5 */
NRF_PPI_TASK_CHG5_DIS = offsetof(NRF_PPI_Type, TASKS_CHG[5].DIS) /**< Task for disabling channel group 5 */
#endif
/*lint -restore*/
} nrf_ppi_task_t;
/**
* @brief Function for enabling a given PPI channel.
*
* @details This function enables only one channel.
*
* @param[in] channel Channel to enable.
*
* */
__STATIC_INLINE void nrf_ppi_channel_enable(nrf_ppi_channel_t channel)
{
NRF_PPI->CHENSET = PPI_CHENSET_CH0_Set << ((uint32_t) channel);
}
/**
* @brief Function for disabling a given PPI channel.
*
* @details This function disables only one channel.
*
* @param[in] channel Channel to disable.
*/
__STATIC_INLINE void nrf_ppi_channel_disable(nrf_ppi_channel_t channel)
{
NRF_PPI->CHENCLR = PPI_CHENCLR_CH0_Clear << ((uint32_t) channel);
}
/**
* @brief Function for checking if a given PPI channel is enabled.
*
* @details This function checks only one channel.
*
* @param[in] channel Channel to check.
*
* @retval NRF_PPI_CHANNEL_ENABLED If the channel is enabled.
* @retval NRF_PPI_CHANNEL_DISABLED If the channel is not enabled.
*
*/
__STATIC_INLINE nrf_ppi_channel_enable_t nrf_ppi_channel_enable_get(nrf_ppi_channel_t channel)
{
if (NRF_PPI->CHEN & (PPI_CHEN_CH0_Msk << ((uint32_t) channel)))
{
return NRF_PPI_CHANNEL_ENABLED;
}
else
{
return NRF_PPI_CHANNEL_DISABLED;
}
}
/**
* @brief Function for disabling all PPI channels.
*/
__STATIC_INLINE void nrf_ppi_channel_disable_all(void)
{
NRF_PPI->CHENCLR = ((uint32_t)0xFFFFFFFFuL);
}
/**
* @brief Function for disabling multiple PPI channels.
*
* @param[in] mask Channel mask.
*/
__STATIC_INLINE void nrf_ppi_channels_disable(uint32_t mask)
{
NRF_PPI->CHENCLR = mask;
}
/**
* @brief Function for setting up event and task endpoints for a given PPI channel.
*
* @param[in] eep Event register address.
*
* @param[in] tep Task register address.
*
* @param[in] channel Channel to which the given endpoints are assigned.
*/
__STATIC_INLINE void nrf_ppi_channel_endpoint_setup(nrf_ppi_channel_t channel,
uint32_t eep,
uint32_t tep)
{
NRF_PPI->CH[(uint32_t) channel].EEP = eep;
NRF_PPI->CH[(uint32_t) channel].TEP = tep;
}
#if defined(PPI_FEATURE_FORKS_PRESENT) || defined(__SDK_DOXYGEN__)
/**
* @brief Function for setting up task endpoint for a given PPI fork.
*
* @param[in] fork_tep Task register address.
*
* @param[in] channel Channel to which the given fork endpoint is assigned.
*/
__STATIC_INLINE void nrf_ppi_fork_endpoint_setup(nrf_ppi_channel_t channel,
uint32_t fork_tep)
{
NRF_PPI->FORK[(uint32_t) channel].TEP = fork_tep;
}
/**
* @brief Function for setting up event and task endpoints for a given PPI channel and fork.
*
* @param[in] eep Event register address.
*
* @param[in] tep Task register address.
*
* @param[in] fork_tep Fork task register address (register value).
*
* @param[in] channel Channel to which the given endpoints are assigned.
*/
__STATIC_INLINE void nrf_ppi_channel_and_fork_endpoint_setup(nrf_ppi_channel_t channel,
uint32_t eep,
uint32_t tep,
uint32_t fork_tep)
{
nrf_ppi_channel_endpoint_setup(channel, eep, tep);
nrf_ppi_fork_endpoint_setup(channel, fork_tep);
}
#endif
/**
* @brief Function for including a PPI channel in a channel group.
*
* @details This function adds only one channel to the group.
*
* @param[in] channel Channel to be included in the group.
*
* @param[in] channel_group Channel group.
*
*/
__STATIC_INLINE void nrf_ppi_channel_include_in_group(nrf_ppi_channel_t channel,
nrf_ppi_channel_group_t channel_group)
{
NRF_PPI->CHG[(uint32_t) channel_group] =
NRF_PPI->CHG[(uint32_t) channel_group] | (PPI_CHG_CH0_Included << ((uint32_t) channel));
}
/**
* @brief Function for including multiple PPI channels in a channel group.
*
* @details This function adds all specified channels to the group.
*
* @param[in] channel_mask Channels to be included in the group.
*
* @param[in] channel_group Channel group.
*
*/
__STATIC_INLINE void nrf_ppi_channels_include_in_group(uint32_t channel_mask,
nrf_ppi_channel_group_t channel_group)
{
NRF_PPI->CHG[(uint32_t) channel_group] =
NRF_PPI->CHG[(uint32_t) channel_group] | (channel_mask);
}
/**
* @brief Function for removing a PPI channel from a channel group.
*
* @details This function removes only one channel from the group.
*
* @param[in] channel Channel to be removed from the group.
*
* @param[in] channel_group Channel group.
*/
__STATIC_INLINE void nrf_ppi_channel_remove_from_group(nrf_ppi_channel_t channel,
nrf_ppi_channel_group_t channel_group)
{
NRF_PPI->CHG[(uint32_t) channel_group] =
NRF_PPI->CHG[(uint32_t) channel_group] & ~(PPI_CHG_CH0_Included << ((uint32_t) channel));
}
/**
* @brief Function for removing multiple PPI channels from a channel group.
*
* @details This function removes all specified channels from the group.
*
* @param[in] channel_mask Channels to be removed from the group.
*
* @param[in] channel_group Channel group.
*/
__STATIC_INLINE void nrf_ppi_channels_remove_from_group(uint32_t channel_mask,
nrf_ppi_channel_group_t channel_group)
{
NRF_PPI->CHG[(uint32_t) channel_group] =
NRF_PPI->CHG[(uint32_t) channel_group] & ~(channel_mask);
}
/**
* @brief Function for removing all PPI channels from a channel group.
*
* @param[in] group Channel group.
*
*/
__STATIC_INLINE void nrf_ppi_channel_group_clear(nrf_ppi_channel_group_t group)
{
NRF_PPI->CHG[(uint32_t) group] = 0;
}
/**
* @brief Function for enabling a channel group.
*
* @param[in] group Channel group.
*
*/
__STATIC_INLINE void nrf_ppi_group_enable(nrf_ppi_channel_group_t group)
{
NRF_PPI->TASKS_CHG[(uint32_t) group].EN = NRF_PPI_TASK_SET;
}
/**
* @brief Function for disabling a channel group.
*
* @param[in] group Channel group.
*
*/
__STATIC_INLINE void nrf_ppi_group_disable(nrf_ppi_channel_group_t group)
{
NRF_PPI->TASKS_CHG[(uint32_t) group].DIS = NRF_PPI_TASK_SET;
}
/**
* @brief Function for setting a PPI task.
*
* @param[in] ppi_task PPI task to set.
*/
__STATIC_INLINE void nrf_ppi_task_trigger(nrf_ppi_task_t ppi_task)
{
*((volatile uint32_t *) ((uint8_t *) NRF_PPI_BASE + (uint32_t) ppi_task)) = NRF_PPI_TASK_SET;
}
/**
* @brief Function for returning the address of a specific PPI task register.
*
* @param[in] ppi_task PPI task.
*/
__STATIC_INLINE uint32_t * nrf_ppi_task_address_get(nrf_ppi_task_t ppi_task)
{
return (uint32_t *) ((uint8_t *) NRF_PPI_BASE + (uint32_t) ppi_task);
}
/**
* @brief Function for returning the PPI enable task address of a specific group.
*
* @param[in] group PPI group.
*/
__STATIC_INLINE uint32_t * nrf_ppi_task_group_enable_address_get(nrf_ppi_channel_group_t group)
{
return (uint32_t *) &NRF_PPI->TASKS_CHG[(uint32_t) group].EN;
}
/**
* @brief Function for returning the PPI disable task address of a specific group.
*
* @param[in] group PPI group.
*/
__STATIC_INLINE uint32_t * nrf_ppi_task_group_disable_address_get(nrf_ppi_channel_group_t group)
{
return (uint32_t *) &NRF_PPI->TASKS_CHG[(uint32_t) group].DIS;
}
/**
*@}
**/
/*lint --flb "Leave library region" */
#ifdef __cplusplus
}
#endif
#endif // NRF_PPI_H__
+22
View File
@@ -317,6 +317,28 @@ __STATIC_INLINE void nrf_radio_shorts_disable(uint32_t radio_short_mask)
NRF_RADIO->SHORTS &= ~radio_short_mask;
}
/**
* @brief Function for setting shortcuts.
*
* @param[in] radio_short_mask Mask of shortcuts.
*
*/
__STATIC_INLINE void nrf_radio_shorts_set(uint32_t radio_short_mask)
{
NRF_RADIO->SHORTS = radio_short_mask;
}
/**
* @brief Function for getting shortcuts.
*
* @return Mask of shortcuts.
*
*/
__STATIC_INLINE uint32_t nrf_radio_shorts_get(void)
{
return NRF_RADIO->SHORTS;
}
/**
* @brief Function for getting present state of the radio module.
*/
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,96 @@
S110/S120/S130/S132/S140 license agreement
NORDIC SEMICONDUCTOR ASA SOFTDEVICE LICENSE AGREEMENT
License Agreement for the Nordic Semiconductor ASA ("Nordic") S110, S120, S130, S132, and S140 Bluetooth SoftDevice software packages
("SoftDevice").
You ("You" "Licensee") must carefully and thoroughly read this License Agreement ("Agreement"), and accept to adhere to this Agreement before
downloading, installing and/or using any software or content in the SoftDevice provided herewith.
YOU ACCEPT THIS LICENSE AGREEMENT BY (A) CLICKING ACCEPT OR AGREE TO THIS LICENSE AGREEMENT, WHERE THIS
OPTION IS MADE AVAILABLE TO YOU; OR (B) BY ACTUALLY USING THE SOFTDEVICE, IN THIS CASE YOU AGREE THAT THE USE OF
THE SOFTDEVICE CONSTITUTES ACCEPTANCE OF THE LICENSING AGREEMENT FROM THAT POINT ONWARDS.
IF YOU DO NOT AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT, THEN DO NOT DOWNLOAD, INSTALL/COMPLETE
INSTALLATION OF, OR IN ANY OTHER WAY MAKE USE OF THE SOFTDEVICE.
1. Grant of License
Subject to the terms in this Agreement Nordic grants Licensee a limited, non-exclusive, non-transferable, non-sub licensable, revocable license
("License"): (a) to use the SoftDevice solely in connection with a Nordic integrated circuit, and (b) to distribute the SoftDevice solely as integrated
in Licensee Product. Licensee shall not use the SoftDevice for any purpose other than specifically authorized herein. It is a material breach of this
agreement to use or modify the SoftDevice for use on any wireless connectivity integrated circuit other than a Nordic integrated circuit.
2. Title
Nordic retains full rights, title, and ownership to the SoftDevice and any and all patents, copyrights, trade secrets, trade names, trademarks, and
other intellectual property rights in and to the SoftDevice.
3. No Modifications or Reverse Engineering
Licensee shall not, modify, reverse engineer, disassemble, decompile or otherwise attempt to discover the source code of any non-source code
parts of the SoftDevice including, but not limited to pre-compiled hex files, binaries and object code.
4. Distribution Restrictions
Except as set forward in Section 1 above, the Licensee may not disclose or distribute any or all parts of the SoftDevice to any third party.
Licensee agrees to provide reasonable security precautions to prevent unauthorized access to or use of the SoftDevice as proscribed herein.
Licensee also agrees that use of and access to the SoftDevice will be strictly limited to the employees and subcontractors of the Licensee
necessary for the performance of development, verification and production tasks under this Agreement. The Licensee is responsible for making
such employees and subcontractors comply with the obligations concerning use and non-disclosure of the SoftDevice.
5. No Other Rights
Licensee shall use the SoftDevice only in compliance with this Agreement and shall refrain from using the SoftDevice in any way that may be
contrary to this Agreement.
6. Fees
Nordic grants the License to the Licensee free of charge provided that the Licensee undertakes the obligations in the Agreement and warrants to
comply with the Agreement.
7. DISCLAIMER OF WARRANTY
THE SOFTDEVICE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EXPRESS OR IMPLIED AND NEITHER NORDIC, ITS
LICENSORS OR AFFILIATES NOR THE COPYRIGHT HOLDERS MAKE ANY REPRESENTATIONS OR WARRANTIES, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE OR
THAT THE SOFTDEVICE WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. THERE
IS NO WARRANTY BY NORDIC OR BY ANY OTHER PARTY THAT THE FUNCTIONS CONTAINED IN THE SOFTDEVICE WILL MEET THE
REQUIREMENTS OF LICENSEE OR THAT THE OPERATION OF THE SOFTDEVICE WILL BE UNINTERRUPTED OR ERROR-FREE.
LICENSEE ASSUMES ALL RESPONSIBILITY AND RISK FOR THE SELECTION OF THE SOFTDEVICE TO ACHIEVE LICENSEE’S
INTENDED RESULTS AND FOR THE INSTALLATION, USE AND RESULTS OBTAINED FROM IT.
8. No Support
Nordic is not obligated to furnish or make available to Licensee any further information, software, technical information, know-how, show-how,
bug-fixes or support. Nordic reserves the right to make changes to the SoftDevice without further notice.
9. Limitation of Liability
In no event shall Nordic, its employees or suppliers, licensors or affiliates be liable for any lost profits, revenue, sales, data or costs of
procurement of substitute goods or services, property damage, personal injury, interruption of business, loss of business information or for any
special, direct, indirect, incidental, economic, punitive, special or consequential damages, however caused and whether arising under contract,
tort, negligence, or other theory of liability arising out of the use of or inability to use the SoftDevice, even if Nordic or its employees or suppliers,
licensors or affiliates are advised of the possibility of such damages. Because some countries/states/jurisdictions do not allow the exclusion or
limitation of liability, but may allow liability to be limited, in such cases, Nordic, its employees or licensors or affiliates’ liability shall be limited to
USD 50.
10. Breach of Contract
Upon a breach of contract by the Licensee, Nordic and its licensor are entitled to damages in respect of any direct loss which can be reasonably
attributed to the breach by the Licensee. If the Licensee has acted with gross negligence or willful misconduct, the Licensee shall cover both
direct and indirect costs for Nordic and its licensors.
11. Indemnity
Licensee undertakes to indemnify, hold harmless and defend Nordic and its directors, officers, affiliates, shareholders, licensors, employees and
agents from and against any claims or lawsuits, including attorney's fees, that arise or result of the Licensee’s execution of the License and which
is not due to causes for which Nordic is responsible.
12. Governing Law
This Agreement shall be construed according to the laws of Norway, and hereby submits to the exclusive jurisdiction of the Oslo tingrett.
13. Assignment
Licensee shall not assign this Agreement or any rights or obligations hereunder without the prior written consent of Nordic.
14. Termination
Without prejudice to any other rights, Nordic may cancel this Agreement if Licensee does not abide by the terms and conditions of this
Agreement. Upon termination Licensee must promptly cease the use of the License and destroy all copies of the Licensed Technology and any
other material provided by Nordic or its affiliate, or produced by the Licensee in connection with the Agreement or the Licensed Technology.
15. Third party beneficiaries
Nordic’s licensors are intended third party beneficiaries under this Agreement.
@@ -0,0 +1,10 @@
s140_nrf52840_5.0.0-2.alpha
This release consists of the following:
- This readme file
- The s140_nrf52840_5.0.0-2.alpha API (SoftDevice header files)
- The s140_nrf52840_5.0.0-2.alpha license agreement
- The s140_nrf52840_5.0.0-2.alpha release notes
- The s140_nrf52840_5.0.0-2.alpha SoftDevice (binary hex file)
- The s140_nrf52840_5.0.0-2.alpha Migration Document
@@ -0,0 +1,615 @@
/*
* 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_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. */
SD_BLE_CFG_SET, /**< Add a configuration to the BLE stack. */
};
/**
* @brief BLE Module Independent Event IDs.
*/
enum BLE_COMMON_EVTS
{
BLE_EVT_USER_MEM_REQUEST = BLE_EVT_BASE, /**< 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 Configuration IDs.
*
* IDs that uniquely identify a connection configuration.
*/
enum BLE_CONN_CFGS
{
BLE_CONN_CFG_GAP = BLE_CONN_CFG_BASE, /**< BLE GAP specific connection configuration. */
BLE_CONN_CFG_GATTC, /**< BLE GATTC specific connection configuration. */
BLE_CONN_CFG_GATTS, /**< BLE GATTS specific connection configuration. */
BLE_CONN_CFG_GATT, /**< BLE GATT specific connection configuration. */
};
/**@brief BLE Common Configuration IDs.
*
* IDs that uniquely identify a common configuration.
*/
enum BLE_COMMON_CFGS
{
BLE_COMMON_CFG_VS_UUID = BLE_CFG_BASE, /**< Vendor specific UUID configuration */
};
/**@brief Common Option IDs.
* IDs that uniquely identify a common option.
*/
enum BLE_COMMON_OPTS
{
BLE_COMMON_OPT_PA_LNA = BLE_OPT_BASE, /**< PA and LNA options */
BLE_COMMON_OPT_CONN_EVT_EXT, /**< Extended connection events option */
};
/** @} */
/** @addtogroup BLE_COMMON_DEFINES Defines
* @{ */
/** @brief Required pointer alignment for BLE Events.
*/
#define BLE_EVT_PTR_ALIGNMENT 4
/** @brief Leaves the maximum of the two arguments.
*/
#define BLE_MAX(a, b) ((a) < (b) ? (b) : (a))
/** @brief Maximum possible length for BLE Events.
* @note The highest value used for @ref ble_gatt_conn_cfg_t::att_mtu in any connection configuration shall be used as a parameter.
* If that value has not been configured for any connections then @ref BLE_GATT_ATT_MTU_DEFAULT must be used instead.
*/
#define BLE_EVT_LEN_MAX(ATT_MTU) (BLE_MAX( \
sizeof(ble_evt_t), \
BLE_MAX( \
offsetof(ble_evt_t, evt.gattc_evt.params.rel_disc_rsp.includes) + ((ATT_MTU) - 2) / 6 * sizeof(ble_gattc_include_t), \
offsetof(ble_evt_t, evt.gattc_evt.params.attr_info_disc_rsp.info.attr_info16) + ((ATT_MTU) - 2) / 4 * sizeof(ble_gattc_attr_info16_t) \
) \
))
/** @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_DEFAULT 10 /**< Default VS UUID count. */
#define BLE_UUID_VS_COUNT_MAX 254 /**< Maximum VS UUID count. */
/** @} */
/** @defgroup BLE_COMMON_CFG_DEFAULTS Configuration defaults.
* @{
*/
#define BLE_CONN_CFG_TAG_DEFAULT 0 /**< Default configuration tag, SoftDevice default connection configuration. */
/** @} */
/** @} */
/** @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_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_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; /**< Event parameter union. */
} 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_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; /**< Event union. */
} 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 Configuration of extended BLE connection events.
*
* When enabled the SoftDevice will dynamically extend the connection event when possible.
*
* The connection event length is controlled by the connection configuration as set by @ref ble_gap_conn_cfg_t::event_length.
* The connection event can be extended if there is time to send another packet pair before the start of the next connection interval,
* and if there are no conflicts with other BLE roles requesting radio time.
*
* @note @ref sd_ble_opt_get is not supported for this option.
*/
typedef struct
{
uint8_t enable : 1; /**< Enable extended BLE connection events, disabled by default. */
} ble_common_opt_conn_evt_ext_t;
/**@brief Option structure for common options. */
typedef union
{
ble_common_opt_pa_lna_t pa_lna; /**< Parameters for controlling PA and LNA pin toggling. */
ble_common_opt_conn_evt_ext_t conn_evt_ext; /**< Parameters for enabling extended connection events. */
} 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 connection configuration type, wrapping the module specific configurations, set with
* @ref sd_ble_cfg_set.
*
* @note Connection configurations don't have to be set.
* In the case that no configurations has been set, or fewer connection configurations has been set than enabled connections,
* the default connection configuration will be automatically added for the remaining connections.
* When creating connections with the default configuration, @ref BLE_CONN_CFG_TAG_DEFAULT should be used in
* place of @ref ble_conn_cfg_t::conn_cfg_tag. See @ref sd_ble_gap_adv_start() and @ref sd_ble_gap_connect()"
*
* @mscs
* @mmsc{@ref BLE_CONN_CFG}
* @endmscs
*/
typedef struct
{
uint8_t conn_cfg_tag; /**< The application chosen tag it can use with the @ref sd_ble_gap_adv_start() and @ref sd_ble_gap_connect()
calls to select this configuration when creating a connection.
Must be different for all connection configurations added and not @ref BLE_CONN_CFG_TAG_DEFAULT. */
union {
ble_gap_conn_cfg_t gap_conn_cfg; /**< GAP connection configuration, cfg_id is @ref BLE_CONN_CFG_GAP. */
ble_gattc_conn_cfg_t gattc_conn_cfg; /**< GATTC connection configuration, cfg_id is @ref BLE_CONN_CFG_GATTC. */
ble_gatts_conn_cfg_t gatts_conn_cfg; /**< GATTS this connection configuration, cfg_id is @ref BLE_CONN_CFG_GATTS. */
ble_gatt_conn_cfg_t gatt_conn_cfg; /**< GATT this connection configuration, cfg_id is @ref BLE_CONN_CFG_GATT. */
} params; /**< Connection configuration union. */
} ble_conn_cfg_t;
/**
* @brief Configuration of Vendor Specific UUIDs, set with @ref sd_ble_cfg_set.
*
* @retval ::NRF_ERROR_INVALID_PARAM Too many UUIDs configured.
*/
typedef struct
{
uint8_t vs_uuid_count; /**< Number of 128-bit Vendor Specific UUID bases to allocate memory for.
Default value is @ref BLE_UUID_VS_COUNT_DEFAULT. Maximum value is
@ref BLE_UUID_VS_COUNT_MAX. */
} ble_common_cfg_vs_uuid_t;
/**@brief Common BLE Configuration type, wrapping the common configurations. */
typedef union
{
ble_common_cfg_vs_uuid_t vs_uuid_cfg; /**< Vendor specific UUID configuration, cfg_id is @ref BLE_COMMON_CFG_VS_UUID. */
} ble_common_cfg_t;
/**@brief BLE Configuration type, wrapping the module specific configurations. */
typedef union
{
ble_conn_cfg_t conn_cfg; /**< Connection specific configurations, cfg_id in @ref BLE_CONN_CFGS series. */
ble_common_cfg_t common_cfg; /**< Global common configurations, cfg_id in @ref BLE_COMMON_CFGS series. */
ble_gap_cfg_t gap_cfg; /**< Global GAP configurations, cfg_id in @ref BLE_GAP_CFGS series. */
ble_gatts_cfg_t gatts_cfg; /**< Global GATTS configuration, cfg_id in @ref BLE_GATTS_CFGS series. */
} ble_cfg_t;
/** @} */
/** @addtogroup BLE_COMMON_FUNCTIONS Functions
* @{ */
/**@brief Enable the BLE stack
*
* @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.
*
* @note The memory requirement for a specific configuration will not increase between SoftDevices
* with the same major version number.
*
* @note The value of *p_app_ram_base when the app has done no custom configuration of the
* SoftDevice, i.e. the app has not called @ref sd_ble_cfg_set before @ref sd_ble_enable, can
* be found in the release notes.
*
* @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 BLE related function other than @ref
* sd_ble_cfg_set 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_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.
*/
SVCALL(SD_BLE_ENABLE, uint32_t, sd_ble_enable(uint32_t * p_app_ram_base));
/**@brief Add configurations for the BLE stack
*
* @param[in] cfg_id Config ID, see @ref BLE_CONN_CFGS, @ref BLE_COMMON_CFGS, @ref
* BLE_GAP_CFGS or @ref BLE_GATTS_CFGS.
* @param[in] p_cfg Pointer to a ble_cfg_t structure containing the configuration value.
* @param[in] app_ram_base The start address of the application RAM region (APP_RAM_BASE).
* See @ref sd_ble_enable for details about APP_RAM_BASE.
*
* @note The memory requirement for a specific configuration will not increase between SoftDevices
* with the same major version number.
*
* @note If a configuration is set more than once, the last one set is the one that takes effect on
* @ref sd_ble_enable.
*
* @note Any part of the BLE stack that is NOT configured with @ref sd_ble_cfg_set will have default
* configuration.
*
* @note @ref sd_ble_cfg_set may be called at any time when the SoftDevice is enabled (see @ref
* sd_softdevice_enable) while the BLE part of the SoftDevice is not enabled (see @ref
* sd_ble_enable).
*
* @note Error codes for the configurations are described in the configuration structs.
*
* @mscs
* @mmsc{@ref BLE_COMMON_ENABLE}
* @endmscs
*
* @retval ::NRF_SUCCESS The configuration has been added successfully.
* @retval ::NRF_ERROR_INVALID_STATE The BLE stack had already been initialized.
* @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid cfg_id supplied.
* @retval ::NRF_ERROR_NO_MEM The amount of memory assigned to the SoftDevice by app_ram_base is not
* large enough to fit this configuration's memory requirement.
*/
SVCALL(SD_BLE_CFG_SET, uint32_t, sd_ble_cfg_set(uint32_t cfg_id, ble_cfg_t const * p_cfg, uint32_t 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 aligned to the extend defined by @ref BLE_EVT_PTR_ALIGNMENT</b>.
* The buffer should be interpreted as a @ref ble_evt_t struct.
* @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.
* The maximum possible event length is defined by @ref BLE_EVT_LEN_MAX. The application may also "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
*
* @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 Add a Vendor Specific base UUID.
*
* @details This call enables the application to add a vendor specific base UUID to the BLE stack's table, for later
* use with 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. This is accomplished 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 indexes 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] p_block Pointer to a user memory block structure or NULL if memory is managed by the application.
*
* @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 ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_LENGTH Invalid user memory block length supplied.
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection state or no user memory request pending.
*/
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}
* @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__ */
/**
@}
@}
*/
@@ -0,0 +1,91 @@
/*
* 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. */
#define BLE_ERROR_BLOCKED_BY_OTHER_LINKS (NRF_ERROR_STK_BASE_NUM+0x006) /**< The attempt to change link settings failed due to the scheduling of other links. */
/** @} */
/** @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
/**
@}
@}
*/
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,221 @@
/*
* 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 ATT MTU, in bytes. */
#define BLE_GATT_ATT_MTU_DEFAULT 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 /**< Cancel prepared write. */
#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE 0x01 /**< Execute prepared write. */
/** @} */
/** @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 Authorization. */
#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 BLE GATT connection configuration parameters, set with @ref sd_ble_cfg_set.
*
* @retval NRF_ERROR_INVALID_PARAM att_mtu is smaller than @ref BLE_GATT_ATT_MTU_DEFAULT.
*/
typedef struct
{
uint16_t att_mtu; /**< Maximum size of ATT packet the SoftDevice can send or receive.
The default and minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT.
@mscs
@mmsc{@ref BLE_GATTC_MTU_EXCHANGE}
@mmsc{@ref BLE_GATTS_MTU_EXCHANGE}
@endmscs
*/
} ble_gatt_conn_cfg_t;
/**@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; /**< Notification 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__
/** @} */
@@ -0,0 +1,700 @@
/*
* 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"
#include "nrf_error.h"
#include "nrf.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. */
SD_BLE_GATTC_EXCHANGE_MTU_REQUEST, /**< Exchange MTU Request. */
};
/**
* @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_EXCHANGE_MTU_RSP, /**< Exchange MTU Response event. \n See @ref ble_gattc_evt_exchange_mtu_rsp_t. */
BLE_GATTC_EVT_TIMEOUT, /**< Timeout event. \n See @ref ble_gattc_evt_timeout_t. */
BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE /**< Write without Response transmission complete. \n See @ref ble_gattc_evt_write_cmd_tx_complete_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. */
/** @} */
/** @defgroup BLE_GATTC_DEFAULTS GATT Client defaults
* @{ */
#define BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT 1 /**< Default number of Write without Response that can be queued for transmission. */
/** @} */
/** @} */
/** @addtogroup BLE_GATTC_STRUCTURES Structures
* @{ */
/**
* @brief BLE GATTC connection configuration parameters, set with @ref sd_ble_cfg_set.
*/
typedef struct
{
uint8_t write_cmd_tx_queue_size; /**< The guaranteed minimum number of Write without Response that can be queued for transmission.
The default value is @ref BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT */
} ble_gattc_conn_cfg_t;
/**@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 const *p_value; /**< Pointer to the value data. */
} ble_gattc_write_params_t;
/**@brief Attribute Information for 16-bit Attribute UUID. */
typedef struct
{
uint16_t handle; /**< Attribute handle. */
ble_uuid_t uuid; /**< 16-bit Attribute UUID. */
} ble_gattc_attr_info16_t;
/**@brief Attribute Information for 128-bit Attribute UUID. */
typedef struct
{
uint16_t handle; /**< Attribute handle. */
ble_uuid128_t uuid; /**< 128-bit Attribute UUID. */
} ble_gattc_attr_info128_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. */
union {
ble_gattc_attr_info16_t attr_info16[1]; /**< Attribute information for 16-bit Attribute UUID.
@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_attr_info128_t attr_info128[1]; /**< Attribute information for 128-bit Attribute UUID.
@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. */
} info; /**< Attribute information union. */
} 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 the Attribute Value, length is available in @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t::value_len. */
} 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. */
uint8_t handle_value[1]; /**< Handle-Value(s) list. To iterate through the list use @ref sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter.
@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_EXCHANGE_MTU_RSP. */
typedef struct
{
uint16_t server_rx_mtu; /**< Server RX MTU size. */
} ble_gattc_evt_exchange_mtu_rsp_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 Event structure for @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE. */
typedef struct
{
uint8_t count; /**< Number of write without response transmissions completed. */
} ble_gattc_evt_write_cmd_tx_complete_t;
/**@brief GATTC event structure. */
typedef struct
{
uint16_t conn_handle; /**< Connection Handle on which event occurred. */
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_exchange_mtu_rsp_t exchange_mtu_rsp; /**< Exchange MTU Response 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. */
ble_gattc_evt_write_cmd_tx_complete_t write_cmd_tx_complete; /**< Write without Response transmission complete 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{@ref 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{@ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_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_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 Only one write with response procedure can be ongoing per connection at a time.
* If the application tries to write with response while another write with response procedure is ongoing,
* the function call will return @ref NRF_ERROR_BUSY.
* A @ref BLE_GATTC_EVT_WRITE_RSP event will be issued as soon as the write response arrives from the peer.
*
* @note The number of Write without Response that can be queued is configured by @ref ble_gattc_conn_cfg_t::write_cmd_tx_queue_size
* When the queue is full, the function call will return @ref NRF_ERROR_RESOURCES.
* A @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event will be issued as soon as the transmission of the write without response is complete.
*
* @note The application can keep track of the available queue element count for writes without responses by following the procedure below:
* - Store initial queue element count in a variable.
* - Decrement the variable, which stores the currently available queue element count, by one when a call to this function returns @ref NRF_SUCCESS.
* - Increment the variable, which stores the current available queue element count, by the count variable in @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event.
*
* @events
* @event{@ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE, Write without response transmission complete.}
* @event{@ref BLE_GATTC_EVT_WRITE_RSP, Write response received from the peer.}
* @endevents
*
* @mscs
* @mmsc{@ref BLE_GATTC_VALUE_WRITE_WITHOUT_RESP_MSC}
* @mmsc{@ref BLE_GATTC_VALUE_WRITE_MSC}
* @mmsc{@ref BLE_GATTC_VALUE_LONG_WRITE_MSC}
* @mmsc{@ref BLE_GATTC_VALUE_RELIABLE_WRITE_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 For write with response, procedure already in progress. Wait for a @ref BLE_GATTC_EVT_WRITE_RSP event and retry.
* @retval ::NRF_ERROR_RESOURCES Too many writes without responses queued.
* Wait for a @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event and retry.
*/
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));
/**@brief Start an ATT_MTU exchange by sending an Exchange MTU Request to the server.
*
* @details The SoftDevice sets ATT_MTU to the minimum of:
* - The Client RX MTU value, and
* - The Server RX MTU value from @ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP.
*
* However, the SoftDevice never sets ATT_MTU lower than @ref BLE_GATT_ATT_MTU_DEFAULT.
*
* @events
* @event{@ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP}
* @endevents
*
* @mscs
* @mmsc{@ref BLE_GATTC_MTU_EXCHANGE}
* @endmscs
*
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
* @param[in] client_rx_mtu Client RX MTU size.
* - The minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT.
* - The maximum value is @ref ble_gatt_conn_cfg_t::att_mtu in the connection configuration
used for this connection.
* - The value must be equal to Server RX MTU size given in @ref sd_ble_gatts_exchange_mtu_reply
* if an ATT_MTU exchange has already been performed in the other direction.
*
* @retval ::NRF_SUCCESS Successfully sent request to the server.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle.
* @retval ::NRF_ERROR_INVALID_STATE Invalid connection state or an ATT_MTU exchange was already requested once.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid Client RX MTU size supplied.
* @retval ::NRF_ERROR_BUSY Client procedure already in progress.
*/
SVCALL(SD_BLE_GATTC_EXCHANGE_MTU_REQUEST, uint32_t, sd_ble_gattc_exchange_mtu_request(uint16_t conn_handle, uint16_t client_rx_mtu));
/**@brief Iterate through Handle-Value(s) list in @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP event.
*
* @param[in] p_gattc_evt Pointer to event buffer containing @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP event.
* @note If the buffer contains different event, behavior is undefined.
* @param[in,out] p_iter Iterator, points to @ref ble_gattc_handle_value_t structure that will be filled in with
* the next Handle-Value pair in each iteration. If the function returns other than
* @ref NRF_SUCCESS, it will not be changed.
* - To start iteration, initialize the structure to zero.
* - To continue, pass the value from previous iteration.
*
* \code
* ble_gattc_handle_value_t iter;
* memset(&iter, 0, sizeof(ble_gattc_handle_value_t));
* while (sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(&ble_evt.evt.gattc_evt, &iter) == NRF_SUCCESS)
* {
* app_handle = iter.handle;
* memcpy(app_value, iter.p_value, ble_evt.evt.gattc_evt.params.char_val_by_uuid_read_rsp.value_len);
* }
* \endcode
*
* @retval ::NRF_SUCCESS Successfully retrieved the next Handle-Value pair.
* @retval ::NRF_ERROR_NOT_FOUND No more Handle-Value pairs available in the list.
*/
__STATIC_INLINE uint32_t sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(ble_gattc_evt_t *p_gattc_evt, ble_gattc_handle_value_t *p_iter);
/** @} */
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE uint32_t sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(ble_gattc_evt_t *p_gattc_evt, ble_gattc_handle_value_t *p_iter)
{
uint32_t value_len = p_gattc_evt->params.char_val_by_uuid_read_rsp.value_len;
uint8_t *p_first = p_gattc_evt->params.char_val_by_uuid_read_rsp.handle_value;
uint8_t *p_next = p_iter->p_value ? p_iter->p_value + value_len : p_first;
if ((p_next - p_first) / (sizeof(uint16_t) + value_len) < p_gattc_evt->params.char_val_by_uuid_read_rsp.count)
{
p_iter->handle = (uint16_t)p_next[1] << 8 | p_next[0];
p_iter->p_value = p_next + sizeof(uint16_t);
return NRF_SUCCESS;
}
else
{
return NRF_ERROR_NOT_FOUND;
}
}
#endif /* SUPPRESS_INLINE_IMPLEMENTATION */
#ifdef __cplusplus
}
#endif
#endif /* BLE_GATTC_H__ */
/**
@}
*/
@@ -0,0 +1,832 @@
/*
* 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. */
SD_BLE_GATTS_EXCHANGE_MTU_REPLY /**< Reply to Exchange MTU Request. */
};
/**
* @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. \n No additional event structure applies. */
BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST, /**< Exchange MTU Request. \n Reply with @ref sd_ble_gatts_exchange_mtu_reply. \n See @ref ble_gatts_evt_exchange_mtu_request_t. */
BLE_GATTS_EVT_TIMEOUT, /**< Peer failed to respond to an ATT request in time. \n See @ref ble_gatts_evt_timeout_t. */
BLE_GATTS_EVT_HVN_TX_COMPLETE /**< Handle Value Notification transmission complete. \n See @ref ble_gatts_evt_hvn_tx_complete_t. */
};
/**@brief GATTS Configuration IDs.
*
* IDs that uniquely identify a GATTS configuration.
*/
enum BLE_GATTS_CFGS
{
BLE_GATTS_CFG_SERVICE_CHANGED = BLE_GATTS_CFG_BASE, /**< Service changed configuration. */
BLE_GATTS_CFG_ATTR_TAB_SIZE, /**< Attribute table size configuration. */
};
/** @} */
/** @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_SERVICE_CHANGED Service Changed Inclusion Values
* @{
*/
#define BLE_GATTS_SERVICE_CHANGED_DEFAULT (1) /**< Default is to include the Service Changed characteristic in the Attribute Table. */
/** @} */
/** @defgroup BLE_GATTS_ATTR_TAB_SIZE Attribute Table size
* @{
*/
#define BLE_GATTS_ATTR_TAB_SIZE_MIN (248) /**< Minimum Attribute Table size */
#define BLE_GATTS_ATTR_TAB_SIZE_DEFAULT (1408) /**< Default Attribute Table size. */
/** @} */
/** @defgroup BLE_GATTS_DEFAULTS GATT Server defaults
* @{
*/
#define BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT 1 /**< Default number of Handle Value Notifications that can be queued for transmission. */
/** @} */
/** @} */
/** @addtogroup BLE_GATTS_STRUCTURES Structures
* @{ */
/**
* @brief BLE GATTS connection configuration parameters, set with @ref sd_ble_cfg_set.
*/
typedef struct
{
uint8_t hvn_tx_queue_size; /**< Minimum guaranteed number of Handle Value Notifications that can be queued for transmission.
The default value is @ref BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT */
} ble_gatts_conn_cfg_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 const *p_uuid; /**< Pointer to the attribute UUID. */
ble_gatts_attr_md_t const *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 const *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 const *p_char_pf; /**< Pointer to a presentation format structure or NULL if the CPF descriptor is not required. */
ble_gatts_attr_md_t const *p_user_desc_md; /**< Attribute metadata for the User Description descriptor, or NULL for default values. */
ble_gatts_attr_md_t const *p_cccd_md; /**< Attribute metadata for the Client Characteristic Configuration Descriptor, or NULL for default values. */
ble_gatts_attr_md_t const *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 const *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_AUTHORIZE_TYPE_WRITE 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. */
uint8_t const *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 Service Changed Inclusion configuration parameters, set with @ref sd_ble_cfg_set. */
typedef struct
{
uint8_t service_changed : 1; /**< If 1, include the Service Changed characteristic in the Attribute Table. Default is @ref BLE_GATTS_SERVICE_CHANGED_DEFAULT. */
} ble_gatts_cfg_service_changed_t;
/**@brief Attribute table size configuration parameters, set with @ref sd_ble_cfg_set.
*
* @retval ::NRF_ERROR_INVALID_LENGTH One or more of the following is true:
* - The specified Attribute Table size is too small.
* The minimum acceptable size is defined by @ref BLE_GATTS_ATTR_TAB_SIZE_MIN.
* - The specified Attribute Table size is not a multiple of 4.
*/
typedef struct
{
uint32_t attr_tab_size; /**< Attribute table size. Default is @ref BLE_GATTS_ATTR_TAB_SIZE_DEFAULT, minimum is @ref BLE_GATTS_ATTR_TAB_SIZE_MIN. */
} ble_gatts_cfg_attr_tab_size_t;
/**@brief Config structure for GATTS configurations. */
typedef union
{
ble_gatts_cfg_service_changed_t service_changed; /**< Include service changed characteristic, cfg_id is @ref BLE_GATTS_CFG_SERVICE_CHANGED. */
ble_gatts_cfg_attr_tab_size_t attr_tab_size; /**< Attribute table size, cfg_id is @ref BLE_GATTS_CFG_ATTR_TAB_SIZE. */
} ble_gatts_cfg_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 finalize 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_EXCHANGE_MTU_REQUEST. */
typedef struct
{
uint16_t client_rx_mtu; /**< Client RX MTU size. */
} ble_gatts_evt_exchange_mtu_request_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 Event structure for @ref BLE_GATTS_EVT_HVN_TX_COMPLETE. */
typedef struct
{
uint8_t count; /**< Number of notification transmissions completed. */
} ble_gatts_evt_hvn_tx_complete_t;
/**@brief GATTS 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_exchange_mtu_request_t exchange_mtu_request; /**< Exchange MTU Request Event Parameters. */
ble_gatts_evt_timeout_t timeout; /**< Timeout Event. */
ble_gatts_evt_hvn_tx_complete_t hvn_tx_complete; /**< Handle Value Notification transmission complete Event Parameters. */
} 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_NOT_SUPPORTED Feature is not supported, service_handle must be that of the last added service.
* @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 writable auxiliaries bits,
* readable (no security) and writable (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 whether 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. Ignored if the value does not belong to a system attribute.
* @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 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. Ignored if the value does not belong to a system attribute.
* @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 on a system attribute.
* @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_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.
*
* @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.
* The Attribute Table has been updated if one of the following error codes is returned: @ref NRF_ERROR_INVALID_STATE, @ref NRF_ERROR_BUSY,
* @ref NRF_ERROR_FORBIDDEN, @ref BLE_ERROR_GATTS_SYS_ATTR_MISSING and @ref NRF_ERROR_RESOURCES.
* The caller can check whether the value has been updated by looking at the contents of *(p_hvx_params->p_len).
*
* @note Only one indication procedure can be ongoing per connection at a time.
* If the application tries to indicate an attribute value while another indication procedure is ongoing,
* the function call will return @ref NRF_ERROR_BUSY.
* A @ref BLE_GATTS_EVT_HVC event will be issued as soon as the confirmation arrives from the peer.
*
* @note The number of Handle Value Notifications that can be queued is configured by @ref ble_gatts_conn_cfg_t::hvn_tx_queue_size
* When the queue is full, the function call will return @ref NRF_ERROR_RESOURCES.
* A @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event will be issued as soon as the transmission of the notification is complete.
*
* @note The application can keep track of the available queue element count for notifications by following the procedure below:
* - Store initial queue element count in a variable.
* - Decrement the variable, which stores the currently available queue element count, by one when a call to this function returns @ref NRF_SUCCESS.
* - Increment the variable, which stores the current available queue element count, by the count variable in @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event.
*
* @events
* @event{@ref BLE_GATTS_EVT_HVN_TX_COMPLETE, Notification transmission complete.}
* @event{@ref BLE_GATTS_EVT_HVC, Confirmation received from the 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}
* @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 One or more of the following is true:
* - Invalid Connection State
* - Notifications and/or indications not enabled in the CCCD
* - An ATT_MTU exchange is ongoing
* @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_FORBIDDEN The connection's current security level is lower than the one required by the write permissions of the CCCD associated with this characteristic.
* @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied.
* @retval ::NRF_ERROR_BUSY For @ref BLE_GATT_HVX_INDICATION Procedure already in progress. Wait for a @ref BLE_GATTS_EVT_HVC event and retry.
* @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 ::NRF_ERROR_RESOURCES Too many notifications queued.
* Wait for a @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event and retry.
*/
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_cfg_set and @ref ble_gatts_cfg_service_changed_t.
* @retval ::NRF_ERROR_INVALID_STATE One or more of the following is true:
* - Invalid Connection State
* - Notifications and/or indications not enabled in the CCCD
* - An ATT_MTU exchange is ongoing
* @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.
*
* @note @ref ble_gatts_authorize_params_t::p_data is ignored when this function is used to respond
* to a @ref BLE_GATTS_AUTHORIZE_TYPE_READ event if @ref ble_gatts_authorize_params_t::update
* is set to 0.
*
* @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.
*/
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_PARAM Invalid flags supplied.
* @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.
*/
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 persistently 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. Unconditionally 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_INVALID_PARAM Invalid flags 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));
/**@brief Reply to an ATT_MTU exchange request by sending an Exchange MTU Response to the client.
*
* @details This function is only used to reply to a @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST event.
*
* @details The SoftDevice sets ATT_MTU to the minimum of:
* - The Client RX MTU value from @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST, and
* - The Server RX MTU value.
*
* However, the SoftDevice never sets ATT_MTU lower than @ref BLE_GATT_ATT_MTU_DEFAULT.
*
* @mscs
* @mmsc{@ref BLE_GATTS_MTU_EXCHANGE}
* @endmscs
*
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
* @param[in] server_rx_mtu Server RX MTU size.
* - The minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT.
* - The maximum value is @ref ble_gatt_conn_cfg_t::att_mtu in the connection configuration
used for this connection.
* - The value must be equal to Client RX MTU size given in @ref sd_ble_gattc_exchange_mtu_request
* if an ATT_MTU exchange has already been performed in the other direction.
*
* @retval ::NRF_SUCCESS Successfully sent response to the client.
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no ATT_MTU exchange request pending.
* @retval ::NRF_ERROR_INVALID_PARAM Invalid Server RX MTU size supplied.
*/
SVCALL(SD_BLE_GATTS_EXCHANGE_MTU_REPLY, uint32_t, sd_ble_gatts_exchange_mtu_reply(uint16_t conn_handle, uint16_t server_rx_mtu));
/** @} */
#ifdef __cplusplus
}
#endif
#endif // BLE_GATTS_H__
/**
@}
*/
@@ -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. */
#define BLE_HCI_STATUS_CODE_LMP_ERROR_TRANSACTION_COLLISION 0x23 /**< LMP Error Transaction Collision/LL Procedure 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 Advertisement 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__
/** @} */
@@ -0,0 +1,67 @@
/*
* 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_DEFINES Defines
* @{ */
/** @} */
#ifdef __cplusplus
}
#endif
#endif // BLE_L2CAP_H__
/**
@}
*/
@@ -0,0 +1,154 @@
/*
* 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 /**< Common BLE SVC last. */
#define BLE_GAP_SVC_BASE 0x6C /**< GAP BLE SVC base. */
#define BLE_GAP_SVC_LAST 0x93 /**< GAP BLE SVC last. */
#define BLE_GATTC_SVC_BASE 0x94 /**< GATTC BLE SVC base. */
#define BLE_GATTC_SVC_LAST 0x9F /**< GATTC BLE SVC last. */
#define BLE_GATTS_SVC_BASE 0xA0 /**< GATTS BLE SVC base. */
#define BLE_GATTS_SVC_LAST 0xAF /**< GATTS BLE SVC last. */
#define BLE_L2CAP_SVC_BASE 0xB0 /**< L2CAP BLE SVC base. */
#define BLE_L2CAP_SVC_LAST 0xBF /**< L2CAP BLE SVC last. */
#define BLE_EVT_INVALID 0x00 /**< Invalid BLE Event. */
#define BLE_EVT_BASE 0x01 /**< Common BLE Event base. */
#define BLE_EVT_LAST 0x0F /**< Common BLE Event last. */
#define BLE_GAP_EVT_BASE 0x10 /**< GAP BLE Event base. */
#define BLE_GAP_EVT_LAST 0x2F /**< GAP BLE Event last. */
#define BLE_GATTC_EVT_BASE 0x30 /**< GATTC BLE Event base. */
#define BLE_GATTC_EVT_LAST 0x4F /**< GATTC BLE Event last. */
#define BLE_GATTS_EVT_BASE 0x50 /**< GATTS BLE Event base. */
#define BLE_GATTS_EVT_LAST 0x6F /**< GATTS BLE Event last. */
#define BLE_L2CAP_EVT_BASE 0x70 /**< L2CAP BLE Event base. */
#define BLE_L2CAP_EVT_LAST 0x8F /**< L2CAP BLE Event last. */
#define BLE_OPT_INVALID 0x00 /**< Invalid BLE Option. */
#define BLE_OPT_BASE 0x01 /**< Common BLE Option base. */
#define BLE_OPT_LAST 0x1F /**< Common BLE Option last. */
#define BLE_GAP_OPT_BASE 0x20 /**< GAP BLE Option base. */
#define BLE_GAP_OPT_LAST 0x3F /**< GAP BLE Option last. */
#define BLE_GATT_OPT_BASE 0x40 /**< GATT BLE Option base. */
#define BLE_GATT_OPT_LAST 0x5F /**< GATT BLE Option last. */
#define BLE_GATTC_OPT_BASE 0x60 /**< GATTC BLE Option base. */
#define BLE_GATTC_OPT_LAST 0x7F /**< GATTC BLE Option last. */
#define BLE_GATTS_OPT_BASE 0x80 /**< GATTS BLE Option base. */
#define BLE_GATTS_OPT_LAST 0x9F /**< GATTS BLE Option last. */
#define BLE_L2CAP_OPT_BASE 0xA0 /**< L2CAP BLE Option base. */
#define BLE_L2CAP_OPT_LAST 0xBF /**< L2CAP BLE Option last. */
#define BLE_CFG_INVALID 0x00 /**< Invalid BLE configuration. */
#define BLE_CFG_BASE 0x01 /**< Common BLE configuration base. */
#define BLE_CFG_LAST 0x1F /**< Common BLE configuration last. */
#define BLE_CONN_CFG_BASE 0x20 /**< BLE connection configuration base. */
#define BLE_CONN_CFG_LAST 0x3F /**< BLE connection configuration last. */
#define BLE_GAP_CFG_BASE 0x40 /**< GAP BLE configuration base. */
#define BLE_GAP_CFG_LAST 0x5F /**< GAP BLE configuration last. */
#define BLE_GATT_CFG_BASE 0x60 /**< GATT BLE configuration base. */
#define BLE_GATT_CFG_LAST 0x7F /**< GATT BLE configuration last. */
#define BLE_GATTC_CFG_BASE 0x80 /**< GATTC BLE configuration base. */
#define BLE_GATTC_CFG_LAST 0x9F /**< GATTC BLE configuration last. */
#define BLE_GATTS_CFG_BASE 0xA0 /**< GATTS BLE configuration base. */
#define BLE_GATTS_CFG_LAST 0xBF /**< GATTS BLE configuration last. */
#define BLE_L2CAP_CFG_BASE 0xC0 /**< L2CAP BLE configuration base. */
#define BLE_L2CAP_CFG_LAST 0xDF /**< L2CAP BLE configuration last. */
#ifdef __cplusplus
}
#endif
#endif /* BLE_RANGES_H__ */
/**
@}
@}
*/
@@ -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_RECONN_ADDR 0x2A03 /**< Reconnection Address Characteristic. */
#define BLE_UUID_GAP_CHARACTERISTIC_PPCP 0x2A04 /**< Peripheral Preferred Connection Parameters Characteristic. */
#define BLE_UUID_GAP_CHARACTERISTIC_CAR 0x2AA6 /**< Central Address Resolution 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 /**< Joystick (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__ */
/**
@}
@}
*/
@@ -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.
*
*/
/**
@defgroup nrf_mbr_api Master Boot Record API
@{
@brief APIs for updating SoftDevice and BootLoader
*/
#ifndef NRF_MBR_H__
#define NRF_MBR_H__
#include "nrf_svc.h"
#include <stdint.h>
#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, /**< Initialize 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 SoftDevice Specification 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 SoftDevice Specification 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 return values, 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__
/**
@}
*/
@@ -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__
/**
@}
*/
@@ -0,0 +1,67 @@
/*
* 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_sdm_api
@{
@defgroup nrf_sdm_error SoftDevice Manager Error Codes
@{
@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
#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 erroneous SoftDevice flashing).
#ifdef __cplusplus
}
#endif
#endif // NRF_ERROR_SDM_H__
/**
@}
@}
*/
@@ -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__
/**
@}
@}
*/
@@ -0,0 +1,517 @@
/*
* 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 = {0};
* \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)SWI5_IRQn) \
))
/**@brief Interrupts available for to application. */
#define __NRF_NVIC_APP_IRQS_0 (~__NRF_NVIC_SD_IRQS_0)
#endif
#if defined(NRF52) || defined(NRF52840_XXAA)
#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)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);
/**@brief Enables IRQ interrupts globally, including the SoftDevice's interrupts.
*/
__STATIC_INLINE void __sd_nvic_irq_enable(void);
/**@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);
/**@brief Checks if priority 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);
/**@} */
/**@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);
/**@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);
/**@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);
/**@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);
/**@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);
/**@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);
/**@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);
/**@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);
/**@brief Enter 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
*
* @param[out] p_is_nested_critical_region If 1, the application is now in a nested critical region.
*
* @retval ::NRF_SUCCESS
*/
__STATIC_INLINE uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region);
/**@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);
/**@} */
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE int __sd_nvic_irq_disable(void)
{
int pm = __get_PRIMASK();
__disable_irq();
return pm;
}
__STATIC_INLINE void __sd_nvic_irq_enable(void)
{
__enable_irq();
}
__STATIC_INLINE uint32_t __sd_nvic_app_accessible_irq(IRQn_Type IRQn)
{
if (IRQn < 32)
{
return ((1UL<<IRQn) & __NRF_NVIC_APP_IRQS_0) != 0;
}
#if defined(NRF52) || defined(NRF52840_XXAA)
else if (IRQn < 64)
{
return ((1UL<<(IRQn-32)) & __NRF_NVIC_APP_IRQS_1) != 0;
}
#endif
else
{
return 1;
}
}
__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
#if defined(NRF52) || defined(NRF52840_XXAA)
if( priority == 0
|| priority == 1
|| priority == 4
|| priority == 5
)
{
return 0;
}
#endif
return 1;
}
__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;
}
__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;
}
__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;
}
}
__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;
}
}
__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;
}
}
__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;
}
__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;
}
}
__STATIC_INLINE uint32_t sd_nvic_SystemReset(void)
{
NVIC_SystemReset();
return NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN;
}
__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;
#if defined(NRF52) || defined(NRF52840_XXAA)
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;
}
__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];
#if defined(NRF52) || defined(NRF52840_XXAA)
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;
}
#endif /* SUPPRESS_INLINE_IMPLEMENTATION */
#ifdef __cplusplus
}
#endif
#endif // NRF_NVIC_H__
/**@} */
@@ -0,0 +1,338 @@
/*
* 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.
*/
#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
/// Declared in nrf_mbr.h
#define MBR_SIZE 0
#warning test
#endif
/** @brief The major version for the SoftDevice binary distributed with this header file. */
#define SD_MAJOR_VERSION (0)
/** @brief The minor version for the SoftDevice binary distributed with this header file. */
#define SD_MINOR_VERSION (0)
/** @brief The bugfix version for the SoftDevice binary distributed with this header file. */
#define SD_BUGFIX_VERSION (0)
/** @brief The full version number for the SoftDevice binary this header file was distributed
* with, as a decimal number in the form Mmmmbbb, where:
* - M is major version (one or more digits)
* - mmm is minor version (three digits)
* - bbb is bugfix version (three digits). */
#define SD_VERSION (SD_MAJOR_VERSION * 1000000 + SD_MINOR_VERSION * 1000 + SD_BUGFIX_VERSION)
/** @brief SoftDevice Manager SVC Base number. */
#define SDM_SVC_BASE 0x10
/** @brief Invalid info field. Returned when an info field does not exist. */
#define SDM_INFO_FIELD_INVALID (0)
/** @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) when the
* SoftDevice is installed just above the MBR (the usual case). */
#define SOFTDEVICE_INFO_STRUCT_ADDRESS (SOFTDEVICE_INFO_STRUCT_OFFSET + MBR_SIZE)
/** @brief Defines the offset for the SoftDevice Information Structure size value relative to the
* SoftDevice base address. The size value is of type uint8_t. */
#define SD_INFO_STRUCT_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET)
/** @brief Defines the offset for the SoftDevice size value relative to the SoftDevice base address.
* The size value is of type uint32_t. */
#define SD_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x08)
/** @brief Defines the offset for FWID value relative to the SoftDevice base address. The FWID value
* is of type uint16_t. */
#define SD_FWID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x0C)
/** @brief Defines the offset for the SoftDevice ID relative to the SoftDevice base address. The ID
* is of type uint32_t. */
#define SD_ID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x10)
/** @brief Defines the offset for the SoftDevice version relative to the SoftDevice base address in
* the same format as @ref SD_VERSION, stored as an uint32_t. */
#define SD_VERSION_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x14)
/** @brief Defines a macro for retrieving the actual SoftDevice Information Structure size value
* from a given base address. Use @ref MBR_SIZE as the argument when the SoftDevice is
* installed just above the MBR (the usual case). */
#define SD_INFO_STRUCT_SIZE_GET(baseaddr) (*((uint8_t *) ((baseaddr) + SD_INFO_STRUCT_SIZE_OFFSET)))
/** @brief Defines a macro for retrieving the actual SoftDevice size value from a given base
* address. Use @ref MBR_SIZE as the argument when the 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 retrieving the actual FWID value from a given base address. Use @ref
* MBR_SIZE as the argument when the SoftDevice is installed just above the MBR (the usual
* case). */
#define SD_FWID_GET(baseaddr) (*((uint16_t *) ((baseaddr) + SD_FWID_OFFSET)))
/** @brief Defines a macro for retrieving the actual SoftDevice ID from a given base address. Use
* @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR (the
* usual case). */
#define SD_ID_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_ID_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \
? (*((uint32_t *) ((baseaddr) + SD_ID_OFFSET))) : SDM_INFO_FIELD_INVALID)
/** @brief Defines a macro for retrieving the actual FWID value from a given base address. Use @ref
* MBR_SIZE as the argument when the SoftDevice is installed just above the MBR (the usual
* case). */
#define SD_VERSION_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_VERSION_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \
? (*((uint32_t *) ((baseaddr) + SD_VERSION_OFFSET))) : SDM_INFO_FIELD_INVALID)
/**@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 is reserved for future used. */
#define NRF_FAULT_ID_APP_MEMACC (NRF_FAULT_ID_APP_RANGE_START + 1) /**< Application invalid memory access (nRF52 only). The info parameter will contain 0x00000000, in case of SoftDevice RAM
access violation. In case of SoftDevice peripheral register violation the info parameter will contain the sub-region number of PREGION[0], on whose address range the disallowed
write access caused the memory access fault. */
/**@} */
/** @} */
/** @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: 250 ppm */
#define NRF_CLOCK_LF_XTAL_ACCURACY_500_PPM (1) /**< 500 ppm */
#define NRF_CLOCK_LF_XTAL_ACCURACY_150_PPM (2) /**< 150 ppm */
#define NRF_CLOCK_LF_XTAL_ACCURACY_100_PPM (3) /**< 100 ppm */
#define NRF_CLOCK_LF_XTAL_ACCURACY_75_PPM (4) /**< 75 ppm */
#define NRF_CLOCK_LF_XTAL_ACCURACY_50_PPM (5) /**< 50 ppm */
#define NRF_CLOCK_LF_XTAL_ACCURACY_30_PPM (6) /**< 30 ppm */
#define NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM (7) /**< 20 ppm */
#define NRF_CLOCK_LF_XTAL_ACCURACY_10_PPM (8) /**< 10 ppm */
#define NRF_CLOCK_LF_XTAL_ACCURACY_5_PPM (9) /**< 5 ppm */
#define NRF_CLOCK_LF_XTAL_ACCURACY_2_PPM (10) /**< 2 ppm */
#define NRF_CLOCK_LF_XTAL_ACCURACY_1_PPM (11) /**< 1 ppm */
/** @} */
/**@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 +/-250 ppm 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, see @ref NRF_CLOCK_LF_XTAL_ACCURACY.
@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().
* If the application returns from the fault handler the SoftDevice will call 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.
*
* @note When id is set to NRF_FAULT_ID_APP_MEMACC, pc will contain the address of the instruction being executed at the time when
* the fault is detected by the CPU. The CPU program counter may have advanced up to 2 instructions (no branching) after the one that triggered the fault.
*/
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, cannot be NULL.
*
* @retval ::NRF_SUCCESS
* @retval ::NRF_ERROR_INVALID_ADDR Invalid or NULL pointer supplied.
* @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__
/**
@}
*/
@@ -0,0 +1,926 @@
/*
* 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) /**< Base value for SVCs that are available when the SoftDevice is disabled. */
#define SOC_SVC_BASE_NOT_AVAILABLE (0x2B) /**< Base value for SVCs that are not available when the SoftDevice is disabled. */
/**@brief Guaranteed 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
#if defined(NRF52) || defined(NRF52840_XXAA)
#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.
The default interrupt priority for this handler is set to 4 */
#define RADIO_NOTIFICATION_IRQn (SWI1_EGU1_IRQn) /**< The radio notification IRQ number. */
#define RADIO_NOTIFICATION_IRQHandler (SWI1_EGU1_IRQHandler) /**< The radio notification IRQ handler.
The default interrupt priority for this handler is set to 4 */
#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_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_RAM_POWER_SET,
SD_POWER_RAM_POWER_CLR,
SD_POWER_RAM_POWER_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_V17 = 4UL, /**< 1.7 Volts power failure threshold. */
NRF_POWER_THRESHOLD_V18, /**< 1.8 Volts power failure threshold. */
NRF_POWER_THRESHOLD_V19, /**< 1.9 Volts power failure threshold. */
NRF_POWER_THRESHOLD_V20, /**< 2.0 Volts power failure threshold. */
NRF_POWER_THRESHOLD_V21, /**< 2.1 Volts power failure threshold. */
NRF_POWER_THRESHOLD_V22, /**< 2.2 Volts power failure threshold. */
NRF_POWER_THRESHOLD_V23, /**< 2.3 Volts power failure threshold. */
NRF_POWER_THRESHOLD_V24, /**< 2.4 Volts power failure threshold. */
NRF_POWER_THRESHOLD_V25, /**< 2.5 Volts power failure threshold. */
NRF_POWER_THRESHOLD_V26, /**< 2.6 Volts power failure threshold. */
NRF_POWER_THRESHOLD_V27, /**< 2.7 Volts power failure threshold. */
NRF_POWER_THRESHOLD_V28 /**< 2.8 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.
@note The SoftDevice will automatically turn on and off the external crystal,
at the beginning and end of the timeslot, respectively. The crystal may also
intentionally be left running after the timeslot, in cases where it is needed
by the SoftDevice shortly after the end of the timeslot. */
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 activities 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; /**< Parameter union. */
} 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; /**< Parameter union. */
} 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]; /**< Encryption key type. */
typedef uint8_t soc_ecb_cleartext_t[SOC_ECB_CLEARTEXT_LENGTH]; /**< Cleartext data type. */
typedef uint8_t soc_ecb_ciphertext_t[SOC_ECB_CIPHERTEXT_LENGTH]; /**< Ciphertext data type. */
/**@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 const * p_key; /**< Pointer to the Encryption key. */
soc_ecb_cleartext_t const * 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 Writes the NRF_POWER->RAM[index].POWERSET register.
*
* @param[in] index Contains the index in the NRF_POWER->RAM[index].POWERSET register to write to.
* @param[in] ram_powerset Contains the word to write to the NRF_POWER->RAM[index].POWERSET register.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_POWER_RAM_POWER_SET, uint32_t, sd_power_ram_power_set(uint8_t index, uint32_t ram_powerset));
/**@brief Writes the NRF_POWER->RAM[index].POWERCLR register.
*
* @param[in] index Contains the index in the NRF_POWER->RAM[index].POWERCLR register to write to.
* @param[in] ram_powerclr Contains the word to write to the NRF_POWER->RAM[index].POWERCLR register.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_POWER_RAM_POWER_CLR, uint32_t, sd_power_ram_power_clr(uint8_t index, uint32_t ram_powerclr));
/**@brief Get contents of NRF_POWER->RAM[index].POWER register, indicates power status of RAM[index] blocks.
*
* @param[in] index Contains the index in the NRF_POWER->RAM[index].POWER register to read from.
* @param[out] p_ram_power Content of NRF_POWER->RAM[index].POWER register.
*
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_POWER_RAM_POWER_GET, uint32_t, sd_power_ram_power_get(uint8_t index, uint32_t * p_ram_power));
/**@brief Set bits in the general purpose retention registers (NRF_POWER->GPREGRET*).
*
* @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2.
* @param[in] gpregret_msk Bits to be set in the GPREGRET register.
*
* @note nRF51 does only have one general purpose retained register, so gpregret_id must be 0 on nRF51.
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_POWER_GPREGRET_SET, uint32_t, sd_power_gpregret_set(uint32_t gpregret_id, uint32_t gpregret_msk));
/**@brief Clear bits in the general purpose retention registers (NRF_POWER->GPREGRET*).
*
* @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2.
* @param[in] gpregret_msk Bits to be clear in the GPREGRET register.
*
* @note nRF51 does only have one general purpose retained register, so gpregret_id must be 0 on nRF51.
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_POWER_GPREGRET_CLR, uint32_t, sd_power_gpregret_clr(uint32_t gpregret_id, uint32_t gpregret_msk));
/**@brief Get contents of the general purpose retention registers (NRF_POWER->GPREGRET*).
*
* @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2.
* @param[out] p_gpregret Contents of the GPREGRET register.
*
* @note nRF51 does only have one general purpose retained register, so gpregret_id must be 0 on nRF51.
* @retval ::NRF_SUCCESS
*/
SVCALL(SD_POWER_GPREGRET_GET, uint32_t, sd_power_gpregret_get(uint32_t gpregret_id, 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
* main thread. 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, the radio
* notifications must be configured 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_ERROR_INVALID_STATE A protocol stack or other SoftDevice is running. Stop all
* running activities and retry.
* @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 50 us 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).
* - The data in the p_src buffer should not be modified before the @ref NRF_EVT_FLASH_OPERATION_SUCCESS
* or the @ref NRF_EVT_FLASH_OPERATION_ERROR have been received if the SoftDevice is enabled.
*
*
* @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 * p_dst, uint32_t 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 Page number 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 100 ms 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 const * p_request));
/**@} */
#ifdef __cplusplus
}
#endif
#endif // NRF_SOC_H__
/**@} */
@@ -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 (uint16_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__