summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhathach <[email protected]>2018-03-20 20:57:49 +0700
committerhathach <[email protected]>2018-03-20 20:57:49 +0700
commit0fdec33521cdab35aa812a2892183b035ef273da (patch)
treeefa199713a595c3282b6f0b9f47e9c2b794fed5c
parent9f5fcb64edded4407184e3698710e000e94fbf61 (diff)
wrap up nrf52 demo
-rw-r--r--hw/bsp/pca10056/board_pca10056.c1
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/common/nrf_drv_common.c297
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/common/nrf_drv_common.h358
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/delay/nrf_delay.h269
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_clock.h401
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_comp.h518
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_ecb.c100
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_ecb.h101
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_egu.h367
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_gpio.h795
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_gpiote.h430
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_i2s.h563
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_lpcomp.h425
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_nvmc.c136
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_nvmc.h125
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_pdm.h396
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_peripherals.h73
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_power.h1065
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_ppi.h439
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_pwm.h701
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_qdec.h504
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_qspi.h765
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_rng.h282
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_rtc.h343
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_saadc.c62
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_saadc.h609
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_spi.h375
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_spim.h571
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_spis.h553
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_systick.h184
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_temp.h91
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_timer.h630
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_twi.h452
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_twim.h527
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_twis.h706
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_uart.h549
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_uarte.h609
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_usbd.h1435
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_wdt.h339
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/power/nrf_drv_power.c477
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/power/nrf_drv_power.h371
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/uart/nrf_drv_uart.c990
-rw-r--r--hw/mcu/nordic/nrf52/sdk/drivers_nrf/uart/nrf_drv_uart.h465
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/atomic/nrf_atomic.h495
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/atomic/nrf_atomic_internal.h234
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/atomic/nrf_atomic_sanity_check.h153
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/balloc/nrf_balloc.c343
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/balloc/nrf_balloc.h309
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/nrf_log.h234
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/nrf_log_backend_interface.h218
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/nrf_log_backend_rtt.h73
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/nrf_log_backend_uart.h68
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/nrf_log_ctrl.h233
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/nrf_log_default_backends.h81
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/nrf_log_str_formatter.h67
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_backend_rtt.c101
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_backend_serial.c116
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_backend_serial.h77
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_backend_uart.c116
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_ctrl_internal.h80
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_default_backends.c76
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_frontend.c1146
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_internal.h548
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_str_formatter.c209
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/experimental_memobj/nrf_memobj.c231
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/experimental_memobj/nrf_memobj.h198
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/experimental_section_vars/nrf_section.h191
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/experimental_section_vars/nrf_section_iter.c125
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/experimental_section_vars/nrf_section_iter.h206
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/strerror/nrf_strerror.c148
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/strerror/nrf_strerror.h89
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/util/app_error.c143
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/util/app_error.h172
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/util/app_error_weak.c109
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/util/app_error_weak.h85
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/util/app_util.h1082
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/util/app_util_bds.h449
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/util/app_util_platform.c127
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/util/app_util_platform.h262
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/util/nordic_common.h211
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/util/nrf_assert.c54
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/util/nrf_assert.h123
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/util/nrf_bitmask.h147
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/util/sdk_common.h77
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/util/sdk_errors.h166
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/util/sdk_macros.h191
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/util/sdk_mapped_flags.c220
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/util/sdk_mapped_flags.h199
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/util/sdk_os.h76
-rw-r--r--hw/mcu/nordic/nrf52/sdk/libraries/util/sdk_resources.h86
-rw-r--r--hw/mcu/nordic/nrf52/sdk/sdk_config.h4
-rw-r--r--hw/mcu/nordic/nrf52/sdk/softdevice/common/nrf_sdh.c422
-rw-r--r--hw/mcu/nordic/nrf52/sdk/softdevice/common/nrf_sdh.h304
-rw-r--r--hw/mcu/nordic/nrf52/sdk/softdevice/common/nrf_sdh_ble.c300
-rw-r--r--hw/mcu/nordic/nrf52/sdk/softdevice/common/nrf_sdh_ble.h187
-rw-r--r--hw/mcu/nordic/nrf52/sdk/softdevice/common/nrf_sdh_soc.c118
-rw-r--r--hw/mcu/nordic/nrf52/sdk/softdevice/common/nrf_sdh_soc.h143
-rw-r--r--hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble.h615
-rw-r--r--hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_err.h91
-rw-r--r--hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_gap.h2211
-rw-r--r--hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_gatt.h221
-rw-r--r--hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_gattc.h700
-rw-r--r--hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_gatts.h832
-rw-r--r--hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_hci.h131
-rw-r--r--hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_l2cap.h67
-rw-r--r--hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_ranges.h154
-rw-r--r--hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_types.h205
-rw-r--r--hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf52/nrf_mbr.h212
-rw-r--r--hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf_error.h87
-rw-r--r--hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf_error_sdm.h67
-rw-r--r--hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf_error_soc.h82
-rw-r--r--hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf_nvic.h517
-rw-r--r--hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf_sd_def.h59
-rw-r--r--hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf_sdm.h338
-rw-r--r--hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf_soc.h926
-rw-r--r--hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf_svc.h88
-rw-r--r--hw/mcu/nordic/nrf52/tusb_port/hal_nrf52.c3
117 files changed, 38672 insertions, 5 deletions
diff --git a/hw/bsp/pca10056/board_pca10056.c b/hw/bsp/pca10056/board_pca10056.c
index 01bf9a3a4..77293cf6e 100644
--- a/hw/bsp/pca10056/board_pca10056.c
+++ b/hw/bsp/pca10056/board_pca10056.c
@@ -37,7 +37,6 @@
#include "board_pca10056.h"
#include "nrf_gpio.h"
-#include "nrf_drv_systick.h"
#include "nrf_drv_power.h"
/*------------------------------------------------------------------*/
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/common/nrf_drv_common.c b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/common/nrf_drv_common.c
new file mode 100644
index 000000000..8d93e97f6
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/common/nrf_drv_common.c
@@ -0,0 +1,297 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 <stddef.h>
+#include "nrf_drv_common.h"
+#include "nrf_assert.h"
+#include "app_util_platform.h"
+#include "nrf_peripherals.h"
+
+#if NRF_DRV_COMMON_POWER_CLOCK_ISR
+#include "nrf_drv_power.h"
+#include "nrf_drv_clock.h"
+#endif
+#ifdef SOFTDEVICE_PRESENT
+#include "nrf_soc.h"
+#endif
+
+#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING)
+
+#define NRF_LOG_MODULE_NAME common
+
+#if COMMON_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL COMMON_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR COMMON_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR COMMON_CONFIG_DEBUG_COLOR
+#else //COMMON_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif //COMMON_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+typedef struct {
+ nrf_drv_irq_handler_t handler;
+ bool acquired;
+} shared_resource_t;
+
+// SPIM0, SPIS0, SPI0, TWIM0, TWIS0, TWI0
+#if (NRF_MODULE_ENABLED(SPI0) || NRF_MODULE_ENABLED(SPIS0) || NRF_MODULE_ENABLED(TWI0) || NRF_MODULE_ENABLED(TWIS0))
+ #define SERIAL_BOX_0_IN_USE
+ // [this checking may need a different form in unit tests, hence macro]
+ #ifndef IS_SERIAL_BOX_0
+ #define IS_SERIAL_BOX_0(p_per_base) (p_per_base == NRF_SPI0)
+ #endif
+
+ static shared_resource_t m_serial_box_0 = { .acquired = false };
+ void SPI0_TWI0_IRQHandler(void)
+ {
+ ASSERT(m_serial_box_0.handler);
+ m_serial_box_0.handler();
+ }
+#endif // (NRF_MODULE_ENABLED(SPI0) || NRF_MODULE_ENABLED(SPIS0) || NRF_MODULE_ENABLED(TWI0) || NRF_MODULE_ENABLED(TWIS0))
+
+// SPIM1, SPIS1, SPI1, TWIM1, TWIS1, TWI1
+#if (NRF_MODULE_ENABLED(SPI1) || NRF_MODULE_ENABLED(SPIS1) || NRF_MODULE_ENABLED(TWI1) || NRF_MODULE_ENABLED(TWIS1))
+ #define SERIAL_BOX_1_IN_USE
+ // [this checking may need a different form in unit tests, hence macro]
+ #ifndef IS_SERIAL_BOX_1
+ #define IS_SERIAL_BOX_1(p_per_base) (p_per_base == NRF_SPI1)
+ #endif
+
+ static shared_resource_t m_serial_box_1 = { .acquired = false };
+#ifdef TWIM_PRESENT
+ void SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler(void)
+#else
+ void SPI1_TWI1_IRQHandler(void)
+#endif
+ {
+ ASSERT(m_serial_box_1.handler);
+ m_serial_box_1.handler();
+ }
+#endif // (NRF_MODULE_ENABLED(SPI1) || NRF_MODULE_ENABLED(SPIS1) || NRF_MODULE_ENABLED(TWI1) || NRF_MODULE_ENABLED(TWIS1))
+
+// SPIM2, SPIS2, SPI2
+#if (NRF_MODULE_ENABLED(SPI2) || NRF_MODULE_ENABLED(SPIS2))
+ #define SERIAL_BOX_2_IN_USE
+ // [this checking may need a different form in unit tests, hence macro]
+ #ifndef IS_SERIAL_BOX_2
+ #define IS_SERIAL_BOX_2(p_per_base) (p_per_base == NRF_SPI2)
+ #endif
+
+ static shared_resource_t m_serial_box_2 = { .acquired = false };
+ void SPIM2_SPIS2_SPI2_IRQHandler(void)
+ {
+ ASSERT(m_serial_box_2.handler);
+ m_serial_box_2.handler();
+ }
+#endif // (NRF_MODULE_ENABLED(SPI2) || NRF_MODULE_ENABLED(SPIS2))
+
+// COMP, LPCOMP
+#if (NRF_MODULE_ENABLED(COMP) || NRF_MODULE_ENABLED(LPCOMP))
+ #define COMP_LPCOMP_IN_USE
+
+ #ifndef IS_COMP_LPCOMP
+ #define IS_COMP_LPCOMP(p_per_base) ((p_per_base) == NRF_LPCOMP)
+ #endif
+
+ static shared_resource_t m_comp_lpcomp = { .acquired = false };
+ void LPCOMP_IRQHandler(void)
+ {
+ ASSERT(m_comp_lpcomp.handler);
+ m_comp_lpcomp.handler();
+ }
+#endif // (NRF_MODULE_ENABLED(COMP) || NRF_MODULE_ENABLED(LPCOMP))
+
+#if defined(SERIAL_BOX_0_IN_USE) || \
+ defined(SERIAL_BOX_1_IN_USE) || \
+ defined(SERIAL_BOX_2_IN_USE) || \
+ defined(COMP_LPCOMP_IN_USE)
+static ret_code_t acquire_shared_resource(shared_resource_t * p_resource,
+ nrf_drv_irq_handler_t handler)
+{
+ ret_code_t err_code;
+
+ bool busy = false;
+
+ CRITICAL_REGION_ENTER();
+ if (p_resource->acquired)
+ {
+ busy = true;
+ }
+ else
+ {
+ p_resource->acquired = true;
+ }
+ CRITICAL_REGION_EXIT();
+
+ if (busy)
+ {
+ err_code = NRF_ERROR_BUSY;
+ NRF_LOG_WARNING("Function: %s, error code: %s.", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code));
+ return err_code;
+ }
+
+ p_resource->handler = handler;
+ err_code = NRF_SUCCESS;
+ NRF_LOG_INFO("Function: %s, error code: %s.", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code));
+ return err_code;
+}
+#endif
+
+ret_code_t nrf_drv_common_per_res_acquire(void const * p_per_base,
+ nrf_drv_irq_handler_t handler)
+{
+#ifdef SERIAL_BOX_0_IN_USE
+ if (IS_SERIAL_BOX_0(p_per_base))
+ {
+ return acquire_shared_resource(&m_serial_box_0, handler);
+ }
+#endif
+
+#ifdef SERIAL_BOX_1_IN_USE
+ if (IS_SERIAL_BOX_1(p_per_base))
+ {
+ return acquire_shared_resource(&m_serial_box_1, handler);
+ }
+#endif
+
+#ifdef SERIAL_BOX_2_IN_USE
+ if (IS_SERIAL_BOX_2(p_per_base))
+ {
+ return acquire_shared_resource(&m_serial_box_2, handler);
+ }
+#endif
+
+#ifdef COMP_LPCOMP_IN_USE
+ if (IS_COMP_LPCOMP(p_per_base))
+ {
+ return acquire_shared_resource(&m_comp_lpcomp, handler);
+ }
+#endif
+ ret_code_t err_code;
+
+ err_code = NRF_ERROR_INVALID_PARAM;
+ NRF_LOG_WARNING("Function: %s, error code: %s.", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code));
+ return err_code;
+}
+
+void nrf_drv_common_per_res_release(void const * p_per_base)
+{
+#ifdef SERIAL_BOX_0_IN_USE
+ if (IS_SERIAL_BOX_0(p_per_base))
+ {
+ m_serial_box_0.acquired = false;
+ }
+ else
+#endif
+
+#ifdef SERIAL_BOX_1_IN_USE
+ if (IS_SERIAL_BOX_1(p_per_base))
+ {
+ m_serial_box_1.acquired = false;
+ }
+ else
+#endif
+
+#ifdef SERIAL_BOX_2_IN_USE
+ if (IS_SERIAL_BOX_2(p_per_base))
+ {
+ m_serial_box_2.acquired = false;
+ }
+ else
+#endif
+
+#ifdef COMP_LPCOMP_IN_USE
+ if (IS_COMP_LPCOMP(p_per_base))
+ {
+ m_comp_lpcomp.acquired = false;
+ }
+ else
+#endif
+
+ {}
+}
+
+#endif // NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING)
+
+#if NRF_MODULE_ENABLED(POWER)
+void nrf_drv_common_power_irq_disable(void)
+{
+#if NRF_DRV_COMMON_POWER_CLOCK_ISR
+ if (!nrf_drv_clock_init_check())
+#endif
+ {
+ nrf_drv_common_irq_disable(POWER_CLOCK_IRQn);
+ }
+}
+#endif
+
+#if NRF_MODULE_ENABLED(CLOCK)
+void nrf_drv_common_clock_irq_disable(void)
+{
+#if NRF_DRV_COMMON_POWER_CLOCK_ISR
+ if (!nrf_drv_power_init_check())
+#endif
+ {
+ nrf_drv_common_irq_disable(POWER_CLOCK_IRQn);
+ }
+}
+#endif
+
+#if NRF_DRV_COMMON_POWER_CLOCK_ISR
+void POWER_CLOCK_IRQHandler(void)
+{
+ extern void nrf_drv_clock_onIRQ(void);
+ extern void nrf_drv_power_onIRQ(void);
+
+ nrf_drv_clock_onIRQ();
+ nrf_drv_power_onIRQ();
+}
+#endif // NRF_DRV_COMMON_POWER_CLOCK_ISR
+
+
+void nrf_drv_common_irq_enable(IRQn_Type IRQn, uint8_t priority)
+{
+ INTERRUPT_PRIORITY_ASSERT(priority);
+
+ NVIC_SetPriority(IRQn, priority);
+ NVIC_ClearPendingIRQ(IRQn);
+ NVIC_EnableIRQ(IRQn);
+}
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/common/nrf_drv_common.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/common/nrf_drv_common.h
new file mode 100644
index 000000000..cdf866a5c
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/common/nrf_drv_common.h
@@ -0,0 +1,358 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_DRV_COMMON_H__
+#define NRF_DRV_COMMON_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf.h"
+#include "sdk_errors.h"
+#include "sdk_common.h"
+#include "nrf_assert.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef NRF51
+#ifdef SOFTDEVICE_PRESENT
+#define INTERRUPT_PRIORITY_IS_VALID(pri) (((pri) == 1) || ((pri) == 3))
+#else
+#define INTERRUPT_PRIORITY_IS_VALID(pri) ((pri) < 4)
+#endif //SOFTDEVICE_PRESENT
+#else
+#ifdef SOFTDEVICE_PRESENT
+#define INTERRUPT_PRIORITY_IS_VALID(pri) ((((pri) > 1) && ((pri) < 4)) || \
+ (((pri) > 4) && ((pri) < 8)))
+#else
+#define INTERRUPT_PRIORITY_IS_VALID(pri) ((pri) < 8)
+#endif //SOFTDEVICE_PRESENT
+#endif //NRF52
+
+#define INTERRUPT_PRIORITY_VALIDATION(pri) STATIC_ASSERT(INTERRUPT_PRIORITY_IS_VALID((pri)))
+#define INTERRUPT_PRIORITY_ASSERT(pri) ASSERT(INTERRUPT_PRIORITY_IS_VALID((pri)))
+
+/**
+ * @defgroup nrf_drv_common Peripheral drivers common module
+ * @{
+ * @ingroup nrf_drivers
+ */
+
+/**
+ * @brief Offset of event registers in every peripheral instance.
+ *
+ * This is the offset where event registers start in every peripheral.
+ */
+#define NRF_DRV_COMMON_EVREGS_OFFSET 0x100U
+
+/**
+ * @brief The flag that is set when POWER_CLOCK ISR is implemented in common module
+ *
+ * This flag means that the function POWER_CLOCK_IRQHandler is implemented in
+ * nrf_drv_common.c file. In the @c clock and @c power modules functions
+ * nrf_drv_clock_onIRQ nrf_drv_power_onIRQ should be implemented
+ * and they would be called from common implementation.
+ *
+ * None of the checking is done here.
+ * The implementation functions in @c clock and @c power are required to handle
+ * correctly the case when they are called without any event bit set.
+ */
+#define NRF_DRV_COMMON_POWER_CLOCK_ISR (NRF_MODULE_ENABLED(CLOCK) && NRF_MODULE_ENABLED(POWER))
+
+/**
+ * @brief Driver state.
+ */
+typedef enum
+{
+ NRF_DRV_STATE_UNINITIALIZED, /**< Uninitialized. */
+ NRF_DRV_STATE_INITIALIZED, /**< Initialized but powered off. */
+ NRF_DRV_STATE_POWERED_ON
+} nrf_drv_state_t;
+
+/**
+ * @brief Driver power state selection.
+ */
+typedef enum
+{
+ NRF_DRV_PWR_CTRL_ON, /**< Power on request. */
+ NRF_DRV_PWR_CTRL_OFF /**< Power off request. */
+} nrf_drv_pwr_ctrl_t;
+
+/**
+ * @brief IRQ handler type.
+ */
+typedef void (*nrf_drv_irq_handler_t)(void);
+
+
+#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING)
+
+/**
+ * @brief Function for acquiring shared peripheral resources associated with
+ * the specified peripheral.
+ *
+ * Certain resources and registers are shared among peripherals that have
+ * the same ID (for example: SPI0, SPIM0, SPIS0, TWI0, TWIM0, and TWIS0).
+ * Only one of them can be utilized at a given time. This function reserves
+ * proper resources to be used by the specified peripheral.
+ * If PERIPHERAL_RESOURCE_SHARING_ENABLED is set to a non-zero value, IRQ
+ * handlers for peripherals that are sharing resources with others are
+ * implemented by the nrf_drv_common module instead of individual drivers.
+ * The drivers must then specify their interrupt handling routines and
+ * register them by using this function.
+ *
+ * @param[in] p_per_base Requested peripheral base pointer.
+ * @param[in] handler Interrupt handler to register. May be NULL
+ * if interrupts are not used for the peripheral.
+ *
+ * @retval NRF_SUCCESS If resources were acquired successfully.
+ * @retval NRF_ERROR_BUSY If resources were already acquired.
+ * @retval NRF_ERROR_INVALID_PARAM If the specified peripheral is not enabled
+ * or the peripheral does not share resources
+ * with other peripherals.
+ */
+ret_code_t nrf_drv_common_per_res_acquire(void const * p_per_base,
+ nrf_drv_irq_handler_t handler);
+
+/**
+ * @brief Function for releasing shared resources reserved previously by
+ * @ref nrf_drv_common_per_res_acquire() for the specified peripheral.
+ *
+ * @param[in] p_per_base Requested peripheral base pointer.
+ */
+void nrf_drv_common_per_res_release(void const * p_per_base);
+
+#endif // NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING)
+
+
+/**
+ * @brief Function sets priority and enables NVIC interrupt
+ *
+ * @note Function checks if correct priority is used when softdevice is present
+ *
+ * @param[in] IRQn Interrupt id
+ * @param[in] priority Interrupt priority
+ */
+void nrf_drv_common_irq_enable(IRQn_Type IRQn, uint8_t priority);
+
+#if NRF_MODULE_ENABLED(POWER)
+/**
+ * @brief Disable power IRQ
+ *
+ * Power and clock peripheral uses the same IRQ.
+ * This function disables POWER_CLOCK IRQ only if CLOCK driver
+ * is uninitialized.
+ *
+ * @sa nrf_drv_common_power_clock_irq_init
+ */
+void nrf_drv_common_power_irq_disable(void);
+#endif
+
+#if NRF_MODULE_ENABLED(CLOCK)
+/**
+ * @brief Disable clock IRQ
+ *
+ * Power and clock peripheral uses the same IRQ.
+ * This function disables POWER_CLOCK IRQ only if POWER driver
+ * is uninitialized.
+ *
+ * @sa nrf_drv_common_power_clock_irq_init
+ */
+void nrf_drv_common_clock_irq_disable(void);
+#endif
+
+/**
+ * @brief Check if interrupt is enabled
+ *
+ * Function that checks if selected interrupt is enabled.
+ *
+ * @param[in] IRQn Interrupt id
+ *
+ * @retval true Selected IRQ is enabled.
+ * @retval false Selected IRQ is disabled.
+ */
+__STATIC_INLINE bool nrf_drv_common_irq_enable_check(IRQn_Type IRQn);
+
+/**
+ * @brief Function disables NVIC interrupt
+ *
+ * @param[in] IRQn Interrupt id
+ */
+__STATIC_INLINE void nrf_drv_common_irq_disable(IRQn_Type IRQn);
+
+/**
+ * @brief Convert bit position to event code
+ *
+ * Function for converting the bit position in INTEN register to event code
+ * that is equivalent to the offset of the event register from the beginning
+ * of peripheral instance.
+ *
+ * For example the result of this function can be casted directly to
+ * the types like @ref nrf_twis_event_t or @ref nrf_rng_event_t
+ *
+ * @param bit Bit position in INTEN register
+ * @return Event code to be casted to the right enum type or to be used in functions like
+ * @ref nrf_rng_event_get
+ *
+ * @sa nrf_drv_event_to_bitpos
+ */
+__STATIC_INLINE uint32_t nrf_drv_bitpos_to_event(uint32_t bit);
+
+/**
+ * @brief Convert event code to bit position
+ *
+ * This function can be used to get bit position in INTEN register from event code.
+ *
+ * @param event Event code that may be casted from enum values from types like
+ * @ref nrf_twis_event_t or @ref nrf_rng_event_t
+ * @return Bit position in INTEN register that corresponds to the given code.
+ *
+ * @sa nrf_drv_bitpos_to_event
+ */
+__STATIC_INLINE uint32_t nrf_drv_event_to_bitpos(uint32_t event);
+
+/**
+ * @brief Get interrupt number connected with given instance
+ *
+ * Function returns interrupt number for a given instance of any peripheral.
+ * @param[in] pinst Pointer to peripheral registry
+ * @return Interrupt number
+ */
+__STATIC_INLINE IRQn_Type nrf_drv_get_IRQn(void const * const pinst);
+
+#if NRF_MODULE_ENABLED(CLOCK) || NRF_MODULE_ENABLED(POWER)
+/**
+ * @brief Enable and setup power clock IRQ
+ *
+ * This function would be called from @ref nrf_drv_clock and @ref nrf_drv_power
+ * to enable related interrupt.
+ * This function avoids multiple interrupt configuration.
+ *
+ * @note
+ * This function is aviable only if @ref nrf_drv_clock or @ref nrf_drv_power
+ * module is enabled.
+ *
+ * @note
+ * If both @ref nrf_drv_clock and @ref nrf_drv_power modules are enabled,
+ * during the compilation the check is made that
+ * @ref CLOCK_CONFIG_IRQ_PRIORITY equals @ref POWER_CONFIG_IRQ_PRIORITY.
+ *
+ * @sa nrf_drv_common_power_irq_disable
+ * @sa nrf_drv_common_clock_irq_disable
+ */
+__STATIC_INLINE void nrf_drv_common_power_clock_irq_init(void);
+#endif
+
+/**
+ * @brief Check if given object is in RAM
+ *
+ * Function for analyzing if given location is placed in RAM.
+ * This function is used to determine if we have address that can be supported by EasyDMA.
+ * @param[in] ptr Pointer to the object
+ * @retval true Object is located in RAM
+ * @retval false Object is not located in RAM
+ */
+__STATIC_INLINE bool nrf_drv_is_in_RAM(void const * const ptr);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE bool nrf_drv_common_irq_enable_check(IRQn_Type IRQn)
+{
+ return 0 != (NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] &
+ (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)));
+}
+
+__STATIC_INLINE void nrf_drv_common_irq_disable(IRQn_Type IRQn)
+{
+ NVIC_DisableIRQ(IRQn);
+}
+
+__STATIC_INLINE uint32_t nrf_drv_bitpos_to_event(uint32_t bit)
+{
+ return NRF_DRV_COMMON_EVREGS_OFFSET + bit * sizeof(uint32_t);
+}
+
+__STATIC_INLINE uint32_t nrf_drv_event_to_bitpos(uint32_t event)
+{
+ return (event - NRF_DRV_COMMON_EVREGS_OFFSET) / sizeof(uint32_t);
+}
+
+__STATIC_INLINE IRQn_Type nrf_drv_get_IRQn(void const * const pinst)
+{
+ uint8_t ret = (uint8_t)((uint32_t)pinst>>12U);
+ return (IRQn_Type) ret;
+}
+
+#if NRF_MODULE_ENABLED(CLOCK) || NRF_MODULE_ENABLED(POWER)
+__STATIC_INLINE void nrf_drv_common_power_clock_irq_init(void)
+{
+ if (!nrf_drv_common_irq_enable_check(POWER_CLOCK_IRQn))
+ {
+ nrf_drv_common_irq_enable(
+ POWER_CLOCK_IRQn,
+#if NRF_DRV_COMMON_POWER_CLOCK_ISR
+ #if CLOCK_CONFIG_IRQ_PRIORITY != POWER_CONFIG_IRQ_PRIORITY
+ #error CLOCK_CONFIG_IRQ_PRIORITY and POWER_CONFIG_IRQ_PRIORITY have to be the same.
+ #endif
+ CLOCK_CONFIG_IRQ_PRIORITY
+#elif NRF_MODULE_ENABLED(CLOCK)
+ CLOCK_CONFIG_IRQ_PRIORITY
+#elif NRF_MODULE_ENABLED(POWER)
+ POWER_CONFIG_IRQ_PRIORITY
+#endif
+ );
+ }
+}
+#endif
+
+__STATIC_INLINE bool nrf_drv_is_in_RAM(void const * const ptr)
+{
+ return ((((uintptr_t)ptr) & 0xE0000000u) == 0x20000000u);
+}
+
+#endif // SUPPRESS_INLINE_IMPLEMENTATION
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_DRV_COMMON_H__
+
+/** @} */
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/delay/nrf_delay.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/delay/nrf_delay.h
new file mode 100644
index 000000000..0a62f7db2
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/delay/nrf_delay.h
@@ -0,0 +1,269 @@
+/**
+ * Copyright (c) 2011 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_DELAY_H
+#define _NRF_DELAY_H
+
+#include "nrf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CLOCK_FREQ_16MHz (16000000UL)
+
+#ifdef NRF52_SERIES
+ #define CPU_FREQ_64MHz
+#endif
+
+/**
+ * @brief Function for delaying execution for number of microseconds.
+ *
+ * @note NRF52 has instruction cache and because of that delay is not precise.
+ *
+ * @param number_of_us
+ *
+ */
+/*lint -e{438, 522, 40, 10, 563} */
+__STATIC_INLINE void nrf_delay_us(uint32_t number_of_us);
+
+
+/**
+ * @brief Function for delaying execution for number of miliseconds.
+ *
+ * @note NRF52 has instruction cache and because of that delay is not precise.
+ *
+ * @note Function internally calls @ref nrf_delay_us so the maximum delay is the
+ * same as in case of @ref nrf_delay_us, approx. 71 minutes.
+ *
+ * @param number_of_ms
+ *
+ */
+
+/*lint -e{438, 522, 40, 10, 563} */
+__STATIC_INLINE void nrf_delay_ms(uint32_t number_of_ms);
+
+#if defined ( __CC_ARM )
+__STATIC_INLINE void nrf_delay_us(uint32_t number_of_us)
+{
+ if (!number_of_us)
+ return;
+__asm
+ {
+loop:
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ CMP SystemCoreClock, CLOCK_FREQ_16MHz
+ BEQ cond
+ NOP
+#ifdef CPU_FREQ_64MHz
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+#endif //CPU_FREQ_64MHz
+cond:
+ SUBS number_of_us, #1
+ BNE loop
+ }
+}
+
+#elif defined ( _WIN32 ) || defined ( __unix ) || defined( __APPLE__ )
+
+
+#ifndef CUSTOM_NRF_DELAY_US
+__STATIC_INLINE void nrf_delay_us(uint32_t number_of_us)
+{}
+#endif
+
+#elif defined ( __GNUC__ ) || ( __ICCARM__ )
+
+__STATIC_INLINE void nrf_delay_us(uint32_t number_of_us)
+{
+ const uint32_t clock16MHz = CLOCK_FREQ_16MHz;
+ if (number_of_us)
+ {
+__ASM volatile (
+#if ( defined(__GNUC__) && (__CORTEX_M == (0x00U) ) )
+ ".syntax unified\n"
+#endif
+"1:\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " CMP %[SystemCoreClock], %[clock16MHz]\n"
+ " BEQ.N 2f\n"
+ " NOP\n"
+#ifdef CPU_FREQ_64MHz
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+ " NOP\n"
+#endif //CPU_FREQ_64MHz
+"2:\n"
+ " SUBS %[number_of_us], %[number_of_us], #1\n"
+ " BNE.N 1b\n"
+#if ( defined(__GNUC__) && (__CORTEX_M == (0x00U) ) )
+ ".syntax divided\n"
+#endif
+#if ( __CORTEX_M == (0x00U) )
+ // The SUBS instruction in Cortex-M0 is available only in 16-bit encoding,
+ // hence it requires a "lo" register (r0-r7) as an operand.
+ : [number_of_us] "=l" (number_of_us)
+#else
+ : [number_of_us] "=r" (number_of_us)
+#endif
+ : [SystemCoreClock] "r" (SystemCoreClock),
+ [clock16MHz] "r" (clock16MHz),
+ "[number_of_us]" (number_of_us)
+ : "cc"
+ );
+ }
+}
+#endif
+
+__STATIC_INLINE void nrf_delay_ms(uint32_t number_of_ms)
+{
+ nrf_delay_us(1000*number_of_ms);
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_clock.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_clock.h
new file mode 100644
index 000000000..50a7271a9
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_clock.h
@@ -0,0 +1,401 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_CLOCK_H__
+#define NRF_CLOCK_H__
+
+#include <stddef.h>
+#include <stdbool.h>
+
+#include "nrf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup nrf_clock_hal Clock HAL
+ * @{
+ * @ingroup nrf_clock
+ * @brief Hardware access layer for managing the low-frequency clock (LFCLK) and the high-frequency clock (HFCLK).
+ */
+
+#define NRF_CLOCK_TASK_TRIGGER (1UL)
+#define NRF_CLOCK_EVENT_CLEAR (0UL)
+
+/**
+ * @brief Low-frequency clock sources.
+ * @details Used by LFCLKSRC, LFCLKSTAT, and LFCLKSRCCOPY registers.
+ */
+typedef enum
+{
+ NRF_CLOCK_LFCLK_RC = CLOCK_LFCLKSRC_SRC_RC, /**< Internal 32 kHz RC oscillator. */
+ NRF_CLOCK_LFCLK_Xtal = CLOCK_LFCLKSRC_SRC_Xtal, /**< External 32 kHz crystal. */
+ NRF_CLOCK_LFCLK_Synth = CLOCK_LFCLKSRC_SRC_Synth /**< Internal 32 kHz synthesizer from HFCLK system clock. */
+} nrf_clock_lfclk_t;
+
+/**
+ * @brief High-frequency clock sources.
+ */
+typedef enum
+{
+ NRF_CLOCK_HFCLK_LOW_ACCURACY = CLOCK_HFCLKSTAT_SRC_RC, /**< Internal 16 MHz RC oscillator. */
+ NRF_CLOCK_HFCLK_HIGH_ACCURACY = CLOCK_HFCLKSTAT_SRC_Xtal /**< External 16 MHz/32 MHz crystal oscillator. */
+} nrf_clock_hfclk_t;
+
+/**
+ * @brief Trigger status of task LFCLKSTART/HFCLKSTART.
+ * @details Used by LFCLKRUN and HFCLKRUN registers.
+ */
+typedef enum
+{
+ NRF_CLOCK_START_TASK_NOT_TRIGGERED = CLOCK_LFCLKRUN_STATUS_NotTriggered, /**< Task LFCLKSTART/HFCLKSTART has not been triggered. */
+ NRF_CLOCK_START_TASK_TRIGGERED = CLOCK_LFCLKRUN_STATUS_Triggered /**< Task LFCLKSTART/HFCLKSTART has been triggered. */
+} nrf_clock_start_task_status_t;
+
+/**
+ * @brief Interrupts.
+ */
+typedef enum
+{
+ NRF_CLOCK_INT_HF_STARTED_MASK = CLOCK_INTENSET_HFCLKSTARTED_Msk, /**< Interrupt on HFCLKSTARTED event. */
+ NRF_CLOCK_INT_LF_STARTED_MASK = CLOCK_INTENSET_LFCLKSTARTED_Msk, /**< Interrupt on LFCLKSTARTED event. */
+ NRF_CLOCK_INT_DONE_MASK = CLOCK_INTENSET_DONE_Msk, /**< Interrupt on DONE event. */
+ NRF_CLOCK_INT_CTTO_MASK = CLOCK_INTENSET_CTTO_Msk /**< Interrupt on CTTO event. */
+} nrf_clock_int_mask_t;
+
+/**
+ * @brief Tasks.
+ *
+ * @details The NRF_CLOCK_TASK_LFCLKSTOP task cannot be set when the low-frequency clock is not running.
+ * The NRF_CLOCK_TASK_HFCLKSTOP task cannot be set when the high-frequency clock is not running.
+ */
+typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
+{
+ NRF_CLOCK_TASK_HFCLKSTART = offsetof(NRF_CLOCK_Type, TASKS_HFCLKSTART), /**< Start HFCLK clock source.*/
+ NRF_CLOCK_TASK_HFCLKSTOP = offsetof(NRF_CLOCK_Type, TASKS_HFCLKSTOP), /**< Stop HFCLK clock source.*/
+ NRF_CLOCK_TASK_LFCLKSTART = offsetof(NRF_CLOCK_Type, TASKS_LFCLKSTART), /**< Start LFCLK clock source.*/
+ NRF_CLOCK_TASK_LFCLKSTOP = offsetof(NRF_CLOCK_Type, TASKS_LFCLKSTOP), /**< Stop LFCLK clock source.*/
+ NRF_CLOCK_TASK_CAL = offsetof(NRF_CLOCK_Type, TASKS_CAL), /**< Start calibration of LFCLK RC oscillator.*/
+ NRF_CLOCK_TASK_CTSTART = offsetof(NRF_CLOCK_Type, TASKS_CTSTART), /**< Start calibration timer.*/
+ NRF_CLOCK_TASK_CTSTOP = offsetof(NRF_CLOCK_Type, TASKS_CTSTOP) /**< Stop calibration timer.*/
+} nrf_clock_task_t; /*lint -restore */
+
+/**
+ * @brief Events.
+ */
+typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
+{
+ NRF_CLOCK_EVENT_HFCLKSTARTED = offsetof(NRF_CLOCK_Type, EVENTS_HFCLKSTARTED), /**< HFCLK oscillator started.*/
+ NRF_CLOCK_EVENT_LFCLKSTARTED = offsetof(NRF_CLOCK_Type, EVENTS_LFCLKSTARTED), /**< LFCLK oscillator started.*/
+ NRF_CLOCK_EVENT_DONE = offsetof(NRF_CLOCK_Type, EVENTS_DONE), /**< Calibration of LFCLK RC oscillator completed.*/
+ NRF_CLOCK_EVENT_CTTO = offsetof(NRF_CLOCK_Type, EVENTS_CTTO) /**< Calibration timer time-out.*/
+} nrf_clock_event_t; /*lint -restore */
+
+/**
+ * @brief Function for enabling a specific interrupt.
+ *
+ * @param[in] int_mask Interrupt.
+ */
+__STATIC_INLINE void nrf_clock_int_enable(uint32_t int_mask);
+
+/**
+ * @brief Function for disabling a specific interrupt.
+ *
+ * @param[in] int_mask Interrupt.
+ */
+__STATIC_INLINE void nrf_clock_int_disable(uint32_t int_mask);
+
+/**
+ * @brief Function for retrieving the state of a specific interrupt.
+ *
+ * @param[in] int_mask Interrupt.
+ *
+ * @retval true If the interrupt is enabled.
+ * @retval false If the interrupt is not enabled.
+ */
+__STATIC_INLINE bool nrf_clock_int_enable_check(nrf_clock_int_mask_t int_mask);
+
+/**
+ * @brief Function for retrieving the address of a specific task.
+ * @details This function can be used by the PPI module.
+ *
+ * @param[in] task Task.
+ *
+ * @return Address of the requested task register.
+ */
+__STATIC_INLINE uint32_t nrf_clock_task_address_get(nrf_clock_task_t task);
+
+/**
+ * @brief Function for setting a specific task.
+ *
+ * @param[in] task Task.
+ */
+__STATIC_INLINE void nrf_clock_task_trigger(nrf_clock_task_t task);
+
+/**
+ * @brief Function for retrieving the address of a specific event.
+ * @details This function can be used by the PPI module.
+ *
+ * @param[in] event Event.
+ *
+ * @return Address of the requested event register.
+ */
+__STATIC_INLINE uint32_t nrf_clock_event_address_get(nrf_clock_event_t event);
+
+/**
+ * @brief Function for clearing a specific event.
+ *
+ * @param[in] event Event.
+ */
+__STATIC_INLINE void nrf_clock_event_clear(nrf_clock_event_t event);
+
+/**
+ * @brief Function for retrieving the state of a specific event.
+ *
+ * @param[in] event Event.
+ *
+ * @retval true If the event is set.
+ * @retval false If the event is not set.
+ */
+__STATIC_INLINE bool nrf_clock_event_check(nrf_clock_event_t event);
+
+/**
+ * @brief Function for changing the low-frequency clock source.
+ * @details This function cannot be called when the low-frequency clock is running.
+ *
+ * @param[in] source New low-frequency clock source.
+ *
+ */
+__STATIC_INLINE void nrf_clock_lf_src_set(nrf_clock_lfclk_t source);
+
+/**
+ * @brief Function for retrieving the selected source for the low-frequency clock.
+ *
+ * @retval NRF_CLOCK_LFCLK_RC If the internal 32 kHz RC oscillator is the selected source for the low-frequency clock.
+ * @retval NRF_CLOCK_LFCLK_Xtal If an external 32 kHz crystal oscillator is the selected source for the low-frequency clock.
+ * @retval NRF_CLOCK_LFCLK_Synth If the internal 32 kHz synthesizer from the HFCLK is the selected source for the low-frequency clock.
+ */
+__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_src_get(void);
+
+/**
+ * @brief Function for retrieving the active source of the low-frequency clock.
+ *
+ * @retval NRF_CLOCK_LFCLK_RC If the internal 32 kHz RC oscillator is the active source of the low-frequency clock.
+ * @retval NRF_CLOCK_LFCLK_Xtal If an external 32 kHz crystal oscillator is the active source of the low-frequency clock.
+ * @retval NRF_CLOCK_LFCLK_Synth If the internal 32 kHz synthesizer from the HFCLK is the active source of the low-frequency clock.
+ */
+__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_actv_src_get(void);
+
+/**
+ * @brief Function for retrieving the clock source for the LFCLK clock when the task LKCLKSTART is triggered.
+ *
+ * @retval NRF_CLOCK_LFCLK_RC If the internal 32 kHz RC oscillator is running and generating the LFCLK clock.
+ * @retval NRF_CLOCK_LFCLK_Xtal If an external 32 kHz crystal oscillator is running and generating the LFCLK clock.
+ * @retval NRF_CLOCK_LFCLK_Synth If the internal 32 kHz synthesizer from the HFCLK is running and generating the LFCLK clock.
+ */
+__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_srccopy_get(void);
+
+/**
+ * @brief Function for retrieving the state of the LFCLK clock.
+ *
+ * @retval false If the LFCLK clock is not running.
+ * @retval true If the LFCLK clock is running.
+ */
+__STATIC_INLINE bool nrf_clock_lf_is_running(void);
+
+/**
+ * @brief Function for retrieving the trigger status of the task LFCLKSTART.
+ *
+ * @retval NRF_CLOCK_START_TASK_NOT_TRIGGERED If the task LFCLKSTART has not been triggered.
+ * @retval NRF_CLOCK_START_TASK_TRIGGERED If the task LFCLKSTART has been triggered.
+ */
+__STATIC_INLINE nrf_clock_start_task_status_t nrf_clock_lf_start_task_status_get(void);
+
+/**
+ * @brief Function for retrieving the active source of the high-frequency clock.
+ *
+ * @retval NRF_CLOCK_HFCLK_LOW_ACCURACY If the internal 16 MHz RC oscillator is the active source of the high-frequency clock.
+ * @retval NRF_CLOCK_HFCLK_HIGH_ACCURACY If an external 16 MHz/32 MHz crystal oscillator is the active source of the high-frequency clock.
+ */
+__STATIC_INLINE nrf_clock_hfclk_t nrf_clock_hf_src_get(void);
+
+/**
+ * @brief Function for retrieving the state of the HFCLK clock.
+ *
+ * @param[in] clk_src Clock source to be checked.
+ *
+ * @retval false If the HFCLK clock is not running.
+ * @retval true If the HFCLK clock is running.
+ */
+__STATIC_INLINE bool nrf_clock_hf_is_running(nrf_clock_hfclk_t clk_src);
+
+/**
+ * @brief Function for retrieving the trigger status of the task HFCLKSTART.
+ *
+ * @retval NRF_CLOCK_START_TASK_NOT_TRIGGERED If the task HFCLKSTART has not been triggered.
+ * @retval NRF_CLOCK_START_TASK_TRIGGERED If the task HFCLKSTART has been triggered.
+ */
+__STATIC_INLINE nrf_clock_start_task_status_t nrf_clock_hf_start_task_status_get(void);
+
+/**
+ * @brief Function for changing the calibration timer interval.
+ *
+ * @param[in] interval New calibration timer interval in 0.25 s resolution (range: 0.25 seconds to 31.75 seconds).
+ */
+__STATIC_INLINE void nrf_clock_cal_timer_timeout_set(uint32_t interval);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE void nrf_clock_int_enable(uint32_t int_mask)
+{
+ NRF_CLOCK->INTENSET = int_mask;
+}
+
+__STATIC_INLINE void nrf_clock_int_disable(uint32_t int_mask)
+{
+ NRF_CLOCK->INTENCLR = int_mask;
+}
+
+__STATIC_INLINE bool nrf_clock_int_enable_check(nrf_clock_int_mask_t int_mask)
+{
+ return (bool)(NRF_CLOCK->INTENCLR & int_mask);
+}
+
+__STATIC_INLINE uint32_t nrf_clock_task_address_get(nrf_clock_task_t task)
+{
+ return ((uint32_t )NRF_CLOCK + task);
+}
+
+__STATIC_INLINE void nrf_clock_task_trigger(nrf_clock_task_t task)
+{
+ *((volatile uint32_t *)((uint8_t *)NRF_CLOCK + task)) = NRF_CLOCK_TASK_TRIGGER;
+}
+
+__STATIC_INLINE uint32_t nrf_clock_event_address_get(nrf_clock_event_t event)
+{
+ return ((uint32_t)NRF_CLOCK + event);
+}
+
+__STATIC_INLINE void nrf_clock_event_clear(nrf_clock_event_t event)
+{
+ *((volatile uint32_t *)((uint8_t *)NRF_CLOCK + event)) = NRF_CLOCK_EVENT_CLEAR;
+#if __CORTEX_M == 0x04
+ volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_CLOCK + event));
+ (void)dummy;
+#endif
+}
+
+__STATIC_INLINE bool nrf_clock_event_check(nrf_clock_event_t event)
+{
+ return (bool)*((volatile uint32_t *)((uint8_t *)NRF_CLOCK + event));
+}
+
+__STATIC_INLINE void nrf_clock_lf_src_set(nrf_clock_lfclk_t source)
+{
+ NRF_CLOCK->LFCLKSRC =
+ (uint32_t)((source << CLOCK_LFCLKSRC_SRC_Pos) & CLOCK_LFCLKSRC_SRC_Msk);
+}
+
+__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_src_get(void)
+{
+ return (nrf_clock_lfclk_t)((NRF_CLOCK->LFCLKSRC &
+ CLOCK_LFCLKSRC_SRC_Msk) >> CLOCK_LFCLKSRC_SRC_Pos);
+}
+
+__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_actv_src_get(void)
+{
+ return (nrf_clock_lfclk_t)((NRF_CLOCK->LFCLKSTAT &
+ CLOCK_LFCLKSTAT_SRC_Msk) >> CLOCK_LFCLKSTAT_SRC_Pos);
+}
+
+__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_srccopy_get(void)
+{
+ return (nrf_clock_lfclk_t)((NRF_CLOCK->LFCLKSRCCOPY &
+ CLOCK_LFCLKSRCCOPY_SRC_Msk) >> CLOCK_LFCLKSRCCOPY_SRC_Pos);
+}
+
+__STATIC_INLINE bool nrf_clock_lf_is_running(void)
+{
+ return ((NRF_CLOCK->LFCLKSTAT &
+ CLOCK_LFCLKSTAT_STATE_Msk) >> CLOCK_LFCLKSTAT_STATE_Pos);
+}
+
+__STATIC_INLINE nrf_clock_start_task_status_t nrf_clock_lf_start_task_status_get(void)
+{
+ return (nrf_clock_start_task_status_t)((NRF_CLOCK->LFCLKRUN &
+ CLOCK_LFCLKRUN_STATUS_Msk) >>
+ CLOCK_LFCLKRUN_STATUS_Pos);
+}
+
+__STATIC_INLINE nrf_clock_hfclk_t nrf_clock_hf_src_get(void)
+{
+ return (nrf_clock_hfclk_t)((NRF_CLOCK->HFCLKSTAT &
+ CLOCK_HFCLKSTAT_SRC_Msk) >> CLOCK_HFCLKSTAT_SRC_Pos);
+}
+
+__STATIC_INLINE bool nrf_clock_hf_is_running(nrf_clock_hfclk_t clk_src)
+{
+ return (NRF_CLOCK->HFCLKSTAT & (CLOCK_HFCLKSTAT_STATE_Msk | CLOCK_HFCLKSTAT_SRC_Msk)) ==
+ (CLOCK_HFCLKSTAT_STATE_Msk | (clk_src << CLOCK_HFCLKSTAT_SRC_Pos));
+}
+
+__STATIC_INLINE nrf_clock_start_task_status_t nrf_clock_hf_start_task_status_get(void)
+{
+ return (nrf_clock_start_task_status_t)((NRF_CLOCK->HFCLKRUN &
+ CLOCK_HFCLKRUN_STATUS_Msk) >>
+ CLOCK_HFCLKRUN_STATUS_Pos);
+}
+
+__STATIC_INLINE void nrf_clock_cal_timer_timeout_set(uint32_t interval)
+{
+ NRF_CLOCK->CTIV = ((interval << CLOCK_CTIV_CTIV_Pos) & CLOCK_CTIV_CTIV_Msk);
+}
+
+#endif // SUPPRESS_INLINE_IMPLEMENTATION
+
+/**
+ *@}
+ **/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_CLOCK_H__
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_comp.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_comp.h
new file mode 100644
index 000000000..31e2ff3cd
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_comp.h
@@ -0,0 +1,518 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ * @brief COMP HAL API.
+ */
+
+#ifndef NRF_COMP_H_
+#define NRF_COMP_H_
+
+/**
+ * @defgroup nrf_comp_hal COMP HAL
+ * @{
+ * @ingroup nrf_comp
+ * @brief @tagAPI52 Hardware access layer for managing the Comparator (COMP).
+ */
+
+#include "nrf.h"
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @enum nrf_comp_input_t
+ * @brief COMP analog pin selection.
+ */
+typedef enum
+{
+ NRF_COMP_INPUT_0 = COMP_PSEL_PSEL_AnalogInput0, /*!< AIN0 selected as analog input. */
+ NRF_COMP_INPUT_1 = COMP_PSEL_PSEL_AnalogInput1, /*!< AIN1 selected as analog input. */
+ NRF_COMP_INPUT_2 = COMP_PSEL_PSEL_AnalogInput2, /*!< AIN2 selected as analog input. */
+ NRF_COMP_INPUT_3 = COMP_PSEL_PSEL_AnalogInput3, /*!< AIN3 selected as analog input. */
+ NRF_COMP_INPUT_4 = COMP_PSEL_PSEL_AnalogInput4, /*!< AIN4 selected as analog input. */
+ NRF_COMP_INPUT_5 = COMP_PSEL_PSEL_AnalogInput5, /*!< AIN5 selected as analog input. */
+ NRF_COMP_INPUT_6 = COMP_PSEL_PSEL_AnalogInput6, /*!< AIN6 selected as analog input. */
+#if defined (COMP_PSEL_PSEL_AnalogInput7) || defined (__SDK_DOXYGEN__)
+ NRF_COMP_INPUT_7 = COMP_PSEL_PSEL_AnalogInput7, /*!< AIN7 selected as analog input. */
+#endif
+#if defined (COMP_PSEL_PSEL_VddDiv2) || defined (__SDK_DOXYGEN__)
+ NRF_COMP_VDD_DIV2 = COMP_PSEL_PSEL_VddDiv2, /*!< VDD/2 selected as analog input. */
+#endif
+}nrf_comp_input_t;
+
+/**
+ * @enum nrf_comp_ref_t
+ * @brief COMP reference selection.
+ */
+typedef enum
+{
+ NRF_COMP_REF_Int1V2 = COMP_REFSEL_REFSEL_Int1V2, /*!< VREF = internal 1.2 V reference (VDD >= 1.7 V). */
+ NRF_COMP_REF_Int1V8 = COMP_REFSEL_REFSEL_Int1V8, /*!< VREF = internal 1.8 V reference (VDD >= VREF + 0.2 V). */
+ NRF_COMP_REF_Int2V4 = COMP_REFSEL_REFSEL_Int2V4, /*!< VREF = internal 2.4 V reference (VDD >= VREF + 0.2 V). */
+ NRF_COMP_REF_VDD = COMP_REFSEL_REFSEL_VDD, /*!< VREF = VDD. */
+ NRF_COMP_REF_ARef = COMP_REFSEL_REFSEL_ARef /*!< VREF = AREF (VDD >= VREF >= AREFMIN). */
+}nrf_comp_ref_t;
+
+/**
+ * @enum nrf_comp_ext_ref_t
+ * @brief COMP external analog reference selection.
+ */
+typedef enum
+{
+ NRF_COMP_EXT_REF_0 = COMP_EXTREFSEL_EXTREFSEL_AnalogReference0, /*!< Use AIN0 as external analog reference. */
+ NRF_COMP_EXT_REF_1 = COMP_EXTREFSEL_EXTREFSEL_AnalogReference1 /*!< Use AIN1 as external analog reference. */
+}nrf_comp_ext_ref_t;
+
+/**
+ * @brief COMP THDOWN and THUP values that are used to calculate the threshold voltages VDOWN and VUP.
+ */
+typedef struct
+{
+ uint8_t th_down; /*!< THDOWN value. */
+ uint8_t th_up; /*!< THUP value. */
+}nrf_comp_th_t;
+
+/**
+ * @enum nrf_comp_main_mode_t
+ * @brief COMP main operation mode.
+ */
+typedef enum
+{
+ NRF_COMP_MAIN_MODE_SE = COMP_MODE_MAIN_SE, /*!< Single ended mode. */
+ NRF_COMP_MAIN_MODE_Diff = COMP_MODE_MAIN_Diff /*!< Differential mode. */
+}nrf_comp_main_mode_t;
+
+/**
+ * @enum nrf_comp_sp_mode_t
+ * @brief COMP speed and power mode.
+ */
+typedef enum
+{
+ NRF_COMP_SP_MODE_Low = COMP_MODE_SP_Low, /*!< Low power mode. */
+ NRF_COMP_SP_MODE_Normal = COMP_MODE_SP_Normal, /*!< Normal mode. */
+ NRF_COMP_SP_MODE_High = COMP_MODE_SP_High /*!< High speed mode. */
+}nrf_comp_sp_mode_t;
+
+/**
+ * @enum nrf_comp_hyst_t
+ * @brief COMP comparator hysteresis.
+ */
+typedef enum
+{
+ NRF_COMP_HYST_NoHyst = COMP_HYST_HYST_NoHyst, /*!< Comparator hysteresis disabled. */
+ NRF_COMP_HYST_50mV = COMP_HYST_HYST_Hyst50mV /*!< Comparator hysteresis enabled. */
+}nrf_comp_hyst_t;
+
+#if defined (COMP_ISOURCE_ISOURCE_Msk)
+/**
+ * @brief COMP current source selection on analog input.
+ */
+typedef enum
+{
+ NRF_COMP_ISOURCE_Off = COMP_ISOURCE_ISOURCE_Off, /*!< Current source disabled. */
+ NRF_COMP_ISOURCE_Ien2uA5 = COMP_ISOURCE_ISOURCE_Ien2mA5, /*!< Current source enabled (+/- 2.5 uA). */
+ NRF_COMP_ISOURCE_Ien5uA = COMP_ISOURCE_ISOURCE_Ien5mA, /*!< Current source enabled (+/- 5 uA). */
+ NRF_COMP_ISOURCE_Ien10uA = COMP_ISOURCE_ISOURCE_Ien10mA /*!< Current source enabled (+/- 10 uA). */
+}nrf_isource_t;
+#endif
+
+/**
+ * @enum nrf_comp_task_t
+ * @brief COMP tasks.
+ */
+typedef enum
+{
+ /*lint -save -e30*/
+ NRF_COMP_TASK_START = offsetof(NRF_COMP_Type, TASKS_START), /*!< COMP start sampling task. */
+ NRF_COMP_TASK_STOP = offsetof(NRF_COMP_Type, TASKS_STOP), /*!< COMP stop sampling task. */
+ NRF_COMP_TASK_SAMPLE = offsetof(NRF_COMP_Type, TASKS_SAMPLE) /*!< Sample comparator value. */
+ /*lint -restore*/
+}nrf_comp_task_t;
+
+/**
+ * @enum nrf_comp_event_t
+ * @brief COMP events.
+ */
+typedef enum
+{
+ /*lint -save -e30*/
+ NRF_COMP_EVENT_READY = offsetof(NRF_COMP_Type, EVENTS_READY), /*!< COMP is ready and output is valid. */
+ NRF_COMP_EVENT_DOWN = offsetof(NRF_COMP_Type, EVENTS_DOWN), /*!< Input voltage crossed the threshold going down. */
+ NRF_COMP_EVENT_UP = offsetof(NRF_COMP_Type, EVENTS_UP), /*!< Input voltage crossed the threshold going up. */
+ NRF_COMP_EVENT_CROSS = offsetof(NRF_COMP_Type, EVENTS_CROSS) /*!< Input voltage crossed the threshold in any direction. */
+ /*lint -restore*/
+}nrf_comp_event_t;
+
+/**
+ * @brief COMP reference configuration.
+ */
+typedef struct
+{
+ nrf_comp_ref_t reference; /*!< COMP reference selection. */
+ nrf_comp_ext_ref_t external; /*!< COMP external analog reference selection. */
+}nrf_comp_ref_conf_t;
+
+
+/**
+ * @brief Function for enabling the COMP peripheral.
+ */
+__STATIC_INLINE void nrf_comp_enable(void);
+
+
+/**
+ * @brief Function for disabling the COMP peripheral.
+ */
+
+__STATIC_INLINE void nrf_comp_disable(void);
+
+/**
+ * @brief Function for checking if the COMP peripheral is enabled.
+ *
+ * @retval true If the COMP peripheral is enabled.
+ * @retval false If the COMP peripheral is not enabled.
+ */
+__STATIC_INLINE bool nrf_comp_enable_check(void);
+
+/**
+ * @brief Function for setting the reference source.
+ *
+ * @param[in] reference COMP reference selection.
+ */
+__STATIC_INLINE void nrf_comp_ref_set(nrf_comp_ref_t reference);
+
+
+/**
+ * @brief Function for setting the external analog reference source.
+ *
+ * @param[in] ext_ref COMP external analog reference selection.
+ */
+__STATIC_INLINE void nrf_comp_ext_ref_set(nrf_comp_ext_ref_t ext_ref);
+
+
+/**
+ * @brief Function for setting threshold voltages.
+ *
+ * @param[in] threshold COMP VDOWN and VUP thresholds.
+ */
+__STATIC_INLINE void nrf_comp_th_set(nrf_comp_th_t threshold);
+
+
+/**
+ * @brief Function for setting the main mode.
+ *
+ * @param[in] main_mode COMP main operation mode.
+ */
+__STATIC_INLINE void nrf_comp_main_mode_set(nrf_comp_main_mode_t main_mode);
+
+
+/**
+ * @brief Function for setting the speed mode.
+ *
+ * @param[in] speed_mode COMP speed and power mode.
+ */
+__STATIC_INLINE void nrf_comp_speed_mode_set(nrf_comp_sp_mode_t speed_mode);
+
+
+/**
+ * @brief Function for setting the hysteresis.
+ *
+ * @param[in] hyst COMP comparator hysteresis.
+ */
+__STATIC_INLINE void nrf_comp_hysteresis_set(nrf_comp_hyst_t hyst);
+
+#if defined (COMP_ISOURCE_ISOURCE_Msk)
+/**
+ * @brief Function for setting the current source on the analog input.
+ *
+ * @param[in] isource COMP current source selection on analog input.
+ */
+__STATIC_INLINE void nrf_comp_isource_set(nrf_isource_t isource);
+#endif
+
+/**
+ * @brief Function for selecting the active input of the COMP.
+ *
+ * @param[in] input Input to be selected.
+ */
+__STATIC_INLINE void nrf_comp_input_select(nrf_comp_input_t input);
+
+
+/**
+ * @brief Function for getting the last COMP compare result.
+ *
+ * @return The last compare result. If 0, then VIN+ < VIN-. If 1, then VIN+ > VIN-.
+ *
+ * @note If VIN+ == VIN-, the return value depends on the previous result.
+ */
+__STATIC_INLINE uint32_t nrf_comp_result_get(void);
+
+
+/**
+ * @brief Function for enabling interrupts from COMP.
+ *
+ * @param[in] comp_int_mask Mask of interrupts to be enabled.
+ *
+ * @sa nrf_comp_int_enable_check()
+ */
+__STATIC_INLINE void nrf_comp_int_enable(uint32_t comp_int_mask);
+
+/**
+ * @brief Function for disabling interrupts from COMP.
+ *
+ * @param[in] comp_int_mask Mask of interrupts to be disabled.
+ *
+ * @sa nrf_comp_int_enable_check()
+ */
+__STATIC_INLINE void nrf_comp_int_disable(uint32_t comp_int_mask);
+
+
+/**
+ * @brief Function for getting the enabled interrupts of COMP.
+ *
+ * @param[in] comp_int_mask Mask of interrupts to be checked.
+ *
+ * @retval true If any interrupts of the specified mask are enabled.
+ */
+__STATIC_INLINE bool nrf_comp_int_enable_check(uint32_t comp_int_mask);
+
+
+
+/**
+ * @brief Function for getting the address of a specific COMP task register.
+ *
+ * @param[in] comp_task COMP task.
+ *
+ * @return Address of the specified COMP task.
+ */
+__STATIC_INLINE uint32_t * nrf_comp_task_address_get(nrf_comp_task_t comp_task);
+
+
+/**
+ * @brief Function for getting the address of a specific COMP event register.
+ *
+ * @param[in] comp_event COMP event.
+ *
+ * @return Address of the specified COMP event.
+ */
+__STATIC_INLINE uint32_t * nrf_comp_event_address_get(nrf_comp_event_t comp_event);
+
+
+/**
+ * @brief Function for setting COMP shorts.
+ *
+ * @param[in] comp_short_mask COMP shorts by mask.
+ *
+ */
+__STATIC_INLINE void nrf_comp_shorts_enable(uint32_t comp_short_mask);
+
+
+/**
+ * @brief Function for clearing COMP shorts by mask.
+ *
+ * @param[in] comp_short_mask COMP shorts to be cleared.
+ *
+ */
+__STATIC_INLINE void nrf_comp_shorts_disable(uint32_t comp_short_mask);
+
+
+/**
+ * @brief Function for setting a specific COMP task.
+ *
+ * @param[in] comp_task COMP task to be set.
+ *
+ */
+__STATIC_INLINE void nrf_comp_task_trigger(nrf_comp_task_t comp_task);
+
+
+/**
+ * @brief Function for clearing a specific COMP event.
+ *
+ * @param[in] comp_event COMP event to be cleared.
+ *
+ */
+__STATIC_INLINE void nrf_comp_event_clear(nrf_comp_event_t comp_event);
+
+
+/**
+ * @brief Function for getting the state of a specific COMP event.
+ *
+ * @retval true If the specified COMP event is active.
+ *
+ */
+__STATIC_INLINE bool nrf_comp_event_check(nrf_comp_event_t comp_event);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE void nrf_comp_enable(void)
+{
+ NRF_COMP->ENABLE = (COMP_ENABLE_ENABLE_Enabled << COMP_ENABLE_ENABLE_Pos);
+}
+
+__STATIC_INLINE void nrf_comp_disable(void)
+{
+ NRF_COMP->ENABLE = (COMP_ENABLE_ENABLE_Disabled << COMP_ENABLE_ENABLE_Pos);
+}
+
+__STATIC_INLINE bool nrf_comp_enable_check(void)
+{
+ return ((NRF_COMP->ENABLE) & COMP_ENABLE_ENABLE_Enabled);
+}
+
+__STATIC_INLINE void nrf_comp_ref_set(nrf_comp_ref_t reference)
+{
+ NRF_COMP->REFSEL = (reference << COMP_REFSEL_REFSEL_Pos);
+}
+
+__STATIC_INLINE void nrf_comp_ext_ref_set(nrf_comp_ext_ref_t ext_ref)
+{
+ NRF_COMP->EXTREFSEL = (ext_ref << COMP_EXTREFSEL_EXTREFSEL_Pos);
+}
+
+__STATIC_INLINE void nrf_comp_th_set(nrf_comp_th_t threshold)
+{
+ NRF_COMP->TH =
+ ((threshold.th_down << COMP_TH_THDOWN_Pos) & COMP_TH_THDOWN_Msk) |
+ ((threshold.th_up << COMP_TH_THUP_Pos) & COMP_TH_THUP_Msk);
+}
+
+__STATIC_INLINE void nrf_comp_main_mode_set(nrf_comp_main_mode_t main_mode)
+{
+ NRF_COMP->MODE |= (main_mode << COMP_MODE_MAIN_Pos);
+}
+
+__STATIC_INLINE void nrf_comp_speed_mode_set(nrf_comp_sp_mode_t speed_mode)
+{
+ NRF_COMP->MODE |= (speed_mode << COMP_MODE_SP_Pos);
+}
+
+__STATIC_INLINE void nrf_comp_hysteresis_set(nrf_comp_hyst_t hyst)
+{
+ NRF_COMP->HYST = (hyst << COMP_HYST_HYST_Pos) & COMP_HYST_HYST_Msk;
+}
+
+#if defined (COMP_ISOURCE_ISOURCE_Msk)
+__STATIC_INLINE void nrf_comp_isource_set(nrf_isource_t isource)
+{
+ NRF_COMP->ISOURCE = (isource << COMP_ISOURCE_ISOURCE_Pos) & COMP_ISOURCE_ISOURCE_Msk;
+}
+#endif
+
+__STATIC_INLINE void nrf_comp_input_select(nrf_comp_input_t input)
+{
+ NRF_COMP->PSEL = ((uint32_t)input << COMP_PSEL_PSEL_Pos);
+}
+
+__STATIC_INLINE uint32_t nrf_comp_result_get(void)
+{
+ return (uint32_t)NRF_COMP->RESULT;
+}
+
+__STATIC_INLINE void nrf_comp_int_enable(uint32_t comp_int_mask)
+{
+ NRF_COMP->INTENSET = comp_int_mask;
+}
+
+__STATIC_INLINE void nrf_comp_int_disable(uint32_t comp_int_mask)
+{
+ NRF_COMP->INTENCLR = comp_int_mask;
+}
+
+__STATIC_INLINE bool nrf_comp_int_enable_check(uint32_t comp_int_mask)
+{
+ return (NRF_COMP->INTENSET & comp_int_mask); // when read this register will return the value of INTEN.
+}
+
+__STATIC_INLINE uint32_t * nrf_comp_task_address_get(nrf_comp_task_t comp_task)
+{
+ return (uint32_t *)((uint8_t *)NRF_COMP + (uint32_t)comp_task);
+}
+
+__STATIC_INLINE uint32_t * nrf_comp_event_address_get(nrf_comp_event_t comp_event)
+{
+ return (uint32_t *)((uint8_t *)NRF_COMP + (uint32_t)comp_event);
+}
+
+__STATIC_INLINE void nrf_comp_shorts_enable(uint32_t comp_short_mask)
+{
+ NRF_COMP->SHORTS |= comp_short_mask;
+}
+
+__STATIC_INLINE void nrf_comp_shorts_disable(uint32_t comp_short_mask)
+{
+ NRF_COMP->SHORTS &= ~comp_short_mask;
+}
+
+__STATIC_INLINE void nrf_comp_task_trigger(nrf_comp_task_t comp_task)
+{
+ *( (volatile uint32_t *)( (uint8_t *)NRF_COMP + comp_task) ) = 1;
+}
+
+__STATIC_INLINE void nrf_comp_event_clear(nrf_comp_event_t comp_event)
+{
+ *( (volatile uint32_t *)( (uint8_t *)NRF_COMP + (uint32_t)comp_event) ) = 0;
+#if __CORTEX_M == 0x04
+ volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_COMP + (uint32_t)comp_event));
+ (void)dummy;
+#endif
+}
+
+__STATIC_INLINE bool nrf_comp_event_check(nrf_comp_event_t comp_event)
+{
+ return (bool) (*(volatile uint32_t *)( (uint8_t *)NRF_COMP + comp_event));
+}
+
+#endif // SUPPRESS_INLINE_IMPLEMENTATION
+
+/**
+ *@}
+ **/
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_COMP_H_
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_ecb.c b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_ecb.c
new file mode 100644
index 000000000..d8c96d4ce
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_ecb.c
@@ -0,0 +1,100 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ * @brief Implementation of AES ECB driver
+ */
+
+
+//lint -e438
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include "nrf.h"
+#include "nrf_ecb.h"
+
+static uint8_t ecb_data[48]; ///< ECB data structure for RNG peripheral to access.
+static uint8_t* ecb_key; ///< Key: Starts at ecb_data
+static uint8_t* ecb_cleartext; ///< Cleartext: Starts at ecb_data + 16 bytes.
+static uint8_t* ecb_ciphertext; ///< Ciphertext: Starts at ecb_data + 32 bytes.
+
+bool nrf_ecb_init(void)
+{
+ ecb_key = ecb_data;
+ ecb_cleartext = ecb_data + 16;
+ ecb_ciphertext = ecb_data + 32;
+
+ NRF_ECB->ECBDATAPTR = (uint32_t)ecb_data;
+ return true;
+}
+
+
+bool nrf_ecb_crypt(uint8_t * dest_buf, const uint8_t * src_buf)
+{
+ uint32_t counter = 0x1000000;
+ if (src_buf != ecb_cleartext)
+ {
+ memcpy(ecb_cleartext,src_buf,16);
+ }
+ NRF_ECB->EVENTS_ENDECB = 0;
+ NRF_ECB->TASKS_STARTECB = 1;
+ while (NRF_ECB->EVENTS_ENDECB == 0)
+ {
+ counter--;
+ if (counter == 0)
+ {
+ return false;
+ }
+ }
+ NRF_ECB->EVENTS_ENDECB = 0;
+ if (dest_buf != ecb_ciphertext)
+ {
+ memcpy(dest_buf,ecb_ciphertext,16);
+ }
+ return true;
+}
+
+void nrf_ecb_set_key(const uint8_t * key)
+{
+ memcpy(ecb_key,key,16);
+}
+
+
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_ecb.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_ecb.h
new file mode 100644
index 000000000..b9bf4fb0a
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_ecb.h
@@ -0,0 +1,101 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ * @brief ECB driver API.
+ */
+
+#ifndef NRF_ECB_H__
+#define NRF_ECB_H__
+
+/**
+ * @defgroup nrf_ecb AES ECB encryption
+ * @{
+ * @ingroup nrf_drivers
+ * @brief Driver for the AES Electronic Code Book (ECB) peripheral.
+ *
+ * To encrypt data, the peripheral must first be powered on
+ * using @ref nrf_ecb_init. Next, the key must be set using @ref nrf_ecb_set_key.
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Function for initializing and powering on the ECB peripheral.
+ *
+ * This function allocates memory for the ECBDATAPTR.
+ * @retval true If initialization was successful.
+ * @retval false If powering on failed.
+ */
+bool nrf_ecb_init(void);
+
+/**
+ * @brief Function for encrypting 16-byte data using current key.
+ *
+ * This function avoids unnecessary copying of data if the parameters point to the
+ * correct locations in the ECB data structure.
+ *
+ * @param dst Result of encryption, 16 bytes will be written.
+ * @param src Source with 16-byte data to be encrypted.
+ *
+ * @retval true If the encryption operation completed.
+ * @retval false If the encryption operation did not complete.
+ */
+bool nrf_ecb_crypt(uint8_t * dst, const uint8_t * src);
+
+/**
+ * @brief Function for setting the key to be used for encryption.
+ *
+ * @param key Pointer to the key. 16 bytes will be read.
+ */
+void nrf_ecb_set_key(const uint8_t * key);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_ECB_H__
+
+/** @} */
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_egu.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_egu.h
new file mode 100644
index 000000000..761051614
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_egu.h
@@ -0,0 +1,367 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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"
+#include "nrf_peripherals.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 EGU_COUNT > 2
+ 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;
+ }
+#endif
+ 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)
+{
+ ASSERT(NRF_EGUx);
+ *((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)
+{
+ ASSERT(NRF_EGUx);
+ 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(NRF_EGUx);
+ 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(NRF_EGUx);
+ 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)
+{
+ ASSERT(NRF_EGUx);
+ 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)
+{
+ ASSERT(NRF_EGUx);
+ *((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)
+{
+ ASSERT(NRF_EGUx);
+ 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(NRF_EGUx);
+ 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(NRF_EGUx);
+ 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)
+{
+ ASSERT(NRF_EGUx);
+ 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)
+{
+ ASSERT(NRF_EGUx);
+ 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)
+{
+ ASSERT(NRF_EGUx);
+ 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(NRF_EGUx);
+ 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
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_gpio.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_gpio.h
new file mode 100644
index 000000000..ccd408c0a
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_gpio.h
@@ -0,0 +1,795 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_GPIO_H__
+#define NRF_GPIO_H__
+
+#include "nrf.h"
+#include "nrf_peripherals.h"
+#include "nrf_assert.h"
+#include <stdbool.h>
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup nrf_gpio GPIO abstraction
+ * @{
+ * @ingroup nrf_drivers
+ * @brief GPIO pin abstraction and port abstraction for reading and writing byte-wise to GPIO ports.
+ */
+
+#if (GPIO_COUNT == 1)
+#define NUMBER_OF_PINS (P0_PIN_NUM)
+#define GPIO_REG_LIST {NRF_GPIO}
+#elif (GPIO_COUNT == 2)
+#define NUMBER_OF_PINS (P0_PIN_NUM + P1_PIN_NUM)
+#define GPIO_REG_LIST {NRF_P0, NRF_P1}
+#else
+#error "Not supported."
+#endif
+
+
+/**
+ * @brief Macro for mapping port and pin numbers to values understandable for nrf_gpio functions.
+ */
+#define NRF_GPIO_PIN_MAP(port, pin) ((port << 5) | (pin & 0x1F))
+
+/**
+ * @brief Pin direction definitions.
+ */
+typedef enum
+{
+ NRF_GPIO_PIN_DIR_INPUT = GPIO_PIN_CNF_DIR_Input, ///< Input.
+ NRF_GPIO_PIN_DIR_OUTPUT = GPIO_PIN_CNF_DIR_Output ///< Output.
+} nrf_gpio_pin_dir_t;
+
+/**
+ * @brief Connection of input buffer.
+ */
+typedef enum
+{
+ NRF_GPIO_PIN_INPUT_CONNECT = GPIO_PIN_CNF_INPUT_Connect, ///< Connect input buffer.
+ NRF_GPIO_PIN_INPUT_DISCONNECT = GPIO_PIN_CNF_INPUT_Disconnect ///< Disconnect input buffer.
+} nrf_gpio_pin_input_t;
+
+/**
+ * @brief Enumerator used for selecting the pin to be pulled down or up at the time of pin configuration.
+ */
+typedef enum
+{
+ NRF_GPIO_PIN_NOPULL = GPIO_PIN_CNF_PULL_Disabled, ///< Pin pull-up resistor disabled.
+ NRF_GPIO_PIN_PULLDOWN = GPIO_PIN_CNF_PULL_Pulldown, ///< Pin pull-down resistor enabled.
+ NRF_GPIO_PIN_PULLUP = GPIO_PIN_CNF_PULL_Pullup, ///< Pin pull-up resistor enabled.
+} nrf_gpio_pin_pull_t;
+
+/**
+ * @brief Enumerator used for selecting output drive mode.
+ */
+typedef enum
+{
+ NRF_GPIO_PIN_S0S1 = GPIO_PIN_CNF_DRIVE_S0S1, ///< !< Standard '0', standard '1'.
+ NRF_GPIO_PIN_H0S1 = GPIO_PIN_CNF_DRIVE_H0S1, ///< !< High-drive '0', standard '1'.
+ NRF_GPIO_PIN_S0H1 = GPIO_PIN_CNF_DRIVE_S0H1, ///< !< Standard '0', high-drive '1'.
+ NRF_GPIO_PIN_H0H1 = GPIO_PIN_CNF_DRIVE_H0H1, ///< !< High drive '0', high-drive '1'.
+ NRF_GPIO_PIN_D0S1 = GPIO_PIN_CNF_DRIVE_D0S1, ///< !< Disconnect '0' standard '1'.
+ NRF_GPIO_PIN_D0H1 = GPIO_PIN_CNF_DRIVE_D0H1, ///< !< Disconnect '0', high-drive '1'.
+ NRF_GPIO_PIN_S0D1 = GPIO_PIN_CNF_DRIVE_S0D1, ///< !< Standard '0', disconnect '1'.
+ NRF_GPIO_PIN_H0D1 = GPIO_PIN_CNF_DRIVE_H0D1, ///< !< High-drive '0', disconnect '1'.
+} nrf_gpio_pin_drive_t;
+
+/**
+ * @brief Enumerator used for selecting the pin to sense high or low level on the pin input.
+ */
+typedef enum
+{
+ NRF_GPIO_PIN_NOSENSE = GPIO_PIN_CNF_SENSE_Disabled, ///< Pin sense level disabled.
+ NRF_GPIO_PIN_SENSE_LOW = GPIO_PIN_CNF_SENSE_Low, ///< Pin sense low level.
+ NRF_GPIO_PIN_SENSE_HIGH = GPIO_PIN_CNF_SENSE_High, ///< Pin sense high level.
+} nrf_gpio_pin_sense_t;
+
+
+#if (__LINT__ != 1)
+
+/**
+ * @brief Function for configuring the GPIO pin range as output pins with normal drive strength.
+ * This function can be used to configure pin range as simple output with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases).
+ *
+ * @param pin_range_start Specifies the start number (inclusive) in the range of pin numbers to be configured (allowed values 0-30).
+ *
+ * @param pin_range_end Specifies the end number (inclusive) in the range of pin numbers to be configured (allowed values 0-30).
+ *
+ * @note For configuring only one pin as output, use @ref nrf_gpio_cfg_output.
+ * Sense capability on the pin is disabled and input is disconnected from the buffer as the pins are configured as output.
+ */
+__STATIC_INLINE void nrf_gpio_range_cfg_output(uint32_t pin_range_start, uint32_t pin_range_end);
+
+/**
+ * @brief Function for configuring the GPIO pin range as input pins with given initial value set, hiding inner details.
+ * This function can be used to configure pin range as simple input.
+ *
+ * @param pin_range_start Specifies the start number (inclusive) in the range of pin numbers to be configured (allowed values 0-30).
+ *
+ * @param pin_range_end Specifies the end number (inclusive) in the range of pin numbers to be configured (allowed values 0-30).
+ *
+ * @param pull_config State of the pin range pull resistor (no pull, pulled down, or pulled high).
+ *
+ * @note For configuring only one pin as input, use @ref nrf_gpio_cfg_input.
+ * Sense capability on the pin is disabled and input is connected to buffer so that the GPIO->IN register is readable.
+ */
+__STATIC_INLINE void nrf_gpio_range_cfg_input(uint32_t pin_range_start,
+ uint32_t pin_range_end,
+ nrf_gpio_pin_pull_t pull_config);
+
+/**
+ * @brief Pin configuration function.
+ *
+ * The main pin configuration function.
+ * This function allows to set any aspect in PIN_CNF register.
+ * @param pin_number Specifies the pin number.
+ * @param dir Pin direction.
+ * @param input Connect or disconnect the input buffer.
+ * @param pull Pull configuration.
+ * @param drive Drive configuration.
+ * @param sense Pin sensing mechanism.
+ */
+__STATIC_INLINE void nrf_gpio_cfg(
+ uint32_t pin_number,
+ nrf_gpio_pin_dir_t dir,
+ nrf_gpio_pin_input_t input,
+ nrf_gpio_pin_pull_t pull,
+ nrf_gpio_pin_drive_t drive,
+ nrf_gpio_pin_sense_t sense);
+
+/**
+ * @brief Function for configuring the given GPIO pin number as output, hiding inner details.
+ * This function can be used to configure a pin as simple output with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases).
+ *
+ * @param pin_number Specifies the pin number.
+ *
+ * @note Sense capability on the pin is disabled and input is disconnected from the buffer as the pins are configured as output.
+ */
+__STATIC_INLINE void nrf_gpio_cfg_output(uint32_t pin_number);
+
+/**
+ * @brief Function for configuring the given GPIO pin number as input, hiding inner details.
+ * This function can be used to configure a pin as simple input.
+ *
+ * @param pin_number Specifies the pin number.
+ * @param pull_config State of the pin range pull resistor (no pull, pulled down, or pulled high).
+ *
+ * @note Sense capability on the pin is disabled and input is connected to buffer so that the GPIO->IN register is readable.
+ */
+__STATIC_INLINE void nrf_gpio_cfg_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config);
+
+/**
+ * @brief Function for resetting pin configuration to its default state.
+ *
+ * @param pin_number Specifies the pin number.
+ */
+__STATIC_INLINE void nrf_gpio_cfg_default(uint32_t pin_number);
+
+/**
+ * @brief Function for configuring the given GPIO pin number as a watcher. Only input is connected.
+ *
+ * @param pin_number Specifies the pin number.
+ *
+ */
+__STATIC_INLINE void nrf_gpio_cfg_watcher(uint32_t pin_number);
+
+/**
+ * @brief Function for disconnecting input for the given GPIO.
+ *
+ * @param pin_number Specifies the pin number.
+ *
+ */
+__STATIC_INLINE void nrf_gpio_input_disconnect(uint32_t pin_number);
+
+/**
+ * @brief Function for configuring the given GPIO pin number as input, hiding inner details.
+ * This function can be used to configure pin range as simple input.
+ * Sense capability on the pin is configurable and input is connected to buffer so that the GPIO->IN register is readable.
+ *
+ * @param pin_number Specifies the pin number.
+ * @param pull_config State of the pin pull resistor (no pull, pulled down, or pulled high).
+ * @param sense_config Sense level of the pin (no sense, sense low, or sense high).
+ */
+__STATIC_INLINE void nrf_gpio_cfg_sense_input(uint32_t pin_number,
+ nrf_gpio_pin_pull_t pull_config,
+ nrf_gpio_pin_sense_t sense_config);
+
+/**
+ * @brief Function for configuring sense level for the given GPIO.
+ *
+ * @param pin_number Specifies the pin number.
+ * @param sense_config Sense configuration.
+ *
+ */
+__STATIC_INLINE void nrf_gpio_cfg_sense_set(uint32_t pin_number, nrf_gpio_pin_sense_t sense_config);
+
+/**
+ * @brief Function for setting the direction for a GPIO pin.
+ *
+ * @param pin_number Specifies the pin number for which to set the direction.
+ *
+ * @param direction Specifies the direction.
+ */
+__STATIC_INLINE void nrf_gpio_pin_dir_set(uint32_t pin_number, nrf_gpio_pin_dir_t direction);
+
+/**
+ * @brief Function for setting a GPIO pin.
+ *
+ * Note that the pin must be configured as an output for this function to have any effect.
+ *
+ * @param pin_number Specifies the pin number to set.
+ */
+__STATIC_INLINE void nrf_gpio_pin_set(uint32_t pin_number);
+
+/**
+ * @brief Function for clearing a GPIO pin.
+ *
+ * Note that the pin must be configured as an output for this
+ * function to have any effect.
+ *
+ * @param pin_number Specifies the pin number to clear.
+ */
+__STATIC_INLINE void nrf_gpio_pin_clear(uint32_t pin_number);
+
+/**
+ * @brief Function for toggling a GPIO pin.
+ *
+ * Note that the pin must be configured as an output for this
+ * function to have any effect.
+ *
+ * @param pin_number Specifies the pin number to toggle.
+ */
+__STATIC_INLINE void nrf_gpio_pin_toggle(uint32_t pin_number);
+
+/**
+ * @brief Function for writing a value to a GPIO pin.
+ *
+ * Note that the pin must be configured as an output for this
+ * function to have any effect.
+ *
+ * @param pin_number Specifies the pin number to write.
+ *
+ * @param value Specifies the value to be written to the pin.
+ * @arg 0 Clears the pin.
+ * @arg >=1 Sets the pin.
+ */
+__STATIC_INLINE void nrf_gpio_pin_write(uint32_t pin_number, uint32_t value);
+
+/**
+ * @brief Function for reading the input level of a GPIO pin.
+ *
+ * Note that the pin must have input connected for the value
+ * returned from this function to be valid.
+ *
+ * @param pin_number Specifies the pin number to read.
+ *
+ * @return 0 if the pin input level is low. Positive value if the pin is high.
+ */
+__STATIC_INLINE uint32_t nrf_gpio_pin_read(uint32_t pin_number);
+
+/**
+ * @brief Function for reading the output level of a GPIO pin.
+ *
+ * @param pin_number Specifies the pin number to read.
+ *
+ * @return 0 if the pin output level is low. Positive value if pin output is high.
+ */
+__STATIC_INLINE uint32_t nrf_gpio_pin_out_read(uint32_t pin_number);
+
+/**
+ * @brief Function for reading the sense configuration of a GPIO pin.
+ *
+ * @param pin_number Specifies the pin number to read.
+ *
+ * @retval Sense configuration.
+ */
+__STATIC_INLINE nrf_gpio_pin_sense_t nrf_gpio_pin_sense_get(uint32_t pin_number);
+
+/**
+ * @brief Function for setting output direction on selected pins on a given port.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ * @param out_mask Mask specifying the pins to set as output.
+ *
+ */
+__STATIC_INLINE void nrf_gpio_port_dir_output_set(NRF_GPIO_Type * p_reg, uint32_t out_mask);
+
+/**
+ * @brief Function for setting input direction on selected pins on a given port.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ * @param in_mask Mask specifying the pins to set as input.
+ *
+ */
+__STATIC_INLINE void nrf_gpio_port_dir_input_set(NRF_GPIO_Type * p_reg, uint32_t in_mask);
+
+/**
+ * @brief Function for writing the direction configuration of GPIO pins in a given port.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ * @param dir_mask Mask specifying the direction of pins. Bit set means that the given pin is configured as output.
+ *
+ */
+__STATIC_INLINE void nrf_gpio_port_dir_write(NRF_GPIO_Type * p_reg, uint32_t dir_mask);
+
+/**
+ * @brief Function for reading the direction configuration of a GPIO port.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ *
+ * @retval Pin configuration of the current direction settings. Bit set means that the given pin is configured as output.
+ */
+__STATIC_INLINE uint32_t nrf_gpio_port_dir_read(NRF_GPIO_Type const * p_reg);
+
+/**
+ * @brief Function for reading the input signals of GPIO pins on a given port.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ *
+ * @retval Port input values.
+ */
+__STATIC_INLINE uint32_t nrf_gpio_port_in_read(NRF_GPIO_Type const * p_reg);
+
+/**
+ * @brief Function for reading the output signals of GPIO pins of a given port.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ *
+ * @retval Port output values.
+ */
+__STATIC_INLINE uint32_t nrf_gpio_port_out_read(NRF_GPIO_Type const * p_reg);
+
+/**
+ * @brief Function for writing the GPIO pins output on a given port.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ * @param value Output port mask.
+ *
+ */
+__STATIC_INLINE void nrf_gpio_port_out_write(NRF_GPIO_Type * p_reg, uint32_t value);
+
+/**
+ * @brief Function for setting high level on selected GPIO pins of a given port.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ * @param set_mask Mask with pins to set as logical high level.
+ *
+ */
+__STATIC_INLINE void nrf_gpio_port_out_set(NRF_GPIO_Type * p_reg, uint32_t set_mask);
+
+/**
+ * @brief Function for setting low level on selected GPIO pins of a given port.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ * @param clr_mask Mask with pins to set as logical low level.
+ *
+ */
+__STATIC_INLINE void nrf_gpio_port_out_clear(NRF_GPIO_Type * p_reg, uint32_t clr_mask);
+
+/**
+ * @brief Function for reading pins state of multiple consecutive ports.
+ *
+ * @param start_port Index of the first port to read.
+ * @param length Number of ports to read.
+ * @param p_masks Pointer to output array where port states will be stored.
+ */
+__STATIC_INLINE void nrf_gpio_ports_read(uint32_t start_port, uint32_t length, uint32_t * p_masks);
+
+#ifdef GPIO_DETECTMODE_DETECTMODE_LDETECT
+/**
+ * @brief Function for reading latch state of multiple consecutive ports.
+ *
+ * @param start_port Index of the first port to read.
+ * @param length Number of ports to read.
+ * @param p_masks Pointer to output array where latch states will be stored.
+ */
+__STATIC_INLINE void nrf_gpio_latches_read(uint32_t start_port, uint32_t length,
+ uint32_t * p_masks);
+
+/**
+ * @brief Function for reading latch state of single pin.
+ *
+ * @param pin_number Pin number.
+ * @return 0 if latch is not set. Positive value otherwise.
+ *
+ */
+__STATIC_INLINE uint32_t nrf_gpio_pin_latch_get(uint32_t pin_number);
+
+/**
+ * @brief Function for clearing latch state of a single pin.
+ *
+ * @param pin_number Pin number.
+ *
+ */
+__STATIC_INLINE void nrf_gpio_pin_latch_clear(uint32_t pin_number);
+#endif
+
+
+#endif // #ifndef (__LINT__ != 1)
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+/**
+ * @brief Function for extracting port and relative pin number from absolute pin number.
+ *
+ * @param[inout] Pointer to absolute pin number which is overriden by relative to port pin number.
+ *
+ * @return Pointer to port register set.
+ *
+ */
+__STATIC_INLINE NRF_GPIO_Type * nrf_gpio_pin_port_decode(uint32_t * p_pin)
+{
+ ASSERT(*p_pin < NUMBER_OF_PINS);
+#if (GPIO_COUNT == 1)
+ // The oldest definition case
+ return NRF_GPIO;
+#else
+ if (*p_pin < P0_PIN_NUM)
+ {
+ return NRF_P0;
+ }
+ else
+ {
+ *p_pin = *p_pin & (P0_PIN_NUM - 1);
+ return NRF_P1;
+ }
+#endif
+}
+
+
+__STATIC_INLINE void nrf_gpio_range_cfg_output(uint32_t pin_range_start, uint32_t pin_range_end)
+{
+ /*lint -e{845} // A zero has been given as right argument to operator '|'" */
+ for (; pin_range_start <= pin_range_end; pin_range_start++)
+ {
+ nrf_gpio_cfg_output(pin_range_start);
+ }
+}
+
+
+__STATIC_INLINE void nrf_gpio_range_cfg_input(uint32_t pin_range_start,
+ uint32_t pin_range_end,
+ nrf_gpio_pin_pull_t pull_config)
+{
+ /*lint -e{845} // A zero has been given as right argument to operator '|'" */
+ for (; pin_range_start <= pin_range_end; pin_range_start++)
+ {
+ nrf_gpio_cfg_input(pin_range_start, pull_config);
+ }
+}
+
+
+__STATIC_INLINE void nrf_gpio_cfg(
+ uint32_t pin_number,
+ nrf_gpio_pin_dir_t dir,
+ nrf_gpio_pin_input_t input,
+ nrf_gpio_pin_pull_t pull,
+ nrf_gpio_pin_drive_t drive,
+ nrf_gpio_pin_sense_t sense)
+{
+ NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number);
+
+ reg->PIN_CNF[pin_number] = ((uint32_t)dir << GPIO_PIN_CNF_DIR_Pos)
+ | ((uint32_t)input << GPIO_PIN_CNF_INPUT_Pos)
+ | ((uint32_t)pull << GPIO_PIN_CNF_PULL_Pos)
+ | ((uint32_t)drive << GPIO_PIN_CNF_DRIVE_Pos)
+ | ((uint32_t)sense << GPIO_PIN_CNF_SENSE_Pos);
+}
+
+
+__STATIC_INLINE void nrf_gpio_cfg_output(uint32_t pin_number)
+{
+ nrf_gpio_cfg(
+ pin_number,
+ NRF_GPIO_PIN_DIR_OUTPUT,
+ NRF_GPIO_PIN_INPUT_DISCONNECT,
+ NRF_GPIO_PIN_NOPULL,
+ NRF_GPIO_PIN_S0S1,
+ NRF_GPIO_PIN_NOSENSE);
+}
+
+
+__STATIC_INLINE void nrf_gpio_cfg_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config)
+{
+ nrf_gpio_cfg(
+ pin_number,
+ NRF_GPIO_PIN_DIR_INPUT,
+ NRF_GPIO_PIN_INPUT_CONNECT,
+ pull_config,
+ NRF_GPIO_PIN_S0S1,
+ NRF_GPIO_PIN_NOSENSE);
+}
+
+
+__STATIC_INLINE void nrf_gpio_cfg_default(uint32_t pin_number)
+{
+ nrf_gpio_cfg(
+ pin_number,
+ NRF_GPIO_PIN_DIR_INPUT,
+ NRF_GPIO_PIN_INPUT_DISCONNECT,
+ NRF_GPIO_PIN_NOPULL,
+ NRF_GPIO_PIN_S0S1,
+ NRF_GPIO_PIN_NOSENSE);
+}
+
+
+__STATIC_INLINE void nrf_gpio_cfg_watcher(uint32_t pin_number)
+{
+ NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number);
+ /*lint -e{845} // A zero has been given as right argument to operator '|'" */
+ uint32_t cnf = reg->PIN_CNF[pin_number] & ~GPIO_PIN_CNF_INPUT_Msk;
+
+ reg->PIN_CNF[pin_number] = cnf | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos);
+}
+
+
+__STATIC_INLINE void nrf_gpio_input_disconnect(uint32_t pin_number)
+{
+ NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number);
+ /*lint -e{845} // A zero has been given as right argument to operator '|'" */
+ uint32_t cnf = reg->PIN_CNF[pin_number] & ~GPIO_PIN_CNF_INPUT_Msk;
+
+ reg->PIN_CNF[pin_number] = cnf | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos);
+}
+
+
+__STATIC_INLINE void nrf_gpio_cfg_sense_input(uint32_t pin_number,
+ nrf_gpio_pin_pull_t pull_config,
+ nrf_gpio_pin_sense_t sense_config)
+{
+ nrf_gpio_cfg(
+ pin_number,
+ NRF_GPIO_PIN_DIR_INPUT,
+ NRF_GPIO_PIN_INPUT_CONNECT,
+ pull_config,
+ NRF_GPIO_PIN_S0S1,
+ sense_config);
+}
+
+
+__STATIC_INLINE void nrf_gpio_cfg_sense_set(uint32_t pin_number, nrf_gpio_pin_sense_t sense_config)
+{
+ NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number);
+
+ /*lint -e{845} // A zero has been given as right argument to operator '|'" */
+ reg->PIN_CNF[pin_number] &= ~GPIO_PIN_CNF_SENSE_Msk;
+ reg->PIN_CNF[pin_number] |= (sense_config << GPIO_PIN_CNF_SENSE_Pos);
+}
+
+
+__STATIC_INLINE void nrf_gpio_pin_dir_set(uint32_t pin_number, nrf_gpio_pin_dir_t direction)
+{
+ if (direction == NRF_GPIO_PIN_DIR_INPUT)
+ {
+ nrf_gpio_cfg(
+ pin_number,
+ NRF_GPIO_PIN_DIR_INPUT,
+ NRF_GPIO_PIN_INPUT_CONNECT,
+ NRF_GPIO_PIN_NOPULL,
+ NRF_GPIO_PIN_S0S1,
+ NRF_GPIO_PIN_NOSENSE);
+ }
+ else
+ {
+ NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number);
+ reg->DIRSET = (1UL << pin_number);
+ }
+}
+
+
+__STATIC_INLINE void nrf_gpio_pin_set(uint32_t pin_number)
+{
+ NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number);
+
+ nrf_gpio_port_out_set(reg, 1UL << pin_number);
+}
+
+
+__STATIC_INLINE void nrf_gpio_pin_clear(uint32_t pin_number)
+{
+ NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number);
+
+ nrf_gpio_port_out_clear(reg, 1UL << pin_number);
+}
+
+
+__STATIC_INLINE void nrf_gpio_pin_toggle(uint32_t pin_number)
+{
+ NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number);
+ uint32_t pins_state = reg->OUT;
+
+ reg->OUTSET = (~pins_state & (1UL << pin_number));
+ reg->OUTCLR = (pins_state & (1UL << pin_number));
+}
+
+
+__STATIC_INLINE void nrf_gpio_pin_write(uint32_t pin_number, uint32_t value)
+{
+ if (value == 0)
+ {
+ nrf_gpio_pin_clear(pin_number);
+ }
+ else
+ {
+ nrf_gpio_pin_set(pin_number);
+ }
+}
+
+
+__STATIC_INLINE uint32_t nrf_gpio_pin_read(uint32_t pin_number)
+{
+ NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number);
+
+ return ((nrf_gpio_port_in_read(reg) >> pin_number) & 1UL);
+}
+
+
+__STATIC_INLINE uint32_t nrf_gpio_pin_out_read(uint32_t pin_number)
+{
+ NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number);
+
+ return ((nrf_gpio_port_out_read(reg) >> pin_number) & 1UL);
+}
+
+
+__STATIC_INLINE nrf_gpio_pin_sense_t nrf_gpio_pin_sense_get(uint32_t pin_number)
+{
+ NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number);
+
+ return (nrf_gpio_pin_sense_t)((reg->PIN_CNF[pin_number] &
+ GPIO_PIN_CNF_SENSE_Msk) >> GPIO_PIN_CNF_SENSE_Pos);
+}
+
+
+__STATIC_INLINE void nrf_gpio_port_dir_output_set(NRF_GPIO_Type * p_reg, uint32_t out_mask)
+{
+ p_reg->DIRSET = out_mask;
+}
+
+
+__STATIC_INLINE void nrf_gpio_port_dir_input_set(NRF_GPIO_Type * p_reg, uint32_t in_mask)
+{
+ p_reg->DIRCLR = in_mask;
+}
+
+
+__STATIC_INLINE void nrf_gpio_port_dir_write(NRF_GPIO_Type * p_reg, uint32_t value)
+{
+ p_reg->DIR = value;
+}
+
+
+__STATIC_INLINE uint32_t nrf_gpio_port_dir_read(NRF_GPIO_Type const * p_reg)
+{
+ return p_reg->DIR;
+}
+
+
+__STATIC_INLINE uint32_t nrf_gpio_port_in_read(NRF_GPIO_Type const * p_reg)
+{
+ return p_reg->IN;
+}
+
+
+__STATIC_INLINE uint32_t nrf_gpio_port_out_read(NRF_GPIO_Type const * p_reg)
+{
+ return p_reg->OUT;
+}
+
+
+__STATIC_INLINE void nrf_gpio_port_out_write(NRF_GPIO_Type * p_reg, uint32_t value)
+{
+ p_reg->OUT = value;
+}
+
+
+__STATIC_INLINE void nrf_gpio_port_out_set(NRF_GPIO_Type * p_reg, uint32_t set_mask)
+{
+ p_reg->OUTSET = set_mask;
+}
+
+
+__STATIC_INLINE void nrf_gpio_port_out_clear(NRF_GPIO_Type * p_reg, uint32_t clr_mask)
+{
+ p_reg->OUTCLR = clr_mask;
+}
+
+
+__STATIC_INLINE void nrf_gpio_ports_read(uint32_t start_port, uint32_t length, uint32_t * p_masks)
+{
+ NRF_GPIO_Type * gpio_regs[GPIO_COUNT] = GPIO_REG_LIST;
+
+ ASSERT(start_port + length <= GPIO_COUNT);
+ uint32_t i;
+
+ for (i = start_port; i < (start_port + length); i++)
+ {
+ *p_masks = nrf_gpio_port_in_read(gpio_regs[i]);
+ p_masks++;
+ }
+}
+
+
+#ifdef GPIO_DETECTMODE_DETECTMODE_LDETECT
+__STATIC_INLINE void nrf_gpio_latches_read(uint32_t start_port, uint32_t length, uint32_t * p_masks)
+{
+ NRF_GPIO_Type * gpio_regs[GPIO_COUNT] = GPIO_REG_LIST;
+ uint32_t i;
+
+ for (i = start_port; i < (start_port + length); i++)
+ {
+ *p_masks = gpio_regs[i]->LATCH;
+ p_masks++;
+ }
+}
+
+
+__STATIC_INLINE uint32_t nrf_gpio_pin_latch_get(uint32_t pin_number)
+{
+ NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number);
+
+ return (reg->LATCH & (1 << pin_number)) ? 1 : 0;
+}
+
+
+__STATIC_INLINE void nrf_gpio_pin_latch_clear(uint32_t pin_number)
+{
+ NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number);
+
+ reg->LATCH = (1 << pin_number);
+}
+
+
+#endif
+#endif // SUPPRESS_INLINE_IMPLEMENTATION
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_gpiote.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_gpiote.h
new file mode 100644
index 000000000..df9bd35ce
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_gpiote.h
@@ -0,0 +1,430 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_i2s.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_i2s.h
new file mode 100644
index 000000000..d5485572b
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_i2s.h
@@ -0,0 +1,563 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_i2s_hal I2S HAL
+ * @{
+ * @ingroup nrf_i2s
+ *
+ * @brief @tagAPI52 Hardware access layer for managing the Inter-IC Sound (I2S) peripheral.
+ */
+
+#ifndef NRF_I2S_H__
+#define NRF_I2S_H__
+
+#include <stddef.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "nrf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief This value can be provided as a parameter for the @ref nrf_i2s_pins_set
+ * function call to specify that a given I2S signal (SDOUT, SDIN, or MCK)
+ * shall not be connected to a physical pin.
+ */
+#define NRF_I2S_PIN_NOT_CONNECTED 0xFFFFFFFF
+
+
+/**
+ * @brief I2S tasks.
+ */
+typedef enum
+{
+ /*lint -save -e30*/
+ NRF_I2S_TASK_START = offsetof(NRF_I2S_Type, TASKS_START), ///< Starts continuous I2S transfer. Also starts the MCK generator if this is enabled.
+ NRF_I2S_TASK_STOP = offsetof(NRF_I2S_Type, TASKS_STOP) ///< Stops I2S transfer. Also stops the MCK generator.
+ /*lint -restore*/
+} nrf_i2s_task_t;
+
+/**
+ * @brief I2S events.
+ */
+typedef enum
+{
+ /*lint -save -e30*/
+ NRF_I2S_EVENT_RXPTRUPD = offsetof(NRF_I2S_Type, EVENTS_RXPTRUPD), ///< The RXD.PTR register has been copied to internal double-buffers.
+ NRF_I2S_EVENT_TXPTRUPD = offsetof(NRF_I2S_Type, EVENTS_TXPTRUPD), ///< The TXD.PTR register has been copied to internal double-buffers.
+ NRF_I2S_EVENT_STOPPED = offsetof(NRF_I2S_Type, EVENTS_STOPPED) ///< I2S transfer stopped.
+ /*lint -restore*/
+} nrf_i2s_event_t;
+
+/**
+ * @brief I2S interrupts.
+ */
+typedef enum
+{
+ NRF_I2S_INT_RXPTRUPD_MASK = I2S_INTENSET_RXPTRUPD_Msk, ///< Interrupt on RXPTRUPD event.
+ NRF_I2S_INT_TXPTRUPD_MASK = I2S_INTENSET_TXPTRUPD_Msk, ///< Interrupt on TXPTRUPD event.
+ NRF_I2S_INT_STOPPED_MASK = I2S_INTENSET_STOPPED_Msk ///< Interrupt on STOPPED event.
+} nrf_i2s_int_mask_t;
+
+/**
+ * @brief I2S modes of operation.
+ */
+typedef enum
+{
+ NRF_I2S_MODE_MASTER = I2S_CONFIG_MODE_MODE_Master, ///< Master mode.
+ NRF_I2S_MODE_SLAVE = I2S_CONFIG_MODE_MODE_Slave ///< Slave mode.
+} nrf_i2s_mode_t;
+
+/**
+ * @brief I2S master clock generator settings.
+ */
+typedef enum
+{
+ NRF_I2S_MCK_DISABLED = 0, ///< MCK disabled.
+ // [conversion to 'int' needed to prevent compilers from complaining
+ // that the provided value (0x80000000UL) is out of range of "int"]
+ NRF_I2S_MCK_32MDIV2 = (int)I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV2, ///< 32 MHz / 2 = 16.0 MHz.
+ NRF_I2S_MCK_32MDIV3 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV3, ///< 32 MHz / 3 = 10.6666667 MHz.
+ NRF_I2S_MCK_32MDIV4 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV4, ///< 32 MHz / 4 = 8.0 MHz.
+ NRF_I2S_MCK_32MDIV5 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV5, ///< 32 MHz / 5 = 6.4 MHz.
+ NRF_I2S_MCK_32MDIV6 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV6, ///< 32 MHz / 6 = 5.3333333 MHz.
+ NRF_I2S_MCK_32MDIV8 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV8, ///< 32 MHz / 8 = 4.0 MHz.
+ NRF_I2S_MCK_32MDIV10 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV10, ///< 32 MHz / 10 = 3.2 MHz.
+ NRF_I2S_MCK_32MDIV11 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV11, ///< 32 MHz / 11 = 2.9090909 MHz.
+ NRF_I2S_MCK_32MDIV15 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV15, ///< 32 MHz / 15 = 2.1333333 MHz.
+ NRF_I2S_MCK_32MDIV16 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV16, ///< 32 MHz / 16 = 2.0 MHz.
+ NRF_I2S_MCK_32MDIV21 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV21, ///< 32 MHz / 21 = 1.5238095 MHz.
+ NRF_I2S_MCK_32MDIV23 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV23, ///< 32 MHz / 23 = 1.3913043 MHz.
+ NRF_I2S_MCK_32MDIV31 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV31, ///< 32 MHz / 31 = 1.0322581 MHz.
+ NRF_I2S_MCK_32MDIV42 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV42, ///< 32 MHz / 42 = 0.7619048 MHz.
+ NRF_I2S_MCK_32MDIV63 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV63, ///< 32 MHz / 63 = 0.5079365 MHz.
+ NRF_I2S_MCK_32MDIV125 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV125 ///< 32 MHz / 125 = 0.256 MHz.
+} nrf_i2s_mck_t;
+
+/**
+ * @brief I2S MCK/LRCK ratios.
+ */
+typedef enum
+{
+ NRF_I2S_RATIO_32X = I2S_CONFIG_RATIO_RATIO_32X, ///< LRCK = MCK / 32.
+ NRF_I2S_RATIO_48X = I2S_CONFIG_RATIO_RATIO_48X, ///< LRCK = MCK / 48.
+ NRF_I2S_RATIO_64X = I2S_CONFIG_RATIO_RATIO_64X, ///< LRCK = MCK / 64.
+ NRF_I2S_RATIO_96X = I2S_CONFIG_RATIO_RATIO_96X, ///< LRCK = MCK / 96.
+ NRF_I2S_RATIO_128X = I2S_CONFIG_RATIO_RATIO_128X, ///< LRCK = MCK / 128.
+ NRF_I2S_RATIO_192X = I2S_CONFIG_RATIO_RATIO_192X, ///< LRCK = MCK / 192.
+ NRF_I2S_RATIO_256X = I2S_CONFIG_RATIO_RATIO_256X, ///< LRCK = MCK / 256.
+ NRF_I2S_RATIO_384X = I2S_CONFIG_RATIO_RATIO_384X, ///< LRCK = MCK / 384.
+ NRF_I2S_RATIO_512X = I2S_CONFIG_RATIO_RATIO_512X ///< LRCK = MCK / 512.
+} nrf_i2s_ratio_t;
+
+/**
+ * @brief I2S sample widths.
+ */
+typedef enum
+{
+ NRF_I2S_SWIDTH_8BIT = I2S_CONFIG_SWIDTH_SWIDTH_8Bit, ///< 8 bit.
+ NRF_I2S_SWIDTH_16BIT = I2S_CONFIG_SWIDTH_SWIDTH_16Bit, ///< 16 bit.
+ NRF_I2S_SWIDTH_24BIT = I2S_CONFIG_SWIDTH_SWIDTH_24Bit ///< 24 bit.
+} nrf_i2s_swidth_t;
+
+/**
+ * @brief I2S alignments of sample within a frame.
+ */
+typedef enum
+{
+ NRF_I2S_ALIGN_LEFT = I2S_CONFIG_ALIGN_ALIGN_Left, ///< Left-aligned.
+ NRF_I2S_ALIGN_RIGHT = I2S_CONFIG_ALIGN_ALIGN_Right ///< Right-aligned.
+} nrf_i2s_align_t;
+
+/**
+ * @brief I2S frame formats.
+ */
+typedef enum
+{
+ NRF_I2S_FORMAT_I2S = I2S_CONFIG_FORMAT_FORMAT_I2S, ///< Original I2S format.
+ NRF_I2S_FORMAT_ALIGNED = I2S_CONFIG_FORMAT_FORMAT_Aligned ///< Alternate (left- or right-aligned) format.
+} nrf_i2s_format_t;
+
+/**
+ * @brief I2S enabled channels.
+ */
+typedef enum
+{
+ NRF_I2S_CHANNELS_STEREO = I2S_CONFIG_CHANNELS_CHANNELS_Stereo, ///< Stereo.
+ NRF_I2S_CHANNELS_LEFT = I2S_CONFIG_CHANNELS_CHANNELS_Left, ///< Left only.
+ NRF_I2S_CHANNELS_RIGHT = I2S_CONFIG_CHANNELS_CHANNELS_Right ///< Right only.
+} nrf_i2s_channels_t;
+
+
+/**
+ * @brief Function for activating a specific I2S task.
+ *
+ * @param[in] p_i2s I2S instance.
+ * @param[in] task Task to activate.
+ */
+__STATIC_INLINE void nrf_i2s_task_trigger(NRF_I2S_Type * p_i2s,
+ nrf_i2s_task_t task);
+
+/**
+ * @brief Function for getting the address of a specific I2S task register.
+ *
+ * @param[in] p_i2s I2S instance.
+ * @param[in] task Requested task.
+ *
+ * @return Address of the specified task register.
+ */
+__STATIC_INLINE uint32_t nrf_i2s_task_address_get(NRF_I2S_Type const * p_i2s,
+ nrf_i2s_task_t task);
+
+/**
+ * @brief Function for clearing a specific I2S event.
+ *
+ * @param[in] p_i2s I2S instance.
+ * @param[in] event Event to clear.
+ */
+__STATIC_INLINE void nrf_i2s_event_clear(NRF_I2S_Type * p_i2s,
+ nrf_i2s_event_t event);
+
+/**
+ * @brief Function for checking the state of a specific I2S event.
+ *
+ * @param[in] p_i2s I2S instance.
+ * @param[in] event Event to check.
+ *
+ * @retval true If the event is set.
+ * @retval false If the event is not set.
+ */
+__STATIC_INLINE bool nrf_i2s_event_check(NRF_I2S_Type const * p_i2s,
+ nrf_i2s_event_t event);
+
+/**
+ * @brief Function for getting the address of a specific I2S event register.
+ *
+ * @param[in] p_i2s I2S instance.
+ * @param[in] event Requested event.
+ *
+ * @return Address of the specified event register.
+ */
+__STATIC_INLINE uint32_t nrf_i2s_event_address_get(NRF_I2S_Type const * p_i2s,
+ nrf_i2s_event_t event);
+
+/**
+ * @brief Function for enabling specified interrupts.
+ *
+ * @param[in] p_i2s I2S instance.
+ * @param[in] mask Interrupts to enable.
+ */
+__STATIC_INLINE void nrf_i2s_int_enable(NRF_I2S_Type * p_i2s, uint32_t mask);
+
+/**
+ * @brief Function for disabling specified interrupts.
+ *
+ * @param[in] p_i2s I2S instance.
+ * @param[in] mask Interrupts to disable.
+ */
+__STATIC_INLINE void nrf_i2s_int_disable(NRF_I2S_Type * p_i2s, uint32_t mask);
+
+/**
+ * @brief Function for retrieving the state of a given interrupt.
+ *
+ * @param[in] p_i2s I2S instance.
+ * @param[in] i2s_int Interrupt to check.
+ *
+ * @retval true If the interrupt is enabled.
+ * @retval false If the interrupt is not enabled.
+ */
+__STATIC_INLINE bool nrf_i2s_int_enable_check(NRF_I2S_Type const * p_i2s,
+ nrf_i2s_int_mask_t i2s_int);
+
+/**
+ * @brief Function for enabling the I2S peripheral.
+ *
+ * @param[in] p_i2s I2S instance.
+ */
+__STATIC_INLINE void nrf_i2s_enable(NRF_I2S_Type * p_i2s);
+
+/**
+ * @brief Function for disabling the I2S peripheral.
+ *
+ * @param[in] p_i2s I2S instance.
+ */
+__STATIC_INLINE void nrf_i2s_disable(NRF_I2S_Type * p_i2s);
+
+/**
+ * @brief Function for configuring I2S pins.
+ *
+ * Usage of the SDOUT, SDIN, and MCK signals is optional.
+ * If a given signal is not needed, pass the @ref NRF_I2S_PIN_NOT_CONNECTED
+ * value instead of its pin number.
+ *
+ * @param[in] p_i2s I2S instance.
+ * @param[in] sck_pin SCK pin number.
+ * @param[in] lrck_pin LRCK pin number.
+ * @param[in] mck_pin MCK pin number.
+ * @param[in] sdout_pin SDOUT pin number.
+ * @param[in] sdin_pin SDIN pin number.
+ */
+__STATIC_INLINE void nrf_i2s_pins_set(NRF_I2S_Type * p_i2s,
+ uint32_t sck_pin,
+ uint32_t lrck_pin,
+ uint32_t mck_pin,
+ uint32_t sdout_pin,
+ uint32_t sdin_pin);
+
+/**
+ * @brief Function for setting the I2S peripheral configuration.
+ *
+ * @param[in] p_i2s I2S instance.
+ * @param[in] mode Mode of operation (master or slave).
+ * @param[in] format I2S frame format.
+ * @param[in] alignment Alignment of sample within a frame.
+ * @param[in] sample_width Sample width.
+ * @param[in] channels Enabled channels.
+ * @param[in] mck_setup Master clock generator setup.
+ * @param[in] ratio MCK/LRCK ratio.
+ *
+ * @retval true If the configuration has been set successfully.
+ * @retval false If the requested configuration is not allowed.
+ */
+__STATIC_INLINE bool nrf_i2s_configure(NRF_I2S_Type * p_i2s,
+ nrf_i2s_mode_t mode,
+ nrf_i2s_format_t format,
+ nrf_i2s_align_t alignment,
+ nrf_i2s_swidth_t sample_width,
+ nrf_i2s_channels_t channels,
+ nrf_i2s_mck_t mck_setup,
+ nrf_i2s_ratio_t ratio);
+
+/**
+ * @brief Function for setting up the I2S transfer.
+ *
+ * This function sets up the RX and TX buffers and enables reception and/or
+ * transmission accordingly. If the transfer in a given direction is not
+ * required, pass NULL instead of the pointer to the corresponding buffer.
+ *
+ * @param[in] p_i2s I2S instance.
+ * @param[in] size Size of the buffers (in 32-bit words).
+ * @param[in] p_rx_buffer Pointer to the receive buffer.
+ * Pass NULL to disable reception.
+ * @param[in] p_tx_buffer Pointer to the transmit buffer.
+ * Pass NULL to disable transmission.
+ */
+__STATIC_INLINE void nrf_i2s_transfer_set(NRF_I2S_Type * p_i2s,
+ uint16_t size,
+ uint32_t * p_rx_buffer,
+ uint32_t const * p_tx_buffer);
+
+/**
+ * @brief Function for setting the pointer to the receive buffer.
+ *
+ * @note The size of the buffer can be set only by calling
+ * @ref nrf_i2s_transfer_set.
+ *
+ * @param[in] p_i2s I2S instance.
+ * @param[in] p_buffer Pointer to the receive buffer.
+ */
+__STATIC_INLINE void nrf_i2s_rx_buffer_set(NRF_I2S_Type * p_i2s,
+ uint32_t * p_buffer);
+
+/**
+ * @brief Function for getting the pointer to the receive buffer.
+ *
+ * @param[in] p_i2s I2S instance.
+ *
+ * @return Pointer to the receive buffer.
+ */
+__STATIC_INLINE uint32_t * nrf_i2s_rx_buffer_get(NRF_I2S_Type const * p_i2s);
+
+/**
+ * @brief Function for setting the pointer to the transmit buffer.
+ *
+ * @note The size of the buffer can be set only by calling
+ * @ref nrf_i2s_transfer_set.
+ *
+ * @param[in] p_i2s I2S instance.
+ * @param[in] p_buffer Pointer to the transmit buffer.
+ */
+__STATIC_INLINE void nrf_i2s_tx_buffer_set(NRF_I2S_Type * p_i2s,
+ uint32_t const * p_buffer);
+
+/**
+ * @brief Function for getting the pointer to the transmit buffer.
+ *
+ * @param[in] p_i2s I2S instance.
+ *
+ * @return Pointer to the transmit buffer.
+ */
+__STATIC_INLINE uint32_t * nrf_i2s_tx_buffer_get(NRF_I2S_Type const * p_i2s);
+
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE void nrf_i2s_task_trigger(NRF_I2S_Type * p_i2s,
+ nrf_i2s_task_t task)
+{
+ *((volatile uint32_t *)((uint8_t *)p_i2s + (uint32_t)task)) = 0x1UL;
+}
+
+__STATIC_INLINE uint32_t nrf_i2s_task_address_get(NRF_I2S_Type const * p_i2s,
+ nrf_i2s_task_t task)
+{
+ return ((uint32_t)p_i2s + (uint32_t)task);
+}
+
+__STATIC_INLINE void nrf_i2s_event_clear(NRF_I2S_Type * p_i2s,
+ nrf_i2s_event_t event)
+{
+ *((volatile uint32_t *)((uint8_t *)p_i2s + (uint32_t)event)) = 0x0UL;
+#if __CORTEX_M == 0x04
+ volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_i2s + (uint32_t)event));
+ (void)dummy;
+#endif
+}
+
+__STATIC_INLINE bool nrf_i2s_event_check(NRF_I2S_Type const * p_i2s,
+ nrf_i2s_event_t event)
+{
+ return (bool)*(volatile uint32_t *)((uint8_t *)p_i2s + (uint32_t)event);
+}
+
+__STATIC_INLINE uint32_t nrf_i2s_event_address_get(NRF_I2S_Type const * p_i2s,
+ nrf_i2s_event_t event)
+{
+ return ((uint32_t)p_i2s + (uint32_t)event);
+}
+
+__STATIC_INLINE void nrf_i2s_int_enable(NRF_I2S_Type * p_i2s, uint32_t mask)
+{
+ p_i2s->INTENSET = mask;
+}
+
+__STATIC_INLINE void nrf_i2s_int_disable(NRF_I2S_Type * p_i2s, uint32_t mask)
+{
+ p_i2s->INTENCLR = mask;
+}
+
+__STATIC_INLINE bool nrf_i2s_int_enable_check(NRF_I2S_Type const * p_i2s,
+ nrf_i2s_int_mask_t i2s_int)
+{
+ return (bool)(p_i2s->INTENSET & i2s_int);
+}
+
+__STATIC_INLINE void nrf_i2s_enable(NRF_I2S_Type * p_i2s)
+{
+ p_i2s->ENABLE = (I2S_ENABLE_ENABLE_Enabled << I2S_ENABLE_ENABLE_Pos);
+}
+
+__STATIC_INLINE void nrf_i2s_disable(NRF_I2S_Type * p_i2s)
+{
+ p_i2s->ENABLE = (I2S_ENABLE_ENABLE_Disabled << I2S_ENABLE_ENABLE_Pos);
+}
+
+__STATIC_INLINE void nrf_i2s_pins_set(NRF_I2S_Type * p_i2s,
+ uint32_t sck_pin,
+ uint32_t lrck_pin,
+ uint32_t mck_pin,
+ uint32_t sdout_pin,
+ uint32_t sdin_pin)
+{
+ p_i2s->PSEL.SCK = sck_pin;
+ p_i2s->PSEL.LRCK = lrck_pin;
+ p_i2s->PSEL.MCK = mck_pin;
+ p_i2s->PSEL.SDOUT = sdout_pin;
+ p_i2s->PSEL.SDIN = sdin_pin;
+}
+
+__STATIC_INLINE bool nrf_i2s_configure(NRF_I2S_Type * p_i2s,
+ nrf_i2s_mode_t mode,
+ nrf_i2s_format_t format,
+ nrf_i2s_align_t alignment,
+ nrf_i2s_swidth_t sample_width,
+ nrf_i2s_channels_t channels,
+ nrf_i2s_mck_t mck_setup,
+ nrf_i2s_ratio_t ratio)
+{
+ if (mode == NRF_I2S_MODE_MASTER)
+ {
+ // The MCK/LRCK ratio shall be a multiple of 2 * sample width.
+ if (((sample_width == NRF_I2S_SWIDTH_16BIT) &&
+ (ratio == NRF_I2S_RATIO_48X))
+ ||
+ ((sample_width == NRF_I2S_SWIDTH_24BIT) &&
+ ((ratio == NRF_I2S_RATIO_32X) ||
+ (ratio == NRF_I2S_RATIO_64X) ||
+ (ratio == NRF_I2S_RATIO_128X) ||
+ (ratio == NRF_I2S_RATIO_256X) ||
+ (ratio == NRF_I2S_RATIO_512X))))
+ {
+ return false;
+ }
+ }
+
+ p_i2s->CONFIG.MODE = mode;
+ p_i2s->CONFIG.FORMAT = format;
+ p_i2s->CONFIG.ALIGN = alignment;
+ p_i2s->CONFIG.SWIDTH = sample_width;
+ p_i2s->CONFIG.CHANNELS = channels;
+ p_i2s->CONFIG.RATIO = ratio;
+
+ if (mck_setup == NRF_I2S_MCK_DISABLED)
+ {
+ p_i2s->CONFIG.MCKEN =
+ (I2S_CONFIG_MCKEN_MCKEN_Disabled << I2S_CONFIG_MCKEN_MCKEN_Pos);
+ }
+ else
+ {
+ p_i2s->CONFIG.MCKFREQ = mck_setup;
+ p_i2s->CONFIG.MCKEN =
+ (I2S_CONFIG_MCKEN_MCKEN_Enabled << I2S_CONFIG_MCKEN_MCKEN_Pos);
+ }
+
+ return true;
+}
+
+__STATIC_INLINE void nrf_i2s_transfer_set(NRF_I2S_Type * p_i2s,
+ uint16_t size,
+ uint32_t * p_buffer_rx,
+ uint32_t const * p_buffer_tx)
+{
+ p_i2s->RXTXD.MAXCNT = size;
+
+ nrf_i2s_rx_buffer_set(p_i2s, p_buffer_rx);
+ p_i2s->CONFIG.RXEN = (p_buffer_rx != NULL) ? 1 : 0;
+
+ nrf_i2s_tx_buffer_set(p_i2s, p_buffer_tx);
+ p_i2s->CONFIG.TXEN = (p_buffer_tx != NULL) ? 1 : 0;
+}
+
+__STATIC_INLINE void nrf_i2s_rx_buffer_set(NRF_I2S_Type * p_i2s,
+ uint32_t * p_buffer)
+{
+ p_i2s->RXD.PTR = (uint32_t)p_buffer;
+}
+
+__STATIC_INLINE uint32_t * nrf_i2s_rx_buffer_get(NRF_I2S_Type const * p_i2s)
+{
+ return (uint32_t *)(p_i2s->RXD.PTR);
+}
+
+__STATIC_INLINE void nrf_i2s_tx_buffer_set(NRF_I2S_Type * p_i2s,
+ uint32_t const * p_buffer)
+{
+ p_i2s->TXD.PTR = (uint32_t)p_buffer;
+}
+
+__STATIC_INLINE uint32_t * nrf_i2s_tx_buffer_get(NRF_I2S_Type const * p_i2s)
+{
+ return (uint32_t *)(p_i2s->TXD.PTR);
+}
+
+#endif // SUPPRESS_INLINE_IMPLEMENTATION
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_I2S_H__
+
+/** @} */
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_lpcomp.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_lpcomp.h
new file mode 100644
index 000000000..4e241a977
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_lpcomp.h
@@ -0,0 +1,425 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ * @brief LPCOMP HAL API.
+ */
+
+#ifndef NRF_LPCOMP_H_
+#define NRF_LPCOMP_H_
+
+/**
+ * @defgroup nrf_lpcomp_hal LPCOMP HAL
+ * @{
+ * @ingroup nrf_lpcomp
+ * @brief Hardware access layer for managing the Low Power Comparator (LPCOMP).
+ */
+
+#include "nrf.h"
+#include "nrf_peripherals.h"
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @enum nrf_lpcomp_ref_t
+ * @brief LPCOMP reference selection.
+ */
+typedef enum
+{
+#if (LPCOMP_REFSEL_RESOLUTION == 8) || defined(__SDK_DOXYGEN__)
+ NRF_LPCOMP_REF_SUPPLY_1_8 = LPCOMP_REFSEL_REFSEL_SupplyOneEighthPrescaling, /**< Use supply with a 1/8 prescaler as reference. */
+ NRF_LPCOMP_REF_SUPPLY_2_8 = LPCOMP_REFSEL_REFSEL_SupplyTwoEighthsPrescaling, /**< Use supply with a 2/8 prescaler as reference. */
+ NRF_LPCOMP_REF_SUPPLY_3_8 = LPCOMP_REFSEL_REFSEL_SupplyThreeEighthsPrescaling, /**< Use supply with a 3/8 prescaler as reference. */
+ NRF_LPCOMP_REF_SUPPLY_4_8 = LPCOMP_REFSEL_REFSEL_SupplyFourEighthsPrescaling, /**< Use supply with a 4/8 prescaler as reference. */
+ NRF_LPCOMP_REF_SUPPLY_5_8 = LPCOMP_REFSEL_REFSEL_SupplyFiveEighthsPrescaling, /**< Use supply with a 5/8 prescaler as reference. */
+ NRF_LPCOMP_REF_SUPPLY_6_8 = LPCOMP_REFSEL_REFSEL_SupplySixEighthsPrescaling, /**< Use supply with a 6/8 prescaler as reference. */
+ NRF_LPCOMP_REF_SUPPLY_7_8 = LPCOMP_REFSEL_REFSEL_SupplySevenEighthsPrescaling, /**< Use supply with a 7/8 prescaler as reference. */
+#elif (LPCOMP_REFSEL_RESOLUTION == 16) || defined(__SDK_DOXYGEN__)
+ NRF_LPCOMP_REF_SUPPLY_1_8 = LPCOMP_REFSEL_REFSEL_Ref1_8Vdd, /**< Use supply with a 1/8 prescaler as reference. */
+ NRF_LPCOMP_REF_SUPPLY_2_8 = LPCOMP_REFSEL_REFSEL_Ref2_8Vdd, /**< Use supply with a 2/8 prescaler as reference. */
+ NRF_LPCOMP_REF_SUPPLY_3_8 = LPCOMP_REFSEL_REFSEL_Ref3_8Vdd, /**< Use supply with a 3/8 prescaler as reference. */
+ NRF_LPCOMP_REF_SUPPLY_4_8 = LPCOMP_REFSEL_REFSEL_Ref4_8Vdd, /**< Use supply with a 4/8 prescaler as reference. */
+ NRF_LPCOMP_REF_SUPPLY_5_8 = LPCOMP_REFSEL_REFSEL_Ref5_8Vdd, /**< Use supply with a 5/8 prescaler as reference. */
+ NRF_LPCOMP_REF_SUPPLY_6_8 = LPCOMP_REFSEL_REFSEL_Ref6_8Vdd, /**< Use supply with a 6/8 prescaler as reference. */
+ NRF_LPCOMP_REF_SUPPLY_7_8 = LPCOMP_REFSEL_REFSEL_Ref7_8Vdd, /**< Use supply with a 7/8 prescaler as reference. */
+ NRF_LPCOMP_REF_SUPPLY_1_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 1/16 prescaler as reference. */
+ NRF_LPCOMP_REF_SUPPLY_3_16 = LPCOMP_REFSEL_REFSEL_Ref3_16Vdd, /**< Use supply with a 3/16 prescaler as reference. */
+ NRF_LPCOMP_REF_SUPPLY_5_16 = LPCOMP_REFSEL_REFSEL_Ref5_16Vdd, /**< Use supply with a 5/16 prescaler as reference. */
+ NRF_LPCOMP_REF_SUPPLY_7_16 = LPCOMP_REFSEL_REFSEL_Ref7_16Vdd, /**< Use supply with a 7/16 prescaler as reference. */
+ NRF_LPCOMP_REF_SUPPLY_9_16 = LPCOMP_REFSEL_REFSEL_Ref9_16Vdd, /**< Use supply with a 9/16 prescaler as reference. */
+ NRF_LPCOMP_REF_SUPPLY_11_16 = LPCOMP_REFSEL_REFSEL_Ref11_16Vdd, /**< Use supply with a 11/16 prescaler as reference. */
+ NRF_LPCOMP_REF_SUPPLY_13_16 = LPCOMP_REFSEL_REFSEL_Ref13_16Vdd, /**< Use supply with a 13/16 prescaler as reference. */
+ NRF_LPCOMP_REF_SUPPLY_15_16 = LPCOMP_REFSEL_REFSEL_Ref15_16Vdd, /**< Use supply with a 15/16 prescaler as reference. */
+#endif
+ NRF_LPCOMP_REF_EXT_REF0 = LPCOMP_REFSEL_REFSEL_ARef |
+ (LPCOMP_EXTREFSEL_EXTREFSEL_AnalogReference0 << 16), /**< External reference 0. */
+ NRF_LPCOMP_CONFIG_REF_EXT_REF1 = LPCOMP_REFSEL_REFSEL_ARef |
+ (LPCOMP_EXTREFSEL_EXTREFSEL_AnalogReference1 << 16), /**< External reference 1. */
+} nrf_lpcomp_ref_t;
+
+/**
+ * @enum nrf_lpcomp_input_t
+ * @brief LPCOMP input selection.
+ */
+typedef enum
+{
+ NRF_LPCOMP_INPUT_0 = LPCOMP_PSEL_PSEL_AnalogInput0, /**< Input 0. */
+ NRF_LPCOMP_INPUT_1 = LPCOMP_PSEL_PSEL_AnalogInput1, /**< Input 1. */
+ NRF_LPCOMP_INPUT_2 = LPCOMP_PSEL_PSEL_AnalogInput2, /**< Input 2. */
+ NRF_LPCOMP_INPUT_3 = LPCOMP_PSEL_PSEL_AnalogInput3, /**< Input 3. */
+ NRF_LPCOMP_INPUT_4 = LPCOMP_PSEL_PSEL_AnalogInput4, /**< Input 4. */
+ NRF_LPCOMP_INPUT_5 = LPCOMP_PSEL_PSEL_AnalogInput5, /**< Input 5. */
+ NRF_LPCOMP_INPUT_6 = LPCOMP_PSEL_PSEL_AnalogInput6, /**< Input 6. */
+ NRF_LPCOMP_INPUT_7 = LPCOMP_PSEL_PSEL_AnalogInput7 /**< Input 7. */
+} nrf_lpcomp_input_t;
+
+/**
+ * @enum nrf_lpcomp_detect_t
+ * @brief LPCOMP detection type selection.
+ */
+typedef enum
+{
+ NRF_LPCOMP_DETECT_CROSS = LPCOMP_ANADETECT_ANADETECT_Cross, /**< Generate ANADETEC on crossing, both upwards and downwards crossing. */
+ NRF_LPCOMP_DETECT_UP = LPCOMP_ANADETECT_ANADETECT_Up, /**< Generate ANADETEC on upwards crossing only. */
+ NRF_LPCOMP_DETECT_DOWN = LPCOMP_ANADETECT_ANADETECT_Down /**< Generate ANADETEC on downwards crossing only. */
+} nrf_lpcomp_detect_t;
+
+/**
+ * @enum nrf_lpcomp_task_t
+ * @brief LPCOMP tasks.
+ */
+typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
+{
+ NRF_LPCOMP_TASK_START = offsetof(NRF_LPCOMP_Type, TASKS_START), /**< LPCOMP start sampling task. */
+ NRF_LPCOMP_TASK_STOP = offsetof(NRF_LPCOMP_Type, TASKS_STOP), /**< LPCOMP stop sampling task. */
+ NRF_LPCOMP_TASK_SAMPLE = offsetof(NRF_LPCOMP_Type, TASKS_SAMPLE) /**< Sample comparator value. */
+} nrf_lpcomp_task_t; /*lint -restore*/
+
+
+/**
+ * @enum nrf_lpcomp_event_t
+ * @brief LPCOMP events.
+ */
+typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
+{
+ NRF_LPCOMP_EVENT_READY = offsetof(NRF_LPCOMP_Type, EVENTS_READY), /**< LPCOMP is ready and output is valid. */
+ NRF_LPCOMP_EVENT_DOWN = offsetof(NRF_LPCOMP_Type, EVENTS_DOWN), /**< Input voltage crossed the threshold going down. */
+ NRF_LPCOMP_EVENT_UP = offsetof(NRF_LPCOMP_Type, EVENTS_UP), /**< Input voltage crossed the threshold going up. */
+ NRF_LPCOMP_EVENT_CROSS = offsetof(NRF_LPCOMP_Type, EVENTS_CROSS) /**< Input voltage crossed the threshold in any direction. */
+} nrf_lpcomp_event_t; /*lint -restore*/
+
+/**
+ * @enum nrf_lpcomp_short_mask_t
+ * @brief LPCOMP shorts masks.
+ */
+typedef enum
+{
+ NRF_LPCOMP_SHORT_CROSS_STOP_MASK = LPCOMP_SHORTS_CROSS_STOP_Msk, /*!< Short between CROSS event and STOP task. */
+ NRF_LPCOMP_SHORT_UP_STOP_MASK = LPCOMP_SHORTS_UP_STOP_Msk, /*!< Short between UP event and STOP task. */
+ NRF_LPCOMP_SHORT_DOWN_STOP_MASK = LPCOMP_SHORTS_DOWN_STOP_Msk, /*!< Short between DOWN event and STOP task. */
+ NRF_LPCOMP_SHORT_READY_STOP_MASK = LPCOMP_SHORTS_READY_STOP_Msk, /*!< Short between READY event and STOP task. */
+ NRF_LPCOMP_SHORT_READY_SAMPLE_MASK = LPCOMP_SHORTS_READY_SAMPLE_Msk /*!< Short between READY event and SAMPLE task. */
+} nrf_lpcomp_short_mask_t;
+
+#ifdef LPCOMP_FEATURE_HYST_PRESENT
+/**
+ * @enum nrf_lpcomp_hysteresis_t
+ * @brief LPCOMP hysteresis.
+ */
+typedef enum
+{
+ NRF_LPCOMP_HYST_NOHYST = LPCOMP_HYST_HYST_NoHyst, /**< Comparator hysteresis disabled. */
+ NRF_LPCOMP_HYST_50mV = LPCOMP_HYST_HYST_Hyst50mV /**< Comparator hysteresis enabled (typ. 50 mV). */
+}nrf_lpcomp_hysteresis_t;
+#endif // LPCOMP_FEATURE_HYST_PRESENT
+
+/** @brief LPCOMP configuration. */
+typedef struct
+{
+ nrf_lpcomp_ref_t reference; /**< LPCOMP reference. */
+ nrf_lpcomp_detect_t detection; /**< LPCOMP detection type. */
+#ifdef LPCOMP_FEATURE_HYST_PRESENT
+ nrf_lpcomp_hysteresis_t hyst; /**< LPCOMP hysteresis. */
+#endif // LPCOMP_FEATURE_HYST_PRESENT
+} nrf_lpcomp_config_t;
+
+/** Default LPCOMP configuration. */
+#define NRF_LPCOMP_CONFIG_DEFAULT { NRF_LPCOMP_REF_SUPPLY_FOUR_EIGHT, NRF_LPCOMP_DETECT_DOWN }
+
+/**
+ * @brief Function for configuring LPCOMP.
+ *
+ * This function powers on LPCOMP and configures it. LPCOMP is in DISABLE state after configuration,
+ * so it must be enabled before using it. All shorts are inactive, events are cleared, and LPCOMP is stopped.
+ *
+ * @param[in] p_config Configuration.
+ */
+__STATIC_INLINE void nrf_lpcomp_configure(const nrf_lpcomp_config_t * p_config)
+{
+ NRF_LPCOMP->TASKS_STOP = 1;
+ NRF_LPCOMP->ENABLE = LPCOMP_ENABLE_ENABLE_Disabled << LPCOMP_ENABLE_ENABLE_Pos;
+ NRF_LPCOMP->REFSEL =
+ (p_config->reference << LPCOMP_REFSEL_REFSEL_Pos) & LPCOMP_REFSEL_REFSEL_Msk;
+
+ //If external source is choosen extract analog reference index.
+ if ((p_config->reference & LPCOMP_REFSEL_REFSEL_ARef)==LPCOMP_REFSEL_REFSEL_ARef)
+ {
+ uint32_t extref = p_config->reference >> 16;
+ NRF_LPCOMP->EXTREFSEL = (extref << LPCOMP_EXTREFSEL_EXTREFSEL_Pos) & LPCOMP_EXTREFSEL_EXTREFSEL_Msk;
+ }
+
+ NRF_LPCOMP->ANADETECT =
+ (p_config->detection << LPCOMP_ANADETECT_ANADETECT_Pos) & LPCOMP_ANADETECT_ANADETECT_Msk;
+#ifdef LPCOMP_FEATURE_HYST_PRESENT
+ NRF_LPCOMP->HYST = ((p_config->hyst) << LPCOMP_HYST_HYST_Pos) & LPCOMP_HYST_HYST_Msk;
+#endif //LPCOMP_FEATURE_HYST_PRESENT
+ NRF_LPCOMP->SHORTS = 0;
+ NRF_LPCOMP->INTENCLR = LPCOMP_INTENCLR_CROSS_Msk | LPCOMP_INTENCLR_UP_Msk |
+ LPCOMP_INTENCLR_DOWN_Msk | LPCOMP_INTENCLR_READY_Msk;
+}
+
+
+/**
+ * @brief Function for selecting the LPCOMP input.
+ *
+ * This function selects the active input of LPCOMP.
+ *
+ * @param[in] input Input to be selected.
+ */
+__STATIC_INLINE void nrf_lpcomp_input_select(nrf_lpcomp_input_t input)
+{
+ uint32_t lpcomp_enable_state = NRF_LPCOMP->ENABLE;
+
+ NRF_LPCOMP->ENABLE = LPCOMP_ENABLE_ENABLE_Disabled << LPCOMP_ENABLE_ENABLE_Pos;
+ NRF_LPCOMP->PSEL =
+ ((uint32_t)input << LPCOMP_PSEL_PSEL_Pos) | (NRF_LPCOMP->PSEL & ~LPCOMP_PSEL_PSEL_Msk);
+ NRF_LPCOMP->ENABLE = lpcomp_enable_state;
+}
+
+
+/**
+ * @brief Function for enabling the Low Power Comparator.
+ *
+ * This function enables LPCOMP.
+ *
+ */
+__STATIC_INLINE void nrf_lpcomp_enable(void)
+{
+ NRF_LPCOMP->ENABLE = LPCOMP_ENABLE_ENABLE_Enabled << LPCOMP_ENABLE_ENABLE_Pos;
+ NRF_LPCOMP->EVENTS_READY = 0;
+ NRF_LPCOMP->EVENTS_DOWN = 0;
+ NRF_LPCOMP->EVENTS_UP = 0;
+ NRF_LPCOMP->EVENTS_CROSS = 0;
+}
+
+
+/**
+ * @brief Function for disabling the Low Power Comparator.
+ *
+ * This function disables LPCOMP.
+ *
+ */
+__STATIC_INLINE void nrf_lpcomp_disable(void)
+{
+ NRF_LPCOMP->ENABLE = LPCOMP_ENABLE_ENABLE_Disabled << LPCOMP_ENABLE_ENABLE_Pos;
+}
+
+
+/**
+ * @brief Function for getting the last LPCOMP compare result.
+ *
+ * @return The last compare result. If 0 then VIN+ < VIN-, if 1 then the opposite.
+ */
+__STATIC_INLINE uint32_t nrf_lpcomp_result_get(void)
+{
+ return (uint32_t)NRF_LPCOMP->RESULT;
+}
+
+
+/**
+ * @brief Function for enabling interrupts from LPCOMP.
+ *
+ * @param[in] lpcomp_int_mask Mask of interrupts to be enabled.
+ *
+ * @sa nrf_lpcomp_int_disable()
+ * @sa nrf_lpcomp_int_enable_check()
+ */
+__STATIC_INLINE void nrf_lpcomp_int_enable(uint32_t lpcomp_int_mask)
+{
+ NRF_LPCOMP->INTENSET = lpcomp_int_mask;
+}
+
+
+/**
+ * @brief Function for disabling interrupts from LPCOMP.
+ *
+ * @param[in] lpcomp_int_mask Mask of interrupts to be disabled.
+ *
+ * @sa nrf_lpcomp_int_enable()
+ * @sa nrf_lpcomp_int_enable_check()
+ */
+__STATIC_INLINE void nrf_lpcomp_int_disable(uint32_t lpcomp_int_mask)
+{
+ NRF_LPCOMP->INTENCLR = lpcomp_int_mask;
+}
+
+
+/**
+ * @brief Function for getting the enabled interrupts of LPCOMP.
+ *
+ * @param[in] lpcomp_int_mask Mask of interrupts to be checked.
+ *
+ * @retval true If any of interrupts of the specified mask are enabled.
+ *
+ * @sa nrf_lpcomp_int_enable()
+ * @sa nrf_lpcomp_int_disable()
+ */
+__STATIC_INLINE bool nrf_lpcomp_int_enable_check(uint32_t lpcomp_int_mask)
+{
+ return (NRF_LPCOMP->INTENSET & lpcomp_int_mask); // when read this register will return the value of INTEN.
+}
+
+
+/**
+ * @brief Function for getting the address of a specific LPCOMP task register.
+ *
+ * @param[in] lpcomp_task LPCOMP task.
+ *
+ * @return The address of the specified LPCOMP task.
+ */
+__STATIC_INLINE uint32_t * nrf_lpcomp_task_address_get(nrf_lpcomp_task_t lpcomp_task)
+{
+ return (uint32_t *)((uint8_t *)NRF_LPCOMP + lpcomp_task);
+}
+
+
+/**
+ * @brief Function for getting the address of a specific LPCOMP event register.
+ *
+ * @param[in] lpcomp_event LPCOMP event.
+ *
+ * @return The address of the specified LPCOMP event.
+ */
+__STATIC_INLINE uint32_t * nrf_lpcomp_event_address_get(nrf_lpcomp_event_t lpcomp_event)
+{
+ return (uint32_t *)((uint8_t *)NRF_LPCOMP + lpcomp_event);
+}
+
+
+/**
+ * @brief Function for setting LPCOMP shorts.
+ *
+ * @param[in] lpcomp_short_mask LPCOMP shorts by mask.
+ *
+ */
+__STATIC_INLINE void nrf_lpcomp_shorts_enable(uint32_t lpcomp_short_mask)
+{
+ NRF_LPCOMP->SHORTS |= lpcomp_short_mask;
+}
+
+
+/**
+ * @brief Function for clearing LPCOMP shorts by mask.
+ *
+ * @param[in] lpcomp_short_mask LPCOMP shorts to be cleared.
+ *
+ */
+__STATIC_INLINE void nrf_lpcomp_shorts_disable(uint32_t lpcomp_short_mask)
+{
+ NRF_LPCOMP->SHORTS &= ~lpcomp_short_mask;
+}
+
+
+/**
+ * @brief Function for setting a specific LPCOMP task.
+ *
+ * @param[in] lpcomp_task LPCOMP task to be set.
+ *
+ */
+__STATIC_INLINE void nrf_lpcomp_task_trigger(nrf_lpcomp_task_t lpcomp_task)
+{
+ *( (volatile uint32_t *)( (uint8_t *)NRF_LPCOMP + lpcomp_task) ) = 1;
+}
+
+
+/**
+ * @brief Function for clearing a specific LPCOMP event.
+ *
+ * @param[in] lpcomp_event LPCOMP event to be cleared.
+ *
+ */
+__STATIC_INLINE void nrf_lpcomp_event_clear(nrf_lpcomp_event_t lpcomp_event)
+{
+ *( (volatile uint32_t *)( (uint8_t *)NRF_LPCOMP + lpcomp_event) ) = 0;
+#if __CORTEX_M == 0x04
+ volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_LPCOMP + lpcomp_event));
+ (void)dummy;
+#endif
+}
+
+
+/**
+ * @brief Function for getting the state of a specific LPCOMP event.
+ *
+ * @retval true If the specified LPCOMP event is active.
+ *
+ */
+__STATIC_INLINE bool nrf_lpcomp_event_check(nrf_lpcomp_event_t lpcomp_event)
+{
+ return (bool) (*(volatile uint32_t *)( (uint8_t *)NRF_LPCOMP + lpcomp_event));
+}
+
+
+/**
+ *@}
+ **/
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_LPCOMP_H_ */
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_nvmc.c b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_nvmc.c
new file mode 100644
index 000000000..ccae784b6
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_nvmc.c
@@ -0,0 +1,136 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *@brief NMVC driver implementation
+ */
+
+#include <stdbool.h>
+#include "nrf.h"
+#include "nrf_nvmc.h"
+
+
+static inline void wait_for_flash_ready(void)
+{
+ while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {;}
+}
+
+
+void nrf_nvmc_page_erase(uint32_t address)
+{
+ // Enable erase.
+ NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Een;
+ __ISB();
+ __DSB();
+
+ // Erase the page
+ NRF_NVMC->ERASEPAGE = address;
+ wait_for_flash_ready();
+
+ NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
+ __ISB();
+ __DSB();
+}
+
+
+void nrf_nvmc_write_byte(uint32_t address, uint8_t value)
+{
+ uint32_t byte_shift = address & (uint32_t)0x03;
+ uint32_t address32 = address & ~byte_shift; // Address to the word this byte is in.
+ uint32_t value32 = (*(uint32_t*)address32 & ~((uint32_t)0xFF << (byte_shift << (uint32_t)3)));
+ value32 = value32 + ((uint32_t)value << (byte_shift << 3));
+
+ // Enable write.
+ NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen;
+ __ISB();
+ __DSB();
+
+ *(uint32_t*)address32 = value32;
+ wait_for_flash_ready();
+
+ NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
+ __ISB();
+ __DSB();
+}
+
+
+void nrf_nvmc_write_word(uint32_t address, uint32_t value)
+{
+ // Enable write.
+ NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen;
+ __ISB();
+ __DSB();
+
+ *(uint32_t*)address = value;
+ wait_for_flash_ready();
+
+ NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
+ __ISB();
+ __DSB();
+}
+
+
+void nrf_nvmc_write_bytes(uint32_t address, const uint8_t * src, uint32_t num_bytes)
+{
+ for (uint32_t i = 0; i < num_bytes; i++)
+ {
+ nrf_nvmc_write_byte(address + i, src[i]);
+ }
+}
+
+
+void nrf_nvmc_write_words(uint32_t address, const uint32_t * src, uint32_t num_words)
+{
+ // Enable write.
+ NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen;
+ __ISB();
+ __DSB();
+
+ for (uint32_t i = 0; i < num_words; i++)
+ {
+ ((uint32_t*)address)[i] = src[i];
+ wait_for_flash_ready();
+ }
+
+ NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
+ __ISB();
+ __DSB();
+}
+
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_nvmc.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_nvmc.h
new file mode 100644
index 000000000..b31c5b1b3
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_nvmc.h
@@ -0,0 +1,125 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ * @brief NMVC driver API.
+ */
+
+#ifndef NRF_NVMC_H__
+#define NRF_NVMC_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @defgroup nrf_nvmc Non-volatile memory controller
+ * @{
+ * @ingroup nrf_drivers
+ * @brief Driver for the NVMC peripheral.
+ *
+ * This driver allows writing to the non-volatile memory (NVM) regions
+ * of the chip. In order to write to NVM the controller must be powered
+ * on and the relevant page must be erased.
+ *
+ */
+
+
+/**
+ * @brief Erase a page in flash. This is required before writing to any
+ * address in the page.
+ *
+ * @param address Start address of the page.
+ */
+void nrf_nvmc_page_erase(uint32_t address);
+
+
+/**
+ * @brief Write a single byte to flash.
+ *
+ * The function reads the word containing the byte, and then
+ * rewrites the entire word.
+ *
+ * @param address Address to write to.
+ * @param value Value to write.
+ */
+void nrf_nvmc_write_byte(uint32_t address , uint8_t value);
+
+
+/**
+ * @brief Write a 32-bit word to flash.
+ * @param address Address to write to.
+ * @param value Value to write.
+ */
+void nrf_nvmc_write_word(uint32_t address, uint32_t value);
+
+
+/**
+ * @brief Write consecutive bytes to flash.
+ *
+ * @param address Address to write to.
+ * @param src Pointer to data to copy from.
+ * @param num_bytes Number of bytes in src to write.
+ */
+void nrf_nvmc_write_bytes(uint32_t address, const uint8_t * src, uint32_t num_bytes);
+
+
+/**
+ * @brief Write consecutive words to flash.
+ *
+ * @param address Address to write to.
+ * @param src Pointer to data to copy from.
+ * @param num_words Number of words in src to write.
+ */
+void nrf_nvmc_write_words(uint32_t address, const uint32_t * src, uint32_t num_words);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_NVMC_H__
+/** @} */
+
+
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_pdm.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_pdm.h
new file mode 100644
index 000000000..7937d7568
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_pdm.h
@@ -0,0 +1,396 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_PDM_H_
+#define NRF_PDM_H_
+
+/**
+ * @defgroup nrf_pdm_hal PDM HAL
+ * @{
+ * @ingroup nrf_pdm
+ *
+ * @brief @tagAPI52 Hardware abstraction layer for accessing the pulse density modulation (PDM) peripheral.
+ */
+
+#include <stdbool.h>
+#include <stddef.h>
+#include "nrf.h"
+#include "nrf_assert.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define NRF_PDM_GAIN_MINIMUM 0x00
+#define NRF_PDM_GAIN_DEFAULT 0x28
+#define NRF_PDM_GAIN_MAXIMUM 0x50
+
+typedef uint8_t nrf_pdm_gain_t;
+
+
+/**
+ * @brief PDM tasks.
+ */
+typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
+{
+ NRF_PDM_TASK_START = offsetof(NRF_PDM_Type, TASKS_START), ///< Starts continuous PDM transfer.
+ NRF_PDM_TASK_STOP = offsetof(NRF_PDM_Type, TASKS_STOP) ///< Stops PDM transfer.
+} nrf_pdm_task_t;
+
+
+/**
+ * @brief PDM events.
+ */
+typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
+{
+ NRF_PDM_EVENT_STARTED = offsetof(NRF_PDM_Type, EVENTS_STARTED), ///< PDM transfer has started.
+ NRF_PDM_EVENT_STOPPED = offsetof(NRF_PDM_Type, EVENTS_STOPPED), ///< PDM transfer has finished.
+ NRF_PDM_EVENT_END = offsetof(NRF_PDM_Type, EVENTS_END) ///< The PDM has written the last sample specified by SAMPLE.MAXCNT (or the last sample after a STOP task has been received) to Data RAM.
+} nrf_pdm_event_t;
+
+
+/**
+ * @brief PDM interrupt masks.
+ */
+typedef enum
+{
+ NRF_PDM_INT_STARTED = PDM_INTENSET_STARTED_Msk, ///< Interrupt on EVENTS_STARTED event.
+ NRF_PDM_INT_STOPPED = PDM_INTENSET_STOPPED_Msk, ///< Interrupt on EVENTS_STOPPED event.
+ NRF_PDM_INT_END = PDM_INTENSET_END_Msk ///< Interrupt on EVENTS_END event.
+} nrf_pdm_int_mask_t;
+
+/**
+ * @brief PDM clock frequency.
+ */
+typedef enum
+{
+ NRF_PDM_FREQ_1000K = PDM_PDMCLKCTRL_FREQ_1000K, ///< PDM_CLK = 1.000 MHz.
+ NRF_PDM_FREQ_1032K = PDM_PDMCLKCTRL_FREQ_Default, ///< PDM_CLK = 1.032 MHz.
+ NRF_PDM_FREQ_1067K = PDM_PDMCLKCTRL_FREQ_1067K ///< PDM_CLK = 1.067 MHz.
+} nrf_pdm_freq_t;
+
+
+/**
+ * @brief PDM operation mode.
+ */
+typedef enum
+{
+ NRF_PDM_MODE_STEREO = PDM_MODE_OPERATION_Stereo, ///< Sample and store one pair (Left + Right) of 16-bit samples per RAM word.
+ NRF_PDM_MODE_MONO = PDM_MODE_OPERATION_Mono ///< Sample and store two successive Left samples (16 bit each) per RAM word.
+} nrf_pdm_mode_t;
+
+
+/**
+ * @brief PDM sampling mode.
+ */
+typedef enum
+{
+ NRF_PDM_EDGE_LEFTFALLING = PDM_MODE_EDGE_LeftFalling, ///< Left (or mono) is sampled on falling edge of PDM_CLK.
+ NRF_PDM_EDGE_LEFTRISING = PDM_MODE_EDGE_LeftRising ///< Left (or mono) is sampled on rising edge of PDM_CLK.
+} nrf_pdm_edge_t;
+
+
+/**
+ * @brief Function for triggering a PDM task.
+ *
+ * @param[in] pdm_task PDM task.
+ */
+__STATIC_INLINE void nrf_pdm_task_trigger(nrf_pdm_task_t pdm_task)
+{
+ *((volatile uint32_t *)((uint8_t *)NRF_PDM + (uint32_t)pdm_task)) = 0x1UL;
+}
+
+
+/**
+ * @brief Function for getting the address of a PDM task register.
+ *
+ * @param[in] pdm_task PDM task.
+ *
+ * @return Address of the specified PDM task.
+ */
+__STATIC_INLINE uint32_t nrf_pdm_task_address_get(nrf_pdm_task_t pdm_task)
+{
+ return (uint32_t)((uint8_t *)NRF_PDM + (uint32_t)pdm_task);
+}
+
+
+/**
+ * @brief Function for getting the state of a PDM event.
+ *
+ * @param[in] pdm_event PDM event.
+ *
+ * @return State of the specified PDM event.
+ */
+__STATIC_INLINE bool nrf_pdm_event_check(nrf_pdm_event_t pdm_event)
+{
+ return (bool)*(volatile uint32_t *)((uint8_t *)NRF_PDM + (uint32_t)pdm_event);
+}
+
+
+/**
+ * @brief Function for clearing a PDM event.
+ *
+ * @param[in] pdm_event PDM event.
+ */
+__STATIC_INLINE void nrf_pdm_event_clear(nrf_pdm_event_t pdm_event)
+{
+ *((volatile uint32_t *)((uint8_t *)NRF_PDM + (uint32_t)pdm_event)) = 0x0UL;
+#if __CORTEX_M == 0x04
+ volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_PDM + (uint32_t)pdm_event));
+ (void)dummy;
+#endif
+}
+
+
+/**
+ * @brief Function for getting the address of a PDM event register.
+ *
+ * @param[in] pdm_event PDM event.
+ *
+ * @return Address of the specified PDM event.
+ */
+__STATIC_INLINE volatile uint32_t * nrf_pdm_event_address_get(nrf_pdm_event_t pdm_event)
+{
+ return (volatile uint32_t *)((uint8_t *)NRF_PDM + (uint32_t)pdm_event);
+}
+
+
+/**
+ * @brief Function for enabling PDM interrupts.
+ *
+ * @param[in] pdm_int_mask Interrupts to enable.
+ */
+__STATIC_INLINE void nrf_pdm_int_enable(uint32_t pdm_int_mask)
+{
+ NRF_PDM->INTENSET = pdm_int_mask;
+}
+
+
+/**
+ * @brief Function for retrieving the state of PDM interrupts.
+ *
+ * @param[in] pdm_int_mask Interrupts to check.
+ *
+ * @retval true If all specified interrupts are enabled.
+ * @retval false If at least one of the given interrupts is not enabled.
+ */
+__STATIC_INLINE bool nrf_pdm_int_enable_check(uint32_t pdm_int_mask)
+{
+ return (bool)(NRF_PDM->INTENSET & pdm_int_mask);
+}
+
+
+/**
+ * @brief Function for disabling interrupts.
+ *
+ * @param pdm_int_mask Interrupts to disable.
+ */
+__STATIC_INLINE void nrf_pdm_int_disable(uint32_t pdm_int_mask)
+{
+ NRF_PDM->INTENCLR = pdm_int_mask;
+}
+
+
+/**
+ * @brief Function for enabling the PDM peripheral.
+ *
+ * The PDM peripheral must be enabled before use.
+ */
+__STATIC_INLINE void nrf_pdm_enable(void)
+{
+ NRF_PDM->ENABLE = (PDM_ENABLE_ENABLE_Enabled << PDM_ENABLE_ENABLE_Pos);
+}
+
+
+/**
+ * @brief Function for disabling the PDM peripheral.
+ */
+__STATIC_INLINE void nrf_pdm_disable(void)
+{
+ NRF_PDM->ENABLE = (PDM_ENABLE_ENABLE_Disabled << PDM_ENABLE_ENABLE_Pos);
+}
+
+
+/**
+ * @brief Function for checking if the PDM peripheral is enabled.
+ *
+ * @retval true If the PDM peripheral is enabled.
+ * @retval false If the PDM peripheral is not enabled.
+ */
+__STATIC_INLINE bool nrf_pdm_enable_check(void)
+{
+ return (NRF_PDM->ENABLE == (PDM_ENABLE_ENABLE_Enabled << PDM_ENABLE_ENABLE_Pos));
+}
+
+
+/**
+ * @brief Function for setting the PDM operation mode.
+ *
+ * @param[in] pdm_mode PDM operation mode.
+ * @param[in] pdm_edge PDM sampling mode.
+ */
+__STATIC_INLINE void nrf_pdm_mode_set(nrf_pdm_mode_t pdm_mode, nrf_pdm_edge_t pdm_edge)
+{
+ NRF_PDM->MODE = ((pdm_mode << PDM_MODE_OPERATION_Pos) & PDM_MODE_OPERATION_Msk)
+ | ((pdm_edge << PDM_MODE_EDGE_Pos) & PDM_MODE_EDGE_Msk);
+}
+
+
+/**
+ * @brief Function for getting the PDM operation mode.
+ *
+ * @param[out] p_pdm_mode PDM operation mode.
+ * @param[out] p_pdm_edge PDM sampling mode.
+ */
+__STATIC_INLINE void nrf_pdm_mode_get(nrf_pdm_mode_t * p_pdm_mode, nrf_pdm_edge_t * p_pdm_edge)
+{
+ uint32_t mode = NRF_PDM->MODE;
+ *p_pdm_mode = (nrf_pdm_mode_t)((mode & PDM_MODE_OPERATION_Msk ) >> PDM_MODE_OPERATION_Pos);
+ *p_pdm_edge = (nrf_pdm_edge_t)((mode & PDM_MODE_EDGE_Msk ) >> PDM_MODE_EDGE_Pos);
+}
+
+
+/**
+ * @brief Function for setting the PDM clock frequency.
+ *
+ * @param[in] pdm_freq PDM clock frequency.
+ */
+__STATIC_INLINE void nrf_pdm_clock_set(nrf_pdm_freq_t pdm_freq)
+{
+ NRF_PDM->PDMCLKCTRL = ((pdm_freq << PDM_PDMCLKCTRL_FREQ_Pos) & PDM_PDMCLKCTRL_FREQ_Msk);
+}
+
+
+/**
+ * @brief Function for getting the PDM clock frequency.
+ */
+__STATIC_INLINE nrf_pdm_freq_t nrf_pdm_clock_get(void)
+{
+ return (nrf_pdm_freq_t) ((NRF_PDM->PDMCLKCTRL << PDM_PDMCLKCTRL_FREQ_Pos) & PDM_PDMCLKCTRL_FREQ_Msk);
+}
+
+
+/**
+ * @brief Function for setting up the PDM pins.
+ *
+ * @param[in] psel_clk CLK pin number.
+ * @param[in] psel_din DIN pin number.
+ */
+__STATIC_INLINE void nrf_pdm_psel_connect(uint32_t psel_clk, uint32_t psel_din)
+{
+ NRF_PDM->PSEL.CLK = psel_clk;
+ NRF_PDM->PSEL.DIN = psel_din;
+}
+
+/**
+ * @brief Function for disconnecting the PDM pins.
+ */
+__STATIC_INLINE void nrf_pdm_psel_disconnect()
+{
+ NRF_PDM->PSEL.CLK = ((PDM_PSEL_CLK_CONNECT_Disconnected << PDM_PSEL_CLK_CONNECT_Pos)
+ & PDM_PSEL_CLK_CONNECT_Msk);
+ NRF_PDM->PSEL.DIN = ((PDM_PSEL_DIN_CONNECT_Disconnected << PDM_PSEL_DIN_CONNECT_Pos)
+ & PDM_PSEL_DIN_CONNECT_Msk);
+}
+
+
+/**
+ * @brief Function for setting the PDM gain.
+ *
+ * @param[in] gain_l Left channel gain.
+ * @param[in] gain_r Right channel gain.
+ */
+__STATIC_INLINE void nrf_pdm_gain_set(nrf_pdm_gain_t gain_l, nrf_pdm_gain_t gain_r)
+{
+ NRF_PDM->GAINL = gain_l;
+ NRF_PDM->GAINR = gain_r;
+}
+
+
+/**
+ * @brief Function for getting the PDM gain.
+ *
+ * @param[out] p_gain_l Left channel gain.
+ * @param[out] p_gain_r Right channel gain.
+ */
+__STATIC_INLINE void nrf_pdm_gain_get(nrf_pdm_gain_t * p_gain_l, nrf_pdm_gain_t * p_gain_r)
+{
+ *p_gain_l = NRF_PDM->GAINL;
+ *p_gain_r = NRF_PDM->GAINR;
+}
+
+
+/**
+ * @brief Function for setting the PDM sample buffer.
+ *
+ * @param[in] p_buffer Pointer to the RAM address where samples should be written with EasyDMA.
+ * @param[in] num Number of samples to allocate memory for in EasyDMA mode.
+ *
+ * The amount of allocated RAM depends on the operation mode.
+ * - For stereo mode: N 32-bit words.
+ * - For mono mode: Ceil(N/2) 32-bit words.
+ */
+__STATIC_INLINE void nrf_pdm_buffer_set(uint32_t * p_buffer, uint32_t num)
+{
+ NRF_PDM->SAMPLE.PTR = (uint32_t)p_buffer;
+ NRF_PDM->SAMPLE.MAXCNT = num;
+}
+
+/**
+ * @brief Function for getting the current PDM sample buffer address.
+ *
+ * @return Pointer to the current sample buffer.
+ */
+__STATIC_INLINE uint32_t * nrf_pdm_buffer_get()
+{
+ return (uint32_t *)NRF_PDM->SAMPLE.PTR;
+}
+
+
+/**
+ *@}
+ **/
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_PDM_H_ */
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_peripherals.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_peripherals.h
new file mode 100644
index 000000000..a1cdd3b4d
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_peripherals.h
@@ -0,0 +1,73 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_PERIPHERALS_H
+#define NRF_PERIPHERALS_H
+
+/*lint ++flb "Enter library region */
+
+#ifdef NRF51422
+#include "nrf51422_peripherals.h"
+#endif
+
+#ifdef NRF51802
+#include "nrf51802_peripherals.h"
+#endif
+
+#ifdef NRF51822
+#include "nrf51822_peripherals.h"
+#endif
+
+#ifdef NRF52810_XXAA
+#include "nrf52810_peripherals.h"
+#endif
+
+#ifdef NRF52832_XXAA
+#include "nrf52832_peripherals.h"
+#endif
+
+#ifdef NRF52840_XXAA
+#include "nrf52840_peripherals.h"
+#endif
+
+
+/*lint --flb "Leave library region" */
+
+#endif /* NRF_PERIPHERALS_H */
+
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_power.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_power.h
new file mode 100644
index 000000000..13116cfee
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_power.h
@@ -0,0 +1,1065 @@
+/**
+ * Copyright (c) 2017 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_POWER_H__
+#define NRF_POWER_H__
+
+/**
+ * @ingroup nrf_power
+ * @defgroup nrf_power_hal POWER HAL
+ * @{
+ *
+ * Hardware access layer for (POWER) peripheral.
+ */
+#include "nrf.h"
+#include "sdk_config.h"
+#include "nordic_common.h"
+#include "nrf_assert.h"
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(POWER_RAMSTATUS_RAMBLOCK0_Msk)
+#define NRF_POWER_HAS_RAMSTATUS 1
+#else
+#define NRF_POWER_HAS_RAMSTATUS 0
+#endif
+
+/**
+ * @name The implemented functionality
+ * @{
+ *
+ * Macros that defines functionality that is implemented into POWER peripheral.
+ */
+#if defined(POWER_INTENSET_SLEEPENTER_Msk) || defined(__SDK_DOXYGEN__)
+/**
+ * @brief The fact that sleep events are present
+ *
+ * In some MCUs there is possibility to process sleep entering and exiting
+ * events.
+ */
+#define NRF_POWER_HAS_SLEEPEVT 1
+#else
+#define NRF_POWER_HAS_SLEEPEVT 0
+#endif
+
+#if defined(POWER_RAM_POWER_S0POWER_Msk) || defined(__SDK_DOXYGEN__)
+/**
+ * @brief The fact that RAMPOWER registers are present
+ *
+ * After nRF51, new way to manage RAM power was implemented.
+ * Special registers, one for every RAM block that makes it possible to
+ * power ON or OFF RAM segments and turn ON and OFF RAM retention in system OFF
+ * state.
+ */
+#define NRF_POWER_HAS_RAMPOWER_REGS 1
+#else
+#define NRF_POWER_HAS_RAMPOWER_REGS 0
+#endif
+
+#if defined(POWER_POFCON_THRESHOLDVDDH_Msk) || defined(__SDK_DOXYGEN__)
+/**
+ * @brief Auxiliary definition to mark the fact that VDDH is present
+ *
+ * This definition can be used in a code to decide if the part with VDDH
+ * related settings should be implemented.
+ */
+#define NRF_POWER_HAS_VDDH 1
+#else
+#define NRF_POWER_HAS_VDDH 0
+#endif
+
+#if defined(POWER_USBREGSTATUS_VBUSDETECT_Msk) || defined(__SDK_DOXYGEN__)
+/**
+ * @brief The fact that power module manages USB regulator
+ *
+ * In devices that have USB, power peripheral manages also connection
+ * detection and USB power regulator, that converts 5&nbsp;V to 3.3&nbsp;V
+ * used by USBD peripheral.
+ */
+#define NRF_POWER_HAS_USBREG 1
+#else
+#define NRF_POWER_HAS_USBREG 0
+#endif
+/** @} */
+
+/* ------------------------------------------------------------------------------------------------
+ * Begin of automatically generated part
+ * ------------------------------------------------------------------------------------------------
+ */
+
+/**
+ * @brief POWER tasks
+ */
+typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
+{
+ NRF_POWER_TASK_CONSTLAT = offsetof(NRF_POWER_Type, TASKS_CONSTLAT), /**< Enable constant latency mode */
+ NRF_POWER_TASK_LOWPWR = offsetof(NRF_POWER_Type, TASKS_LOWPWR ), /**< Enable low power mode (variable latency) */
+}nrf_power_task_t; /*lint -restore */
+
+/**
+ * @brief POWER events
+ */
+typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
+{
+ NRF_POWER_EVENT_POFWARN = offsetof(NRF_POWER_Type, EVENTS_POFWARN ), /**< Power failure warning */
+#if NRF_POWER_HAS_SLEEPEVT
+ NRF_POWER_EVENT_SLEEPENTER = offsetof(NRF_POWER_Type, EVENTS_SLEEPENTER ), /**< CPU entered WFI/WFE sleep */
+ NRF_POWER_EVENT_SLEEPEXIT = offsetof(NRF_POWER_Type, EVENTS_SLEEPEXIT ), /**< CPU exited WFI/WFE sleep */
+#endif
+#if NRF_POWER_HAS_USBREG
+ NRF_POWER_EVENT_USBDETECTED = offsetof(NRF_POWER_Type, EVENTS_USBDETECTED), /**< Voltage supply detected on VBUS */
+ NRF_POWER_EVENT_USBREMOVED = offsetof(NRF_POWER_Type, EVENTS_USBREMOVED ), /**< Voltage supply removed from VBUS */
+ NRF_POWER_EVENT_USBPWRRDY = offsetof(NRF_POWER_Type, EVENTS_USBPWRRDY ), /**< USB 3.3&nbsp;V supply ready */
+#endif
+}nrf_power_event_t; /*lint -restore */
+
+/**
+ * @brief POWER interrupts
+ */
+typedef enum
+{
+ NRF_POWER_INT_POFWARN_MASK = POWER_INTENSET_POFWARN_Msk , /**< Write '1' to Enable interrupt for POFWARN event */
+#if NRF_POWER_HAS_SLEEPEVT
+ NRF_POWER_INT_SLEEPENTER_MASK = POWER_INTENSET_SLEEPENTER_Msk , /**< Write '1' to Enable interrupt for SLEEPENTER event */
+ NRF_POWER_INT_SLEEPEXIT_MASK = POWER_INTENSET_SLEEPEXIT_Msk , /**< Write '1' to Enable interrupt for SLEEPEXIT event */
+#endif
+#if NRF_POWER_HAS_USBREG
+ NRF_POWER_INT_USBDETECTED_MASK = POWER_INTENSET_USBDETECTED_Msk, /**< Write '1' to Enable interrupt for USBDETECTED event */
+ NRF_POWER_INT_USBREMOVED_MASK = POWER_INTENSET_USBREMOVED_Msk , /**< Write '1' to Enable interrupt for USBREMOVED event */
+ NRF_POWER_INT_USBPWRRDY_MASK = POWER_INTENSET_USBPWRRDY_Msk , /**< Write '1' to Enable interrupt for USBPWRRDY event */
+#endif
+}nrf_power_int_mask_t;
+
+/**
+ * @brief Function for activating a specific POWER task.
+ *
+ * @param task Task.
+ */
+__STATIC_INLINE void nrf_power_task_trigger(nrf_power_task_t task);
+
+/**
+ * @brief Function for returning the address of a specific POWER task register.
+ *
+ * @param task Task.
+ *
+ * @return Task address.
+ */
+__STATIC_INLINE uint32_t nrf_power_task_address_get(nrf_power_task_t task);
+
+/**
+ * @brief Function for clearing a specific event.
+ *
+ * @param event Event.
+ */
+__STATIC_INLINE void nrf_power_event_clear(nrf_power_event_t event);
+
+/**
+ * @brief Function for returning the state of a specific event.
+ *
+ * @param event Event.
+ *
+ * @retval true If the event is set.
+ * @retval false If the event is not set.
+ */
+__STATIC_INLINE bool nrf_power_event_check(nrf_power_event_t event);
+
+/**
+ * @brief Function for getting and clearing the state of specific event
+ *
+ * This function checks the state of the event and clears it.
+ *
+ * @param event Event.
+ *
+ * @retval true If the event was set.
+ * @retval false If the event was not set.
+ */
+__STATIC_INLINE bool nrf_power_event_get_and_clear(nrf_power_event_t event);
+
+/**
+ * @brief Function for returning the address of a specific POWER event register.
+ *
+ * @param event Event.
+ *
+ * @return Address.
+ */
+__STATIC_INLINE uint32_t nrf_power_event_address_get(nrf_power_event_t event);
+
+/**
+ * @brief Function for enabling selected interrupts.
+ *
+ * @param int_mask Interrupts mask.
+ */
+__STATIC_INLINE void nrf_power_int_enable(uint32_t int_mask);
+
+/**
+ * @brief Function for retrieving the state of selected interrupts.
+ *
+ * @param int_mask Interrupts mask.
+ *
+ * @retval true If any of selected interrupts is enabled.
+ * @retval false If none of selected interrupts is enabled.
+ */
+__STATIC_INLINE bool nrf_power_int_enable_check(uint32_t int_mask);
+
+/**
+ * @brief Function for retrieving the information about enabled interrupts.
+ *
+ * @return The flags of enabled interrupts.
+ */
+__STATIC_INLINE uint32_t nrf_power_int_enable_get(void);
+
+/**
+ * @brief Function for disabling selected interrupts.
+ *
+ * @param int_mask Interrupts mask.
+ */
+__STATIC_INLINE void nrf_power_int_disable(uint32_t int_mask);
+
+
+/** @} */ /* End of nrf_power_hal */
+
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+/* ------------------------------------------------------------------------------------------------
+ * Internal functions
+ */
+
+/**
+ * @internal
+ * @brief Internal function for getting task/event register address
+ *
+ * @oaram offset Offset of the register from the instance beginning
+ *
+ * @attention offset has to be modulo 4 value. In other case we can get hardware fault.
+ * @return Pointer to the register
+ */
+__STATIC_INLINE volatile uint32_t * nrf_power_regptr_get(uint32_t offset)
+{
+ return (volatile uint32_t *)(((uint8_t *)NRF_POWER) + (uint32_t)offset);
+}
+
+/**
+ * @internal
+ * @brief Internal function for getting task/event register address - constant version
+ *
+ * @oaram offset Offset of the register from the instance beginning
+ *
+ * @attention offset has to be modulo 4 value. In other case we can get hardware fault.
+ * @return Pointer to the register
+ */
+__STATIC_INLINE volatile const uint32_t * nrf_power_regptr_get_c(
+ uint32_t offset)
+{
+ return (volatile const uint32_t *)(((uint8_t *)NRF_POWER) +
+ (uint32_t)offset);
+}
+
+/* ------------------------------------------------------------------------------------------------
+ * Interface functions definitions
+ */
+
+void nrf_power_task_trigger(nrf_power_task_t task)
+{
+ *(nrf_power_regptr_get((uint32_t)task)) = 1UL;
+}
+
+uint32_t nrf_power_task_address_get(nrf_power_task_t task)
+{
+ return (uint32_t)nrf_power_regptr_get_c((uint32_t)task);
+}
+
+void nrf_power_event_clear(nrf_power_event_t event)
+{
+ *(nrf_power_regptr_get((uint32_t)event)) = 0UL;
+}
+
+bool nrf_power_event_check(nrf_power_event_t event)
+{
+ return (bool)*nrf_power_regptr_get_c((uint32_t)event);
+}
+
+bool nrf_power_event_get_and_clear(nrf_power_event_t event)
+{
+ bool ret = nrf_power_event_check(event);
+ if (ret)
+ {
+ nrf_power_event_clear(event);
+ }
+ return ret;
+}
+
+uint32_t nrf_power_event_address_get(nrf_power_event_t event)
+{
+ return (uint32_t)nrf_power_regptr_get_c((uint32_t)event);
+}
+
+void nrf_power_int_enable(uint32_t int_mask)
+{
+ NRF_POWER->INTENSET = int_mask;
+}
+
+bool nrf_power_int_enable_check(uint32_t int_mask)
+{
+ return !!(NRF_POWER->INTENSET & int_mask);
+}
+
+uint32_t nrf_power_int_enable_get(void)
+{
+ return NRF_POWER->INTENSET;
+}
+
+void nrf_power_int_disable(uint32_t int_mask)
+{
+ NRF_POWER->INTENCLR = int_mask;
+}
+
+#endif /* SUPPRESS_INLINE_IMPLEMENTATION */
+
+/* ------------------------------------------------------------------------------------------------
+ * End of automatically generated part
+ * ------------------------------------------------------------------------------------------------
+ */
+/**
+ * @ingroup nrf_power_hal
+ * @{
+ */
+
+/**
+ * @brief Reset reason
+ */
+typedef enum
+{
+ NRF_POWER_RESETREAS_RESETPIN_MASK = POWER_RESETREAS_RESETPIN_Msk, /*!< Bit mask of RESETPIN field. *///!< NRF_POWER_RESETREAS_RESETPIN_MASK
+ NRF_POWER_RESETREAS_DOG_MASK = POWER_RESETREAS_DOG_Msk , /*!< Bit mask of DOG field. */ //!< NRF_POWER_RESETREAS_DOG_MASK
+ NRF_POWER_RESETREAS_SREQ_MASK = POWER_RESETREAS_SREQ_Msk , /*!< Bit mask of SREQ field. */ //!< NRF_POWER_RESETREAS_SREQ_MASK
+ NRF_POWER_RESETREAS_LOCKUP_MASK = POWER_RESETREAS_LOCKUP_Msk , /*!< Bit mask of LOCKUP field. */ //!< NRF_POWER_RESETREAS_LOCKUP_MASK
+ NRF_POWER_RESETREAS_OFF_MASK = POWER_RESETREAS_OFF_Msk , /*!< Bit mask of OFF field. */ //!< NRF_POWER_RESETREAS_OFF_MASK
+#if defined(POWER_RESETREAS_LPCOMP_Msk) || defined(__SDK_DOXYGEN__)
+ NRF_POWER_RESETREAS_LPCOMP_MASK = POWER_RESETREAS_LPCOMP_Msk , /*!< Bit mask of LPCOMP field. */ //!< NRF_POWER_RESETREAS_LPCOMP_MASK
+#endif
+ NRF_POWER_RESETREAS_DIF_MASK = POWER_RESETREAS_DIF_Msk , /*!< Bit mask of DIF field. */ //!< NRF_POWER_RESETREAS_DIF_MASK
+#if defined(POWER_RESETREAS_NFC_Msk) || defined(__SDK_DOXYGEN__)
+ NRF_POWER_RESETREAS_NFC_MASK = POWER_RESETREAS_NFC_Msk , /*!< Bit mask of NFC field. */
+#endif
+#if defined(POWER_RESETREAS_VBUS_Msk) || defined(__SDK_DOXYGEN__)
+ NRF_POWER_RESETREAS_VBUS_MASK = POWER_RESETREAS_VBUS_Msk , /*!< Bit mask of VBUS field. */
+#endif
+}nrf_power_resetreas_mask_t;
+
+#if NRF_POWER_HAS_USBREG
+/**
+ * @brief USBREGSTATUS register bit masks
+ *
+ * @sa nrf_power_usbregstatus_get
+ */
+typedef enum
+{
+ NRF_POWER_USBREGSTATUS_VBUSDETECT_MASK = POWER_USBREGSTATUS_VBUSDETECT_Msk, /**< USB detected or removed */
+ NRF_POWER_USBREGSTATUS_OUTPUTRDY_MASK = POWER_USBREGSTATUS_OUTPUTRDY_Msk /**< USB 3.3&nbsp;V supply ready */
+}nrf_power_usbregstatus_mask_t;
+#endif
+
+#if NRF_POWER_HAS_RAMSTATUS
+/**
+ * @brief RAM blocks numbers
+ *
+ * @sa nrf_power_ramblock_mask_t
+ * @note
+ * Ram blocks has to been used in nrf51.
+ * In new CPU ram is divided into segments and this functionality is depreciated.
+ * For the newer MCU see the PS for mapping between internal RAM and RAM blocks,
+ * because this mapping is not 1:1, and functions related to old style blocks
+ * should not be used.
+ */
+typedef enum
+{
+ NRF_POWER_RAMBLOCK0 = POWER_RAMSTATUS_RAMBLOCK0_Pos,
+ NRF_POWER_RAMBLOCK1 = POWER_RAMSTATUS_RAMBLOCK1_Pos,
+ NRF_POWER_RAMBLOCK2 = POWER_RAMSTATUS_RAMBLOCK2_Pos,
+ NRF_POWER_RAMBLOCK3 = POWER_RAMSTATUS_RAMBLOCK3_Pos
+}nrf_power_ramblock_t;
+
+/**
+ * @brief RAM blocks masks
+ *
+ * @sa nrf_power_ramblock_t
+ */
+
+typedef enum
+{
+ NRF_POWER_RAMBLOCK0_MASK = POWER_RAMSTATUS_RAMBLOCK0_Msk,
+ NRF_POWER_RAMBLOCK1_MASK = POWER_RAMSTATUS_RAMBLOCK1_Msk,
+ NRF_POWER_RAMBLOCK2_MASK = POWER_RAMSTATUS_RAMBLOCK2_Msk,
+ NRF_POWER_RAMBLOCK3_MASK = POWER_RAMSTATUS_RAMBLOCK3_Msk
+}nrf_power_ramblock_mask_t;
+#endif // NRF_POWER_HAS_RAMSTATUS
+
+/**
+ * @brief RAM power state position of the bits
+ *
+ * @sa nrf_power_onoffram_mask_t
+ */
+typedef enum
+{
+ NRF_POWER_ONRAM0, /**< Keep RAM block 0 on or off in system ON Mode */
+ NRF_POWER_OFFRAM0, /**< Keep retention on RAM block 0 when RAM block is switched off */
+ NRF_POWER_ONRAM1, /**< Keep RAM block 1 on or off in system ON Mode */
+ NRF_POWER_OFFRAM1, /**< Keep retention on RAM block 1 when RAM block is switched off */
+ NRF_POWER_ONRAM2, /**< Keep RAM block 2 on or off in system ON Mode */
+ NRF_POWER_OFFRAM2, /**< Keep retention on RAM block 2 when RAM block is switched off */
+ NRF_POWER_ONRAM3, /**< Keep RAM block 3 on or off in system ON Mode */
+ NRF_POWER_OFFRAM3, /**< Keep retention on RAM block 3 when RAM block is switched off */
+}nrf_power_onoffram_t;
+
+/**
+ * @brief RAM power state bit masks
+ *
+ * @sa nrf_power_onoffram_t
+ */
+typedef enum
+{
+ NRF_POWER_ONRAM0_MASK = 1U << NRF_POWER_ONRAM0, /**< Keep RAM block 0 on or off in system ON Mode */
+ NRF_POWER_OFFRAM0_MASK = 1U << NRF_POWER_OFFRAM0, /**< Keep retention on RAM block 0 when RAM block is switched off */
+ NRF_POWER_ONRAM1_MASK = 1U << NRF_POWER_ONRAM1, /**< Keep RAM block 1 on or off in system ON Mode */
+ NRF_POWER_OFFRAM1_MASK = 1U << NRF_POWER_OFFRAM1, /**< Keep retention on RAM block 1 when RAM block is switched off */
+ NRF_POWER_ONRAM2_MASK = 1U << NRF_POWER_ONRAM2, /**< Keep RAM block 2 on or off in system ON Mode */
+ NRF_POWER_OFFRAM2_MASK = 1U << NRF_POWER_OFFRAM2, /**< Keep retention on RAM block 2 when RAM block is switched off */
+ NRF_POWER_ONRAM3_MASK = 1U << NRF_POWER_ONRAM3, /**< Keep RAM block 3 on or off in system ON Mode */
+ NRF_POWER_OFFRAM3_MASK = 1U << NRF_POWER_OFFRAM3, /**< Keep retention on RAM block 3 when RAM block is switched off */
+}nrf_power_onoffram_mask_t;
+
+/**
+ * @brief Power failure comparator thresholds
+ */
+typedef enum
+{
+ NRF_POWER_POFTHR_V21 = POWER_POFCON_THRESHOLD_V21, /**< Set threshold to 2.1&nbsp;V */
+ NRF_POWER_POFTHR_V23 = POWER_POFCON_THRESHOLD_V23, /**< Set threshold to 2.3&nbsp;V */
+ NRF_POWER_POFTHR_V25 = POWER_POFCON_THRESHOLD_V25, /**< Set threshold to 2.5&nbsp;V */
+ NRF_POWER_POFTHR_V27 = POWER_POFCON_THRESHOLD_V27, /**< Set threshold to 2.7&nbsp;V */
+#if defined(POWER_POFCON_THRESHOLD_V17) || defined(__SDK_DOXYGEN__)
+ NRF_POWER_POFTHR_V17 = POWER_POFCON_THRESHOLD_V17, /**< Set threshold to 1.7&nbsp;V */
+ NRF_POWER_POFTHR_V18 = POWER_POFCON_THRESHOLD_V18, /**< Set threshold to 1.8&nbsp;V */
+ NRF_POWER_POFTHR_V19 = POWER_POFCON_THRESHOLD_V19, /**< Set threshold to 1.9&nbsp;V */
+ NRF_POWER_POFTHR_V20 = POWER_POFCON_THRESHOLD_V20, /**< Set threshold to 2.0&nbsp;V */
+ NRF_POWER_POFTHR_V22 = POWER_POFCON_THRESHOLD_V22, /**< Set threshold to 2.2&nbsp;V */
+ NRF_POWER_POFTHR_V24 = POWER_POFCON_THRESHOLD_V24, /**< Set threshold to 2.4&nbsp;V */
+ NRF_POWER_POFTHR_V26 = POWER_POFCON_THRESHOLD_V26, /**< Set threshold to 2.6&nbsp;V */
+ NRF_POWER_POFTHR_V28 = POWER_POFCON_THRESHOLD_V28, /**< Set threshold to 2.8&nbsp;V */
+#endif
+}nrf_power_pof_thr_t;
+
+#if NRF_POWER_HAS_VDDH
+/**
+ * @brief Power failure comparator thresholds for VDDH
+ */
+typedef enum
+{
+ NRF_POWER_POFTHRVDDH_V27 = POWER_POFCON_THRESHOLDVDDH_V27, /**< Set threshold to 2.7&nbsp;V */
+ NRF_POWER_POFTHRVDDH_V28 = POWER_POFCON_THRESHOLDVDDH_V28, /**< Set threshold to 2.8&nbsp;V */
+ NRF_POWER_POFTHRVDDH_V29 = POWER_POFCON_THRESHOLDVDDH_V29, /**< Set threshold to 2.9&nbsp;V */
+ NRF_POWER_POFTHRVDDH_V30 = POWER_POFCON_THRESHOLDVDDH_V30, /**< Set threshold to 3.0&nbsp;V */
+ NRF_POWER_POFTHRVDDH_V31 = POWER_POFCON_THRESHOLDVDDH_V31, /**< Set threshold to 3.1&nbsp;V */
+ NRF_POWER_POFTHRVDDH_V32 = POWER_POFCON_THRESHOLDVDDH_V32, /**< Set threshold to 3.2&nbsp;V */
+ NRF_POWER_POFTHRVDDH_V33 = POWER_POFCON_THRESHOLDVDDH_V33, /**< Set threshold to 3.3&nbsp;V */
+ NRF_POWER_POFTHRVDDH_V34 = POWER_POFCON_THRESHOLDVDDH_V34, /**< Set threshold to 3.4&nbsp;V */
+ NRF_POWER_POFTHRVDDH_V35 = POWER_POFCON_THRESHOLDVDDH_V35, /**< Set threshold to 3.5&nbsp;V */
+ NRF_POWER_POFTHRVDDH_V36 = POWER_POFCON_THRESHOLDVDDH_V36, /**< Set threshold to 3.6&nbsp;V */
+ NRF_POWER_POFTHRVDDH_V37 = POWER_POFCON_THRESHOLDVDDH_V37, /**< Set threshold to 3.7&nbsp;V */
+ NRF_POWER_POFTHRVDDH_V38 = POWER_POFCON_THRESHOLDVDDH_V38, /**< Set threshold to 3.8&nbsp;V */
+ NRF_POWER_POFTHRVDDH_V39 = POWER_POFCON_THRESHOLDVDDH_V39, /**< Set threshold to 3.9&nbsp;V */
+ NRF_POWER_POFTHRVDDH_V40 = POWER_POFCON_THRESHOLDVDDH_V40, /**< Set threshold to 4.0&nbsp;V */
+ NRF_POWER_POFTHRVDDH_V41 = POWER_POFCON_THRESHOLDVDDH_V41, /**< Set threshold to 4.1&nbsp;V */
+ NRF_POWER_POFTHRVDDH_V42 = POWER_POFCON_THRESHOLDVDDH_V42, /**< Set threshold to 4.2&nbsp;V */
+}nrf_power_pof_thrvddh_t;
+
+/**
+ * @brief Main regulator status
+ */
+typedef enum
+{
+ NRF_POWER_MAINREGSTATUS_NORMAL = POWER_MAINREGSTATUS_MAINREGSTATUS_Normal, /**< Normal voltage mode. Voltage supplied on VDD. */
+ NRF_POWER_MAINREGSTATUS_HIGH = POWER_MAINREGSTATUS_MAINREGSTATUS_High /**< High voltage mode. Voltage supplied on VDDH. */
+}nrf_power_mainregstatus_t;
+
+#endif /* NRF_POWER_HAS_VDDH */
+
+#if NRF_POWER_HAS_RAMPOWER_REGS
+/**
+ * @brief Bit positions for RAMPOWER register
+ *
+ * All possible bits described, even if they are not used in selected MCU.
+ */
+typedef enum
+{
+ /** Keep RAM section S0 ON in System ON mode */
+ NRF_POWER_RAMPOWER_S0POWER = POWER_RAM_POWER_S0POWER_Pos,
+ NRF_POWER_RAMPOWER_S1POWER, /**< Keep RAM section S1 ON in System ON mode */
+ NRF_POWER_RAMPOWER_S2POWER, /**< Keep RAM section S2 ON in System ON mode */
+ NRF_POWER_RAMPOWER_S3POWER, /**< Keep RAM section S3 ON in System ON mode */
+ NRF_POWER_RAMPOWER_S4POWER, /**< Keep RAM section S4 ON in System ON mode */
+ NRF_POWER_RAMPOWER_S5POWER, /**< Keep RAM section S5 ON in System ON mode */
+ NRF_POWER_RAMPOWER_S6POWER, /**< Keep RAM section S6 ON in System ON mode */
+ NRF_POWER_RAMPOWER_S7POWER, /**< Keep RAM section S7 ON in System ON mode */
+ NRF_POWER_RAMPOWER_S8POWER, /**< Keep RAM section S8 ON in System ON mode */
+ NRF_POWER_RAMPOWER_S9POWER, /**< Keep RAM section S9 ON in System ON mode */
+ NRF_POWER_RAMPOWER_S10POWER, /**< Keep RAM section S10 ON in System ON mode */
+ NRF_POWER_RAMPOWER_S11POWER, /**< Keep RAM section S11 ON in System ON mode */
+ NRF_POWER_RAMPOWER_S12POWER, /**< Keep RAM section S12 ON in System ON mode */
+ NRF_POWER_RAMPOWER_S13POWER, /**< Keep RAM section S13 ON in System ON mode */
+ NRF_POWER_RAMPOWER_S14POWER, /**< Keep RAM section S14 ON in System ON mode */
+ NRF_POWER_RAMPOWER_S15POWER, /**< Keep RAM section S15 ON in System ON mode */
+
+ /** Keep section retention in OFF mode when section is OFF */
+ NRF_POWER_RAMPOWER_S0RETENTION = POWER_RAM_POWER_S0RETENTION_Pos,
+ NRF_POWER_RAMPOWER_S1RETENTION, /**< Keep section retention in OFF mode when section is OFF */
+ NRF_POWER_RAMPOWER_S2RETENTION, /**< Keep section retention in OFF mode when section is OFF */
+ NRF_POWER_RAMPOWER_S3RETENTION, /**< Keep section retention in OFF mode when section is OFF */
+ NRF_POWER_RAMPOWER_S4RETENTION, /**< Keep section retention in OFF mode when section is OFF */
+ NRF_POWER_RAMPOWER_S5RETENTION, /**< Keep section retention in OFF mode when section is OFF */
+ NRF_POWER_RAMPOWER_S6RETENTION, /**< Keep section retention in OFF mode when section is OFF */
+ NRF_POWER_RAMPOWER_S7RETENTION, /**< Keep section retention in OFF mode when section is OFF */
+ NRF_POWER_RAMPOWER_S8RETENTION, /**< Keep section retention in OFF mode when section is OFF */
+ NRF_POWER_RAMPOWER_S9RETENTION, /**< Keep section retention in OFF mode when section is OFF */
+ NRF_POWER_RAMPOWER_S10RETENTION, /**< Keep section retention in OFF mode when section is OFF */
+ NRF_POWER_RAMPOWER_S11RETENTION, /**< Keep section retention in OFF mode when section is OFF */
+ NRF_POWER_RAMPOWER_S12RETENTION, /**< Keep section retention in OFF mode when section is OFF */
+ NRF_POWER_RAMPOWER_S13RETENTION, /**< Keep section retention in OFF mode when section is OFF */
+ NRF_POWER_RAMPOWER_S14RETENTION, /**< Keep section retention in OFF mode when section is OFF */
+ NRF_POWER_RAMPOWER_S15RETENTION, /**< Keep section retention in OFF mode when section is OFF */
+}nrf_power_rampower_t;
+
+#if defined ( __CC_ARM )
+#pragma push
+#pragma diag_suppress 66
+#endif
+/**
+ * @brief Bit masks for RAMPOWER register
+ *
+ * All possible bits described, even if they are not used in selected MCU.
+ */
+typedef enum
+{
+ NRF_POWER_RAMPOWER_S0POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S0POWER ,
+ NRF_POWER_RAMPOWER_S1POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S1POWER ,
+ NRF_POWER_RAMPOWER_S2POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S2POWER ,
+ NRF_POWER_RAMPOWER_S3POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S3POWER ,
+ NRF_POWER_RAMPOWER_S4POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S4POWER ,
+ NRF_POWER_RAMPOWER_S5POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S5POWER ,
+ NRF_POWER_RAMPOWER_S7POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S7POWER ,
+ NRF_POWER_RAMPOWER_S8POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S8POWER ,
+ NRF_POWER_RAMPOWER_S9POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S9POWER ,
+ NRF_POWER_RAMPOWER_S10POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S10POWER,
+ NRF_POWER_RAMPOWER_S11POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S11POWER,
+ NRF_POWER_RAMPOWER_S12POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S12POWER,
+ NRF_POWER_RAMPOWER_S13POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S13POWER,
+ NRF_POWER_RAMPOWER_S14POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S14POWER,
+ NRF_POWER_RAMPOWER_S15POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S15POWER,
+
+ NRF_POWER_RAMPOWER_S0RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S0RETENTION ,
+ NRF_POWER_RAMPOWER_S1RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S1RETENTION ,
+ NRF_POWER_RAMPOWER_S2RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S2RETENTION ,
+ NRF_POWER_RAMPOWER_S3RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S3RETENTION ,
+ NRF_POWER_RAMPOWER_S4RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S4RETENTION ,
+ NRF_POWER_RAMPOWER_S5RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S5RETENTION ,
+ NRF_POWER_RAMPOWER_S7RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S7RETENTION ,
+ NRF_POWER_RAMPOWER_S8RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S8RETENTION ,
+ NRF_POWER_RAMPOWER_S9RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S9RETENTION ,
+ NRF_POWER_RAMPOWER_S10RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S10RETENTION,
+ NRF_POWER_RAMPOWER_S11RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S11RETENTION,
+ NRF_POWER_RAMPOWER_S12RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S12RETENTION,
+ NRF_POWER_RAMPOWER_S13RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S13RETENTION,
+ NRF_POWER_RAMPOWER_S14RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S14RETENTION,
+ NRF_POWER_RAMPOWER_S15RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S15RETENTION,
+}nrf_power_rampower_mask_t;
+#if defined ( __CC_ARM )
+#pragma pop
+#endif
+#endif /* NRF_POWER_HAS_RAMPOWER_REGS */
+
+
+/**
+ * @brief Get reset reason mask
+ *
+ * Function returns the reset reason.
+ * Unless cleared, the RESETREAS register is cumulative.
+ * A field is cleared by writing '1' to it (see @ref nrf_power_resetreas_clear).
+ * If none of the reset sources are flagged,
+ * this indicates that the chip was reset from the on-chip reset generator,
+ * which indicates a power-on-reset or a brown out reset.
+ *
+ * @return The mask of reset reasons constructed with @ref nrf_power_resetreas_mask_t.
+ */
+__STATIC_INLINE uint32_t nrf_power_resetreas_get(void);
+
+/**
+ * @brief Clear selected reset reason field
+ *
+ * Function clears selected reset reason fields.
+ *
+ * @param[in] mask The mask constructed from @ref nrf_power_resetreas_mask_t enumerator values.
+ * @sa nrf_power_resetreas_get
+ */
+__STATIC_INLINE void nrf_power_resetreas_clear(uint32_t mask);
+
+#if NRF_POWER_HAS_RAMSTATUS
+/**
+ * @brief Get RAMSTATUS register
+ *
+ * Returns the masks of RAM blocks that are powered ON.
+ *
+ * @return Value with bits sets according to masks in @ref nrf_power_ramblock_mask_t.
+ */
+__STATIC_INLINE uint32_t nrf_power_ramstatus_get(void);
+#endif // NRF_POWER_HAS_RAMSTATUS
+
+/**
+ * @brief Go to system OFF
+ *
+ * This function puts the CPU into system off mode.
+ * The only way to wake up the CPU is by reset.
+ *
+ * @note This function never returns.
+ */
+__STATIC_INLINE void nrf_power_system_off(void);
+
+/**
+ * @brief Set power failure comparator configuration
+ *
+ * Sets power failure comparator threshold and enable/disable flag.
+ *
+ * @param enabled Set to true if power failure comparator should be enabled.
+ * @param thr Set the voltage threshold value.
+ *
+ * @note
+ * If VDDH settings is present in the device, this function would
+ * clear it settings (set to the lowest voltage).
+ * Use @ref nrf_power_pofcon_vddh_set function to set new value.
+ */
+__STATIC_INLINE void nrf_power_pofcon_set(bool enabled, nrf_power_pof_thr_t thr);
+
+/**
+ * @brief Get power failure comparator configuration
+ *
+ * Get power failure comparator threshold and enable bit.
+ *
+ * @param[out] p_enabled Function would set this boolean variable to true
+ * if power failure comparator is enabled.
+ * The pointer can be NULL if we do not need this information.
+ * @return Threshold setting for power failure comparator
+ */
+__STATIC_INLINE nrf_power_pof_thr_t nrf_power_pofcon_get(bool * p_enabled);
+
+#if NRF_POWER_HAS_VDDH
+/**
+ * @brief Set VDDH power failure comparator threshold
+ *
+ * @param thr Threshold to be set
+ */
+__STATIC_INLINE void nrf_power_pofcon_vddh_set(nrf_power_pof_thrvddh_t thr);
+
+/**
+ * @brief Get VDDH power failure comparator threshold
+ *
+ * @return VDDH threshold currently configured
+ */
+__STATIC_INLINE nrf_power_pof_thrvddh_t nrf_power_pofcon_vddh_get(void);
+#endif
+
+/**
+ * @brief Set general purpose retention register
+ *
+ * @param val Value to be set in the register
+ */
+__STATIC_INLINE void nrf_power_gpregret_set(uint8_t val);
+
+/**
+ * @brief Get general purpose retention register
+ *
+ * @return The value from the register
+ */
+__STATIC_INLINE uint8_t nrf_power_gpregret_get(void);
+
+#if defined(POWER_GPREGRET2_GPREGRET_Msk) || defined(__SDK_DOXYGEN__)
+/**
+ * @brief Set general purpose retention register 2
+ *
+ * @param val Value to be set in the register
+ * @note This register is not available in nrf51 MCU family
+ */
+__STATIC_INLINE void nrf_power_gpregret2_set(uint8_t val);
+
+/**
+ * @brief Get general purpose retention register 2
+ *
+ * @return The value from the register
+ * @note This register is not available in all MCUs.
+ */
+__STATIC_INLINE uint8_t nrf_power_gpregret2_get(void);
+#endif
+
+/**
+ * @brief Enable or disable DCDC converter
+ *
+ * @param enable Set true to enable or false to disable DCDC converter.
+ *
+ * @note
+ * If the device consist of high voltage power input (VDDH) this setting
+ * would relate to the converter on low voltage side (1.3&nbsp;V output).
+ */
+__STATIC_INLINE void nrf_power_dcdcen_set(bool enable);
+
+/**
+ * @brief Get the state of DCDC converter
+ *
+ * @retval true Converter is enabled
+ * @retval false Converter is disabled
+ *
+ * @note
+ * If the device consist of high voltage power input (VDDH) this setting
+ * would relate to the converter on low voltage side (1.3&nbsp;V output).
+ */
+__STATIC_INLINE bool nrf_power_dcdcen_get(void);
+
+#if NRF_POWER_HAS_RAMPOWER_REGS
+/**
+ * @brief Turn ON sections in selected RAM block.
+ *
+ * This function turns ON sections in block and also block retention.
+ *
+ * @sa nrf_power_rampower_mask_t
+ * @sa nrf_power_rampower_mask_off
+ *
+ * @param block RAM block index.
+ * @param section_mask Mask of the sections created by merging
+ * @ref nrf_power_rampower_mask_t flags.
+ */
+__STATIC_INLINE void nrf_power_rampower_mask_on(uint8_t block, uint32_t section_mask);
+
+/**
+ * @brief Turn ON sections in selected RAM block.
+ *
+ * This function turns OFF sections in block and also block retention.
+ *
+ * @sa nrf_power_rampower_mask_t
+ * @sa nrf_power_rampower_mask_off
+ *
+ * @param block RAM block index.
+ * @param section_mask Mask of the sections created by merging
+ * @ref nrf_power_rampower_mask_t flags.
+ */
+__STATIC_INLINE void nrf_power_rampower_mask_off(uint8_t block, uint32_t section_mask);
+
+/**
+ * @brief Get the mask of ON and retention sections in selected RAM block.
+ *
+ * @param block RAM block index.
+ * @return Mask of sections state composed from @ref nrf_power_rampower_mask_t flags.
+ */
+__STATIC_INLINE uint32_t nrf_power_rampower_mask_get(uint8_t block);
+#endif /* NRF_POWER_HAS_RAMPOWER_REGS */
+
+#if NRF_POWER_HAS_VDDH
+/**
+ * @brief Enable of disable DCDC converter on VDDH
+ *
+ * @param enable Set true to enable or false to disable DCDC converter.
+ */
+__STATIC_INLINE void nrf_power_dcdcen_vddh_set(bool enable);
+
+/**
+ * @brief Get the state of DCDC converter on VDDH
+ *
+ * @retval true Converter is enabled
+ * @retval false Converter is disabled
+ */
+__STATIC_INLINE bool nrf_power_dcdcen_vddh_get(void);
+
+/**
+ * @brief Get main supply status
+ *
+ * @return Current main supply status
+ */
+__STATIC_INLINE nrf_power_mainregstatus_t nrf_power_mainregstatus_get(void);
+#endif /* NRF_POWER_HAS_VDDH */
+
+#if NRF_POWER_HAS_USBREG
+/**
+ *
+ * @return Get the whole USBREGSTATUS register
+ *
+ * @return The USBREGSTATUS register value.
+ * Use @ref nrf_power_usbregstatus_mask_t values for bit masking.
+ *
+ * @sa nrf_power_usbregstatus_vbusdet_get
+ * @sa nrf_power_usbregstatus_outrdy_get
+ */
+__STATIC_INLINE uint32_t nrf_power_usbregstatus_get(void);
+
+/**
+ * @brief VBUS input detection status
+ *
+ * USBDETECTED and USBREMOVED events are derived from this information
+ *
+ * @retval false VBUS voltage below valid threshold
+ * @retval true VBUS voltage above valid threshold
+ *
+ * @sa nrf_power_usbregstatus_get
+ */
+__STATIC_INLINE bool nrf_power_usbregstatus_vbusdet_get(void);
+
+/**
+ * @brief USB supply output settling time elapsed
+ *
+ * @retval false USBREG output settling time not elapsed
+ * @retval true USBREG output settling time elapsed
+ * (same information as USBPWRRDY event)
+ *
+ * @sa nrf_power_usbregstatus_get
+ */
+__STATIC_INLINE bool nrf_power_usbregstatus_outrdy_get(void);
+#endif /* NRF_POWER_HAS_USBREG */
+
+/** @} */
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE uint32_t nrf_power_resetreas_get(void)
+{
+ return NRF_POWER->RESETREAS;
+}
+
+__STATIC_INLINE void nrf_power_resetreas_clear(uint32_t mask)
+{
+ NRF_POWER->RESETREAS = mask;
+}
+
+#if NRF_POWER_HAS_RAMSTATUS
+__STATIC_INLINE uint32_t nrf_power_ramstatus_get(void)
+{
+ return NRF_POWER->RAMSTATUS;
+}
+#endif // NRF_POWER_HAS_RAMSTATUS
+
+__STATIC_INLINE void nrf_power_system_off(void)
+{
+ NRF_POWER->SYSTEMOFF = POWER_SYSTEMOFF_SYSTEMOFF_Enter;
+ __DSB();
+
+ /* Solution for simulated System OFF in debug mode */
+ while (true)
+ {
+ __WFE();
+ }
+}
+
+__STATIC_INLINE void nrf_power_pofcon_set(bool enabled, nrf_power_pof_thr_t thr)
+{
+ ASSERT(thr == (thr & (POWER_POFCON_THRESHOLD_Msk >> POWER_POFCON_THRESHOLD_Pos)));
+#if NRF_POWER_HAS_VDDH
+ uint32_t pofcon = NRF_POWER->POFCON;
+ pofcon &= ~(POWER_POFCON_THRESHOLD_Msk | POWER_POFCON_POF_Msk);
+ pofcon |=
+#else /* NRF_POWER_HAS_VDDH */
+ NRF_POWER->POFCON =
+#endif
+ (((uint32_t)thr) << POWER_POFCON_THRESHOLD_Pos) |
+ (enabled ?
+ (POWER_POFCON_POF_Enabled << POWER_POFCON_POF_Pos)
+ :
+ (POWER_POFCON_POF_Disabled << POWER_POFCON_POF_Pos));
+#if NRF_POWER_HAS_VDDH
+ NRF_POWER->POFCON = pofcon;
+#endif
+}
+
+__STATIC_INLINE nrf_power_pof_thr_t nrf_power_pofcon_get(bool * p_enabled)
+{
+ uint32_t pofcon = NRF_POWER->POFCON;
+ if (NULL != p_enabled)
+ {
+ (*p_enabled) = ((pofcon & POWER_POFCON_POF_Msk) >> POWER_POFCON_POF_Pos)
+ == POWER_POFCON_POF_Enabled;
+ }
+ return (nrf_power_pof_thr_t)((pofcon & POWER_POFCON_THRESHOLD_Msk) >>
+ POWER_POFCON_THRESHOLD_Pos);
+}
+
+#if NRF_POWER_HAS_VDDH
+__STATIC_INLINE void nrf_power_pofcon_vddh_set(nrf_power_pof_thrvddh_t thr)
+{
+ ASSERT(thr == (thr & (POWER_POFCON_THRESHOLDVDDH_Msk >> POWER_POFCON_THRESHOLDVDDH_Pos)));
+ uint32_t pofcon = NRF_POWER->POFCON;
+ pofcon &= ~POWER_POFCON_THRESHOLDVDDH_Msk;
+ pofcon |= (((uint32_t)thr) << POWER_POFCON_THRESHOLDVDDH_Pos);
+ NRF_POWER->POFCON = pofcon;
+}
+
+__STATIC_INLINE nrf_power_pof_thrvddh_t nrf_power_pofcon_vddh_get(void)
+{
+ return (nrf_power_pof_thrvddh_t)((NRF_POWER->POFCON &
+ POWER_POFCON_THRESHOLDVDDH_Msk) >> POWER_POFCON_THRESHOLDVDDH_Pos);
+}
+#endif /* NRF_POWER_HAS_VDDH */
+
+__STATIC_INLINE void nrf_power_gpregret_set(uint8_t val)
+{
+ NRF_POWER->GPREGRET = val;
+}
+
+__STATIC_INLINE uint8_t nrf_power_gpregret_get(void)
+{
+ return NRF_POWER->GPREGRET;
+}
+
+#if defined(POWER_GPREGRET2_GPREGRET_Msk) || defined(__SDK_DOXYGEN__)
+void nrf_power_gpregret2_set(uint8_t val)
+{
+ NRF_POWER->GPREGRET2 = val;
+}
+
+__STATIC_INLINE uint8_t nrf_power_gpregret2_get(void)
+{
+ return NRF_POWER->GPREGRET2;
+}
+#endif
+
+__STATIC_INLINE void nrf_power_dcdcen_set(bool enable)
+{
+#if NRF_POWER_HAS_VDDH
+ NRF_POWER->DCDCEN = (enable ?
+ POWER_DCDCEN_DCDCEN_Enabled : POWER_DCDCEN_DCDCEN_Disabled) <<
+ POWER_DCDCEN_DCDCEN_Pos;
+#else
+ NRF_POWER->DCDCEN = (enable ?
+ POWER_DCDCEN_DCDCEN_Enabled : POWER_DCDCEN_DCDCEN_Disabled) <<
+ POWER_DCDCEN_DCDCEN_Pos;
+#endif
+}
+
+__STATIC_INLINE bool nrf_power_dcdcen_get(void)
+{
+#if NRF_POWER_HAS_VDDH
+ return (NRF_POWER->DCDCEN & POWER_DCDCEN_DCDCEN_Msk)
+ ==
+ (POWER_DCDCEN_DCDCEN_Enabled << POWER_DCDCEN_DCDCEN_Pos);
+#else
+ return (NRF_POWER->DCDCEN & POWER_DCDCEN_DCDCEN_Msk)
+ ==
+ (POWER_DCDCEN_DCDCEN_Enabled << POWER_DCDCEN_DCDCEN_Pos);
+#endif
+}
+
+#if NRF_POWER_HAS_RAMPOWER_REGS
+__STATIC_INLINE void nrf_power_rampower_mask_on(uint8_t block, uint32_t section_mask)
+{
+ ASSERT(block < ARRAY_SIZE(NRF_POWER->RAM));
+ NRF_POWER->RAM[block].POWERSET = section_mask;
+}
+
+__STATIC_INLINE void nrf_power_rampower_mask_off(uint8_t block, uint32_t section_mask)
+{
+ ASSERT(block < ARRAY_SIZE(NRF_POWER->RAM));
+ NRF_POWER->RAM[block].POWERCLR = section_mask;
+}
+
+__STATIC_INLINE uint32_t nrf_power_rampower_mask_get(uint8_t block)
+{
+ ASSERT(block < ARRAY_SIZE(NRF_POWER->RAM));
+ return NRF_POWER->RAM[block].POWER;
+}
+#endif /* NRF_POWER_HAS_RAMPOWER_REGS */
+
+#if NRF_POWER_HAS_VDDH
+__STATIC_INLINE void nrf_power_dcdcen_vddh_set(bool enable)
+{
+ NRF_POWER->DCDCEN0 = (enable ?
+ POWER_DCDCEN0_DCDCEN_Enabled : POWER_DCDCEN0_DCDCEN_Disabled) <<
+ POWER_DCDCEN0_DCDCEN_Pos;
+}
+
+bool nrf_power_dcdcen_vddh_get(void)
+{
+ return (NRF_POWER->DCDCEN0 & POWER_DCDCEN0_DCDCEN_Msk)
+ ==
+ (POWER_DCDCEN0_DCDCEN_Enabled << POWER_DCDCEN0_DCDCEN_Pos);
+}
+
+nrf_power_mainregstatus_t nrf_power_mainregstatus_get(void)
+{
+ return (nrf_power_mainregstatus_t)(((NRF_POWER->MAINREGSTATUS) &
+ POWER_MAINREGSTATUS_MAINREGSTATUS_Msk) >>
+ POWER_MAINREGSTATUS_MAINREGSTATUS_Pos);
+}
+#endif /* NRF_POWER_HAS_VDDH */
+
+#if NRF_POWER_HAS_USBREG
+__STATIC_INLINE uint32_t nrf_power_usbregstatus_get(void)
+{
+ return NRF_POWER->USBREGSTATUS;
+}
+
+__STATIC_INLINE bool nrf_power_usbregstatus_vbusdet_get(void)
+{
+ return (nrf_power_usbregstatus_get() &
+ NRF_POWER_USBREGSTATUS_VBUSDETECT_MASK) != 0;
+}
+
+__STATIC_INLINE bool nrf_power_usbregstatus_outrdy_get(void)
+{
+ return (nrf_power_usbregstatus_get() &
+ NRF_POWER_USBREGSTATUS_OUTPUTRDY_MASK) != 0;
+}
+#endif /* NRF_POWER_HAS_USBREG */
+
+#endif /* SUPPRESS_INLINE_IMPLEMENTATION */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_POWER_H__ */
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_ppi.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_ppi.h
new file mode 100644
index 000000000..945fedc2d
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_ppi.h
@@ -0,0 +1,439 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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__
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_pwm.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_pwm.h
new file mode 100644
index 000000000..710f307e2
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_pwm.h
@@ -0,0 +1,701 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_pwm_hal PWM HAL
+ * @{
+ * @ingroup nrf_pwm
+ *
+ * @brief @tagAPI52 Hardware access layer for managing the Pulse Width Modulation (PWM)
+ * peripheral.
+ */
+
+#ifndef NRF_PWM_H__
+#define NRF_PWM_H__
+
+#include <stddef.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "nrf.h"
+#include "nrf_assert.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief This value can be provided as a parameter for the @ref nrf_pwm_pins_set
+ * function call to specify that a given output channel shall not be
+ * connected to a physical pin.
+ */
+#define NRF_PWM_PIN_NOT_CONNECTED 0xFFFFFFFF
+
+/**
+ * @brief Number of channels in each Pointer to the peripheral registers structure.
+ */
+#define NRF_PWM_CHANNEL_COUNT 4
+
+
+/**
+ * @brief PWM tasks.
+ */
+typedef enum
+{
+ /*lint -save -e30*/
+ NRF_PWM_TASK_STOP = offsetof(NRF_PWM_Type, TASKS_STOP), ///< Stops PWM pulse generation on all channels at the end of the current PWM period, and stops the sequence playback.
+ NRF_PWM_TASK_SEQSTART0 = offsetof(NRF_PWM_Type, TASKS_SEQSTART[0]), ///< Starts playback of sequence 0.
+ NRF_PWM_TASK_SEQSTART1 = offsetof(NRF_PWM_Type, TASKS_SEQSTART[1]), ///< Starts playback of sequence 1.
+ NRF_PWM_TASK_NEXTSTEP = offsetof(NRF_PWM_Type, TASKS_NEXTSTEP) ///< Steps by one value in the current sequence if the decoder is set to @ref NRF_PWM_STEP_TRIGGERED mode.
+ /*lint -restore*/
+} nrf_pwm_task_t;
+
+/**
+ * @brief PWM events.
+ */
+typedef enum
+{
+ /*lint -save -e30*/
+ NRF_PWM_EVENT_STOPPED = offsetof(NRF_PWM_Type, EVENTS_STOPPED), ///< Response to STOP task, emitted when PWM pulses are no longer generated.
+ NRF_PWM_EVENT_SEQSTARTED0 = offsetof(NRF_PWM_Type, EVENTS_SEQSTARTED[0]), ///< First PWM period started on sequence 0.
+ NRF_PWM_EVENT_SEQSTARTED1 = offsetof(NRF_PWM_Type, EVENTS_SEQSTARTED[1]), ///< First PWM period started on sequence 1.
+ NRF_PWM_EVENT_SEQEND0 = offsetof(NRF_PWM_Type, EVENTS_SEQEND[0]), ///< Emitted at the end of every sequence 0 when its last value has been read from RAM.
+ NRF_PWM_EVENT_SEQEND1 = offsetof(NRF_PWM_Type, EVENTS_SEQEND[1]), ///< Emitted at the end of every sequence 1 when its last value has been read from RAM.
+ NRF_PWM_EVENT_PWMPERIODEND = offsetof(NRF_PWM_Type, EVENTS_PWMPERIODEND), ///< Emitted at the end of each PWM period.
+ NRF_PWM_EVENT_LOOPSDONE = offsetof(NRF_PWM_Type, EVENTS_LOOPSDONE) ///< Concatenated sequences have been played the requested number of times.
+ /*lint -restore*/
+} nrf_pwm_event_t;
+
+/**
+ * @brief PWM interrupts.
+ */
+typedef enum
+{
+ NRF_PWM_INT_STOPPED_MASK = PWM_INTENSET_STOPPED_Msk, ///< Interrupt on STOPPED event.
+ NRF_PWM_INT_SEQSTARTED0_MASK = PWM_INTENSET_SEQSTARTED0_Msk, ///< Interrupt on SEQSTARTED[0] event.
+ NRF_PWM_INT_SEQSTARTED1_MASK = PWM_INTENSET_SEQSTARTED1_Msk, ///< Interrupt on SEQSTARTED[1] event.
+ NRF_PWM_INT_SEQEND0_MASK = PWM_INTENSET_SEQEND0_Msk, ///< Interrupt on SEQEND[0] event.
+ NRF_PWM_INT_SEQEND1_MASK = PWM_INTENSET_SEQEND1_Msk, ///< Interrupt on SEQEND[1] event.
+ NRF_PWM_INT_PWMPERIODEND_MASK = PWM_INTENSET_PWMPERIODEND_Msk, ///< Interrupt on PWMPERIODEND event.
+ NRF_PWM_INT_LOOPSDONE_MASK = PWM_INTENSET_LOOPSDONE_Msk ///< Interrupt on LOOPSDONE event.
+} nrf_pwm_int_mask_t;
+
+/**
+ * @brief PWM shortcuts.
+ */
+typedef enum
+{
+ NRF_PWM_SHORT_SEQEND0_STOP_MASK = PWM_SHORTS_SEQEND0_STOP_Msk, ///< Shortcut between SEQEND[0] event and STOP task.
+ NRF_PWM_SHORT_SEQEND1_STOP_MASK = PWM_SHORTS_SEQEND1_STOP_Msk, ///< Shortcut between SEQEND[1] event and STOP task.
+ NRF_PWM_SHORT_LOOPSDONE_SEQSTART0_MASK = PWM_SHORTS_LOOPSDONE_SEQSTART0_Msk, ///< Shortcut between LOOPSDONE event and SEQSTART[0] task.
+ NRF_PWM_SHORT_LOOPSDONE_SEQSTART1_MASK = PWM_SHORTS_LOOPSDONE_SEQSTART1_Msk, ///< Shortcut between LOOPSDONE event and SEQSTART[1] task.
+ NRF_PWM_SHORT_LOOPSDONE_STOP_MASK = PWM_SHORTS_LOOPSDONE_STOP_Msk ///< Shortcut between LOOPSDONE event and STOP task.
+} nrf_pwm_short_mask_t;
+
+/**
+ * @brief PWM modes of operation.
+ */
+typedef enum
+{
+ NRF_PWM_MODE_UP = PWM_MODE_UPDOWN_Up, ///< Up counter (edge-aligned PWM duty cycle).
+ NRF_PWM_MODE_UP_AND_DOWN = PWM_MODE_UPDOWN_UpAndDown, ///< Up and down counter (center-aligned PWM duty cycle).
+} nrf_pwm_mode_t;
+
+/**
+ * @brief PWM base clock frequencies.
+ */
+typedef enum
+{
+ NRF_PWM_CLK_16MHz = PWM_PRESCALER_PRESCALER_DIV_1, ///< 16 MHz / 1 = 16 MHz.
+ NRF_PWM_CLK_8MHz = PWM_PRESCALER_PRESCALER_DIV_2, ///< 16 MHz / 2 = 8 MHz.
+ NRF_PWM_CLK_4MHz = PWM_PRESCALER_PRESCALER_DIV_4, ///< 16 MHz / 4 = 4 MHz.
+ NRF_PWM_CLK_2MHz = PWM_PRESCALER_PRESCALER_DIV_8, ///< 16 MHz / 8 = 2 MHz.
+ NRF_PWM_CLK_1MHz = PWM_PRESCALER_PRESCALER_DIV_16, ///< 16 MHz / 16 = 1 MHz.
+ NRF_PWM_CLK_500kHz = PWM_PRESCALER_PRESCALER_DIV_32, ///< 16 MHz / 32 = 500 kHz.
+ NRF_PWM_CLK_250kHz = PWM_PRESCALER_PRESCALER_DIV_64, ///< 16 MHz / 64 = 250 kHz.
+ NRF_PWM_CLK_125kHz = PWM_PRESCALER_PRESCALER_DIV_128 ///< 16 MHz / 128 = 125 kHz.
+} nrf_pwm_clk_t;
+
+/**
+ * @brief PWM decoder load modes.
+ *
+ * The selected mode determines how the sequence data is read from RAM and
+ * spread to the compare registers.
+ */
+typedef enum
+{
+ NRF_PWM_LOAD_COMMON = PWM_DECODER_LOAD_Common, ///< 1st half word (16-bit) used in all PWM channels (0-3).
+ NRF_PWM_LOAD_GROUPED = PWM_DECODER_LOAD_Grouped, ///< 1st half word (16-bit) used in channels 0 and 1; 2nd word in channels 2 and 3.
+ NRF_PWM_LOAD_INDIVIDUAL = PWM_DECODER_LOAD_Individual, ///< 1st half word (16-bit) used in channel 0; 2nd in channel 1; 3rd in channel 2; 4th in channel 3.
+ NRF_PWM_LOAD_WAVE_FORM = PWM_DECODER_LOAD_WaveForm ///< 1st half word (16-bit) used in channel 0; 2nd in channel 1; ... ; 4th as the top value for the pulse generator counter.
+} nrf_pwm_dec_load_t;
+
+/**
+ * @brief PWM decoder next step modes.
+ *
+ * The selected mode determines when the next value from the active sequence
+ * is loaded.
+ */
+typedef enum
+{
+ NRF_PWM_STEP_AUTO = PWM_DECODER_MODE_RefreshCount, ///< Automatically after the current value is played and repeated the requested number of times.
+ NRF_PWM_STEP_TRIGGERED = PWM_DECODER_MODE_NextStep ///< When the @ref NRF_PWM_TASK_NEXTSTEP task is triggered.
+} nrf_pwm_dec_step_t;
+
+
+/**
+ * @brief Type used for defining duty cycle values for a sequence
+ * loaded in @ref NRF_PWM_LOAD_COMMON mode.
+ */
+typedef uint16_t nrf_pwm_values_common_t;
+
+/**
+ * @brief Structure for defining duty cycle values for a sequence
+ * loaded in @ref NRF_PWM_LOAD_GROUPED mode.
+ */
+typedef struct {
+ uint16_t group_0; ///< Duty cycle value for group 0 (channels 0 and 1).
+ uint16_t group_1; ///< Duty cycle value for group 1 (channels 2 and 3).
+} nrf_pwm_values_grouped_t;
+
+/**
+ * @brief Structure for defining duty cycle values for a sequence
+ * loaded in @ref NRF_PWM_LOAD_INDIVIDUAL mode.
+ */
+typedef struct
+{
+ uint16_t channel_0; ///< Duty cycle value for channel 0.
+ uint16_t channel_1; ///< Duty cycle value for channel 1.
+ uint16_t channel_2; ///< Duty cycle value for channel 2.
+ uint16_t channel_3; ///< Duty cycle value for channel 3.
+} nrf_pwm_values_individual_t;
+
+/**
+ * @brief Structure for defining duty cycle values for a sequence
+ * loaded in @ref NRF_PWM_LOAD_WAVE_FORM mode.
+ */
+typedef struct {
+ uint16_t channel_0; ///< Duty cycle value for channel 0.
+ uint16_t channel_1; ///< Duty cycle value for channel 1.
+ uint16_t channel_2; ///< Duty cycle value for channel 2.
+ uint16_t counter_top; ///< Top value for the pulse generator counter.
+} nrf_pwm_values_wave_form_t;
+
+/**
+ * @brief Union grouping pointers to arrays of duty cycle values applicable to
+ * various loading modes.
+ */
+typedef union {
+ nrf_pwm_values_common_t const * p_common; ///< Pointer to be used in @ref NRF_PWM_LOAD_COMMON mode.
+ nrf_pwm_values_grouped_t const * p_grouped; ///< Pointer to be used in @ref NRF_PWM_LOAD_GROUPED mode.
+ nrf_pwm_values_individual_t const * p_individual; ///< Pointer to be used in @ref NRF_PWM_LOAD_INDIVIDUAL mode.
+ nrf_pwm_values_wave_form_t const * p_wave_form; ///< Pointer to be used in @ref NRF_PWM_LOAD_WAVE_FORM mode.
+ uint16_t const * p_raw; ///< Pointer providing raw access to the values.
+} nrf_pwm_values_t;
+
+/**
+ * @brief Structure for defining a sequence of PWM duty cycles.
+ *
+ * When the sequence is set (by a call to @ref nrf_pwm_sequence_set), the
+ * provided duty cycle values are not copied. The @p values pointer is stored
+ * in the peripheral's internal register, and the values are loaded from RAM
+ * during the sequence playback. Therefore, you must ensure that the values
+ * do not change before and during the sequence playback (for example,
+ * the values cannot be placed in a local variable that is allocated on stack).
+ * If the sequence is played in a loop and the values should be updated
+ * before the next iteration, it is safe to modify them when the corresponding
+ * event signaling the end of sequence occurs (@ref NRF_PWM_EVENT_SEQEND0
+ * or @ref NRF_PWM_EVENT_SEQEND1, respectively).
+ *
+ * @note The @p repeats and @p end_delay values (which are written to the
+ * SEQ[n].REFRESH and SEQ[n].ENDDELAY registers in the peripheral,
+ * respectively) are ignored at the end of a complex sequence
+ * playback, indicated by the LOOPSDONE event.
+ * See the @linkProductSpecification52 for more information.
+ */
+typedef struct
+{
+ nrf_pwm_values_t values; ///< Pointer to an array with duty cycle values. This array must be in Data RAM.
+ /**< This field is defined as an union of pointers
+ * to provide a convenient way to define duty
+ * cycle values in various loading modes
+ * (see @ref nrf_pwm_dec_load_t).
+ * In each value, the most significant bit (15)
+ * determines the polarity of the output and the
+ * others (14-0) compose the 15-bit value to be
+ * compared with the pulse generator counter. */
+ uint16_t length; ///< Number of 16-bit values in the array pointed by @p values.
+ uint32_t repeats; ///< Number of times that each duty cycle should be repeated (after being played once). Ignored in @ref NRF_PWM_STEP_TRIGGERED mode.
+ uint32_t end_delay; ///< Additional time (in PWM periods) that the last duty cycle is to be kept after the sequence is played. Ignored in @ref NRF_PWM_STEP_TRIGGERED mode.
+} nrf_pwm_sequence_t;
+
+/**
+ * @brief Helper macro for calculating the number of 16-bit values in specified
+ * array of duty cycle values.
+ */
+#define NRF_PWM_VALUES_LENGTH(array) (sizeof(array) / sizeof(uint16_t))
+
+
+/**
+ * @brief Function for activating a specific PWM task.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] task Task to activate.
+ */
+__STATIC_INLINE void nrf_pwm_task_trigger(NRF_PWM_Type * p_reg,
+ nrf_pwm_task_t task);
+
+/**
+ * @brief Function for getting the address of a specific PWM task register.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] task Requested task.
+ *
+ * @return Address of the specified task register.
+ */
+__STATIC_INLINE uint32_t nrf_pwm_task_address_get(NRF_PWM_Type const * p_reg,
+ nrf_pwm_task_t task);
+
+/**
+ * @brief Function for clearing a specific PWM event.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] event Event to clear.
+ */
+__STATIC_INLINE void nrf_pwm_event_clear(NRF_PWM_Type * p_reg,
+ nrf_pwm_event_t event);
+
+/**
+ * @brief Function for checking the state of a specific PWM event.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] event Event to check.
+ *
+ * @retval true If the event is set.
+ * @retval false If the event is not set.
+ */
+__STATIC_INLINE bool nrf_pwm_event_check(NRF_PWM_Type const * p_reg,
+ nrf_pwm_event_t event);
+
+/**
+ * @brief Function for getting the address of a specific PWM event register.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] event Requested event.
+ *
+ * @return Address of the specified event register.
+ */
+__STATIC_INLINE uint32_t nrf_pwm_event_address_get(NRF_PWM_Type const * p_reg,
+ nrf_pwm_event_t event);
+
+/**
+ * @brief Function for enabling specified shortcuts.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] pwm_shorts_mask Shortcuts to enable.
+ */
+__STATIC_INLINE void nrf_pwm_shorts_enable(NRF_PWM_Type * p_reg,
+ uint32_t pwm_shorts_mask);
+
+/**
+ * @brief Function for disabling specified shortcuts.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] pwm_shorts_mask Shortcuts to disable.
+ */
+__STATIC_INLINE void nrf_pwm_shorts_disable(NRF_PWM_Type * p_reg,
+ uint32_t pwm_shorts_mask);
+
+/**
+ * @brief Function for setting the configuration of PWM shortcuts.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] pwm_shorts_mask Shortcuts configuration to set.
+ */
+__STATIC_INLINE void nrf_pwm_shorts_set(NRF_PWM_Type * p_reg,
+ uint32_t pwm_shorts_mask);
+
+/**
+ * @brief Function for enabling specified interrupts.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] pwm_int_mask Interrupts to enable.
+ */
+__STATIC_INLINE void nrf_pwm_int_enable(NRF_PWM_Type * p_reg,
+ uint32_t pwm_int_mask);
+
+/**
+ * @brief Function for disabling specified interrupts.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] pwm_int_mask Interrupts to disable.
+ */
+__STATIC_INLINE void nrf_pwm_int_disable(NRF_PWM_Type * p_reg,
+ uint32_t pwm_int_mask);
+
+/**
+ * @brief Function for setting the configuration of PWM interrupts.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] pwm_int_mask Interrupts configuration to set.
+ */
+__STATIC_INLINE void nrf_pwm_int_set(NRF_PWM_Type * p_reg,
+ uint32_t pwm_int_mask);
+
+/**
+ * @brief Function for retrieving the state of a given interrupt.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] pwm_int Interrupt to check.
+ *
+ * @retval true If the interrupt is enabled.
+ * @retval false If the interrupt is not enabled.
+ */
+__STATIC_INLINE bool nrf_pwm_int_enable_check(NRF_PWM_Type const * p_reg,
+ nrf_pwm_int_mask_t pwm_int);
+
+/**
+ * @brief Function for enabling the PWM peripheral.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE void nrf_pwm_enable(NRF_PWM_Type * p_reg);
+
+/**
+ * @brief Function for disabling the PWM peripheral.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE void nrf_pwm_disable(NRF_PWM_Type * p_reg);
+
+/**
+ * @brief Function for assigning pins to PWM output channels.
+ *
+ * Usage of all PWM output channels is optional. If a given channel is not
+ * needed, pass the @ref NRF_PWM_PIN_NOT_CONNECTED value instead of its pin
+ * number.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] out_pins Array with pin numbers for individual PWM output channels.
+ */
+__STATIC_INLINE void nrf_pwm_pins_set(NRF_PWM_Type * p_reg,
+ uint32_t out_pins[NRF_PWM_CHANNEL_COUNT]);
+
+/**
+ * @brief Function for configuring the PWM peripheral.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] base_clock Base clock frequency.
+ * @param[in] mode Operating mode of the pulse generator counter.
+ * @param[in] top_value Value up to which the pulse generator counter counts.
+ */
+__STATIC_INLINE void nrf_pwm_configure(NRF_PWM_Type * p_reg,
+ nrf_pwm_clk_t base_clock,
+ nrf_pwm_mode_t mode,
+ uint16_t top_value);
+
+/**
+ * @brief Function for defining a sequence of PWM duty cycles.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] seq_id Identifier of the sequence (0 or 1).
+ * @param[in] p_seq Pointer to the sequence definition.
+ */
+__STATIC_INLINE void nrf_pwm_sequence_set(NRF_PWM_Type * p_reg,
+ uint8_t seq_id,
+ nrf_pwm_sequence_t const * p_seq);
+
+/**
+ * @brief Function for modifying the pointer to the duty cycle values
+ * in the specified sequence.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] seq_id Identifier of the sequence (0 or 1).
+ * @param[in] p_values Pointer to an array with duty cycle values.
+ */
+__STATIC_INLINE void nrf_pwm_seq_ptr_set(NRF_PWM_Type * p_reg,
+ uint8_t seq_id,
+ uint16_t const * p_values);
+
+/**
+ * @brief Function for modifying the total number of duty cycle values
+ * in the specified sequence.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] seq_id Identifier of the sequence (0 or 1).
+ * @param[in] length Number of duty cycle values.
+ */
+__STATIC_INLINE void nrf_pwm_seq_cnt_set(NRF_PWM_Type * p_reg,
+ uint8_t seq_id,
+ uint16_t length);
+
+/**
+ * @brief Function for modifying the additional number of PWM periods spent
+ * on each duty cycle value in the specified sequence.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] seq_id Identifier of the sequence (0 or 1).
+ * @param[in] refresh Number of additional PWM periods for each duty cycle value.
+ */
+__STATIC_INLINE void nrf_pwm_seq_refresh_set(NRF_PWM_Type * p_reg,
+ uint8_t seq_id,
+ uint32_t refresh);
+
+/**
+ * @brief Function for modifying the additional time added after the sequence
+ * is played.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] seq_id Identifier of the sequence (0 or 1).
+ * @param[in] end_delay Number of PWM periods added at the end of the sequence.
+ */
+__STATIC_INLINE void nrf_pwm_seq_end_delay_set(NRF_PWM_Type * p_reg,
+ uint8_t seq_id,
+ uint32_t end_delay);
+
+/**
+ * @brief Function for setting the mode of loading sequence data from RAM
+ * and advancing the sequence.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] dec_load Mode of loading sequence data from RAM.
+ * @param[in] dec_step Mode of advancing the active sequence.
+ */
+__STATIC_INLINE void nrf_pwm_decoder_set(NRF_PWM_Type * p_reg,
+ nrf_pwm_dec_load_t dec_load,
+ nrf_pwm_dec_step_t dec_step);
+
+/**
+ * @brief Function for setting the number of times the sequence playback
+ * should be performed.
+ *
+ * This function applies to two-sequence playback (concatenated sequence 0 and 1).
+ * A single sequence can be played back only once.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] loop_count Number of times to perform the sequence playback.
+ */
+__STATIC_INLINE void nrf_pwm_loop_set(NRF_PWM_Type * p_reg,
+ uint16_t loop_count);
+
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE void nrf_pwm_task_trigger(NRF_PWM_Type * p_reg,
+ nrf_pwm_task_t task)
+{
+ *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
+}
+
+__STATIC_INLINE uint32_t nrf_pwm_task_address_get(NRF_PWM_Type const * p_reg,
+ nrf_pwm_task_t task)
+{
+ return ((uint32_t)p_reg + (uint32_t)task);
+}
+
+__STATIC_INLINE void nrf_pwm_event_clear(NRF_PWM_Type * p_reg,
+ nrf_pwm_event_t event)
+{
+ *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
+#if __CORTEX_M == 0x04
+ volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event));
+ (void)dummy;
+#endif
+}
+
+__STATIC_INLINE bool nrf_pwm_event_check(NRF_PWM_Type const * p_reg,
+ nrf_pwm_event_t event)
+{
+ return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
+}
+
+__STATIC_INLINE uint32_t nrf_pwm_event_address_get(NRF_PWM_Type const * p_reg,
+ nrf_pwm_event_t event)
+{
+ return ((uint32_t)p_reg + (uint32_t)event);
+}
+
+__STATIC_INLINE void nrf_pwm_shorts_enable(NRF_PWM_Type * p_reg,
+ uint32_t pwm_shorts_mask)
+{
+ p_reg->SHORTS |= pwm_shorts_mask;
+}
+
+__STATIC_INLINE void nrf_pwm_shorts_disable(NRF_PWM_Type * p_reg,
+ uint32_t pwm_shorts_mask)
+{
+ p_reg->SHORTS &= ~(pwm_shorts_mask);
+}
+
+__STATIC_INLINE void nrf_pwm_shorts_set(NRF_PWM_Type * p_reg,
+ uint32_t pwm_shorts_mask)
+{
+ p_reg->SHORTS = pwm_shorts_mask;
+}
+
+__STATIC_INLINE void nrf_pwm_int_enable(NRF_PWM_Type * p_reg,
+ uint32_t pwm_int_mask)
+{
+ p_reg->INTENSET = pwm_int_mask;
+}
+
+__STATIC_INLINE void nrf_pwm_int_disable(NRF_PWM_Type * p_reg,
+ uint32_t pwm_int_mask)
+{
+ p_reg->INTENCLR = pwm_int_mask;
+}
+
+__STATIC_INLINE void nrf_pwm_int_set(NRF_PWM_Type * p_reg,
+ uint32_t pwm_int_mask)
+{
+ p_reg->INTEN = pwm_int_mask;
+}
+
+__STATIC_INLINE bool nrf_pwm_int_enable_check(NRF_PWM_Type const * p_reg,
+ nrf_pwm_int_mask_t pwm_int)
+{
+ return (bool)(p_reg->INTENSET & pwm_int);
+}
+
+__STATIC_INLINE void nrf_pwm_enable(NRF_PWM_Type * p_reg)
+{
+ p_reg->ENABLE = (PWM_ENABLE_ENABLE_Enabled << PWM_ENABLE_ENABLE_Pos);
+}
+
+__STATIC_INLINE void nrf_pwm_disable(NRF_PWM_Type * p_reg)
+{
+ p_reg->ENABLE = (PWM_ENABLE_ENABLE_Disabled << PWM_ENABLE_ENABLE_Pos);
+}
+
+__STATIC_INLINE void nrf_pwm_pins_set(NRF_PWM_Type * p_reg,
+ uint32_t out_pins[NRF_PWM_CHANNEL_COUNT])
+{
+ uint8_t i;
+ for (i = 0; i < NRF_PWM_CHANNEL_COUNT; ++i)
+ {
+ p_reg->PSEL.OUT[i] = out_pins[i];
+ }
+}
+
+__STATIC_INLINE void nrf_pwm_configure(NRF_PWM_Type * p_reg,
+ nrf_pwm_clk_t base_clock,
+ nrf_pwm_mode_t mode,
+ uint16_t top_value)
+{
+ ASSERT(top_value <= PWM_COUNTERTOP_COUNTERTOP_Msk);
+
+ p_reg->PRESCALER = base_clock;
+ p_reg->MODE = mode;
+ p_reg->COUNTERTOP = top_value;
+}
+
+__STATIC_INLINE void nrf_pwm_sequence_set(NRF_PWM_Type * p_reg,
+ uint8_t seq_id,
+ nrf_pwm_sequence_t const * p_seq)
+{
+ ASSERT(p_seq != NULL);
+
+ nrf_pwm_seq_ptr_set( p_reg, seq_id, p_seq->values.p_raw);
+ nrf_pwm_seq_cnt_set( p_reg, seq_id, p_seq->length);
+ nrf_pwm_seq_refresh_set( p_reg, seq_id, p_seq->repeats);
+ nrf_pwm_seq_end_delay_set(p_reg, seq_id, p_seq->end_delay);
+}
+
+__STATIC_INLINE void nrf_pwm_seq_ptr_set(NRF_PWM_Type * p_reg,
+ uint8_t seq_id,
+ uint16_t const * p_values)
+{
+ ASSERT(seq_id <= 1);
+ ASSERT(p_values != NULL);
+ p_reg->SEQ[seq_id].PTR = (uint32_t)p_values;
+}
+
+__STATIC_INLINE void nrf_pwm_seq_cnt_set(NRF_PWM_Type * p_reg,
+ uint8_t seq_id,
+ uint16_t length)
+{
+ ASSERT(seq_id <= 1);
+ ASSERT(length != 0);
+ ASSERT(length <= PWM_SEQ_CNT_CNT_Msk);
+ p_reg->SEQ[seq_id].CNT = length;
+}
+
+__STATIC_INLINE void nrf_pwm_seq_refresh_set(NRF_PWM_Type * p_reg,
+ uint8_t seq_id,
+ uint32_t refresh)
+{
+ ASSERT(seq_id <= 1);
+ ASSERT(refresh <= PWM_SEQ_REFRESH_CNT_Msk);
+ p_reg->SEQ[seq_id].REFRESH = refresh;
+}
+
+__STATIC_INLINE void nrf_pwm_seq_end_delay_set(NRF_PWM_Type * p_reg,
+ uint8_t seq_id,
+ uint32_t end_delay)
+{
+ ASSERT(seq_id <= 1);
+ ASSERT(end_delay <= PWM_SEQ_ENDDELAY_CNT_Msk);
+ p_reg->SEQ[seq_id].ENDDELAY = end_delay;
+}
+
+__STATIC_INLINE void nrf_pwm_decoder_set(NRF_PWM_Type * p_reg,
+ nrf_pwm_dec_load_t dec_load,
+ nrf_pwm_dec_step_t dec_step)
+{
+ p_reg->DECODER = ((uint32_t)dec_load << PWM_DECODER_LOAD_Pos) |
+ ((uint32_t)dec_step << PWM_DECODER_MODE_Pos);
+}
+
+__STATIC_INLINE void nrf_pwm_loop_set(NRF_PWM_Type * p_reg,
+ uint16_t loop_count)
+{
+ p_reg->LOOP = loop_count;
+}
+
+#endif // SUPPRESS_INLINE_IMPLEMENTATION
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_PWM_H__
+
+/** @} */
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_qdec.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_qdec.h
new file mode 100644
index 000000000..e6a0fccbf
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_qdec.h
@@ -0,0 +1,504 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_QDEC_H__
+#define NRF_QDEC_H__
+
+#include <stddef.h>
+#include "nrf_error.h"
+#include "nrf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*lint ++flb "Enter library region" */
+
+/**
+ * @defgroup nrf_qdec_hal QDEC HAL
+ * @{
+ * @ingroup nrf_qdec
+ * @brief Hardware access layer for accessing the quadrature decoder (QDEC) peripheral.
+ */
+
+/**
+ * @enum nrf_qdec_task_t
+ * @brief QDEC tasks.
+ */
+typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
+{
+ NRF_QDEC_TASK_START = offsetof(NRF_QDEC_Type, TASKS_START), /**< Starting the quadrature decoder. */
+ NRF_QDEC_TASK_STOP = offsetof(NRF_QDEC_Type, TASKS_STOP), /**< Stopping the quadrature decoder. */
+ NRF_QDEC_TASK_READCLRACC = offsetof(NRF_QDEC_Type, TASKS_READCLRACC) /**< Reading and clearing ACC and ACCDBL registers. */
+} nrf_qdec_task_t;
+
+/**
+ * @enum nrf_qdec_event_t
+ * @brief QDEC events.
+ */
+typedef enum
+{
+ NRF_QDEC_EVENT_SAMPLERDY = offsetof(NRF_QDEC_Type, EVENTS_SAMPLERDY), /**< Event generated for every new sample. */
+ NRF_QDEC_EVENT_REPORTRDY = offsetof(NRF_QDEC_Type, EVENTS_REPORTRDY), /**< Event generated for every new report. */
+ NRF_QDEC_EVENT_ACCOF = offsetof(NRF_QDEC_Type, EVENTS_ACCOF) /**< Event generated for every accumulator overflow. */
+} nrf_qdec_event_t; /*lint -restore */
+
+/**
+ * @enum nrf_qdec_short_mask_t
+ * @brief QDEC shortcuts.
+ */
+typedef enum
+{
+ NRF_QDEC_SHORT_REPORTRDY_READCLRACC_MASK = QDEC_SHORTS_REPORTRDY_READCLRACC_Msk, /**< Shortcut between REPORTRDY event and READCLRACC task. */
+ NRF_QDEC_SHORT_SAMPLERDY_STOP_MASK = QDEC_SHORTS_SAMPLERDY_STOP_Msk /**< Shortcut between SAMPLERDY event and STOP task. */
+} nrf_qdec_short_mask_t;
+
+/**
+ * @enum nrf_qdec_int_mask_t
+ * @brief QDEC interrupts.
+ */
+typedef enum
+{
+ NRF_QDEC_INT_SAMPLERDY_MASK = QDEC_INTENSET_SAMPLERDY_Msk, /**< Mask for enabling or disabling an interrupt on SAMPLERDY event. */
+ NRF_QDEC_INT_REPORTRDY_MASK = QDEC_INTENSET_REPORTRDY_Msk, /**< Mask for enabling or disabling an interrupt on REPORTRDY event. */
+ NRF_QDEC_INT_ACCOF_MASK = QDEC_INTENSET_ACCOF_Msk /**< Mask for enabling or disabling an interrupt on ACCOF event. */
+} nrf_qdec_int_mask_t;
+
+/**
+ * @enum nrf_qdec_enable_t
+ * @brief States of the enable bit.
+ */
+typedef enum
+{
+ NRF_QDEC_DISABLE = QDEC_ENABLE_ENABLE_Disabled, /**< Mask for disabling the QDEC periperal. When disabled, the QDEC decoder pins are not active. */
+ NRF_QDEC_ENABLE = QDEC_ENABLE_ENABLE_Enabled /**< Mask for enabling the QDEC periperal. When enabled, the QDEC pins are active. */
+} nrf_qdec_enable_t;
+
+
+/**
+ * @enum nrf_qdec_dbfen_t
+ * @brief States of the debounce filter enable bit.
+ */
+typedef enum
+{
+ NRF_QDEC_DBFEN_DISABLE = QDEC_DBFEN_DBFEN_Disabled, /**< Mask for disabling the debounce filter. */
+ NRF_QDEC_DBFEN_ENABLE = QDEC_DBFEN_DBFEN_Enabled /**< Mask for enabling the debounce filter. */
+} nrf_qdec_dbfen_t;
+
+/**
+ * @enum nrf_qdec_ledpol_t
+ * @brief Active LED polarity.
+ */
+typedef enum
+{
+ NRF_QDEC_LEPOL_ACTIVE_LOW = QDEC_LEDPOL_LEDPOL_ActiveLow, /**< QDEC LED active on output pin low. */
+ NRF_QDEC_LEPOL_ACTIVE_HIGH = QDEC_LEDPOL_LEDPOL_ActiveHigh /**< QDEC LED active on output pin high. */
+} nrf_qdec_ledpol_t;
+
+
+/**
+ * @enum nrf_qdec_sampleper_t
+ * @brief Available sampling periods.
+ */
+typedef enum
+{
+ NRF_QDEC_SAMPLEPER_128us = QDEC_SAMPLEPER_SAMPLEPER_128us, /**< QDEC sampling period 128 microseconds. */
+ NRF_QDEC_SAMPLEPER_256us = QDEC_SAMPLEPER_SAMPLEPER_256us, /**< QDEC sampling period 256 microseconds. */
+ NRF_QDEC_SAMPLEPER_512us = QDEC_SAMPLEPER_SAMPLEPER_512us, /**< QDEC sampling period 512 microseconds. */
+ NRF_QDEC_SAMPLEPER_1024us = QDEC_SAMPLEPER_SAMPLEPER_1024us, /**< QDEC sampling period 1024 microseconds. */
+ NRF_QDEC_SAMPLEPER_2048us = QDEC_SAMPLEPER_SAMPLEPER_2048us, /**< QDEC sampling period 2048 microseconds. */
+ NRF_QDEC_SAMPLEPER_4096us = QDEC_SAMPLEPER_SAMPLEPER_4096us, /**< QDEC sampling period 4096 microseconds. */
+ NRF_QDEC_SAMPLEPER_8192us = QDEC_SAMPLEPER_SAMPLEPER_8192us, /**< QDEC sampling period 8192 microseconds. */
+ NRF_QDEC_SAMPLEPER_16384us = QDEC_SAMPLEPER_SAMPLEPER_16384us /**< QDEC sampling period 16384 microseconds. */
+} nrf_qdec_sampleper_t;
+
+/**
+ * @enum nrf_qdec_reportper_t
+ * @brief Available report periods.
+ */
+typedef enum
+{
+ NRF_QDEC_REPORTPER_10 = QDEC_REPORTPER_REPORTPER_10Smpl, /**< QDEC report period 10 samples. */
+ NRF_QDEC_REPORTPER_40 = QDEC_REPORTPER_REPORTPER_40Smpl, /**< QDEC report period 40 samples. */
+ NRF_QDEC_REPORTPER_80 = QDEC_REPORTPER_REPORTPER_80Smpl, /**< QDEC report period 80 samples. */
+ NRF_QDEC_REPORTPER_120 = QDEC_REPORTPER_REPORTPER_120Smpl, /**< QDEC report period 120 samples. */
+ NRF_QDEC_REPORTPER_160 = QDEC_REPORTPER_REPORTPER_160Smpl, /**< QDEC report period 160 samples. */
+ NRF_QDEC_REPORTPER_200 = QDEC_REPORTPER_REPORTPER_200Smpl, /**< QDEC report period 200 samples. */
+ NRF_QDEC_REPORTPER_240 = QDEC_REPORTPER_REPORTPER_240Smpl, /**< QDEC report period 240 samples. */
+ NRF_QDEC_REPORTPER_280 = QDEC_REPORTPER_REPORTPER_280Smpl, /**< QDEC report period 280 samples. */
+ NRF_QDEC_REPORTPER_DISABLED /**< QDEC reporting disabled. */
+} nrf_qdec_reportper_t;
+
+/**
+ * @brief Function for enabling QDEC.
+ */
+__STATIC_INLINE void nrf_qdec_enable(void)
+{
+ NRF_QDEC->ENABLE = NRF_QDEC_ENABLE;
+}
+
+
+/**
+ * @brief Function for disabling QDEC.
+ */
+__STATIC_INLINE void nrf_qdec_disable(void)
+{
+ NRF_QDEC->ENABLE = NRF_QDEC_DISABLE;
+}
+
+
+/**
+ * @brief Function for returning the enable state of QDEC.
+ * @return State of the register.
+ */
+__STATIC_INLINE uint32_t nrf_qdec_enable_get(void)
+{
+ return NRF_QDEC->ENABLE;
+}
+
+
+/**
+ * @brief Function for enabling QDEC interrupts by mask.
+ * @param[in] qdec_int_mask Sources of the interrupts to enable.
+ */
+__STATIC_INLINE void nrf_qdec_int_enable(uint32_t qdec_int_mask)
+{
+ NRF_QDEC->INTENSET = qdec_int_mask; // writing 0 has no effect
+}
+
+
+/**
+ * @brief Function for disabling QDEC interrupts by mask.
+ * @param[in] qdec_int_mask Sources of the interrupts to disable.
+ *
+ */
+__STATIC_INLINE void nrf_qdec_int_disable(uint32_t qdec_int_mask)
+{
+ NRF_QDEC->INTENCLR = qdec_int_mask; // writing 0 has no effect
+}
+
+
+/**
+ * @brief Function for getting the enabled interrupts of the QDEC.
+ */
+__STATIC_INLINE uint32_t nrf_qdec_int_enable_check(nrf_qdec_int_mask_t qdec_int_mask)
+{
+ return NRF_QDEC->INTENSET & qdec_int_mask; // when read this register will return the value of INTEN.
+}
+
+
+/**
+ * @brief Function for enabling the debouncing filter of the QED.
+ */
+__STATIC_INLINE void nrf_qdec_dbfen_enable(void)
+{
+ NRF_QDEC->DBFEN = NRF_QDEC_DBFEN_ENABLE;
+}
+
+
+/**
+ * @brief Function for disabling the debouncing filter of the QED.
+ */
+__STATIC_INLINE void nrf_qdec_dbfen_disable(void)
+{
+ NRF_QDEC->DBFEN = NRF_QDEC_DBFEN_DISABLE;
+}
+
+
+/**
+ * @brief Function for getting the state of the QDEC's debouncing filter.
+ * @retval NRF_QDEC_DBFEN_DISABLE If the debouncing filter is disabled.
+ * @retval NRF_QDEC_DBFEN_ENABLE If the debouncing filter is enabled.
+ */
+__STATIC_INLINE uint32_t nrf_qdec_dbfen_get(void)
+{
+ return NRF_QDEC->DBFEN;
+}
+
+
+/**
+ * @brief Function for assigning QDEC pins.
+ * @param[in] psela Pin number.
+ * @param[in] pselb Pin number.
+ * @param[in] pselled Pin number.
+ */
+__STATIC_INLINE void nrf_qdec_pio_assign( uint32_t psela, uint32_t pselb, uint32_t pselled)
+{
+ NRF_QDEC->PSELA = psela;
+ NRF_QDEC->PSELB = pselb;
+ NRF_QDEC->PSELLED = pselled;
+
+}
+
+/**
+ * @brief Function for setting a specific QDEC task.
+ * @param[in] qdec_task QDEC task to be set.
+ */
+__STATIC_INLINE void nrf_qdec_task_trigger(nrf_qdec_task_t qdec_task)
+{
+ *( (volatile uint32_t *)( (uint8_t *)NRF_QDEC + qdec_task) ) = 1;
+}
+
+
+/**
+ * @brief Function for retrieving the address of a QDEC task register.
+ * @param[in] qdec_task QDEC task.
+ */
+__STATIC_INLINE uint32_t * nrf_qdec_task_address_get(nrf_qdec_task_t qdec_task)
+{
+ return (uint32_t *)( (uint8_t *)NRF_QDEC + qdec_task);
+}
+
+
+/**
+ * @brief Function for clearing a specific QDEC event.
+ * @param[in] qdec_event QDEC event to clear.
+ */
+__STATIC_INLINE void nrf_qdec_event_clear(nrf_qdec_event_t qdec_event)
+{
+ *( (volatile uint32_t *)( (uint8_t *)NRF_QDEC + qdec_event) ) = 0;
+#if __CORTEX_M == 0x04
+ volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_QDEC + qdec_event));
+ (void)dummy;
+#endif
+}
+
+
+/**
+ * @brief Function for retrieving the state of a specific QDEC event.
+ * @return State of the QDEC event.
+ */
+__STATIC_INLINE uint32_t nrf_qdec_event_check(nrf_qdec_event_t qdec_event)
+{
+ return *(volatile uint32_t *)( (uint8_t *)NRF_QDEC + qdec_event);
+}
+
+
+/**
+ * @brief Function for retrieving the address of a specific QDEC event register.
+ * @param[in] qdec_event QDEC event.
+ * @return Address of the specified QDEC event.
+ */
+__STATIC_INLINE uint32_t * nrf_qdec_event_address_get(nrf_qdec_event_t qdec_event)
+{
+ return (uint32_t *)( (uint8_t *)NRF_QDEC + qdec_event);
+}
+
+
+/**
+ * @brief Function for setting QDEC shortcuts.
+ * @param[in] qdec_short_mask QDEC shortcut by mask.
+ */
+__STATIC_INLINE void nrf_qdec_shorts_enable(uint32_t qdec_short_mask)
+{
+ NRF_QDEC->SHORTS |= qdec_short_mask;
+}
+
+
+/**
+ * @brief Function for clearing shortcuts of the QDEC by mask.
+ * @param[in] qdec_short_mask QDEC shortcute to be cleared.
+ */
+__STATIC_INLINE void nrf_qdec_shorts_disable(uint32_t qdec_short_mask)
+{
+ NRF_QDEC->SHORTS &= ~qdec_short_mask;
+}
+
+
+/**
+ * @brief Function for retrieving the value of QDEC's SAMPLEPER register.
+ * @return Value of the SAMPLEPER register.
+ */
+__STATIC_INLINE int32_t nrf_qdec_sampleper_reg_get(void)
+{
+ return NRF_QDEC->SAMPLEPER;
+}
+
+
+/**
+ * @brief Function for converting the value of QDEC's SAMPLE PERIOD to microseconds.
+ * @retval sampling period in microseconds.
+ */
+__STATIC_INLINE uint32_t nrf_qdec_sampleper_to_value(uint32_t sampleper)
+{
+ return (1 << (7 + sampleper));
+}
+
+/**
+ * @brief Function for setting the value of QDEC's SAMPLEPER register.
+ * @param[in] sample_per Sampling period.
+ */
+__STATIC_INLINE void nrf_qdec_sampleper_set(nrf_qdec_sampleper_t sample_per)
+{
+ NRF_QDEC->SAMPLEPER = sample_per;
+}
+
+
+/**
+ * @brief Function for retrieving the value of QDEC's SAMPLE register.
+ * @return Value of the SAMPLE register.
+ */
+__STATIC_INLINE int32_t nrf_qdec_sample_get(void)
+{
+ return NRF_QDEC->SAMPLE;
+}
+
+
+/**
+ * @brief Function for retrieving the value of QDEC's ACC register.
+ * @return Value of the ACC register.
+ */
+__STATIC_INLINE int32_t nrf_qdec_acc_get(void)
+{
+ return NRF_QDEC->ACC;
+}
+
+
+/**
+ * @brief Function for retrieving the value of QDEC's ACCREAD register.
+ * @return Value of the ACCREAD register.
+ */
+__STATIC_INLINE int32_t nrf_qdec_accread_get(void)
+{
+ return NRF_QDEC->ACCREAD;
+}
+
+
+/**
+ * @brief Function for retrieving the value of QDEC's ACCDBL register.
+ * @return Value of the ACCDBL register.
+ */
+__STATIC_INLINE uint32_t nrf_qdec_accdbl_get(void)
+{
+ return NRF_QDEC->ACCDBL;
+}
+
+
+/**
+ * @brief Function for retrieving the value of QDEC's ACCDBLREAD register.
+ * @return Value of the ACCDBLREAD register.
+ */
+__STATIC_INLINE uint32_t nrf_qdec_accdblread_get(void)
+{
+ return NRF_QDEC->ACCDBLREAD;
+}
+
+
+/**
+ * @brief Function for setting how long the LED is switched on before sampling.
+ * @param[in] time_us Time (in microseconds) how long the LED is switched on before sampling.
+ */
+__STATIC_INLINE void nrf_qdec_ledpre_set(uint32_t time_us)
+{
+ NRF_QDEC->LEDPRE = time_us;
+}
+
+
+/**
+ * @brief Function for retrieving how long the LED is switched on before sampling.
+ * @retval time_us Time (in microseconds) how long the LED is switched on before sampling.
+ */
+__STATIC_INLINE uint32_t nrf_qdec_ledpre_get(void)
+{
+ return NRF_QDEC->LEDPRE;
+}
+
+
+/**
+ * @brief Function for setting the report period (in samples).
+ * @param[in] reportper Number of samples.
+ */
+__STATIC_INLINE void nrf_qdec_reportper_set(nrf_qdec_reportper_t reportper)
+{
+ NRF_QDEC->REPORTPER = reportper;
+}
+
+
+/**
+ * @brief Function for retrieving the report period.
+ * @retval reportper Number of samples as encoded in the register.
+ */
+__STATIC_INLINE uint32_t nrf_qdec_reportper_reg_get(void)
+{
+ return NRF_QDEC->REPORTPER;
+}
+
+
+/**
+ * @brief Function for retrieving the value of QDEC's SAMPLEPER register.
+ * @param [in] reportper Reportper to be converted to amount of samples per report.
+
+ */
+__STATIC_INLINE uint32_t nrf_qdec_reportper_to_value(uint32_t reportper)
+{
+ return (reportper == NRF_QDEC_REPORTPER_10) ? 10 : reportper * 40;
+}
+
+
+/**
+ * @brief Function for setting the active level for the LED.
+ * @param[in] pol Active level for the LED.
+ */
+__STATIC_INLINE void nrf_qdec_ledpol_set(nrf_qdec_ledpol_t pol)
+{
+ NRF_QDEC->LEDPOL = pol;
+}
+
+
+/**
+ * @brief Function for retrieving the active level for the LED.
+ * @return Active level for the LED.
+ */
+__STATIC_INLINE uint32_t nrf_qdec_ledpol_get(void)
+{
+ return NRF_QDEC->LEDPOL;
+}
+
+
+/**
+ *@}
+ **/
+
+/*lint --flb "Leave library region" */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_qspi.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_qspi.h
new file mode 100644
index 000000000..72b2d7237
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_qspi.h
@@ -0,0 +1,765 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_qspi_hal QSPI HAL
+ * @{
+ * @ingroup nrf_qspi
+ *
+ * @brief Hardware access layer for accessing the QSPI peripheral.
+ */
+
+#ifndef NRF_QSPI_H__
+#define NRF_QSPI_H__
+
+#include <stddef.h>
+#include <stdbool.h>
+#include "boards.h"
+#include "nrf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief This value can be used as a parameter for the @ref nrf_qspi_pins_set
+ * function to specify that a given QSPI signal (SCK, CSN, IO0, IO1, IO2, or IO3)
+ * will not be connected to a physical pin.
+ */
+#define NRF_QSPI_PIN_NOT_CONNECTED 0xFF
+
+/**
+ * @brief Macro for setting proper values to pin registers.
+ */
+
+#define NRF_QSPI_PIN_VAL(pin) (pin) == NRF_QSPI_PIN_NOT_CONNECTED ? 0xFFFFFFFF : (pin)
+
+/**
+ * @brief QSPI tasks.
+ */
+typedef enum
+{
+ /*lint -save -e30*/
+ NRF_QSPI_TASK_ACTIVATE = offsetof(NRF_QSPI_Type, TASKS_ACTIVATE), /**< Activate the QSPI interface. */
+ NRF_QSPI_TASK_READSTART = offsetof(NRF_QSPI_Type, TASKS_READSTART), /**< Start transfer from external flash memory to internal RAM. */
+ NRF_QSPI_TASK_WRITESTART = offsetof(NRF_QSPI_Type, TASKS_WRITESTART), /**< Start transfer from internal RAM to external flash memory. */
+ NRF_QSPI_TASK_ERASESTART = offsetof(NRF_QSPI_Type, TASKS_ERASESTART), /**< Start external flash memory erase operation. */
+ /*lint -restore*/
+} nrf_qspi_task_t;
+
+/**
+ * @brief QSPI events.
+ */
+typedef enum
+{
+ /*lint -save -e30*/
+ NRF_QSPI_EVENT_READY = offsetof(NRF_QSPI_Type, EVENTS_READY) /**< QSPI peripheral is ready after it executes any task. */
+ /*lint -restore*/
+} nrf_qspi_event_t;
+
+/**
+ * @brief QSPI interrupts.
+ */
+typedef enum
+{
+ NRF_QSPI_INT_READY_MASK = QSPI_INTENSET_READY_Msk /**< Interrupt on READY event. */
+} nrf_qspi_int_mask_t;
+
+/**
+ * @brief QSPI frequency divider values.
+ */
+typedef enum
+{
+ NRF_QSPI_FREQ_32MDIV1, /**< 32.0 MHz. */
+ NRF_QSPI_FREQ_32MDIV2, /**< 16.0 MHz. */
+ NRF_QSPI_FREQ_32MDIV3, /**< 10.6 MHz. */
+ NRF_QSPI_FREQ_32MDIV4, /**< 8.00 MHz. */
+ NRF_QSPI_FREQ_32MDIV5, /**< 6.40 MHz. */
+ NRF_QSPI_FREQ_32MDIV6, /**< 5.33 MHz. */
+ NRF_QSPI_FREQ_32MDIV7, /**< 4.57 MHz. */
+ NRF_QSPI_FREQ_32MDIV8, /**< 4.00 MHz. */
+ NRF_QSPI_FREQ_32MDIV9, /**< 3.55 MHz. */
+ NRF_QSPI_FREQ_32MDIV10, /**< 3.20 MHz. */
+ NRF_QSPI_FREQ_32MDIV11, /**< 2.90 MHz. */
+ NRF_QSPI_FREQ_32MDIV12, /**< 2.66 MHz. */
+ NRF_QSPI_FREQ_32MDIV13, /**< 2.46 MHz. */
+ NRF_QSPI_FREQ_32MDIV14, /**< 2.29 MHz. */
+ NRF_QSPI_FREQ_32MDIV15, /**< 2.13 MHz. */
+ NRF_QSPI_FREQ_32MDIV16, /**< 2.00 MHz. */
+} nrf_qspi_frequency_t;
+
+/**
+ * @brief Interface configuration for a read operation.
+ */
+typedef enum
+{
+ NRF_QSPI_READOC_FASTREAD = QSPI_IFCONFIG0_READOC_FASTREAD, /**< Single data line SPI. FAST_READ (opcode 0x0B). */
+ NRF_QSPI_READOC_READ2O = QSPI_IFCONFIG0_READOC_READ2O, /**< Dual data line SPI. READ2O (opcode 0x3B). */
+ NRF_QSPI_READOC_READ2IO = QSPI_IFCONFIG0_READOC_READ2IO, /**< Dual data line SPI. READ2IO (opcode 0xBB). */
+ NRF_QSPI_READOC_READ4O = QSPI_IFCONFIG0_READOC_READ4O, /**< Quad data line SPI. READ4O (opcode 0x6B). */
+ NRF_QSPI_READOC_READ4IO = QSPI_IFCONFIG0_READOC_READ4IO /**< Quad data line SPI. READ4IO (opcode 0xEB). */
+} nrf_qspi_readoc_t;
+
+/**
+ * @brief Interface configuration for a write operation.
+ */
+typedef enum
+{
+ NRF_QSPI_WRITEOC_PP = QSPI_IFCONFIG0_WRITEOC_PP, /**< Single data line SPI. PP (opcode 0x02). */
+ NRF_QSPI_WRITEOC_PP2O = QSPI_IFCONFIG0_WRITEOC_PP2O, /**< Dual data line SPI. PP2O (opcode 0xA2). */
+ NRF_QSPI_WRITEOC_PP4O = QSPI_IFCONFIG0_WRITEOC_PP4O, /**< Quad data line SPI. PP4O (opcode 0x32). */
+ NRF_QSPI_WRITEOC_PP4IO = QSPI_IFCONFIG0_WRITEOC_PP4IO, /**< Quad data line SPI. READ4O (opcode 0x38). */
+} nrf_qspi_writeoc_t;
+
+/**
+ * @brief Interface configuration for addressing mode.
+ */
+typedef enum
+{
+ NRF_QSPI_ADDRMODE_24BIT = QSPI_IFCONFIG0_ADDRMODE_24BIT, /**< 24-bit addressing. */
+ NRF_QSPI_ADDRMODE_32BIT = QSPI_IFCONFIG0_ADDRMODE_32BIT /**< 32-bit addressing. */
+} nrf_qspi_addrmode_t;
+
+/**
+ * @brief QSPI SPI mode. Polarization and phase configuration.
+ */
+typedef enum
+{
+ NRF_QSPI_MODE_0 = QSPI_IFCONFIG1_SPIMODE_MODE0, /**< Mode 0 (CPOL=0, CPHA=0). */
+ NRF_QSPI_MODE_1 = QSPI_IFCONFIG1_SPIMODE_MODE3 /**< Mode 1 (CPOL=1, CPHA=1). */
+} nrf_qspi_spi_mode_t;
+
+/**
+ * @brief Addressing configuration mode.
+ */
+typedef enum
+{
+ NRF_QSPI_ADDRCONF_MODE_NOINSTR = QSPI_ADDRCONF_MODE_NoInstr, /**< Do not send any instruction. */
+ NRF_QSPI_ADDRCONF_MODE_OPCODE = QSPI_ADDRCONF_MODE_Opcode, /**< Send opcode. */
+ NRF_QSPI_ADDRCONF_MODE_OPBYTE0 = QSPI_ADDRCONF_MODE_OpByte0, /**< Send opcode, byte0. */
+ NRF_QSPI_ADDRCONF_MODE_ALL = QSPI_ADDRCONF_MODE_All /**< Send opcode, byte0, byte1. */
+} nrf_qspi_addrconfig_mode_t;
+
+/**
+ * @brief Erasing data length.
+ */
+typedef enum
+{
+ NRF_QSPI_ERASE_LEN_4KB = QSPI_ERASE_LEN_LEN_4KB, /**< Erase 4 kB block (flash command 0x20). */
+ NRF_QSPI_ERASE_LEN_64KB = QSPI_ERASE_LEN_LEN_64KB, /**< Erase 64 kB block (flash command 0xD8). */
+ NRF_QSPI_ERASE_LEN_ALL = QSPI_ERASE_LEN_LEN_All /**< Erase all (flash command 0xC7). */
+} nrf_qspi_erase_len_t;
+
+/**
+ * @brief Custom instruction length.
+ */
+typedef enum
+{
+ NRF_QSPI_CINSTR_LEN_1B = QSPI_CINSTRCONF_LENGTH_1B, /**< Send opcode only. */
+ NRF_QSPI_CINSTR_LEN_2B = QSPI_CINSTRCONF_LENGTH_2B, /**< Send opcode, CINSTRDAT0.BYTE0. */
+ NRF_QSPI_CINSTR_LEN_3B = QSPI_CINSTRCONF_LENGTH_3B, /**< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT0.BYTE1. */
+ NRF_QSPI_CINSTR_LEN_4B = QSPI_CINSTRCONF_LENGTH_4B, /**< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT0.BYTE2. */
+ NRF_QSPI_CINSTR_LEN_5B = QSPI_CINSTRCONF_LENGTH_5B, /**< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT0.BYTE3. */
+ NRF_QSPI_CINSTR_LEN_6B = QSPI_CINSTRCONF_LENGTH_6B, /**< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT1.BYTE4. */
+ NRF_QSPI_CINSTR_LEN_7B = QSPI_CINSTRCONF_LENGTH_7B, /**< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT1.BYTE5. */
+ NRF_QSPI_CINSTR_LEN_8B = QSPI_CINSTRCONF_LENGTH_8B, /**< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT1.BYTE6. */
+ NRF_QSPI_CINSTR_LEN_9B = QSPI_CINSTRCONF_LENGTH_9B /**< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT1.BYTE7. */
+} nrf_qspi_cinstr_len_t;
+
+/**
+ * @brief Pins configuration.
+ */
+typedef struct
+{
+ uint8_t sck_pin; /**< SCK pin number. */
+ uint8_t csn_pin; /**< Chip select pin number. */
+ uint8_t io0_pin; /**< IO0/MOSI pin number. */
+ uint8_t io1_pin; /**< IO1/MISO pin number. */
+ uint8_t io2_pin; /**< IO2 pin number (optional).
+ * Set to @ref NRF_QSPI_PIN_NOT_CONNECTED if this signal is not needed.
+ */
+ uint8_t io3_pin; /**< IO3 pin number (optional).
+ * Set to @ref NRF_QSPI_PIN_NOT_CONNECTED if this signal is not needed.
+ */
+} nrf_qspi_pins_t;
+
+/**
+ * @brief Custom instruction configuration.
+ */
+typedef struct
+{
+ uint8_t opcode; /**< Opcode used in custom instruction transmission. */
+ nrf_qspi_cinstr_len_t length; /**< Length of the custom instruction data. */
+ bool io2_level; /**< I/O line level during transmission. */
+ bool io3_level; /**< I/O line level during transmission. */
+ bool wipwait; /**< Wait if a Wait in Progress bit is set in the memory status byte. */
+ bool wren; /**< Send write enable before instruction. */
+} nrf_qspi_cinstr_conf_t;
+
+/**
+ * @brief Addressing mode register configuration. See @ref nrf_qspi_addrconfig_set
+ */
+typedef struct
+{
+ uint8_t opcode; /**< Opcode used to enter proper addressing mode. */
+ uint8_t byte0; /**< Byte following the opcode. */
+ uint8_t byte1; /**< Byte following byte0. */
+ nrf_qspi_addrconfig_mode_t mode; /**< Extended addresing mode. */
+ bool wipwait; /**< Enable/disable waiting for complete operation execution. */
+ bool wren; /**< Send write enable before instruction. */
+} nrf_qspi_addrconfig_conf_t;
+
+/**
+ * @brief Structure with QSPI protocol interface configuration.
+ */
+typedef struct
+{
+ nrf_qspi_readoc_t readoc; /**< Read operation code. */
+ nrf_qspi_writeoc_t writeoc; /**< Write operation code. */
+ nrf_qspi_addrmode_t addrmode; /**< Addresing mode (24-bit or 32-bit). */
+ bool dpmconfig; /**< Enable the Deep Power-down Mode (DPM) feature. */
+} nrf_qspi_prot_conf_t;
+
+/**
+ * @brief QSPI physical interface configuration.
+ */
+typedef struct
+{
+ uint8_t sck_delay; /**< tSHSL, tWHSL, and tSHWL in number of 16 MHz periods (62.5ns). */
+ bool dpmen; /**< Enable the DPM feature. */
+ nrf_qspi_spi_mode_t spi_mode; /**< SPI phase and polarization. */
+ nrf_qspi_frequency_t sck_freq; /**< SCK frequency given as enum @ref nrf_qspi_frequency_t. */
+} nrf_qspi_phy_conf_t;
+
+/**
+ * @brief Function for activating a specific QSPI task.
+ *
+ * @param[in] p_reg Pointer to the peripheral register structure.
+ * @param[in] task Task to activate.
+ */
+__STATIC_INLINE void nrf_qspi_task_trigger(NRF_QSPI_Type * p_reg, nrf_qspi_task_t task);
+
+/**
+ * @brief Function for getting the address of a specific QSPI task register.
+ *
+ * @param[in] p_reg Pointer to the peripheral register structure.
+ * @param[in] task Requested task.
+ *
+ * @return Address of the specified task register.
+ */
+__STATIC_INLINE uint32_t nrf_qspi_task_address_get(NRF_QSPI_Type const * p_reg,
+ nrf_qspi_task_t task);
+
+/**
+ * @brief Function for clearing a specific QSPI event.
+ *
+ * @param[in] p_reg Pointer to the peripheral register structure.
+ * @param[in] qspi_event Event to clear.
+ */
+__STATIC_INLINE void nrf_qspi_event_clear(NRF_QSPI_Type * p_reg, nrf_qspi_event_t qspi_event);
+
+/**
+ * @brief Function for checking the state of a specific SPI event.
+ *
+ * @param[in] p_reg Pointer to the peripheral register structure.
+ * @param[in] qspi_event Event to check.
+ *
+ * @retval true If the event is set.
+ * @retval false If the event is not set.
+ */
+__STATIC_INLINE bool nrf_qspi_event_check(NRF_QSPI_Type const * p_reg, nrf_qspi_event_t qspi_event);
+
+/**
+ * @brief Function for getting the address of a specific QSPI event register.
+ *
+ * @param[in] p_reg Pointer to the peripheral register structure.
+ * @param[in] qspi_event Requested event.
+ *
+ * @return Address of the specified event register.
+ */
+__STATIC_INLINE uint32_t * nrf_qspi_event_address_get(NRF_QSPI_Type const * p_reg,
+ nrf_qspi_event_t qspi_event);
+
+/**
+ * @brief Function for enabling specified interrupts.
+ *
+ * @param[in] p_reg Pointer to the peripheral register structure.
+ * @param[in] qspi_int_mask Interrupts to enable.
+ */
+__STATIC_INLINE void nrf_qspi_int_enable(NRF_QSPI_Type * p_reg, uint32_t qspi_int_mask);
+
+/**
+ * @brief Function for disabling specified interrupts.
+ *
+ * @param[in] p_reg Pointer to the peripheral register structure.
+ * @param[in] qspi_int_mask Interrupts to disable.
+ */
+__STATIC_INLINE void nrf_qspi_int_disable(NRF_QSPI_Type * p_reg, uint32_t qspi_int_mask);
+
+/**
+ * @brief Function for retrieving the state of a given interrupt.
+ *
+ * @param[in] p_reg Pointer to the peripheral register structure.
+ * @param[in] qspi_int Interrupt to check.
+ *
+ * @retval true If the interrupt is enabled.
+ * @retval false If the interrupt is not enabled.
+ */
+__STATIC_INLINE bool nrf_qspi_int_enable_check(NRF_QSPI_Type const * p_reg,
+ nrf_qspi_int_mask_t qspi_int);
+
+/**
+ * @brief Function for enabling the QSPI peripheral.
+ *
+ * @param[in] p_reg Pointer to the peripheral register structure.
+ */
+__STATIC_INLINE void nrf_qspi_enable(NRF_QSPI_Type * p_reg);
+
+/**
+ * @brief Function for disabling the QSPI peripheral.
+ *
+ * @param[in] p_reg Pointer to the peripheral register structure.
+ */
+__STATIC_INLINE void nrf_qspi_disable(NRF_QSPI_Type * p_reg);
+
+/**
+ * @brief Function for configuring QSPI pins.
+ *
+ * If a given signal is not needed, pass the @ref NRF_QSPI_PIN_NOT_CONNECTED
+ * value instead of its pin number.
+ *
+ * @param[in] p_reg Pointer to the peripheral register structure.
+ * @param[in] p_pins Pointer to the pins configuration structure. See @ref nrf_qspi_pins_t.
+ */
+__STATIC_INLINE void nrf_qspi_pins_set(NRF_QSPI_Type * p_reg,
+ const nrf_qspi_pins_t * p_pins);
+
+/**
+ * @brief Function for setting the QSPI IFCONFIG0 register.
+ *
+ * @param[in] p_reg Pointer to the peripheral register structure.
+ * @param[in] p_config Pointer to the QSPI protocol interface configuration structure. See @ref nrf_qspi_prot_conf_t.
+ */
+__STATIC_INLINE void nrf_qspi_ifconfig0_set(NRF_QSPI_Type * p_reg,
+ const nrf_qspi_prot_conf_t * p_config);
+
+/**
+ * @brief Function for setting the QSPI IFCONFIG1 register.
+ *
+ * @param[in] p_reg Pointer to the peripheral register structure.
+ * @param[in] p_config Pointer to the QSPI physical interface configuration structure. See @ref nrf_qspi_phy_conf_t.
+ */
+__STATIC_INLINE void nrf_qspi_ifconfig1_set(NRF_QSPI_Type * p_reg,
+ const nrf_qspi_phy_conf_t * p_config);
+
+/**
+ * @brief Function for setting the QSPI ADDRCONF register.
+ *
+ * Function must be executed before sending task NRF_QSPI_TASK_ACTIVATE. Data stored in the structure
+ * is sent during the start of the peripheral. Remember that the reset instruction can set
+ * addressing mode to default in the memory device. If memory reset is necessary before configuring
+ * the addressing mode, use custom instruction feature instead of this function.
+ * Case with reset: Enable the peripheral without setting ADDRCONF register, send reset instructions
+ * using a custom instruction feature (reset enable and then reset), set proper addressing mode
+ * using the custom instruction feature.
+ *
+ * @param[in] p_reg Pointer to the peripheral register structure.
+ * @param[in] p_config Pointer to the addressing mode configuration structure. See @ref nrf_qspi_addrconfig_conf_t.
+*/
+__STATIC_INLINE void nrf_qspi_addrconfig_set(NRF_QSPI_Type * p_reg,
+ const nrf_qspi_addrconfig_conf_t * p_config);
+
+/**
+ * @brief Function for setting write data into the peripheral register (without starting the process).
+ *
+ * @param[in] p_reg Pointer to the peripheral register structure.
+ * @param[in] p_buffer Pointer to the writing buffer.
+ * @param[in] length Lenght of the writing data.
+ * @param[in] dest_addr Address in memory to write to.
+ */
+__STATIC_INLINE void nrf_qspi_write_buffer_set(NRF_QSPI_Type * p_reg,
+ void const * p_buffer,
+ uint32_t length,
+ uint32_t dest_addr);
+
+/**
+ * @brief Function for setting read data into the peripheral register (without starting the process).
+ *
+ * @param[in] p_reg Pointer to the peripheral register structure.
+ * @param[out] p_buffer Pointer to the reading buffer.
+ * @param[in] length Length of the read data.
+ * @param[in] src_addr Address in memory to read from.
+ */
+__STATIC_INLINE void nrf_qspi_read_buffer_set(NRF_QSPI_Type * p_reg,
+ void * p_buffer,
+ uint32_t length,
+ uint32_t src_addr);
+
+/**
+ * @brief Function for setting erase data into the peripheral register (without starting the process).
+ *
+ * @param[in] p_reg Pointer to the peripheral register structure.
+ * @param[in] erase_addr Start address to erase. Address must have padding set to 4 bytes.
+ * @param[in] len Size of erasing area.
+ */
+__STATIC_INLINE void nrf_qspi_erase_ptr_set(NRF_QSPI_Type * p_reg,
+ uint32_t erase_addr,
+ nrf_qspi_erase_len_t len);
+
+/**
+ * @brief Function for getting the peripheral status register.
+ *
+ * @param[in] p_reg Pointer to the peripheral register structure.
+ *
+ * @return Peripheral status register.
+ */
+__STATIC_INLINE uint32_t nrf_qspi_status_reg_get(NRF_QSPI_Type const * p_reg);
+
+/**
+ * @brief Function for getting the device status register stored in the peripheral status register.
+ *
+ * @param[in] p_reg Pointer to the peripheral register structure.
+ *
+ * @return Device status register (lower byte).
+ */
+__STATIC_INLINE uint8_t nrf_qspi_sreg_get(NRF_QSPI_Type const * p_reg);
+
+/**
+ * @brief Function for checking if the peripheral is busy or not.
+ *
+ * @param[in] p_reg Pointer to the peripheral register structure.
+ *
+ * @retval true If QSPI is busy.
+ * @retval false If QSPI is ready.
+ */
+__STATIC_INLINE bool nrf_qspi_busy_check(NRF_QSPI_Type const * p_reg);
+
+/**
+ * @brief Function for setting registers sending with custom instruction transmission.
+ *
+ * This function can be ommited when using NRF_QSPI_CINSTR_LEN_1B as the length argument
+ * (sending only opcode without data).
+ *
+ * @param[in] p_reg Pointer to the peripheral register structure.
+ * @param[in] length Length of the custom instruction data.
+ * @param[in] p_tx_data Pointer to the data to send with the custom instruction.
+ */
+__STATIC_INLINE void nrf_qspi_cinstrdata_set(NRF_QSPI_Type * p_reg,
+ nrf_qspi_cinstr_len_t length,
+ void const * p_tx_data);
+
+/**
+ * @brief Function for getting data from register after custom instruction transmission.
+ * @param[in] p_reg Pointer to the peripheral register structure.
+ * @param[in] length Length of the custom instruction data.
+ * @param[in] p_rx_data Pointer to the reading buffer.
+ */
+__STATIC_INLINE void nrf_qspi_cinstrdata_get(NRF_QSPI_Type const * p_reg,
+ nrf_qspi_cinstr_len_t length,
+ void * p_rx_data);
+
+/**
+ * @brief Function for sending custom instruction to external memory.
+ *
+ * @param[in] p_reg Pointer to the peripheral register structure.
+ * @param[in] p_config Pointer to the custom instruction configuration structure. See @ref nrf_qspi_cinstr_conf_t.
+ */
+
+__STATIC_INLINE void nrf_qspi_cinstr_transfer_start(NRF_QSPI_Type * p_reg,
+ const nrf_qspi_cinstr_conf_t * p_config);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE void nrf_qspi_task_trigger(NRF_QSPI_Type * p_reg, nrf_qspi_task_t task)
+{
+ *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
+}
+
+__STATIC_INLINE uint32_t nrf_qspi_task_address_get(NRF_QSPI_Type const * p_reg,
+ nrf_qspi_task_t task)
+{
+ return ((uint32_t)p_reg + (uint32_t)task);
+}
+
+__STATIC_INLINE void nrf_qspi_event_clear(NRF_QSPI_Type * p_reg, nrf_qspi_event_t qspi_event)
+{
+ *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)qspi_event)) = 0x0UL;
+}
+
+__STATIC_INLINE bool nrf_qspi_event_check(NRF_QSPI_Type const * p_reg, nrf_qspi_event_t qspi_event)
+{
+ return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)qspi_event);
+}
+
+__STATIC_INLINE uint32_t * nrf_qspi_event_address_get(NRF_QSPI_Type const * p_reg,
+ nrf_qspi_event_t qspi_event)
+{
+ return (uint32_t *)((uint8_t *)p_reg + (uint32_t)qspi_event);
+}
+
+__STATIC_INLINE void nrf_qspi_int_enable(NRF_QSPI_Type * p_reg, uint32_t qspi_int_mask)
+{
+ p_reg->INTENSET = qspi_int_mask;
+}
+
+__STATIC_INLINE void nrf_qspi_int_disable(NRF_QSPI_Type * p_reg, uint32_t qspi_int_mask)
+{
+ p_reg->INTENCLR = qspi_int_mask;
+}
+
+__STATIC_INLINE bool nrf_qspi_int_enable_check(NRF_QSPI_Type const * p_reg,
+ nrf_qspi_int_mask_t qspi_int)
+{
+ return (bool)(p_reg->INTENSET & qspi_int);
+}
+
+__STATIC_INLINE void nrf_qspi_enable(NRF_QSPI_Type * p_reg)
+{
+ p_reg->ENABLE = (QSPI_ENABLE_ENABLE_Enabled << QSPI_ENABLE_ENABLE_Pos);
+}
+
+__STATIC_INLINE void nrf_qspi_disable(NRF_QSPI_Type * p_reg)
+{
+ p_reg->ENABLE = (QSPI_ENABLE_ENABLE_Disabled << QSPI_ENABLE_ENABLE_Pos);
+}
+
+__STATIC_INLINE void nrf_qspi_pins_set(NRF_QSPI_Type * p_reg, const nrf_qspi_pins_t * p_pins)
+{
+ p_reg->PSEL.SCK = NRF_QSPI_PIN_VAL(p_pins->sck_pin);
+ p_reg->PSEL.CSN = NRF_QSPI_PIN_VAL(p_pins->csn_pin);
+ p_reg->PSEL.IO0 = NRF_QSPI_PIN_VAL(p_pins->io0_pin);
+ p_reg->PSEL.IO1 = NRF_QSPI_PIN_VAL(p_pins->io1_pin);
+ p_reg->PSEL.IO2 = NRF_QSPI_PIN_VAL(p_pins->io2_pin);
+ p_reg->PSEL.IO3 = NRF_QSPI_PIN_VAL(p_pins->io3_pin);
+}
+
+__STATIC_INLINE void nrf_qspi_ifconfig0_set(NRF_QSPI_Type * p_reg,
+ const nrf_qspi_prot_conf_t * p_config)
+{
+ uint32_t config = p_config->readoc;
+ config |= ((uint32_t)p_config->writeoc) << QSPI_IFCONFIG0_WRITEOC_Pos;
+ config |= ((uint32_t)p_config->addrmode) << QSPI_IFCONFIG0_ADDRMODE_Pos;
+ config |= (p_config->dpmconfig ? 1U : 0U ) << QSPI_IFCONFIG0_DPMENABLE_Pos;
+
+ p_reg->IFCONFIG0 = config;
+}
+
+__STATIC_INLINE void nrf_qspi_ifconfig1_set(NRF_QSPI_Type * p_reg,
+ const nrf_qspi_phy_conf_t * p_config)
+{
+ // IFCONFIG1 mask for reserved fields in the register.
+ uint32_t config = p_reg->IFCONFIG1 & 0x00FFFF00;
+ config |= p_config->sck_delay;
+ config |= (p_config->dpmen ? 1U : 0U) << QSPI_IFCONFIG1_DPMEN_Pos;
+ config |= ((uint32_t)(p_config->spi_mode)) << QSPI_IFCONFIG1_SPIMODE_Pos;
+ config |= ((uint32_t)(p_config->sck_freq)) << QSPI_IFCONFIG1_SCKFREQ_Pos;
+
+ p_reg->IFCONFIG1 = config;
+}
+
+__STATIC_INLINE void nrf_qspi_addrconfig_set(NRF_QSPI_Type * p_reg,
+ const nrf_qspi_addrconfig_conf_t * p_config)
+{
+ uint32_t config = p_config->opcode;
+ config |= ((uint32_t)p_config->byte0) << QSPI_ADDRCONF_BYTE0_Pos;
+ config |= ((uint32_t)p_config->byte1) << QSPI_ADDRCONF_BYTE1_Pos;
+ config |= ((uint32_t)(p_config->mode)) << QSPI_ADDRCONF_MODE_Pos;
+ config |= (p_config->wipwait ? 1U : 0U) << QSPI_ADDRCONF_WIPWAIT_Pos;
+ config |= (p_config->wren ? 1U : 0U) << QSPI_ADDRCONF_WREN_Pos;
+
+ p_reg->ADDRCONF = config;
+}
+
+__STATIC_INLINE void nrf_qspi_write_buffer_set(NRF_QSPI_Type * p_reg,
+ void const * p_buffer,
+ uint32_t length,
+ uint32_t dest_addr)
+{
+ p_reg->WRITE.DST = dest_addr;
+ p_reg->WRITE.SRC = (uint32_t) p_buffer;
+ p_reg->WRITE.CNT = length;
+}
+
+__STATIC_INLINE void nrf_qspi_read_buffer_set(NRF_QSPI_Type * p_reg,
+ void * p_buffer,
+ uint32_t length,
+ uint32_t src_addr)
+{
+ p_reg->READ.SRC = src_addr;
+ p_reg->READ.DST = (uint32_t) p_buffer;
+ p_reg->READ.CNT = length;
+}
+
+__STATIC_INLINE void nrf_qspi_erase_ptr_set(NRF_QSPI_Type * p_reg,
+ uint32_t erase_addr,
+ nrf_qspi_erase_len_t len)
+{
+ p_reg->ERASE.PTR = erase_addr;
+ p_reg->ERASE.LEN = len;
+}
+
+__STATIC_INLINE uint32_t nrf_qspi_status_reg_get(NRF_QSPI_Type const * p_reg)
+{
+ return p_reg->STATUS;
+}
+
+__STATIC_INLINE uint8_t nrf_qspi_sreg_get(NRF_QSPI_Type const * p_reg)
+{
+ return (uint8_t)(p_reg->STATUS & QSPI_STATUS_SREG_Msk) >> QSPI_STATUS_SREG_Pos;
+}
+
+__STATIC_INLINE bool nrf_qspi_busy_check(NRF_QSPI_Type const * p_reg)
+{
+ return ((p_reg->STATUS & QSPI_STATUS_READY_Msk) >>
+ QSPI_STATUS_READY_Pos) == QSPI_STATUS_READY_BUSY;
+}
+
+__STATIC_INLINE void nrf_qspi_cinstrdata_set(NRF_QSPI_Type * p_reg,
+ nrf_qspi_cinstr_len_t length,
+ void const * p_tx_data)
+{
+ uint32_t reg = 0;
+ uint8_t const *p_tx_data_8 = (uint8_t const *) p_tx_data;
+
+ // Load custom instruction.
+ switch (length)
+ {
+ case NRF_QSPI_CINSTR_LEN_9B:
+ reg |= ((uint32_t)p_tx_data_8[7]) << QSPI_CINSTRDAT1_BYTE7_Pos;
+ /* fall-through */
+ case NRF_QSPI_CINSTR_LEN_8B:
+ reg |= ((uint32_t)p_tx_data_8[6]) << QSPI_CINSTRDAT1_BYTE6_Pos;
+ /* fall-through */
+ case NRF_QSPI_CINSTR_LEN_7B:
+ reg |= ((uint32_t)p_tx_data_8[5]) << QSPI_CINSTRDAT1_BYTE5_Pos;
+ /* fall-through */
+ case NRF_QSPI_CINSTR_LEN_6B:
+ reg |= ((uint32_t)p_tx_data_8[4]);
+ p_reg->CINSTRDAT1 = reg;
+ reg = 0;
+ /* fall-through */
+ case NRF_QSPI_CINSTR_LEN_5B:
+ reg |= ((uint32_t)p_tx_data_8[3]) << QSPI_CINSTRDAT0_BYTE3_Pos;
+ /* fall-through */
+ case NRF_QSPI_CINSTR_LEN_4B:
+ reg |= ((uint32_t)p_tx_data_8[2]) << QSPI_CINSTRDAT0_BYTE2_Pos;
+ /* fall-through */
+ case NRF_QSPI_CINSTR_LEN_3B:
+ reg |= ((uint32_t)p_tx_data_8[1]) << QSPI_CINSTRDAT0_BYTE1_Pos;
+ /* fall-through */
+ case NRF_QSPI_CINSTR_LEN_2B:
+ reg |= ((uint32_t)p_tx_data_8[0]);
+ p_reg->CINSTRDAT0 = reg;
+ /* fall-through */
+ case NRF_QSPI_CINSTR_LEN_1B:
+ /* Send only opcode. Case to avoid compiler warnings. */
+ break;
+ default:
+ break;
+ }
+}
+
+__STATIC_INLINE void nrf_qspi_cinstrdata_get(NRF_QSPI_Type const * p_reg,
+ nrf_qspi_cinstr_len_t length,
+ void * p_rx_data)
+{
+ uint8_t *p_rx_data_8 = (uint8_t *) p_rx_data;
+
+ uint32_t reg = p_reg->CINSTRDAT1;
+ switch (length)
+ {
+ case NRF_QSPI_CINSTR_LEN_9B:
+ p_rx_data_8[7] = (uint8_t)(reg >> QSPI_CINSTRDAT1_BYTE7_Pos);
+ /* fall-through */
+ case NRF_QSPI_CINSTR_LEN_8B:
+ p_rx_data_8[6] = (uint8_t)(reg >> QSPI_CINSTRDAT1_BYTE6_Pos);
+ /* fall-through */
+ case NRF_QSPI_CINSTR_LEN_7B:
+ p_rx_data_8[5] = (uint8_t)(reg >> QSPI_CINSTRDAT1_BYTE5_Pos);
+ /* fall-through */
+ case NRF_QSPI_CINSTR_LEN_6B:
+ p_rx_data_8[4] = (uint8_t)(reg);
+ /* fall-through */
+ default:
+ break;
+ }
+
+ reg = p_reg->CINSTRDAT0;
+ switch (length)
+ {
+ case NRF_QSPI_CINSTR_LEN_5B:
+ p_rx_data_8[3] = (uint8_t)(reg >> QSPI_CINSTRDAT0_BYTE3_Pos);
+ /* fall-through */
+ case NRF_QSPI_CINSTR_LEN_4B:
+ p_rx_data_8[2] = (uint8_t)(reg >> QSPI_CINSTRDAT0_BYTE2_Pos);
+ /* fall-through */
+ case NRF_QSPI_CINSTR_LEN_3B:
+ p_rx_data_8[1] = (uint8_t)(reg >> QSPI_CINSTRDAT0_BYTE1_Pos);
+ /* fall-through */
+ case NRF_QSPI_CINSTR_LEN_2B:
+ p_rx_data_8[0] = (uint8_t)(reg);
+ /* fall-through */
+ case NRF_QSPI_CINSTR_LEN_1B:
+ /* Send only opcode. Case to avoid compiler warnings. */
+ break;
+ default:
+ break;
+ }
+}
+
+__STATIC_INLINE void nrf_qspi_cinstr_transfer_start(NRF_QSPI_Type * p_reg,
+ const nrf_qspi_cinstr_conf_t * p_config)
+{
+ p_reg->CINSTRCONF = (((uint32_t)p_config->opcode << QSPI_CINSTRCONF_OPCODE_Pos) |
+ ((uint32_t)p_config->length << QSPI_CINSTRCONF_LENGTH_Pos) |
+ ((uint32_t)p_config->io2_level << QSPI_CINSTRCONF_LIO2_Pos) |
+ ((uint32_t)p_config->io3_level << QSPI_CINSTRCONF_LIO3_Pos) |
+ ((uint32_t)p_config->wipwait << QSPI_CINSTRCONF_WIPWAIT_Pos) |
+ ((uint32_t)p_config->wren << QSPI_CINSTRCONF_WREN_Pos));
+}
+
+#endif // SUPPRESS_INLINE_IMPLEMENTATION
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_QSPI_H__
+
+/** @} */
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_rng.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_rng.h
new file mode 100644
index 000000000..9ebf81748
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_rng.h
@@ -0,0 +1,282 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ * @brief RNG HAL API.
+ */
+
+#ifndef NRF_RNG_H__
+#define NRF_RNG_H__
+/**
+ * @defgroup nrf_rng_hal RNG HAL
+ * @{
+ * @ingroup nrf_rng
+ * @brief Hardware access layer for managing the random number generator (RNG).
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+#include "nrf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NRF_RNG_TASK_SET (1UL)
+#define NRF_RNG_EVENT_CLEAR (0UL)
+/**
+ * @enum nrf_rng_task_t
+ * @brief RNG tasks.
+ */
+typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
+{
+ NRF_RNG_TASK_START = offsetof(NRF_RNG_Type, TASKS_START), /**< Start the random number generator. */
+ NRF_RNG_TASK_STOP = offsetof(NRF_RNG_Type, TASKS_STOP) /**< Stop the random number generator. */
+} nrf_rng_task_t; /*lint -restore */
+
+/**
+ * @enum nrf_rng_event_t
+ * @brief RNG events.
+ */
+typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
+{
+ NRF_RNG_EVENT_VALRDY = offsetof(NRF_RNG_Type, EVENTS_VALRDY) /**< New random number generated event. */
+} nrf_rng_event_t; /*lint -restore */
+
+/**
+ * @enum nrf_rng_int_mask_t
+ * @brief RNG interrupts.
+ */
+typedef enum
+{
+ NRF_RNG_INT_VALRDY_MASK = RNG_INTENSET_VALRDY_Msk /**< Mask for enabling or disabling an interrupt on VALRDY event. */
+} nrf_rng_int_mask_t;
+
+/**
+ * @enum nrf_rng_short_mask_t
+ * @brief Types of RNG shortcuts.
+ */
+typedef enum
+{
+ NRF_RNG_SHORT_VALRDY_STOP_MASK = RNG_SHORTS_VALRDY_STOP_Msk /**< Mask for setting shortcut between EVENT_VALRDY and TASK_STOP. */
+} nrf_rng_short_mask_t;
+
+/**
+ * @brief Function for enabling interrupts.
+ *
+ * @param[in] rng_int_mask Mask of interrupts.
+ */
+__STATIC_INLINE void nrf_rng_int_enable(uint32_t rng_int_mask);
+
+/**
+ * @brief Function for disabling interrupts.
+ *
+ * @param[in] rng_int_mask Mask of interrupts.
+ */
+__STATIC_INLINE void nrf_rng_int_disable(uint32_t rng_int_mask);
+
+/**
+ * @brief Function for getting the state of a specific interrupt.
+ *
+ * @param[in] rng_int_mask Interrupt.
+ *
+ * @retval true If the interrupt is not enabled.
+ * @retval false If the interrupt is enabled.
+ */
+__STATIC_INLINE bool nrf_rng_int_get(nrf_rng_int_mask_t rng_int_mask);
+
+/**
+ * @brief Function for getting the address of a specific task.
+ *
+ * This function can be used by the PPI module.
+ *
+ * @param[in] rng_task Task.
+ */
+__STATIC_INLINE uint32_t * nrf_rng_task_address_get(nrf_rng_task_t rng_task);
+
+/**
+ * @brief Function for setting a specific task.
+ *
+ * @param[in] rng_task Task.
+ */
+__STATIC_INLINE void nrf_rng_task_trigger(nrf_rng_task_t rng_task);
+
+/**
+ * @brief Function for getting address of a specific event.
+ *
+ * This function can be used by the PPI module.
+ *
+ * @param[in] rng_event Event.
+ */
+__STATIC_INLINE uint32_t * nrf_rng_event_address_get(nrf_rng_event_t rng_event);
+
+/**
+ * @brief Function for clearing a specific event.
+ *
+ * @param[in] rng_event Event.
+ */
+__STATIC_INLINE void nrf_rng_event_clear(nrf_rng_event_t rng_event);
+
+/**
+ * @brief Function for getting the state of a specific event.
+ *
+ * @param[in] rng_event Event.
+ *
+ * @retval true If the event is not set.
+ * @retval false If the event is set.
+ */
+__STATIC_INLINE bool nrf_rng_event_get(nrf_rng_event_t rng_event);
+
+/**
+ * @brief Function for setting shortcuts.
+ *
+ * @param[in] rng_short_mask Mask of shortcuts.
+ *
+ */
+__STATIC_INLINE void nrf_rng_shorts_enable(uint32_t rng_short_mask);
+
+/**
+ * @brief Function for clearing shortcuts.
+ *
+ * @param[in] rng_short_mask Mask of shortcuts.
+ *
+ */
+__STATIC_INLINE void nrf_rng_shorts_disable(uint32_t rng_short_mask);
+
+/**
+ * @brief Function for getting the previously generated random value.
+ *
+ * @return Previously generated random value.
+ */
+__STATIC_INLINE uint8_t nrf_rng_random_value_get(void);
+
+/**
+ * @brief Function for enabling digital error correction.
+ */
+__STATIC_INLINE void nrf_rng_error_correction_enable(void);
+
+/**
+ * @brief Function for disabling digital error correction.
+ */
+__STATIC_INLINE void nrf_rng_error_correction_disable(void);
+
+/**
+ *@}
+ **/
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE void nrf_rng_int_enable(uint32_t rng_int_mask)
+{
+ NRF_RNG->INTENSET = rng_int_mask;
+}
+
+__STATIC_INLINE void nrf_rng_int_disable(uint32_t rng_int_mask)
+{
+ NRF_RNG->INTENCLR = rng_int_mask;
+}
+
+__STATIC_INLINE bool nrf_rng_int_get(nrf_rng_int_mask_t rng_int_mask)
+{
+ return (bool)(NRF_RNG->INTENCLR & rng_int_mask);
+}
+
+__STATIC_INLINE uint32_t * nrf_rng_task_address_get(nrf_rng_task_t rng_task)
+{
+ return (uint32_t *)((uint8_t *)NRF_RNG + rng_task);
+}
+
+__STATIC_INLINE void nrf_rng_task_trigger(nrf_rng_task_t rng_task)
+{
+ *((volatile uint32_t *)((uint8_t *)NRF_RNG + rng_task)) = NRF_RNG_TASK_SET;
+}
+
+__STATIC_INLINE uint32_t * nrf_rng_event_address_get(nrf_rng_event_t rng_event)
+{
+ return (uint32_t *)((uint8_t *)NRF_RNG + rng_event);
+}
+
+__STATIC_INLINE void nrf_rng_event_clear(nrf_rng_event_t rng_event)
+{
+ *((volatile uint32_t *)((uint8_t *)NRF_RNG + rng_event)) = NRF_RNG_EVENT_CLEAR;
+#if __CORTEX_M == 0x04
+ volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_RNG + rng_event));
+ (void)dummy;
+#endif
+}
+
+__STATIC_INLINE bool nrf_rng_event_get(nrf_rng_event_t rng_event)
+{
+ return (bool) * ((volatile uint32_t *)((uint8_t *)NRF_RNG + rng_event));
+}
+
+__STATIC_INLINE void nrf_rng_shorts_enable(uint32_t rng_short_mask)
+{
+ NRF_RNG->SHORTS |= rng_short_mask;
+}
+
+__STATIC_INLINE void nrf_rng_shorts_disable(uint32_t rng_short_mask)
+{
+ NRF_RNG->SHORTS &= ~rng_short_mask;
+}
+
+__STATIC_INLINE uint8_t nrf_rng_random_value_get(void)
+{
+ return (uint8_t)(NRF_RNG->VALUE & RNG_VALUE_VALUE_Msk);
+}
+
+__STATIC_INLINE void nrf_rng_error_correction_enable(void)
+{
+ NRF_RNG->CONFIG |= RNG_CONFIG_DERCEN_Msk;
+}
+
+__STATIC_INLINE void nrf_rng_error_correction_disable(void)
+{
+ NRF_RNG->CONFIG &= ~RNG_CONFIG_DERCEN_Msk;
+}
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_RNG_H__ */
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_rtc.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_rtc.h
new file mode 100644
index 000000000..1b1f83988
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_rtc.h
@@ -0,0 +1,343 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ * @brief RTC HAL API.
+ */
+
+#ifndef NRF_RTC_H
+#define NRF_RTC_H
+
+/**
+ * @defgroup nrf_rtc_hal RTC HAL
+ * @{
+ * @ingroup nrf_rtc
+ * @brief Hardware access layer for managing the real time counter (RTC).
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+#include "nrf.h"
+#include "nrf_assert.h"
+#include "nrf_peripherals.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Macro for getting the number of compare channels available
+ * in a given RTC instance.
+ */
+
+#define NRF_RTC_CC_CHANNEL_COUNT(id) CONCAT_3(RTC, id, _CC_NUM)
+
+#define RTC_INPUT_FREQ 32768 /**< Input frequency of the RTC instance. */
+
+/**
+ * @brief Macro for converting expected frequency to prescaler setting.
+ */
+#define RTC_FREQ_TO_PRESCALER(FREQ) (uint16_t)(((RTC_INPUT_FREQ) / (FREQ)) - 1)
+
+/**< Macro for wrapping values to RTC capacity. */
+#define RTC_WRAP(val) ((val) & RTC_COUNTER_COUNTER_Msk)
+
+#define RTC_CHANNEL_INT_MASK(ch) ((uint32_t)(NRF_RTC_INT_COMPARE0_MASK) << (ch))
+#define RTC_CHANNEL_EVENT_ADDR(ch) (nrf_rtc_event_t)((NRF_RTC_EVENT_COMPARE_0) + (ch) * sizeof(uint32_t))
+/**
+ * @enum nrf_rtc_task_t
+ * @brief RTC tasks.
+ */
+typedef enum
+{
+ /*lint -save -e30*/
+ NRF_RTC_TASK_START = offsetof(NRF_RTC_Type,TASKS_START), /**< Start. */
+ NRF_RTC_TASK_STOP = offsetof(NRF_RTC_Type,TASKS_STOP), /**< Stop. */
+ NRF_RTC_TASK_CLEAR = offsetof(NRF_RTC_Type,TASKS_CLEAR), /**< Clear. */
+ NRF_RTC_TASK_TRIGGER_OVERFLOW = offsetof(NRF_RTC_Type,TASKS_TRIGOVRFLW),/**< Trigger overflow. */
+ /*lint -restore*/
+} nrf_rtc_task_t;
+
+/**
+ * @enum nrf_rtc_event_t
+ * @brief RTC events.
+ */
+typedef enum
+{
+ /*lint -save -e30*/
+ NRF_RTC_EVENT_TICK = offsetof(NRF_RTC_Type,EVENTS_TICK), /**< Tick event. */
+ NRF_RTC_EVENT_OVERFLOW = offsetof(NRF_RTC_Type,EVENTS_OVRFLW), /**< Overflow event. */
+ NRF_RTC_EVENT_COMPARE_0 = offsetof(NRF_RTC_Type,EVENTS_COMPARE[0]), /**< Compare 0 event. */
+ NRF_RTC_EVENT_COMPARE_1 = offsetof(NRF_RTC_Type,EVENTS_COMPARE[1]), /**< Compare 1 event. */
+ NRF_RTC_EVENT_COMPARE_2 = offsetof(NRF_RTC_Type,EVENTS_COMPARE[2]), /**< Compare 2 event. */
+ NRF_RTC_EVENT_COMPARE_3 = offsetof(NRF_RTC_Type,EVENTS_COMPARE[3]) /**< Compare 3 event. */
+ /*lint -restore*/
+} nrf_rtc_event_t;
+
+/**
+ * @enum nrf_rtc_int_t
+ * @brief RTC interrupts.
+ */
+typedef enum
+{
+ NRF_RTC_INT_TICK_MASK = RTC_INTENSET_TICK_Msk, /**< RTC interrupt from tick event. */
+ NRF_RTC_INT_OVERFLOW_MASK = RTC_INTENSET_OVRFLW_Msk, /**< RTC interrupt from overflow event. */
+ NRF_RTC_INT_COMPARE0_MASK = RTC_INTENSET_COMPARE0_Msk, /**< RTC interrupt from compare event on channel 0. */
+ NRF_RTC_INT_COMPARE1_MASK = RTC_INTENSET_COMPARE1_Msk, /**< RTC interrupt from compare event on channel 1. */
+ NRF_RTC_INT_COMPARE2_MASK = RTC_INTENSET_COMPARE2_Msk, /**< RTC interrupt from compare event on channel 2. */
+ NRF_RTC_INT_COMPARE3_MASK = RTC_INTENSET_COMPARE3_Msk /**< RTC interrupt from compare event on channel 3. */
+} nrf_rtc_int_t;
+
+/**@brief Function for setting a compare value for a channel.
+ *
+ * @param[in] p_rtc Pointer to the peripheral registers structure.
+ * @param[in] ch Channel.
+ * @param[in] cc_val Compare value to set.
+ */
+__STATIC_INLINE void nrf_rtc_cc_set(NRF_RTC_Type * p_rtc, uint32_t ch, uint32_t cc_val);
+
+/**@brief Function for returning the compare value for a channel.
+ *
+ * @param[in] p_rtc Pointer to the peripheral registers structure.
+ * @param[in] ch Channel.
+ *
+ * @return COMPARE[ch] value.
+ */
+__STATIC_INLINE uint32_t nrf_rtc_cc_get(NRF_RTC_Type * p_rtc, uint32_t ch);
+
+/**@brief Function for enabling interrupts.
+ *
+ * @param[in] p_rtc Pointer to the peripheral registers structure.
+ * @param[in] mask Interrupt mask to be enabled.
+ */
+__STATIC_INLINE void nrf_rtc_int_enable(NRF_RTC_Type * p_rtc, uint32_t mask);
+
+/**@brief Function for disabling interrupts.
+ *
+ * @param[in] p_rtc Pointer to the peripheral registers structure.
+ * @param[in] mask Interrupt mask to be disabled.
+ */
+__STATIC_INLINE void nrf_rtc_int_disable(NRF_RTC_Type * p_rtc, uint32_t mask);
+
+/**@brief Function for checking if interrupts are enabled.
+ *
+ * @param[in] p_rtc Pointer to the peripheral registers structure.
+ * @param[in] mask Mask of interrupt flags to check.
+ *
+ * @return Mask with enabled interrupts.
+ */
+__STATIC_INLINE uint32_t nrf_rtc_int_is_enabled(NRF_RTC_Type * p_rtc, uint32_t mask);
+
+/**@brief Function for returning the status of currently enabled interrupts.
+ *
+ * @param[in] p_rtc Pointer to the peripheral registers structure.
+ *
+ * @return Value in INTEN register.
+ */
+__STATIC_INLINE uint32_t nrf_rtc_int_get(NRF_RTC_Type * p_rtc);
+
+/**@brief Function for checking if an event is pending.
+ *
+ * @param[in] p_rtc Pointer to the peripheral registers structure.
+ * @param[in] event Address of the event.
+ *
+ * @return Mask of pending events.
+ */
+__STATIC_INLINE uint32_t nrf_rtc_event_pending(NRF_RTC_Type * p_rtc, nrf_rtc_event_t event);
+
+/**@brief Function for clearing an event.
+ *
+ * @param[in] p_rtc Pointer to the peripheral registers structure.
+ * @param[in] event Event to clear.
+ */
+__STATIC_INLINE void nrf_rtc_event_clear(NRF_RTC_Type * p_rtc, nrf_rtc_event_t event);
+
+/**@brief Function for returning a counter value.
+ *
+ * @param[in] p_rtc Pointer to the peripheral registers structure.
+ *
+ * @return Counter value.
+ */
+__STATIC_INLINE uint32_t nrf_rtc_counter_get(NRF_RTC_Type * p_rtc);
+
+/**@brief Function for setting a prescaler value.
+ *
+ * @param[in] p_rtc Pointer to the peripheral registers structure.
+ * @param[in] val Value to set the prescaler to.
+ */
+__STATIC_INLINE void nrf_rtc_prescaler_set(NRF_RTC_Type * p_rtc, uint32_t val);
+
+/**@brief Function for returning the address of an event.
+ *
+ * @param[in] p_rtc Pointer to the peripheral registers structure.
+ * @param[in] event Requested event.
+ *
+ * @return Address of the requested event register.
+ */
+__STATIC_INLINE uint32_t nrf_rtc_event_address_get(NRF_RTC_Type * p_rtc, nrf_rtc_event_t event);
+
+/**@brief Function for returning the address of a task.
+ *
+ * @param[in] p_rtc Pointer to the peripheral registers structure.
+ * @param[in] task Requested task.
+ *
+ * @return Address of the requested task register.
+ */
+__STATIC_INLINE uint32_t nrf_rtc_task_address_get(NRF_RTC_Type * p_rtc, nrf_rtc_task_t task);
+
+/**@brief Function for starting a task.
+ *
+ * @param[in] p_rtc Pointer to the peripheral registers structure.
+ * @param[in] task Requested task.
+ */
+__STATIC_INLINE void nrf_rtc_task_trigger(NRF_RTC_Type * p_rtc, nrf_rtc_task_t task);
+
+/**@brief Function for enabling events.
+ *
+ * @param[in] p_rtc Pointer to the peripheral registers structure.
+ * @param[in] mask Mask of event flags to enable.
+ */
+__STATIC_INLINE void nrf_rtc_event_enable(NRF_RTC_Type * p_rtc, uint32_t mask);
+
+/**@brief Function for disabling an event.
+ *
+ * @param[in] p_rtc Pointer to the peripheral registers structure.
+ * @param[in] event Requested event.
+ */
+__STATIC_INLINE void nrf_rtc_event_disable(NRF_RTC_Type * p_rtc, uint32_t event);
+
+/**
+ *@}
+ **/
+
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE void nrf_rtc_cc_set(NRF_RTC_Type * p_rtc, uint32_t ch, uint32_t cc_val)
+{
+ p_rtc->CC[ch] = cc_val;
+}
+
+__STATIC_INLINE uint32_t nrf_rtc_cc_get(NRF_RTC_Type * p_rtc, uint32_t ch)
+{
+ return p_rtc->CC[ch];
+}
+
+__STATIC_INLINE void nrf_rtc_int_enable(NRF_RTC_Type * p_rtc, uint32_t mask)
+{
+ p_rtc->INTENSET = mask;
+}
+
+__STATIC_INLINE void nrf_rtc_int_disable(NRF_RTC_Type * p_rtc, uint32_t mask)
+{
+ p_rtc->INTENCLR = mask;
+}
+
+__STATIC_INLINE uint32_t nrf_rtc_int_is_enabled(NRF_RTC_Type * p_rtc, uint32_t mask)
+{
+ return (p_rtc->INTENSET & mask);
+}
+
+__STATIC_INLINE uint32_t nrf_rtc_int_get(NRF_RTC_Type * p_rtc)
+{
+ return p_rtc->INTENSET;
+}
+
+__STATIC_INLINE uint32_t nrf_rtc_event_pending(NRF_RTC_Type * p_rtc, nrf_rtc_event_t event)
+{
+ return *(volatile uint32_t *)((uint8_t *)p_rtc + (uint32_t)event);
+}
+
+__STATIC_INLINE void nrf_rtc_event_clear(NRF_RTC_Type * p_rtc, nrf_rtc_event_t event)
+{
+ *((volatile uint32_t *)((uint8_t *)p_rtc + (uint32_t)event)) = 0;
+#if __CORTEX_M == 0x04
+ volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_rtc + (uint32_t)event));
+ (void)dummy;
+#endif
+}
+
+__STATIC_INLINE uint32_t nrf_rtc_counter_get(NRF_RTC_Type * p_rtc)
+{
+ return p_rtc->COUNTER;
+}
+
+__STATIC_INLINE void nrf_rtc_prescaler_set(NRF_RTC_Type * p_rtc, uint32_t val)
+{
+ ASSERT(val <= (RTC_PRESCALER_PRESCALER_Msk >> RTC_PRESCALER_PRESCALER_Pos));
+ p_rtc->PRESCALER = val;
+}
+__STATIC_INLINE uint32_t rtc_prescaler_get(NRF_RTC_Type * p_rtc)
+{
+ return p_rtc->PRESCALER;
+}
+
+__STATIC_INLINE uint32_t nrf_rtc_event_address_get(NRF_RTC_Type * p_rtc, nrf_rtc_event_t event)
+{
+ return (uint32_t)p_rtc + event;
+}
+
+__STATIC_INLINE uint32_t nrf_rtc_task_address_get(NRF_RTC_Type * p_rtc, nrf_rtc_task_t task)
+{
+ return (uint32_t)p_rtc + task;
+}
+
+__STATIC_INLINE void nrf_rtc_task_trigger(NRF_RTC_Type * p_rtc, nrf_rtc_task_t task)
+{
+ *(__IO uint32_t *)((uint32_t)p_rtc + task) = 1;
+}
+
+__STATIC_INLINE void nrf_rtc_event_enable(NRF_RTC_Type * p_rtc, uint32_t mask)
+{
+ p_rtc->EVTENSET = mask;
+}
+__STATIC_INLINE void nrf_rtc_event_disable(NRF_RTC_Type * p_rtc, uint32_t mask)
+{
+ p_rtc->EVTENCLR = mask;
+}
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_RTC_H */
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_saadc.c b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_saadc.c
new file mode 100644
index 000000000..c028eaa49
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_saadc.c
@@ -0,0 +1,62 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ * @brief SAADC HAL implementation
+ */
+#include "sdk_config.h"
+#if SAADC_ENABLED
+#include "nrf_saadc.h"
+
+void nrf_saadc_channel_init(uint8_t channel, nrf_saadc_channel_config_t const * const config)
+{
+ NRF_SAADC->CH[channel].CONFIG =
+ ((config->resistor_p << SAADC_CH_CONFIG_RESP_Pos) & SAADC_CH_CONFIG_RESP_Msk)
+ | ((config->resistor_n << SAADC_CH_CONFIG_RESN_Pos) & SAADC_CH_CONFIG_RESN_Msk)
+ | ((config->gain << SAADC_CH_CONFIG_GAIN_Pos) & SAADC_CH_CONFIG_GAIN_Msk)
+ | ((config->reference << SAADC_CH_CONFIG_REFSEL_Pos) & SAADC_CH_CONFIG_REFSEL_Msk)
+ | ((config->acq_time << SAADC_CH_CONFIG_TACQ_Pos) & SAADC_CH_CONFIG_TACQ_Msk)
+ | ((config->mode << SAADC_CH_CONFIG_MODE_Pos) & SAADC_CH_CONFIG_MODE_Msk)
+ | ((config->burst << SAADC_CH_CONFIG_BURST_Pos) & SAADC_CH_CONFIG_BURST_Msk);
+ nrf_saadc_channel_input_set(channel, config->pin_p, config->pin_n);
+ return;
+}
+#endif //SAADC_ENABLED
+
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_saadc.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_saadc.h
new file mode 100644
index 000000000..73eb8128b
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_saadc.h
@@ -0,0 +1,609 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_SAADC_H_
+#define NRF_SAADC_H_
+
+/**
+ * @defgroup nrf_saadc_hal SAADC HAL
+ * @{
+ * @ingroup nrf_saadc
+ *
+ * @brief @tagAPI52 Hardware access layer for accessing the SAADC peripheral.
+ */
+
+#include <stdbool.h>
+#include <stddef.h>
+#include "nrf.h"
+#include "nrf_assert.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NRF_SAADC_CHANNEL_COUNT 8
+
+/**
+ * @brief Resolution of the analog-to-digital converter.
+ */
+typedef enum
+{
+ NRF_SAADC_RESOLUTION_8BIT = SAADC_RESOLUTION_VAL_8bit, ///< 8 bit resolution.
+ NRF_SAADC_RESOLUTION_10BIT = SAADC_RESOLUTION_VAL_10bit, ///< 10 bit resolution.
+ NRF_SAADC_RESOLUTION_12BIT = SAADC_RESOLUTION_VAL_12bit, ///< 12 bit resolution.
+ NRF_SAADC_RESOLUTION_14BIT = SAADC_RESOLUTION_VAL_14bit ///< 14 bit resolution.
+} nrf_saadc_resolution_t;
+
+
+/**
+ * @brief Input selection for the analog-to-digital converter.
+ */
+typedef enum
+{
+ NRF_SAADC_INPUT_DISABLED = SAADC_CH_PSELP_PSELP_NC, ///< Not connected.
+ NRF_SAADC_INPUT_AIN0 = SAADC_CH_PSELP_PSELP_AnalogInput0, ///< Analog input 0 (AIN0).
+ NRF_SAADC_INPUT_AIN1 = SAADC_CH_PSELP_PSELP_AnalogInput1, ///< Analog input 1 (AIN1).
+ NRF_SAADC_INPUT_AIN2 = SAADC_CH_PSELP_PSELP_AnalogInput2, ///< Analog input 2 (AIN2).
+ NRF_SAADC_INPUT_AIN3 = SAADC_CH_PSELP_PSELP_AnalogInput3, ///< Analog input 3 (AIN3).
+ NRF_SAADC_INPUT_AIN4 = SAADC_CH_PSELP_PSELP_AnalogInput4, ///< Analog input 4 (AIN4).
+ NRF_SAADC_INPUT_AIN5 = SAADC_CH_PSELP_PSELP_AnalogInput5, ///< Analog input 5 (AIN5).
+ NRF_SAADC_INPUT_AIN6 = SAADC_CH_PSELP_PSELP_AnalogInput6, ///< Analog input 6 (AIN6).
+ NRF_SAADC_INPUT_AIN7 = SAADC_CH_PSELP_PSELP_AnalogInput7, ///< Analog input 7 (AIN7).
+ NRF_SAADC_INPUT_VDD = SAADC_CH_PSELP_PSELP_VDD ///< VDD as input.
+} nrf_saadc_input_t;
+
+
+/**
+ * @brief Analog-to-digital converter oversampling mode.
+ */
+typedef enum
+{
+ NRF_SAADC_OVERSAMPLE_DISABLED = SAADC_OVERSAMPLE_OVERSAMPLE_Bypass, ///< No oversampling.
+ NRF_SAADC_OVERSAMPLE_2X = SAADC_OVERSAMPLE_OVERSAMPLE_Over2x, ///< Oversample 2x.
+ NRF_SAADC_OVERSAMPLE_4X = SAADC_OVERSAMPLE_OVERSAMPLE_Over4x, ///< Oversample 4x.
+ NRF_SAADC_OVERSAMPLE_8X = SAADC_OVERSAMPLE_OVERSAMPLE_Over8x, ///< Oversample 8x.
+ NRF_SAADC_OVERSAMPLE_16X = SAADC_OVERSAMPLE_OVERSAMPLE_Over16x, ///< Oversample 16x.
+ NRF_SAADC_OVERSAMPLE_32X = SAADC_OVERSAMPLE_OVERSAMPLE_Over32x, ///< Oversample 32x.
+ NRF_SAADC_OVERSAMPLE_64X = SAADC_OVERSAMPLE_OVERSAMPLE_Over64x, ///< Oversample 64x.
+ NRF_SAADC_OVERSAMPLE_128X = SAADC_OVERSAMPLE_OVERSAMPLE_Over128x, ///< Oversample 128x.
+ NRF_SAADC_OVERSAMPLE_256X = SAADC_OVERSAMPLE_OVERSAMPLE_Over256x ///< Oversample 256x.
+} nrf_saadc_oversample_t;
+
+
+/**
+ * @brief Analog-to-digital converter channel resistor control.
+ */
+typedef enum
+{
+ NRF_SAADC_RESISTOR_DISABLED = SAADC_CH_CONFIG_RESP_Bypass, ///< Bypass resistor ladder.
+ NRF_SAADC_RESISTOR_PULLDOWN = SAADC_CH_CONFIG_RESP_Pulldown, ///< Pull-down to GND.
+ NRF_SAADC_RESISTOR_PULLUP = SAADC_CH_CONFIG_RESP_Pullup, ///< Pull-up to VDD.
+ NRF_SAADC_RESISTOR_VDD1_2 = SAADC_CH_CONFIG_RESP_VDD1_2 ///< Set input at VDD/2.
+} nrf_saadc_resistor_t;
+
+
+/**
+ * @brief Gain factor of the analog-to-digital converter input.
+ */
+typedef enum
+{
+ NRF_SAADC_GAIN1_6 = SAADC_CH_CONFIG_GAIN_Gain1_6, ///< Gain factor 1/6.
+ NRF_SAADC_GAIN1_5 = SAADC_CH_CONFIG_GAIN_Gain1_5, ///< Gain factor 1/5.
+ NRF_SAADC_GAIN1_4 = SAADC_CH_CONFIG_GAIN_Gain1_4, ///< Gain factor 1/4.
+ NRF_SAADC_GAIN1_3 = SAADC_CH_CONFIG_GAIN_Gain1_3, ///< Gain factor 1/3.
+ NRF_SAADC_GAIN1_2 = SAADC_CH_CONFIG_GAIN_Gain1_2, ///< Gain factor 1/2.
+ NRF_SAADC_GAIN1 = SAADC_CH_CONFIG_GAIN_Gain1, ///< Gain factor 1.
+ NRF_SAADC_GAIN2 = SAADC_CH_CONFIG_GAIN_Gain2, ///< Gain factor 2.
+ NRF_SAADC_GAIN4 = SAADC_CH_CONFIG_GAIN_Gain4, ///< Gain factor 4.
+} nrf_saadc_gain_t;
+
+
+/**
+ * @brief Reference selection for the analog-to-digital converter.
+ */
+typedef enum
+{
+ NRF_SAADC_REFERENCE_INTERNAL = SAADC_CH_CONFIG_REFSEL_Internal, ///< Internal reference (0.6 V).
+ NRF_SAADC_REFERENCE_VDD4 = SAADC_CH_CONFIG_REFSEL_VDD1_4 ///< VDD/4 as reference.
+} nrf_saadc_reference_t;
+
+
+/**
+ * @brief Analog-to-digital converter acquisition time.
+ */
+typedef enum
+{
+ NRF_SAADC_ACQTIME_3US = SAADC_CH_CONFIG_TACQ_3us, ///< 3 us.
+ NRF_SAADC_ACQTIME_5US = SAADC_CH_CONFIG_TACQ_5us, ///< 5 us.
+ NRF_SAADC_ACQTIME_10US = SAADC_CH_CONFIG_TACQ_10us, ///< 10 us.
+ NRF_SAADC_ACQTIME_15US = SAADC_CH_CONFIG_TACQ_15us, ///< 15 us.
+ NRF_SAADC_ACQTIME_20US = SAADC_CH_CONFIG_TACQ_20us, ///< 20 us.
+ NRF_SAADC_ACQTIME_40US = SAADC_CH_CONFIG_TACQ_40us ///< 40 us.
+} nrf_saadc_acqtime_t;
+
+
+/**
+ * @brief Analog-to-digital converter channel mode.
+ */
+typedef enum
+{
+ NRF_SAADC_MODE_SINGLE_ENDED = SAADC_CH_CONFIG_MODE_SE, ///< Single ended, PSELN will be ignored, negative input to ADC shorted to GND.
+ NRF_SAADC_MODE_DIFFERENTIAL = SAADC_CH_CONFIG_MODE_Diff ///< Differential mode.
+} nrf_saadc_mode_t;
+
+
+/**
+ * @brief Analog-to-digital converter channel burst mode.
+ */
+typedef enum
+{
+ NRF_SAADC_BURST_DISABLED = SAADC_CH_CONFIG_BURST_Disabled, ///< Burst mode is disabled (normal operation).
+ NRF_SAADC_BURST_ENABLED = SAADC_CH_CONFIG_BURST_Enabled ///< Burst mode is enabled. SAADC takes 2^OVERSAMPLE number of samples as fast as it can, and sends the average to Data RAM.
+} nrf_saadc_burst_t;
+
+
+/**
+ * @brief Analog-to-digital converter tasks.
+ */
+typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
+{
+ NRF_SAADC_TASK_START = offsetof(NRF_SAADC_Type, TASKS_START), ///< Start the ADC and prepare the result buffer in RAM.
+ NRF_SAADC_TASK_SAMPLE = offsetof(NRF_SAADC_Type, TASKS_SAMPLE), ///< Take one ADC sample. If scan is enabled, all channels are sampled.
+ NRF_SAADC_TASK_STOP = offsetof(NRF_SAADC_Type, TASKS_STOP), ///< Stop the ADC and terminate any on-going conversion.
+ NRF_SAADC_TASK_CALIBRATEOFFSET = offsetof(NRF_SAADC_Type, TASKS_CALIBRATEOFFSET), ///< Starts offset auto-calibration.
+} nrf_saadc_task_t;
+
+
+/**
+ * @brief Analog-to-digital converter events.
+ */
+typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
+{
+ NRF_SAADC_EVENT_STARTED = offsetof(NRF_SAADC_Type, EVENTS_STARTED), ///< The ADC has started.
+ NRF_SAADC_EVENT_END = offsetof(NRF_SAADC_Type, EVENTS_END), ///< The ADC has filled up the result buffer.
+ NRF_SAADC_EVENT_DONE = offsetof(NRF_SAADC_Type, EVENTS_DONE), ///< A conversion task has been completed.
+ NRF_SAADC_EVENT_RESULTDONE = offsetof(NRF_SAADC_Type, EVENTS_RESULTDONE), ///< A result is ready to get transferred to RAM.
+ NRF_SAADC_EVENT_CALIBRATEDONE = offsetof(NRF_SAADC_Type, EVENTS_CALIBRATEDONE), ///< Calibration is complete.
+ NRF_SAADC_EVENT_STOPPED = offsetof(NRF_SAADC_Type, EVENTS_STOPPED), ///< The ADC has stopped.
+ NRF_SAADC_EVENT_CH0_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[0].LIMITH), ///< Last result is equal or above CH[0].LIMIT.HIGH.
+ NRF_SAADC_EVENT_CH0_LIMITL = offsetof(NRF_SAADC_Type, EVENTS_CH[0].LIMITL), ///< Last result is equal or below CH[0].LIMIT.LOW.
+ NRF_SAADC_EVENT_CH1_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[1].LIMITH), ///< Last result is equal or above CH[1].LIMIT.HIGH.
+ NRF_SAADC_EVENT_CH1_LIMITL = offsetof(NRF_SAADC_Type, EVENTS_CH[1].LIMITL), ///< Last result is equal or below CH[1].LIMIT.LOW.
+ NRF_SAADC_EVENT_CH2_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[2].LIMITH), ///< Last result is equal or above CH[2].LIMIT.HIGH.
+ NRF_SAADC_EVENT_CH2_LIMITL = offsetof(NRF_SAADC_Type, EVENTS_CH[2].LIMITL), ///< Last result is equal or below CH[2].LIMIT.LOW.
+ NRF_SAADC_EVENT_CH3_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[3].LIMITH), ///< Last result is equal or above CH[3].LIMIT.HIGH.
+ NRF_SAADC_EVENT_CH3_LIMITL = offsetof(NRF_SAADC_Type, EVENTS_CH[3].LIMITL), ///< Last result is equal or below CH[3].LIMIT.LOW.
+ NRF_SAADC_EVENT_CH4_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[4].LIMITH), ///< Last result is equal or above CH[4].LIMIT.HIGH.
+ NRF_SAADC_EVENT_CH4_LIMITL = offsetof(NRF_SAADC_Type, EVENTS_CH[4].LIMITL), ///< Last result is equal or below CH[4].LIMIT.LOW.
+ NRF_SAADC_EVENT_CH5_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[5].LIMITH), ///< Last result is equal or above CH[5].LIMIT.HIGH.
+ NRF_SAADC_EVENT_CH5_LIMITL = offsetof(NRF_SAADC_Type, EVENTS_CH[5].LIMITL), ///< Last result is equal or below CH[5].LIMIT.LOW.
+ NRF_SAADC_EVENT_CH6_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[6].LIMITH), ///< Last result is equal or above CH[6].LIMIT.HIGH.
+ NRF_SAADC_EVENT_CH6_LIMITL = offsetof(NRF_SAADC_Type, EVENTS_CH[6].LIMITL), ///< Last result is equal or below CH[6].LIMIT.LOW.
+ NRF_SAADC_EVENT_CH7_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[7].LIMITH), ///< Last result is equal or above CH[7].LIMIT.HIGH.
+ NRF_SAADC_EVENT_CH7_LIMITL = offsetof(NRF_SAADC_Type, EVENTS_CH[7].LIMITL) ///< Last result is equal or below CH[7].LIMIT.LOW.
+} nrf_saadc_event_t;
+
+
+/**
+ * @brief Analog-to-digital converter interrupt masks.
+ */
+typedef enum
+{
+ NRF_SAADC_INT_STARTED = SAADC_INTENSET_STARTED_Msk, ///< Interrupt on EVENTS_STARTED event.
+ NRF_SAADC_INT_END = SAADC_INTENSET_END_Msk, ///< Interrupt on EVENTS_END event.
+ NRF_SAADC_INT_DONE = SAADC_INTENSET_DONE_Msk, ///< Interrupt on EVENTS_DONE event.
+ NRF_SAADC_INT_RESULTDONE = SAADC_INTENSET_RESULTDONE_Msk, ///< Interrupt on EVENTS_RESULTDONE event.
+ NRF_SAADC_INT_CALIBRATEDONE = SAADC_INTENSET_CALIBRATEDONE_Msk, ///< Interrupt on EVENTS_CALIBRATEDONE event.
+ NRF_SAADC_INT_STOPPED = SAADC_INTENSET_STOPPED_Msk, ///< Interrupt on EVENTS_STOPPED event.
+ NRF_SAADC_INT_CH0LIMITH = SAADC_INTENSET_CH0LIMITH_Msk, ///< Interrupt on EVENTS_CH[0].LIMITH event.
+ NRF_SAADC_INT_CH0LIMITL = SAADC_INTENSET_CH0LIMITL_Msk, ///< Interrupt on EVENTS_CH[0].LIMITL event.
+ NRF_SAADC_INT_CH1LIMITH = SAADC_INTENSET_CH1LIMITH_Msk, ///< Interrupt on EVENTS_CH[1].LIMITH event.
+ NRF_SAADC_INT_CH1LIMITL = SAADC_INTENSET_CH1LIMITL_Msk, ///< Interrupt on EVENTS_CH[1].LIMITL event.
+ NRF_SAADC_INT_CH2LIMITH = SAADC_INTENSET_CH2LIMITH_Msk, ///< Interrupt on EVENTS_CH[2].LIMITH event.
+ NRF_SAADC_INT_CH2LIMITL = SAADC_INTENSET_CH2LIMITL_Msk, ///< Interrupt on EVENTS_CH[2].LIMITL event.
+ NRF_SAADC_INT_CH3LIMITH = SAADC_INTENSET_CH3LIMITH_Msk, ///< Interrupt on EVENTS_CH[3].LIMITH event.
+ NRF_SAADC_INT_CH3LIMITL = SAADC_INTENSET_CH3LIMITL_Msk, ///< Interrupt on EVENTS_CH[3].LIMITL event.
+ NRF_SAADC_INT_CH4LIMITH = SAADC_INTENSET_CH4LIMITH_Msk, ///< Interrupt on EVENTS_CH[4].LIMITH event.
+ NRF_SAADC_INT_CH4LIMITL = SAADC_INTENSET_CH4LIMITL_Msk, ///< Interrupt on EVENTS_CH[4].LIMITL event.
+ NRF_SAADC_INT_CH5LIMITH = SAADC_INTENSET_CH5LIMITH_Msk, ///< Interrupt on EVENTS_CH[5].LIMITH event.
+ NRF_SAADC_INT_CH5LIMITL = SAADC_INTENSET_CH5LIMITL_Msk, ///< Interrupt on EVENTS_CH[5].LIMITL event.
+ NRF_SAADC_INT_CH6LIMITH = SAADC_INTENSET_CH6LIMITH_Msk, ///< Interrupt on EVENTS_CH[6].LIMITH event.
+ NRF_SAADC_INT_CH6LIMITL = SAADC_INTENSET_CH6LIMITL_Msk, ///< Interrupt on EVENTS_CH[6].LIMITL event.
+ NRF_SAADC_INT_CH7LIMITH = SAADC_INTENSET_CH7LIMITH_Msk, ///< Interrupt on EVENTS_CH[7].LIMITH event.
+ NRF_SAADC_INT_CH7LIMITL = SAADC_INTENSET_CH7LIMITL_Msk, ///< Interrupt on EVENTS_CH[7].LIMITL event.
+ NRF_SAADC_INT_ALL = 0x7FFFFFFFUL ///< Mask of all interrupts.
+} nrf_saadc_int_mask_t;
+
+
+/**
+ * @brief Analog-to-digital converter value limit type.
+ */
+typedef enum
+{
+ NRF_SAADC_LIMIT_LOW = 0,
+ NRF_SAADC_LIMIT_HIGH = 1
+} nrf_saadc_limit_t;
+
+
+typedef int16_t nrf_saadc_value_t; ///< Type of a single ADC conversion result.
+
+
+/**
+ * @brief Analog-to-digital converter configuration structure.
+ */
+typedef struct
+{
+ nrf_saadc_resolution_t resolution;
+ nrf_saadc_oversample_t oversample;
+ nrf_saadc_value_t * buffer;
+ uint32_t buffer_size;
+} nrf_saadc_config_t;
+
+
+/**
+ * @brief Analog-to-digital converter channel configuration structure.
+ */
+typedef struct
+{
+ nrf_saadc_resistor_t resistor_p;
+ nrf_saadc_resistor_t resistor_n;
+ nrf_saadc_gain_t gain;
+ nrf_saadc_reference_t reference;
+ nrf_saadc_acqtime_t acq_time;
+ nrf_saadc_mode_t mode;
+ nrf_saadc_burst_t burst;
+ nrf_saadc_input_t pin_p;
+ nrf_saadc_input_t pin_n;
+} nrf_saadc_channel_config_t;
+
+
+/**
+ * @brief Function for triggering a specific SAADC task.
+ *
+ * @param[in] saadc_task SAADC task.
+ */
+__STATIC_INLINE void nrf_saadc_task_trigger(nrf_saadc_task_t saadc_task)
+{
+ *((volatile uint32_t *)((uint8_t *)NRF_SAADC + (uint32_t)saadc_task)) = 0x1UL;
+}
+
+
+/**
+ * @brief Function for getting the address of a specific SAADC task register.
+ *
+ * @param[in] saadc_task SAADC task.
+ *
+ * @return Address of the specified SAADC task.
+ */
+__STATIC_INLINE uint32_t nrf_saadc_task_address_get(nrf_saadc_task_t saadc_task)
+{
+ return (uint32_t)((uint8_t *)NRF_SAADC + (uint32_t)saadc_task);
+}
+
+
+/**
+ * @brief Function for getting the state of a specific SAADC event.
+ *
+ * @param[in] saadc_event SAADC event.
+ *
+ * @return State of the specified SAADC event.
+ */
+__STATIC_INLINE bool nrf_saadc_event_check(nrf_saadc_event_t saadc_event)
+{
+ return (bool)*(volatile uint32_t *)((uint8_t *)NRF_SAADC + (uint32_t)saadc_event);
+}
+
+
+/**
+ * @brief Function for clearing the specific SAADC event.
+ *
+ * @param[in] saadc_event SAADC event.
+ */
+__STATIC_INLINE void nrf_saadc_event_clear(nrf_saadc_event_t saadc_event)
+{
+ *((volatile uint32_t *)((uint8_t *)NRF_SAADC + (uint32_t)saadc_event)) = 0x0UL;
+#if __CORTEX_M == 0x04
+ volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_SAADC + (uint32_t)saadc_event));
+ (void)dummy;
+#endif
+}
+
+
+/**
+ * @brief Function for getting the address of a specific SAADC event register.
+ *
+ * @param[in] saadc_event SAADC event.
+ *
+ * @return Address of the specified SAADC event.
+ */
+__STATIC_INLINE uint32_t nrf_saadc_event_address_get(nrf_saadc_event_t saadc_event)
+{
+ return (uint32_t )((uint8_t *)NRF_SAADC + (uint32_t)saadc_event);
+}
+
+
+/**
+ * @brief Function for getting the address of a specific SAADC limit event register.
+ *
+ * @param[in] channel Channel number.
+ * @param[in] limit_type Low limit or high limit.
+ *
+ * @return Address of the specified SAADC limit event.
+ */
+__STATIC_INLINE volatile uint32_t * nrf_saadc_event_limit_address_get(uint8_t channel, nrf_saadc_limit_t limit_type)
+{
+ ASSERT(channel < NRF_SAADC_CHANNEL_COUNT);
+ if (limit_type == NRF_SAADC_LIMIT_HIGH)
+ {
+ return &NRF_SAADC->EVENTS_CH[channel].LIMITH;
+ }
+ else
+ {
+ return &NRF_SAADC->EVENTS_CH[channel].LIMITL;
+ }
+}
+
+
+/**
+ * @brief Function for getting the SAADC channel monitoring limit events.
+ *
+ * @param[in] channel Channel number.
+ * @param[in] limit_type Low limit or high limit.
+ */
+__STATIC_INLINE nrf_saadc_event_t nrf_saadc_event_limit_get(uint8_t channel, nrf_saadc_limit_t limit_type)
+{
+ if (limit_type == NRF_SAADC_LIMIT_HIGH)
+ {
+ return (nrf_saadc_event_t)( (uint32_t) NRF_SAADC_EVENT_CH0_LIMITH +
+ (uint32_t) (NRF_SAADC_EVENT_CH1_LIMITH - NRF_SAADC_EVENT_CH0_LIMITH)
+ * (uint32_t) channel );
+ }
+ else
+ {
+ return (nrf_saadc_event_t)( (uint32_t) NRF_SAADC_EVENT_CH0_LIMITL +
+ (uint32_t) (NRF_SAADC_EVENT_CH1_LIMITL - NRF_SAADC_EVENT_CH0_LIMITL)
+ * (uint32_t) channel );
+ }
+}
+
+
+/**
+ * @brief Function for configuring the input pins for a specific SAADC channel.
+ *
+ * @param[in] channel Channel number.
+ * @param[in] pselp Positive input.
+ * @param[in] pseln Negative input. Set to NRF_SAADC_INPUT_DISABLED in single ended mode.
+ */
+__STATIC_INLINE void nrf_saadc_channel_input_set(uint8_t channel,
+ nrf_saadc_input_t pselp,
+ nrf_saadc_input_t pseln)
+{
+ NRF_SAADC->CH[channel].PSELN = pseln;
+ NRF_SAADC->CH[channel].PSELP = pselp;
+}
+
+
+/**
+ * @brief Function for setting the SAADC channel monitoring limits.
+ *
+ * @param[in] channel Channel number.
+ * @param[in] low Low limit.
+ * @param[in] high High limit.
+ */
+__STATIC_INLINE void nrf_saadc_channel_limits_set(uint8_t channel, int16_t low, int16_t high)
+{
+ NRF_SAADC->CH[channel].LIMIT = (
+ (((uint32_t) low << SAADC_CH_LIMIT_LOW_Pos) & SAADC_CH_LIMIT_LOW_Msk)
+ | (((uint32_t) high << SAADC_CH_LIMIT_HIGH_Pos) & SAADC_CH_LIMIT_HIGH_Msk));
+}
+
+
+/**
+ * @brief Function for enabling specified SAADC interrupts.
+ *
+ * @param[in] saadc_int_mask Interrupt(s) to enable.
+ */
+__STATIC_INLINE void nrf_saadc_int_enable(uint32_t saadc_int_mask)
+{
+ NRF_SAADC->INTENSET = saadc_int_mask;
+}
+
+
+/**
+ * @brief Function for retrieving the state of specified SAADC interrupts.
+ *
+ * @param[in] saadc_int_mask Interrupt(s) to check.
+ *
+ * @retval true If all specified interrupts are enabled.
+ * @retval false If at least one of the given interrupts is not enabled.
+ */
+__STATIC_INLINE bool nrf_saadc_int_enable_check(uint32_t saadc_int_mask)
+{
+ return (bool)(NRF_SAADC->INTENSET & saadc_int_mask);
+}
+
+
+/**
+ * @brief Function for disabling specified interrupts.
+ *
+ * @param saadc_int_mask Interrupt(s) to disable.
+ */
+__STATIC_INLINE void nrf_saadc_int_disable(uint32_t saadc_int_mask)
+{
+ NRF_SAADC->INTENCLR = saadc_int_mask;
+}
+
+
+/**
+ * @brief Function for generating masks for SAADC channel limit interrupts.
+ *
+ * @param[in] channel SAADC channel number.
+ * @param[in] limit_type Limit type.
+ *
+ * @returns Interrupt mask.
+ */
+__STATIC_INLINE uint32_t nrf_saadc_limit_int_get(uint8_t channel, nrf_saadc_limit_t limit_type)
+{
+ ASSERT(channel < NRF_SAADC_CHANNEL_COUNT);
+ uint32_t mask = (limit_type == NRF_SAADC_LIMIT_LOW) ? NRF_SAADC_INT_CH0LIMITL : NRF_SAADC_INT_CH0LIMITH;
+ return mask << (channel * 2);
+}
+
+
+/**
+ * @brief Function for checking whether the SAADC is busy.
+ *
+ * This function checks whether the analog-to-digital converter is busy with a conversion.
+ *
+ * @retval true If the SAADC is busy.
+ * @retval false If the SAADC is not busy.
+ */
+__STATIC_INLINE bool nrf_saadc_busy_check(void)
+{
+ //return ((NRF_SAADC->STATUS & SAADC_STATUS_STATUS_Msk) == SAADC_STATUS_STATUS_Msk);
+ //simplified for performance
+ return NRF_SAADC->STATUS;
+}
+
+
+/**
+ * @brief Function for enabling the SAADC.
+ *
+ * The analog-to-digital converter must be enabled before use.
+ */
+__STATIC_INLINE void nrf_saadc_enable(void)
+{
+ NRF_SAADC->ENABLE = (SAADC_ENABLE_ENABLE_Enabled << SAADC_ENABLE_ENABLE_Pos);
+}
+
+
+/**
+ * @brief Function for disabling the SAADC.
+ */
+__STATIC_INLINE void nrf_saadc_disable(void)
+{
+ NRF_SAADC->ENABLE = (SAADC_ENABLE_ENABLE_Disabled << SAADC_ENABLE_ENABLE_Pos);
+}
+
+
+/**
+ * @brief Function for checking if the SAADC is enabled.
+ *
+ * @retval true If the SAADC is enabled.
+ * @retval false If the SAADC is not enabled.
+ */
+__STATIC_INLINE bool nrf_saadc_enable_check(void)
+{
+ //simplified for performance
+ return NRF_SAADC->ENABLE;
+}
+
+
+/**
+ * @brief Function for initializing the SAADC result buffer.
+ *
+ * @param[in] buffer Pointer to the result buffer.
+ * @param[in] num Size of buffer in words.
+ */
+__STATIC_INLINE void nrf_saadc_buffer_init(nrf_saadc_value_t * buffer, uint32_t num)
+{
+ NRF_SAADC->RESULT.PTR = (uint32_t)buffer;
+ NRF_SAADC->RESULT.MAXCNT = num;
+}
+
+/**
+ * @brief Function for getting the number of buffer words transferred since last START operation.
+ *
+ * @returns Number of words transferred.
+ */
+__STATIC_INLINE uint16_t nrf_saadc_amount_get(void)
+{
+ return NRF_SAADC->RESULT.AMOUNT;
+}
+
+
+/**
+ * @brief Function for setting the SAADC sample resolution.
+ *
+ * @param[in] resolution Bit resolution.
+ */
+__STATIC_INLINE void nrf_saadc_resolution_set(nrf_saadc_resolution_t resolution)
+{
+ NRF_SAADC->RESOLUTION = resolution;
+}
+
+
+/**
+ * @brief Function for configuring the oversampling feature.
+ *
+ * @param[in] oversample Oversampling mode.
+ */
+__STATIC_INLINE void nrf_saadc_oversample_set(nrf_saadc_oversample_t oversample)
+{
+ NRF_SAADC->OVERSAMPLE = oversample;
+}
+
+/**
+ * @brief Function for getting the oversampling feature configuration.
+ *
+ * @return Oversampling configuration.
+ */
+__STATIC_INLINE nrf_saadc_oversample_t nrf_saadc_oversample_get(void)
+{
+ return (nrf_saadc_oversample_t)NRF_SAADC->OVERSAMPLE;
+}
+
+/**
+ * @brief Function for initializing the SAADC channel.
+ *
+ * @param[in] channel Channel number.
+ * @param[in] config Pointer to the channel configuration structure.
+ */
+void nrf_saadc_channel_init(uint8_t channel, nrf_saadc_channel_config_t const * const config);
+
+/**
+ *@}
+ **/
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_SAADC_H_ */
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_spi.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_spi.h
new file mode 100644
index 000000000..3f7215e73
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_spi.h
@@ -0,0 +1,375 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_spi_hal SPI HAL
+ * @{
+ * @ingroup nrf_spi
+ *
+ * @brief Hardware access layer for accessing the SPI peripheral.
+ */
+
+#ifndef NRF_SPI_H__
+#define NRF_SPI_H__
+
+#include <stddef.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "nrf.h"
+#include "nrf_peripherals.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief This value can be used as a parameter for the @ref nrf_spi_pins_set
+ * function to specify that a given SPI signal (SCK, MOSI, or MISO)
+ * shall not be connected to a physical pin.
+ */
+#define NRF_SPI_PIN_NOT_CONNECTED 0xFFFFFFFF
+
+
+/**
+ * @brief SPI events.
+ */
+typedef enum
+{
+ /*lint -save -e30*/
+ NRF_SPI_EVENT_READY = offsetof(NRF_SPI_Type, EVENTS_READY) ///< TXD byte sent and RXD byte received.
+ /*lint -restore*/
+} nrf_spi_event_t;
+
+/**
+ * @brief SPI interrupts.
+ */
+typedef enum
+{
+ NRF_SPI_INT_READY_MASK = SPI_INTENSET_READY_Msk ///< Interrupt on READY event.
+} nrf_spi_int_mask_t;
+
+/**
+ * @brief SPI data rates.
+ */
+typedef enum
+{
+ NRF_SPI_FREQ_125K = SPI_FREQUENCY_FREQUENCY_K125, ///< 125 kbps.
+ NRF_SPI_FREQ_250K = SPI_FREQUENCY_FREQUENCY_K250, ///< 250 kbps.
+ NRF_SPI_FREQ_500K = SPI_FREQUENCY_FREQUENCY_K500, ///< 500 kbps.
+ NRF_SPI_FREQ_1M = SPI_FREQUENCY_FREQUENCY_M1, ///< 1 Mbps.
+ NRF_SPI_FREQ_2M = SPI_FREQUENCY_FREQUENCY_M2, ///< 2 Mbps.
+ NRF_SPI_FREQ_4M = SPI_FREQUENCY_FREQUENCY_M4, ///< 4 Mbps.
+ // [conversion to 'int' needed to prevent compilers from complaining
+ // that the provided value (0x80000000UL) is out of range of "int"]
+ NRF_SPI_FREQ_8M = (int)SPI_FREQUENCY_FREQUENCY_M8 ///< 8 Mbps.
+} nrf_spi_frequency_t;
+
+/**
+ * @brief SPI modes.
+ */
+typedef enum
+{
+ NRF_SPI_MODE_0, ///< SCK active high, sample on leading edge of clock.
+ NRF_SPI_MODE_1, ///< SCK active high, sample on trailing edge of clock.
+ NRF_SPI_MODE_2, ///< SCK active low, sample on leading edge of clock.
+ NRF_SPI_MODE_3 ///< SCK active low, sample on trailing edge of clock.
+} nrf_spi_mode_t;
+
+/**
+ * @brief SPI bit orders.
+ */
+typedef enum
+{
+ NRF_SPI_BIT_ORDER_MSB_FIRST = SPI_CONFIG_ORDER_MsbFirst, ///< Most significant bit shifted out first.
+ NRF_SPI_BIT_ORDER_LSB_FIRST = SPI_CONFIG_ORDER_LsbFirst ///< Least significant bit shifted out first.
+} nrf_spi_bit_order_t;
+
+
+/**
+ * @brief Function for clearing a specific SPI event.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] spi_event Event to clear.
+ */
+__STATIC_INLINE void nrf_spi_event_clear(NRF_SPI_Type * p_reg,
+ nrf_spi_event_t spi_event);
+
+/**
+ * @brief Function for checking the state of a specific SPI event.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] spi_event Event to check.
+ *
+ * @retval true If the event is set.
+ * @retval false If the event is not set.
+ */
+__STATIC_INLINE bool nrf_spi_event_check(NRF_SPI_Type * p_reg,
+ nrf_spi_event_t spi_event);
+
+/**
+ * @brief Function for getting the address of a specific SPI event register.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] spi_event Requested event.
+ *
+ * @return Address of the specified event register.
+ */
+__STATIC_INLINE uint32_t * nrf_spi_event_address_get(NRF_SPI_Type * p_reg,
+ nrf_spi_event_t spi_event);
+
+/**
+ * @brief Function for enabling specified interrupts.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] spi_int_mask Interrupts to enable.
+ */
+__STATIC_INLINE void nrf_spi_int_enable(NRF_SPI_Type * p_reg,
+ uint32_t spi_int_mask);
+
+/**
+ * @brief Function for disabling specified interrupts.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] spi_int_mask Interrupts to disable.
+ */
+__STATIC_INLINE void nrf_spi_int_disable(NRF_SPI_Type * p_reg,
+ uint32_t spi_int_mask);
+
+/**
+ * @brief Function for retrieving the state of a given interrupt.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] spi_int Interrupt to check.
+ *
+ * @retval true If the interrupt is enabled.
+ * @retval false If the interrupt is not enabled.
+ */
+__STATIC_INLINE bool nrf_spi_int_enable_check(NRF_SPI_Type * p_reg,
+ nrf_spi_int_mask_t spi_int);
+
+/**
+ * @brief Function for enabling the SPI peripheral.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE void nrf_spi_enable(NRF_SPI_Type * p_reg);
+
+/**
+ * @brief Function for disabling the SPI peripheral.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE void nrf_spi_disable(NRF_SPI_Type * p_reg);
+
+/**
+ * @brief Function for configuring SPI pins.
+ *
+ * If a given signal is not needed, pass the @ref NRF_SPI_PIN_NOT_CONNECTED
+ * value instead of its pin number.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] sck_pin SCK pin number.
+ * @param[in] mosi_pin MOSI pin number.
+ * @param[in] miso_pin MISO pin number.
+ */
+__STATIC_INLINE void nrf_spi_pins_set(NRF_SPI_Type * p_reg,
+ uint32_t sck_pin,
+ uint32_t mosi_pin,
+ uint32_t miso_pin);
+
+/**
+ * @brief Function for writing data to the SPI transmitter register.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] data TX data to send.
+ */
+__STATIC_INLINE void nrf_spi_txd_set(NRF_SPI_Type * p_reg, uint8_t data);
+
+/**
+ * @brief Function for reading data from the SPI receiver register.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ *
+ * @return RX data received.
+ */
+__STATIC_INLINE uint8_t nrf_spi_rxd_get(NRF_SPI_Type * p_reg);
+
+/**
+ * @brief Function for setting the SPI master data rate.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] frequency SPI frequency.
+ */
+__STATIC_INLINE void nrf_spi_frequency_set(NRF_SPI_Type * p_reg,
+ nrf_spi_frequency_t frequency);
+
+/**
+ * @brief Function for setting the SPI configuration.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] spi_mode SPI mode.
+ * @param[in] spi_bit_order SPI bit order.
+ */
+__STATIC_INLINE void nrf_spi_configure(NRF_SPI_Type * p_reg,
+ nrf_spi_mode_t spi_mode,
+ nrf_spi_bit_order_t spi_bit_order);
+
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE void nrf_spi_event_clear(NRF_SPI_Type * p_reg,
+ nrf_spi_event_t spi_event)
+{
+ *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spi_event)) = 0x0UL;
+#if __CORTEX_M == 0x04
+ volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spi_event));
+ (void)dummy;
+#endif
+}
+
+__STATIC_INLINE bool nrf_spi_event_check(NRF_SPI_Type * p_reg,
+ nrf_spi_event_t spi_event)
+{
+ return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spi_event);
+}
+
+__STATIC_INLINE uint32_t * nrf_spi_event_address_get(NRF_SPI_Type * p_reg,
+ nrf_spi_event_t spi_event)
+{
+ return (uint32_t *)((uint8_t *)p_reg + (uint32_t)spi_event);
+}
+
+__STATIC_INLINE void nrf_spi_int_enable(NRF_SPI_Type * p_reg,
+ uint32_t spi_int_mask)
+{
+ p_reg->INTENSET = spi_int_mask;
+}
+
+__STATIC_INLINE void nrf_spi_int_disable(NRF_SPI_Type * p_reg,
+ uint32_t spi_int_mask)
+{
+ p_reg->INTENCLR = spi_int_mask;
+}
+
+__STATIC_INLINE bool nrf_spi_int_enable_check(NRF_SPI_Type * p_reg,
+ nrf_spi_int_mask_t spi_int)
+{
+ return (bool)(p_reg->INTENSET & spi_int);
+}
+
+__STATIC_INLINE void nrf_spi_enable(NRF_SPI_Type * p_reg)
+{
+ p_reg->ENABLE = (SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos);
+}
+
+__STATIC_INLINE void nrf_spi_disable(NRF_SPI_Type * p_reg)
+{
+ p_reg->ENABLE = (SPI_ENABLE_ENABLE_Disabled << SPI_ENABLE_ENABLE_Pos);
+}
+
+__STATIC_INLINE void nrf_spi_pins_set(NRF_SPI_Type * p_reg,
+ uint32_t sck_pin,
+ uint32_t mosi_pin,
+ uint32_t miso_pin)
+{
+ p_reg->PSELSCK = sck_pin;
+ p_reg->PSELMOSI = mosi_pin;
+ p_reg->PSELMISO = miso_pin;
+}
+
+__STATIC_INLINE void nrf_spi_txd_set(NRF_SPI_Type * p_reg, uint8_t data)
+{
+ p_reg->TXD = data;
+}
+
+__STATIC_INLINE uint8_t nrf_spi_rxd_get(NRF_SPI_Type * p_reg)
+{
+ return p_reg->RXD;
+}
+
+__STATIC_INLINE void nrf_spi_frequency_set(NRF_SPI_Type * p_reg,
+ nrf_spi_frequency_t frequency)
+{
+ p_reg->FREQUENCY = frequency;
+}
+
+__STATIC_INLINE void nrf_spi_configure(NRF_SPI_Type * p_reg,
+ nrf_spi_mode_t spi_mode,
+ nrf_spi_bit_order_t spi_bit_order)
+{
+ uint32_t config = (spi_bit_order == NRF_SPI_BIT_ORDER_MSB_FIRST ?
+ SPI_CONFIG_ORDER_MsbFirst : SPI_CONFIG_ORDER_LsbFirst);
+ switch (spi_mode)
+ {
+ default:
+ case NRF_SPI_MODE_0:
+ config |= (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos) |
+ (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos);
+ break;
+
+ case NRF_SPI_MODE_1:
+ config |= (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos) |
+ (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos);
+ break;
+
+ case NRF_SPI_MODE_2:
+ config |= (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos) |
+ (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos);
+ break;
+
+ case NRF_SPI_MODE_3:
+ config |= (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos) |
+ (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos);
+ break;
+ }
+ p_reg->CONFIG = config;
+}
+
+#endif // SUPPRESS_INLINE_IMPLEMENTATION
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_SPI_H__
+
+/** @} */
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_spim.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_spim.h
new file mode 100644
index 000000000..d20eaa44a
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_spim.h
@@ -0,0 +1,571 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_spim_hal SPIM HAL
+ * @{
+ * @ingroup nrf_spi
+ *
+ * @brief Hardware access layer for accessing the SPIM peripheral.
+ */
+
+#ifndef NRF_SPIM_H__
+#define NRF_SPIM_H__
+
+#include <stddef.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "nrf.h"
+#include "nrf_peripherals.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief This value can be used as a parameter for the @ref nrf_spim_pins_set
+ * function to specify that a given SPI signal (SCK, MOSI, or MISO)
+ * shall not be connected to a physical pin.
+ */
+#define NRF_SPIM_PIN_NOT_CONNECTED 0xFFFFFFFF
+
+
+/**
+ * @brief SPIM tasks.
+ */
+typedef enum
+{
+ /*lint -save -e30*/
+ NRF_SPIM_TASK_START = offsetof(NRF_SPIM_Type, TASKS_START), ///< Start SPI transaction.
+ NRF_SPIM_TASK_STOP = offsetof(NRF_SPIM_Type, TASKS_STOP), ///< Stop SPI transaction.
+ NRF_SPIM_TASK_SUSPEND = offsetof(NRF_SPIM_Type, TASKS_SUSPEND), ///< Suspend SPI transaction.
+ NRF_SPIM_TASK_RESUME = offsetof(NRF_SPIM_Type, TASKS_RESUME) ///< Resume SPI transaction.
+ /*lint -restore*/
+} nrf_spim_task_t;
+
+/**
+ * @brief SPIM events.
+ */
+typedef enum
+{
+ /*lint -save -e30*/
+ NRF_SPIM_EVENT_STOPPED = offsetof(NRF_SPIM_Type, EVENTS_STOPPED), ///< SPI transaction has stopped.
+ NRF_SPIM_EVENT_ENDRX = offsetof(NRF_SPIM_Type, EVENTS_ENDRX), ///< End of RXD buffer reached.
+ NRF_SPIM_EVENT_END = offsetof(NRF_SPIM_Type, EVENTS_END), ///< End of RXD buffer and TXD buffer reached.
+ NRF_SPIM_EVENT_ENDTX = offsetof(NRF_SPIM_Type, EVENTS_ENDTX), ///< End of TXD buffer reached.
+ NRF_SPIM_EVENT_STARTED = offsetof(NRF_SPIM_Type, EVENTS_STARTED) ///< Transaction started.
+ /*lint -restore*/
+} nrf_spim_event_t;
+
+/**
+ * @brief SPIM shortcuts.
+ */
+typedef enum
+{
+ NRF_SPIM_SHORT_END_START_MASK = SPIM_SHORTS_END_START_Msk ///< Shortcut between END event and START task.
+} nrf_spim_short_mask_t;
+
+/**
+ * @brief SPIM interrupts.
+ */
+typedef enum
+{
+ NRF_SPIM_INT_STOPPED_MASK = SPIM_INTENSET_STOPPED_Msk, ///< Interrupt on STOPPED event.
+ NRF_SPIM_INT_ENDRX_MASK = SPIM_INTENSET_ENDRX_Msk, ///< Interrupt on ENDRX event.
+ NRF_SPIM_INT_END_MASK = SPIM_INTENSET_END_Msk, ///< Interrupt on END event.
+ NRF_SPIM_INT_ENDTX_MASK = SPIM_INTENSET_ENDTX_Msk, ///< Interrupt on ENDTX event.
+ NRF_SPIM_INT_STARTED_MASK = SPIM_INTENSET_STARTED_Msk ///< Interrupt on STARTED event.
+} nrf_spim_int_mask_t;
+
+/**
+ * @brief SPI master data rates.
+ */
+typedef enum
+{
+ NRF_SPIM_FREQ_125K = SPIM_FREQUENCY_FREQUENCY_K125, ///< 125 kbps.
+ NRF_SPIM_FREQ_250K = SPIM_FREQUENCY_FREQUENCY_K250, ///< 250 kbps.
+ NRF_SPIM_FREQ_500K = SPIM_FREQUENCY_FREQUENCY_K500, ///< 500 kbps.
+ NRF_SPIM_FREQ_1M = SPIM_FREQUENCY_FREQUENCY_M1, ///< 1 Mbps.
+ NRF_SPIM_FREQ_2M = SPIM_FREQUENCY_FREQUENCY_M2, ///< 2 Mbps.
+ NRF_SPIM_FREQ_4M = SPIM_FREQUENCY_FREQUENCY_M4, ///< 4 Mbps.
+ // [conversion to 'int' needed to prevent compilers from complaining
+ // that the provided value (0x80000000UL) is out of range of "int"]
+ NRF_SPIM_FREQ_8M = (int)SPIM_FREQUENCY_FREQUENCY_M8,///< 8 Mbps.
+#ifndef SPI_PRESENT
+ NRF_SPI_FREQ_125K = NRF_SPIM_FREQ_125K,
+ NRF_SPI_FREQ_250K = NRF_SPIM_FREQ_250K,
+ NRF_SPI_FREQ_500K = NRF_SPIM_FREQ_500K,
+ NRF_SPI_FREQ_1M = NRF_SPIM_FREQ_1M,
+ NRF_SPI_FREQ_2M = NRF_SPIM_FREQ_2M,
+ NRF_SPI_FREQ_4M = NRF_SPIM_FREQ_4M,
+ NRF_SPI_FREQ_8M = NRF_SPIM_FREQ_8M,
+#endif
+} nrf_spim_frequency_t;
+
+/**
+ * @brief SPI modes.
+ */
+typedef enum
+{
+ NRF_SPIM_MODE_0, ///< SCK active high, sample on leading edge of clock.
+ NRF_SPIM_MODE_1, ///< SCK active high, sample on trailing edge of clock.
+ NRF_SPIM_MODE_2, ///< SCK active low, sample on leading edge of clock.
+ NRF_SPIM_MODE_3, ///< SCK active low, sample on trailing edge of clock.
+#ifndef SPI_PRESENT
+ NRF_SPI_MODE_0 = NRF_SPIM_MODE_0,
+ NRF_SPI_MODE_1 = NRF_SPIM_MODE_1,
+ NRF_SPI_MODE_2 = NRF_SPIM_MODE_2,
+ NRF_SPI_MODE_3 = NRF_SPIM_MODE_3,
+#endif
+} nrf_spim_mode_t;
+
+/**
+ * @brief SPI bit orders.
+ */
+typedef enum
+{
+ NRF_SPIM_BIT_ORDER_MSB_FIRST = SPIM_CONFIG_ORDER_MsbFirst, ///< Most significant bit shifted out first.
+ NRF_SPIM_BIT_ORDER_LSB_FIRST = SPIM_CONFIG_ORDER_LsbFirst, ///< Least significant bit shifted out first.
+#ifndef SPI_PRESENT
+ NRF_SPI_BIT_ORDER_MSB_FIRST = NRF_SPIM_BIT_ORDER_MSB_FIRST,
+ NRF_SPI_BIT_ORDER_LSB_FIRST = NRF_SPIM_BIT_ORDER_LSB_FIRST,
+#endif
+} nrf_spim_bit_order_t;
+
+
+/**
+ * @brief Function for activating a specific SPIM task.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] spim_task Task to activate.
+ */
+__STATIC_INLINE void nrf_spim_task_trigger(NRF_SPIM_Type * p_reg,
+ nrf_spim_task_t spim_task);
+
+/**
+ * @brief Function for getting the address of a specific SPIM task register.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] spim_task Requested task.
+ *
+ * @return Address of the specified task register.
+ */
+__STATIC_INLINE uint32_t nrf_spim_task_address_get(NRF_SPIM_Type * p_reg,
+ nrf_spim_task_t spim_task);
+
+/**
+ * @brief Function for clearing a specific SPIM event.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] spim_event Event to clear.
+ */
+__STATIC_INLINE void nrf_spim_event_clear(NRF_SPIM_Type * p_reg,
+ nrf_spim_event_t spim_event);
+
+/**
+ * @brief Function for checking the state of a specific SPIM event.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] spim_event Event to check.
+ *
+ * @retval true If the event is set.
+ * @retval false If the event is not set.
+ */
+__STATIC_INLINE bool nrf_spim_event_check(NRF_SPIM_Type * p_reg,
+ nrf_spim_event_t spim_event);
+
+/**
+ * @brief Function for getting the address of a specific SPIM event register.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] spim_event Requested event.
+ *
+ * @return Address of the specified event register.
+ */
+__STATIC_INLINE uint32_t nrf_spim_event_address_get(NRF_SPIM_Type * p_reg,
+ nrf_spim_event_t spim_event);
+/**
+ * @brief Function for enabling specified shortcuts.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] spim_shorts_mask Shortcuts to enable.
+ */
+__STATIC_INLINE void nrf_spim_shorts_enable(NRF_SPIM_Type * p_reg,
+ uint32_t spim_shorts_mask);
+
+/**
+ * @brief Function for disabling specified shortcuts.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] spim_shorts_mask Shortcuts to disable.
+ */
+__STATIC_INLINE void nrf_spim_shorts_disable(NRF_SPIM_Type * p_reg,
+ uint32_t spim_shorts_mask);
+
+/**
+ * @brief Function for getting shorts setting.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE uint32_t nrf_spim_shorts_get(NRF_SPIM_Type * p_reg);
+
+/**
+ * @brief Function for enabling specified interrupts.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] spim_int_mask Interrupts to enable.
+ */
+__STATIC_INLINE void nrf_spim_int_enable(NRF_SPIM_Type * p_reg,
+ uint32_t spim_int_mask);
+
+/**
+ * @brief Function for disabling specified interrupts.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] spim_int_mask Interrupts to disable.
+ */
+__STATIC_INLINE void nrf_spim_int_disable(NRF_SPIM_Type * p_reg,
+ uint32_t spim_int_mask);
+
+/**
+ * @brief Function for retrieving the state of a given interrupt.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] spim_int Interrupt to check.
+ *
+ * @retval true If the interrupt is enabled.
+ * @retval false If the interrupt is not enabled.
+ */
+__STATIC_INLINE bool nrf_spim_int_enable_check(NRF_SPIM_Type * p_reg,
+ nrf_spim_int_mask_t spim_int);
+
+/**
+ * @brief Function for enabling the SPIM peripheral.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE void nrf_spim_enable(NRF_SPIM_Type * p_reg);
+
+/**
+ * @brief Function for disabling the SPIM peripheral.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE void nrf_spim_disable(NRF_SPIM_Type * p_reg);
+
+/**
+ * @brief Function for configuring SPIM pins.
+ *
+ * If a given signal is not needed, pass the @ref NRF_SPIM_PIN_NOT_CONNECTED
+ * value instead of its pin number.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] sck_pin SCK pin number.
+ * @param[in] mosi_pin MOSI pin number.
+ * @param[in] miso_pin MISO pin number.
+ */
+__STATIC_INLINE void nrf_spim_pins_set(NRF_SPIM_Type * p_reg,
+ uint32_t sck_pin,
+ uint32_t mosi_pin,
+ uint32_t miso_pin);
+
+/**
+ * @brief Function for setting the SPI master data rate.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] frequency SPI frequency.
+ */
+__STATIC_INLINE void nrf_spim_frequency_set(NRF_SPIM_Type * p_reg,
+ nrf_spim_frequency_t frequency);
+
+/**
+ * @brief Function for setting the transmit buffer.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] p_buffer Pointer to the buffer with data to send.
+ * @param[in] length Maximum number of data bytes to transmit.
+ */
+__STATIC_INLINE void nrf_spim_tx_buffer_set(NRF_SPIM_Type * p_reg,
+ uint8_t const * p_buffer,
+ uint8_t length);
+
+/**
+ * @brief Function for setting the receive buffer.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] p_buffer Pointer to the buffer for received data.
+ * @param[in] length Maximum number of data bytes to receive.
+ */
+__STATIC_INLINE void nrf_spim_rx_buffer_set(NRF_SPIM_Type * p_reg,
+ uint8_t * p_buffer,
+ uint8_t length);
+
+/**
+ * @brief Function for setting the SPI configuration.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] spi_mode SPI mode.
+ * @param[in] spi_bit_order SPI bit order.
+ */
+__STATIC_INLINE void nrf_spim_configure(NRF_SPIM_Type * p_reg,
+ nrf_spim_mode_t spi_mode,
+ nrf_spim_bit_order_t spi_bit_order);
+
+/**
+ * @brief Function for setting the over-read character.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] orc Over-read character that is clocked out in case of
+ * an over-read of the TXD buffer.
+ */
+__STATIC_INLINE void nrf_spim_orc_set(NRF_SPIM_Type * p_reg,
+ uint8_t orc);
+
+/**
+ * @brief Function for enabling the TX list feature.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE void nrf_spim_tx_list_enable(NRF_SPIM_Type * p_reg);
+
+/**
+ * @brief Function for disabling the TX list feature.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE void nrf_spim_tx_list_disable(NRF_SPIM_Type * p_reg);
+
+/**
+ * @brief Function for enabling the RX list feature.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE void nrf_spim_rx_list_enable(NRF_SPIM_Type * p_reg);
+
+/**
+ * @brief Function for disabling the RX list feature.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE void nrf_spim_rx_list_disable(NRF_SPIM_Type * p_reg);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE void nrf_spim_task_trigger(NRF_SPIM_Type * p_reg,
+ nrf_spim_task_t spim_task)
+{
+ *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spim_task)) = 0x1UL;
+}
+
+__STATIC_INLINE uint32_t nrf_spim_task_address_get(NRF_SPIM_Type * p_reg,
+ nrf_spim_task_t spim_task)
+{
+ return (uint32_t)((uint8_t *)p_reg + (uint32_t)spim_task);
+}
+
+__STATIC_INLINE void nrf_spim_event_clear(NRF_SPIM_Type * p_reg,
+ nrf_spim_event_t spim_event)
+{
+ *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spim_event)) = 0x0UL;
+#if __CORTEX_M == 0x04
+ volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spim_event));
+ (void)dummy;
+#endif
+}
+
+__STATIC_INLINE bool nrf_spim_event_check(NRF_SPIM_Type * p_reg,
+ nrf_spim_event_t spim_event)
+{
+ return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spim_event);
+}
+
+__STATIC_INLINE uint32_t nrf_spim_event_address_get(NRF_SPIM_Type * p_reg,
+ nrf_spim_event_t spim_event)
+{
+ return (uint32_t)((uint8_t *)p_reg + (uint32_t)spim_event);
+}
+
+__STATIC_INLINE void nrf_spim_shorts_enable(NRF_SPIM_Type * p_reg,
+ uint32_t spim_shorts_mask)
+{
+ p_reg->SHORTS |= spim_shorts_mask;
+}
+
+__STATIC_INLINE void nrf_spim_shorts_disable(NRF_SPIM_Type * p_reg,
+ uint32_t spim_shorts_mask)
+{
+ p_reg->SHORTS &= ~(spim_shorts_mask);
+}
+
+__STATIC_INLINE uint32_t nrf_spim_shorts_get(NRF_SPIM_Type * p_reg)
+{
+ return p_reg->SHORTS;
+}
+
+__STATIC_INLINE void nrf_spim_int_enable(NRF_SPIM_Type * p_reg,
+ uint32_t spim_int_mask)
+{
+ p_reg->INTENSET = spim_int_mask;
+}
+
+__STATIC_INLINE void nrf_spim_int_disable(NRF_SPIM_Type * p_reg,
+ uint32_t spim_int_mask)
+{
+ p_reg->INTENCLR = spim_int_mask;
+}
+
+__STATIC_INLINE bool nrf_spim_int_enable_check(NRF_SPIM_Type * p_reg,
+ nrf_spim_int_mask_t spim_int)
+{
+ return (bool)(p_reg->INTENSET & spim_int);
+}
+
+__STATIC_INLINE void nrf_spim_enable(NRF_SPIM_Type * p_reg)
+{
+ p_reg->ENABLE = (SPIM_ENABLE_ENABLE_Enabled << SPIM_ENABLE_ENABLE_Pos);
+}
+
+__STATIC_INLINE void nrf_spim_disable(NRF_SPIM_Type * p_reg)
+{
+ p_reg->ENABLE = (SPIM_ENABLE_ENABLE_Disabled << SPIM_ENABLE_ENABLE_Pos);
+}
+
+__STATIC_INLINE void nrf_spim_pins_set(NRF_SPIM_Type * p_reg,
+ uint32_t sck_pin,
+ uint32_t mosi_pin,
+ uint32_t miso_pin)
+{
+ p_reg->PSEL.SCK = sck_pin;
+ p_reg->PSEL.MOSI = mosi_pin;
+ p_reg->PSEL.MISO = miso_pin;
+}
+
+__STATIC_INLINE void nrf_spim_frequency_set(NRF_SPIM_Type * p_reg,
+ nrf_spim_frequency_t frequency)
+{
+ p_reg->FREQUENCY = frequency;
+}
+
+__STATIC_INLINE void nrf_spim_tx_buffer_set(NRF_SPIM_Type * p_reg,
+ uint8_t const * p_buffer,
+ uint8_t length)
+{
+ p_reg->TXD.PTR = (uint32_t)p_buffer;
+ p_reg->TXD.MAXCNT = length;
+}
+
+__STATIC_INLINE void nrf_spim_rx_buffer_set(NRF_SPIM_Type * p_reg,
+ uint8_t * p_buffer,
+ uint8_t length)
+{
+ p_reg->RXD.PTR = (uint32_t)p_buffer;
+ p_reg->RXD.MAXCNT = length;
+}
+
+__STATIC_INLINE void nrf_spim_configure(NRF_SPIM_Type * p_reg,
+ nrf_spim_mode_t spi_mode,
+ nrf_spim_bit_order_t spi_bit_order)
+{
+ uint32_t config = (spi_bit_order == NRF_SPIM_BIT_ORDER_MSB_FIRST ?
+ SPIM_CONFIG_ORDER_MsbFirst : SPIM_CONFIG_ORDER_LsbFirst);
+ switch (spi_mode)
+ {
+ default:
+ case NRF_SPIM_MODE_0:
+ config |= (SPIM_CONFIG_CPOL_ActiveHigh << SPIM_CONFIG_CPOL_Pos) |
+ (SPIM_CONFIG_CPHA_Leading << SPIM_CONFIG_CPHA_Pos);
+ break;
+
+ case NRF_SPIM_MODE_1:
+ config |= (SPIM_CONFIG_CPOL_ActiveHigh << SPIM_CONFIG_CPOL_Pos) |
+ (SPIM_CONFIG_CPHA_Trailing << SPIM_CONFIG_CPHA_Pos);
+ break;
+
+ case NRF_SPIM_MODE_2:
+ config |= (SPIM_CONFIG_CPOL_ActiveLow << SPIM_CONFIG_CPOL_Pos) |
+ (SPIM_CONFIG_CPHA_Leading << SPIM_CONFIG_CPHA_Pos);
+ break;
+
+ case NRF_SPIM_MODE_3:
+ config |= (SPIM_CONFIG_CPOL_ActiveLow << SPIM_CONFIG_CPOL_Pos) |
+ (SPIM_CONFIG_CPHA_Trailing << SPIM_CONFIG_CPHA_Pos);
+ break;
+ }
+ p_reg->CONFIG = config;
+}
+
+__STATIC_INLINE void nrf_spim_orc_set(NRF_SPIM_Type * p_reg,
+ uint8_t orc)
+{
+ p_reg->ORC = orc;
+}
+
+
+__STATIC_INLINE void nrf_spim_tx_list_enable(NRF_SPIM_Type * p_reg)
+{
+ p_reg->TXD.LIST = 1;
+}
+
+__STATIC_INLINE void nrf_spim_tx_list_disable(NRF_SPIM_Type * p_reg)
+{
+ p_reg->TXD.LIST = 0;
+}
+
+__STATIC_INLINE void nrf_spim_rx_list_enable(NRF_SPIM_Type * p_reg)
+{
+ p_reg->RXD.LIST = 1;
+}
+
+__STATIC_INLINE void nrf_spim_rx_list_disable(NRF_SPIM_Type * p_reg)
+{
+ p_reg->RXD.LIST = 0;
+}
+
+#endif // SUPPRESS_INLINE_IMPLEMENTATION
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_SPIM_H__
+
+/** @} */
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_spis.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_spis.h
new file mode 100644
index 000000000..68746ad38
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_spis.h
@@ -0,0 +1,553 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_spis_hal SPIS HAL
+ * @{
+ * @ingroup nrf_spis
+ *
+ * @brief Hardware access layer for accessing the SPIS peripheral.
+ */
+
+#ifndef NRF_SPIS_H__
+#define NRF_SPIS_H__
+
+#include <stddef.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "nrf.h"
+#include "nrf_peripherals.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief This value can be used as a parameter for the @ref nrf_spis_pins_set
+ * function to specify that a given SPI signal (SCK, MOSI, or MISO)
+ * shall not be connected to a physical pin.
+ */
+#define NRF_SPIS_PIN_NOT_CONNECTED 0xFFFFFFFF
+
+
+/**
+ * @brief SPIS tasks.
+ */
+typedef enum
+{
+ /*lint -save -e30*/
+ NRF_SPIS_TASK_ACQUIRE = offsetof(NRF_SPIS_Type, TASKS_ACQUIRE), ///< Acquire SPI semaphore.
+ NRF_SPIS_TASK_RELEASE = offsetof(NRF_SPIS_Type, TASKS_RELEASE), ///< Release SPI semaphore, enabling the SPI slave to acquire it.
+ /*lint -restore*/
+} nrf_spis_task_t;
+
+/**
+ * @brief SPIS events.
+ */
+typedef enum
+{
+ /*lint -save -e30*/
+ NRF_SPIS_EVENT_END = offsetof(NRF_SPIS_Type, EVENTS_END), ///< Granted transaction completed.
+ NRF_SPIS_EVENT_ACQUIRED = offsetof(NRF_SPIS_Type, EVENTS_ACQUIRED) ///< Semaphore acquired.
+ /*lint -restore*/
+} nrf_spis_event_t;
+
+/**
+ * @brief SPIS shortcuts.
+ */
+typedef enum
+{
+ NRF_SPIS_SHORT_END_ACQUIRE = SPIS_SHORTS_END_ACQUIRE_Msk ///< Shortcut between END event and ACQUIRE task.
+} nrf_spis_short_mask_t;
+
+/**
+ * @brief SPIS interrupts.
+ */
+typedef enum
+{
+ NRF_SPIS_INT_END_MASK = SPIS_INTENSET_END_Msk, ///< Interrupt on END event.
+ NRF_SPIS_INT_ACQUIRED_MASK = SPIS_INTENSET_ACQUIRED_Msk ///< Interrupt on ACQUIRED event.
+} nrf_spis_int_mask_t;
+
+/**
+ * @brief SPI modes.
+ */
+typedef enum
+{
+ NRF_SPIS_MODE_0, ///< SCK active high, sample on leading edge of clock.
+ NRF_SPIS_MODE_1, ///< SCK active high, sample on trailing edge of clock.
+ NRF_SPIS_MODE_2, ///< SCK active low, sample on leading edge of clock.
+ NRF_SPIS_MODE_3 ///< SCK active low, sample on trailing edge of clock.
+} nrf_spis_mode_t;
+
+/**
+ * @brief SPI bit orders.
+ */
+typedef enum
+{
+ NRF_SPIS_BIT_ORDER_MSB_FIRST = SPIS_CONFIG_ORDER_MsbFirst, ///< Most significant bit shifted out first.
+ NRF_SPIS_BIT_ORDER_LSB_FIRST = SPIS_CONFIG_ORDER_LsbFirst ///< Least significant bit shifted out first.
+} nrf_spis_bit_order_t;
+
+/**
+ * @brief SPI semaphore status.
+ */
+typedef enum
+{
+ NRF_SPIS_SEMSTAT_FREE = 0, ///< Semaphore is free.
+ NRF_SPIS_SEMSTAT_CPU = 1, ///< Semaphore is assigned to the CPU.
+ NRF_SPIS_SEMSTAT_SPIS = 2, ///< Semaphore is assigned to the SPI slave.
+ NRF_SPIS_SEMSTAT_CPUPENDING = 3 ///< Semaphore is assigned to the SPI, but a handover to the CPU is pending.
+} nrf_spis_semstat_t;
+
+/**
+ * @brief SPIS status.
+ */
+typedef enum
+{
+ NRF_SPIS_STATUS_OVERREAD = SPIS_STATUS_OVERREAD_Msk, ///< TX buffer over-read detected and prevented.
+ NRF_SPIS_STATUS_OVERFLOW = SPIS_STATUS_OVERFLOW_Msk ///< RX buffer overflow detected and prevented.
+} nrf_spis_status_mask_t;
+
+/**
+ * @brief Function for activating a specific SPIS task.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] spis_task Task to activate.
+ */
+__STATIC_INLINE void nrf_spis_task_trigger(NRF_SPIS_Type * p_reg,
+ nrf_spis_task_t spis_task);
+
+/**
+ * @brief Function for getting the address of a specific SPIS task register.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] spis_task Requested task.
+ *
+ * @return Address of the specified task register.
+ */
+__STATIC_INLINE uint32_t nrf_spis_task_address_get(NRF_SPIS_Type const * p_reg,
+ nrf_spis_task_t spis_task);
+
+/**
+ * @brief Function for clearing a specific SPIS event.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] spis_event Event to clear.
+ */
+__STATIC_INLINE void nrf_spis_event_clear(NRF_SPIS_Type * p_reg,
+ nrf_spis_event_t spis_event);
+
+/**
+ * @brief Function for checking the state of a specific SPIS event.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] spis_event Event to check.
+ *
+ * @retval true If the event is set.
+ * @retval false If the event is not set.
+ */
+__STATIC_INLINE bool nrf_spis_event_check(NRF_SPIS_Type const * p_reg,
+ nrf_spis_event_t spis_event);
+
+/**
+ * @brief Function for getting the address of a specific SPIS event register.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] spis_event Requested event.
+ *
+ * @return Address of the specified event register.
+ */
+__STATIC_INLINE uint32_t nrf_spis_event_address_get(NRF_SPIS_Type const * p_reg,
+ nrf_spis_event_t spis_event);
+
+/**
+ * @brief Function for enabling specified shortcuts.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] spis_shorts_mask Shortcuts to enable.
+ */
+__STATIC_INLINE void nrf_spis_shorts_enable(NRF_SPIS_Type * p_reg,
+ uint32_t spis_shorts_mask);
+
+/**
+ * @brief Function for disabling specified shortcuts.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] spis_shorts_mask Shortcuts to disable.
+ */
+__STATIC_INLINE void nrf_spis_shorts_disable(NRF_SPIS_Type * p_reg,
+ uint32_t spis_shorts_mask);
+
+/**
+ * @brief Function for enabling specified interrupts.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] spis_int_mask Interrupts to enable.
+ */
+__STATIC_INLINE void nrf_spis_int_enable(NRF_SPIS_Type * p_reg,
+ uint32_t spis_int_mask);
+
+/**
+ * @brief Function for disabling specified interrupts.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] spis_int_mask Interrupts to disable.
+ */
+__STATIC_INLINE void nrf_spis_int_disable(NRF_SPIS_Type * p_reg,
+ uint32_t spis_int_mask);
+
+/**
+ * @brief Function for retrieving the state of a given interrupt.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] spis_int Interrupt to check.
+ *
+ * @retval true If the interrupt is enabled.
+ * @retval false If the interrupt is not enabled.
+ */
+__STATIC_INLINE bool nrf_spis_int_enable_check(NRF_SPIS_Type const * p_reg,
+ nrf_spis_int_mask_t spis_int);
+
+/**
+ * @brief Function for enabling the SPIS peripheral.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE void nrf_spis_enable(NRF_SPIS_Type * p_reg);
+
+/**
+ * @brief Function for disabling the SPIS peripheral.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE void nrf_spis_disable(NRF_SPIS_Type * p_reg);
+
+/**
+ * @brief Function for retrieving the SPIS semaphore status.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ *
+ * @returns Current semaphore status.
+ */
+__STATIC_INLINE nrf_spis_semstat_t nrf_spis_semaphore_status_get(NRF_SPIS_Type * p_reg);
+
+/**
+ * @brief Function for retrieving the SPIS status.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ *
+ * @returns Current SPIS status.
+ */
+__STATIC_INLINE nrf_spis_status_mask_t nrf_spis_status_get(NRF_SPIS_Type * p_reg);
+
+/**
+ * @brief Function for configuring SPIS pins.
+ *
+ * If a given signal is not needed, pass the @ref NRF_SPIS_PIN_NOT_CONNECTED
+ * value instead of its pin number.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] sck_pin SCK pin number.
+ * @param[in] mosi_pin MOSI pin number.
+ * @param[in] miso_pin MISO pin number.
+ * @param[in] csn_pin CSN pin number.
+ */
+__STATIC_INLINE void nrf_spis_pins_set(NRF_SPIS_Type * p_reg,
+ uint32_t sck_pin,
+ uint32_t mosi_pin,
+ uint32_t miso_pin,
+ uint32_t csn_pin);
+
+/**
+ * @brief Function for setting the transmit buffer.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] p_buffer Pointer to the buffer that contains the data to send.
+ * @param[in] length Maximum number of data bytes to transmit.
+ */
+__STATIC_INLINE void nrf_spis_tx_buffer_set(NRF_SPIS_Type * p_reg,
+ uint8_t const * p_buffer,
+ uint8_t length);
+
+/**
+ * @brief Function for setting the receive buffer.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] p_buffer Pointer to the buffer for received data.
+ * @param[in] length Maximum number of data bytes to receive.
+ */
+__STATIC_INLINE void nrf_spis_rx_buffer_set(NRF_SPIS_Type * p_reg,
+ uint8_t * p_buffer,
+ uint8_t length);
+
+/**
+ * @brief Function for getting the number of bytes transmitted
+ * in the last granted transaction.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ *
+ * @returns Number of bytes transmitted.
+ */
+__STATIC_INLINE uint8_t nrf_spis_tx_amount_get(NRF_SPIS_Type const * p_reg);
+
+/**
+ * @brief Function for getting the number of bytes received
+ * in the last granted transaction.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ *
+ * @returns Number of bytes received.
+ */
+__STATIC_INLINE uint8_t nrf_spis_rx_amount_get(NRF_SPIS_Type const * p_reg);
+
+/**
+ * @brief Function for setting the SPI configuration.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] spi_mode SPI mode.
+ * @param[in] spi_bit_order SPI bit order.
+ */
+__STATIC_INLINE void nrf_spis_configure(NRF_SPIS_Type * p_reg,
+ nrf_spis_mode_t spi_mode,
+ nrf_spis_bit_order_t spi_bit_order);
+
+/**
+ * @brief Function for setting the default character.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] def Default character that is clocked out in case of
+ * an overflow of the RXD buffer.
+ */
+__STATIC_INLINE void nrf_spis_def_set(NRF_SPIS_Type * p_reg,
+ uint8_t def);
+
+/**
+ * @brief Function for setting the over-read character.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] orc Over-read character that is clocked out in case of
+ * an over-read of the TXD buffer.
+ */
+__STATIC_INLINE void nrf_spis_orc_set(NRF_SPIS_Type * p_reg,
+ uint8_t orc);
+
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE void nrf_spis_task_trigger(NRF_SPIS_Type * p_reg,
+ nrf_spis_task_t spis_task)
+{
+ *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spis_task)) = 0x1UL;
+}
+
+__STATIC_INLINE uint32_t nrf_spis_task_address_get(NRF_SPIS_Type const * p_reg,
+ nrf_spis_task_t spis_task)
+{
+ return (uint32_t)p_reg + (uint32_t)spis_task;
+}
+
+__STATIC_INLINE void nrf_spis_event_clear(NRF_SPIS_Type * p_reg,
+ nrf_spis_event_t spis_event)
+{
+ *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spis_event)) = 0x0UL;
+#if __CORTEX_M == 0x04
+ volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spis_event));
+ (void)dummy;
+#endif
+}
+
+__STATIC_INLINE bool nrf_spis_event_check(NRF_SPIS_Type const * p_reg,
+ nrf_spis_event_t spis_event)
+{
+ return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spis_event);
+}
+
+__STATIC_INLINE uint32_t nrf_spis_event_address_get(NRF_SPIS_Type const * p_reg,
+ nrf_spis_event_t spis_event)
+{
+ return (uint32_t)p_reg + (uint32_t)spis_event;
+}
+
+__STATIC_INLINE void nrf_spis_shorts_enable(NRF_SPIS_Type * p_reg,
+ uint32_t spis_shorts_mask)
+{
+ p_reg->SHORTS |= spis_shorts_mask;
+}
+
+__STATIC_INLINE void nrf_spis_shorts_disable(NRF_SPIS_Type * p_reg,
+ uint32_t spis_shorts_mask)
+{
+ p_reg->SHORTS &= ~(spis_shorts_mask);
+}
+
+__STATIC_INLINE void nrf_spis_int_enable(NRF_SPIS_Type * p_reg,
+ uint32_t spis_int_mask)
+{
+ p_reg->INTENSET = spis_int_mask;
+}
+
+__STATIC_INLINE void nrf_spis_int_disable(NRF_SPIS_Type * p_reg,
+ uint32_t spis_int_mask)
+{
+ p_reg->INTENCLR = spis_int_mask;
+}
+
+__STATIC_INLINE bool nrf_spis_int_enable_check(NRF_SPIS_Type const * p_reg,
+ nrf_spis_int_mask_t spis_int)
+{
+ return (bool)(p_reg->INTENSET & spis_int);
+}
+
+__STATIC_INLINE void nrf_spis_enable(NRF_SPIS_Type * p_reg)
+{
+ p_reg->ENABLE = (SPIS_ENABLE_ENABLE_Enabled << SPIS_ENABLE_ENABLE_Pos);
+}
+
+__STATIC_INLINE void nrf_spis_disable(NRF_SPIS_Type * p_reg)
+{
+ p_reg->ENABLE = (SPIS_ENABLE_ENABLE_Disabled << SPIS_ENABLE_ENABLE_Pos);
+}
+
+__STATIC_INLINE nrf_spis_semstat_t nrf_spis_semaphore_status_get(NRF_SPIS_Type * p_reg)
+{
+ return (nrf_spis_semstat_t) ((p_reg->SEMSTAT & SPIS_SEMSTAT_SEMSTAT_Msk)
+ >> SPIS_SEMSTAT_SEMSTAT_Pos);
+}
+
+__STATIC_INLINE nrf_spis_status_mask_t nrf_spis_status_get(NRF_SPIS_Type * p_reg)
+{
+ return (nrf_spis_status_mask_t) p_reg->STATUS;
+}
+
+__STATIC_INLINE void nrf_spis_pins_set(NRF_SPIS_Type * p_reg,
+ uint32_t sck_pin,
+ uint32_t mosi_pin,
+ uint32_t miso_pin,
+ uint32_t csn_pin)
+{
+ p_reg->PSELSCK = sck_pin;
+ p_reg->PSELMOSI = mosi_pin;
+ p_reg->PSELMISO = miso_pin;
+ p_reg->PSELCSN = csn_pin;
+}
+
+__STATIC_INLINE void nrf_spis_tx_buffer_set(NRF_SPIS_Type * p_reg,
+ uint8_t const * p_buffer,
+ uint8_t length)
+{
+ p_reg->TXDPTR = (uint32_t)p_buffer;
+ p_reg->MAXTX = length;
+}
+
+__STATIC_INLINE void nrf_spis_rx_buffer_set(NRF_SPIS_Type * p_reg,
+ uint8_t * p_buffer,
+ uint8_t length)
+{
+ p_reg->RXDPTR = (uint32_t)p_buffer;
+ p_reg->MAXRX = length;
+}
+
+__STATIC_INLINE uint8_t nrf_spis_tx_amount_get(NRF_SPIS_Type const * p_reg)
+{
+ return (uint8_t) p_reg->AMOUNTTX;
+}
+
+__STATIC_INLINE uint8_t nrf_spis_rx_amount_get(NRF_SPIS_Type const * p_reg)
+{
+ return (uint8_t) p_reg->AMOUNTRX;
+}
+
+__STATIC_INLINE void nrf_spis_configure(NRF_SPIS_Type * p_reg,
+ nrf_spis_mode_t spi_mode,
+ nrf_spis_bit_order_t spi_bit_order)
+{
+ uint32_t config = (spi_bit_order == NRF_SPIS_BIT_ORDER_MSB_FIRST ?
+ SPIS_CONFIG_ORDER_MsbFirst : SPIS_CONFIG_ORDER_LsbFirst);
+
+ switch (spi_mode)
+ {
+ default:
+ case NRF_SPIS_MODE_0:
+ config |= (SPIS_CONFIG_CPOL_ActiveHigh << SPIS_CONFIG_CPOL_Pos) |
+ (SPIS_CONFIG_CPHA_Leading << SPIS_CONFIG_CPHA_Pos);
+ break;
+
+ case NRF_SPIS_MODE_1:
+ config |= (SPIS_CONFIG_CPOL_ActiveHigh << SPIS_CONFIG_CPOL_Pos) |
+ (SPIS_CONFIG_CPHA_Trailing << SPIS_CONFIG_CPHA_Pos);
+ break;
+
+ case NRF_SPIS_MODE_2:
+ config |= (SPIS_CONFIG_CPOL_ActiveLow << SPIS_CONFIG_CPOL_Pos) |
+ (SPIS_CONFIG_CPHA_Leading << SPIS_CONFIG_CPHA_Pos);
+ break;
+
+ case NRF_SPIS_MODE_3:
+ config |= (SPIS_CONFIG_CPOL_ActiveLow << SPIS_CONFIG_CPOL_Pos) |
+ (SPIS_CONFIG_CPHA_Trailing << SPIS_CONFIG_CPHA_Pos);
+ break;
+ }
+ p_reg->CONFIG = config;
+}
+
+__STATIC_INLINE void nrf_spis_orc_set(NRF_SPIS_Type * p_reg,
+ uint8_t orc)
+{
+ p_reg->ORC = orc;
+}
+
+__STATIC_INLINE void nrf_spis_def_set(NRF_SPIS_Type * p_reg,
+ uint8_t def)
+{
+ p_reg->DEF = def;
+}
+
+#endif // SUPPRESS_INLINE_IMPLEMENTATION
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_SPIS_H__
+
+/** @} */
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_systick.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_systick.h
new file mode 100644
index 000000000..26fbf37e3
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_systick.h
@@ -0,0 +1,184 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_SYSTICK_H__
+#define NRF_SYSTICK_H__
+
+#include "nrf.h"
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+/**
+ * @defgroup nrf_systick_hal SYSTICK HAL
+ * @{
+ * @ingroup nrf_systick
+ *
+ * @brief Hardware access layer for accessing the SYSTICK peripheral.
+ *
+ * SYSTICK is ARM peripheral, not Nordic design.
+ * It means that it has no Nordic-typical interface with Tasks and Events.
+ *
+ * Its usage is limited here to implement simple delays.
+ * Also keep in mind that this timer would be stopped when CPU is sleeping
+ * (WFE/WFI instruction is successfully executed).
+ */
+
+/**
+ * @brief Mask of usable bits in the SysTick value
+ */
+#define NRF_SYSTICK_VAL_MASK SysTick_VAL_CURRENT_Msk
+
+/**
+ * @brief Flags used by SysTick configuration.
+ *
+ * @sa nrf_systick_csr_set
+ * @sa nrf_systick_csr_get
+ */
+typedef enum {
+ NRF_SYSTICK_CSR_COUNTFLAG_MASK = SysTick_CTRL_COUNTFLAG_Msk, /**< Status flag: Returns 1 if timer counted to 0 since the last read of this register. */
+
+ NRF_SYSTICK_CSR_CLKSOURCE_MASK = SysTick_CTRL_CLKSOURCE_Msk, /**< Configuration bit: Select the SysTick clock source. */
+ NRF_SYSTICK_CSR_CLKSOURCE_REF = 0U << SysTick_CTRL_CLKSOURCE_Pos, /**< Configuration value: Select reference clock. */
+ NRF_SYSTICK_CSR_CLKSOURCE_CPU = 1U << SysTick_CTRL_CLKSOURCE_Pos, /**< Configuration value: Select CPU clock. */
+
+ NRF_SYSTICK_CSR_TICKINT_MASK = SysTick_CTRL_TICKINT_Msk, /**< Configuration bit: Enables SysTick exception request. */
+ NRF_SYSTICK_CSR_TICKINT_ENABLE = 1U << SysTick_CTRL_TICKINT_Pos, /**< Configuration value: Counting down to zero does not assert the SysTick exception request. */
+ NRF_SYSTICK_CSR_TICKINT_DISABLE = 0U << SysTick_CTRL_TICKINT_Pos, /**< Configuration value: Counting down to zero to asserts the SysTick exception request. */
+
+ NRF_SYSTICK_CSR_ENABLE_MASK = SysTick_CTRL_ENABLE_Msk, /**< Configuration bit: Enable the SysTick timer. */
+ NRF_SYSTICK_CSR_ENABLE = 1U << SysTick_CTRL_ENABLE_Pos, /**< Configuration value: Counter enabled. */
+ NRF_SYSTICK_CSR_DISABLE = 0U << SysTick_CTRL_ENABLE_Pos /**< Configuration value: Counter disabled. */
+} nrf_systick_csr_flags_t;
+
+/**
+ * @brief Get Configuration and Status Register
+ *
+ * @return Values composed by @ref nrf_systick_csr_flags_t.
+ * @note The @ref NRF_SYSTICK_CSR_COUNTFLAG_MASK value is cleared when CSR register is read.
+ */
+__STATIC_INLINE uint32_t nrf_systick_csr_get(void);
+
+/**
+ * @brief Set Configuration and Status Register
+ *
+ * @param[in] val The value composed from @ref nrf_systick_csr_flags_t.
+ */
+__STATIC_INLINE void nrf_systick_csr_set(uint32_t val);
+
+/**
+ * @brief Get the current reload value.
+ *
+ * @return The reload register value.
+ */
+__STATIC_INLINE uint32_t nrf_systick_load_get(void);
+
+/**
+ * @brief Configure the reload value.
+ *
+ * @param[in] val The value to set in the reload register.
+ */
+__STATIC_INLINE void nrf_systick_load_set(uint32_t val);
+
+/**
+ * @brief Read the SysTick current value
+ *
+ * @return The current SysTick value
+ * @sa NRF_SYSTICK_VAL_MASK
+ */
+__STATIC_INLINE uint32_t nrf_systick_val_get(void);
+
+/**
+ * @brief Clear the SysTick current value
+ *
+ * @note The SysTick does not allow setting current value.
+ * Any write to VAL register would clear the timer.
+ */
+__STATIC_INLINE void nrf_systick_val_clear(void);
+
+/**
+ * @brief Read the calibration register
+ *
+ * @return The calibration register value
+ */
+__STATIC_INLINE uint32_t nrf_systick_calib_get(void);
+
+
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE uint32_t nrf_systick_csr_get(void)
+{
+ return SysTick->CTRL;
+}
+
+__STATIC_INLINE void nrf_systick_csr_set(uint32_t val)
+{
+ SysTick->CTRL = val;
+}
+
+__STATIC_INLINE uint32_t nrf_systick_load_get(void)
+{
+ return SysTick->LOAD;
+}
+
+__STATIC_INLINE void nrf_systick_load_set(uint32_t val)
+{
+ SysTick->LOAD = val;
+}
+
+__STATIC_INLINE uint32_t nrf_systick_val_get(void)
+{
+ return SysTick->VAL;
+}
+
+__STATIC_INLINE void nrf_systick_val_clear(void)
+{
+ SysTick->VAL = 0;
+}
+
+__STATIC_INLINE uint32_t nrf_systick_calib_get(void)
+{
+ return SysTick->CALIB;
+}
+
+#endif /* SUPPRESS_INLINE_IMPLEMENTATION */
+
+/** @} */
+#endif /* NRF_SYSTICK_H__ */
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_temp.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_temp.h
new file mode 100644
index 000000000..415a3e74e
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_temp.h
@@ -0,0 +1,91 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_TEMP_H__
+#define NRF_TEMP_H__
+
+#include "nrf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+* @defgroup nrf_temperature TEMP (temperature) abstraction
+* @{
+* @ingroup nrf_drivers temperature_example
+* @brief Temperature module init and read functions.
+*
+*/
+
+/**@cond NO_DOXYGEN */
+#define MASK_SIGN (0x00000200UL)
+#define MASK_SIGN_EXTENSION (0xFFFFFC00UL)
+
+/**
+ * @brief Function for preparing the temp module for temperature measurement.
+ *
+ * This function initializes the TEMP module and writes to the hidden configuration register.
+ */
+static __INLINE void nrf_temp_init(void)
+{
+ /**@note Workaround for PAN_028 rev2.0A anomaly 31 - TEMP: Temperature offset value has to be manually loaded to the TEMP module */
+ *(uint32_t *) 0x4000C504 = 0;
+}
+
+/**
+ * @brief Function for reading temperature measurement.
+ *
+ * The function reads the 10 bit 2's complement value and transforms it to a 32 bit 2's complement value.
+ */
+static __INLINE int32_t nrf_temp_read(void)
+{
+ /**@note Workaround for PAN_028 rev2.0A anomaly 28 - TEMP: Negative measured values are not represented correctly */
+ return ((NRF_TEMP->TEMP & MASK_SIGN) != 0) ? (NRF_TEMP->TEMP | MASK_SIGN_EXTENSION) : (NRF_TEMP->TEMP);
+}
+/**@endcond */
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_timer.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_timer.h
new file mode 100644
index 000000000..d089d01b3
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_timer.h
@@ -0,0 +1,630 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_timer_hal Timer HAL
+ * @{
+ * @ingroup nrf_timer
+ *
+ * @brief Hardware access layer for accessing the timer peripheral.
+ */
+
+#ifndef NRF_TIMER_H__
+#define NRF_TIMER_H__
+
+#include <stddef.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "nrf_peripherals.h"
+#include "nrf.h"
+#include "nrf_assert.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief Macro for validating the correctness of the BIT_WIDTH setting.
+ */
+
+#define TIMER_MAX_SIZE(id) CONCAT_3(TIMER, id, _MAX_SIZE)
+
+#define TIMER_BIT_WIDTH_MAX(id, bit_width) \
+ (TIMER_MAX_SIZE(id) == 8 ? (bit_width == NRF_TIMER_BIT_WIDTH_8) : \
+ (TIMER_MAX_SIZE(id) == 16 ? (bit_width == NRF_TIMER_BIT_WIDTH_8) || \
+ (bit_width == NRF_TIMER_BIT_WIDTH_16) : \
+ (TIMER_MAX_SIZE(id) == 24 ? (bit_width == NRF_TIMER_BIT_WIDTH_8) || \
+ (bit_width == NRF_TIMER_BIT_WIDTH_16) || \
+ (bit_width == NRF_TIMER_BIT_WIDTH_24) : \
+ (TIMER_MAX_SIZE(id) == 32 ? (bit_width == NRF_TIMER_BIT_WIDTH_8) || \
+ (bit_width == NRF_TIMER_BIT_WIDTH_16) || \
+ (bit_width == NRF_TIMER_BIT_WIDTH_24) || \
+ (bit_width == NRF_TIMER_BIT_WIDTH_32) : \
+ false))))
+
+#if TIMER_COUNT > 3
+#define NRF_TIMER_IS_BIT_WIDTH_VALID(p_reg, bit_width) ( \
+ ((p_reg == NRF_TIMER0) && (TIMER_BIT_WIDTH_MAX(0, bit_width))) \
+ || ((p_reg == NRF_TIMER1) && (TIMER_BIT_WIDTH_MAX(1, bit_width))) \
+ || ((p_reg == NRF_TIMER2) && (TIMER_BIT_WIDTH_MAX(2, bit_width))) \
+ || ((p_reg == NRF_TIMER3) && (TIMER_BIT_WIDTH_MAX(3, bit_width))) \
+ || ((p_reg == NRF_TIMER4) && (TIMER_BIT_WIDTH_MAX(4, bit_width))) )
+
+#else
+#define NRF_TIMER_IS_BIT_WIDTH_VALID(p_reg, bit_width) ( \
+ ((p_reg == NRF_TIMER0) && TIMER_BIT_WIDTH_MAX(0, bit_width)) \
+ || ((p_reg == NRF_TIMER1) && TIMER_BIT_WIDTH_MAX(1, bit_width)) \
+ || ((p_reg == NRF_TIMER2) && TIMER_BIT_WIDTH_MAX(2, bit_width)) )
+
+#endif
+
+/**
+ * @brief Macro for getting the number of capture/compare channels available
+ * in a given timer instance.
+ */
+#define NRF_TIMER_CC_CHANNEL_COUNT(id) CONCAT_3(TIMER, id, _CC_NUM)
+
+/**
+ * @brief Timer tasks.
+ */
+typedef enum
+{
+ /*lint -save -e30 -esym(628,__INTADDR__)*/
+ NRF_TIMER_TASK_START = offsetof(NRF_TIMER_Type, TASKS_START), ///< Task for starting the timer.
+ NRF_TIMER_TASK_STOP = offsetof(NRF_TIMER_Type, TASKS_STOP), ///< Task for stopping the timer.
+ NRF_TIMER_TASK_COUNT = offsetof(NRF_TIMER_Type, TASKS_COUNT), ///< Task for incrementing the timer (in counter mode).
+ NRF_TIMER_TASK_CLEAR = offsetof(NRF_TIMER_Type, TASKS_CLEAR), ///< Task for resetting the timer value.
+ NRF_TIMER_TASK_SHUTDOWN = offsetof(NRF_TIMER_Type, TASKS_SHUTDOWN), ///< Task for powering off the timer.
+ NRF_TIMER_TASK_CAPTURE0 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[0]), ///< Task for capturing the timer value on channel 0.
+ NRF_TIMER_TASK_CAPTURE1 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[1]), ///< Task for capturing the timer value on channel 1.
+ NRF_TIMER_TASK_CAPTURE2 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[2]), ///< Task for capturing the timer value on channel 2.
+ NRF_TIMER_TASK_CAPTURE3 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[3]), ///< Task for capturing the timer value on channel 3.
+#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__)
+ NRF_TIMER_TASK_CAPTURE4 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[4]), ///< Task for capturing the timer value on channel 4.
+ NRF_TIMER_TASK_CAPTURE5 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[5]), ///< Task for capturing the timer value on channel 5.
+#endif
+ /*lint -restore*/
+} nrf_timer_task_t;
+
+/**
+ * @brief Timer events.
+ */
+typedef enum
+{
+ /*lint -save -e30*/
+ NRF_TIMER_EVENT_COMPARE0 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[0]), ///< Event from compare channel 0.
+ NRF_TIMER_EVENT_COMPARE1 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[1]), ///< Event from compare channel 1.
+ NRF_TIMER_EVENT_COMPARE2 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[2]), ///< Event from compare channel 2.
+ NRF_TIMER_EVENT_COMPARE3 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[3]), ///< Event from compare channel 3.
+#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__)
+ NRF_TIMER_EVENT_COMPARE4 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[4]), ///< Event from compare channel 4.
+ NRF_TIMER_EVENT_COMPARE5 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[5]), ///< Event from compare channel 5.
+#endif
+ /*lint -restore*/
+} nrf_timer_event_t;
+
+/**
+ * @brief Types of timer shortcuts.
+ */
+typedef enum
+{
+ NRF_TIMER_SHORT_COMPARE0_STOP_MASK = TIMER_SHORTS_COMPARE0_STOP_Msk, ///< Shortcut for stopping the timer based on compare 0.
+ NRF_TIMER_SHORT_COMPARE1_STOP_MASK = TIMER_SHORTS_COMPARE1_STOP_Msk, ///< Shortcut for stopping the timer based on compare 1.
+ NRF_TIMER_SHORT_COMPARE2_STOP_MASK = TIMER_SHORTS_COMPARE2_STOP_Msk, ///< Shortcut for stopping the timer based on compare 2.
+ NRF_TIMER_SHORT_COMPARE3_STOP_MASK = TIMER_SHORTS_COMPARE3_STOP_Msk, ///< Shortcut for stopping the timer based on compare 3.
+#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__)
+ NRF_TIMER_SHORT_COMPARE4_STOP_MASK = TIMER_SHORTS_COMPARE4_STOP_Msk, ///< Shortcut for stopping the timer based on compare 4.
+ NRF_TIMER_SHORT_COMPARE5_STOP_MASK = TIMER_SHORTS_COMPARE5_STOP_Msk, ///< Shortcut for stopping the timer based on compare 5.
+#endif
+ NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK = TIMER_SHORTS_COMPARE0_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 0.
+ NRF_TIMER_SHORT_COMPARE1_CLEAR_MASK = TIMER_SHORTS_COMPARE1_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 1.
+ NRF_TIMER_SHORT_COMPARE2_CLEAR_MASK = TIMER_SHORTS_COMPARE2_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 2.
+ NRF_TIMER_SHORT_COMPARE3_CLEAR_MASK = TIMER_SHORTS_COMPARE3_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 3.
+#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__)
+ NRF_TIMER_SHORT_COMPARE4_CLEAR_MASK = TIMER_SHORTS_COMPARE4_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 4.
+ NRF_TIMER_SHORT_COMPARE5_CLEAR_MASK = TIMER_SHORTS_COMPARE5_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 5.
+#endif
+} nrf_timer_short_mask_t;
+
+/**
+ * @brief Timer modes.
+ */
+typedef enum
+{
+ NRF_TIMER_MODE_TIMER = TIMER_MODE_MODE_Timer, ///< Timer mode: timer.
+ NRF_TIMER_MODE_COUNTER = TIMER_MODE_MODE_Counter, ///< Timer mode: counter.
+#if defined(TIMER_MODE_MODE_LowPowerCounter) || defined(__SDK_DOXYGEN__)
+ NRF_TIMER_MODE_LOW_POWER_COUNTER = TIMER_MODE_MODE_LowPowerCounter, ///< Timer mode: low-power counter.
+#endif
+} nrf_timer_mode_t;
+
+/**
+ * @brief Timer bit width.
+ */
+typedef enum
+{
+ NRF_TIMER_BIT_WIDTH_8 = TIMER_BITMODE_BITMODE_08Bit, ///< Timer bit width 8 bit.
+ NRF_TIMER_BIT_WIDTH_16 = TIMER_BITMODE_BITMODE_16Bit, ///< Timer bit width 16 bit.
+ NRF_TIMER_BIT_WIDTH_24 = TIMER_BITMODE_BITMODE_24Bit, ///< Timer bit width 24 bit.
+ NRF_TIMER_BIT_WIDTH_32 = TIMER_BITMODE_BITMODE_32Bit ///< Timer bit width 32 bit.
+} nrf_timer_bit_width_t;
+
+/**
+ * @brief Timer prescalers.
+ */
+typedef enum
+{
+ NRF_TIMER_FREQ_16MHz = 0, ///< Timer frequency 16 MHz.
+ NRF_TIMER_FREQ_8MHz, ///< Timer frequency 8 MHz.
+ NRF_TIMER_FREQ_4MHz, ///< Timer frequency 4 MHz.
+ NRF_TIMER_FREQ_2MHz, ///< Timer frequency 2 MHz.
+ NRF_TIMER_FREQ_1MHz, ///< Timer frequency 1 MHz.
+ NRF_TIMER_FREQ_500kHz, ///< Timer frequency 500 kHz.
+ NRF_TIMER_FREQ_250kHz, ///< Timer frequency 250 kHz.
+ NRF_TIMER_FREQ_125kHz, ///< Timer frequency 125 kHz.
+ NRF_TIMER_FREQ_62500Hz, ///< Timer frequency 62500 Hz.
+ NRF_TIMER_FREQ_31250Hz ///< Timer frequency 31250 Hz.
+} nrf_timer_frequency_t;
+
+/**
+ * @brief Timer capture/compare channels.
+ */
+typedef enum
+{
+ NRF_TIMER_CC_CHANNEL0 = 0, ///< Timer capture/compare channel 0.
+ NRF_TIMER_CC_CHANNEL1, ///< Timer capture/compare channel 1.
+ NRF_TIMER_CC_CHANNEL2, ///< Timer capture/compare channel 2.
+ NRF_TIMER_CC_CHANNEL3, ///< Timer capture/compare channel 3.
+#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__)
+ NRF_TIMER_CC_CHANNEL4, ///< Timer capture/compare channel 4.
+ NRF_TIMER_CC_CHANNEL5, ///< Timer capture/compare channel 5.
+#endif
+} nrf_timer_cc_channel_t;
+
+/**
+ * @brief Timer interrupts.
+ */
+typedef enum
+{
+ NRF_TIMER_INT_COMPARE0_MASK = TIMER_INTENSET_COMPARE0_Msk, ///< Timer interrupt from compare event on channel 0.
+ NRF_TIMER_INT_COMPARE1_MASK = TIMER_INTENSET_COMPARE1_Msk, ///< Timer interrupt from compare event on channel 1.
+ NRF_TIMER_INT_COMPARE2_MASK = TIMER_INTENSET_COMPARE2_Msk, ///< Timer interrupt from compare event on channel 2.
+ NRF_TIMER_INT_COMPARE3_MASK = TIMER_INTENSET_COMPARE3_Msk, ///< Timer interrupt from compare event on channel 3.
+#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__)
+ NRF_TIMER_INT_COMPARE4_MASK = TIMER_INTENSET_COMPARE4_Msk, ///< Timer interrupt from compare event on channel 4.
+ NRF_TIMER_INT_COMPARE5_MASK = TIMER_INTENSET_COMPARE5_Msk, ///< Timer interrupt from compare event on channel 5.
+#endif
+} nrf_timer_int_mask_t;
+
+
+/**
+ * @brief Function for activating a specific timer task.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] task Task to activate.
+ */
+__STATIC_INLINE void nrf_timer_task_trigger(NRF_TIMER_Type * p_reg,
+ nrf_timer_task_t task);
+
+/**
+ * @brief Function for getting the address of a specific timer task register.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] task Requested task.
+ *
+ * @return Address of the specified task register.
+ */
+__STATIC_INLINE uint32_t * nrf_timer_task_address_get(NRF_TIMER_Type * p_reg,
+ nrf_timer_task_t task);
+
+/**
+ * @brief Function for clearing a specific timer event.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] event Event to clear.
+ */
+__STATIC_INLINE void nrf_timer_event_clear(NRF_TIMER_Type * p_reg,
+ nrf_timer_event_t event);
+
+/**
+ * @brief Function for checking the state of a specific timer event.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] event Event to check.
+ *
+ * @retval true If the event is set.
+ * @retval false If the event is not set.
+ */
+__STATIC_INLINE bool nrf_timer_event_check(NRF_TIMER_Type * p_reg,
+ nrf_timer_event_t event);
+
+/**
+ * @brief Function for getting the address of a specific timer event register.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] event Requested event.
+ *
+ * @return Address of the specified event register.
+ */
+__STATIC_INLINE uint32_t * nrf_timer_event_address_get(NRF_TIMER_Type * p_reg,
+ nrf_timer_event_t event);
+
+/**
+ * @brief Function for enabling specified shortcuts.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] timer_shorts_mask Shortcuts to enable.
+ */
+__STATIC_INLINE void nrf_timer_shorts_enable(NRF_TIMER_Type * p_reg,
+ uint32_t timer_shorts_mask);
+
+/**
+ * @brief Function for disabling specified shortcuts.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] timer_shorts_mask Shortcuts to disable.
+ */
+__STATIC_INLINE void nrf_timer_shorts_disable(NRF_TIMER_Type * p_reg,
+ uint32_t timer_shorts_mask);
+
+/**
+ * @brief Function for enabling specified interrupts.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] timer_int_mask Interrupts to enable.
+ */
+__STATIC_INLINE void nrf_timer_int_enable(NRF_TIMER_Type * p_reg,
+ uint32_t timer_int_mask);
+
+/**
+ * @brief Function for disabling specified interrupts.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] timer_int_mask Interrupts to disable.
+ */
+__STATIC_INLINE void nrf_timer_int_disable(NRF_TIMER_Type * p_reg,
+ uint32_t timer_int_mask);
+
+/**
+ * @brief Function for retrieving the state of a given interrupt.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] timer_int Interrupt to check.
+ *
+ * @retval true If the interrupt is enabled.
+ * @retval false If the interrupt is not enabled.
+ */
+__STATIC_INLINE bool nrf_timer_int_enable_check(NRF_TIMER_Type * p_reg,
+ uint32_t timer_int);
+
+/**
+ * @brief Function for setting the timer mode.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] mode Timer mode.
+ */
+__STATIC_INLINE void nrf_timer_mode_set(NRF_TIMER_Type * p_reg,
+ nrf_timer_mode_t mode);
+
+/**
+ * @brief Function for retrieving the timer mode.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ *
+ * @return Timer mode.
+ */
+__STATIC_INLINE nrf_timer_mode_t nrf_timer_mode_get(NRF_TIMER_Type * p_reg);
+
+/**
+ * @brief Function for setting the timer bit width.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] bit_width Timer bit width.
+ */
+__STATIC_INLINE void nrf_timer_bit_width_set(NRF_TIMER_Type * p_reg,
+ nrf_timer_bit_width_t bit_width);
+
+/**
+ * @brief Function for retrieving the timer bit width.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ *
+ * @return Timer bit width.
+ */
+__STATIC_INLINE nrf_timer_bit_width_t nrf_timer_bit_width_get(NRF_TIMER_Type * p_reg);
+
+/**
+ * @brief Function for setting the timer frequency.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] frequency Timer frequency.
+ */
+__STATIC_INLINE void nrf_timer_frequency_set(NRF_TIMER_Type * p_reg,
+ nrf_timer_frequency_t frequency);
+
+/**
+ * @brief Function for retrieving the timer frequency.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ *
+ * @return Timer frequency.
+ */
+__STATIC_INLINE nrf_timer_frequency_t nrf_timer_frequency_get(NRF_TIMER_Type * p_reg);
+
+/**
+ * @brief Function for writing the capture/compare register for a specified channel.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] cc_channel Requested capture/compare channel.
+ * @param[in] cc_value Value to write to the capture/compare register.
+ */
+__STATIC_INLINE void nrf_timer_cc_write(NRF_TIMER_Type * p_reg,
+ nrf_timer_cc_channel_t cc_channel,
+ uint32_t cc_value);
+
+/**
+ * @brief Function for retrieving the capture/compare value for a specified channel.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] cc_channel Requested capture/compare channel.
+ *
+ * @return Value from the requested capture/compare register.
+ */
+__STATIC_INLINE uint32_t nrf_timer_cc_read(NRF_TIMER_Type * p_reg,
+ nrf_timer_cc_channel_t cc_channel);
+
+/**
+ * @brief Function for getting a specific timer capture task.
+ *
+ * @param[in] channel Capture channel.
+ *
+ * @return Capture task.
+ */
+__STATIC_INLINE nrf_timer_task_t nrf_timer_capture_task_get(uint32_t channel);
+
+/**
+ * @brief Function for getting a specific timer compare event.
+ *
+ * @param[in] channel Compare channel.
+ *
+ * @return Compare event.
+ */
+__STATIC_INLINE nrf_timer_event_t nrf_timer_compare_event_get(uint32_t channel);
+
+/**
+ * @brief Function for getting a specific timer compare interrupt.
+ *
+ * @param[in] channel Compare channel.
+ *
+ * @return Compare interrupt.
+ */
+__STATIC_INLINE nrf_timer_int_mask_t nrf_timer_compare_int_get(uint32_t channel);
+
+/**
+ * @brief Function for calculating the number of timer ticks for a given time
+ * (in microseconds) and timer frequency.
+ *
+ * @param[in] time_us Time in microseconds.
+ * @param[in] frequency Timer frequency.
+ *
+ * @return Number of timer ticks.
+ */
+__STATIC_INLINE uint32_t nrf_timer_us_to_ticks(uint32_t time_us,
+ nrf_timer_frequency_t frequency);
+
+/**
+ * @brief Function for calculating the number of timer ticks for a given time
+ * (in milliseconds) and timer frequency.
+ *
+ * @param[in] time_ms Time in milliseconds.
+ * @param[in] frequency Timer frequency.
+ *
+ * @return Number of timer ticks.
+ */
+__STATIC_INLINE uint32_t nrf_timer_ms_to_ticks(uint32_t time_ms,
+ nrf_timer_frequency_t frequency);
+
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE void nrf_timer_task_trigger(NRF_TIMER_Type * p_reg,
+ nrf_timer_task_t task)
+{
+ *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
+}
+
+__STATIC_INLINE uint32_t * nrf_timer_task_address_get(NRF_TIMER_Type * p_reg,
+ nrf_timer_task_t task)
+{
+ return (uint32_t *)((uint8_t *)p_reg + (uint32_t)task);
+}
+
+__STATIC_INLINE void nrf_timer_event_clear(NRF_TIMER_Type * p_reg,
+ nrf_timer_event_t event)
+{
+ *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
+#if __CORTEX_M == 0x04
+ volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event));
+ (void)dummy;
+#endif
+}
+
+__STATIC_INLINE bool nrf_timer_event_check(NRF_TIMER_Type * p_reg,
+ nrf_timer_event_t event)
+{
+ return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
+}
+
+__STATIC_INLINE uint32_t * nrf_timer_event_address_get(NRF_TIMER_Type * p_reg,
+ nrf_timer_event_t event)
+{
+ return (uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
+}
+
+__STATIC_INLINE void nrf_timer_shorts_enable(NRF_TIMER_Type * p_reg,
+ uint32_t timer_shorts_mask)
+{
+ p_reg->SHORTS |= timer_shorts_mask;
+}
+
+__STATIC_INLINE void nrf_timer_shorts_disable(NRF_TIMER_Type * p_reg,
+ uint32_t timer_shorts_mask)
+{
+ p_reg->SHORTS &= ~(timer_shorts_mask);
+}
+
+__STATIC_INLINE void nrf_timer_int_enable(NRF_TIMER_Type * p_reg,
+ uint32_t timer_int_mask)
+{
+ p_reg->INTENSET = timer_int_mask;
+}
+
+__STATIC_INLINE void nrf_timer_int_disable(NRF_TIMER_Type * p_reg,
+ uint32_t timer_int_mask)
+{
+ p_reg->INTENCLR = timer_int_mask;
+}
+
+__STATIC_INLINE bool nrf_timer_int_enable_check(NRF_TIMER_Type * p_reg,
+ uint32_t timer_int)
+{
+ return (bool)(p_reg->INTENSET & timer_int);
+}
+
+__STATIC_INLINE void nrf_timer_mode_set(NRF_TIMER_Type * p_reg,
+ nrf_timer_mode_t mode)
+{
+ p_reg->MODE = (p_reg->MODE & ~TIMER_MODE_MODE_Msk) |
+ ((mode << TIMER_MODE_MODE_Pos) & TIMER_MODE_MODE_Msk);
+}
+
+__STATIC_INLINE nrf_timer_mode_t nrf_timer_mode_get(NRF_TIMER_Type * p_reg)
+{
+ return (nrf_timer_mode_t)(p_reg->MODE);
+}
+
+__STATIC_INLINE void nrf_timer_bit_width_set(NRF_TIMER_Type * p_reg,
+ nrf_timer_bit_width_t bit_width)
+{
+ p_reg->BITMODE = (p_reg->BITMODE & ~TIMER_BITMODE_BITMODE_Msk) |
+ ((bit_width << TIMER_BITMODE_BITMODE_Pos) &
+ TIMER_BITMODE_BITMODE_Msk);
+}
+
+__STATIC_INLINE nrf_timer_bit_width_t nrf_timer_bit_width_get(NRF_TIMER_Type * p_reg)
+{
+ return (nrf_timer_bit_width_t)(p_reg->BITMODE);
+}
+
+__STATIC_INLINE void nrf_timer_frequency_set(NRF_TIMER_Type * p_reg,
+ nrf_timer_frequency_t frequency)
+{
+ p_reg->PRESCALER = (p_reg->PRESCALER & ~TIMER_PRESCALER_PRESCALER_Msk) |
+ ((frequency << TIMER_PRESCALER_PRESCALER_Pos) &
+ TIMER_PRESCALER_PRESCALER_Msk);
+}
+
+__STATIC_INLINE nrf_timer_frequency_t nrf_timer_frequency_get(NRF_TIMER_Type * p_reg)
+{
+ return (nrf_timer_frequency_t)(p_reg->PRESCALER);
+}
+
+__STATIC_INLINE void nrf_timer_cc_write(NRF_TIMER_Type * p_reg,
+ nrf_timer_cc_channel_t cc_channel,
+ uint32_t cc_value)
+{
+ p_reg->CC[cc_channel] = cc_value;
+}
+
+__STATIC_INLINE uint32_t nrf_timer_cc_read(NRF_TIMER_Type * p_reg,
+ nrf_timer_cc_channel_t cc_channel)
+{
+ return (uint32_t)p_reg->CC[cc_channel];
+}
+
+__STATIC_INLINE nrf_timer_task_t nrf_timer_capture_task_get(uint32_t channel)
+{
+ return (nrf_timer_task_t)
+ ((uint32_t)NRF_TIMER_TASK_CAPTURE0 + (channel * sizeof(uint32_t)));
+}
+
+__STATIC_INLINE nrf_timer_event_t nrf_timer_compare_event_get(uint32_t channel)
+{
+ return (nrf_timer_event_t)
+ ((uint32_t)NRF_TIMER_EVENT_COMPARE0 + (channel * sizeof(uint32_t)));
+}
+
+__STATIC_INLINE nrf_timer_int_mask_t nrf_timer_compare_int_get(uint32_t channel)
+{
+ return (nrf_timer_int_mask_t)
+ ((uint32_t)NRF_TIMER_INT_COMPARE0_MASK << channel);
+}
+
+__STATIC_INLINE uint32_t nrf_timer_us_to_ticks(uint32_t time_us,
+ nrf_timer_frequency_t frequency)
+{
+ // The "frequency" parameter here is actually the prescaler value, and the
+ // timer runs at the following frequency: f = 16 MHz / 2^prescaler.
+ uint32_t prescaler = (uint32_t)frequency;
+ ASSERT(time_us <= (UINT32_MAX / 16UL));
+ return ((time_us * 16UL) >> prescaler);
+}
+
+__STATIC_INLINE uint32_t nrf_timer_ms_to_ticks(uint32_t time_ms,
+ nrf_timer_frequency_t frequency)
+{
+ // The "frequency" parameter here is actually the prescaler value, and the
+ // timer runs at the following frequency: f = 16000 kHz / 2^prescaler.
+ uint32_t prescaler = (uint32_t)frequency;
+ ASSERT(time_ms <= (UINT32_MAX / 16000UL));
+ return ((time_ms * 16000UL) >> prescaler);
+}
+
+#endif // SUPPRESS_INLINE_IMPLEMENTATION
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_TIMER_H__
+
+/** @} */
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_twi.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_twi.h
new file mode 100644
index 000000000..5e80272be
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_twi.h
@@ -0,0 +1,452 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_TWI_H__
+#define NRF_TWI_H__
+
+/**
+ * @defgroup nrf_twi_hal TWI HAL
+ * @{
+ * @ingroup nrf_twi
+ *
+ * @brief Hardware access layer for managing the TWI peripheral.
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+#include "nrf_peripherals.h"
+#include "nrf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief TWI tasks.
+ */
+typedef enum
+{
+ /*lint -save -e30*/
+ NRF_TWI_TASK_STARTRX = offsetof(NRF_TWI_Type, TASKS_STARTRX), ///< Start TWI receive sequence.
+ NRF_TWI_TASK_STARTTX = offsetof(NRF_TWI_Type, TASKS_STARTTX), ///< Start TWI transmit sequence.
+ NRF_TWI_TASK_STOP = offsetof(NRF_TWI_Type, TASKS_STOP), ///< Stop TWI transaction.
+ NRF_TWI_TASK_SUSPEND = offsetof(NRF_TWI_Type, TASKS_SUSPEND), ///< Suspend TWI transaction.
+ NRF_TWI_TASK_RESUME = offsetof(NRF_TWI_Type, TASKS_RESUME) ///< Resume TWI transaction.
+ /*lint -restore*/
+} nrf_twi_task_t;
+
+/**
+ * @brief TWI events.
+ */
+typedef enum
+{
+ /*lint -save -e30*/
+ NRF_TWI_EVENT_STOPPED = offsetof(NRF_TWI_Type, EVENTS_STOPPED), ///< TWI stopped.
+ NRF_TWI_EVENT_RXDREADY = offsetof(NRF_TWI_Type, EVENTS_RXDREADY), ///< TWI RXD byte received.
+ NRF_TWI_EVENT_TXDSENT = offsetof(NRF_TWI_Type, EVENTS_TXDSENT), ///< TWI TXD byte sent.
+ NRF_TWI_EVENT_ERROR = offsetof(NRF_TWI_Type, EVENTS_ERROR), ///< TWI error.
+ NRF_TWI_EVENT_BB = offsetof(NRF_TWI_Type, EVENTS_BB), ///< TWI byte boundary, generated before each byte that is sent or received.
+ NRF_TWI_EVENT_SUSPENDED = offsetof(NRF_TWI_Type, EVENTS_SUSPENDED) ///< TWI entered the suspended state.
+ /*lint -restore*/
+} nrf_twi_event_t;
+
+/**
+ * @brief TWI shortcuts.
+ */
+typedef enum
+{
+ NRF_TWI_SHORT_BB_SUSPEND_MASK = TWI_SHORTS_BB_SUSPEND_Msk, ///< Shortcut between BB event and SUSPEND task.
+ NRF_TWI_SHORT_BB_STOP_MASK = TWI_SHORTS_BB_STOP_Msk, ///< Shortcut between BB event and STOP task.
+} nrf_twi_short_mask_t;
+
+/**
+ * @brief TWI interrupts.
+ */
+typedef enum
+{
+ NRF_TWI_INT_STOPPED_MASK = TWI_INTENSET_STOPPED_Msk, ///< Interrupt on STOPPED event.
+ NRF_TWI_INT_RXDREADY_MASK = TWI_INTENSET_RXDREADY_Msk, ///< Interrupt on RXDREADY event.
+ NRF_TWI_INT_TXDSENT_MASK = TWI_INTENSET_TXDSENT_Msk, ///< Interrupt on TXDSENT event.
+ NRF_TWI_INT_ERROR_MASK = TWI_INTENSET_ERROR_Msk, ///< Interrupt on ERROR event.
+ NRF_TWI_INT_BB_MASK = TWI_INTENSET_BB_Msk, ///< Interrupt on BB event.
+ NRF_TWI_INT_SUSPENDED_MASK = TWI_INTENSET_SUSPENDED_Msk ///< Interrupt on SUSPENDED event.
+} nrf_twi_int_mask_t;
+
+/**
+ * @brief TWI error source.
+ */
+typedef enum
+{
+ NRF_TWI_ERROR_ADDRESS_NACK = TWI_ERRORSRC_ANACK_Msk, ///< NACK received after sending the address.
+ NRF_TWI_ERROR_DATA_NACK = TWI_ERRORSRC_DNACK_Msk, ///< NACK received after sending a data byte.
+ NRF_TWI_ERROR_OVERRUN = TWI_ERRORSRC_OVERRUN_Msk ///< Overrun error.
+ /**< A new byte was received before the previous byte was read
+ * from the RXD register (previous data is lost). */
+} nrf_twi_error_t;
+
+/**
+ * @brief TWI master clock frequency.
+ */
+typedef enum
+{
+ NRF_TWI_FREQ_100K = TWI_FREQUENCY_FREQUENCY_K100, ///< 100 kbps.
+ NRF_TWI_FREQ_250K = TWI_FREQUENCY_FREQUENCY_K250, ///< 250 kbps.
+ NRF_TWI_FREQ_400K = TWI_FREQUENCY_FREQUENCY_K400 ///< 400 kbps.
+} nrf_twi_frequency_t;
+
+
+/**
+ * @brief Function for activating a specific TWI task.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] task Task to activate.
+ */
+__STATIC_INLINE void nrf_twi_task_trigger(NRF_TWI_Type * p_reg,
+ nrf_twi_task_t task);
+
+/**
+ * @brief Function for getting the address of a specific TWI task register.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] task Requested task.
+ *
+ * @return Address of the specified task register.
+ */
+__STATIC_INLINE uint32_t * nrf_twi_task_address_get(NRF_TWI_Type * p_reg,
+ nrf_twi_task_t task);
+
+/**
+ * @brief Function for clearing a specific TWI event.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] event Event to clear.
+ */
+__STATIC_INLINE void nrf_twi_event_clear(NRF_TWI_Type * p_reg,
+ nrf_twi_event_t event);
+
+/**
+ * @brief Function for checking the state of a specific event.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] event Event to check.
+ *
+ * @retval true If the event is set.
+ * @retval false If the event is not set.
+ */
+__STATIC_INLINE bool nrf_twi_event_check(NRF_TWI_Type * p_reg,
+ nrf_twi_event_t event);
+
+/**
+ * @brief Function for getting the address of a specific TWI event register.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] event Requested event.
+ *
+ * @return Address of the specified event register.
+ */
+__STATIC_INLINE uint32_t * nrf_twi_event_address_get(NRF_TWI_Type * p_reg,
+ nrf_twi_event_t event);
+
+/**
+ * @brief Function for enabling specified shortcuts.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] shorts_mask Shortcuts to enable.
+ */
+__STATIC_INLINE void nrf_twi_shorts_enable(NRF_TWI_Type * p_reg,
+ uint32_t shorts_mask);
+
+/**
+ * @brief Function for disabling specified shortcuts.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] shorts_mask Shortcuts to disable.
+ */
+__STATIC_INLINE void nrf_twi_shorts_disable(NRF_TWI_Type * p_reg,
+ uint32_t shorts_mask);
+
+/**
+ * @brief Function for enabling specified interrupts.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] int_mask Interrupts to enable.
+ */
+__STATIC_INLINE void nrf_twi_int_enable(NRF_TWI_Type * p_reg,
+ uint32_t int_mask);
+
+/**
+ * @brief Function for disabling specified interrupts.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] int_mask Interrupts to disable.
+ */
+__STATIC_INLINE void nrf_twi_int_disable(NRF_TWI_Type * p_reg,
+ uint32_t int_mask);
+
+/**
+ * @brief Function for retrieving the state of a given interrupt.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] int_mask Interrupt to check.
+ *
+ * @retval true If the interrupt is enabled.
+ * @retval false If the interrupt is not enabled.
+ */
+__STATIC_INLINE bool nrf_twi_int_enable_check(NRF_TWI_Type * p_reg,
+ nrf_twi_int_mask_t int_mask);
+
+/**
+ * @brief Function for enabling the TWI peripheral.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE void nrf_twi_enable(NRF_TWI_Type * p_reg);
+
+/**
+ * @brief Function for disabling the TWI peripheral.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE void nrf_twi_disable(NRF_TWI_Type * p_reg);
+
+/**
+ * @brief Function for configuring TWI pins.
+ *
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] scl_pin SCL pin number.
+ * @param[in] sda_pin SDA pin number.
+ */
+__STATIC_INLINE void nrf_twi_pins_set(NRF_TWI_Type * p_reg,
+ uint32_t scl_pin,
+ uint32_t sda_pin);
+
+/**
+ * @brief Function for setting the TWI master clock frequency.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] frequency TWI frequency.
+ */
+__STATIC_INLINE void nrf_twi_frequency_set(NRF_TWI_Type * p_reg,
+ nrf_twi_frequency_t frequency);
+
+/**
+ * @brief Function for checking the TWI error source.
+ *
+ * The error flags are cleared after reading.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ *
+ * @return Mask with error source flags.
+ */
+__STATIC_INLINE uint32_t nrf_twi_errorsrc_get_and_clear(NRF_TWI_Type * p_reg);
+
+/**
+ * @brief Function for setting the address to be used in TWI transfers.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] address Address to be used in transfers.
+ */
+__STATIC_INLINE void nrf_twi_address_set(NRF_TWI_Type * p_reg, uint8_t address);
+
+/**
+ * @brief Function for reading data received by TWI.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ *
+ * @return Received data.
+ */
+__STATIC_INLINE uint8_t nrf_twi_rxd_get(NRF_TWI_Type * p_reg);
+
+/**
+ * @brief Function for writing data to be transmitted by TWI.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] data Data to be transmitted.
+ */
+__STATIC_INLINE void nrf_twi_txd_set(NRF_TWI_Type * p_reg, uint8_t data);
+
+__STATIC_INLINE void nrf_twi_shorts_set(NRF_TWI_Type * p_reg,
+ uint32_t shorts_mask);
+
+/**
+ * @}
+ */
+
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE void nrf_twi_task_trigger(NRF_TWI_Type * p_reg,
+ nrf_twi_task_t task)
+{
+ *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
+}
+
+__STATIC_INLINE uint32_t * nrf_twi_task_address_get(NRF_TWI_Type * p_reg,
+ nrf_twi_task_t task)
+{
+ return (uint32_t *)((uint8_t *)p_reg + (uint32_t)task);
+}
+
+__STATIC_INLINE void nrf_twi_event_clear(NRF_TWI_Type * p_reg,
+ nrf_twi_event_t event)
+{
+ *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
+#if __CORTEX_M == 0x04
+ volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event));
+ (void)dummy;
+#endif
+}
+
+__STATIC_INLINE bool nrf_twi_event_check(NRF_TWI_Type * p_reg,
+ nrf_twi_event_t event)
+{
+ return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
+}
+
+__STATIC_INLINE uint32_t * nrf_twi_event_address_get(NRF_TWI_Type * p_reg,
+ nrf_twi_event_t event)
+{
+ return (uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
+}
+
+__STATIC_INLINE void nrf_twi_shorts_enable(NRF_TWI_Type * p_reg,
+ uint32_t shorts_mask)
+{
+ p_reg->SHORTS |= shorts_mask;
+}
+
+__STATIC_INLINE void nrf_twi_shorts_disable(NRF_TWI_Type * p_reg,
+ uint32_t shorts_mask)
+{
+ p_reg->SHORTS &= ~(shorts_mask);
+}
+
+__STATIC_INLINE void nrf_twi_int_enable(NRF_TWI_Type * p_reg,
+ uint32_t int_mask)
+{
+ p_reg->INTENSET = int_mask;
+}
+
+__STATIC_INLINE void nrf_twi_int_disable(NRF_TWI_Type * p_reg,
+ uint32_t int_mask)
+{
+ p_reg->INTENCLR = int_mask;
+}
+
+__STATIC_INLINE bool nrf_twi_int_enable_check(NRF_TWI_Type * p_reg,
+ nrf_twi_int_mask_t int_mask)
+{
+ return (bool)(p_reg->INTENSET & int_mask);
+}
+
+__STATIC_INLINE void nrf_twi_enable(NRF_TWI_Type * p_reg)
+{
+ p_reg->ENABLE = (TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos);
+}
+
+__STATIC_INLINE void nrf_twi_disable(NRF_TWI_Type * p_reg)
+{
+ p_reg->ENABLE = (TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos);
+}
+
+__STATIC_INLINE void nrf_twi_pins_set(NRF_TWI_Type * p_reg,
+ uint32_t scl_pin,
+ uint32_t sda_pin)
+{
+#if defined(TWI_PSEL_SCL_CONNECT_Pos)
+ p_reg->PSEL.SCL = scl_pin;
+#else
+ p_reg->PSELSCL = scl_pin;
+#endif
+
+#if defined(TWI_PSEL_SDA_CONNECT_Pos)
+ p_reg->PSEL.SDA = sda_pin;
+#else
+ p_reg->PSELSDA = sda_pin;
+#endif
+}
+
+__STATIC_INLINE void nrf_twi_frequency_set(NRF_TWI_Type * p_reg,
+ nrf_twi_frequency_t frequency)
+{
+ p_reg->FREQUENCY = frequency;
+}
+
+__STATIC_INLINE uint32_t nrf_twi_errorsrc_get_and_clear(NRF_TWI_Type * p_reg)
+{
+ uint32_t error_source = p_reg->ERRORSRC;
+
+ // [error flags are cleared by writing '1' on their position]
+ p_reg->ERRORSRC = error_source;
+
+ return error_source;
+}
+
+__STATIC_INLINE void nrf_twi_address_set(NRF_TWI_Type * p_reg, uint8_t address)
+{
+ p_reg->ADDRESS = address;
+}
+
+__STATIC_INLINE uint8_t nrf_twi_rxd_get(NRF_TWI_Type * p_reg)
+{
+ return (uint8_t)p_reg->RXD;
+}
+
+__STATIC_INLINE void nrf_twi_txd_set(NRF_TWI_Type * p_reg, uint8_t data)
+{
+ p_reg->TXD = data;
+}
+
+__STATIC_INLINE void nrf_twi_shorts_set(NRF_TWI_Type * p_reg,
+ uint32_t shorts_mask)
+{
+ p_reg->SHORTS = shorts_mask;
+}
+
+#endif // SUPPRESS_INLINE_IMPLEMENTATION
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_TWI_H__
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_twim.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_twim.h
new file mode 100644
index 000000000..73d790efb
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_twim.h
@@ -0,0 +1,527 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_TWIM_H__
+#define NRF_TWIM_H__
+
+/**
+ * @defgroup nrf_twim_hal TWIM HAL
+ * @{
+ * @ingroup nrf_twi
+ *
+ * @brief Hardware access layer for managing the TWIM peripheral.
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+#include "nrf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief TWIM tasks.
+ */
+typedef enum
+{
+ /*lint -save -e30*/
+ NRF_TWIM_TASK_STARTRX = offsetof(NRF_TWIM_Type, TASKS_STARTRX), ///< Start TWI receive sequence.
+ NRF_TWIM_TASK_STARTTX = offsetof(NRF_TWIM_Type, TASKS_STARTTX), ///< Start TWI transmit sequence.
+ NRF_TWIM_TASK_STOP = offsetof(NRF_TWIM_Type, TASKS_STOP), ///< Stop TWI transaction.
+ NRF_TWIM_TASK_SUSPEND = offsetof(NRF_TWIM_Type, TASKS_SUSPEND), ///< Suspend TWI transaction.
+ NRF_TWIM_TASK_RESUME = offsetof(NRF_TWIM_Type, TASKS_RESUME) ///< Resume TWI transaction.
+ /*lint -restore*/
+} nrf_twim_task_t;
+
+/**
+ * @brief TWIM events.
+ */
+typedef enum
+{
+ /*lint -save -e30*/
+ NRF_TWIM_EVENT_STOPPED = offsetof(NRF_TWIM_Type, EVENTS_STOPPED), ///< TWI stopped.
+ NRF_TWIM_EVENT_ERROR = offsetof(NRF_TWIM_Type, EVENTS_ERROR), ///< TWI error.
+ NRF_TWIM_EVENT_SUSPENDED = 0x148, ///< TWI suspended.
+ NRF_TWIM_EVENT_RXSTARTED = offsetof(NRF_TWIM_Type, EVENTS_RXSTARTED), ///< Receive sequence started.
+ NRF_TWIM_EVENT_TXSTARTED = offsetof(NRF_TWIM_Type, EVENTS_TXSTARTED), ///< Transmit sequence started.
+ NRF_TWIM_EVENT_LASTRX = offsetof(NRF_TWIM_Type, EVENTS_LASTRX), ///< Byte boundary, starting to receive the last byte.
+ NRF_TWIM_EVENT_LASTTX = offsetof(NRF_TWIM_Type, EVENTS_LASTTX) ///< Byte boundary, starting to transmit the last byte.
+ /*lint -restore*/
+} nrf_twim_event_t;
+
+/**
+ * @brief TWIM shortcuts.
+ */
+typedef enum
+{
+ NRF_TWIM_SHORT_LASTTX_STARTRX_MASK = TWIM_SHORTS_LASTTX_STARTRX_Msk, ///< Shortcut between LASTTX event and STARTRX task.
+ NRF_TWIM_SHORT_LASTTX_SUSPEND_MASK = TWIM_SHORTS_LASTTX_SUSPEND_Msk, ///< Shortcut between LASTTX event and SUSPEND task.
+ NRF_TWIM_SHORT_LASTTX_STOP_MASK = TWIM_SHORTS_LASTTX_STOP_Msk, ///< Shortcut between LASTTX event and STOP task.
+ NRF_TWIM_SHORT_LASTRX_STARTTX_MASK = TWIM_SHORTS_LASTRX_STARTTX_Msk, ///< Shortcut between LASTRX event and STARTTX task.
+ NRF_TWIM_SHORT_LASTRX_STOP_MASK = TWIM_SHORTS_LASTRX_STOP_Msk ///< Shortcut between LASTRX event and STOP task.
+} nrf_twim_short_mask_t;
+
+/**
+ * @brief TWIM interrupts.
+ */
+typedef enum
+{
+ NRF_TWIM_INT_STOPPED_MASK = TWIM_INTENSET_STOPPED_Msk, ///< Interrupt on STOPPED event.
+ NRF_TWIM_INT_ERROR_MASK = TWIM_INTENSET_ERROR_Msk, ///< Interrupt on ERROR event.
+ NRF_TWIM_INT_SUSPENDED_MASK = (1 << 18), ///< Interrupt on SUSPENDED event.
+ NRF_TWIM_INT_RXSTARTED_MASK = TWIM_INTENSET_RXSTARTED_Msk, ///< Interrupt on RXSTARTED event.
+ NRF_TWIM_INT_TXSTARTED_MASK = TWIM_INTENSET_TXSTARTED_Msk, ///< Interrupt on TXSTARTED event.
+ NRF_TWIM_INT_LASTRX_MASK = TWIM_INTENSET_LASTRX_Msk, ///< Interrupt on LASTRX event.
+ NRF_TWIM_INT_LASTTX_MASK = TWIM_INTENSET_LASTTX_Msk ///< Interrupt on LASTTX event.
+} nrf_twim_int_mask_t;
+
+/**
+ * @brief TWIM master clock frequency.
+ */
+typedef enum
+{
+ NRF_TWIM_FREQ_100K = TWIM_FREQUENCY_FREQUENCY_K100, ///< 100 kbps.
+ NRF_TWIM_FREQ_250K = TWIM_FREQUENCY_FREQUENCY_K250, ///< 250 kbps.
+ NRF_TWIM_FREQ_400K = TWIM_FREQUENCY_FREQUENCY_K400, ///< 400 kbps.
+#ifndef TWI_PRESENT
+ NRF_TWI_FREQ_100K = NRF_TWIM_FREQ_100K,
+ NRF_TWI_FREQ_250K = NRF_TWIM_FREQ_250K,
+ NRF_TWI_FREQ_400K = NRF_TWIM_FREQ_400K,
+#endif
+} nrf_twim_frequency_t;
+
+/**
+ * @brief TWIM error source.
+ */
+typedef enum
+{
+ NRF_TWIM_ERROR_ADDRESS_NACK = TWIM_ERRORSRC_ANACK_Msk, ///< NACK received after sending the address.
+ NRF_TWIM_ERROR_DATA_NACK = TWIM_ERRORSRC_DNACK_Msk, ///< NACK received after sending a data byte.
+#ifndef TWI_PRESENT
+ NRF_TWI_ERROR_ADDRESS_NACK = NRF_TWIM_ERROR_ADDRESS_NACK,
+ NRF_TWI_ERROR_DATA_NACK = NRF_TWIM_ERROR_DATA_NACK,
+#endif
+} nrf_twim_error_t;
+
+
+/**
+ * @brief Function for activating a specific TWIM task.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] task Task to activate.
+ */
+__STATIC_INLINE void nrf_twim_task_trigger(NRF_TWIM_Type * p_reg,
+ nrf_twim_task_t task);
+
+/**
+ * @brief Function for getting the address of a specific TWIM task register.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] task Requested task.
+ *
+ * @return Address of the specified task register.
+ */
+__STATIC_INLINE uint32_t * nrf_twim_task_address_get(NRF_TWIM_Type * p_reg,
+ nrf_twim_task_t task);
+
+/**
+ * @brief Function for clearing a specific TWIM event.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] event Event to clear.
+ */
+__STATIC_INLINE void nrf_twim_event_clear(NRF_TWIM_Type * p_reg,
+ nrf_twim_event_t event);
+
+/**
+ * @brief Function for checking the state of a specific TWIM event.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] event Event to check.
+ *
+ * @retval true If the event is set.
+ * @retval false If the event is not set.
+ */
+__STATIC_INLINE bool nrf_twim_event_check(NRF_TWIM_Type * p_reg,
+ nrf_twim_event_t event);
+
+/**
+ * @brief Function for getting the address of a specific TWIM event register.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] event Requested event.
+ *
+ * @return Address of the specified event register.
+ */
+__STATIC_INLINE uint32_t * nrf_twim_event_address_get(NRF_TWIM_Type * p_reg,
+ nrf_twim_event_t event);
+
+/**
+ * @brief Function for enabling specified shortcuts.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] shorts_mask Shortcuts to enable.
+ */
+__STATIC_INLINE void nrf_twim_shorts_enable(NRF_TWIM_Type * p_reg,
+ uint32_t shorts_mask);
+
+/**
+ * @brief Function for disabling specified shortcuts.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] shorts_mask Shortcuts to disable.
+ */
+__STATIC_INLINE void nrf_twim_shorts_disable(NRF_TWIM_Type * p_reg,
+ uint32_t shorts_mask);
+
+/**
+ * @brief Function for enabling specified interrupts.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] int_mask Interrupts to enable.
+ */
+__STATIC_INLINE void nrf_twim_int_enable(NRF_TWIM_Type * p_reg,
+ uint32_t int_mask);
+
+/**
+ * @brief Function for disabling specified interrupts.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] int_mask Interrupts to disable.
+ */
+__STATIC_INLINE void nrf_twim_int_disable(NRF_TWIM_Type * p_reg,
+ uint32_t int_mask);
+
+/**
+ * @brief Function for checking the state of a given interrupt.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] int_mask Interrupt to check.
+ *
+ * @retval true If the interrupt is enabled.
+ * @retval false If the interrupt is not enabled.
+ */
+__STATIC_INLINE bool nrf_twim_int_enable_check(NRF_TWIM_Type * p_reg,
+ nrf_twim_int_mask_t int_mask);
+
+/**
+ * @brief Function for enabling the TWIM peripheral.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE void nrf_twim_enable(NRF_TWIM_Type * p_reg);
+
+/**
+ * @brief Function for disabling the TWIM peripheral.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE void nrf_twim_disable(NRF_TWIM_Type * p_reg);
+
+/**
+ * @brief Function for configuring TWI pins.
+ *
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] scl_pin SCL pin number.
+ * @param[in] sda_pin SDA pin number.
+ */
+__STATIC_INLINE void nrf_twim_pins_set(NRF_TWIM_Type * p_reg,
+ uint32_t scl_pin,
+ uint32_t sda_pin);
+
+/**
+ * @brief Function for setting the TWI master clock frequency.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] frequency TWI frequency.
+ */
+__STATIC_INLINE void nrf_twim_frequency_set(NRF_TWIM_Type * p_reg,
+ nrf_twim_frequency_t frequency);
+
+/**
+ * @brief Function for checking the TWI error source.
+ *
+ * The error flags are cleared after reading.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ *
+ * @return Mask with error source flags.
+ */
+__STATIC_INLINE uint32_t nrf_twim_errorsrc_get_and_clear(NRF_TWIM_Type * p_reg);
+
+/**
+ * @brief Function for setting the address to be used in TWI transfers.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] address Address to be used in transfers.
+ */
+__STATIC_INLINE void nrf_twim_address_set(NRF_TWIM_Type * p_reg,
+ uint8_t address);
+
+/**
+ * @brief Function for setting the transmit buffer.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] p_buffer Pointer to the buffer with data to send.
+ * @param[in] length Maximum number of data bytes to transmit.
+ */
+__STATIC_INLINE void nrf_twim_tx_buffer_set(NRF_TWIM_Type * p_reg,
+ uint8_t const * p_buffer,
+ uint8_t length);
+
+/**
+ * @brief Function for setting the receive buffer.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] p_buffer Pointer to the buffer for received data.
+ * @param[in] length Maximum number of data bytes to receive.
+ */
+__STATIC_INLINE void nrf_twim_rx_buffer_set(NRF_TWIM_Type * p_reg,
+ uint8_t * p_buffer,
+ uint8_t length);
+
+__STATIC_INLINE void nrf_twim_shorts_set(NRF_TWIM_Type * p_reg,
+ uint32_t shorts_mask);
+
+__STATIC_INLINE uint32_t nrf_twim_txd_amount_get(NRF_TWIM_Type * p_reg);
+
+__STATIC_INLINE uint32_t nrf_twim_rxd_amount_get(NRF_TWIM_Type * p_reg);
+
+/**
+ * @brief Function for enabling the TX list feature.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE void nrf_twim_tx_list_enable(NRF_TWIM_Type * p_reg);
+
+/**
+ * @brief Function for disabling the TX list feature.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE void nrf_twim_tx_list_disable(NRF_TWIM_Type * p_reg);
+
+/**
+ * @brief Function for enabling the RX list feature.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE void nrf_twim_rx_list_enable(NRF_TWIM_Type * p_reg);
+
+/**
+ * @brief Function for disabling the RX list feature.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE void nrf_twim_rx_list_disable(NRF_TWIM_Type * p_reg);
+
+/**
+ * @}
+ */
+
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE void nrf_twim_task_trigger(NRF_TWIM_Type * p_reg,
+ nrf_twim_task_t task)
+{
+ *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
+}
+
+__STATIC_INLINE uint32_t * nrf_twim_task_address_get(NRF_TWIM_Type * p_reg,
+ nrf_twim_task_t task)
+{
+ return (uint32_t *)((uint8_t *)p_reg + (uint32_t)task);
+}
+
+__STATIC_INLINE void nrf_twim_event_clear(NRF_TWIM_Type * p_reg,
+ nrf_twim_event_t event)
+{
+ *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
+#if __CORTEX_M == 0x04
+ volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event));
+ (void)dummy;
+#endif
+}
+
+__STATIC_INLINE bool nrf_twim_event_check(NRF_TWIM_Type * p_reg,
+ nrf_twim_event_t event)
+{
+ return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
+}
+
+__STATIC_INLINE uint32_t * nrf_twim_event_address_get(NRF_TWIM_Type * p_reg,
+ nrf_twim_event_t event)
+{
+ return (uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
+}
+
+__STATIC_INLINE void nrf_twim_shorts_enable(NRF_TWIM_Type * p_reg,
+ uint32_t shorts_mask)
+{
+ p_reg->SHORTS |= shorts_mask;
+}
+
+__STATIC_INLINE void nrf_twim_shorts_disable(NRF_TWIM_Type * p_reg,
+ uint32_t shorts_mask)
+{
+ p_reg->SHORTS &= ~(shorts_mask);
+}
+
+__STATIC_INLINE void nrf_twim_int_enable(NRF_TWIM_Type * p_reg,
+ uint32_t int_mask)
+{
+ p_reg->INTENSET = int_mask;
+}
+
+__STATIC_INLINE void nrf_twim_int_disable(NRF_TWIM_Type * p_reg,
+ uint32_t int_mask)
+{
+ p_reg->INTENCLR = int_mask;
+}
+
+__STATIC_INLINE bool nrf_twim_int_enable_check(NRF_TWIM_Type * p_reg,
+ nrf_twim_int_mask_t int_mask)
+{
+ return (bool)(p_reg->INTENSET & int_mask);
+}
+
+__STATIC_INLINE void nrf_twim_enable(NRF_TWIM_Type * p_reg)
+{
+ p_reg->ENABLE = (TWIM_ENABLE_ENABLE_Enabled << TWIM_ENABLE_ENABLE_Pos);
+}
+
+__STATIC_INLINE void nrf_twim_disable(NRF_TWIM_Type * p_reg)
+{
+ p_reg->ENABLE = (TWIM_ENABLE_ENABLE_Disabled << TWIM_ENABLE_ENABLE_Pos);
+}
+
+__STATIC_INLINE void nrf_twim_pins_set(NRF_TWIM_Type * p_reg,
+ uint32_t scl_pin,
+ uint32_t sda_pin)
+{
+ p_reg->PSEL.SCL = scl_pin;
+ p_reg->PSEL.SDA = sda_pin;
+}
+
+__STATIC_INLINE void nrf_twim_frequency_set(NRF_TWIM_Type * p_reg,
+ nrf_twim_frequency_t frequency)
+{
+ p_reg->FREQUENCY = frequency;
+}
+
+__STATIC_INLINE uint32_t nrf_twim_errorsrc_get_and_clear(NRF_TWIM_Type * p_reg)
+{
+ uint32_t error_source = p_reg->ERRORSRC;
+
+ // [error flags are cleared by writing '1' on their position]
+ p_reg->ERRORSRC = error_source;
+
+ return error_source;
+}
+
+__STATIC_INLINE void nrf_twim_address_set(NRF_TWIM_Type * p_reg,
+ uint8_t address)
+{
+ p_reg->ADDRESS = address;
+}
+
+__STATIC_INLINE void nrf_twim_tx_buffer_set(NRF_TWIM_Type * p_reg,
+ uint8_t const * p_buffer,
+ uint8_t length)
+{
+ p_reg->TXD.PTR = (uint32_t)p_buffer;
+ p_reg->TXD.MAXCNT = length;
+}
+
+__STATIC_INLINE void nrf_twim_rx_buffer_set(NRF_TWIM_Type * p_reg,
+ uint8_t * p_buffer,
+ uint8_t length)
+{
+ p_reg->RXD.PTR = (uint32_t)p_buffer;
+ p_reg->RXD.MAXCNT = length;
+}
+
+__STATIC_INLINE void nrf_twim_shorts_set(NRF_TWIM_Type * p_reg,
+ uint32_t shorts_mask)
+{
+ p_reg->SHORTS = shorts_mask;
+}
+
+__STATIC_INLINE uint32_t nrf_twim_txd_amount_get(NRF_TWIM_Type * p_reg)
+{
+ return p_reg->TXD.AMOUNT;
+}
+
+__STATIC_INLINE uint32_t nrf_twim_rxd_amount_get(NRF_TWIM_Type * p_reg)
+{
+ return p_reg->RXD.AMOUNT;
+}
+
+__STATIC_INLINE void nrf_twim_tx_list_enable(NRF_TWIM_Type * p_reg)
+{
+ p_reg->TXD.LIST = 1;
+}
+
+__STATIC_INLINE void nrf_twim_tx_list_disable(NRF_TWIM_Type * p_reg)
+{
+ p_reg->TXD.LIST = 0;
+}
+
+__STATIC_INLINE void nrf_twim_rx_list_enable(NRF_TWIM_Type * p_reg)
+{
+ p_reg->RXD.LIST = 1;
+}
+
+__STATIC_INLINE void nrf_twim_rx_list_disable(NRF_TWIM_Type * p_reg)
+{
+ p_reg->RXD.LIST = 0;
+}
+#endif // SUPPRESS_INLINE_IMPLEMENTATION
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_TWIM_H__
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_twis.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_twis.h
new file mode 100644
index 000000000..3cd56d6ce
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_twis.h
@@ -0,0 +1,706 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/**
+ * @ingroup nrf_twis
+ * @defgroup nrf_twis_hal TWIS HAL
+ * @{
+ *
+ * @brief @tagAPI52 Hardware access layer for Two Wire Interface Slave with EasyDMA
+ * (TWIS) peripheral.
+ */
+#ifndef NRF_TWIS_H__
+#define NRF_TWIS_H__
+
+#include "nrf.h"
+#include "sdk_config.h"
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief TWIS tasks
+ */
+typedef enum
+{
+ /*lint -save -e30*/
+ NRF_TWIS_TASK_STOP = offsetof(NRF_TWIS_Type, TASKS_STOP), /**< Stop TWIS transaction */
+ NRF_TWIS_TASK_SUSPEND = offsetof(NRF_TWIS_Type, TASKS_SUSPEND), /**< Suspend TWIS transaction */
+ NRF_TWIS_TASK_RESUME = offsetof(NRF_TWIS_Type, TASKS_RESUME), /**< Resume TWIS transaction */
+ NRF_TWIS_TASK_PREPARERX = offsetof(NRF_TWIS_Type, TASKS_PREPARERX), /**< Prepare the TWIS slave to respond to a write command */
+ NRF_TWIS_TASK_PREPARETX = offsetof(NRF_TWIS_Type, TASKS_PREPARETX) /**< Prepare the TWIS slave to respond to a read command */
+ /*lint -restore*/
+} nrf_twis_task_t;
+
+/**
+ * @brief TWIS events
+ */
+typedef enum
+{
+ /*lint -save -e30*/
+ NRF_TWIS_EVENT_STOPPED = offsetof(NRF_TWIS_Type, EVENTS_STOPPED), /**< TWIS stopped */
+ NRF_TWIS_EVENT_ERROR = offsetof(NRF_TWIS_Type, EVENTS_ERROR), /**< TWIS error */
+ NRF_TWIS_EVENT_RXSTARTED = offsetof(NRF_TWIS_Type, EVENTS_RXSTARTED), /**< Receive sequence started */
+ NRF_TWIS_EVENT_TXSTARTED = offsetof(NRF_TWIS_Type, EVENTS_TXSTARTED), /**< Transmit sequence started */
+ NRF_TWIS_EVENT_WRITE = offsetof(NRF_TWIS_Type, EVENTS_WRITE), /**< Write command received */
+ NRF_TWIS_EVENT_READ = offsetof(NRF_TWIS_Type, EVENTS_READ) /**< Read command received */
+ /*lint -restore*/
+} nrf_twis_event_t;
+
+/**
+ * @brief TWIS shortcuts
+ */
+typedef enum
+{
+ NRF_TWIS_SHORT_WRITE_SUSPEND_MASK = TWIS_SHORTS_WRITE_SUSPEND_Msk, /**< Shortcut between WRITE event and SUSPEND task */
+ NRF_TWIS_SHORT_READ_SUSPEND_MASK = TWIS_SHORTS_READ_SUSPEND_Msk, /**< Shortcut between READ event and SUSPEND task */
+} nrf_twis_short_mask_t;
+
+/**
+ * @brief TWIS interrupts
+ */
+typedef enum
+{
+ NRF_TWIS_INT_STOPPED_MASK = TWIS_INTEN_STOPPED_Msk, /**< Interrupt on STOPPED event */
+ NRF_TWIS_INT_ERROR_MASK = TWIS_INTEN_ERROR_Msk, /**< Interrupt on ERROR event */
+ NRF_TWIS_INT_RXSTARTED_MASK = TWIS_INTEN_RXSTARTED_Msk, /**< Interrupt on RXSTARTED event */
+ NRF_TWIS_INT_TXSTARTED_MASK = TWIS_INTEN_TXSTARTED_Msk, /**< Interrupt on TXSTARTED event */
+ NRF_TWIS_INT_WRITE_MASK = TWIS_INTEN_WRITE_Msk, /**< Interrupt on WRITE event */
+ NRF_TWIS_INT_READ_MASK = TWIS_INTEN_READ_Msk, /**< Interrupt on READ event */
+} nrf_twis_int_mask_t;
+
+/**
+ * @brief TWIS error source
+ */
+typedef enum
+{
+ NRF_TWIS_ERROR_OVERFLOW = TWIS_ERRORSRC_OVERFLOW_Msk, /**< RX buffer overflow detected, and prevented */
+ NRF_TWIS_ERROR_DATA_NACK = TWIS_ERRORSRC_DNACK_Msk, /**< NACK sent after receiving a data byte */
+ NRF_TWIS_ERROR_OVERREAD = TWIS_ERRORSRC_OVERREAD_Msk /**< TX buffer over-read detected, and prevented */
+} nrf_twis_error_t;
+
+/**
+ * @brief TWIS address matching configuration
+ */
+typedef enum
+{
+ NRF_TWIS_CONFIG_ADDRESS0_MASK = TWIS_CONFIG_ADDRESS0_Msk, /**< Enable or disable address matching on ADDRESS[0] */
+ NRF_TWIS_CONFIG_ADDRESS1_MASK = TWIS_CONFIG_ADDRESS1_Msk, /**< Enable or disable address matching on ADDRESS[1] */
+ NRF_TWIS_CONFIG_ADDRESS01_MASK = TWIS_CONFIG_ADDRESS0_Msk | TWIS_CONFIG_ADDRESS1_Msk /**< Enable both address matching */
+} nrf_twis_config_addr_mask_t;
+
+/**
+ * @brief Variable type to hold amount of data for EasyDMA
+ *
+ * Variable of the minimum size that can hold the amount of data to transfer.
+ *
+ * @note
+ * Defined to make it simple to change if EasyDMA would be updated to support more data in
+ * the future devices to.
+ */
+typedef uint8_t nrf_twis_amount_t;
+
+/**
+ * @brief Smallest variable type to hold TWI address
+ *
+ * Variable of the minimum size that can hold single TWI address.
+ *
+ * @note
+ * Defined to make it simple to change if new TWI would support for example
+ * 10 bit addressing mode.
+ */
+typedef uint8_t nrf_twis_address_t;
+
+
+/**
+ * @brief Function for activating a specific TWIS task.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param task Task.
+ */
+__STATIC_INLINE void nrf_twis_task_trigger(NRF_TWIS_Type * const p_reg, nrf_twis_task_t task);
+
+/**
+ * @brief Function for returning the address of a specific TWIS task register.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param task Task.
+ *
+ * @return Task address.
+ */
+__STATIC_INLINE uint32_t nrf_twis_task_address_get(
+ NRF_TWIS_Type const * const p_reg,
+ nrf_twis_task_t task);
+
+/**
+ * @brief Function for clearing a specific event.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param event Event.
+ */
+__STATIC_INLINE void nrf_twis_event_clear(
+ NRF_TWIS_Type * const p_reg,
+ nrf_twis_event_t event);
+/**
+ * @brief Function for returning the state of a specific event.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param event Event.
+ *
+ * @retval true If the event is set.
+ * @retval false If the event is not set.
+ */
+__STATIC_INLINE bool nrf_twis_event_check(
+ NRF_TWIS_Type const * const p_reg,
+ nrf_twis_event_t event);
+
+
+/**
+ * @brief Function for getting and clearing the state of specific event
+ *
+ * This function checks the state of the event and clears it.
+ * @param[in,out] p_reg Pointer to the peripheral registers structure.
+ * @param event Event.
+ *
+ * @retval true If the event was set.
+ * @retval false If the event was not set.
+ */
+__STATIC_INLINE bool nrf_twis_event_get_and_clear(
+ NRF_TWIS_Type * const p_reg,
+ nrf_twis_event_t event);
+
+
+/**
+ * @brief Function for returning the address of a specific TWIS event register.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param event Event.
+ *
+ * @return Address.
+ */
+__STATIC_INLINE uint32_t nrf_twis_event_address_get(
+ NRF_TWIS_Type const * const p_reg,
+ nrf_twis_event_t event);
+
+/**
+ * @brief Function for setting a shortcut.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param short_mask Shortcuts mask.
+ */
+__STATIC_INLINE void nrf_twis_shorts_enable(NRF_TWIS_Type * const p_reg, uint32_t short_mask);
+
+/**
+ * @brief Function for clearing shortcuts.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param short_mask Shortcuts mask.
+ */
+__STATIC_INLINE void nrf_twis_shorts_disable(NRF_TWIS_Type * const p_reg, uint32_t short_mask);
+
+/**
+ * @brief Get the shorts mask
+ *
+ * Function returns shorts register.
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @return Flags of currently enabled shortcuts
+ */
+__STATIC_INLINE uint32_t nrf_twis_shorts_get(NRF_TWIS_Type * const p_reg);
+
+/**
+ * @brief Function for enabling selected interrupts.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param int_mask Interrupts mask.
+ */
+__STATIC_INLINE void nrf_twis_int_enable(NRF_TWIS_Type * const p_reg, uint32_t int_mask);
+
+/**
+ * @brief Function for retrieving the state of selected interrupts.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param int_mask Interrupts mask.
+ *
+ * @retval true If any of selected interrupts is enabled.
+ * @retval false If none of selected interrupts is enabled.
+ */
+__STATIC_INLINE bool nrf_twis_int_enable_check(NRF_TWIS_Type const * const p_reg, uint32_t int_mask);
+
+/**
+ * @brief Function for disabling selected interrupts.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param int_mask Interrupts mask.
+ */
+__STATIC_INLINE void nrf_twis_int_disable(NRF_TWIS_Type * const p_reg, uint32_t int_mask);
+
+/**
+ * @brief Function for retrieving and clearing the TWIS error source.
+ *
+ * @attention Error sources are cleared after read.
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @return Error source mask with values from @ref nrf_twis_error_t.
+ */
+__STATIC_INLINE uint32_t nrf_twis_error_source_get_and_clear(NRF_TWIS_Type * const p_reg);
+
+/**
+ * @brief Get information which of addresses matched
+ *
+ * Function returns index in the address table
+ * that points to the address that already matched.
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @return Index of matched address
+ */
+__STATIC_INLINE uint_fast8_t nrf_twis_match_get(NRF_TWIS_Type const * p_reg);
+
+/**
+ * @brief Function for enabling TWIS.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE void nrf_twis_enable(NRF_TWIS_Type * const p_reg);
+
+/**
+ * @brief Function for disabling TWIS.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE void nrf_twis_disable(NRF_TWIS_Type * const p_reg);
+
+/**
+ * @brief Function for configuring TWIS pins.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param scl SCL pin number.
+ * @param sda SDA pin number.
+ */
+__STATIC_INLINE void nrf_twis_pins_set(NRF_TWIS_Type * const p_reg, uint32_t scl, uint32_t sda);
+
+/**
+ * @brief Function for setting the receive buffer.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param p_buf Pointer to the buffer for received data.
+ * @param length Maximum number of data bytes to receive.
+ */
+__STATIC_INLINE void nrf_twis_rx_buffer_set(
+ NRF_TWIS_Type * const p_reg,
+ uint8_t * p_buf,
+ nrf_twis_amount_t length);
+
+/**
+ * @brief Function that prepares TWIS for receiving
+ *
+ * This function sets receive buffer and then sets NRF_TWIS_TASK_PREPARERX task.
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param p_buf Pointer to the buffer for received data.
+ * @param length Maximum number of data bytes to receive.
+ */
+__STATIC_INLINE void nrf_twis_rx_prepare(
+ NRF_TWIS_Type * const p_reg,
+ uint8_t * p_buf,
+ nrf_twis_amount_t length);
+
+/**
+ * @brief Function for getting number of bytes received in the last transaction.
+ *
+ * @param[in] p_reg TWIS instance.
+ * @return Amount of bytes received.
+ * */
+__STATIC_INLINE nrf_twis_amount_t nrf_twis_rx_amount_get(NRF_TWIS_Type const * const p_reg);
+
+/**
+ * @brief Function for setting the transmit buffer.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param p_buf Pointer to the buffer with data to send.
+ * @param length Maximum number of data bytes to transmit.
+ */
+__STATIC_INLINE void nrf_twis_tx_buffer_set(
+ NRF_TWIS_Type * const p_reg,
+ uint8_t const * p_buf,
+ nrf_twis_amount_t length);
+
+/**
+ * @brief Function that prepares TWIS for transmitting
+ *
+ * This function sets transmit buffer and then sets NRF_TWIS_TASK_PREPARETX task.
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param p_buf Pointer to the buffer with data to send.
+ * @param length Maximum number of data bytes to transmit.
+ */
+__STATIC_INLINE void nrf_twis_tx_prepare(
+ NRF_TWIS_Type * const p_reg,
+ uint8_t const * p_buf,
+ nrf_twis_amount_t length);
+
+/**
+ * @brief Function for getting number of bytes transmitted in the last transaction.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @return Amount of bytes transmitted.
+ */
+__STATIC_INLINE nrf_twis_amount_t nrf_twis_tx_amount_get(NRF_TWIS_Type const * const p_reg);
+
+/**
+ * @brief Function for setting slave address
+ *
+ * Function sets the selected address for this TWI interface.
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param n Index of address to set
+ * @param addr Addres to set
+ * @sa nrf_twis_config_address_set
+ * @sa nrf_twis_config_address_get
+ */
+__STATIC_INLINE void nrf_twis_address_set(
+ NRF_TWIS_Type * const p_reg,
+ uint_fast8_t n,
+ nrf_twis_address_t addr);
+
+/**
+ * @brief Function for retrieving configured slave address
+ *
+ * Function gets the selected address for this TWI interface.
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param n Index of address to get
+ */
+__STATIC_INLINE nrf_twis_address_t nrf_twis_address_get(
+ NRF_TWIS_Type const * const p_reg,
+ uint_fast8_t n);
+
+/**
+ * @brief Function for setting the device address configuration.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param addr_mask Mask of address indexes of what device should answer to.
+ *
+ * @sa nrf_twis_address_set
+ */
+__STATIC_INLINE void nrf_twis_config_address_set(
+ NRF_TWIS_Type * const p_reg,
+ nrf_twis_config_addr_mask_t addr_mask);
+
+/**
+ * @brief Function for retrieving the device address configuration.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ *
+ * @return Mask of address indexes of what device should answer to.
+ */
+__STATIC_INLINE nrf_twis_config_addr_mask_t nrf_twis_config_address_get(
+ NRF_TWIS_Type const * const p_reg);
+
+/**
+ * @brief Function for setting the over-read character.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] orc Over-read character. Character clocked out in case of
+ * over-read of the TXD buffer.
+ */
+__STATIC_INLINE void nrf_twis_orc_set(
+ NRF_TWIS_Type * const p_reg,
+ uint8_t orc);
+
+/**
+ * @brief Function for setting the over-read character.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ *
+ * @return Over-read character configured for selected instance.
+ */
+__STATIC_INLINE uint8_t nrf_twis_orc_get(NRF_TWIS_Type const * const p_reg);
+
+
+/** @} */ /* End of nrf_twis_hal */
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+/* ------------------------------------------------------------------------------------------------
+ * Internal functions
+ */
+
+/**
+ * @internal
+ * @brief Internal function for getting task/event register address
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @oaram offset Offset of the register from the instance beginning
+ *
+ * @attention offset has to be modulo 4 value. In other case we can get hardware fault.
+ * @return Pointer to the register
+ */
+__STATIC_INLINE volatile uint32_t* nrf_twis_getRegPtr(NRF_TWIS_Type * const p_reg, uint32_t offset)
+{
+ return (volatile uint32_t*)((uint8_t *)p_reg + (uint32_t)offset);
+}
+
+/**
+ * @internal
+ * @brief Internal function for getting task/event register address - constant version
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @oaram offset Offset of the register from the instance beginning
+ *
+ * @attention offset has to be modulo 4 value. In other case we can get hardware fault.
+ * @return Pointer to the register
+ */
+__STATIC_INLINE volatile const uint32_t* nrf_twis_getRegPtr_c(NRF_TWIS_Type const * const p_reg, uint32_t offset)
+{
+ return (volatile const uint32_t*)((uint8_t *)p_reg + (uint32_t)offset);
+}
+
+
+/* ------------------------------------------------------------------------------------------------
+ * Interface functions definitions
+ */
+
+
+void nrf_twis_task_trigger(NRF_TWIS_Type * const p_reg, nrf_twis_task_t task)
+{
+ *(nrf_twis_getRegPtr(p_reg, (uint32_t)task)) = 1UL;
+}
+
+uint32_t nrf_twis_task_address_get(
+ NRF_TWIS_Type const * const p_reg,
+ nrf_twis_task_t task)
+{
+ return (uint32_t)nrf_twis_getRegPtr_c(p_reg, (uint32_t)task);
+}
+
+void nrf_twis_event_clear(
+ NRF_TWIS_Type * const p_reg,
+ nrf_twis_event_t event)
+{
+ *(nrf_twis_getRegPtr(p_reg, (uint32_t)event)) = 0UL;
+#if __CORTEX_M == 0x04
+ volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event));
+ (void)dummy;
+#endif
+}
+
+bool nrf_twis_event_check(
+ NRF_TWIS_Type const * const p_reg,
+ nrf_twis_event_t event)
+{
+ return (bool)*nrf_twis_getRegPtr_c(p_reg, (uint32_t)event);
+}
+
+bool nrf_twis_event_get_and_clear(
+ NRF_TWIS_Type * const p_reg,
+ nrf_twis_event_t event)
+{
+ bool ret = nrf_twis_event_check(p_reg, event);
+ if (ret)
+ {
+ nrf_twis_event_clear(p_reg, event);
+ }
+ return ret;
+}
+
+uint32_t nrf_twis_event_address_get(
+ NRF_TWIS_Type const * const p_reg,
+ nrf_twis_event_t event)
+{
+ return (uint32_t)nrf_twis_getRegPtr_c(p_reg, (uint32_t)event);
+}
+
+void nrf_twis_shorts_enable(NRF_TWIS_Type * const p_reg, uint32_t short_mask)
+{
+ p_reg->SHORTS |= short_mask;
+}
+
+void nrf_twis_shorts_disable(NRF_TWIS_Type * const p_reg, uint32_t short_mask)
+{
+ if (~0U == short_mask)
+ {
+ /* Optimized version for "disable all" */
+ p_reg->SHORTS = 0;
+ }
+ else
+ {
+ p_reg->SHORTS &= ~short_mask;
+ }
+}
+
+uint32_t nrf_twis_shorts_get(NRF_TWIS_Type * const p_reg)
+{
+ return p_reg->SHORTS;
+}
+
+void nrf_twis_int_enable(NRF_TWIS_Type * const p_reg, uint32_t int_mask)
+{
+ p_reg->INTENSET = int_mask;
+}
+
+bool nrf_twis_int_enable_check(NRF_TWIS_Type const * const p_reg, uint32_t int_mask)
+{
+ return (bool)(p_reg->INTENSET & int_mask);
+}
+
+void nrf_twis_int_disable(NRF_TWIS_Type * const p_reg, uint32_t int_mask)
+{
+ p_reg->INTENCLR = int_mask;
+}
+
+uint32_t nrf_twis_error_source_get_and_clear(NRF_TWIS_Type * const p_reg)
+{
+ uint32_t ret = p_reg->ERRORSRC;
+ p_reg->ERRORSRC = ret;
+ return ret;
+}
+
+uint_fast8_t nrf_twis_match_get(NRF_TWIS_Type const * p_reg)
+{
+ return (uint_fast8_t)p_reg->MATCH;
+}
+
+void nrf_twis_enable(NRF_TWIS_Type * const p_reg)
+{
+ p_reg->ENABLE = (TWIS_ENABLE_ENABLE_Enabled << TWIS_ENABLE_ENABLE_Pos);
+}
+
+void nrf_twis_disable(NRF_TWIS_Type * const p_reg)
+{
+ p_reg->ENABLE = (TWIS_ENABLE_ENABLE_Disabled << TWIS_ENABLE_ENABLE_Pos);
+}
+
+void nrf_twis_pins_set(NRF_TWIS_Type * const p_reg, uint32_t scl, uint32_t sda)
+{
+ p_reg->PSEL.SCL = scl;
+ p_reg->PSEL.SDA = sda;
+}
+
+void nrf_twis_rx_buffer_set(
+ NRF_TWIS_Type * const p_reg,
+ uint8_t * p_buf,
+ nrf_twis_amount_t length)
+{
+ p_reg->RXD.PTR = (uint32_t)p_buf;
+ p_reg->RXD.MAXCNT = length;
+}
+
+__STATIC_INLINE void nrf_twis_rx_prepare(
+ NRF_TWIS_Type * const p_reg,
+ uint8_t * p_buf,
+ nrf_twis_amount_t length)
+{
+ nrf_twis_rx_buffer_set(p_reg, p_buf, length);
+ nrf_twis_task_trigger(p_reg, NRF_TWIS_TASK_PREPARERX);
+}
+
+nrf_twis_amount_t nrf_twis_rx_amount_get(NRF_TWIS_Type const * const p_reg)
+{
+ return (nrf_twis_amount_t)p_reg->RXD.AMOUNT;
+}
+
+void nrf_twis_tx_buffer_set(
+ NRF_TWIS_Type * const p_reg,
+ uint8_t const * p_buf,
+ nrf_twis_amount_t length)
+{
+ p_reg->TXD.PTR = (uint32_t)p_buf;
+ p_reg->TXD.MAXCNT = length;
+}
+
+__STATIC_INLINE void nrf_twis_tx_prepare(
+ NRF_TWIS_Type * const p_reg,
+ uint8_t const * p_buf,
+ nrf_twis_amount_t length)
+{
+ nrf_twis_tx_buffer_set(p_reg, p_buf, length);
+ nrf_twis_task_trigger(p_reg, NRF_TWIS_TASK_PREPARETX);
+}
+
+nrf_twis_amount_t nrf_twis_tx_amount_get(NRF_TWIS_Type const * const p_reg)
+{
+ return (nrf_twis_amount_t)p_reg->TXD.AMOUNT;
+}
+
+void nrf_twis_address_set(
+ NRF_TWIS_Type * const p_reg,
+ uint_fast8_t n,
+ nrf_twis_address_t addr)
+{
+ p_reg->ADDRESS[n] = addr;
+}
+
+nrf_twis_address_t nrf_twis_address_get(
+ NRF_TWIS_Type const * const p_reg,
+ uint_fast8_t n)
+{
+ return (nrf_twis_address_t)p_reg->ADDRESS[n];
+}
+void nrf_twis_config_address_set(
+ NRF_TWIS_Type * const p_reg,
+ nrf_twis_config_addr_mask_t addr_mask)
+{
+ /* This is the only configuration in TWIS - just write it without masking */
+ p_reg->CONFIG = addr_mask;
+}
+
+nrf_twis_config_addr_mask_t nrf_twis_config_address_get(NRF_TWIS_Type const * const p_reg)
+{
+ return (nrf_twis_config_addr_mask_t)(p_reg->CONFIG & TWIS_ADDRESS_ADDRESS_Msk);
+}
+
+void nrf_twis_orc_set(
+ NRF_TWIS_Type * const p_reg,
+ uint8_t orc)
+{
+ p_reg->ORC = orc;
+}
+
+uint8_t nrf_twis_orc_get(NRF_TWIS_Type const * const p_reg)
+{
+ return (uint8_t)p_reg->ORC;
+}
+
+#endif /* SUPPRESS_INLINE_IMPLEMENTATION */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_TWIS_H__ */
+
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_uart.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_uart.h
new file mode 100644
index 000000000..5bb1dcd17
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_uart.h
@@ -0,0 +1,549 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_UART_H__
+#define NRF_UART_H__
+
+#include "nrf.h"
+#include "nrf_peripherals.h"
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//Temporary defining legacy UART for instance 1
+#define NRF_UART1 (NRF_UART_Type *)NRF_UARTE1
+
+/**
+ * @defgroup nrf_uart_hal UART HAL
+ * @{
+ * @ingroup nrf_uart
+ *
+ * @brief Hardware access layer for accessing the UART peripheral.
+ */
+
+#define NRF_UART_PSEL_DISCONNECTED 0xFFFFFFFF
+
+/**
+ * @enum nrf_uart_task_t
+ * @brief UART tasks.
+ */
+typedef enum
+{
+ /*lint -save -e30 -esym(628,__INTADDR__)*/
+ NRF_UART_TASK_STARTRX = offsetof(NRF_UART_Type, TASKS_STARTRX), /**< Task for starting reception. */
+ NRF_UART_TASK_STOPRX = offsetof(NRF_UART_Type, TASKS_STOPRX), /**< Task for stopping reception. */
+ NRF_UART_TASK_STARTTX = offsetof(NRF_UART_Type, TASKS_STARTTX), /**< Task for starting transmission. */
+ NRF_UART_TASK_STOPTX = offsetof(NRF_UART_Type, TASKS_STOPTX), /**< Task for stopping transmission. */
+ NRF_UART_TASK_SUSPEND = offsetof(NRF_UART_Type, TASKS_SUSPEND), /**< Task for suspending UART. */
+ /*lint -restore*/
+} nrf_uart_task_t;
+
+/**
+ * @enum nrf_uart_event_t
+ * @brief UART events.
+ */
+typedef enum
+{
+ /*lint -save -e30*/
+ NRF_UART_EVENT_CTS = offsetof(NRF_UART_Type, EVENTS_CTS), /**< Event from CTS line activation. */
+ NRF_UART_EVENT_NCTS = offsetof(NRF_UART_Type, EVENTS_NCTS), /**< Event from CTS line deactivation. */
+ NRF_UART_EVENT_RXDRDY = offsetof(NRF_UART_Type, EVENTS_RXDRDY),/**< Event from data ready in RXD. */
+ NRF_UART_EVENT_TXDRDY = offsetof(NRF_UART_Type, EVENTS_TXDRDY),/**< Event from data sent from TXD. */
+ NRF_UART_EVENT_ERROR = offsetof(NRF_UART_Type, EVENTS_ERROR), /**< Event from error detection. */
+ NRF_UART_EVENT_RXTO = offsetof(NRF_UART_Type, EVENTS_RXTO) /**< Event from receiver timeout. */
+ /*lint -restore*/
+} nrf_uart_event_t;
+
+/**
+ * @enum nrf_uart_int_mask_t
+ * @brief UART interrupts.
+ */
+typedef enum
+{
+ /*lint -save -e30*/
+ NRF_UART_INT_MASK_CTS = UART_INTENCLR_CTS_Msk, /**< CTS line activation interrupt. */
+ NRF_UART_INT_MASK_NCTS = UART_INTENCLR_NCTS_Msk, /**< CTS line deactivation interrupt. */
+ NRF_UART_INT_MASK_RXDRDY = UART_INTENCLR_RXDRDY_Msk, /**< Data ready in RXD interrupt. */
+ NRF_UART_INT_MASK_TXDRDY = UART_INTENCLR_TXDRDY_Msk, /**< Data sent from TXD interrupt. */
+ NRF_UART_INT_MASK_ERROR = UART_INTENCLR_ERROR_Msk, /**< Error detection interrupt. */
+ NRF_UART_INT_MASK_RXTO = UART_INTENCLR_RXTO_Msk /**< Receiver timeout interrupt. */
+ /*lint -restore*/
+} nrf_uart_int_mask_t;
+
+/**
+ * @enum nrf_uart_baudrate_t
+ * @brief Baudrates supported by UART.
+ */
+typedef enum
+{
+#ifdef UARTE_PRESENT
+ NRF_UART_BAUDRATE_1200 = UARTE_BAUDRATE_BAUDRATE_Baud1200, /**< 1200 baud. */
+ NRF_UART_BAUDRATE_2400 = UARTE_BAUDRATE_BAUDRATE_Baud2400, /**< 2400 baud. */
+ NRF_UART_BAUDRATE_4800 = UARTE_BAUDRATE_BAUDRATE_Baud4800, /**< 4800 baud. */
+ NRF_UART_BAUDRATE_9600 = UARTE_BAUDRATE_BAUDRATE_Baud9600, /**< 9600 baud. */
+ NRF_UART_BAUDRATE_14400 = UARTE_BAUDRATE_BAUDRATE_Baud14400, /**< 14400 baud. */
+ NRF_UART_BAUDRATE_19200 = UARTE_BAUDRATE_BAUDRATE_Baud19200, /**< 19200 baud. */
+ NRF_UART_BAUDRATE_28800 = UARTE_BAUDRATE_BAUDRATE_Baud28800, /**< 28800 baud. */
+ NRF_UART_BAUDRATE_38400 = UARTE_BAUDRATE_BAUDRATE_Baud38400, /**< 38400 baud. */
+ NRF_UART_BAUDRATE_57600 = UARTE_BAUDRATE_BAUDRATE_Baud57600, /**< 57600 baud. */
+ NRF_UART_BAUDRATE_76800 = UARTE_BAUDRATE_BAUDRATE_Baud76800, /**< 76800 baud. */
+ NRF_UART_BAUDRATE_115200 = UARTE_BAUDRATE_BAUDRATE_Baud115200, /**< 115200 baud. */
+ NRF_UART_BAUDRATE_230400 = UARTE_BAUDRATE_BAUDRATE_Baud230400, /**< 230400 baud. */
+ NRF_UART_BAUDRATE_250000 = UARTE_BAUDRATE_BAUDRATE_Baud250000, /**< 250000 baud. */
+ NRF_UART_BAUDRATE_460800 = UARTE_BAUDRATE_BAUDRATE_Baud460800, /**< 460800 baud. */
+ NRF_UART_BAUDRATE_921600 = UARTE_BAUDRATE_BAUDRATE_Baud921600, /**< 921600 baud. */
+ NRF_UART_BAUDRATE_1000000 = UARTE_BAUDRATE_BAUDRATE_Baud1M, /**< 1000000 baud. */
+#else
+ NRF_UART_BAUDRATE_1200 = UART_BAUDRATE_BAUDRATE_Baud1200, /**< 1200 baud. */
+ NRF_UART_BAUDRATE_2400 = UART_BAUDRATE_BAUDRATE_Baud2400, /**< 2400 baud. */
+ NRF_UART_BAUDRATE_4800 = UART_BAUDRATE_BAUDRATE_Baud4800, /**< 4800 baud. */
+ NRF_UART_BAUDRATE_9600 = UART_BAUDRATE_BAUDRATE_Baud9600, /**< 9600 baud. */
+ NRF_UART_BAUDRATE_14400 = UART_BAUDRATE_BAUDRATE_Baud14400, /**< 14400 baud. */
+ NRF_UART_BAUDRATE_19200 = UART_BAUDRATE_BAUDRATE_Baud19200, /**< 19200 baud. */
+ NRF_UART_BAUDRATE_28800 = UART_BAUDRATE_BAUDRATE_Baud28800, /**< 28800 baud. */
+ NRF_UART_BAUDRATE_38400 = UART_BAUDRATE_BAUDRATE_Baud38400, /**< 38400 baud. */
+ NRF_UART_BAUDRATE_57600 = UART_BAUDRATE_BAUDRATE_Baud57600, /**< 57600 baud. */
+ NRF_UART_BAUDRATE_76800 = UART_BAUDRATE_BAUDRATE_Baud76800, /**< 76800 baud. */
+ NRF_UART_BAUDRATE_115200 = UART_BAUDRATE_BAUDRATE_Baud115200, /**< 115200 baud. */
+ NRF_UART_BAUDRATE_230400 = UART_BAUDRATE_BAUDRATE_Baud230400, /**< 230400 baud. */
+ NRF_UART_BAUDRATE_250000 = UART_BAUDRATE_BAUDRATE_Baud250000, /**< 250000 baud. */
+ NRF_UART_BAUDRATE_460800 = UART_BAUDRATE_BAUDRATE_Baud460800, /**< 460800 baud. */
+ NRF_UART_BAUDRATE_921600 = UART_BAUDRATE_BAUDRATE_Baud921600, /**< 921600 baud. */
+ NRF_UART_BAUDRATE_1000000 = UART_BAUDRATE_BAUDRATE_Baud1M, /**< 1000000 baud. */
+#endif
+} nrf_uart_baudrate_t;
+
+/**
+ * @enum nrf_uart_error_mask_t
+ * @brief Types of UART error masks.
+ */
+typedef enum
+{
+ NRF_UART_ERROR_OVERRUN_MASK = UART_ERRORSRC_OVERRUN_Msk, /**< Overrun error. */
+ NRF_UART_ERROR_PARITY_MASK = UART_ERRORSRC_PARITY_Msk, /**< Parity error. */
+ NRF_UART_ERROR_FRAMING_MASK = UART_ERRORSRC_FRAMING_Msk, /**< Framing error. */
+ NRF_UART_ERROR_BREAK_MASK = UART_ERRORSRC_BREAK_Msk, /**< Break error. */
+} nrf_uart_error_mask_t;
+
+/**
+ * @enum nrf_uart_parity_t
+ * @brief Types of UART parity modes.
+ */
+typedef enum
+{
+ NRF_UART_PARITY_EXCLUDED = UART_CONFIG_PARITY_Excluded << UART_CONFIG_PARITY_Pos, /**< Parity excluded. */
+ NRF_UART_PARITY_INCLUDED = UART_CONFIG_PARITY_Included << UART_CONFIG_PARITY_Pos, /**< Parity included. */
+} nrf_uart_parity_t;
+
+/**
+ * @enum nrf_uart_hwfc_t
+ * @brief Types of UART flow control modes.
+ */
+typedef enum
+{
+ NRF_UART_HWFC_DISABLED = UART_CONFIG_HWFC_Disabled, /**< HW flow control disabled. */
+ NRF_UART_HWFC_ENABLED = UART_CONFIG_HWFC_Enabled, /**< HW flow control enabled. */
+} nrf_uart_hwfc_t;
+
+/**
+ * @brief Function for clearing a specific UART event.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] event Event to clear.
+ */
+__STATIC_INLINE void nrf_uart_event_clear(NRF_UART_Type * p_reg, nrf_uart_event_t event);
+
+/**
+ * @brief Function for checking the state of a specific UART event.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] event Event to check.
+ *
+ * @retval True if event is set, False otherwise.
+ */
+__STATIC_INLINE bool nrf_uart_event_check(NRF_UART_Type * p_reg, nrf_uart_event_t event);
+
+/**
+ * @brief Function for returning the address of a specific UART event register.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] event Desired event.
+ *
+ * @retval Address of specified event register.
+ */
+__STATIC_INLINE uint32_t nrf_uart_event_address_get(NRF_UART_Type * p_reg,
+ nrf_uart_event_t event);
+
+/**
+ * @brief Function for enabling a specific interrupt.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ * @param int_mask Interrupts to enable.
+ */
+__STATIC_INLINE void nrf_uart_int_enable(NRF_UART_Type * p_reg, uint32_t int_mask);
+
+/**
+ * @brief Function for retrieving the state of a given interrupt.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ * @param int_mask Mask of interrupt to check.
+ *
+ * @retval true If the interrupt is enabled.
+ * @retval false If the interrupt is not enabled.
+ */
+__STATIC_INLINE bool nrf_uart_int_enable_check(NRF_UART_Type * p_reg, uint32_t int_mask);
+
+/**
+ * @brief Function for disabling specific interrupts.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ * @param int_mask Interrupts to disable.
+ */
+__STATIC_INLINE void nrf_uart_int_disable(NRF_UART_Type * p_reg, uint32_t int_mask);
+
+/**
+ * @brief Function for getting error source mask. Function is clearing error source flags after reading.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ * @return Mask with error source flags.
+ */
+__STATIC_INLINE uint32_t nrf_uart_errorsrc_get_and_clear(NRF_UART_Type * p_reg);
+
+/**
+ * @brief Function for enabling UART.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE void nrf_uart_enable(NRF_UART_Type * p_reg);
+
+/**
+ * @brief Function for disabling UART.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE void nrf_uart_disable(NRF_UART_Type * p_reg);
+
+/**
+ * @brief Function for configuring TX/RX pins.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ * @param pseltxd TXD pin number.
+ * @param pselrxd RXD pin number.
+ */
+__STATIC_INLINE void nrf_uart_txrx_pins_set(NRF_UART_Type * p_reg, uint32_t pseltxd, uint32_t pselrxd);
+
+/**
+ * @brief Function for disconnecting TX/RX pins.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE void nrf_uart_txrx_pins_disconnect(NRF_UART_Type * p_reg);
+
+/**
+ * @brief Function for getting TX pin.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE uint32_t nrf_uart_tx_pin_get(NRF_UART_Type * p_reg);
+
+/**
+ * @brief Function for getting RX pin.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE uint32_t nrf_uart_rx_pin_get(NRF_UART_Type * p_reg);
+
+/**
+ * @brief Function for getting RTS pin.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE uint32_t nrf_uart_rts_pin_get(NRF_UART_Type * p_reg);
+
+/**
+ * @brief Function for getting CTS pin.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE uint32_t nrf_uart_cts_pin_get(NRF_UART_Type * p_reg);
+
+
+/**
+ * @brief Function for configuring flow control pins.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ * @param pselrts RTS pin number.
+ * @param pselcts CTS pin number.
+ */
+__STATIC_INLINE void nrf_uart_hwfc_pins_set(NRF_UART_Type * p_reg,
+ uint32_t pselrts,
+ uint32_t pselcts);
+
+/**
+ * @brief Function for disconnecting flow control pins.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE void nrf_uart_hwfc_pins_disconnect(NRF_UART_Type * p_reg);
+
+/**
+ * @brief Function for reading RX data.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ * @return Received byte.
+ */
+__STATIC_INLINE uint8_t nrf_uart_rxd_get(NRF_UART_Type * p_reg);
+
+/**
+ * @brief Function for setting Tx data.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ * @param txd Byte.
+ */
+__STATIC_INLINE void nrf_uart_txd_set(NRF_UART_Type * p_reg, uint8_t txd);
+
+/**
+ * @brief Function for starting an UART task.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ * @param task Task.
+ */
+__STATIC_INLINE void nrf_uart_task_trigger(NRF_UART_Type * p_reg, nrf_uart_task_t task);
+
+/**
+ * @brief Function for returning the address of a specific task register.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ * @param task Task.
+ *
+ * @return Task address.
+ */
+__STATIC_INLINE uint32_t nrf_uart_task_address_get(NRF_UART_Type * p_reg, nrf_uart_task_t task);
+
+/**
+ * @brief Function for configuring UART.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ * @param hwfc Hardware flow control. Enabled if true.
+ * @param parity Parity. Included if true.
+ */
+__STATIC_INLINE void nrf_uart_configure(NRF_UART_Type * p_reg,
+ nrf_uart_parity_t parity,
+ nrf_uart_hwfc_t hwfc);
+
+/**
+ * @brief Function for setting UART baudrate.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ * @param baudrate Baudrate.
+ */
+__STATIC_INLINE void nrf_uart_baudrate_set(NRF_UART_Type * p_reg, nrf_uart_baudrate_t baudrate);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+__STATIC_INLINE void nrf_uart_event_clear(NRF_UART_Type * p_reg, nrf_uart_event_t event)
+{
+ *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
+#if __CORTEX_M == 0x04
+ volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event));
+ (void)dummy;
+#endif
+
+}
+
+__STATIC_INLINE bool nrf_uart_event_check(NRF_UART_Type * p_reg, nrf_uart_event_t event)
+{
+ return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
+}
+
+__STATIC_INLINE uint32_t nrf_uart_event_address_get(NRF_UART_Type * p_reg,
+ nrf_uart_event_t event)
+{
+ return (uint32_t)((uint8_t *)p_reg + (uint32_t)event);
+}
+
+__STATIC_INLINE void nrf_uart_int_enable(NRF_UART_Type * p_reg, uint32_t int_mask)
+{
+ p_reg->INTENSET = int_mask;
+}
+
+__STATIC_INLINE bool nrf_uart_int_enable_check(NRF_UART_Type * p_reg, uint32_t int_mask)
+{
+ return (bool)(p_reg->INTENSET & int_mask);
+}
+
+__STATIC_INLINE void nrf_uart_int_disable(NRF_UART_Type * p_reg, uint32_t int_mask)
+{
+ p_reg->INTENCLR = int_mask;
+}
+
+__STATIC_INLINE uint32_t nrf_uart_errorsrc_get_and_clear(NRF_UART_Type * p_reg)
+{
+ uint32_t errsrc_mask = p_reg->ERRORSRC;
+ p_reg->ERRORSRC = errsrc_mask;
+ return errsrc_mask;
+}
+
+__STATIC_INLINE void nrf_uart_enable(NRF_UART_Type * p_reg)
+{
+ p_reg->ENABLE = UART_ENABLE_ENABLE_Enabled;
+}
+
+__STATIC_INLINE void nrf_uart_disable(NRF_UART_Type * p_reg)
+{
+ p_reg->ENABLE = UART_ENABLE_ENABLE_Disabled;
+}
+
+__STATIC_INLINE void nrf_uart_txrx_pins_set(NRF_UART_Type * p_reg, uint32_t pseltxd, uint32_t pselrxd)
+{
+#if defined(UART_PSEL_RXD_CONNECT_Pos)
+ p_reg->PSEL.RXD = pselrxd;
+#else
+ p_reg->PSELRXD = pselrxd;
+#endif
+#if defined(UART_PSEL_TXD_CONNECT_Pos)
+ p_reg->PSEL.TXD = pseltxd;
+#else
+ p_reg->PSELTXD = pseltxd;
+#endif
+}
+
+__STATIC_INLINE void nrf_uart_txrx_pins_disconnect(NRF_UART_Type * p_reg)
+{
+ nrf_uart_txrx_pins_set(p_reg, NRF_UART_PSEL_DISCONNECTED, NRF_UART_PSEL_DISCONNECTED);
+}
+
+__STATIC_INLINE uint32_t nrf_uart_tx_pin_get(NRF_UART_Type * p_reg)
+{
+#if defined(UART_PSEL_TXD_CONNECT_Pos)
+ return p_reg->PSEL.TXD;
+#else
+ return p_reg->PSELTXD;
+#endif
+}
+
+__STATIC_INLINE uint32_t nrf_uart_rx_pin_get(NRF_UART_Type * p_reg)
+{
+#if defined(UART_PSEL_RXD_CONNECT_Pos)
+ return p_reg->PSEL.RXD;
+#else
+ return p_reg->PSELRXD;
+#endif
+}
+
+__STATIC_INLINE uint32_t nrf_uart_rts_pin_get(NRF_UART_Type * p_reg)
+{
+#if defined(UART_PSEL_RTS_CONNECT_Pos)
+ return p_reg->PSEL.RTS;
+#else
+ return p_reg->PSELRTS;
+#endif
+}
+
+__STATIC_INLINE uint32_t nrf_uart_cts_pin_get(NRF_UART_Type * p_reg)
+{
+#if defined(UART_PSEL_RTS_CONNECT_Pos)
+ return p_reg->PSEL.CTS;
+#else
+ return p_reg->PSELCTS;
+#endif
+}
+
+__STATIC_INLINE void nrf_uart_hwfc_pins_set(NRF_UART_Type * p_reg, uint32_t pselrts, uint32_t pselcts)
+{
+#if defined(UART_PSEL_RTS_CONNECT_Pos)
+ p_reg->PSEL.RTS = pselrts;
+#else
+ p_reg->PSELRTS = pselrts;
+#endif
+
+#if defined(UART_PSEL_RTS_CONNECT_Pos)
+ p_reg->PSEL.CTS = pselcts;
+#else
+ p_reg->PSELCTS = pselcts;
+#endif
+}
+
+__STATIC_INLINE void nrf_uart_hwfc_pins_disconnect(NRF_UART_Type * p_reg)
+{
+ nrf_uart_hwfc_pins_set(p_reg, NRF_UART_PSEL_DISCONNECTED, NRF_UART_PSEL_DISCONNECTED);
+}
+
+__STATIC_INLINE uint8_t nrf_uart_rxd_get(NRF_UART_Type * p_reg)
+{
+ return p_reg->RXD;
+}
+
+__STATIC_INLINE void nrf_uart_txd_set(NRF_UART_Type * p_reg, uint8_t txd)
+{
+ p_reg->TXD = txd;
+}
+
+__STATIC_INLINE void nrf_uart_task_trigger(NRF_UART_Type * p_reg, nrf_uart_task_t task)
+{
+ *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
+}
+
+__STATIC_INLINE uint32_t nrf_uart_task_address_get(NRF_UART_Type * p_reg, nrf_uart_task_t task)
+{
+ return (uint32_t)p_reg + (uint32_t)task;
+}
+
+__STATIC_INLINE void nrf_uart_configure(NRF_UART_Type * p_reg,
+ nrf_uart_parity_t parity,
+ nrf_uart_hwfc_t hwfc)
+{
+ p_reg->CONFIG = (uint32_t)parity | (uint32_t)hwfc;
+}
+
+__STATIC_INLINE void nrf_uart_baudrate_set(NRF_UART_Type * p_reg, nrf_uart_baudrate_t baudrate)
+{
+ p_reg->BAUDRATE = baudrate;
+}
+#endif //SUPPRESS_INLINE_IMPLEMENTATION
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //NRF_UART_H__
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_uarte.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_uarte.h
new file mode 100644
index 000000000..49a5c4e5d
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_uarte.h
@@ -0,0 +1,609 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_UARTE_H__
+#define NRF_UARTE_H__
+
+#include "nrf.h"
+#include "nrf_peripherals.h"
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NRF_UARTE_PSEL_DISCONNECTED 0xFFFFFFFF
+
+/**
+ * @defgroup nrf_uarte_hal UARTE HAL
+ * @{
+ * @ingroup nrf_uart
+ *
+ * @brief Hardware access layer for accessing the UARTE peripheral.
+ */
+
+/**
+ * @enum nrf_uarte_task_t
+ * @brief UARTE tasks.
+ */
+typedef enum
+{
+ /*lint -save -e30*/
+ NRF_UARTE_TASK_STARTRX = offsetof(NRF_UARTE_Type, TASKS_STARTRX),///< Start UART receiver.
+ NRF_UARTE_TASK_STOPRX = offsetof(NRF_UARTE_Type, TASKS_STOPRX), ///< Stop UART receiver.
+ NRF_UARTE_TASK_STARTTX = offsetof(NRF_UARTE_Type, TASKS_STARTTX),///< Start UART transmitter.
+ NRF_UARTE_TASK_STOPTX = offsetof(NRF_UARTE_Type, TASKS_STOPTX), ///< Stop UART transmitter.
+ NRF_UARTE_TASK_FLUSHRX = offsetof(NRF_UARTE_Type, TASKS_FLUSHRX) ///< Flush RX FIFO in RX buffer.
+ /*lint -restore*/
+} nrf_uarte_task_t;
+
+/**
+ * @enum nrf_uarte_event_t
+ * @brief UARTE events.
+ */
+typedef enum
+{
+ /*lint -save -e30*/
+ NRF_UARTE_EVENT_CTS = offsetof(NRF_UARTE_Type, EVENTS_CTS), ///< CTS is activated.
+ NRF_UARTE_EVENT_NCTS = offsetof(NRF_UARTE_Type, EVENTS_NCTS), ///< CTS is deactivated.
+ NRF_UARTE_EVENT_ENDRX = offsetof(NRF_UARTE_Type, EVENTS_ENDRX), ///< Receive buffer is filled up.
+ NRF_UARTE_EVENT_ENDTX = offsetof(NRF_UARTE_Type, EVENTS_ENDTX), ///< Last TX byte transmitted.
+ NRF_UARTE_EVENT_ERROR = offsetof(NRF_UARTE_Type, EVENTS_ERROR), ///< Error detected.
+ NRF_UARTE_EVENT_RXTO = offsetof(NRF_UARTE_Type, EVENTS_RXTO), ///< Receiver timeout.
+ NRF_UARTE_EVENT_RXSTARTED = offsetof(NRF_UARTE_Type, EVENTS_RXSTARTED),///< Receiver has started.
+ NRF_UARTE_EVENT_TXSTARTED = offsetof(NRF_UARTE_Type, EVENTS_TXSTARTED),///< Transmitter has started.
+ NRF_UARTE_EVENT_TXSTOPPED = offsetof(NRF_UARTE_Type, EVENTS_TXSTOPPED) ///< Transmitted stopped.
+ /*lint -restore*/
+} nrf_uarte_event_t;
+
+/**
+ * @brief Types of UARTE shortcuts.
+ */
+typedef enum
+{
+ NRF_UARTE_SHORT_ENDRX_STARTRX = UARTE_SHORTS_ENDRX_STARTRX_Msk,///< Shortcut between ENDRX event and STARTRX task.
+ NRF_UARTE_SHORT_ENDRX_STOPRX = UARTE_SHORTS_ENDRX_STOPRX_Msk, ///< Shortcut between ENDRX event and STOPRX task.
+} nrf_uarte_short_t;
+
+
+/**
+ * @enum nrf_uarte_int_mask_t
+ * @brief UARTE interrupts.
+ */
+typedef enum
+{
+ NRF_UARTE_INT_CTS_MASK = UARTE_INTENSET_CTS_Msk, ///< Interrupt on CTS event.
+ NRF_UARTE_INT_NCTSRX_MASK = UARTE_INTENSET_NCTS_Msk, ///< Interrupt on NCTS event.
+ NRF_UARTE_INT_ENDRX_MASK = UARTE_INTENSET_ENDRX_Msk, ///< Interrupt on ENDRX event.
+ NRF_UARTE_INT_ENDTX_MASK = UARTE_INTENSET_ENDTX_Msk, ///< Interrupt on ENDTX event.
+ NRF_UARTE_INT_ERROR_MASK = UARTE_INTENSET_ERROR_Msk, ///< Interrupt on ERROR event.
+ NRF_UARTE_INT_RXTO_MASK = UARTE_INTENSET_RXTO_Msk, ///< Interrupt on RXTO event.
+ NRF_UARTE_INT_RXSTARTED_MASK = UARTE_INTENSET_RXSTARTED_Msk,///< Interrupt on RXSTARTED event.
+ NRF_UARTE_INT_TXSTARTED_MASK = UARTE_INTENSET_TXSTARTED_Msk,///< Interrupt on TXSTARTED event.
+ NRF_UARTE_INT_TXSTOPPED_MASK = UARTE_INTENSET_TXSTOPPED_Msk ///< Interrupt on TXSTOPPED event.
+} nrf_uarte_int_mask_t;
+
+/**
+ * @enum nrf_uarte_baudrate_t
+ * @brief Baudrates supported by UARTE.
+ */
+typedef enum
+{
+ NRF_UARTE_BAUDRATE_1200 = UARTE_BAUDRATE_BAUDRATE_Baud1200, ///< 1200 baud.
+ NRF_UARTE_BAUDRATE_2400 = UARTE_BAUDRATE_BAUDRATE_Baud2400, ///< 2400 baud.
+ NRF_UARTE_BAUDRATE_4800 = UARTE_BAUDRATE_BAUDRATE_Baud4800, ///< 4800 baud.
+ NRF_UARTE_BAUDRATE_9600 = UARTE_BAUDRATE_BAUDRATE_Baud9600, ///< 9600 baud.
+ NRF_UARTE_BAUDRATE_14400 = UARTE_BAUDRATE_BAUDRATE_Baud14400, ///< 14400 baud.
+ NRF_UARTE_BAUDRATE_19200 = UARTE_BAUDRATE_BAUDRATE_Baud19200, ///< 19200 baud.
+ NRF_UARTE_BAUDRATE_28800 = UARTE_BAUDRATE_BAUDRATE_Baud28800, ///< 28800 baud.
+ NRF_UARTE_BAUDRATE_38400 = UARTE_BAUDRATE_BAUDRATE_Baud38400, ///< 38400 baud.
+ NRF_UARTE_BAUDRATE_57600 = UARTE_BAUDRATE_BAUDRATE_Baud57600, ///< 57600 baud.
+ NRF_UARTE_BAUDRATE_76800 = UARTE_BAUDRATE_BAUDRATE_Baud76800, ///< 76800 baud.
+ NRF_UARTE_BAUDRATE_115200 = UARTE_BAUDRATE_BAUDRATE_Baud115200, ///< 115200 baud.
+ NRF_UARTE_BAUDRATE_230400 = UARTE_BAUDRATE_BAUDRATE_Baud230400, ///< 230400 baud.
+ NRF_UARTE_BAUDRATE_250000 = UARTE_BAUDRATE_BAUDRATE_Baud250000, ///< 250000 baud.
+ NRF_UARTE_BAUDRATE_460800 = UARTE_BAUDRATE_BAUDRATE_Baud460800, ///< 460800 baud.
+ NRF_UARTE_BAUDRATE_921600 = UARTE_BAUDRATE_BAUDRATE_Baud921600, ///< 921600 baud.
+ NRF_UARTE_BAUDRATE_1000000 = UARTE_BAUDRATE_BAUDRATE_Baud1M, ///< 1000000 baud.
+#ifndef UART_PRESENT
+ NRF_UART_BAUDRATE_1200 = NRF_UARTE_BAUDRATE_1200,
+ NRF_UART_BAUDRATE_2400 = NRF_UARTE_BAUDRATE_2400,
+ NRF_UART_BAUDRATE_4800 = NRF_UARTE_BAUDRATE_4800,
+ NRF_UART_BAUDRATE_9600 = NRF_UARTE_BAUDRATE_9600,
+ NRF_UART_BAUDRATE_14400 = NRF_UARTE_BAUDRATE_14400,
+ NRF_UART_BAUDRATE_19200 = NRF_UARTE_BAUDRATE_19200,
+ NRF_UART_BAUDRATE_28800 = NRF_UARTE_BAUDRATE_28800,
+ NRF_UART_BAUDRATE_38400 = NRF_UARTE_BAUDRATE_38400,
+ NRF_UART_BAUDRATE_57600 = NRF_UARTE_BAUDRATE_57600,
+ NRF_UART_BAUDRATE_76800 = NRF_UARTE_BAUDRATE_76800,
+ NRF_UART_BAUDRATE_115200 = NRF_UARTE_BAUDRATE_115200,
+ NRF_UART_BAUDRATE_230400 = NRF_UARTE_BAUDRATE_230400,
+ NRF_UART_BAUDRATE_250000 = NRF_UARTE_BAUDRATE_250000,
+ NRF_UART_BAUDRATE_460800 = NRF_UARTE_BAUDRATE_460800,
+ NRF_UART_BAUDRATE_921600 = NRF_UARTE_BAUDRATE_921600,
+ NRF_UART_BAUDRATE_1000000 = NRF_UARTE_BAUDRATE_1000000,
+#endif
+} nrf_uarte_baudrate_t;
+
+/**
+ * @enum nrf_uarte_error_mask_t
+ * @brief Types of UARTE error masks.
+ */
+typedef enum
+{
+ NRF_UARTE_ERROR_OVERRUN_MASK = UARTE_ERRORSRC_OVERRUN_Msk, ///< Overrun error.
+ NRF_UARTE_ERROR_PARITY_MASK = UARTE_ERRORSRC_PARITY_Msk, ///< Parity error.
+ NRF_UARTE_ERROR_FRAMING_MASK = UARTE_ERRORSRC_FRAMING_Msk, ///< Framing error.
+ NRF_UARTE_ERROR_BREAK_MASK = UARTE_ERRORSRC_BREAK_Msk, ///< Break error.
+#ifndef UART_PRESENT
+ NRF_UART_ERROR_OVERRUN_MASK = NRF_UARTE_ERROR_OVERRUN_MASK,
+ NRF_UART_ERROR_PARITY_MASK = NRF_UARTE_ERROR_PARITY_MASK,
+ NRF_UART_ERROR_FRAMING_MASK = NRF_UARTE_ERROR_FRAMING_MASK,
+ NRF_UART_ERROR_BREAK_MASK = NRF_UARTE_ERROR_BREAK_MASK,
+#endif
+} nrf_uarte_error_mask_t;
+
+/**
+ * @enum nrf_uarte_parity_t
+ * @brief Types of UARTE parity modes.
+ */
+typedef enum
+{
+ NRF_UARTE_PARITY_EXCLUDED = UARTE_CONFIG_PARITY_Excluded << UARTE_CONFIG_PARITY_Pos, ///< Parity excluded.
+ NRF_UARTE_PARITY_INCLUDED = UARTE_CONFIG_PARITY_Included << UARTE_CONFIG_PARITY_Pos, ///< Parity included.
+#ifndef UART_PRESENT
+ NRF_UART_PARITY_EXCLUDED = NRF_UARTE_PARITY_EXCLUDED,
+ NRF_UART_PARITY_INCLUDED = NRF_UARTE_PARITY_INCLUDED,
+#endif
+} nrf_uarte_parity_t;
+
+/**
+ * @enum nrf_uarte_hwfc_t
+ * @brief Types of UARTE flow control modes.
+ */
+typedef enum
+{
+ NRF_UARTE_HWFC_DISABLED = UARTE_CONFIG_HWFC_Disabled << UARTE_CONFIG_HWFC_Pos, ///< HW flow control disabled.
+ NRF_UARTE_HWFC_ENABLED = UARTE_CONFIG_HWFC_Enabled << UARTE_CONFIG_HWFC_Pos, ///< HW flow control enabled.
+#ifndef UART_PRESENT
+ NRF_UART_HWFC_DISABLED = NRF_UARTE_HWFC_DISABLED,
+ NRF_UART_HWFC_ENABLED = NRF_UARTE_HWFC_ENABLED,
+#endif
+} nrf_uarte_hwfc_t;
+
+
+/**
+ * @brief Function for clearing a specific UARTE event.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] event Event to clear.
+ */
+__STATIC_INLINE void nrf_uarte_event_clear(NRF_UARTE_Type * p_reg, nrf_uarte_event_t event);
+
+/**
+ * @brief Function for checking the state of a specific UARTE event.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] event Event to check.
+ *
+ * @retval True if event is set, False otherwise.
+ */
+__STATIC_INLINE bool nrf_uarte_event_check(NRF_UARTE_Type * p_reg, nrf_uarte_event_t event);
+
+/**
+ * @brief Function for returning the address of a specific UARTE event register.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] event Desired event.
+ *
+ * @retval Address of specified event register.
+ */
+__STATIC_INLINE uint32_t nrf_uarte_event_address_get(NRF_UARTE_Type * p_reg,
+ nrf_uarte_event_t event);
+
+/**
+ * @brief Function for enabling UARTE shortcuts.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ * @param shorts_mask Shortcuts to enable.
+ */
+__STATIC_INLINE void nrf_uarte_shorts_enable(NRF_UARTE_Type * p_reg, uint32_t shorts_mask);
+
+/**
+ * @brief Function for disabling UARTE shortcuts.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ * @param shorts_mask Shortcuts to disable.
+ */
+__STATIC_INLINE void nrf_uarte_shorts_disable(NRF_UARTE_Type * p_reg, uint32_t shorts_mask);
+
+/**
+ * @brief Function for enabling UARTE interrupts.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ * @param int_mask Interrupts to enable.
+ */
+__STATIC_INLINE void nrf_uarte_int_enable(NRF_UARTE_Type * p_reg, uint32_t int_mask);
+
+/**
+ * @brief Function for retrieving the state of a given interrupt.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ * @param int_mask Mask of interrupt to check.
+ *
+ * @retval true If the interrupt is enabled.
+ * @retval false If the interrupt is not enabled.
+ */
+__STATIC_INLINE bool nrf_uarte_int_enable_check(NRF_UARTE_Type * p_reg, nrf_uarte_int_mask_t int_mask);
+
+/**
+ * @brief Function for disabling specific interrupts.
+ *
+ * @param p_reg Instance.
+ * @param int_mask Interrupts to disable.
+ */
+__STATIC_INLINE void nrf_uarte_int_disable(NRF_UARTE_Type * p_reg, uint32_t int_mask);
+
+/**
+ * @brief Function for getting error source mask. Function is clearing error source flags after reading.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ * @return Mask with error source flags.
+ */
+__STATIC_INLINE uint32_t nrf_uarte_errorsrc_get_and_clear(NRF_UARTE_Type * p_reg);
+
+/**
+ * @brief Function for enabling UARTE.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE void nrf_uarte_enable(NRF_UARTE_Type * p_reg);
+
+/**
+ * @brief Function for disabling UARTE.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE void nrf_uarte_disable(NRF_UARTE_Type * p_reg);
+
+/**
+ * @brief Function for configuring TX/RX pins.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ * @param pseltxd TXD pin number.
+ * @param pselrxd RXD pin number.
+ */
+__STATIC_INLINE void nrf_uarte_txrx_pins_set(NRF_UARTE_Type * p_reg, uint32_t pseltxd, uint32_t pselrxd);
+
+/**
+ * @brief Function for disconnecting TX/RX pins.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE void nrf_uarte_txrx_pins_disconnect(NRF_UARTE_Type * p_reg);
+
+/**
+ * @brief Function for getting TX pin.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE uint32_t nrf_uarte_tx_pin_get(NRF_UARTE_Type * p_reg);
+
+/**
+ * @brief Function for getting RX pin.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE uint32_t nrf_uarte_rx_pin_get(NRF_UARTE_Type * p_reg);
+
+/**
+ * @brief Function for getting RTS pin.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE uint32_t nrf_uarte_rts_pin_get(NRF_UARTE_Type * p_reg);
+
+/**
+ * @brief Function for getting CTS pin.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE uint32_t nrf_uarte_cts_pin_get(NRF_UARTE_Type * p_reg);
+
+
+/**
+ * @brief Function for configuring flow control pins.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ * @param pselrts RTS pin number.
+ * @param pselcts CTS pin number.
+ */
+__STATIC_INLINE void nrf_uarte_hwfc_pins_set(NRF_UARTE_Type * p_reg,
+ uint32_t pselrts,
+ uint32_t pselcts);
+
+/**
+ * @brief Function for disconnecting flow control pins.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ */
+__STATIC_INLINE void nrf_uarte_hwfc_pins_disconnect(NRF_UARTE_Type * p_reg);
+
+/**
+ * @brief Function for starting an UARTE task.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ * @param task Task.
+ */
+__STATIC_INLINE void nrf_uarte_task_trigger(NRF_UARTE_Type * p_reg, nrf_uarte_task_t task);
+
+/**
+ * @brief Function for returning the address of a specific task register.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ * @param task Task.
+ *
+ * @return Task address.
+ */
+__STATIC_INLINE uint32_t nrf_uarte_task_address_get(NRF_UARTE_Type * p_reg, nrf_uarte_task_t task);
+
+/**
+ * @brief Function for configuring UARTE.
+ *
+ * @param p_reg Pointer to the peripheral registers structure.
+ * @param hwfc Hardware flow control. Enabled if true.
+ * @param parity Parity. Included if true.
+ */
+__STATIC_INLINE void nrf_uarte_configure(NRF_UARTE_Type * p_reg,
+ nrf_uarte_parity_t parity,
+ nrf_uarte_hwfc_t hwfc);
+
+
+/**
+ * @brief Function for setting UARTE baudrate.
+ *
+ * @param p_reg Instance.
+ * @param baudrate Baudrate.
+ */
+__STATIC_INLINE void nrf_uarte_baudrate_set(NRF_UARTE_Type * p_reg, nrf_uarte_baudrate_t baudrate);
+
+/**
+ * @brief Function for setting the transmit buffer.
+ *
+ * @param[in] p_reg Instance.
+ * @param[in] p_buffer Pointer to the buffer with data to send.
+ * @param[in] length Maximum number of data bytes to transmit.
+ */
+__STATIC_INLINE void nrf_uarte_tx_buffer_set(NRF_UARTE_Type * p_reg,
+ uint8_t const * p_buffer,
+ uint8_t length);
+
+/**
+ * @brief Function for getting number of bytes transmitted in the last transaction.
+ *
+ * @param[in] p_reg Instance.
+ *
+ * @retval Amount of bytes transmitted.
+ */
+__STATIC_INLINE uint32_t nrf_uarte_tx_amount_get(NRF_UARTE_Type * p_reg);
+
+/**
+ * @brief Function for setting the receive buffer.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ * @param[in] p_buffer Pointer to the buffer for received data.
+ * @param[in] length Maximum number of data bytes to receive.
+ */
+__STATIC_INLINE void nrf_uarte_rx_buffer_set(NRF_UARTE_Type * p_reg,
+ uint8_t * p_buffer,
+ uint8_t length);
+
+/**
+ * @brief Function for getting number of bytes received in the last transaction.
+ *
+ * @param[in] p_reg Pointer to the peripheral registers structure.
+ *
+ * @retval Amount of bytes received.
+ */
+__STATIC_INLINE uint32_t nrf_uarte_rx_amount_get(NRF_UARTE_Type * p_reg);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+__STATIC_INLINE void nrf_uarte_event_clear(NRF_UARTE_Type * p_reg, nrf_uarte_event_t event)
+{
+ *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
+#if __CORTEX_M == 0x04
+ volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event));
+ (void)dummy;
+#endif
+
+}
+
+__STATIC_INLINE bool nrf_uarte_event_check(NRF_UARTE_Type * p_reg, nrf_uarte_event_t event)
+{
+ return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
+}
+
+__STATIC_INLINE uint32_t nrf_uarte_event_address_get(NRF_UARTE_Type * p_reg,
+ nrf_uarte_event_t event)
+{
+ return (uint32_t)((uint8_t *)p_reg + (uint32_t)event);
+}
+
+__STATIC_INLINE void nrf_uarte_shorts_enable(NRF_UARTE_Type * p_reg, uint32_t shorts_mask)
+{
+ p_reg->SHORTS |= shorts_mask;
+}
+
+__STATIC_INLINE void nrf_uarte_shorts_disable(NRF_UARTE_Type * p_reg, uint32_t shorts_mask)
+{
+ p_reg->SHORTS &= ~(shorts_mask);
+}
+
+__STATIC_INLINE void nrf_uarte_int_enable(NRF_UARTE_Type * p_reg, uint32_t int_mask)
+{
+ p_reg->INTENSET = int_mask;
+}
+
+__STATIC_INLINE bool nrf_uarte_int_enable_check(NRF_UARTE_Type * p_reg, nrf_uarte_int_mask_t int_mask)
+{
+ return (bool)(p_reg->INTENSET & int_mask);
+}
+
+__STATIC_INLINE void nrf_uarte_int_disable(NRF_UARTE_Type * p_reg, uint32_t int_mask)
+{
+ p_reg->INTENCLR = int_mask;
+}
+
+__STATIC_INLINE uint32_t nrf_uarte_errorsrc_get_and_clear(NRF_UARTE_Type * p_reg)
+{
+ uint32_t errsrc_mask = p_reg->ERRORSRC;
+ p_reg->ERRORSRC = errsrc_mask;
+ return errsrc_mask;
+}
+
+__STATIC_INLINE void nrf_uarte_enable(NRF_UARTE_Type * p_reg)
+{
+ p_reg->ENABLE = UARTE_ENABLE_ENABLE_Enabled;
+}
+
+__STATIC_INLINE void nrf_uarte_disable(NRF_UARTE_Type * p_reg)
+{
+ p_reg->ENABLE = UARTE_ENABLE_ENABLE_Disabled;
+}
+
+__STATIC_INLINE void nrf_uarte_txrx_pins_set(NRF_UARTE_Type * p_reg, uint32_t pseltxd, uint32_t pselrxd)
+{
+ p_reg->PSEL.TXD = pseltxd;
+ p_reg->PSEL.RXD = pselrxd;
+}
+
+__STATIC_INLINE void nrf_uarte_txrx_pins_disconnect(NRF_UARTE_Type * p_reg)
+{
+ nrf_uarte_txrx_pins_set(p_reg, NRF_UARTE_PSEL_DISCONNECTED, NRF_UARTE_PSEL_DISCONNECTED);
+}
+
+__STATIC_INLINE uint32_t nrf_uarte_tx_pin_get(NRF_UARTE_Type * p_reg)
+{
+ return p_reg->PSEL.TXD;
+}
+
+__STATIC_INLINE uint32_t nrf_uarte_rx_pin_get(NRF_UARTE_Type * p_reg)
+{
+ return p_reg->PSEL.RXD;
+}
+
+__STATIC_INLINE uint32_t nrf_uarte_rts_pin_get(NRF_UARTE_Type * p_reg)
+{
+ return p_reg->PSEL.RTS;
+}
+
+__STATIC_INLINE uint32_t nrf_uarte_cts_pin_get(NRF_UARTE_Type * p_reg)
+{
+ return p_reg->PSEL.CTS;
+}
+
+__STATIC_INLINE void nrf_uarte_hwfc_pins_set(NRF_UARTE_Type * p_reg, uint32_t pselrts, uint32_t pselcts)
+{
+ p_reg->PSEL.RTS = pselrts;
+ p_reg->PSEL.CTS = pselcts;
+}
+
+__STATIC_INLINE void nrf_uarte_hwfc_pins_disconnect(NRF_UARTE_Type * p_reg)
+{
+ nrf_uarte_hwfc_pins_set(p_reg, NRF_UARTE_PSEL_DISCONNECTED, NRF_UARTE_PSEL_DISCONNECTED);
+}
+
+__STATIC_INLINE void nrf_uarte_task_trigger(NRF_UARTE_Type * p_reg, nrf_uarte_task_t task)
+{
+ *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
+}
+
+__STATIC_INLINE uint32_t nrf_uarte_task_address_get(NRF_UARTE_Type * p_reg, nrf_uarte_task_t task)
+{
+ return (uint32_t)p_reg + (uint32_t)task;
+}
+
+__STATIC_INLINE void nrf_uarte_configure(NRF_UARTE_Type * p_reg,
+ nrf_uarte_parity_t parity,
+ nrf_uarte_hwfc_t hwfc)
+{
+ p_reg->CONFIG = (uint32_t)parity | (uint32_t)hwfc;
+}
+
+__STATIC_INLINE void nrf_uarte_baudrate_set(NRF_UARTE_Type * p_reg, nrf_uarte_baudrate_t baudrate)
+{
+ p_reg->BAUDRATE = baudrate;
+}
+
+__STATIC_INLINE void nrf_uarte_tx_buffer_set(NRF_UARTE_Type * p_reg,
+ uint8_t const * p_buffer,
+ uint8_t length)
+{
+ p_reg->TXD.PTR = (uint32_t)p_buffer;
+ p_reg->TXD.MAXCNT = length;
+}
+
+__STATIC_INLINE uint32_t nrf_uarte_tx_amount_get(NRF_UARTE_Type * p_reg)
+{
+ return p_reg->TXD.AMOUNT;
+}
+
+__STATIC_INLINE void nrf_uarte_rx_buffer_set(NRF_UARTE_Type * p_reg,
+ uint8_t * p_buffer,
+ uint8_t length)
+{
+ p_reg->RXD.PTR = (uint32_t)p_buffer;
+ p_reg->RXD.MAXCNT = length;
+}
+
+__STATIC_INLINE uint32_t nrf_uarte_rx_amount_get(NRF_UARTE_Type * p_reg)
+{
+ return p_reg->RXD.AMOUNT;
+}
+#endif //SUPPRESS_INLINE_IMPLEMENTATION
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //NRF_UARTE_H__
+
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_usbd.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_usbd.h
new file mode 100644
index 000000000..8905788db
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_usbd.h
@@ -0,0 +1,1435 @@
+/**
+ * Copyright (c) 2017 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_USBD_H__
+#define NRF_USBD_H__
+
+/**
+ * @ingroup nrf_drivers
+ * @defgroup nrf_usbd_hal USBD HAL
+ * @{
+ *
+ * @brief @tagAPI52840 Hardware access layer for Universal Serial Bus Device (USBD) peripheral.
+ */
+
+#include "nrf_peripherals.h"
+#include "nrf.h"
+#include "nrf_assert.h"
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief USBD tasks
+ */
+typedef enum
+{
+ /*lint -save -e30*/
+ NRF_USBD_TASK_STARTEPIN0 = offsetof(NRF_USBD_Type, TASKS_STARTEPIN[0] ), /**< Captures the EPIN[0].PTR, EPIN[0].MAXCNT and EPIN[0].CONFIG registers values, and enables control endpoint IN 0 to respond to traffic from host */
+ NRF_USBD_TASK_STARTEPIN1 = offsetof(NRF_USBD_Type, TASKS_STARTEPIN[1] ), /**< Captures the EPIN[1].PTR, EPIN[1].MAXCNT and EPIN[1].CONFIG registers values, and enables data endpoint IN 1 to respond to traffic from host */
+ NRF_USBD_TASK_STARTEPIN2 = offsetof(NRF_USBD_Type, TASKS_STARTEPIN[2] ), /**< Captures the EPIN[2].PTR, EPIN[2].MAXCNT and EPIN[2].CONFIG registers values, and enables data endpoint IN 2 to respond to traffic from host */
+ NRF_USBD_TASK_STARTEPIN3 = offsetof(NRF_USBD_Type, TASKS_STARTEPIN[3] ), /**< Captures the EPIN[3].PTR, EPIN[3].MAXCNT and EPIN[3].CONFIG registers values, and enables data endpoint IN 3 to respond to traffic from host */
+ NRF_USBD_TASK_STARTEPIN4 = offsetof(NRF_USBD_Type, TASKS_STARTEPIN[4] ), /**< Captures the EPIN[4].PTR, EPIN[4].MAXCNT and EPIN[4].CONFIG registers values, and enables data endpoint IN 4 to respond to traffic from host */
+ NRF_USBD_TASK_STARTEPIN5 = offsetof(NRF_USBD_Type, TASKS_STARTEPIN[5] ), /**< Captures the EPIN[5].PTR, EPIN[5].MAXCNT and EPIN[5].CONFIG registers values, and enables data endpoint IN 5 to respond to traffic from host */
+ NRF_USBD_TASK_STARTEPIN6 = offsetof(NRF_USBD_Type, TASKS_STARTEPIN[6] ), /**< Captures the EPIN[6].PTR, EPIN[6].MAXCNT and EPIN[6].CONFIG registers values, and enables data endpoint IN 6 to respond to traffic from host */
+ NRF_USBD_TASK_STARTEPIN7 = offsetof(NRF_USBD_Type, TASKS_STARTEPIN[7] ), /**< Captures the EPIN[7].PTR, EPIN[7].MAXCNT and EPIN[7].CONFIG registers values, and enables data endpoint IN 7 to respond to traffic from host */
+ NRF_USBD_TASK_STARTISOIN = offsetof(NRF_USBD_Type, TASKS_STARTISOIN ), /**< Captures the ISOIN.PTR, ISOIN.MAXCNT and ISOIN.CONFIG registers values, and enables sending data on iso endpoint 8 */
+ NRF_USBD_TASK_STARTEPOUT0 = offsetof(NRF_USBD_Type, TASKS_STARTEPOUT[0]), /**< Captures the EPOUT[0].PTR, EPOUT[0].MAXCNT and EPOUT[0].CONFIG registers values, and enables control endpoint 0 to respond to traffic from host */
+ NRF_USBD_TASK_STARTEPOUT1 = offsetof(NRF_USBD_Type, TASKS_STARTEPOUT[1]), /**< Captures the EPOUT[1].PTR, EPOUT[1].MAXCNT and EPOUT[1].CONFIG registers values, and enables data endpoint 1 to respond to traffic from host */
+ NRF_USBD_TASK_STARTEPOUT2 = offsetof(NRF_USBD_Type, TASKS_STARTEPOUT[2]), /**< Captures the EPOUT[2].PTR, EPOUT[2].MAXCNT and EPOUT[2].CONFIG registers values, and enables data endpoint 2 to respond to traffic from host */
+ NRF_USBD_TASK_STARTEPOUT3 = offsetof(NRF_USBD_Type, TASKS_STARTEPOUT[3]), /**< Captures the EPOUT[3].PTR, EPOUT[3].MAXCNT and EPOUT[3].CONFIG registers values, and enables data endpoint 3 to respond to traffic from host */
+ NRF_USBD_TASK_STARTEPOUT4 = offsetof(NRF_USBD_Type, TASKS_STARTEPOUT[4]), /**< Captures the EPOUT[4].PTR, EPOUT[4].MAXCNT and EPOUT[4].CONFIG registers values, and enables data endpoint 4 to respond to traffic from host */
+ NRF_USBD_TASK_STARTEPOUT5 = offsetof(NRF_USBD_Type, TASKS_STARTEPOUT[5]), /**< Captures the EPOUT[5].PTR, EPOUT[5].MAXCNT and EPOUT[5].CONFIG registers values, and enables data endpoint 5 to respond to traffic from host */
+ NRF_USBD_TASK_STARTEPOUT6 = offsetof(NRF_USBD_Type, TASKS_STARTEPOUT[6]), /**< Captures the EPOUT[6].PTR, EPOUT[6].MAXCNT and EPOUT[6].CONFIG registers values, and enables data endpoint 6 to respond to traffic from host */
+ NRF_USBD_TASK_STARTEPOUT7 = offsetof(NRF_USBD_Type, TASKS_STARTEPOUT[7]), /**< Captures the EPOUT[7].PTR, EPOUT[7].MAXCNT and EPOUT[7].CONFIG registers values, and enables data endpoint 7 to respond to traffic from host */
+ NRF_USBD_TASK_STARTISOOUT = offsetof(NRF_USBD_Type, TASKS_STARTISOOUT ), /**< Captures the ISOOUT.PTR, ISOOUT.MAXCNT and ISOOUT.CONFIG registers values, and enables receiving of data on iso endpoint 8 */
+ NRF_USBD_TASK_EP0RCVOUT = offsetof(NRF_USBD_Type, TASKS_EP0RCVOUT ), /**< Allows OUT data stage on control endpoint 0 */
+ NRF_USBD_TASK_EP0STATUS = offsetof(NRF_USBD_Type, TASKS_EP0STATUS ), /**< Allows status stage on control endpoint 0 */
+ NRF_USBD_TASK_EP0STALL = offsetof(NRF_USBD_Type, TASKS_EP0STALL ), /**< STALLs data and status stage on control endpoint 0 */
+ NRF_USBD_TASK_DRIVEDPDM = offsetof(NRF_USBD_Type, TASKS_DPDMDRIVE ), /**< Forces D+ and D-lines to the state defined in the DPDMVALUE register */
+ NRF_USBD_TASK_NODRIVEDPDM = offsetof(NRF_USBD_Type, TASKS_DPDMNODRIVE ), /**< Stops forcing D+ and D- lines to any state (USB engine takes control) */
+ /*lint -restore*/
+}nrf_usbd_task_t;
+
+/**
+ * @brief USBD events
+ */
+typedef enum
+{
+ /*lint -save -e30*/
+ NRF_USBD_EVENT_USBRESET = offsetof(NRF_USBD_Type, EVENTS_USBRESET ), /**< Signals that a USB reset condition has been detected on the USB lines */
+ NRF_USBD_EVENT_STARTED = offsetof(NRF_USBD_Type, EVENTS_STARTED ), /**< Confirms that the EPIN[n].PTR, EPIN[n].MAXCNT, EPIN[n].CONFIG, or EPOUT[n].PTR, EPOUT[n].MAXCNT and EPOUT[n].CONFIG registers have been captured on all endpoints reported in the EPSTATUS register */
+ NRF_USBD_EVENT_ENDEPIN0 = offsetof(NRF_USBD_Type, EVENTS_ENDEPIN[0] ), /**< The whole EPIN[0] buffer has been consumed. The RAM buffer can be accessed safely by software. */
+ NRF_USBD_EVENT_ENDEPIN1 = offsetof(NRF_USBD_Type, EVENTS_ENDEPIN[1] ), /**< The whole EPIN[1] buffer has been consumed. The RAM buffer can be accessed safely by software. */
+ NRF_USBD_EVENT_ENDEPIN2 = offsetof(NRF_USBD_Type, EVENTS_ENDEPIN[2] ), /**< The whole EPIN[2] buffer has been consumed. The RAM buffer can be accessed safely by software. */
+ NRF_USBD_EVENT_ENDEPIN3 = offsetof(NRF_USBD_Type, EVENTS_ENDEPIN[3] ), /**< The whole EPIN[3] buffer has been consumed. The RAM buffer can be accessed safely by software. */
+ NRF_USBD_EVENT_ENDEPIN4 = offsetof(NRF_USBD_Type, EVENTS_ENDEPIN[4] ), /**< The whole EPIN[4] buffer has been consumed. The RAM buffer can be accessed safely by software. */
+ NRF_USBD_EVENT_ENDEPIN5 = offsetof(NRF_USBD_Type, EVENTS_ENDEPIN[5] ), /**< The whole EPIN[5] buffer has been consumed. The RAM buffer can be accessed safely by software. */
+ NRF_USBD_EVENT_ENDEPIN6 = offsetof(NRF_USBD_Type, EVENTS_ENDEPIN[6] ), /**< The whole EPIN[6] buffer has been consumed. The RAM buffer can be accessed safely by software. */
+ NRF_USBD_EVENT_ENDEPIN7 = offsetof(NRF_USBD_Type, EVENTS_ENDEPIN[7] ), /**< The whole EPIN[7] buffer has been consumed. The RAM buffer can be accessed safely by software. */
+ NRF_USBD_EVENT_EP0DATADONE = offsetof(NRF_USBD_Type, EVENTS_EP0DATADONE), /**< An acknowledged data transfer has taken place on the control endpoint */
+ NRF_USBD_EVENT_ENDISOIN0 = offsetof(NRF_USBD_Type, EVENTS_ENDISOIN ), /**< The whole ISOIN buffer has been consumed. The RAM buffer can be accessed safely by software. */
+ NRF_USBD_EVENT_ENDEPOUT0 = offsetof(NRF_USBD_Type, EVENTS_ENDEPOUT[0]), /**< The whole EPOUT[0] buffer has been consumed. The RAM buffer can be accessed safely by software. */
+ NRF_USBD_EVENT_ENDEPOUT1 = offsetof(NRF_USBD_Type, EVENTS_ENDEPOUT[1]), /**< The whole EPOUT[1] buffer has been consumed. The RAM buffer can be accessed safely by software. */
+ NRF_USBD_EVENT_ENDEPOUT2 = offsetof(NRF_USBD_Type, EVENTS_ENDEPOUT[2]), /**< The whole EPOUT[2] buffer has been consumed. The RAM buffer can be accessed safely by software. */
+ NRF_USBD_EVENT_ENDEPOUT3 = offsetof(NRF_USBD_Type, EVENTS_ENDEPOUT[3]), /**< The whole EPOUT[3] buffer has been consumed. The RAM buffer can be accessed safely by software. */
+ NRF_USBD_EVENT_ENDEPOUT4 = offsetof(NRF_USBD_Type, EVENTS_ENDEPOUT[4]), /**< The whole EPOUT[4] buffer has been consumed. The RAM buffer can be accessed safely by software. */
+ NRF_USBD_EVENT_ENDEPOUT5 = offsetof(NRF_USBD_Type, EVENTS_ENDEPOUT[5]), /**< The whole EPOUT[5] buffer has been consumed. The RAM buffer can be accessed safely by software. */
+ NRF_USBD_EVENT_ENDEPOUT6 = offsetof(NRF_USBD_Type, EVENTS_ENDEPOUT[6]), /**< The whole EPOUT[6] buffer has been consumed. The RAM buffer can be accessed safely by software. */
+ NRF_USBD_EVENT_ENDEPOUT7 = offsetof(NRF_USBD_Type, EVENTS_ENDEPOUT[7]), /**< The whole EPOUT[7] buffer has been consumed. The RAM buffer can be accessed safely by software. */
+ NRF_USBD_EVENT_ENDISOOUT0 = offsetof(NRF_USBD_Type, EVENTS_ENDISOOUT ), /**< The whole ISOOUT buffer has been consumed. The RAM buffer can be accessed safely by software. */
+ NRF_USBD_EVENT_SOF = offsetof(NRF_USBD_Type, EVENTS_SOF ), /**< Signals that a SOF (start of frame) condition has been detected on the USB lines */
+ NRF_USBD_EVENT_USBEVENT = offsetof(NRF_USBD_Type, EVENTS_USBEVENT ), /**< An event or an error not covered by specific events has occurred, check EVENTCAUSE register to find the cause */
+ NRF_USBD_EVENT_EP0SETUP = offsetof(NRF_USBD_Type, EVENTS_EP0SETUP ), /**< A valid SETUP token has been received (and acknowledged) on the control endpoint */
+ NRF_USBD_EVENT_DATAEP = offsetof(NRF_USBD_Type, EVENTS_EPDATA ), /**< A data transfer has occurred on a data endpoint, indicated by the EPDATASTATUS register */
+ NRF_USBD_EVENT_ACCESSFAULT = offsetof(NRF_USBD_Type, EVENTS_ACCESSFAULT), /**< >Access to an unavailable USB register has been attempted (software or EasyDMA) */
+ /*lint -restore*/
+}nrf_usbd_event_t;
+
+/**
+ * @brief USBD shorts
+ */
+typedef enum
+{
+ NRF_USBD_SHORT_EP0DATADONE_STARTEPIN0_MASK = USBD_SHORTS_EP0DATADONE_STARTEPIN0_Msk , /**< Shortcut between EP0DATADONE event and STARTEPIN0 task */
+ NRF_USBD_SHORT_EP0DATADONE_STARTEPOUT0_MASK = USBD_SHORTS_EP0DATADONE_STARTEPOUT0_Msk, /**< Shortcut between EP0DATADONE event and STARTEPOUT0 task */
+ NRF_USBD_SHORT_EP0DATADONE_EP0STATUS_MASK = USBD_SHORTS_EP0DATADONE_EP0STATUS_Msk , /**< Shortcut between EP0DATADONE event and EP0STATUS task */
+ NRF_USBD_SHORT_ENDEPOUT0_EP0STATUS_MASK = USBD_SHORTS_ENDEPOUT0_EP0STATUS_Msk , /**< Shortcut between ENDEPOUT[0] event and EP0STATUS task */
+ NRF_USBD_SHORT_ENDEPOUT0_EP0RCVOUT_MASK = USBD_SHORTS_ENDEPOUT0_EP0RCVOUT_Msk , /**< Shortcut between ENDEPOUT[0] event and EP0RCVOUT task */
+}nrf_usbd_short_mask_t;
+
+/**
+ * @brief USBD interrupts
+ */
+typedef enum
+{
+ NRF_USBD_INT_USBRESET_MASK = USBD_INTEN_USBRESET_Msk , /**< Enable or disable interrupt for USBRESET event */
+ NRF_USBD_INT_STARTED_MASK = USBD_INTEN_STARTED_Msk , /**< Enable or disable interrupt for STARTED event */
+ NRF_USBD_INT_ENDEPIN0_MASK = USBD_INTEN_ENDEPIN0_Msk , /**< Enable or disable interrupt for ENDEPIN[0] event */
+ NRF_USBD_INT_ENDEPIN1_MASK = USBD_INTEN_ENDEPIN1_Msk , /**< Enable or disable interrupt for ENDEPIN[1] event */
+ NRF_USBD_INT_ENDEPIN2_MASK = USBD_INTEN_ENDEPIN2_Msk , /**< Enable or disable interrupt for ENDEPIN[2] event */
+ NRF_USBD_INT_ENDEPIN3_MASK = USBD_INTEN_ENDEPIN3_Msk , /**< Enable or disable interrupt for ENDEPIN[3] event */
+ NRF_USBD_INT_ENDEPIN4_MASK = USBD_INTEN_ENDEPIN4_Msk , /**< Enable or disable interrupt for ENDEPIN[4] event */
+ NRF_USBD_INT_ENDEPIN5_MASK = USBD_INTEN_ENDEPIN5_Msk , /**< Enable or disable interrupt for ENDEPIN[5] event */
+ NRF_USBD_INT_ENDEPIN6_MASK = USBD_INTEN_ENDEPIN6_Msk , /**< Enable or disable interrupt for ENDEPIN[6] event */
+ NRF_USBD_INT_ENDEPIN7_MASK = USBD_INTEN_ENDEPIN7_Msk , /**< Enable or disable interrupt for ENDEPIN[7] event */
+ NRF_USBD_INT_EP0DATADONE_MASK = USBD_INTEN_EP0DATADONE_Msk, /**< Enable or disable interrupt for EP0DATADONE event */
+ NRF_USBD_INT_ENDISOIN0_MASK = USBD_INTEN_ENDISOIN_Msk , /**< Enable or disable interrupt for ENDISOIN[0] event */
+ NRF_USBD_INT_ENDEPOUT0_MASK = USBD_INTEN_ENDEPOUT0_Msk , /**< Enable or disable interrupt for ENDEPOUT[0] event */
+ NRF_USBD_INT_ENDEPOUT1_MASK = USBD_INTEN_ENDEPOUT1_Msk , /**< Enable or disable interrupt for ENDEPOUT[1] event */
+ NRF_USBD_INT_ENDEPOUT2_MASK = USBD_INTEN_ENDEPOUT2_Msk , /**< Enable or disable interrupt for ENDEPOUT[2] event */
+ NRF_USBD_INT_ENDEPOUT3_MASK = USBD_INTEN_ENDEPOUT3_Msk , /**< Enable or disable interrupt for ENDEPOUT[3] event */
+ NRF_USBD_INT_ENDEPOUT4_MASK = USBD_INTEN_ENDEPOUT4_Msk , /**< Enable or disable interrupt for ENDEPOUT[4] event */
+ NRF_USBD_INT_ENDEPOUT5_MASK = USBD_INTEN_ENDEPOUT5_Msk , /**< Enable or disable interrupt for ENDEPOUT[5] event */
+ NRF_USBD_INT_ENDEPOUT6_MASK = USBD_INTEN_ENDEPOUT6_Msk , /**< Enable or disable interrupt for ENDEPOUT[6] event */
+ NRF_USBD_INT_ENDEPOUT7_MASK = USBD_INTEN_ENDEPOUT7_Msk , /**< Enable or disable interrupt for ENDEPOUT[7] event */
+ NRF_USBD_INT_ENDISOOUT0_MASK = USBD_INTEN_ENDISOOUT_Msk , /**< Enable or disable interrupt for ENDISOOUT[0] event */
+ NRF_USBD_INT_SOF_MASK = USBD_INTEN_SOF_Msk , /**< Enable or disable interrupt for SOF event */
+ NRF_USBD_INT_USBEVENT_MASK = USBD_INTEN_USBEVENT_Msk , /**< Enable or disable interrupt for USBEVENT event */
+ NRF_USBD_INT_EP0SETUP_MASK = USBD_INTEN_EP0SETUP_Msk , /**< Enable or disable interrupt for EP0SETUP event */
+ NRF_USBD_INT_DATAEP_MASK = USBD_INTEN_EPDATA_Msk , /**< Enable or disable interrupt for EPDATA event */
+ NRF_USBD_INT_ACCESSFAULT_MASK = USBD_INTEN_ACCESSFAULT_Msk, /**< Enable or disable interrupt for ACCESSFAULT event */
+}nrf_usbd_int_mask_t;
+
+
+/**
+ * @brief Function for activating a specific USBD task.
+ *
+ * @param task Task.
+ */
+__STATIC_INLINE void nrf_usbd_task_trigger(nrf_usbd_task_t task);
+
+/**
+ * @brief Function for returning the address of a specific USBD task register.
+ *
+ * @param task Task.
+ *
+ * @return Task address.
+ */
+__STATIC_INLINE uint32_t nrf_usbd_task_address_get(nrf_usbd_task_t task);
+
+/**
+ * @brief Function for clearing a specific event.
+ *
+ * @param event Event.
+ */
+__STATIC_INLINE void nrf_usbd_event_clear(nrf_usbd_event_t event);
+
+/**
+ * @brief Function for returning the state of a specific event.
+ *
+ * @param event Event.
+ *
+ * @retval true If the event is set.
+ * @retval false If the event is not set.
+ */
+__STATIC_INLINE bool nrf_usbd_event_check(nrf_usbd_event_t event);
+
+/**
+ * @brief Function for getting and clearing the state of specific event
+ *
+ * This function checks the state of the event and clears it.
+ *
+ * @param event Event.
+ *
+ * @retval true If the event was set.
+ * @retval false If the event was not set.
+ */
+__STATIC_INLINE bool nrf_usbd_event_get_and_clear(nrf_usbd_event_t event);
+
+/**
+ * @brief Function for returning the address of a specific USBD event register.
+ *
+ * @param event Event.
+ *
+ * @return Address.
+ */
+__STATIC_INLINE uint32_t nrf_usbd_event_address_get(nrf_usbd_event_t event);
+
+/**
+ * @brief Function for setting a shortcut.
+ *
+ * @param short_mask Shortcuts mask.
+ */
+__STATIC_INLINE void nrf_usbd_shorts_enable(uint32_t short_mask);
+
+/**
+ * @brief Function for clearing shortcuts.
+ *
+ * @param short_mask Shortcuts mask.
+ */
+__STATIC_INLINE void nrf_usbd_shorts_disable(uint32_t short_mask);
+
+/**
+ * @brief Get the shorts mask
+ *
+ * Function returns shorts register.
+ *
+ * @return Flags of currently enabled shortcuts
+ */
+__STATIC_INLINE uint32_t nrf_usbd_shorts_get(void);
+
+/**
+ * @brief Function for enabling selected interrupts.
+ *
+ * @param int_mask Interrupts mask.
+ */
+__STATIC_INLINE void nrf_usbd_int_enable(uint32_t int_mask);
+
+/**
+ * @brief Function for retrieving the state of selected interrupts.
+ *
+ * @param int_mask Interrupts mask.
+ *
+ * @retval true If any of selected interrupts is enabled.
+ * @retval false If none of selected interrupts is enabled.
+ */
+__STATIC_INLINE bool nrf_usbd_int_enable_check(uint32_t int_mask);
+
+/**
+ * @brief Function for retrieving the information about enabled interrupts.
+ *
+ * @return The flags of enabled interrupts.
+ */
+__STATIC_INLINE uint32_t nrf_usbd_int_enable_get(void);
+
+/**
+ * @brief Function for disabling selected interrupts.
+ *
+ * @param int_mask Interrupts mask.
+ */
+__STATIC_INLINE void nrf_usbd_int_disable(uint32_t int_mask);
+
+
+/** @} */ /* End of nrf_usbd_hal */
+
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+/* ------------------------------------------------------------------------------------------------
+ * Internal functions
+ */
+
+/**
+ * @internal
+ * @brief Internal function for getting task/event register address
+ *
+ * @oaram offset Offset of the register from the instance beginning
+ *
+ * @attention offset has to be modulo 4 value. In other case we can get hardware fault.
+ * @return Pointer to the register
+ */
+__STATIC_INLINE volatile uint32_t* nrf_usbd_getRegPtr(uint32_t offset)
+{
+ return (volatile uint32_t*)(((uint8_t *)NRF_USBD) + (uint32_t)offset);
+}
+
+/**
+ * @internal
+ * @brief Internal function for getting task/event register address - constant version
+ *
+ * @oaram offset Offset of the register from the instance beginning
+ *
+ * @attention offset has to be modulo 4 value. In other case we can get hardware fault.
+ * @return Pointer to the register
+ */
+__STATIC_INLINE volatile const uint32_t* nrf_usbd_getRegPtr_c(uint32_t offset)
+{
+ return (volatile const uint32_t*)(((uint8_t *)NRF_USBD) + (uint32_t)offset);
+}
+
+/* ------------------------------------------------------------------------------------------------
+ * Interface functions definitions
+ */
+
+void nrf_usbd_task_trigger(nrf_usbd_task_t task)
+{
+ *(nrf_usbd_getRegPtr((uint32_t)task)) = 1UL;
+ __ISB();
+ __DSB();
+}
+
+uint32_t nrf_usbd_task_address_get(nrf_usbd_task_t task)
+{
+ return (uint32_t)nrf_usbd_getRegPtr_c((uint32_t)task);
+}
+
+void nrf_usbd_event_clear(nrf_usbd_event_t event)
+{
+ *(nrf_usbd_getRegPtr((uint32_t)event)) = 0UL;
+ __ISB();
+ __DSB();
+}
+
+bool nrf_usbd_event_check(nrf_usbd_event_t event)
+{
+ return (bool)*nrf_usbd_getRegPtr_c((uint32_t)event);
+}
+
+bool nrf_usbd_event_get_and_clear(nrf_usbd_event_t event)
+{
+ bool ret = nrf_usbd_event_check(event);
+ if (ret)
+ {
+ nrf_usbd_event_clear(event);
+ }
+ return ret;
+}
+
+uint32_t nrf_usbd_event_address_get(nrf_usbd_event_t event)
+{
+ return (uint32_t)nrf_usbd_getRegPtr_c((uint32_t)event);
+}
+
+void nrf_usbd_shorts_enable(uint32_t short_mask)
+{
+ NRF_USBD->SHORTS |= short_mask;
+}
+
+void nrf_usbd_shorts_disable(uint32_t short_mask)
+{
+ if (~0U == short_mask)
+ {
+ /* Optimized version for "disable all" */
+ NRF_USBD->SHORTS = 0;
+ }
+ else
+ {
+ NRF_USBD->SHORTS &= ~short_mask;
+ }
+}
+
+uint32_t nrf_usbd_shorts_get(void)
+{
+ return NRF_USBD->SHORTS;
+}
+
+void nrf_usbd_int_enable(uint32_t int_mask)
+{
+ NRF_USBD->INTENSET = int_mask;
+}
+
+bool nrf_usbd_int_enable_check(uint32_t int_mask)
+{
+ return !!(NRF_USBD->INTENSET & int_mask);
+}
+
+uint32_t nrf_usbd_int_enable_get(void)
+{
+ return NRF_USBD->INTENSET;
+}
+
+void nrf_usbd_int_disable(uint32_t int_mask)
+{
+ NRF_USBD->INTENCLR = int_mask;
+}
+
+#endif /* SUPPRESS_INLINE_IMPLEMENTATION */
+
+/* ------------------------------------------------------------------------------------------------
+ * End of automatically generated part
+ * ------------------------------------------------------------------------------------------------
+ */
+/**
+ * @addtogroup nrf_usbd_hal
+ * @{
+ */
+
+/**
+ * @brief Frame counter size
+ *
+ * The number of counts that can be fitted into frame counter
+ */
+#define NRF_USBD_FRAMECNTR_SIZE \
+ ( (USBD_FRAMECNTR_FRAMECNTR_Msk >> USBD_FRAMECNTR_FRAMECNTR_Pos) + 1UL )
+#ifndef USBD_FRAMECNTR_FRAMECNTR_Msk
+#error USBD_FRAMECNTR_FRAMECNTR_Msk should be changed into USBD_FRAMECNTR_FRAMECNTR_Msk
+#endif
+
+/**
+ * @brief First isochronous endpoint number
+ *
+ * The number of the first isochronous endpoint
+ */
+#define NRF_USBD_EPISO_FIRST 8
+
+/**
+ * @brief Total number of IN endpoints
+ *
+ * Total number of IN endpoint (including ISOCHRONOUS).
+ */
+#define NRF_USBD_EPIN_CNT 9
+
+/**
+ * @brief Total number of OUT endpoints
+ *
+ * Total number of OUT endpoint (including ISOCHRONOUS).
+ */
+#define NRF_USBD_EPOUT_CNT 9
+
+/**
+ * @brief Mask of the direction bit in endpoint number
+ */
+#define NRF_USBD_EP_DIR_Msk (1U << 7)
+
+/**
+ * @brief The value of direction bit for IN endpoint direction
+ */
+#define NRF_USBD_EP_DIR_IN (1U << 7)
+
+/**
+ * @brief The value of direction bit for OUT endpoint direction
+ */
+#define NRF_USBD_EP_DIR_OUT (0U << 7)
+
+/**
+ * @brief Macro for making IN endpoint identifier from endpoint number
+ *
+ * Macro that sets direction bit to make IN endpoint
+ * @param[in] epnr Endpoint number
+ * @return IN Endpoint identifier
+ */
+#define NRF_USBD_EPIN(epnr) (((uint8_t)(epnr)) | NRF_USBD_EP_DIR_IN)
+
+/**
+ * @brief Macro for making OUT endpoint identifier from endpoint number
+ *
+ * Macro that sets direction bit to make OUT endpoint
+ * @param[in] epnr Endpoint number
+ * @return OUT Endpoint identifier
+ */
+#define NRF_USBD_EPOUT(epnr) (((uint8_t)(epnr)) | NRF_USBD_EP_DIR_OUT)
+
+/**
+ * @brief Macro for extracting the endpoint number from endpoint identifier
+ *
+ * Macro that strips out the information about endpoint direction.
+ * @param[in] ep Endpoint identifier
+ * @return Endpoint number
+ */
+#define NRF_USBD_EP_NR_GET(ep) ((uint8_t)(((uint8_t)(ep)) & 0xFU))
+
+/**
+ * @brief Macro for checking endpoint direction
+ *
+ * This macro checks if given endpoint has IN direction
+ * @param ep Endpoint identifier
+ * @retval true If the endpoint direction is IN
+ * @retval false If the endpoint direction is OUT
+ */
+#define NRF_USBD_EPIN_CHECK(ep) ( (((uint8_t)(ep)) & NRF_USBD_EP_DIR_Msk) == NRF_USBD_EP_DIR_IN )
+
+/**
+ * @brief Macro for checking endpoint direction
+ *
+ * This macro checks if given endpoint has OUT direction
+ * @param ep Endpoint identifier
+ * @retval true If the endpoint direction is OUT
+ * @retval false If the endpoint direction is IN
+ */
+#define NRF_USBD_EPOUT_CHECK(ep) ( (((uint8_t)(ep)) & NRF_USBD_EP_DIR_Msk) == NRF_USBD_EP_DIR_OUT )
+
+/**
+ * @brief Macro for checking if endpoint is isochronous
+ *
+ * @param ep It can be endpoint identifier or just endpoint number to check
+ * @retval true The endpoint is isochronous type
+ * @retval false The endpoint is bulk of interrupt type
+ */
+#define NRF_USBD_EPISO_CHECK(ep) (NRF_USBD_EP_NR_GET(ep) >= NRF_USBD_EPISO_FIRST)
+
+/**
+ * @brief Macro for checking if given number is valid endpoint number
+ *
+ * @param ep Endpoint number to check
+ * @retval true The endpoint is valid
+ * @retval false The endpoint is not valid
+ */
+#define NRF_USBD_EP_VALIDATE(ep) ( \
+ (NRF_USBD_EPIN_CHECK(ep) && (NRF_USBD_EP_NR_GET(ep) < NRF_USBD_EPIN_CNT)) \
+ || \
+ (NRF_USBD_EPOUT_CHECK(ep) && (NRF_USBD_EP_NR_GET(ep) < NRF_USBD_EPOUT_CNT)) \
+ )
+
+/**
+ * @brief Not isochronous data frame received
+ *
+ * Special value returned by @ref nrf_usbd_episoout_size_get function that means that
+ * data frame was not received at all.
+ * This allows differentiate between situations when zero size data comes or no data comes at all
+ * on isochronous endpoint.
+ */
+#define NRF_USBD_EPISOOUT_NO_DATA ((size_t)(-1))
+
+/**
+ * @brief EVENTCAUSE register bit masks
+ */
+typedef enum
+{
+ NRF_USBD_EVENTCAUSE_ISOOUTCRC_MASK = USBD_EVENTCAUSE_ISOOUTCRC_Msk, /**< CRC error was detected on isochronous OUT endpoint 8. */
+ NRF_USBD_EVENTCAUSE_SUSPEND_MASK = USBD_EVENTCAUSE_SUSPEND_Msk , /**< Signals that the USB lines have been seen idle long enough for the device to enter suspend. */
+ NRF_USBD_EVENTCAUSE_RESUME_MASK = USBD_EVENTCAUSE_RESUME_Msk , /**< Signals that a RESUME condition (K state or activity restart) has been detected on the USB lines. */
+ NRF_USBD_EVENTCAUSE_READY_MASK = USBD_EVENTCAUSE_READY_Msk, /**< MAC is ready for normal operation, rised few us after USBD enabling */
+ NRF_USBD_EVENTCAUSE_WUREQ_MASK = (1U << 10) /**< The USBD peripheral has exited Low Power mode */
+}nrf_usbd_eventcause_mask_t;
+
+/**
+ * @brief BUSSTATE register bit masks
+ */
+typedef enum
+{
+ NRF_USBD_BUSSTATE_DM_MASK = USBD_BUSSTATE_DM_Msk, /**< Negative line mask */
+ NRF_USBD_BUSSTATE_DP_MASK = USBD_BUSSTATE_DP_Msk, /**< Positive line mask */
+ /** Both lines are low */
+ NRF_USBD_BUSSTATE_DPDM_LL = (USBD_BUSSTATE_DM_Low << USBD_BUSSTATE_DM_Pos) | (USBD_BUSSTATE_DP_Low << USBD_BUSSTATE_DP_Pos),
+ /** Positive line is high, negative line is low */
+ NRF_USBD_BUSSTATE_DPDM_HL = (USBD_BUSSTATE_DM_Low << USBD_BUSSTATE_DM_Pos) | (USBD_BUSSTATE_DP_High << USBD_BUSSTATE_DP_Pos),
+ /** Positive line is low, negative line is high */
+ NRF_USBD_BUSSTATE_DPDM_LH = (USBD_BUSSTATE_DM_High << USBD_BUSSTATE_DM_Pos) | (USBD_BUSSTATE_DP_Low << USBD_BUSSTATE_DP_Pos),
+ /** Both lines are high */
+ NRF_USBD_BUSSTATE_DPDM_HH = (USBD_BUSSTATE_DM_High << USBD_BUSSTATE_DM_Pos) | (USBD_BUSSTATE_DP_High << USBD_BUSSTATE_DP_Pos),
+ /** J state */
+ NRF_USBD_BUSSTATE_J = NRF_USBD_BUSSTATE_DPDM_HL,
+ /** K state */
+ NRF_USBD_BUSSTATE_K = NRF_USBD_BUSSTATE_DPDM_LH,
+ /** Single ended 0 */
+ NRF_USBD_BUSSTATE_SE0 = NRF_USBD_BUSSTATE_DPDM_LL,
+ /** Single ended 1 */
+ NRF_USBD_BUSSTATE_SE1 = NRF_USBD_BUSSTATE_DPDM_HH
+}nrf_usbd_busstate_t;
+
+/**
+ * @brief DPDMVALUE register
+ */
+typedef enum
+{
+ /**Generate Resume signal. Signal is generated for 50&nbsp;us or 5&nbsp;ms,
+ * depending on bus state */
+ NRF_USBD_DPDMVALUE_RESUME = USBD_DPDMVALUE_STATE_Resume,
+ /** D+ Forced high, D- forced low (J state) */
+ NRF_USBD_DPDMVALUE_J = USBD_DPDMVALUE_STATE_J,
+ /** D+ Forced low, D- forced high (K state) */
+ NRF_USBD_DPMVALUE_K = USBD_DPDMVALUE_STATE_K
+}nrf_usbd_dpdmvalue_t;
+
+/**
+ * @brief Dtoggle value or operation
+ */
+typedef enum
+{
+ NRF_USBD_DTOGGLE_NOP = USBD_DTOGGLE_VALUE_Nop, /**< No operation - do not change current data toggle on selected endpoint */
+ NRF_USBD_DTOGGLE_DATA0 = USBD_DTOGGLE_VALUE_Data0,/**< Data toggle is DATA0 on selected endpoint */
+ NRF_USBD_DTOGGLE_DATA1 = USBD_DTOGGLE_VALUE_Data1 /**< Data toggle is DATA1 on selected endpoint */
+}nrf_usbd_dtoggle_t;
+
+/**
+ * @brief EPSTATUS bit masks
+ */
+typedef enum
+{
+ NRF_USBD_EPSTATUS_EPIN0_MASK = USBD_EPSTATUS_EPIN0_Msk,
+ NRF_USBD_EPSTATUS_EPIN1_MASK = USBD_EPSTATUS_EPIN1_Msk,
+ NRF_USBD_EPSTATUS_EPIN2_MASK = USBD_EPSTATUS_EPIN2_Msk,
+ NRF_USBD_EPSTATUS_EPIN3_MASK = USBD_EPSTATUS_EPIN3_Msk,
+ NRF_USBD_EPSTATUS_EPIN4_MASK = USBD_EPSTATUS_EPIN4_Msk,
+ NRF_USBD_EPSTATUS_EPIN5_MASK = USBD_EPSTATUS_EPIN5_Msk,
+ NRF_USBD_EPSTATUS_EPIN6_MASK = USBD_EPSTATUS_EPIN6_Msk,
+ NRF_USBD_EPSTATUS_EPIN7_MASK = USBD_EPSTATUS_EPIN7_Msk,
+
+ NRF_USBD_EPSTATUS_EPOUT0_MASK = USBD_EPSTATUS_EPOUT0_Msk,
+ NRF_USBD_EPSTATUS_EPOUT1_MASK = USBD_EPSTATUS_EPOUT1_Msk,
+ NRF_USBD_EPSTATUS_EPOUT2_MASK = USBD_EPSTATUS_EPOUT2_Msk,
+ NRF_USBD_EPSTATUS_EPOUT3_MASK = USBD_EPSTATUS_EPOUT3_Msk,
+ NRF_USBD_EPSTATUS_EPOUT4_MASK = USBD_EPSTATUS_EPOUT4_Msk,
+ NRF_USBD_EPSTATUS_EPOUT5_MASK = USBD_EPSTATUS_EPOUT5_Msk,
+ NRF_USBD_EPSTATUS_EPOUT6_MASK = USBD_EPSTATUS_EPOUT6_Msk,
+ NRF_USBD_EPSTATUS_EPOUT7_MASK = USBD_EPSTATUS_EPOUT7_Msk,
+}nrf_usbd_epstatus_mask_t;
+
+/**
+ * @brief DATAEPSTATUS bit masks
+ */
+typedef enum
+{
+ NRF_USBD_EPDATASTATUS_EPIN1_MASK = USBD_EPDATASTATUS_EPIN1_Msk,
+ NRF_USBD_EPDATASTATUS_EPIN2_MASK = USBD_EPDATASTATUS_EPIN2_Msk,
+ NRF_USBD_EPDATASTATUS_EPIN3_MASK = USBD_EPDATASTATUS_EPIN3_Msk,
+ NRF_USBD_EPDATASTATUS_EPIN4_MASK = USBD_EPDATASTATUS_EPIN4_Msk,
+ NRF_USBD_EPDATASTATUS_EPIN5_MASK = USBD_EPDATASTATUS_EPIN5_Msk,
+ NRF_USBD_EPDATASTATUS_EPIN6_MASK = USBD_EPDATASTATUS_EPIN6_Msk,
+ NRF_USBD_EPDATASTATUS_EPIN7_MASK = USBD_EPDATASTATUS_EPIN7_Msk,
+
+ NRF_USBD_EPDATASTATUS_EPOUT1_MASK = USBD_EPDATASTATUS_EPOUT1_Msk,
+ NRF_USBD_EPDATASTATUS_EPOUT2_MASK = USBD_EPDATASTATUS_EPOUT2_Msk,
+ NRF_USBD_EPDATASTATUS_EPOUT3_MASK = USBD_EPDATASTATUS_EPOUT3_Msk,
+ NRF_USBD_EPDATASTATUS_EPOUT4_MASK = USBD_EPDATASTATUS_EPOUT4_Msk,
+ NRF_USBD_EPDATASTATUS_EPOUT5_MASK = USBD_EPDATASTATUS_EPOUT5_Msk,
+ NRF_USBD_EPDATASTATUS_EPOUT6_MASK = USBD_EPDATASTATUS_EPOUT6_Msk,
+ NRF_USBD_EPDATASTATUS_EPOUT7_MASK = USBD_EPDATASTATUS_EPOUT7_Msk,
+}nrf_usbd_dataepstatus_mask_t;
+
+/**
+ * @brief ISOSPLIT configurations
+ */
+typedef enum
+{
+ NRF_USBD_ISOSPLIT_OneDir = USBD_ISOSPLIT_SPLIT_OneDir, /**< Full buffer dedicated to either iso IN or OUT */
+ NRF_USBD_ISOSPLIT_Half = USBD_ISOSPLIT_SPLIT_HalfIN, /**< Buffer divided in half */
+}nrf_usbd_isosplit_t;
+
+/**
+ * @brief Function for enabling USBD
+ */
+__STATIC_INLINE void nrf_usbd_enable(void);
+
+/**
+ * @brief Function for disabling USBD
+ */
+__STATIC_INLINE void nrf_usbd_disable(void);
+
+/**
+ * @brief Function for getting EVENTCAUSE register
+ *
+ * @return Flag values defined in @ref nrf_usbd_eventcause_mask_t
+ */
+__STATIC_INLINE uint32_t nrf_usbd_eventcause_get(void);
+
+/**
+ * @brief Function for clearing EVENTCAUSE flags
+ *
+ * @param flags Flags defined in @ref nrf_usbd_eventcause_mask_t
+ */
+__STATIC_INLINE void nrf_usbd_eventcause_clear(uint32_t flags);
+
+/**
+ * @brief Function for getting EVENTCAUSE register and clear flags that are set
+ *
+ * The safest way to return current EVENTCAUSE register.
+ * All the flags that are returned would be cleared inside EVENTCAUSE register.
+ *
+ * @return Flag values defined in @ref nrf_usbd_eventcause_mask_t
+ */
+__STATIC_INLINE uint32_t nrf_usbd_eventcause_get_and_clear(void);
+
+/**
+ * @brief Function for getting BUSSTATE register value
+ *
+ * @return The value of BUSSTATE register
+ */
+__STATIC_INLINE nrf_usbd_busstate_t nrf_usbd_busstate_get(void);
+
+/**
+ * @brief Function for getting HALTEDEPIN register value
+ *
+ * @param ep Endpoint number with IN/OUT flag
+ *
+ * @return The value of HALTEDEPIN or HALTEDOUT register for selected endpoint
+ *
+ * @note
+ * Use this function for the response for GetStatus() request to endpoint.
+ * To check if endpoint is stalled in the code use @ref nrf_usbd_ep_is_stall.
+ */
+__STATIC_INLINE uint32_t nrf_usbd_haltedep(uint8_t ep);
+
+/**
+ * @brief Function for checking if selected endpoint is stalled
+ *
+ * Function to be used as a syntax sweeter for @ref nrf_usbd_haltedep.
+ *
+ * Also as the isochronous endpoint cannot be halted - it returns always false
+ * if isochronous endpoint is checked.
+ *
+ * @param ep Endpoint number with IN/OUT flag
+ *
+ * @return The information if the enepoint is halted.
+ */
+__STATIC_INLINE bool nrf_usbd_ep_is_stall(uint8_t ep);
+
+/**
+ * @brief Function for getting EPSTATUS register value
+ *
+ * @return Flag values defined in @ref nrf_usbd_epstatus_mask_t
+ */
+__STATIC_INLINE uint32_t nrf_usbd_epstatus_get(void);
+
+/**
+ * @brief Function for clearing EPSTATUS register value
+ *
+ * @param flags Flags defined in @ref nrf_usbd_epstatus_mask_t
+ */
+__STATIC_INLINE void nrf_usbd_epstatus_clear(uint32_t flags);
+
+/**
+ * @brief Function for getting and clearing EPSTATUS register value
+ *
+ * Function clears all flags in register set before returning its value.
+ * @return Flag values defined in @ref nrf_usbd_epstatus_mask_t
+ */
+__STATIC_INLINE uint32_t nrf_usbd_epstatus_get_and_clear(void);
+
+/**
+ * @brief Function for getting DATAEPSTATUS register value
+ *
+ * @return Flag values defined in @ref nrf_usbd_dataepstatus_mask_t
+ */
+__STATIC_INLINE uint32_t nrf_usbd_epdatastatus_get(void);
+
+/**
+ * @brief Function for clearing DATAEPSTATUS register value
+ *
+ * @param flags Flags defined in @ref nrf_usbd_dataepstatus_mask_t
+ */
+__STATIC_INLINE void nrf_usbd_epdatastatus_clear(uint32_t flags);
+
+/**
+ * @brief Function for getting and clearing DATAEPSTATUS register value
+ *
+ * Function clears all flags in register set before returning its value.
+ * @return Flag values defined in @ref nrf_usbd_dataepstatus_mask_t
+ */
+__STATIC_INLINE uint32_t nrf_usbd_epdatastatus_get_and_clear(void);
+
+/**
+ * @name Setup command frame functions
+ *
+ * Functions for setup command frame parts access
+ * @{
+ */
+ /**
+ * @brief Function for reading BMREQUESTTYPE - part of SETUP packet
+ *
+ * @return the value of BREQUESTTYPE on last received SETUP frame
+ */
+ __STATIC_INLINE uint8_t nrf_usbd_setup_bmrequesttype_get(void);
+
+ /**
+ * @brief Function for reading BMREQUEST - part of SETUP packet
+ *
+ * @return the value of BREQUEST on last received SETUP frame
+ */
+ __STATIC_INLINE uint8_t nrf_usbd_setup_brequest_get(void);
+
+ /**
+ * @brief Function for reading WVALUE - part of SETUP packet
+ *
+ * @return the value of WVALUE on last received SETUP frame
+ */
+ __STATIC_INLINE uint16_t nrf_usbd_setup_wvalue_get(void);
+
+ /**
+ * @brief Function for reading WINDEX - part of SETUP packet
+ *
+ * @return the value of WINDEX on last received SETUP frame
+ */
+ __STATIC_INLINE uint16_t nrf_usbd_setup_windex_get(void);
+
+ /**
+ * @brief Function for reading WLENGTH - part of SETUP packet
+ *
+ * @return the value of WLENGTH on last received SETUP frame
+ */
+ __STATIC_INLINE uint16_t nrf_usbd_setup_wlength_get(void);
+/** @} */
+
+/**
+ * @brief Function for getting number of received bytes on selected endpoint
+ *
+ * @param ep Endpoint identifier.
+ *
+ * @return Number of received bytes.
+ *
+ * @note This function may be used on Bulk/Interrupt and Isochronous endpoints.
+ * @note For the function that returns different value for ISOOUT zero transfer or no transfer at all,
+ * see @ref nrf_usbd_episoout_size_get function. This function would return 0 for both cases.
+ */
+__STATIC_INLINE size_t nrf_usbd_epout_size_get(uint8_t ep);
+
+/**
+ * @brief Function for getting number of received bytes on isochronous endpoint.
+ *
+ * @param ep Endpoint identifier, has to be isochronous out endpoint.
+ *
+ * @return Number of bytes received or @ref NRF_USBD_EPISOOUT_NO_DATA
+ */
+__STATIC_INLINE size_t nrf_usbd_episoout_size_get(uint8_t ep);
+
+/**
+ * @brief Function for clearing out endpoint to accept any new incoming traffic
+ *
+ * @param ep ep Endpoint identifier. Only OUT Interrupt/Bulk endpoints are accepted.
+ */
+__STATIC_INLINE void nrf_usbd_epout_clear(uint8_t ep);
+
+/**
+ * @brief Function for enabling USB pullup
+ */
+__STATIC_INLINE void nrf_usbd_pullup_enable(void);
+
+/**
+ * @brief Function for disabling USB pullup
+ */
+__STATIC_INLINE void nrf_usbd_pullup_disable(void);
+
+/**
+ * @brief Function for returning current USB pullup state
+ *
+ * @retval true USB pullup is enabled
+ * @retval false USB pullup is disabled
+ */
+__STATIC_INLINE bool nrf_usbd_pullup_check(void);
+
+/**
+ * @brief Function for configuring the value to be forced on the bus on DRIVEDPDM task
+ *
+ * Selected state would be forced on the bus when @ref NRF_USBD_TASK_DRIVEDPDM is set.
+ * The state would be removed from the bus on @ref NRF_USBD_TASK_NODRIVEDPDM and
+ * the control would be returned to the USBD peripheral.
+ * @param val State to be set
+ */
+__STATIC_INLINE void nrf_usbd_dpdmvalue_set(nrf_usbd_dpdmvalue_t val);
+
+/**
+ * @brief Function for setting data toggle
+ *
+ * Configuration of current state of data toggling
+ * @param ep Endpoint number with the information about its direction
+ * @param op Operation to execute
+ */
+__STATIC_INLINE void nrf_usbd_dtoggle_set(uint8_t ep, nrf_usbd_dtoggle_t op);
+
+/**
+ * @brief Function for getting data toggle
+ *
+ * Get the current state of data toggling
+ * @param ep Endpoint number to return the information about current data toggling
+ * @retval NRF_USBD_DTOGGLE_DATA0 Data toggle is DATA0 on selected endpoint
+ * @retval NRF_USBD_DTOGGLE_DATA1 Data toggle is DATA1 on selected endpoint
+ */
+__STATIC_INLINE nrf_usbd_dtoggle_t nrf_usbd_dtoggle_get(uint8_t ep);
+
+/**
+ * @brief Function for checking if endpoint is enabled
+ *
+ * @param ep Endpoint id to check
+ *
+ * @retval true Endpoint is enabled
+ * @retval false Endpoint is disabled
+ */
+__STATIC_INLINE bool nrf_usbd_ep_enable_check(uint8_t ep);
+
+/**
+ * @brief Function for enabling selected endpoint
+ *
+ * Enabled endpoint responds for the tokens on the USB bus
+ *
+ * @param ep Endpoint id to enable
+ */
+__STATIC_INLINE void nrf_usbd_ep_enable(uint8_t ep);
+
+/**
+ * @brief Function for disabling selected endpoint
+ *
+ * Disabled endpoint does not respond for the tokens on the USB bus
+ *
+ * @param ep Endpoint id to disable
+ */
+__STATIC_INLINE void nrf_usbd_ep_disable(uint8_t ep);
+
+/**
+ * @brief Function for disabling all endpoints
+ *
+ * Auxiliary function to simply disable all aviable endpoints.
+ * It lefts only EP0 IN and OUT enabled.
+ */
+__STATIC_INLINE void nrf_usbd_ep_all_disable(void);
+
+/**
+ * @brief Function for stalling selected endpoint
+ *
+ * @param ep Endpoint identifier
+ * @note This function cannot be called on isochronous endpoint
+ */
+__STATIC_INLINE void nrf_usbd_ep_stall(uint8_t ep);
+
+/**
+ * @brief Function for unstalling selected endpoint
+ *
+ * @param ep Endpoint identifier
+ * @note This function cannot be called on isochronous endpoint
+ */
+__STATIC_INLINE void nrf_usbd_ep_unstall(uint8_t ep);
+
+/**
+ * @brief Function for configuration of isochronous buffer splitting
+ *
+ * Configure isochronous buffer splitting between IN and OUT endpoints.
+ *
+ * @param split Required configuration
+ */
+__STATIC_INLINE void nrf_usbd_isosplit_set(nrf_usbd_isosplit_t split);
+
+/**
+ * @brief Function for getting the isochronous buffer splitting configuration
+ *
+ * Get the current isochronous buffer splitting configuration.
+ *
+ * @return Current configuration
+ */
+__STATIC_INLINE nrf_usbd_isosplit_t nrf_usbd_isosplit_get(void);
+
+/**
+ * @brief Function for getting current frame counter
+ *
+ * @return Current frame counter
+ */
+__STATIC_INLINE uint32_t nrf_usbd_framecntr_get(void);
+
+/**
+ * @brief Function for entering into low power mode
+ *
+ * After this function is called the clock source from the USBD is disconnected internally.
+ * After this function is called most of the USBD registers cannot be accessed anymore.
+ *
+ * @sa nrf_usbd_lowpower_disable
+ * @sa nrf_usbd_lowpower_check
+ */
+__STATIC_INLINE void nrf_usbd_lowpower_enable(void);
+
+/**
+ * @brief Function for exiting from low power mode
+ *
+ * After this function is called the clock source for the USBD is connected internally.
+ * The @ref NRF_USBD_EVENTCAUSE_WUREQ_MASK event would be generated and
+ * then the USBD registers may be accessed.
+ *
+ * @sa nrf_usbd_lowpower_enable
+ * @sa nrf_usbd_lowpower_check
+ */
+__STATIC_INLINE void nrf_usbd_lowpower_disable(void);
+
+/**
+ * @brief Function for checking the state of the low power mode
+ *
+ * @retval true USBD is in low power mode
+ * @retval false USBD is not in low power mode
+ */
+__STATIC_INLINE bool nrf_usbd_lowpower_check(void);
+
+/**
+ * @brief Function for configuring EasyDMA channel
+ *
+ * Configures EasyDMA for the transfer.
+ *
+ * @param ep Endpoint identifier (with direction)
+ * @param ptr Pointer to the data
+ * @param maxcnt Number of bytes to transfer
+ */
+__STATIC_INLINE void nrf_usbd_ep_easydma_set(uint8_t ep, uint32_t ptr, uint32_t maxcnt);
+
+/**
+ * @brief Function for getting number of transferred bytes
+ *
+ * Get number of transferred bytes in the last transaction
+ *
+ * @param ep Endpoint identifier
+ *
+ * @return The content of the AMOUNT register
+ */
+__STATIC_INLINE uint32_t nrf_usbd_ep_amount_get(uint8_t ep);
+
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+void nrf_usbd_enable(void)
+{
+#ifdef NRF_FPGA_IMPLEMENTATION
+ *(volatile uint32_t *)0x400005F4 = 3;
+ __ISB();
+ __DSB();
+ *(volatile uint32_t *)0x400005F0 = 3;
+ __ISB();
+ __DSB();
+#endif
+
+ NRF_USBD->ENABLE = USBD_ENABLE_ENABLE_Enabled << USBD_ENABLE_ENABLE_Pos;
+ __ISB();
+ __DSB();
+}
+
+void nrf_usbd_disable(void)
+{
+ NRF_USBD->ENABLE = USBD_ENABLE_ENABLE_Disabled << USBD_ENABLE_ENABLE_Pos;
+ __ISB();
+ __DSB();
+}
+
+uint32_t nrf_usbd_eventcause_get(void)
+{
+ return NRF_USBD->EVENTCAUSE;
+}
+
+void nrf_usbd_eventcause_clear(uint32_t flags)
+{
+ NRF_USBD->EVENTCAUSE = flags;
+ __ISB();
+ __DSB();
+}
+
+uint32_t nrf_usbd_eventcause_get_and_clear(void)
+{
+ uint32_t ret;
+ ret = nrf_usbd_eventcause_get();
+ nrf_usbd_eventcause_clear(ret);
+ __ISB();
+ __DSB();
+ return ret;
+}
+
+nrf_usbd_busstate_t nrf_usbd_busstate_get(void)
+{
+ return (nrf_usbd_busstate_t)(NRF_USBD->BUSSTATE);
+}
+
+uint32_t nrf_usbd_haltedep(uint8_t ep)
+{
+ uint8_t epnr = NRF_USBD_EP_NR_GET(ep);
+ if (NRF_USBD_EPIN_CHECK(ep))
+ {
+ ASSERT(epnr < ARRAY_SIZE(NRF_USBD->HALTED.EPIN));
+ return NRF_USBD->HALTED.EPIN[epnr];
+ }
+ else
+ {
+ ASSERT(epnr < ARRAY_SIZE(NRF_USBD->HALTED.EPOUT));
+ return NRF_USBD->HALTED.EPOUT[epnr];
+ }
+}
+
+bool nrf_usbd_ep_is_stall(uint8_t ep)
+{
+ if (NRF_USBD_EPISO_CHECK(ep))
+ return false;
+ return USBD_HALTED_EPOUT_GETSTATUS_Halted == nrf_usbd_haltedep(ep);
+}
+
+uint32_t nrf_usbd_epstatus_get(void)
+{
+ return NRF_USBD->EPSTATUS;
+}
+
+void nrf_usbd_epstatus_clear(uint32_t flags)
+{
+ NRF_USBD->EPSTATUS = flags;
+ __ISB();
+ __DSB();
+}
+
+uint32_t nrf_usbd_epstatus_get_and_clear(void)
+{
+ uint32_t ret;
+ ret = nrf_usbd_epstatus_get();
+ nrf_usbd_epstatus_clear(ret);
+ return ret;
+}
+
+uint32_t nrf_usbd_epdatastatus_get(void)
+{
+ return NRF_USBD->EPDATASTATUS;
+}
+
+void nrf_usbd_epdatastatus_clear(uint32_t flags)
+{
+ NRF_USBD->EPDATASTATUS = flags;
+ __ISB();
+ __DSB();
+}
+
+uint32_t nrf_usbd_epdatastatus_get_and_clear(void)
+{
+ uint32_t ret;
+ ret = nrf_usbd_epdatastatus_get();
+ nrf_usbd_epdatastatus_clear(ret);
+ __ISB();
+ __DSB();
+ return ret;
+}
+
+uint8_t nrf_usbd_setup_bmrequesttype_get(void)
+{
+ return (uint8_t)(NRF_USBD->BMREQUESTTYPE);
+}
+
+uint8_t nrf_usbd_setup_brequest_get(void)
+{
+ return (uint8_t)(NRF_USBD->BREQUEST);
+}
+
+uint16_t nrf_usbd_setup_wvalue_get(void)
+{
+ const uint16_t val = NRF_USBD->WVALUEL;
+ return (uint16_t)(val | ((NRF_USBD->WVALUEH) << 8));
+}
+
+uint16_t nrf_usbd_setup_windex_get(void)
+{
+ const uint16_t val = NRF_USBD->WINDEXL;
+ return (uint16_t)(val | ((NRF_USBD->WINDEXH) << 8));
+}
+
+uint16_t nrf_usbd_setup_wlength_get(void)
+{
+ const uint16_t val = NRF_USBD->WLENGTHL;
+ return (uint16_t)(val | ((NRF_USBD->WLENGTHH) << 8));
+}
+
+size_t nrf_usbd_epout_size_get(uint8_t ep)
+{
+ ASSERT(NRF_USBD_EP_VALIDATE(ep));
+ ASSERT(NRF_USBD_EPOUT_CHECK(ep));
+ if (NRF_USBD_EPISO_CHECK(ep))
+ {
+ size_t size_isoout = NRF_USBD->SIZE.ISOOUT;
+ if ((size_isoout & USBD_SIZE_ISOOUT_ZERO_Msk) == (USBD_SIZE_ISOOUT_ZERO_ZeroData << USBD_SIZE_ISOOUT_ZERO_Pos))
+ {
+ size_isoout = 0;
+ }
+ return size_isoout;
+ }
+
+ ASSERT(NRF_USBD_EP_NR_GET(ep) < ARRAY_SIZE(NRF_USBD->SIZE.EPOUT));
+ return NRF_USBD->SIZE.EPOUT[NRF_USBD_EP_NR_GET(ep)];
+}
+
+size_t nrf_usbd_episoout_size_get(uint8_t ep)
+{
+ ASSERT(NRF_USBD_EP_VALIDATE(ep));
+ ASSERT(NRF_USBD_EPOUT_CHECK(ep));
+ ASSERT(NRF_USBD_EPISO_CHECK(ep));
+
+ size_t size_isoout = NRF_USBD->SIZE.ISOOUT;
+ if (size_isoout == 0)
+ {
+ size_isoout = NRF_USBD_EPISOOUT_NO_DATA;
+ }
+ else if ((size_isoout & USBD_SIZE_ISOOUT_ZERO_Msk) == (USBD_SIZE_ISOOUT_ZERO_ZeroData << USBD_SIZE_ISOOUT_ZERO_Pos))
+ {
+ size_isoout = 0;
+ }
+ return size_isoout;
+}
+
+void nrf_usbd_epout_clear(uint8_t ep)
+{
+ ASSERT(NRF_USBD_EPOUT_CHECK(ep) && (NRF_USBD_EP_NR_GET(ep) < ARRAY_SIZE(NRF_USBD->SIZE.EPOUT)));
+ NRF_USBD->SIZE.EPOUT[NRF_USBD_EP_NR_GET(ep)] = 0;
+ __ISB();
+ __DSB();
+}
+
+void nrf_usbd_pullup_enable(void)
+{
+ NRF_USBD->USBPULLUP = USBD_USBPULLUP_CONNECT_Enabled << USBD_USBPULLUP_CONNECT_Pos;
+ __ISB();
+ __DSB();
+}
+
+void nrf_usbd_pullup_disable(void)
+{
+ NRF_USBD->USBPULLUP = USBD_USBPULLUP_CONNECT_Disabled << USBD_USBPULLUP_CONNECT_Pos;
+ __ISB();
+ __DSB();
+}
+
+bool nrf_usbd_pullup_check(void)
+{
+ return NRF_USBD->USBPULLUP == (USBD_USBPULLUP_CONNECT_Enabled << USBD_USBPULLUP_CONNECT_Pos);
+}
+
+void nrf_usbd_dpdmvalue_set(nrf_usbd_dpdmvalue_t val)
+{
+ NRF_USBD->DPDMVALUE = ((uint32_t)val) << USBD_DPDMVALUE_STATE_Pos;
+}
+
+void nrf_usbd_dtoggle_set(uint8_t ep, nrf_usbd_dtoggle_t op)
+{
+ ASSERT(NRF_USBD_EP_VALIDATE(ep));
+ ASSERT(!NRF_USBD_EPISO_CHECK(ep));
+ NRF_USBD->DTOGGLE = ep | (NRF_USBD_DTOGGLE_NOP << USBD_DTOGGLE_VALUE_Pos);
+ __DSB();
+ NRF_USBD->DTOGGLE = ep | (op << USBD_DTOGGLE_VALUE_Pos);
+ __ISB();
+ __DSB();
+}
+
+nrf_usbd_dtoggle_t nrf_usbd_dtoggle_get(uint8_t ep)
+{
+ uint32_t retval;
+ /* Select the endpoint to read */
+ NRF_USBD->DTOGGLE = ep | (NRF_USBD_DTOGGLE_NOP << USBD_DTOGGLE_VALUE_Pos);
+ retval = ((NRF_USBD->DTOGGLE) & USBD_DTOGGLE_VALUE_Msk) >> USBD_DTOGGLE_VALUE_Pos;
+ return (nrf_usbd_dtoggle_t)retval;
+}
+
+bool nrf_usbd_ep_enable_check(uint8_t ep)
+{
+ ASSERT(NRF_USBD_EP_VALIDATE(ep));
+ uint8_t epnr = NRF_USBD_EP_NR_GET(ep);
+
+ if (NRF_USBD_EPIN_CHECK(ep))
+ {
+ return 0 != (NRF_USBD->EPINEN & (1UL << epnr));
+ }
+ else
+ {
+ return 0 != (NRF_USBD->EPOUTEN & (1UL << epnr));
+ }
+}
+
+void nrf_usbd_ep_enable(uint8_t ep)
+{
+ ASSERT(NRF_USBD_EP_VALIDATE(ep));
+ uint8_t epnr = NRF_USBD_EP_NR_GET(ep);
+
+ if (NRF_USBD_EPIN_CHECK(ep))
+ {
+ NRF_USBD->EPINEN |= 1UL << epnr;
+ }
+ else
+ {
+ NRF_USBD->EPOUTEN |= 1UL << epnr;
+ }
+ __ISB();
+ __DSB();
+}
+
+void nrf_usbd_ep_disable(uint8_t ep)
+{
+ ASSERT(NRF_USBD_EP_VALIDATE(ep));
+ uint8_t epnr = NRF_USBD_EP_NR_GET(ep);
+
+ if (NRF_USBD_EPIN_CHECK(ep))
+ {
+ NRF_USBD->EPINEN &= ~(1UL << epnr);
+ }
+ else
+ {
+ NRF_USBD->EPOUTEN &= ~(1UL << epnr);
+ }
+ __ISB();
+ __DSB();
+}
+
+void nrf_usbd_ep_all_disable(void)
+{
+ NRF_USBD->EPINEN = USBD_EPINEN_IN0_Enable << USBD_EPINEN_IN0_Pos;
+ NRF_USBD->EPOUTEN = USBD_EPOUTEN_OUT0_Enable << USBD_EPOUTEN_OUT0_Pos;
+ __ISB();
+ __DSB();
+}
+
+void nrf_usbd_ep_stall(uint8_t ep)
+{
+ ASSERT(!NRF_USBD_EPISO_CHECK(ep));
+ NRF_USBD->EPSTALL = (USBD_EPSTALL_STALL_Stall << USBD_EPSTALL_STALL_Pos) | ep;
+ __ISB();
+ __DSB();
+}
+
+void nrf_usbd_ep_unstall(uint8_t ep)
+{
+ ASSERT(!NRF_USBD_EPISO_CHECK(ep));
+ NRF_USBD->EPSTALL = (USBD_EPSTALL_STALL_UnStall << USBD_EPSTALL_STALL_Pos) | ep;
+ __ISB();
+ __DSB();
+}
+
+void nrf_usbd_isosplit_set(nrf_usbd_isosplit_t split)
+{
+ NRF_USBD->ISOSPLIT = split << USBD_ISOSPLIT_SPLIT_Pos;
+}
+
+nrf_usbd_isosplit_t nrf_usbd_isosplit_get(void)
+{
+ return (nrf_usbd_isosplit_t)
+ (((NRF_USBD->ISOSPLIT) & USBD_ISOSPLIT_SPLIT_Msk) >> USBD_ISOSPLIT_SPLIT_Pos);
+}
+
+uint32_t nrf_usbd_framecntr_get(void)
+{
+ return NRF_USBD->FRAMECNTR;
+}
+
+void nrf_usbd_lowpower_enable(void)
+{
+ NRF_USBD->LOWPOWER = USBD_LOWPOWER_LOWPOWER_LowPower << USBD_LOWPOWER_LOWPOWER_Pos;
+}
+
+void nrf_usbd_lowpower_disable(void)
+{
+ NRF_USBD->LOWPOWER = USBD_LOWPOWER_LOWPOWER_ForceNormal << USBD_LOWPOWER_LOWPOWER_Pos;
+}
+
+bool nrf_usbd_lowpower_check(void)
+{
+ return (NRF_USBD->LOWPOWER != (USBD_LOWPOWER_LOWPOWER_ForceNormal << USBD_LOWPOWER_LOWPOWER_Pos));
+}
+
+
+void nrf_usbd_ep_easydma_set(uint8_t ep, uint32_t ptr, uint32_t maxcnt)
+{
+ if (NRF_USBD_EPIN_CHECK(ep))
+ {
+ if (NRF_USBD_EPISO_CHECK(ep))
+ {
+ NRF_USBD->ISOIN.PTR = ptr;
+ NRF_USBD->ISOIN.MAXCNT = maxcnt;
+ }
+ else
+ {
+ uint8_t epnr = NRF_USBD_EP_NR_GET(ep);
+ ASSERT(epnr < ARRAY_SIZE(NRF_USBD->EPIN));
+ NRF_USBD->EPIN[epnr].PTR = ptr;
+ NRF_USBD->EPIN[epnr].MAXCNT = maxcnt;
+ }
+ }
+ else
+ {
+ if (NRF_USBD_EPISO_CHECK(ep))
+ {
+ NRF_USBD->ISOOUT.PTR = ptr;
+ NRF_USBD->ISOOUT.MAXCNT = maxcnt;
+ }
+ else
+ {
+ uint8_t epnr = NRF_USBD_EP_NR_GET(ep);
+ ASSERT(epnr < ARRAY_SIZE(NRF_USBD->EPOUT));
+ NRF_USBD->EPOUT[epnr].PTR = ptr;
+ NRF_USBD->EPOUT[epnr].MAXCNT = maxcnt;
+ }
+ }
+}
+
+uint32_t nrf_usbd_ep_amount_get(uint8_t ep)
+{
+ uint32_t ret;
+
+ if (NRF_USBD_EPIN_CHECK(ep))
+ {
+ if (NRF_USBD_EPISO_CHECK(ep))
+ {
+ ret = NRF_USBD->ISOIN.AMOUNT;
+ }
+ else
+ {
+ uint8_t epnr = NRF_USBD_EP_NR_GET(ep);
+ ASSERT(epnr < ARRAY_SIZE(NRF_USBD->EPOUT));
+ ret = NRF_USBD->EPIN[epnr].AMOUNT;
+ }
+ }
+ else
+ {
+ if (NRF_USBD_EPISO_CHECK(ep))
+ {
+ ret = NRF_USBD->ISOOUT.AMOUNT;
+ }
+ else
+ {
+ uint8_t epnr = NRF_USBD_EP_NR_GET(ep);
+ ASSERT(epnr < ARRAY_SIZE(NRF_USBD->EPOUT));
+ ret = NRF_USBD->EPOUT[epnr].AMOUNT;
+ }
+ }
+
+ return ret;
+}
+
+#endif /* SUPPRESS_INLINE_IMPLEMENTATION */
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_USBD_H__ */
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_wdt.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_wdt.h
new file mode 100644
index 000000000..d497fc246
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/hal/nrf_wdt.h
@@ -0,0 +1,339 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_wdt_hal WDT HAL
+ * @{
+ * @ingroup nrf_wdt
+ *
+ * @brief Hardware access layer for accessing the watchdog timer (WDT) peripheral.
+ */
+
+#ifndef NRF_WDT_H__
+#define NRF_WDT_H__
+
+#include <stddef.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "nrf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NRF_WDT_CHANNEL_NUMBER 0x8UL
+#define NRF_WDT_RR_VALUE 0x6E524635UL /* Fixed value, shouldn't be modified.*/
+
+#define NRF_WDT_TASK_SET 1UL
+#define NRF_WDT_EVENT_CLEAR 0UL
+
+/**
+ * @enum nrf_wdt_task_t
+ * @brief WDT tasks.
+ */
+typedef enum
+{
+ /*lint -save -e30 -esym(628,__INTADDR__)*/
+ NRF_WDT_TASK_START = offsetof(NRF_WDT_Type, TASKS_START), /**< Task for starting WDT. */
+ /*lint -restore*/
+} nrf_wdt_task_t;
+
+/**
+ * @enum nrf_wdt_event_t
+ * @brief WDT events.
+ */
+typedef enum
+{
+ /*lint -save -e30*/
+ NRF_WDT_EVENT_TIMEOUT = offsetof(NRF_WDT_Type, EVENTS_TIMEOUT), /**< Event from WDT time-out. */
+ /*lint -restore*/
+} nrf_wdt_event_t;
+
+/**
+ * @enum nrf_wdt_behaviour_t
+ * @brief WDT behavior in CPU SLEEP or HALT mode.
+ */
+typedef enum
+{
+ NRF_WDT_BEHAVIOUR_RUN_SLEEP = WDT_CONFIG_SLEEP_Msk, /**< WDT will run when CPU is in SLEEP mode. */
+ NRF_WDT_BEHAVIOUR_RUN_HALT = WDT_CONFIG_HALT_Msk, /**< WDT will run when CPU is in HALT mode. */
+ NRF_WDT_BEHAVIOUR_RUN_SLEEP_HALT = WDT_CONFIG_SLEEP_Msk | WDT_CONFIG_HALT_Msk, /**< WDT will run when CPU is in SLEEP or HALT mode. */
+ NRF_WDT_BEHAVIOUR_PAUSE_SLEEP_HALT = 0, /**< WDT will be paused when CPU is in SLEEP or HALT mode. */
+} nrf_wdt_behaviour_t;
+
+/**
+ * @enum nrf_wdt_rr_register_t
+ * @brief WDT reload request registers.
+ */
+typedef enum
+{
+ NRF_WDT_RR0 = 0, /**< Reload request register 0. */
+ NRF_WDT_RR1, /**< Reload request register 1. */
+ NRF_WDT_RR2, /**< Reload request register 2. */
+ NRF_WDT_RR3, /**< Reload request register 3. */
+ NRF_WDT_RR4, /**< Reload request register 4. */
+ NRF_WDT_RR5, /**< Reload request register 5. */
+ NRF_WDT_RR6, /**< Reload request register 6. */
+ NRF_WDT_RR7 /**< Reload request register 7. */
+} nrf_wdt_rr_register_t;
+
+/**
+ * @enum nrf_wdt_int_mask_t
+ * @brief WDT interrupts.
+ */
+typedef enum
+{
+ NRF_WDT_INT_TIMEOUT_MASK = WDT_INTENSET_TIMEOUT_Msk, /**< WDT interrupt from time-out event. */
+} nrf_wdt_int_mask_t;
+
+/**
+ * @brief Function for configuring the watchdog behavior when the CPU is sleeping or halted.
+ *
+ * @param behaviour Watchdog behavior when CPU is in SLEEP or HALT mode.
+ */
+__STATIC_INLINE void nrf_wdt_behaviour_set(nrf_wdt_behaviour_t behaviour)
+{
+ NRF_WDT->CONFIG = behaviour;
+}
+
+
+/**
+ * @brief Function for starting the watchdog.
+ *
+ * @param[in] task Task.
+ */
+__STATIC_INLINE void nrf_wdt_task_trigger(nrf_wdt_task_t task)
+{
+ *((volatile uint32_t *)((uint8_t *)NRF_WDT + task)) = NRF_WDT_TASK_SET;
+}
+
+
+/**
+ * @brief Function for clearing the WDT event.
+ *
+ * @param[in] event Event.
+ */
+__STATIC_INLINE void nrf_wdt_event_clear(nrf_wdt_event_t event)
+{
+ *((volatile uint32_t *)((uint8_t *)NRF_WDT + (uint32_t)event)) = NRF_WDT_EVENT_CLEAR;
+#if __CORTEX_M == 0x04
+ volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_WDT + (uint32_t)event));
+ (void)dummy;
+#endif
+}
+
+
+/**
+ * @brief Function for retrieving the state of the WDT event.
+ *
+ * @param[in] event Event.
+ *
+ * @retval true If the event is set.
+ * @retval false If the event is not set.
+ */
+__STATIC_INLINE bool nrf_wdt_event_check(nrf_wdt_event_t event)
+{
+ return (bool)*((volatile uint32_t *)((uint8_t *)NRF_WDT + event));
+}
+
+
+/**
+ * @brief Function for enabling a specific interrupt.
+ *
+ * @param[in] int_mask Interrupt.
+ */
+__STATIC_INLINE void nrf_wdt_int_enable(uint32_t int_mask)
+{
+ NRF_WDT->INTENSET = int_mask;
+}
+
+
+/**
+ * @brief Function for retrieving the state of given interrupt.
+ *
+ * @param[in] int_mask Interrupt.
+ *
+ * @retval true Interrupt is enabled.
+ * @retval false Interrupt is not enabled.
+ */
+__STATIC_INLINE bool nrf_wdt_int_enable_check(uint32_t int_mask)
+{
+ return (bool)(NRF_WDT->INTENSET & int_mask);
+}
+
+
+/**
+ * @brief Function for disabling a specific interrupt.
+ *
+ * @param[in] int_mask Interrupt.
+ */
+__STATIC_INLINE void nrf_wdt_int_disable(uint32_t int_mask)
+{
+ NRF_WDT->INTENCLR = int_mask;
+}
+
+
+/**
+ * @brief Function for returning the address of a specific WDT task register.
+ *
+ * @param[in] task Task.
+ */
+__STATIC_INLINE uint32_t nrf_wdt_task_address_get(nrf_wdt_task_t task)
+{
+ return ((uint32_t)NRF_WDT + task);
+}
+
+
+/**
+ * @brief Function for returning the address of a specific WDT event register.
+ *
+ * @param[in] event Event.
+ *
+ * @retval address of requested event register
+ */
+__STATIC_INLINE uint32_t nrf_wdt_event_address_get(nrf_wdt_event_t event)
+{
+ return ((uint32_t)NRF_WDT + event);
+}
+
+
+/**
+ * @brief Function for retrieving the watchdog status.
+ *
+ * @retval true If the watchdog is started.
+ * @retval false If the watchdog is not started.
+ */
+__STATIC_INLINE bool nrf_wdt_started(void)
+{
+ return (bool)(NRF_WDT->RUNSTATUS);
+}
+
+
+/**
+ * @brief Function for retrieving the watchdog reload request status.
+ *
+ * @param[in] rr_register Reload request register to check.
+ *
+ * @retval true If a reload request is running.
+ * @retval false If no reload request is running.
+ */
+__STATIC_INLINE bool nrf_wdt_request_status(nrf_wdt_rr_register_t rr_register)
+{
+ return (bool)(((NRF_WDT->REQSTATUS) >> rr_register) & 0x1UL);
+}
+
+
+/**
+ * @brief Function for setting the watchdog reload value.
+ *
+ * @param[in] reload_value Watchdog counter initial value.
+ */
+__STATIC_INLINE void nrf_wdt_reload_value_set(uint32_t reload_value)
+{
+ NRF_WDT->CRV = reload_value;
+}
+
+
+/**
+ * @brief Function for retrieving the watchdog reload value.
+ *
+ * @retval Reload value.
+ */
+__STATIC_INLINE uint32_t nrf_wdt_reload_value_get(void)
+{
+ return (uint32_t)NRF_WDT->CRV;
+}
+
+
+/**
+ * @brief Function for enabling a specific reload request register.
+ *
+ * @param[in] rr_register Reload request register to enable.
+ */
+__STATIC_INLINE void nrf_wdt_reload_request_enable(nrf_wdt_rr_register_t rr_register)
+{
+ NRF_WDT->RREN |= 0x1UL << rr_register;
+}
+
+
+/**
+ * @brief Function for disabling a specific reload request register.
+ *
+ * @param[in] rr_register Reload request register to disable.
+ */
+__STATIC_INLINE void nrf_wdt_reload_request_disable(nrf_wdt_rr_register_t rr_register)
+{
+ NRF_WDT->RREN &= ~(0x1UL << rr_register);
+}
+
+
+/**
+ * @brief Function for retrieving the status of a specific reload request register.
+ *
+ * @param[in] rr_register Reload request register to check.
+ *
+ * @retval true If the reload request register is enabled.
+ * @retval false If the reload request register is not enabled.
+ */
+__STATIC_INLINE bool nrf_wdt_reload_request_is_enabled(nrf_wdt_rr_register_t rr_register)
+{
+ return (bool)(NRF_WDT->RREN & (0x1UL << rr_register));
+}
+
+
+/**
+ * @brief Function for setting a specific reload request register.
+ *
+ * @param[in] rr_register Reload request register to set.
+ */
+__STATIC_INLINE void nrf_wdt_reload_request_set(nrf_wdt_rr_register_t rr_register)
+{
+ NRF_WDT->RR[rr_register] = NRF_WDT_RR_VALUE;
+}
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/** @} */
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/power/nrf_drv_power.c b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/power/nrf_drv_power.c
new file mode 100644
index 000000000..3c1f26818
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/power/nrf_drv_power.c
@@ -0,0 +1,477 @@
+/**
+ * Copyright (c) 2017 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "sdk_common.h"
+#if NRF_MODULE_ENABLED(POWER)
+
+#include "nrf_drv_power.h"
+#include "nrf_assert.h"
+#include "nordic_common.h"
+#include "app_util_platform.h"
+#ifdef SOFTDEVICE_PRESENT
+#include "nrf_sdm.h"
+#include "nrf_soc.h"
+#include "nrf_sdh.h"
+#include "nrf_sdh_soc.h"
+#endif
+
+/* Validate configuration */
+INTERRUPT_PRIORITY_VALIDATION(POWER_CONFIG_IRQ_PRIORITY);
+
+/**
+ * @internal
+ * @defgroup nrf_drv_power_internals POWER driver internals
+ * @ingroup nrf_drv_power
+ *
+ * Internal variables, auxiliary macros and functions of POWER driver.
+ * @{
+ */
+
+/**
+ * @brief Default configuration
+ *
+ * The structure with default configuration data.
+ * This structure would be used if configuration pointer given
+ * to the @ref nrf_drv_power_init is set to NULL.
+ */
+static const nrf_drv_power_config_t m_drv_power_config_default =
+{
+ .dcdcen = POWER_CONFIG_DEFAULT_DCDCEN,
+#if NRF_POWER_HAS_VDDH
+ .dcdcenhv = POWER_CONFIG_DEFAULT_DCDCENHV,
+#endif
+};
+
+/**
+ * @brief The initialization flag
+ */
+static bool m_initialized;
+
+/**
+ * @brief The handler of power fail comparator warning event
+ */
+static nrf_drv_power_pofwarn_event_handler_t m_pofwarn_handler;
+
+#if NRF_POWER_HAS_SLEEPEVT
+/**
+ * @brief The handler of sleep event handler
+ */
+static nrf_drv_power_sleep_event_handler_t m_sleepevt_handler;
+#endif
+
+#if NRF_POWER_HAS_USBREG
+/**
+ * @brief The handler of USB power events
+ */
+static nrf_drv_power_usb_event_handler_t m_usbevt_handler;
+#endif
+
+/** @} */
+
+bool nrf_drv_power_init_check(void)
+{
+ return m_initialized;
+}
+
+ret_code_t nrf_drv_power_init(nrf_drv_power_config_t const * p_config)
+{
+ nrf_drv_power_config_t const * p_used_config;
+ if (m_initialized)
+ {
+ return NRF_ERROR_MODULE_ALREADY_INITIALIZED;
+ }
+#ifdef SOFTDEVICE_PRESENT
+ if (nrf_sdh_is_enabled())
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+#endif
+
+ p_used_config = (p_config != NULL) ?
+ p_config : (&m_drv_power_config_default);
+#if NRF_POWER_HAS_VDDH
+ nrf_power_dcdcen_vddh_set(p_used_config->dcdcenhv);
+#endif
+ nrf_power_dcdcen_set(p_used_config->dcdcen);
+
+ nrf_drv_common_power_clock_irq_init();
+
+ m_initialized = true;
+ return NRF_SUCCESS;
+}
+
+void nrf_drv_power_uninit(void)
+{
+ ASSERT(m_initialized);
+ nrf_drv_power_pof_uninit();
+#if NRF_POWER_HAS_SLEEPEVT
+ nrf_drv_power_sleepevt_uninit();
+#endif
+#if NRF_POWER_HAS_USBREG
+ nrf_drv_power_usbevt_uninit();
+#endif
+ m_initialized = false;
+}
+
+ret_code_t nrf_drv_power_pof_init(nrf_drv_power_pofwarn_config_t const * p_config)
+{
+ ASSERT(p_config != NULL);
+
+ nrf_drv_power_pof_uninit();
+
+#ifdef SOFTDEVICE_PRESENT
+ if (nrf_sdh_is_enabled())
+ {
+ /* Currently when SD is enabled - the configuration can be changed
+ * in very limited range.
+ * It is the SoftDevice limitation.
+ */
+#if NRF_POWER_HAS_VDDH
+ if (p_config->thrvddh != nrf_power_pofcon_vddh_get())
+ {
+ /* Cannot change THRVDDH with current SD API */
+ return NRF_ERROR_INVALID_STATE;
+ }
+#endif
+ if (p_config->thr != nrf_power_pofcon_get(NULL))
+ {
+ /* Only limited number of THR values are supported and
+ * the values taken by SD is different than the one in hardware
+ */
+ uint8_t thr;
+ switch (p_config->thr)
+ {
+ case NRF_POWER_POFTHR_V21:
+ thr = NRF_POWER_THRESHOLD_V21;
+ break;
+ case NRF_POWER_POFTHR_V23:
+ thr = NRF_POWER_THRESHOLD_V23;
+ break;
+ case NRF_POWER_POFTHR_V25:
+ thr = NRF_POWER_THRESHOLD_V25;
+ break;
+ case NRF_POWER_POFTHR_V27:
+ thr = NRF_POWER_THRESHOLD_V27;
+ break;
+ default:
+ /* Cannot configure */
+ return NRF_ERROR_INVALID_STATE;
+ }
+ ASSERT(sd_power_pof_threshold_set(thr));
+ }
+ }
+ else
+#endif /* SOFTDEVICE_PRESENT */
+ {
+ nrf_power_pofcon_set(true, p_config->thr);
+#if NRF_POWER_HAS_VDDH
+ nrf_power_pofcon_vddh_set(p_config->thrvddh);
+#endif
+ }
+
+ if (p_config->handler != NULL)
+ {
+ m_pofwarn_handler = p_config->handler;
+#ifdef SOFTDEVICE_PRESENT
+ if (nrf_sdh_is_enabled())
+ {
+ (void) sd_power_pof_enable(true);
+ }
+ else
+#endif
+ {
+ nrf_power_int_enable(NRF_POWER_INT_POFWARN_MASK);
+ }
+ }
+ return NRF_SUCCESS;
+}
+
+void nrf_drv_power_pof_uninit(void)
+{
+#ifdef SOFTDEVICE_PRESENT
+ if (nrf_sdh_is_enabled())
+ {
+ (void) sd_power_pof_enable(false);
+ }
+ else
+#endif
+ {
+ nrf_power_int_disable(NRF_POWER_INT_POFWARN_MASK);
+ }
+ m_pofwarn_handler = NULL;
+}
+
+#if NRF_POWER_HAS_SLEEPEVT
+ret_code_t nrf_drv_power_sleepevt_init(nrf_drv_power_sleepevt_config_t const * p_config)
+{
+ ASSERT(p_config != NULL);
+
+ nrf_drv_power_sleepevt_uninit();
+ if (p_config->handler != NULL)
+ {
+ uint32_t enmask = 0;
+ m_sleepevt_handler = p_config->handler;
+ if (p_config->en_enter)
+ {
+ enmask |= NRF_POWER_INT_SLEEPENTER_MASK;
+ nrf_power_event_clear(NRF_POWER_EVENT_SLEEPENTER);
+ }
+ if (p_config->en_exit)
+ {
+ enmask |= NRF_POWER_INT_SLEEPEXIT_MASK;
+ nrf_power_event_clear(NRF_POWER_EVENT_SLEEPEXIT);
+ }
+#ifdef SOFTDEVICE_PRESENT
+ if (nrf_sdh_is_enabled())
+ {
+ if (enmask != 0)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ }
+ else
+#endif
+ {
+ nrf_power_int_enable(enmask);
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+void nrf_drv_power_sleepevt_uninit(void)
+{
+#ifdef SOFTDEVICE_PRESENT
+ if (nrf_sdh_is_enabled())
+ {
+ /* Nothing to do */
+ }
+ else
+#endif
+ {
+ nrf_power_int_disable(
+ NRF_POWER_INT_SLEEPENTER_MASK |
+ NRF_POWER_INT_SLEEPEXIT_MASK);
+ }
+ m_sleepevt_handler = NULL;
+}
+#endif /* NRF_POWER_HAS_SLEEPEVT */
+
+#if NRF_POWER_HAS_USBREG
+ret_code_t nrf_drv_power_usbevt_init(nrf_drv_power_usbevt_config_t const * p_config)
+{
+ nrf_drv_power_usbevt_uninit();
+ if (p_config->handler != NULL)
+ {
+ m_usbevt_handler = p_config->handler;
+#ifdef SOFTDEVICE_PRESENT
+ if (nrf_sdh_is_enabled())
+ {
+ /** @todo Implement USB power events when SD support it */
+ return NRF_ERROR_INVALID_STATE;
+ }
+ else
+#endif
+ {
+ nrf_power_int_enable(
+ NRF_POWER_INT_USBDETECTED_MASK |
+ NRF_POWER_INT_USBREMOVED_MASK |
+ NRF_POWER_INT_USBPWRRDY_MASK);
+ }
+ }
+ return NRF_SUCCESS;
+}
+
+void nrf_drv_power_usbevt_uninit(void)
+{
+#ifdef SOFTDEVICE_PRESENT
+ if (nrf_sdh_is_enabled())
+ {
+ /** @todo Implement USB power events when SD support it */
+ }
+ else
+#endif
+ {
+ nrf_power_int_disable(
+ NRF_POWER_INT_USBDETECTED_MASK |
+ NRF_POWER_INT_USBREMOVED_MASK |
+ NRF_POWER_INT_USBPWRRDY_MASK);
+ }
+ m_usbevt_handler = NULL;
+}
+#endif /* NRF_POWER_HAS_USBREG */
+
+
+/**
+ * @ingroup nrf_drv_power_internals
+ * @brief Interrupt handler
+ *
+ * POWER peripheral interrupt handler
+ */
+#if NRF_DRV_COMMON_POWER_CLOCK_ISR
+void nrf_drv_power_onIRQ(void)
+#else
+void POWER_CLOCK_IRQHandler(void)
+#endif
+{
+ uint32_t enabled = nrf_power_int_enable_get();
+ if ((0 != (enabled & NRF_POWER_INT_POFWARN_MASK)) &&
+ nrf_power_event_get_and_clear(NRF_POWER_EVENT_POFWARN))
+ {
+ /* Cannot be null if event is enabled */
+ ASSERT(m_pofwarn_handler != NULL);
+ m_pofwarn_handler();
+ }
+#if NRF_POWER_HAS_SLEEPEVT
+ if ((0 != (enabled & NRF_POWER_INT_SLEEPENTER_MASK)) &&
+ nrf_power_event_get_and_clear(NRF_POWER_EVENT_SLEEPENTER))
+ {
+ /* Cannot be null if event is enabled */
+ ASSERT(m_sleepevt_handler != NULL);
+ m_sleepevt_handler(NRF_DRV_POWER_SLEEP_EVT_ENTER);
+ }
+ if ((0 != (enabled & NRF_POWER_INT_SLEEPEXIT_MASK)) &&
+ nrf_power_event_get_and_clear(NRF_POWER_EVENT_SLEEPEXIT))
+ {
+ /* Cannot be null if event is enabled */
+ ASSERT(m_sleepevt_handler != NULL);
+ m_sleepevt_handler(NRF_DRV_POWER_SLEEP_EVT_EXIT);
+ }
+#endif
+#if NRF_POWER_HAS_USBREG
+ if ((0 != (enabled & NRF_POWER_INT_USBDETECTED_MASK)) &&
+ nrf_power_event_get_and_clear(NRF_POWER_EVENT_USBDETECTED))
+ {
+ /* Cannot be null if event is enabled */
+ ASSERT(m_usbevt_handler != NULL);
+ m_usbevt_handler(NRF_DRV_POWER_USB_EVT_DETECTED);
+ }
+ if ((0 != (enabled & NRF_POWER_INT_USBREMOVED_MASK)) &&
+ nrf_power_event_get_and_clear(NRF_POWER_EVENT_USBREMOVED))
+ {
+ /* Cannot be null if event is enabled */
+ ASSERT(m_usbevt_handler != NULL);
+ m_usbevt_handler(NRF_DRV_POWER_USB_EVT_REMOVED);
+ }
+ if ((0 != (enabled & NRF_POWER_INT_USBPWRRDY_MASK)) &&
+ nrf_power_event_get_and_clear(NRF_POWER_EVENT_USBPWRRDY))
+ {
+ /* Cannot be null if event is enabled */
+ ASSERT(m_usbevt_handler != NULL);
+ m_usbevt_handler(NRF_DRV_POWER_USB_EVT_READY);
+ }
+#endif
+}
+
+#ifdef SOFTDEVICE_PRESENT
+
+static void nrf_drv_power_sdh_soc_evt_handler(uint32_t evt_id, void * p_context);
+static void nrf_drv_power_sdh_state_evt_handler(nrf_sdh_state_evt_t state, void * p_context);
+
+NRF_SDH_SOC_OBSERVER(m_soc_observer, POWER_CONFIG_SOC_OBSERVER_PRIO,
+ nrf_drv_power_sdh_soc_evt_handler, NULL);
+
+NRF_SDH_STATE_OBSERVER(m_sd_observer, POWER_CONFIG_STATE_OBSERVER_PRIO) =
+{
+ .handler = nrf_drv_power_sdh_state_evt_handler,
+ .p_context = NULL
+};
+
+static void nrf_drv_power_sdh_soc_evt_handler(uint32_t evt_id, void * p_context)
+{
+ if (evt_id == NRF_EVT_POWER_FAILURE_WARNING)
+ {
+ /* Cannot be null if event is enabled */
+ ASSERT(m_pofwarn_handler != NULL);
+ m_pofwarn_handler();
+ }
+}
+
+static void nrf_drv_power_on_sd_enable(void)
+{
+ ASSERT(m_initialized); /* This module has to be enabled first */
+ CRITICAL_REGION_ENTER();
+ if (m_pofwarn_handler != NULL)
+ {
+ (void) sd_power_pof_enable(true);
+ }
+ CRITICAL_REGION_EXIT();
+}
+
+static void nrf_drv_power_on_sd_disable(void)
+{
+ /* Reinit interrupts */
+ ASSERT(m_initialized);
+ nrf_drv_common_irq_enable(POWER_CLOCK_IRQn, CLOCK_CONFIG_IRQ_PRIORITY);
+ if (m_pofwarn_handler != NULL)
+ {
+ nrf_power_int_enable(NRF_POWER_INT_POFWARN_MASK);
+ }
+#if NRF_POWER_HAS_USBREG
+ if (m_usbevt_handler != NULL)
+ {
+ nrf_power_int_enable(
+ NRF_POWER_INT_USBDETECTED_MASK |
+ NRF_POWER_INT_USBREMOVED_MASK |
+ NRF_POWER_INT_USBPWRRDY_MASK);
+ }
+#endif
+}
+
+static void nrf_drv_power_sdh_state_evt_handler(nrf_sdh_state_evt_t state, void * p_context)
+{
+ switch (state)
+ {
+ case NRF_SDH_EVT_STATE_ENABLED:
+ nrf_drv_power_on_sd_enable();
+ break;
+
+ case NRF_SDH_EVT_STATE_DISABLED:
+ nrf_drv_power_on_sd_disable();
+ break;
+
+ default:
+ break;
+ }
+}
+
+#endif // SOFTDEVICE_PRESENT
+
+#endif /* NRF_MODULE_ENABLED(POWER) */
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/power/nrf_drv_power.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/power/nrf_drv_power.h
new file mode 100644
index 000000000..bb645e311
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/power/nrf_drv_power.h
@@ -0,0 +1,371 @@
+/**
+ * Copyright (c) 2017 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_DRV_POWER_H__
+#define NRF_DRV_POWER_H__
+
+#include <stdbool.h>
+#include <stdint.h>
+#include "nrf_power.h"
+#include "sdk_config.h"
+#include "nrf_drv_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup nrf_power Power HAL and driver
+ * @ingroup nrf_drivers
+ * @brief POWER peripheral APIs.
+ *
+ * The power peripheral HAL provides basic APIs for accessing
+ * the registers of the POWER peripheral.
+ * The POWER driver provides APIs on a higher level.
+ */
+
+/**
+ * @defgroup nrf_drv_power POWER driver
+ * @{
+ * @ingroup nrf_power
+ * @brief Driver for managing events and the state of POWER peripheral.
+ *
+ */
+
+/**
+ * @brief Power mode possible configurations
+ */
+typedef enum
+{
+ NRF_DRV_POWER_MODE_CONSTLAT, /**< Constant latency mode *///!< NRF_DRV_POWER_MODE_CONSTLAT
+ NRF_DRV_POWER_MODE_LOWPWR /**< Low power mode *///!< NRF_DRV_POWER_MODE_LOWPWR
+}nrf_drv_power_mode_t;
+
+#if NRF_POWER_HAS_SLEEPEVT
+/**
+ * @brief Events from power system
+ */
+typedef enum
+{
+ NRF_DRV_POWER_SLEEP_EVT_ENTER, /**< CPU entered WFI/WFE sleep
+ *
+ * Keep in mind that if this interrupt is enabled,
+ * it means that CPU was waken up just after WFI by this interrupt.
+ */
+ NRF_DRV_POWER_SLEEP_EVT_EXIT /**< CPU exited WFI/WFE sleep */
+}nrf_drv_power_sleep_evt_t;
+#endif /* NRF_POWER_HAS_SLEEPEVT */
+
+#if NRF_POWER_HAS_USBREG
+/**
+ * @brief Events from USB power system
+ */
+typedef enum
+{
+ NRF_DRV_POWER_USB_EVT_DETECTED, /**< USB power detected on the connector (plugged in). */
+ NRF_DRV_POWER_USB_EVT_REMOVED, /**< USB power removed from the connector. */
+ NRF_DRV_POWER_USB_EVT_READY /**< USB power regulator ready. */
+}nrf_drv_power_usb_evt_t;
+
+/**
+ * @brief USB power state
+ *
+ * The single enumerator that holds all data about current state of USB
+ * related POWER.
+ *
+ * Organized this way that higher power state has higher numeric value
+ */
+typedef enum
+{
+ NRF_DRV_POWER_USB_STATE_DISCONNECTED, /**< No power on USB lines detected */
+ NRF_DRV_POWER_USB_STATE_CONNECTED, /**< The USB power is detected, but USB power regulator is not ready */
+ NRF_DRV_POWER_USB_STATE_READY /**< From the power point of view USB is ready for working */
+}nrf_drv_power_usb_state_t;
+#endif /* NRF_POWER_HAS_USBREG */
+
+/**
+ * @name Callback types
+ *
+ * Defined types of callback functions
+ * @{
+ */
+/**
+ * @brief Event handler for power failure warning
+ */
+typedef void (*nrf_drv_power_pofwarn_event_handler_t)(void);
+
+#if NRF_POWER_HAS_SLEEPEVT
+/**
+ * @brief Event handler for entering/exiting sleep
+ *
+ * @param event Event type
+ */
+typedef void (*nrf_drv_power_sleep_event_handler_t)(nrf_drv_power_sleep_evt_t event);
+#endif
+
+#if NRF_POWER_HAS_USBREG
+/**
+ * @brief Event handler for USB related power events
+ *
+ * @param event Event type
+ */
+typedef void (*nrf_drv_power_usb_event_handler_t)(nrf_drv_power_usb_evt_t event);
+#endif
+/** @} */
+
+/**
+ * @brief General power configuration
+ *
+ * Parameters required to initialize power driver.
+ */
+typedef struct
+{
+ /**
+ * @brief Enable main DCDC regulator
+ *
+ * This bit only informs the driver that elements for DCDC regulator
+ * are installed and regulator can be used.
+ * The regulator would be enabled or disabled automatically
+ * automatically by the hardware, basing on current power requirement.
+ */
+ bool dcdcen:1;
+
+#if NRF_POWER_HAS_VDDH
+ /**
+ * @brief Enable HV DCDC regulator
+ *
+ * This bit only informs the driver that elements for DCDC regulator
+ * are installed and regulator can be used.
+ * The regulator would be enabled or disabled automatically
+ * automatically by the hardware, basing on current power requirement.
+ */
+ bool dcdcenhv: 1;
+#endif
+}nrf_drv_power_config_t;
+
+/**
+ * @brief The configuration for power failure comparator
+ *
+ * Configuration used to enable and configure power failure comparator
+ */
+typedef struct
+{
+ nrf_drv_power_pofwarn_event_handler_t handler; //!< Event handler
+ nrf_power_pof_thr_t thr; //!< Threshold for power failure detection
+#if NRF_POWER_HAS_VDDH
+ nrf_power_pof_thrvddh_t thrvddh; //!< Threshold for power failure detection on VDDH pin
+#endif
+}nrf_drv_power_pofwarn_config_t;
+
+#if NRF_POWER_HAS_SLEEPEVT
+/**
+ * @brief The configuration of sleep event processing
+ *
+ * Configuration used to enable and configure sleep event handling
+ */
+typedef struct
+{
+ nrf_drv_power_sleep_event_handler_t handler; //!< Event handler
+ bool en_enter:1; //!< Enable event on sleep entering
+ bool en_exit :1; //!< Enable event on sleep exiting
+}nrf_drv_power_sleepevt_config_t;
+#endif
+
+#if NRF_POWER_HAS_USBREG
+/**
+ * @brief The configuration of USB related power events
+ *
+ * Configuration used to enable and configure USB power event handling
+ */
+typedef struct
+{
+ nrf_drv_power_usb_event_handler_t handler; //!< Event processing
+}nrf_drv_power_usbevt_config_t;
+#endif /* NRF_POWER_HAS_USBREG */
+
+/**
+ * @brief Function for checking if driver is already initialized
+ *
+ * This function is used to check whatever common POWER_CLOCK common interrupt
+ * should be disabled or not if @ref nrf_drv_clock tries to disable the interrupt.
+ *
+ * @retval true Driver is initialized
+ * @retval false Driver is uninitialized
+ *
+ * @sa nrf_drv_power_uninit
+ */
+bool nrf_drv_power_init_check(void);
+
+/**
+ * @brief Initialize power module driver
+ *
+ * Enabled power module driver would process all the interrupts from power system.
+ *
+ * @param[in] p_config Driver configuration. Can be NULL - the default configuration
+ * from @em sdk_config.h file would be used then.
+ *
+ * @retval NRF_ERROR_INVALID_STATE Power driver has to be enabled
+ * before SoftDevice.
+ * @retval NRF_ERROR_MODULE_ALREADY_INITIALIZED Module is initialized already.
+ * @retval NRF_SUCCESS Successfully initialized.
+ */
+ret_code_t nrf_drv_power_init(nrf_drv_power_config_t const * p_config);
+
+/**
+ * @brief Unintialize power module driver
+ *
+ * Disables all the interrupt handling in the module.
+ *
+ * @sa nrf_drv_power_init
+ */
+void nrf_drv_power_uninit(void);
+
+/**
+ * @brief Initialize power failure comparator
+ *
+ * Configures and setups the power failure comparator and enables it.
+ *
+ * @param[in] p_config Configuration with values and event handler.
+ * If event handler is set to NULL, interrupt would be disabled.
+ *
+ * @retval NRF_ERROR_INVALID_STATE POF is initialized when SD is enabled and
+ * the configuration differs from the old one and
+ * is not possible to be set using SD interface.
+ * @retval NRF_SUCCESS Successfully initialized and configured.
+ */
+ret_code_t nrf_drv_power_pof_init(nrf_drv_power_pofwarn_config_t const * p_config);
+
+/**
+ * @brief Turn off the power failure comparator
+ *
+ * Disables and clears the settings of the power failure comparator.
+ */
+void nrf_drv_power_pof_uninit(void);
+
+#if NRF_POWER_HAS_SLEEPEVT
+/**
+ * @brief Initialize sleep entering and exiting events processing
+ *
+ * Configures and setups the sleep event processing.
+ *
+ * @param[in] p_config Configuration with values and event handler.
+ *
+ * @sa nrf_drv_power_sleepevt_uninit
+ *
+ * @note Sleep events are not available when SoftDevice is enabled.
+ * @note If sleep event is enabled when SoftDevice is initialized, sleep events
+ * would be automatically disabled - it is the limitation of the
+ * SoftDevice itself.
+ *
+ * @retval NRF_ERROR_INVALID_STATE This event cannot be initialized
+ * when SD is enabled.
+ * @retval NRF_SUCCESS Successfully initialized and configured.
+ */
+ret_code_t nrf_drv_power_sleepevt_init(nrf_drv_power_sleepevt_config_t const * p_config);
+
+/**
+ * @brief Uninitialize sleep entering and exiting events processing
+ *
+ * @sa nrf_drv_power_sleepevt_init
+ */
+void nrf_drv_power_sleepevt_uninit(void);
+#endif /* NRF_POWER_HAS_SLEEPEVT */
+
+#if NRF_POWER_HAS_USBREG
+/**
+ * @brief Initialize USB power event processing
+ *
+ * Configures and setups the USB power event processing.
+ *
+ * @param[in] p_config Configuration with values and event handler.
+ *
+ * @sa nrf_drv_power_usbevt_uninit
+ *
+ * @retval NRF_ERROR_INVALID_STATE This event cannot be initialized
+ * when SD is enabled and SD does not support
+ * USB power events.
+ * @retval NRF_SUCCESS Successfully initialized and configured.
+ */
+ret_code_t nrf_drv_power_usbevt_init(nrf_drv_power_usbevt_config_t const * p_config);
+
+/**
+ * @brief Uninitalize USB power event processing
+ *
+ * @sa nrf_drv_power_usbevt_init
+ */
+void nrf_drv_power_usbevt_uninit(void);
+
+/**
+ * @brief Get the status of USB power
+ *
+ * @return Current USB power status
+ */
+__STATIC_INLINE nrf_drv_power_usb_state_t nrf_drv_power_usbstatus_get(void);
+
+#endif /* NRF_POWER_HAS_USBREG */
+
+/** @} */
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+#if NRF_POWER_HAS_USBREG
+__STATIC_INLINE nrf_drv_power_usb_state_t nrf_drv_power_usbstatus_get(void)
+{
+ uint32_t status = nrf_power_usbregstatus_get();
+ if (0 == (status & NRF_POWER_USBREGSTATUS_VBUSDETECT_MASK))
+ {
+ return NRF_DRV_POWER_USB_STATE_DISCONNECTED;
+ }
+ if (0 == (status & NRF_POWER_USBREGSTATUS_OUTPUTRDY_MASK))
+ {
+ return NRF_DRV_POWER_USB_STATE_CONNECTED;
+ }
+ return NRF_DRV_POWER_USB_STATE_READY;
+}
+#endif /* NRF_POWER_HAS_USBREG */
+
+#endif /* SUPPRESS_INLINE_IMPLEMENTATION */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_DRV_POWER_H__ */
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/uart/nrf_drv_uart.c b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/uart/nrf_drv_uart.c
new file mode 100644
index 000000000..495a92b22
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/uart/nrf_drv_uart.c
@@ -0,0 +1,990 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "sdk_common.h"
+#if NRF_MODULE_ENABLED(UART)
+#include "nrf_drv_uart.h"
+#include "nrf_assert.h"
+#include "nrf_drv_common.h"
+#include "nrf_gpio.h"
+#include "app_util_platform.h"
+
+#define NRF_LOG_MODULE_NAME uart
+
+#if UART_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL UART_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR UART_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR UART_CONFIG_DEBUG_COLOR
+#define EVT_TO_STR(event) (event == NRF_UART_EVENT_ERROR ? "NRF_UART_EVENT_ERROR" : "UNKNOWN EVENT")
+#else //UART_CONFIG_LOG_ENABLED
+#define EVT_TO_STR(event) ""
+#define NRF_LOG_LEVEL 0
+#endif //UART_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#if (defined(UARTE_IN_USE) && defined(UART_IN_USE))
+ // UARTE and UART combined
+ #define CODE_FOR_UARTE(code) if (m_cb[p_instance->drv_inst_idx].use_easy_dma) { code }
+ #define CODE_FOR_UARTE_INT(idx, code) if (m_cb[idx].use_easy_dma) { code }
+ #define CODE_FOR_UART(code) else { code }
+#elif (defined(UARTE_IN_USE) && !defined(UART_IN_USE))
+ // UARTE only
+ #define CODE_FOR_UARTE(code) { code }
+ #define CODE_FOR_UARTE_INT(idx, code) { code }
+ #define CODE_FOR_UART(code)
+#elif (!defined(UARTE_IN_USE) && defined(UART_IN_USE))
+ // UART only
+ #define CODE_FOR_UARTE(code)
+ #define CODE_FOR_UARTE_INT(idx, code)
+ #define CODE_FOR_UART(code) { code }
+#else
+ #error "Wrong configuration."
+#endif
+
+#define TX_COUNTER_ABORT_REQ_VALUE 256
+
+typedef struct
+{
+ void * p_context;
+ nrf_uart_event_handler_t handler;
+ uint8_t const * p_tx_buffer;
+ uint8_t * p_rx_buffer;
+ uint8_t * p_rx_secondary_buffer;
+ volatile uint16_t tx_counter;
+ uint8_t tx_buffer_length;
+ uint8_t rx_buffer_length;
+ uint8_t rx_secondary_buffer_length;
+ volatile uint8_t rx_counter;
+ bool rx_enabled;
+ nrf_drv_state_t state;
+#if (defined(UARTE_IN_USE) && defined(UART_IN_USE))
+ bool use_easy_dma;
+#endif
+} uart_control_block_t;
+
+static uart_control_block_t m_cb[UART_ENABLED_COUNT];
+
+#ifdef NRF52810_XXAA
+ #define IRQ_HANDLER(n) void UARTE##n##_IRQHandler(void)
+#else
+ #define IRQ_HANDLER(n) void UART##n##_IRQHandler(void)
+#endif
+
+__STATIC_INLINE void apply_config(nrf_drv_uart_t const * p_instance, nrf_drv_uart_config_t const * p_config)
+{
+ if (p_config->pseltxd != NRF_UART_PSEL_DISCONNECTED)
+ {
+ nrf_gpio_pin_set(p_config->pseltxd);
+ nrf_gpio_cfg_output(p_config->pseltxd);
+ }
+ if (p_config->pselrxd != NRF_UART_PSEL_DISCONNECTED)
+ {
+ nrf_gpio_cfg_input(p_config->pselrxd, NRF_GPIO_PIN_NOPULL);
+ }
+
+ CODE_FOR_UARTE
+ (
+ nrf_uarte_baudrate_set(p_instance->reg.p_uarte, (nrf_uarte_baudrate_t)p_config->baudrate);
+ nrf_uarte_configure(p_instance->reg.p_uarte, (nrf_uarte_parity_t)p_config->parity,
+ (nrf_uarte_hwfc_t)p_config->hwfc);
+ nrf_uarte_txrx_pins_set(p_instance->reg.p_uarte, p_config->pseltxd, p_config->pselrxd);
+ if (p_config->hwfc == NRF_UART_HWFC_ENABLED)
+ {
+ if (p_config->pselcts != NRF_UART_PSEL_DISCONNECTED)
+ {
+ nrf_gpio_cfg_input(p_config->pselcts, NRF_GPIO_PIN_NOPULL);
+ }
+ if (p_config->pselrts != NRF_UART_PSEL_DISCONNECTED)
+ {
+ nrf_gpio_pin_set(p_config->pselrts);
+ nrf_gpio_cfg_output(p_config->pselrts);
+ }
+ nrf_uarte_hwfc_pins_set(p_instance->reg.p_uarte, p_config->pselrts, p_config->pselcts);
+ }
+ )
+ CODE_FOR_UART
+ (
+ nrf_uart_baudrate_set(p_instance->reg.p_uart, p_config->baudrate);
+ nrf_uart_configure(p_instance->reg.p_uart, p_config->parity, p_config->hwfc);
+ nrf_uart_txrx_pins_set(p_instance->reg.p_uart, p_config->pseltxd, p_config->pselrxd);
+ if (p_config->hwfc == NRF_UART_HWFC_ENABLED)
+ {
+ if (p_config->pselcts != NRF_UART_PSEL_DISCONNECTED)
+ {
+ nrf_gpio_cfg_input(p_config->pselcts, NRF_GPIO_PIN_NOPULL);
+ }
+ if (p_config->pselrts != NRF_UART_PSEL_DISCONNECTED)
+ {
+ nrf_gpio_pin_set(p_config->pselrts);
+ nrf_gpio_cfg_output(p_config->pselrts);
+ }
+ nrf_uart_hwfc_pins_set(p_instance->reg.p_uart, p_config->pselrts, p_config->pselcts);
+ }
+ )
+}
+
+__STATIC_INLINE void interrupts_enable(const nrf_drv_uart_t * p_instance, uint8_t interrupt_priority)
+{
+ CODE_FOR_UARTE
+ (
+ nrf_uarte_event_clear(p_instance->reg.p_uarte, NRF_UARTE_EVENT_ENDRX);
+ nrf_uarte_event_clear(p_instance->reg.p_uarte, NRF_UARTE_EVENT_ENDTX);
+ nrf_uarte_event_clear(p_instance->reg.p_uarte, NRF_UARTE_EVENT_ERROR);
+ nrf_uarte_event_clear(p_instance->reg.p_uarte, NRF_UARTE_EVENT_RXTO);
+ nrf_uarte_int_enable(p_instance->reg.p_uarte, NRF_UARTE_INT_ENDRX_MASK |
+ NRF_UARTE_INT_ENDTX_MASK |
+ NRF_UARTE_INT_ERROR_MASK |
+ NRF_UARTE_INT_RXTO_MASK);
+ nrf_drv_common_irq_enable(nrf_drv_get_IRQn((void *)p_instance->reg.p_uarte), interrupt_priority);
+ )
+ CODE_FOR_UART
+ (
+ nrf_uart_event_clear(p_instance->reg.p_uart, NRF_UART_EVENT_TXDRDY);
+ nrf_uart_event_clear(p_instance->reg.p_uart, NRF_UART_EVENT_RXTO);
+ nrf_uart_int_enable(p_instance->reg.p_uart, NRF_UART_INT_MASK_TXDRDY |
+ NRF_UART_INT_MASK_RXTO);
+ nrf_drv_common_irq_enable(nrf_drv_get_IRQn((void *)p_instance->reg.p_uart), interrupt_priority);
+ )
+}
+
+__STATIC_INLINE void interrupts_disable(const nrf_drv_uart_t * p_instance)
+{
+ CODE_FOR_UARTE
+ (
+ nrf_uarte_int_disable(p_instance->reg.p_uarte, NRF_UARTE_INT_ENDRX_MASK |
+ NRF_UARTE_INT_ENDTX_MASK |
+ NRF_UARTE_INT_ERROR_MASK |
+ NRF_UARTE_INT_RXTO_MASK);
+ nrf_drv_common_irq_disable(nrf_drv_get_IRQn((void *)p_instance->reg.p_uarte));
+ )
+ CODE_FOR_UART
+ (
+ nrf_uart_int_disable(p_instance->reg.p_uart, NRF_UART_INT_MASK_RXDRDY |
+ NRF_UART_INT_MASK_TXDRDY |
+ NRF_UART_INT_MASK_ERROR |
+ NRF_UART_INT_MASK_RXTO);
+ nrf_drv_common_irq_disable(nrf_drv_get_IRQn((void *)p_instance->reg.p_uart));
+ )
+
+}
+
+__STATIC_INLINE void pins_to_default(const nrf_drv_uart_t * p_instance)
+{
+ /* Reset pins to default states */
+ uint32_t txd;
+ uint32_t rxd;
+ uint32_t rts;
+ uint32_t cts;
+
+ CODE_FOR_UARTE
+ (
+ txd = nrf_uarte_tx_pin_get(p_instance->reg.p_uarte);
+ rxd = nrf_uarte_rx_pin_get(p_instance->reg.p_uarte);
+ rts = nrf_uarte_rts_pin_get(p_instance->reg.p_uarte);
+ cts = nrf_uarte_cts_pin_get(p_instance->reg.p_uarte);
+ nrf_uarte_txrx_pins_disconnect(p_instance->reg.p_uarte);
+ nrf_uarte_hwfc_pins_disconnect(p_instance->reg.p_uarte);
+ )
+ CODE_FOR_UART
+ (
+ txd = nrf_uart_tx_pin_get(p_instance->reg.p_uart);
+ rxd = nrf_uart_rx_pin_get(p_instance->reg.p_uart);
+ rts = nrf_uart_rts_pin_get(p_instance->reg.p_uart);
+ cts = nrf_uart_cts_pin_get(p_instance->reg.p_uart);
+ nrf_uart_txrx_pins_disconnect(p_instance->reg.p_uart);
+ nrf_uart_hwfc_pins_disconnect(p_instance->reg.p_uart);
+ )
+
+ if (txd != NRF_UART_PSEL_DISCONNECTED)
+ {
+ nrf_gpio_cfg_default(txd);
+ }
+
+ if (rxd != NRF_UART_PSEL_DISCONNECTED)
+ {
+ nrf_gpio_cfg_default(rxd);
+ }
+
+ if (cts != NRF_UART_PSEL_DISCONNECTED)
+ {
+ nrf_gpio_cfg_default(cts);
+ }
+
+ if (rts != NRF_UART_PSEL_DISCONNECTED)
+ {
+ nrf_gpio_cfg_default(rts);
+ }
+
+}
+
+__STATIC_INLINE void uart_enable(const nrf_drv_uart_t * p_instance)
+{
+ CODE_FOR_UARTE(nrf_uarte_enable(p_instance->reg.p_uarte);)
+ CODE_FOR_UART(nrf_uart_enable(p_instance->reg.p_uart););
+}
+
+__STATIC_INLINE void uart_disable(const nrf_drv_uart_t * p_instance)
+{
+ CODE_FOR_UARTE(nrf_uarte_disable(p_instance->reg.p_uarte);)
+ CODE_FOR_UART(nrf_uart_disable(p_instance->reg.p_uart););
+}
+
+ret_code_t nrf_drv_uart_init(const nrf_drv_uart_t * p_instance, nrf_drv_uart_config_t const * p_config,
+ nrf_uart_event_handler_t event_handler)
+{
+ ASSERT(p_config);
+ uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
+ ret_code_t err_code = NRF_SUCCESS;
+
+ if (p_cb->state != NRF_DRV_STATE_UNINITIALIZED)
+ {
+ err_code = NRF_ERROR_INVALID_STATE;
+ NRF_LOG_ERROR("Init failed. id:%d in wrong state", nrf_drv_get_IRQn((void *)p_instance->reg.p_reg));
+ return err_code;
+ }
+
+#if (defined(UARTE_IN_USE) && defined(UART_IN_USE))
+ p_cb->use_easy_dma = p_config->use_easy_dma;
+#endif
+ apply_config(p_instance, p_config);
+
+ p_cb->handler = event_handler;
+ p_cb->p_context = p_config->p_context;
+
+ if (p_cb->handler)
+ {
+ interrupts_enable(p_instance, p_config->interrupt_priority);
+ }
+
+ uart_enable(p_instance);
+ p_cb->rx_buffer_length = 0;
+ p_cb->rx_secondary_buffer_length = 0;
+ p_cb->tx_buffer_length = 0;
+ p_cb->state = NRF_DRV_STATE_INITIALIZED;
+ p_cb->rx_enabled = false;
+ return err_code;
+}
+
+void nrf_drv_uart_uninit(const nrf_drv_uart_t * p_instance)
+{
+ uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
+
+ uart_disable(p_instance);
+
+ if (p_cb->handler)
+ {
+ interrupts_disable(p_instance);
+ }
+
+ pins_to_default(p_instance);
+
+ p_cb->state = NRF_DRV_STATE_UNINITIALIZED;
+ p_cb->handler = NULL;
+ NRF_LOG_INFO("Uninit id: %d.", nrf_drv_get_IRQn((void *)p_instance->reg.p_reg));
+}
+
+#if defined(UART_IN_USE)
+__STATIC_INLINE void tx_byte(NRF_UART_Type * p_uart, uart_control_block_t * p_cb)
+{
+ nrf_uart_event_clear(p_uart, NRF_UART_EVENT_TXDRDY);
+ uint8_t txd = p_cb->p_tx_buffer[p_cb->tx_counter];
+ p_cb->tx_counter++;
+ nrf_uart_txd_set(p_uart, txd);
+}
+
+__STATIC_INLINE ret_code_t nrf_drv_uart_tx_for_uart(const nrf_drv_uart_t * p_instance)
+{
+ uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
+ ret_code_t err_code = NRF_SUCCESS;
+
+ nrf_uart_event_clear(p_instance->reg.p_uart, NRF_UART_EVENT_TXDRDY);
+ nrf_uart_task_trigger(p_instance->reg.p_uart, NRF_UART_TASK_STARTTX);
+
+ tx_byte(p_instance->reg.p_uart, p_cb);
+
+ if (p_cb->handler == NULL)
+ {
+ while (p_cb->tx_counter < (uint16_t) p_cb->tx_buffer_length)
+ {
+ while (!nrf_uart_event_check(p_instance->reg.p_uart, NRF_UART_EVENT_TXDRDY) &&
+ p_cb->tx_counter != TX_COUNTER_ABORT_REQ_VALUE)
+ {
+ }
+ if (p_cb->tx_counter != TX_COUNTER_ABORT_REQ_VALUE)
+ {
+ tx_byte(p_instance->reg.p_uart, p_cb);
+ }
+ }
+
+ if (p_cb->tx_counter == TX_COUNTER_ABORT_REQ_VALUE)
+ {
+ err_code = NRF_ERROR_FORBIDDEN;
+ }
+ else
+ {
+ while (!nrf_uart_event_check(p_instance->reg.p_uart, NRF_UART_EVENT_TXDRDY))
+ {
+ }
+ nrf_uart_task_trigger(p_instance->reg.p_uart, NRF_UART_TASK_STOPTX);
+ }
+ p_cb->tx_buffer_length = 0;
+ }
+ return err_code;
+}
+#endif
+
+#if defined(UARTE_IN_USE)
+__STATIC_INLINE ret_code_t nrf_drv_uart_tx_for_uarte(const nrf_drv_uart_t * p_instance)
+{
+ uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
+ ret_code_t err_code = NRF_SUCCESS;
+
+ nrf_uarte_event_clear(p_instance->reg.p_uarte, NRF_UARTE_EVENT_ENDTX);
+ nrf_uarte_event_clear(p_instance->reg.p_uarte, NRF_UARTE_EVENT_TXSTOPPED);
+ nrf_uarte_tx_buffer_set(p_instance->reg.p_uarte, p_cb->p_tx_buffer, p_cb->tx_buffer_length);
+ nrf_uarte_task_trigger(p_instance->reg.p_uarte, NRF_UARTE_TASK_STARTTX);
+
+ if (p_cb->handler == NULL)
+ {
+ bool endtx;
+ bool txstopped;
+ do
+ {
+ endtx = nrf_uarte_event_check(p_instance->reg.p_uarte, NRF_UARTE_EVENT_ENDTX);
+ txstopped = nrf_uarte_event_check(p_instance->reg.p_uarte, NRF_UARTE_EVENT_TXSTOPPED);
+ }
+ while ((!endtx) && (!txstopped));
+
+ if (txstopped)
+ {
+ err_code = NRF_ERROR_FORBIDDEN;
+ }
+ p_cb->tx_buffer_length = 0;
+ }
+ return err_code;
+}
+#endif
+
+ret_code_t nrf_drv_uart_tx(const nrf_drv_uart_t * p_instance, uint8_t const * const p_data, uint8_t length)
+{
+ uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
+ ASSERT(p_cb->state == NRF_DRV_STATE_INITIALIZED);
+ ASSERT(length>0);
+ ASSERT(p_data);
+
+ ret_code_t err_code;
+
+ CODE_FOR_UARTE
+ (
+ // EasyDMA requires that transfer buffers are placed in DataRAM,
+ // signal error if the are not.
+ if (!nrf_drv_is_in_RAM(p_data))
+ {
+ err_code = NRF_ERROR_INVALID_ADDR;
+ NRF_LOG_ERROR("Id:%d, Easy-DMA buffer not in RAM: %08x",
+ nrf_drv_get_IRQn((void *)p_instance->reg.p_reg), p_data);
+ return err_code;
+ }
+ )
+
+ if (nrf_drv_uart_tx_in_progress(p_instance))
+ {
+ err_code = NRF_ERROR_BUSY;
+ NRF_LOG_WARNING("Id:%d busy",nrf_drv_get_IRQn((void *)p_instance->reg.p_reg));
+ return err_code;
+ }
+ p_cb->tx_buffer_length = length;
+ p_cb->p_tx_buffer = p_data;
+ p_cb->tx_counter = 0;
+
+ NRF_LOG_INFO("TX req id:%d length: %d.",
+ nrf_drv_get_IRQn((void *)p_instance->reg.p_reg),
+ p_cb->tx_buffer_length);
+ NRF_LOG_DEBUG("Tx data:");
+ NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_cb->p_tx_buffer,
+ p_cb->tx_buffer_length * sizeof(p_cb->p_tx_buffer[0]));
+
+ CODE_FOR_UARTE
+ (
+ return nrf_drv_uart_tx_for_uarte(p_instance);
+ )
+ CODE_FOR_UART
+ (
+ return nrf_drv_uart_tx_for_uart(p_instance);
+ )
+}
+
+bool nrf_drv_uart_tx_in_progress(const nrf_drv_uart_t * p_instance)
+{
+ return (m_cb[p_instance->drv_inst_idx].tx_buffer_length != 0);
+}
+
+#if defined(UART_IN_USE)
+__STATIC_INLINE void rx_enable(const nrf_drv_uart_t * p_instance)
+{
+ nrf_uart_event_clear(p_instance->reg.p_uart, NRF_UART_EVENT_ERROR);
+ nrf_uart_event_clear(p_instance->reg.p_uart, NRF_UART_EVENT_RXDRDY);
+ nrf_uart_task_trigger(p_instance->reg.p_uart, NRF_UART_TASK_STARTRX);
+}
+
+__STATIC_INLINE void rx_byte(NRF_UART_Type * p_uart, uart_control_block_t * p_cb)
+{
+ if (!p_cb->rx_buffer_length)
+ {
+ nrf_uart_event_clear(p_uart, NRF_UART_EVENT_RXDRDY);
+ // Byte received when buffer is not set - data lost.
+ (void) nrf_uart_rxd_get(p_uart);
+ return;
+ }
+ nrf_uart_event_clear(p_uart, NRF_UART_EVENT_RXDRDY);
+ p_cb->p_rx_buffer[p_cb->rx_counter] = nrf_uart_rxd_get(p_uart);
+ p_cb->rx_counter++;
+}
+
+__STATIC_INLINE ret_code_t nrf_drv_uart_rx_for_uart(const nrf_drv_uart_t * p_instance, uint8_t * p_data, uint8_t length, bool second_buffer)
+{
+ ret_code_t err_code;
+
+ uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
+
+ if ((!p_cb->rx_enabled) && (!second_buffer))
+ {
+ rx_enable(p_instance);
+ }
+
+ if (p_cb->handler == NULL)
+ {
+ nrf_uart_event_clear(p_instance->reg.p_uart, NRF_UART_EVENT_RXTO);
+
+ bool rxrdy;
+ bool rxto;
+ bool error;
+ do
+ {
+ do
+ {
+ error = nrf_uart_event_check(p_instance->reg.p_uart, NRF_UART_EVENT_ERROR);
+ rxrdy = nrf_uart_event_check(p_instance->reg.p_uart, NRF_UART_EVENT_RXDRDY);
+ rxto = nrf_uart_event_check(p_instance->reg.p_uart, NRF_UART_EVENT_RXTO);
+ } while ((!rxrdy) && (!rxto) && (!error));
+
+ if (error || rxto)
+ {
+ break;
+ }
+ rx_byte(p_instance->reg.p_uart, p_cb);
+ } while (p_cb->rx_buffer_length > p_cb->rx_counter);
+
+ p_cb->rx_buffer_length = 0;
+ if (error)
+ {
+ err_code = NRF_ERROR_INTERNAL;
+ NRF_LOG_WARNING("RX Id: %d, transfer error.", nrf_drv_get_IRQn((void *)p_instance->reg.p_reg));
+ return err_code;
+ }
+
+ if (rxto)
+ {
+ NRF_LOG_WARNING("RX Id: %d, aborted.", nrf_drv_get_IRQn((void *)p_instance->reg.p_reg));
+ err_code = NRF_ERROR_FORBIDDEN;
+ return err_code;
+ }
+
+ if (p_cb->rx_enabled)
+ {
+ nrf_uart_task_trigger(p_instance->reg.p_uart, NRF_UART_TASK_STARTRX);
+ }
+ else
+ {
+ // Skip stopping RX if driver is forced to be enabled.
+ nrf_uart_task_trigger(p_instance->reg.p_uart, NRF_UART_TASK_STOPRX);
+ }
+ }
+ else
+ {
+ nrf_uart_int_enable(p_instance->reg.p_uart, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR);
+ }
+ err_code = NRF_SUCCESS;
+ return err_code;
+}
+#endif
+
+#if defined(UARTE_IN_USE)
+__STATIC_INLINE ret_code_t nrf_drv_uart_rx_for_uarte(const nrf_drv_uart_t * p_instance, uint8_t * p_data, uint8_t length, bool second_buffer)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+ nrf_uarte_event_clear(p_instance->reg.p_uarte, NRF_UARTE_EVENT_ENDRX);
+ nrf_uarte_event_clear(p_instance->reg.p_uarte, NRF_UARTE_EVENT_RXTO);
+ nrf_uarte_rx_buffer_set(p_instance->reg.p_uarte, p_data, length);
+ if (!second_buffer)
+ {
+ nrf_uarte_task_trigger(p_instance->reg.p_uarte, NRF_UARTE_TASK_STARTRX);
+ }
+ else
+ {
+ nrf_uarte_shorts_enable(p_instance->reg.p_uarte, NRF_UARTE_SHORT_ENDRX_STARTRX);
+ }
+
+ if (m_cb[p_instance->drv_inst_idx].handler == NULL)
+ {
+ bool endrx;
+ bool rxto;
+ bool error;
+ do {
+ endrx = nrf_uarte_event_check(p_instance->reg.p_uarte, NRF_UARTE_EVENT_ENDRX);
+ rxto = nrf_uarte_event_check(p_instance->reg.p_uarte, NRF_UARTE_EVENT_RXTO);
+ error = nrf_uarte_event_check(p_instance->reg.p_uarte, NRF_UARTE_EVENT_ERROR);
+ }while ((!endrx) && (!rxto) && (!error));
+
+ m_cb[p_instance->drv_inst_idx].rx_buffer_length = 0;
+
+ if (error)
+ {
+ err_code = NRF_ERROR_INTERNAL;
+ }
+
+ if (rxto)
+ {
+ err_code = NRF_ERROR_FORBIDDEN;
+ }
+ }
+ else
+ {
+ nrf_uarte_int_enable(p_instance->reg.p_uarte, NRF_UARTE_INT_ERROR_MASK | NRF_UARTE_INT_ENDRX_MASK);
+ }
+ return err_code;
+}
+#endif
+
+ret_code_t nrf_drv_uart_rx(const nrf_drv_uart_t * p_instance, uint8_t * p_data, uint8_t length)
+{
+ uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
+
+ ASSERT(m_cb[p_instance->drv_inst_idx].state == NRF_DRV_STATE_INITIALIZED);
+ ASSERT(length>0);
+
+ ret_code_t err_code;
+
+ CODE_FOR_UARTE
+ (
+ // EasyDMA requires that transfer buffers are placed in DataRAM,
+ // signal error if the are not.
+ if (!nrf_drv_is_in_RAM(p_data))
+ {
+ err_code = NRF_ERROR_INVALID_ADDR;
+ NRF_LOG_ERROR("Id:%d, Easy-DMA buffer not in RAM: %08x",
+ nrf_drv_get_IRQn((void *)p_instance->reg.p_reg), p_data);
+ return err_code;
+ }
+ )
+
+ bool second_buffer = false;
+
+ if (p_cb->handler)
+ {
+ CODE_FOR_UARTE
+ (
+ nrf_uarte_int_disable(p_instance->reg.p_uarte, NRF_UARTE_INT_ERROR_MASK | NRF_UARTE_INT_ENDRX_MASK);
+ )
+ CODE_FOR_UART
+ (
+ nrf_uart_int_disable(p_instance->reg.p_uart, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR);
+ )
+ }
+ if (p_cb->rx_buffer_length != 0)
+ {
+ if (p_cb->rx_secondary_buffer_length != 0)
+ {
+ if (p_cb->handler)
+ {
+ CODE_FOR_UARTE
+ (
+ nrf_uarte_int_enable(p_instance->reg.p_uarte, NRF_UARTE_INT_ERROR_MASK | NRF_UARTE_INT_ENDRX_MASK);
+ )
+ CODE_FOR_UART
+ (
+ nrf_uart_int_enable(p_instance->reg.p_uart, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR);
+ )
+ }
+ err_code = NRF_ERROR_BUSY;
+ NRF_LOG_WARNING("RX Id:%d, busy", nrf_drv_get_IRQn((void *)p_instance->reg.p_reg));
+ return err_code;
+ }
+ second_buffer = true;
+ }
+
+ if (!second_buffer)
+ {
+ p_cb->rx_buffer_length = length;
+ p_cb->p_rx_buffer = p_data;
+ p_cb->rx_counter = 0;
+ p_cb->rx_secondary_buffer_length = 0;
+ }
+ else
+ {
+ p_cb->p_rx_secondary_buffer = p_data;
+ p_cb->rx_secondary_buffer_length = length;
+ }
+
+ NRF_LOG_INFO("RX Id:%d len:%d", nrf_drv_get_IRQn((void *)p_instance->reg.p_reg), length);
+
+ CODE_FOR_UARTE
+ (
+ return nrf_drv_uart_rx_for_uarte(p_instance, p_data, length, second_buffer);
+ )
+ CODE_FOR_UART
+ (
+ return nrf_drv_uart_rx_for_uart(p_instance, p_data, length, second_buffer);
+ )
+}
+
+bool nrf_drv_uart_rx_ready(nrf_drv_uart_t const * p_instance)
+{
+ CODE_FOR_UARTE
+ (
+ return nrf_uarte_event_check(p_instance->reg.p_uarte, NRF_UARTE_EVENT_ENDRX);
+ )
+ CODE_FOR_UART
+ (
+ return nrf_uart_event_check(p_instance->reg.p_uart, NRF_UART_EVENT_RXDRDY);
+ )
+}
+
+void nrf_drv_uart_rx_enable(const nrf_drv_uart_t * p_instance)
+{
+ //Easy dma mode does not support enabling receiver without setting up buffer.
+ CODE_FOR_UARTE
+ (
+ ASSERT(false);
+ )
+ CODE_FOR_UART
+ (
+ if (!m_cb[p_instance->drv_inst_idx].rx_enabled)
+ {
+ rx_enable(p_instance);
+ m_cb[p_instance->drv_inst_idx].rx_enabled = true;
+ }
+ )
+}
+
+void nrf_drv_uart_rx_disable(const nrf_drv_uart_t * p_instance)
+{
+ //Easy dma mode does not support enabling receiver without setting up buffer.
+ CODE_FOR_UARTE
+ (
+ ASSERT(false);
+ )
+ CODE_FOR_UART
+ (
+ nrf_uart_task_trigger(p_instance->reg.p_uart, NRF_UART_TASK_STOPRX);
+ m_cb[p_instance->drv_inst_idx].rx_enabled = false;
+ )
+}
+
+uint32_t nrf_drv_uart_errorsrc_get(const nrf_drv_uart_t * p_instance)
+{
+ uint32_t errsrc;
+ CODE_FOR_UARTE
+ (
+ nrf_uarte_event_clear(p_instance->reg.p_uarte, NRF_UARTE_EVENT_ERROR);
+ errsrc = nrf_uarte_errorsrc_get_and_clear(p_instance->reg.p_uarte);
+ )
+ CODE_FOR_UART
+ (
+ nrf_uart_event_clear(p_instance->reg.p_uart, NRF_UART_EVENT_ERROR);
+ errsrc = nrf_uart_errorsrc_get_and_clear(p_instance->reg.p_uart);
+ )
+ return errsrc;
+}
+
+__STATIC_INLINE void rx_done_event(uart_control_block_t * p_cb, uint8_t bytes, uint8_t * p_data)
+{
+ nrf_drv_uart_event_t event;
+
+ event.type = NRF_DRV_UART_EVT_RX_DONE;
+ event.data.rxtx.bytes = bytes;
+ event.data.rxtx.p_data = p_data;
+
+ p_cb->handler(&event, p_cb->p_context);
+}
+
+__STATIC_INLINE void tx_done_event(uart_control_block_t * p_cb, uint8_t bytes)
+{
+ nrf_drv_uart_event_t event;
+
+ event.type = NRF_DRV_UART_EVT_TX_DONE;
+ event.data.rxtx.bytes = bytes;
+ event.data.rxtx.p_data = (uint8_t *)p_cb->p_tx_buffer;
+
+ p_cb->tx_buffer_length = 0;
+
+ NRF_LOG_INFO("TX done len:%d", bytes);
+ p_cb->handler(&event, p_cb->p_context);
+}
+
+void nrf_drv_uart_tx_abort(const nrf_drv_uart_t * p_instance)
+{
+ uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
+
+ CODE_FOR_UARTE
+ (
+ nrf_uarte_event_clear(p_instance->reg.p_uarte, NRF_UARTE_EVENT_TXSTOPPED);
+ nrf_uarte_task_trigger(p_instance->reg.p_uarte, NRF_UARTE_TASK_STOPTX);
+ if (p_cb->handler == NULL)
+ {
+ while (!nrf_uarte_event_check(p_instance->reg.p_uarte, NRF_UARTE_EVENT_TXSTOPPED));
+ }
+ )
+ CODE_FOR_UART
+ (
+ nrf_uart_task_trigger(p_instance->reg.p_uart, NRF_UART_TASK_STOPTX);
+ if (p_cb->handler)
+ {
+ tx_done_event(p_cb, p_cb->tx_counter);
+ }
+ else
+ {
+ p_cb->tx_counter = TX_COUNTER_ABORT_REQ_VALUE;
+ }
+ )
+ NRF_LOG_INFO("TX abort Id:%d", nrf_drv_get_IRQn((void *)p_instance->reg.p_reg));
+}
+
+void nrf_drv_uart_rx_abort(const nrf_drv_uart_t * p_instance)
+{
+ CODE_FOR_UARTE
+ (
+ nrf_uarte_task_trigger(p_instance->reg.p_uarte, NRF_UARTE_TASK_STOPRX);
+ )
+ CODE_FOR_UART
+ (
+ nrf_uart_int_disable(p_instance->reg.p_uart, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR);
+ nrf_uart_task_trigger(p_instance->reg.p_uart, NRF_UART_TASK_STOPRX);
+ )
+ NRF_LOG_INFO("RX abort Id:%d", nrf_drv_get_IRQn((void *)p_instance->reg.p_reg));
+}
+
+
+#if defined(UART_IN_USE)
+__STATIC_INLINE void uart_irq_handler(NRF_UART_Type * p_uart, uart_control_block_t * p_cb)
+{
+ if (nrf_uart_int_enable_check(p_uart, NRF_UART_INT_MASK_ERROR) &&
+ nrf_uart_event_check(p_uart, NRF_UART_EVENT_ERROR))
+ {
+ nrf_drv_uart_event_t event;
+ nrf_uart_event_clear(p_uart, NRF_UART_EVENT_ERROR);
+ nrf_uart_int_disable(p_uart, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR);
+ if (!p_cb->rx_enabled)
+ {
+ nrf_uart_task_trigger(p_uart, NRF_UART_TASK_STOPRX);
+ }
+ event.type = NRF_DRV_UART_EVT_ERROR;
+ event.data.error.error_mask = nrf_uart_errorsrc_get_and_clear(p_uart);
+ event.data.error.rxtx.bytes = p_cb->rx_buffer_length;
+ event.data.error.rxtx.p_data = p_cb->p_rx_buffer;
+
+ //abort transfer
+ p_cb->rx_buffer_length = 0;
+ p_cb->rx_secondary_buffer_length = 0;
+
+ p_cb->handler(&event,p_cb->p_context);
+ }
+ else if (nrf_uart_int_enable_check(p_uart, NRF_UART_INT_MASK_RXDRDY) &&
+ nrf_uart_event_check(p_uart, NRF_UART_EVENT_RXDRDY))
+ {
+ rx_byte(p_uart, p_cb);
+ if (p_cb->rx_buffer_length == p_cb->rx_counter)
+ {
+ if (p_cb->rx_secondary_buffer_length)
+ {
+ uint8_t * p_data = p_cb->p_rx_buffer;
+ uint8_t rx_counter = p_cb->rx_counter;
+
+ //Switch to secondary buffer.
+ p_cb->rx_buffer_length = p_cb->rx_secondary_buffer_length;
+ p_cb->p_rx_buffer = p_cb->p_rx_secondary_buffer;
+ p_cb->rx_secondary_buffer_length = 0;
+ p_cb->rx_counter = 0;
+ rx_done_event(p_cb, rx_counter, p_data);
+ }
+ else
+ {
+ if (!p_cb->rx_enabled)
+ {
+ nrf_uart_task_trigger(p_uart, NRF_UART_TASK_STOPRX);
+ }
+ nrf_uart_int_disable(p_uart, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR);
+ p_cb->rx_buffer_length = 0;
+ rx_done_event(p_cb, p_cb->rx_counter, p_cb->p_rx_buffer);
+ }
+ }
+ }
+
+ if (nrf_uart_event_check(p_uart, NRF_UART_EVENT_TXDRDY))
+ {
+ if (p_cb->tx_counter < (uint16_t) p_cb->tx_buffer_length)
+ {
+ tx_byte(p_uart, p_cb);
+ }
+ else
+ {
+ nrf_uart_event_clear(p_uart, NRF_UART_EVENT_TXDRDY);
+ if (p_cb->tx_buffer_length)
+ {
+ tx_done_event(p_cb, p_cb->tx_buffer_length);
+ }
+ }
+ }
+
+ if (nrf_uart_event_check(p_uart, NRF_UART_EVENT_RXTO))
+ {
+ nrf_uart_event_clear(p_uart, NRF_UART_EVENT_RXTO);
+
+ // RXTO event may be triggered as a result of abort call. In th
+ if (p_cb->rx_enabled)
+ {
+ nrf_uart_task_trigger(p_uart, NRF_UART_TASK_STARTRX);
+ }
+ if (p_cb->rx_buffer_length)
+ {
+ p_cb->rx_buffer_length = 0;
+ rx_done_event(p_cb, p_cb->rx_counter, p_cb->p_rx_buffer);
+ }
+ }
+}
+#endif
+
+#if defined(UARTE_IN_USE)
+__STATIC_INLINE void uarte_irq_handler(NRF_UARTE_Type * p_uarte, uart_control_block_t * p_cb)
+{
+ if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_ERROR))
+ {
+ nrf_drv_uart_event_t event;
+
+ nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_ERROR);
+
+ event.type = NRF_DRV_UART_EVT_ERROR;
+ event.data.error.error_mask = nrf_uarte_errorsrc_get_and_clear(p_uarte);
+ event.data.error.rxtx.bytes = nrf_uarte_rx_amount_get(p_uarte);
+ event.data.error.rxtx.p_data = p_cb->p_rx_buffer;
+
+ //abort transfer
+ p_cb->rx_buffer_length = 0;
+ p_cb->rx_secondary_buffer_length = 0;
+
+ p_cb->handler(&event, p_cb->p_context);
+ }
+ else if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_ENDRX))
+ {
+ nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_ENDRX);
+ uint8_t amount = nrf_uarte_rx_amount_get(p_uarte);
+ // If the transfer was stopped before completion, amount of transfered bytes
+ // will not be equal to the buffer length. Interrupted trunsfer is ignored.
+ if (amount == p_cb->rx_buffer_length)
+ {
+ if (p_cb->rx_secondary_buffer_length)
+ {
+ uint8_t * p_data = p_cb->p_rx_buffer;
+ nrf_uarte_shorts_disable(p_uarte, NRF_UARTE_SHORT_ENDRX_STARTRX);
+ p_cb->rx_buffer_length = p_cb->rx_secondary_buffer_length;
+ p_cb->p_rx_buffer = p_cb->p_rx_secondary_buffer;
+ p_cb->rx_secondary_buffer_length = 0;
+ rx_done_event(p_cb, amount, p_data);
+ }
+ else
+ {
+ p_cb->rx_buffer_length = 0;
+ rx_done_event(p_cb, amount, p_cb->p_rx_buffer);
+ }
+ }
+ }
+
+ if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_RXTO))
+ {
+ nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_RXTO);
+ if (p_cb->rx_buffer_length)
+ {
+ p_cb->rx_buffer_length = 0;
+ rx_done_event(p_cb, nrf_uarte_rx_amount_get(p_uarte), p_cb->p_rx_buffer);
+ }
+ }
+
+ if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_ENDTX))
+ {
+ nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_ENDTX);
+ if (p_cb->tx_buffer_length)
+ {
+ tx_done_event(p_cb, nrf_uarte_tx_amount_get(p_uarte));
+ }
+ }
+}
+#endif
+
+#if UART0_ENABLED
+IRQ_HANDLER(0)
+{
+ CODE_FOR_UARTE_INT
+ (
+ UART0_INSTANCE_INDEX,
+ uarte_irq_handler(NRF_UARTE0, &m_cb[UART0_INSTANCE_INDEX]);
+ )
+ CODE_FOR_UART
+ (
+ uart_irq_handler(NRF_UART0, &m_cb[UART0_INSTANCE_INDEX]);
+ )
+}
+#endif
+
+#if UART1_ENABLED
+void UARTE1_IRQHandler(void)
+{
+ CODE_FOR_UARTE_INT
+ (
+ UART1_INSTANCE_INDEX,
+ uarte_irq_handler(NRF_UARTE1, &m_cb[UART1_INSTANCE_INDEX]);
+ )
+ CODE_FOR_UART
+ (
+ uart_irq_handler(NRF_UART1, &m_cb[UART1_INSTANCE_INDEX]);
+ )
+}
+#endif
+#endif //NRF_MODULE_ENABLED(UART)
+
diff --git a/hw/mcu/nordic/nrf52/sdk/drivers_nrf/uart/nrf_drv_uart.h b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/uart/nrf_drv_uart.h
new file mode 100644
index 000000000..382192217
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/drivers_nrf/uart/nrf_drv_uart.h
@@ -0,0 +1,465 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ * @addtogroup nrf_uart UART driver and HAL
+ * @ingroup nrf_drivers
+ * @brief UART API.
+ * @details The UART driver provides APIs for utilizing the UART peripheral.
+ *
+ * @defgroup nrf_drv_uart UART driver
+ * @{
+ * @ingroup nrf_uart
+ *
+ * @brief UART driver.
+ */
+
+#ifndef NRF_DRV_UART_H
+#define NRF_DRV_UART_H
+
+#include "nrf_peripherals.h"
+
+#ifdef UART_PRESENT
+#include "nrf_uart.h"
+#endif
+
+#ifdef UARTE_PRESENT
+#include "nrf_uarte.h"
+#endif
+
+#include "sdk_errors.h"
+#include "sdk_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef UART1_ENABLED
+#define UART1_ENABLED 0
+#endif
+
+#ifndef UART0_ENABLED
+#define UART0_ENABLED 0
+#endif
+
+#define UART0_INSTANCE_INDEX 0
+#define UART1_INSTANCE_INDEX UART0_ENABLED
+#define UART_ENABLED_COUNT UART0_ENABLED + UART1_ENABLED
+
+#if defined(UARTE_PRESENT) && defined(UART_PRESENT)
+ #define NRF_DRV_UART_PERIPHERAL(id) \
+ (CONCAT_3(UART, id, _CONFIG_USE_EASY_DMA) == 1 ? \
+ (void *)CONCAT_2(NRF_UARTE, id) \
+ : (void *)CONCAT_2(NRF_UART, id))
+#elif defined(UART_PRESENT)
+ #define NRF_DRV_UART_PERIPHERAL(id) (void *)CONCAT_2(NRF_UART, id)
+#else //UARTE_PRESENT !UART_PRESENT
+ #define NRF_DRV_UART_PERIPHERAL(id) (void *)CONCAT_2(NRF_UARTE, id)
+#endif
+
+// This set of macros makes it possible to exclude parts of code, when one type
+// of supported peripherals is not used.
+
+#if defined(UARTE_PRESENT) && defined(UART_PRESENT)
+
+#if (UART_EASY_DMA_SUPPORT == 1)
+#define UARTE_IN_USE
+#endif
+
+#if (UART_LEGACY_SUPPORT == 1)
+#define UART_IN_USE
+#endif
+
+#if (UART_ENABLED == 1) && ((!defined(UARTE_IN_USE) && !defined(UART_IN_USE)) || ((UART_EASY_DMA_SUPPORT == 0) && (UART_LEGACY_SUPPORT == 0)))
+#error "Illegal settings in uart module!"
+#endif
+
+#elif defined(UART_PRESENT)
+#define UART_IN_USE
+#elif defined(UARTE_PRESENT)
+#define UARTE_IN_USE
+#endif
+
+#if defined(UARTE_PRESENT) && !defined(UART_PRESENT)
+typedef nrf_uarte_hwfc_t nrf_uart_hwfc_t;
+typedef nrf_uarte_parity_t nrf_uart_parity_t;
+typedef nrf_uarte_baudrate_t nrf_uart_baudrate_t;
+typedef nrf_uarte_error_mask_t nrf_uart_error_mask_t;
+typedef nrf_uarte_task_t nrf_uart_task_t;
+typedef nrf_uarte_event_t nrf_uart_event_t;
+#ifndef NRF_UART_PSEL_DISCONNECTED
+#define NRF_UART_PSEL_DISCONNECTED 0xFFFFFFFF
+#endif
+#endif
+
+/**
+ * @brief Structure for the UART driver instance.
+ */
+typedef struct
+{
+ union
+ {
+#if (defined(UARTE_IN_USE))
+ NRF_UARTE_Type * p_uarte; ///< Pointer to a structure with UARTE registers.
+#endif
+#if (defined(UART_IN_USE) || (UART_ENABLED == 0))
+ NRF_UART_Type * p_uart; ///< Pointer to a structure with UART registers.
+#endif
+ void * p_reg;
+ } reg;
+ uint8_t drv_inst_idx; ///< Driver instance index.
+} nrf_drv_uart_t;
+
+/**
+ * @brief Macro for creating an UART driver instance.
+ */
+#define NRF_DRV_UART_INSTANCE(id) \
+{ \
+ .reg = {NRF_DRV_UART_PERIPHERAL(id)}, \
+ .drv_inst_idx = CONCAT_3(UART, id, _INSTANCE_INDEX),\
+}
+
+/**
+ * @brief Types of UART driver events.
+ */
+typedef enum
+{
+ NRF_DRV_UART_EVT_TX_DONE, ///< Requested TX transfer completed.
+ NRF_DRV_UART_EVT_RX_DONE, ///< Requested RX transfer completed.
+ NRF_DRV_UART_EVT_ERROR, ///< Error reported by UART peripheral.
+} nrf_drv_uart_evt_type_t;
+
+/**@brief Structure for UART configuration. */
+typedef struct
+{
+ uint32_t pseltxd; ///< TXD pin number.
+ uint32_t pselrxd; ///< RXD pin number.
+ uint32_t pselcts; ///< CTS pin number.
+ uint32_t pselrts; ///< RTS pin number.
+ void * p_context; ///< Context passed to interrupt handler.
+ nrf_uart_hwfc_t hwfc; ///< Flow control configuration.
+ nrf_uart_parity_t parity; ///< Parity configuration.
+ nrf_uart_baudrate_t baudrate; ///< Baudrate.
+ uint8_t interrupt_priority; ///< Interrupt priority.
+#ifdef UARTE_PRESENT
+ bool use_easy_dma;
+#endif
+} nrf_drv_uart_config_t;
+
+/**@brief UART default configuration. */
+#ifdef UARTE_PRESENT
+#if !UART_LEGACY_SUPPORT
+#define DEFAULT_CONFIG_USE_EASY_DMA true
+#elif !UART_EASY_DMA_SUPPORT
+#define DEFAULT_CONFIG_USE_EASY_DMA false
+#else
+#define DEFAULT_CONFIG_USE_EASY_DMA UART0_USE_EASY_DMA
+#endif
+#define NRF_DRV_UART_DEFAULT_CONFIG \
+ { \
+ .pseltxd = NRF_UART_PSEL_DISCONNECTED, \
+ .pselrxd = NRF_UART_PSEL_DISCONNECTED, \
+ .pselcts = NRF_UART_PSEL_DISCONNECTED, \
+ .pselrts = NRF_UART_PSEL_DISCONNECTED, \
+ .p_context = NULL, \
+ .hwfc = (nrf_uart_hwfc_t)UART_DEFAULT_CONFIG_HWFC, \
+ .parity = (nrf_uart_parity_t)UART_DEFAULT_CONFIG_PARITY, \
+ .baudrate = (nrf_uart_baudrate_t)UART_DEFAULT_CONFIG_BAUDRATE, \
+ .interrupt_priority = UART_DEFAULT_CONFIG_IRQ_PRIORITY, \
+ .use_easy_dma = true \
+ }
+#else
+#define NRF_DRV_UART_DEFAULT_CONFIG \
+ { \
+ .pseltxd = NRF_UART_PSEL_DISCONNECTED, \
+ .pselrxd = NRF_UART_PSEL_DISCONNECTED, \
+ .pselcts = NRF_UART_PSEL_DISCONNECTED, \
+ .pselrts = NRF_UART_PSEL_DISCONNECTED, \
+ .p_context = NULL, \
+ .hwfc = (nrf_uart_hwfc_t)UART_DEFAULT_CONFIG_HWFC, \
+ .parity = (nrf_uart_parity_t)UART_DEFAULT_CONFIG_PARITY, \
+ .baudrate = (nrf_uart_baudrate_t)UART_DEFAULT_CONFIG_BAUDRATE, \
+ .interrupt_priority = UART_DEFAULT_CONFIG_IRQ_PRIORITY, \
+ }
+#endif
+
+/**@brief Structure for UART transfer completion event. */
+typedef struct
+{
+ uint8_t * p_data; ///< Pointer to memory used for transfer.
+ uint8_t bytes; ///< Number of bytes transfered.
+} nrf_drv_uart_xfer_evt_t;
+
+/**@brief Structure for UART error event. */
+typedef struct
+{
+ nrf_drv_uart_xfer_evt_t rxtx; ///< Transfer details includes number of bytes transfered.
+ uint32_t error_mask;///< Mask of error flags that generated the event.
+} nrf_drv_uart_error_evt_t;
+
+/**@brief Structure for UART event. */
+typedef struct
+{
+ nrf_drv_uart_evt_type_t type; ///< Event type.
+ union
+ {
+ nrf_drv_uart_xfer_evt_t rxtx; ///< Data provided for transfer completion events.
+ nrf_drv_uart_error_evt_t error;///< Data provided for error event.
+ } data;
+} nrf_drv_uart_event_t;
+
+/**
+ * @brief UART interrupt event handler.
+ *
+ * @param[in] p_event Pointer to event structure. Event is allocated on the stack so it is available
+ * only within the context of the event handler.
+ * @param[in] p_context Context passed to interrupt handler, set on initialization.
+ */
+typedef void (*nrf_uart_event_handler_t)(nrf_drv_uart_event_t * p_event, void * p_context);
+
+/**
+ * @brief Function for initializing the UART driver.
+ *
+ * This function configures and enables UART. After this function GPIO pins are controlled by UART.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ * @param[in] p_config Initial configuration.
+ * @param[in] event_handler Event handler provided by the user. If not provided driver works in
+ * blocking mode.
+ *
+ * @retval NRF_SUCCESS If initialization was successful.
+ * @retval NRF_ERROR_INVALID_STATE If driver is already initialized.
+ */
+ret_code_t nrf_drv_uart_init(nrf_drv_uart_t const * p_instance,
+ nrf_drv_uart_config_t const * p_config,
+ nrf_uart_event_handler_t event_handler);
+
+/**
+ * @brief Function for uninitializing the UART driver.
+ * @param[in] p_instance Pointer to the driver instance structure.
+ */
+void nrf_drv_uart_uninit(nrf_drv_uart_t const * p_instance);
+
+/**
+ * @brief Function for getting the address of a specific UART task.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ * @param[in] task Task.
+ *
+ * @return Task address.
+ */
+__STATIC_INLINE uint32_t nrf_drv_uart_task_address_get(nrf_drv_uart_t const * p_instance,
+ nrf_uart_task_t task);
+
+/**
+ * @brief Function for getting the address of a specific UART event.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ * @param[in] event Event.
+ *
+ * @return Event address.
+ */
+__STATIC_INLINE uint32_t nrf_drv_uart_event_address_get(nrf_drv_uart_t const * p_instance,
+ nrf_uart_event_t event);
+
+/**
+ * @brief Function for sending data over UART.
+ *
+ * If an event handler was provided in nrf_drv_uart_init() call, this function
+ * returns immediately and the handler is called when the transfer is done.
+ * Otherwise, the transfer is performed in blocking mode, i.e. this function
+ * returns when the transfer is finished. Blocking mode is not using interrupt so
+ * there is no context switching inside the function.
+ *
+ * @note Peripherals using EasyDMA (i.e. UARTE) require that the transfer buffers
+ * are placed in the Data RAM region. If they are not and UARTE instance is
+ * used, this function will fail with error code NRF_ERROR_INVALID_ADDR.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ * @param[in] p_data Pointer to data.
+ * @param[in] length Number of bytes to send.
+ *
+ * @retval NRF_SUCCESS If initialization was successful.
+ * @retval NRF_ERROR_BUSY If driver is already transferring.
+ * @retval NRF_ERROR_FORBIDDEN If the transfer was aborted from a different context
+ * (blocking mode only, also see @ref nrf_drv_uart_rx_disable).
+ * @retval NRF_ERROR_INVALID_ADDR If p_data does not point to RAM buffer (UARTE only).
+ */
+ret_code_t nrf_drv_uart_tx(nrf_drv_uart_t const * p_instance,
+ uint8_t const * const p_data, uint8_t length);
+
+/**
+ * @brief Function for checking if UART is currently transmitting.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ *
+ * @retval true If UART is transmitting.
+ * @retval false If UART is not transmitting.
+ */
+bool nrf_drv_uart_tx_in_progress(nrf_drv_uart_t const * p_instance);
+
+/**
+ * @brief Function for aborting any ongoing transmission.
+ * @note @ref NRF_DRV_UART_EVT_TX_DONE event will be generated in non-blocking mode. Event will
+ * contain number of bytes sent until abort was called. If Easy DMA is not used event will be
+ * called from the function context. If Easy DMA is used it will be called from UART interrupt
+ * context.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ */
+void nrf_drv_uart_tx_abort(nrf_drv_uart_t const * p_instance);
+
+/**
+ * @brief Function for receiving data over UART.
+ *
+ * If an event handler was provided in the nrf_drv_uart_init() call, this function
+ * returns immediately and the handler is called when the transfer is done.
+ * Otherwise, the transfer is performed in blocking mode, i.e. this function
+ * returns when the transfer is finished. Blocking mode is not using interrupt so
+ * there is no context switching inside the function.
+ * The receive buffer pointer is double buffered in non-blocking mode. The secondary
+ * buffer can be set immediately after starting the transfer and will be filled
+ * when the primary buffer is full. The double buffering feature allows
+ * receiving data continuously.
+ *
+ * @note Peripherals using EasyDMA (i.e. UARTE) require that the transfer buffers
+ * are placed in the Data RAM region. If they are not and UARTE driver instance
+ * is used, this function will fail with error code NRF_ERROR_INVALID_ADDR.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ * @param[in] p_data Pointer to data.
+ * @param[in] length Number of bytes to receive.
+ *
+ * @retval NRF_SUCCESS If initialization was successful.
+ * @retval NRF_ERROR_BUSY If the driver is already receiving
+ * (and the secondary buffer has already been set
+ * in non-blocking mode).
+ * @retval NRF_ERROR_FORBIDDEN If the transfer was aborted from a different context
+ * (blocking mode only, also see @ref nrf_drv_uart_rx_disable).
+ * @retval NRF_ERROR_INTERNAL If UART peripheral reported an error.
+ * @retval NRF_ERROR_INVALID_ADDR If p_data does not point to RAM buffer (UARTE only).
+ */
+ret_code_t nrf_drv_uart_rx(nrf_drv_uart_t const * p_instance,
+ uint8_t * p_data, uint8_t length);
+
+
+
+/**
+ * @brief Function for testing the receiver state in blocking mode.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ *
+ * @retval true If the receiver has at least one byte of data to get.
+ * @retval false If the receiver is empty.
+ */
+bool nrf_drv_uart_rx_ready(nrf_drv_uart_t const * p_instance);
+
+/**
+ * @brief Function for enabling the receiver.
+ *
+ * UART has a 6-byte-long RX FIFO and it is used to store incoming data. If a user does not call the
+ * UART receive function before the FIFO is filled, an overrun error will appear. Enabling the receiver
+ * without specifying an RX buffer is supported only in UART mode (without Easy DMA). The receiver must be
+ * explicitly closed by the user @sa nrf_drv_uart_rx_disable. This function asserts if the mode is wrong.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ */
+void nrf_drv_uart_rx_enable(nrf_drv_uart_t const * p_instance);
+
+/**
+ * @brief Function for disabling the receiver.
+ *
+ * This function must be called to close the receiver after it has been explicitly enabled by
+ * @sa nrf_drv_uart_rx_enable. The feature is supported only in UART mode (without Easy DMA). The function
+ * asserts if mode is wrong.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ */
+void nrf_drv_uart_rx_disable(nrf_drv_uart_t const * p_instance);
+
+/**
+ * @brief Function for aborting any ongoing reception.
+ * @note @ref NRF_DRV_UART_EVT_RX_DONE event will be generated in non-blocking mode. The event will
+ * contain the number of bytes received until abort was called. The event is called from UART interrupt
+ * context.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ */
+void nrf_drv_uart_rx_abort(nrf_drv_uart_t const * p_instance);
+
+/**
+ * @brief Function for reading error source mask. Mask contains values from @ref nrf_uart_error_mask_t.
+ * @note Function should be used in blocking mode only. In case of non-blocking mode, an error event is
+ * generated. Function clears error sources after reading.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ *
+ * @retval Mask of reported errors.
+ */
+uint32_t nrf_drv_uart_errorsrc_get(nrf_drv_uart_t const * p_instance);
+
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+__STATIC_INLINE uint32_t nrf_drv_uart_task_address_get(nrf_drv_uart_t const * p_instance,
+ nrf_uart_task_t task)
+{
+#ifdef UART_IN_USE
+ return nrf_uart_task_address_get(p_instance->reg.p_uart, task);
+#else
+ return nrf_uarte_task_address_get(p_instance->reg.p_uarte, (nrf_uarte_task_t)task);
+#endif
+}
+
+__STATIC_INLINE uint32_t nrf_drv_uart_event_address_get(nrf_drv_uart_t const * p_instance,
+ nrf_uart_event_t event)
+{
+#ifdef UART_IN_USE
+ return nrf_uart_event_address_get(p_instance->reg.p_uart, event);
+#else
+ return nrf_uarte_event_address_get(p_instance->reg.p_uarte, (nrf_uarte_event_t)event);
+#endif
+}
+#endif //SUPPRESS_INLINE_IMPLEMENTATION
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //NRF_DRV_UART_H
+/** @} */
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/atomic/nrf_atomic.h b/hw/mcu/nordic/nrf52/sdk/libraries/atomic/nrf_atomic.h
new file mode 100644
index 000000000..32ae3462f
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/atomic/nrf_atomic.h
@@ -0,0 +1,495 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_atomic Atomic operations API
+ * @ingroup nrf_atfifo
+ * @{
+ *
+ * @brief @tagAPI52 This module implements C11 stdatomic.h simplified API.
+ At this point only Cortex-M3/M4 cores are supported (LDREX/STREX instructions).
+ * Atomic types are limited to @ref nrf_atomic_u32_t and @ref nrf_atomic_flag_t.
+ */
+
+#ifndef NRF_ATOMIC_H__
+#define NRF_ATOMIC_H__
+
+#include "sdk_common.h"
+
+
+#ifndef NRF_ATOMIC_USE_BUILD_IN
+#if (defined(__GNUC__) && defined(WIN32))
+ #define NRF_ATOMIC_USE_BUILD_IN 1
+#else
+ #define NRF_ATOMIC_USE_BUILD_IN 0
+#endif
+#endif // NRF_ATOMIC_USE_BUILD_IN
+
+#if ((__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U))
+#define STREX_LDREX_PRESENT
+#else
+#include "app_util_platform.h"
+#endif
+
+/**
+ * @brief Atomic 32 bit unsigned type
+ * */
+typedef volatile uint32_t nrf_atomic_u32_t;
+
+/**
+ * @brief Atomic 1 bit flag type (technically 32 bit)
+ * */
+typedef volatile uint32_t nrf_atomic_flag_t;
+
+#if (NRF_ATOMIC_USE_BUILD_IN == 0) && defined(STREX_LDREX_PRESENT)
+#include "nrf_atomic_internal.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Stores value to an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value to store
+ *
+ * @return Old value stored into atomic object
+ * */
+static inline uint32_t nrf_atomic_u32_fetch_store(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_exchange_n(p_data, value, __ATOMIC_SEQ_CST);
+
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+ NRF_ATOMIC_OP(mov, old_val, new_val, p_data, value);
+
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return old_val;
+#else
+ CRITICAL_REGION_ENTER();
+ uint32_t old_val = *p_data;
+ *p_data = value;
+ CRITICAL_REGION_EXIT();
+ return old_val;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+/**
+ * @brief Stores value to an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value to store
+ *
+ * @return New value stored into atomic object
+ * */
+static inline uint32_t nrf_atomic_u32_store(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ __atomic_store_n(p_data, value, __ATOMIC_SEQ_CST);
+ return value;
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(mov, old_val, new_val, p_data, value);
+
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return new_val;
+#else
+ CRITICAL_REGION_ENTER();
+ *p_data = value;
+ CRITICAL_REGION_EXIT();
+ return value;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+/**
+ * @brief Logical OR operation on an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand OR operation
+ *
+ * @return Old value stored into atomic object
+ * */
+static inline uint32_t nrf_atomic_u32_fetch_or(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_fetch_or(p_data, value, __ATOMIC_SEQ_CST);
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(orr, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return old_val;
+#else
+ CRITICAL_REGION_ENTER();
+ uint32_t old_val = *p_data;
+ *p_data |= value;
+ CRITICAL_REGION_EXIT();
+ return old_val;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+/**
+ * @brief Logical OR operation on an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand OR operation
+ *
+ * @return New value stored into atomic object
+ * */
+static inline uint32_t nrf_atomic_u32_or(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_or_fetch(p_data, value, __ATOMIC_SEQ_CST);
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(orr, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return new_val;
+#else
+ CRITICAL_REGION_ENTER();
+ *p_data |= value;
+ uint32_t new_value = *p_data;
+ CRITICAL_REGION_EXIT();
+ return new_value;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+/**
+ * @brief Logical AND operation on an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand AND operation
+ *
+ * @return Old value stored into atomic object
+ * */
+static inline uint32_t nrf_atomic_u32_fetch_and(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_fetch_and(p_data, value, __ATOMIC_SEQ_CST);
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(and, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return old_val;
+#else
+ CRITICAL_REGION_ENTER();
+ uint32_t old_val = *p_data;
+ *p_data &= value;
+ CRITICAL_REGION_EXIT();
+ return old_val;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+/**
+ * @brief Logical AND operation on an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand AND operation
+ *
+ * @return New value stored into atomic object
+ * */
+static inline uint32_t nrf_atomic_u32_and(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_and_fetch(p_data, value, __ATOMIC_SEQ_CST);
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(and, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return new_val;
+#else
+ CRITICAL_REGION_ENTER();
+ *p_data &= value;
+ uint32_t new_value = *p_data;
+ CRITICAL_REGION_EXIT();
+ return new_value;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+/**
+ * @brief Logical XOR operation on an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand XOR operation
+ *
+ * @return Old value stored into atomic object
+ * */
+static inline uint32_t nrf_atomic_u32_fetch_xor(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_fetch_xor(p_data, value, __ATOMIC_SEQ_CST);
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(eor, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return old_val;
+#else
+ CRITICAL_REGION_ENTER();
+ uint32_t old_val = *p_data;
+ *p_data ^= value;
+ CRITICAL_REGION_EXIT();
+ return old_val;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+/**
+ * @brief Logical XOR operation on an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand XOR operation
+ *
+ * @return New value stored into atomic object
+ * */
+static inline uint32_t nrf_atomic_u32_xor(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_xor_fetch(p_data, value, __ATOMIC_SEQ_CST);
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(eor, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return new_val;
+#else
+ CRITICAL_REGION_ENTER();
+ *p_data ^= value;
+ uint32_t new_value = *p_data;
+ CRITICAL_REGION_EXIT();
+ return new_value;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+/**
+ * @brief Arithmetic ADD operation on an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand ADD operation
+ *
+ * @return Old value stored into atomic object
+ * */
+static inline uint32_t nrf_atomic_u32_fetch_add(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_fetch_add(p_data, value, __ATOMIC_SEQ_CST);
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(add, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return old_val;
+#else
+ CRITICAL_REGION_ENTER();
+ uint32_t old_val = *p_data;
+ *p_data += value;
+ CRITICAL_REGION_EXIT();
+ return old_val;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+/**
+ * @brief Arithmetic ADD operation on an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand ADD operation
+ *
+ * @return New value stored into atomic object
+ * */
+static inline uint32_t nrf_atomic_u32_add(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_add_fetch(p_data, value, __ATOMIC_SEQ_CST);
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(add, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return new_val;
+#else
+ CRITICAL_REGION_ENTER();
+ *p_data += value;
+ uint32_t new_value = *p_data;
+ CRITICAL_REGION_EXIT();
+ return new_value;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+/**
+ * @brief Arithmetic SUB operation on an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand SUB operation
+ *
+ * @return Old value stored into atomic object
+ * */
+static inline uint32_t nrf_atomic_u32_fetch_sub(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_fetch_sub(p_data, value, __ATOMIC_SEQ_CST);
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(sub, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return old_val;
+#else
+ CRITICAL_REGION_ENTER();
+ uint32_t old_val = *p_data;
+ *p_data -= value;
+ CRITICAL_REGION_EXIT();
+ return old_val;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+/**
+ * @brief Arithmetic SUB operation on an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand SUB operation
+ *
+ * @return New value stored into atomic object
+ * */
+static inline uint32_t nrf_atomic_u32_sub(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_sub_fetch(p_data, value, __ATOMIC_SEQ_CST);
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(sub, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return new_val;
+#else
+ CRITICAL_REGION_ENTER();
+ *p_data -= value;
+ uint32_t new_value = *p_data;
+ CRITICAL_REGION_EXIT();
+ return new_value;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+/**************************************************************************************************/
+
+/**
+ * @brief Logic one bit flag set operation on an atomic object
+ *
+ * @param[in] p_data Atomic flag memory pointer
+ *
+ * @return Old flag value
+ * */
+static inline uint32_t nrf_atomic_flag_set_fetch(nrf_atomic_flag_t * p_data)
+{
+ return nrf_atomic_u32_fetch_or(p_data, 1);
+}
+
+/**
+ * @brief Logic one bit flag set operation on an atomic object
+ *
+ * @param[in] p_data Atomic flag memory pointer
+ *
+ * @return New flag value
+ * */
+static inline uint32_t nrf_atomic_flag_set(nrf_atomic_flag_t * p_data)
+{
+ return nrf_atomic_u32_or(p_data, 1);
+}
+
+/**
+ * @brief Logic one bit flag clear operation on an atomic object
+ *
+ * @param[in] p_data Atomic flag memory pointer
+ *
+ * @return Old flag value
+ * */
+static inline uint32_t nrf_atomic_flag_clear_fetch(nrf_atomic_flag_t * p_data)
+{
+ return nrf_atomic_u32_fetch_and(p_data, 0);
+}
+
+/**
+ * @brief Logic one bit flag clear operation on an atomic object
+ *
+ * @param[in] p_data Atomic flag memory pointer
+ *
+ * @return New flag value
+ * */
+static inline uint32_t nrf_atomic_flag_clear(nrf_atomic_flag_t * p_data)
+{
+ return nrf_atomic_u32_and(p_data, 0);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_ATOMIC_H__ */
+
+/** @} */
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/atomic/nrf_atomic_internal.h b/hw/mcu/nordic/nrf52/sdk/libraries/atomic/nrf_atomic_internal.h
new file mode 100644
index 000000000..ada00c671
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/atomic/nrf_atomic_internal.h
@@ -0,0 +1,234 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_ATOMIC_INTERNAL_H__
+#define NRF_ATOMIC_INTERNAL_H__
+
+#include "sdk_common.h"
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ *
+ * @defgroup nrf_atomic_internal Atomic operations internals
+ * @ingroup nrf_atomic
+ * @{
+ *
+ */
+
+/* Only Cortex M cores > 3 support LDREX/STREX instructions*/
+#if ((__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)) == 0
+#error "Unsupported core version"
+#endif
+
+#if defined ( __CC_ARM )
+static __asm uint32_t nrf_atomic_internal_mov(nrf_atomic_u32_t * p_ptr,
+ uint32_t value,
+ uint32_t * p_new)
+{
+ /* The base standard provides for passing arguments in core registers (r0-r3) and on the stack.
+ * Registers r4 and r5 have to be saved on stack. Note that only even number of register push are
+ * allowed. This is a requirement of the Procedure Call Standard for the ARM Architecture [AAPCS].
+ * */
+ push {r4, r5}
+ mov r4, r0
+
+loop_mov
+ ldrex r0, [r4]
+ mov r5, r1
+ strex r3, r5, [r4]
+ cmp r3, #0
+ bne loop_mov
+
+ str r5, [r2]
+ pop {r4, r5}
+ bx lr
+}
+
+
+static __asm uint32_t nrf_atomic_internal_orr(nrf_atomic_u32_t * p_ptr,
+ uint32_t value,
+ uint32_t * p_new)
+{
+ push {r4, r5}
+ mov r4, r0
+
+loop_orr
+ ldrex r0, [r4]
+ orr r5, r0, r1
+ strex r3, r5, [r4]
+ cmp r3, #0
+ bne loop_orr
+
+ str r5, [r2]
+ pop {r4, r5}
+ bx lr
+}
+
+static __asm uint32_t nrf_atomic_internal_and(nrf_atomic_u32_t * p_ptr,
+ uint32_t value,
+ uint32_t * p_new)
+{
+ push {r4, r5}
+ mov r4, r0
+
+loop_and
+ ldrex r0, [r4]
+ and r5, r0, r1
+ strex r3, r5, [r4]
+ cmp r3, #0
+ bne loop_and
+
+ str r5, [r2]
+ pop {r4, r5}
+ bx lr
+}
+
+static __asm uint32_t nrf_atomic_internal_eor(nrf_atomic_u32_t * p_ptr,
+ uint32_t value,
+ uint32_t * p_new)
+{
+ push {r4, r5}
+ mov r4, r0
+
+loop_eor
+ ldrex r0, [r4]
+ eor r5, r0, r1
+ strex r3, r5, [r4]
+ cmp r3, #0
+ bne loop_eor
+
+ str r5, [r2]
+ pop {r4, r5}
+ bx lr
+}
+
+static __asm uint32_t nrf_atomic_internal_add(nrf_atomic_u32_t * p_ptr,
+ uint32_t value,
+ uint32_t * p_new)
+{
+ push {r4, r5}
+ mov r4, r0
+
+loop_add
+ ldrex r0, [r4]
+ add r5, r0, r1
+ strex r3, r5, [r4]
+ cmp r3, #0
+ bne loop_add
+
+ str r5, [r2]
+ pop {r4, r5}
+ bx lr
+}
+
+static __asm uint32_t nrf_atomic_internal_sub(nrf_atomic_u32_t * p_ptr,
+ uint32_t value,
+ uint32_t * p_new)
+{
+ push {r4, r5}
+ mov r4, r0
+
+loop_sub
+ ldrex r0, [r4]
+ sub r5, r0, r1
+ strex r3, r5, [r4]
+ cmp r3, #0
+ bne loop_sub
+
+ str r5, [r2]
+ pop {r4, r5}
+ bx lr
+}
+
+
+#define NRF_ATOMIC_OP(asm_op, old_val, new_val, ptr, value) \
+ old_val = nrf_atomic_internal_##asm_op(ptr, value, &new_val)
+
+#elif defined ( __ICCARM__ ) || defined ( __GNUC__ )
+
+/**
+ * @brief Atomic operation generic macro
+ * @param[in] asm_op operation: mov, orr, and, eor, add, sub
+ * @param[out] old_val atomic object output (uint32_t), value before operation
+ * @param[out] new_val atomic object output (uint32_t), value after operation
+ * @param[in] value atomic operation operand
+ * */
+#define NRF_ATOMIC_OP(asm_op, old_val, new_val, ptr, value) \
+{ \
+ uint32_t str_res; \
+ __ASM volatile( \
+ "1: ldrex %["#old_val"], [%["#ptr"]]\n" \
+ NRF_ATOMIC_OP_##asm_op(new_val, old_val, value) \
+ " strex %[str_res], %["#new_val"], [%["#ptr"]]\n" \
+ " teq %[str_res], #0\n" \
+ " bne.n 1b" \
+ : \
+ [old_val]"=&r" (old_val), \
+ [new_val]"=&r" (new_val), \
+ [str_res]"=&r" (str_res) \
+ : \
+ [ptr]"r" (ptr), \
+ [value]"r" (value) \
+ : "cc"); \
+ UNUSED_PARAMETER(str_res); \
+}
+
+#define NRF_ATOMIC_OP_mov(new_val, old_val, value) "mov %["#new_val"], %["#value"]\n"
+#define NRF_ATOMIC_OP_orr(new_val, old_val, value) "orr %["#new_val"], %["#old_val"], %["#value"]\n"
+#define NRF_ATOMIC_OP_and(new_val, old_val, value) "and %["#new_val"], %["#old_val"], %["#value"]\n"
+#define NRF_ATOMIC_OP_eor(new_val, old_val, value) "eor %["#new_val"], %["#old_val"], %["#value"]\n"
+#define NRF_ATOMIC_OP_add(new_val, old_val, value) "add %["#new_val"], %["#old_val"], %["#value"]\n"
+#define NRF_ATOMIC_OP_sub(new_val, old_val, value) "sub %["#new_val"], %["#old_val"], %["#value"]\n"
+
+#else
+#error "Unsupported compiler"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_ATOMIC_INTERNAL_H__ */
+
+/** @} */
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/atomic/nrf_atomic_sanity_check.h b/hw/mcu/nordic/nrf52/sdk/libraries/atomic/nrf_atomic_sanity_check.h
new file mode 100644
index 000000000..f07006cf7
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/atomic/nrf_atomic_sanity_check.h
@@ -0,0 +1,153 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_ATOMIC_SANITY_CHECK_H__
+#define NRF_ATOMIC_SANITY_CHECK_H__
+
+#include "nrf_atomic.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Quick sanity check of nrf_atomic API
+ * */
+static inline void nrf_atomic_sanity_check(void)
+{
+#if defined(DEBUG_NRF) || defined(DEBUG_NRF_USER)
+ nrf_atomic_u32_t val;
+ nrf_atomic_u32_t flag;
+
+ /*Fetch version tests*/
+ val = 0;
+ ASSERT(nrf_atomic_u32_store_fetch(&val, 10) == 0);
+ ASSERT(nrf_atomic_u32_store_fetch(&val, 0) == 10);
+
+ val = 0;
+ ASSERT(nrf_atomic_u32_or_fetch(&val, 1 << 16) == 0);
+ ASSERT(nrf_atomic_u32_or_fetch(&val, 1 << 5) == ((1 << 16)));
+ ASSERT(nrf_atomic_u32_or_fetch(&val, 1 << 5) == ((1 << 16) | (1 << 5)));
+ ASSERT(nrf_atomic_u32_or_fetch(&val, 0) == ((1 << 16) | (1 << 5)));
+ ASSERT(nrf_atomic_u32_or_fetch(&val, 0xFFFFFFFF) == ((1 << 16) | (1 << 5)));
+ ASSERT(nrf_atomic_u32_or_fetch(&val, 0xFFFFFFFF) == (0xFFFFFFFF));
+
+ val = 0xFFFFFFFF;
+ ASSERT(nrf_atomic_u32_and_fetch(&val, ~(1 << 16)) == 0xFFFFFFFF);
+ ASSERT(nrf_atomic_u32_and_fetch(&val, ~(1 << 5)) == (0xFFFFFFFF & ~((1 << 16))));
+ ASSERT(nrf_atomic_u32_and_fetch(&val, 0) == (0xFFFFFFFF & ~(((1 << 16) | (1 << 5)))));
+ ASSERT(nrf_atomic_u32_and_fetch(&val, 0xFFFFFFFF) == (0));
+
+ val = 0;
+ ASSERT(nrf_atomic_u32_xor_fetch(&val, (1 << 16)) == 0);
+ ASSERT(nrf_atomic_u32_xor_fetch(&val, (1 << 5)) == ((1 << 16)));
+ ASSERT(nrf_atomic_u32_xor_fetch(&val, 0) == ((1 << 16) | (1 << 5)));
+ ASSERT(nrf_atomic_u32_xor_fetch(&val, (1 << 16) | (1 << 5)) == ((1 << 16) | (1 << 5)));
+ ASSERT(nrf_atomic_u32_xor_fetch(&val, 0) == (0));
+
+ val = 0;
+ ASSERT(nrf_atomic_u32_add_fetch(&val, 100) == 0);
+ ASSERT(nrf_atomic_u32_add_fetch(&val, 100) == 100);
+ ASSERT(nrf_atomic_u32_add_fetch(&val, 1 << 24) == 200);
+ ASSERT(nrf_atomic_u32_add_fetch(&val, 0) == (200 + (1 << 24)));
+ ASSERT(nrf_atomic_u32_add_fetch(&val, 0xFFFFFFFF) == (200 + (1 << 24)));
+ ASSERT(nrf_atomic_u32_add_fetch(&val, 0) == (200 - 1 + (1 << 24)));
+
+ val = 1000;
+ ASSERT(nrf_atomic_u32_sub_fetch(&val, 100) == 1000);
+ ASSERT(nrf_atomic_u32_sub_fetch(&val, 100) == 900);
+ ASSERT(nrf_atomic_u32_sub_fetch(&val, 0) == 800);
+ ASSERT(nrf_atomic_u32_sub_fetch(&val, 0xFFFFFFFF) == 800);
+ ASSERT(nrf_atomic_u32_sub_fetch(&val, 0) == 801);
+
+ flag = 0;
+ ASSERT(nrf_atomic_flag_set_fetch(&flag) == 0);
+ ASSERT(nrf_atomic_flag_set_fetch(&flag) == 1);
+ ASSERT(nrf_atomic_flag_clear_fetch(&flag) == 1);
+ ASSERT(nrf_atomic_flag_clear_fetch(&flag) == 0);
+
+ /*No fetch version tests*/
+ val = 0;
+ ASSERT(nrf_atomic_u32_store(&val, 10) == 10);
+ ASSERT(nrf_atomic_u32_store(&val, 0) == 0);
+
+ val = 0;
+ ASSERT(nrf_atomic_u32_or(&val, 1 << 16) == 1 << 16);
+ ASSERT(nrf_atomic_u32_or(&val, 1 << 5) == ((1 << 16) | (1 << 5)));
+ ASSERT(nrf_atomic_u32_or(&val, 1 << 5) == ((1 << 16) | (1 << 5)));
+ ASSERT(nrf_atomic_u32_or(&val, 0) == ((1 << 16) | (1 << 5)));
+ ASSERT(nrf_atomic_u32_or(&val, 0xFFFFFFFF) == 0xFFFFFFFF);
+
+ val = 0xFFFFFFFF;
+ ASSERT(nrf_atomic_u32_and(&val, ~(1 << 16)) == (0xFFFFFFFF & ~((1 << 16))));
+ ASSERT(nrf_atomic_u32_and(&val, ~(1 << 5)) == (0xFFFFFFFF & ~(((1 << 16) | (1 << 5)))));
+ ASSERT(nrf_atomic_u32_and(&val, 0) == 0);
+
+ val = 0;
+ ASSERT(nrf_atomic_u32_xor(&val, (1 << 16)) == ((1 << 16)));
+ ASSERT(nrf_atomic_u32_xor(&val, (1 << 5)) == ((1 << 16) | (1 << 5)));
+ ASSERT(nrf_atomic_u32_xor(&val, 0) == ((1 << 16) | (1 << 5)));
+ ASSERT(nrf_atomic_u32_xor(&val, (1 << 16) | (1 << 5)) == 0);
+
+ val = 0;
+ ASSERT(nrf_atomic_u32_add(&val, 100) == 100);
+ ASSERT(nrf_atomic_u32_add(&val, 100) == 200);
+ ASSERT(nrf_atomic_u32_add(&val, 1 << 24) == (200 + (1 << 24)));
+ ASSERT(nrf_atomic_u32_add(&val, 0) == (200 + (1 << 24)));
+ ASSERT(nrf_atomic_u32_add(&val, 0xFFFFFFFF) == (200 - 1 + (1 << 24)));
+
+ val = 1000;
+ ASSERT(nrf_atomic_u32_sub(&val, 100) == 900);
+ ASSERT(nrf_atomic_u32_sub(&val, 100) == 800);
+ ASSERT(nrf_atomic_u32_sub(&val, 0) == 800);
+ ASSERT(nrf_atomic_u32_sub(&val, 0xFFFFFFFF) == 801);
+
+ flag = 0;
+ ASSERT(nrf_atomic_flag_set(&flag) == 1);
+ ASSERT(nrf_atomic_flag_set(&flag) == 1);
+ ASSERT(nrf_atomic_flag_clear(&flag) == 0);
+ ASSERT(nrf_atomic_flag_clear(&flag) == 0);
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_ATOMIC_SANITY_CHECK_H__ */
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/balloc/nrf_balloc.c b/hw/mcu/nordic/nrf52/sdk/libraries/balloc/nrf_balloc.c
new file mode 100644
index 000000000..b2eb43d09
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/balloc/nrf_balloc.c
@@ -0,0 +1,343 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "sdk_common.h"
+ #if NRF_MODULE_ENABLED(NRF_BALLOC)
+
+#include "nrf_balloc.h"
+#include "app_util_platform.h"
+
+#define NRF_LOG_MODULE_NAME balloc
+#if NRF_BALLOC_CONFIG_LOG_ENABLED
+ #define NRF_LOG_LEVEL NRF_BALLOC_CONFIG_LOG_LEVEL
+ #define NRF_LOG_INFO_COLOR NRF_BALLOC_CONFIG_INFO_COLOR
+ #define NRF_LOG_DEBUG_COLOR NRF_BALLOC_CONFIG_DEBUG_COLOR
+#else
+ #define NRF_LOG_LEVEL 0
+#endif // NRF_BALLOC_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define HEAD_GUARD_FILL 0xBAADF00D /**< Magic number used to mark head guard.*/
+#define TAIL_GUARD_FILL 0xBAADCAFE /**< Magic number used to mark tail guard.*/
+#define FREE_MEM_FILL 0xBAADBAAD /**< Magic number used to mark free memory.*/
+
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+#define POOL_ID(_p_pool) _p_pool->p_name
+#define POOL_MARKER "%s"
+#else
+#define POOL_ID(_p_pool) _p_pool
+#define POOL_MARKER "0x%08X"
+#endif
+
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+
+/**@brief Validate block memory, prepare block guards, and calculate pointer to the element.
+ *
+ * @param[in] p_pool Pointer to the memory pool.
+ * @param[in] p_head Pointer to the beginning of the block.
+ *
+ * @return Pointer to the element.
+ */
+__STATIC_INLINE void * nrf_balloc_block_unwrap(nrf_balloc_t const * p_pool, void * p_head)
+{
+ ASSERT((p_pool != NULL) && ((p_pool->block_size % sizeof(uint32_t)) == 0));
+ ASSERT((p_head != NULL) && (((uint32_t)(p_head) % sizeof(uint32_t)) == 0));
+
+ uint32_t head_words = NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_GET(p_pool->debug_flags);
+ uint32_t tail_words = NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_GET(p_pool->debug_flags);
+
+ uint32_t * p_tail = (uint32_t *)((size_t)(p_head) + p_pool->block_size);
+ uint32_t * p_element = (uint32_t *)p_head + head_words;
+
+ if (NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_GET(p_pool->debug_flags))
+ {
+ for (uint32_t * ptr = p_head; ptr < p_tail; ptr++)
+ {
+ if (*ptr != FREE_MEM_FILL)
+ {
+ NRF_LOG_ERROR("Detected free memory corruption at 0x%08X (0x%08X != 0x%08X, pool: '" POOL_MARKER "')",
+ ptr, *ptr, FREE_MEM_FILL, POOL_ID(p_pool));
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ }
+ }
+
+ for (uint32_t * ptr = p_head; ptr < p_element; ptr++)
+ {
+ *ptr = HEAD_GUARD_FILL;
+ }
+
+ for (uint32_t * ptr = ( p_tail - tail_words); ptr < p_tail; ptr++)
+ {
+ *ptr = TAIL_GUARD_FILL;
+ }
+
+ return p_element;
+}
+
+/**@brief Calculate pointer to the block, validate block guards, and mark block memory as free.
+ *
+ * @param[in] p_pool Pointer to the memory pool.
+ * @param[in] p_element Pointer to the element.
+ *
+ * @return Pointer to the beginning of the block.
+ */
+__STATIC_INLINE void * nrf_balloc_element_wrap(nrf_balloc_t const * p_pool, void * p_element)
+{
+ ASSERT((p_pool != NULL) && ((p_pool->block_size % sizeof(uint32_t)) == 0));
+ ASSERT((p_element != NULL) && (((uint32_t)(p_element) % sizeof(uint32_t)) == 0));
+
+ uint32_t head_words = NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_GET(p_pool->debug_flags);
+ uint32_t tail_words = NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_GET(p_pool->debug_flags);
+
+ uint32_t * p_head = (uint32_t *)p_element - head_words;
+ uint32_t * p_tail = (uint32_t *)((size_t)(p_head) + p_pool->block_size);
+
+ for (uint32_t * ptr = p_head; ptr < (uint32_t *)p_element; ptr++)
+ {
+ if (*ptr != HEAD_GUARD_FILL)
+ {
+ NRF_LOG_ERROR("Detected Head Guard corruption at 0x%08X (0x%08X != 0x%08X, pool: '" POOL_MARKER "')",
+ ptr, *ptr, HEAD_GUARD_FILL, POOL_ID(p_pool));
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ }
+
+ for (uint32_t * ptr = ( p_tail - tail_words); ptr < p_tail; ptr++)
+ {
+ if (*ptr != TAIL_GUARD_FILL)
+ {
+ NRF_LOG_ERROR("Detected Tail Guard corruption at 0x%08X (0x%08X != 0x%08X, pool: '" POOL_MARKER "')",
+ ptr, *ptr, TAIL_GUARD_FILL, POOL_ID(p_pool));
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ }
+
+ if (NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_GET(p_pool->debug_flags))
+ {
+ for (uint32_t * ptr = p_head; ptr < p_tail; ptr++)
+ {
+ *ptr = FREE_MEM_FILL;
+ }
+ }
+
+ return p_head;
+}
+
+#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED
+
+/**@brief Convert block index to a pointer.
+ *
+ * @param[in] p_pool Pointer to the memory pool.
+ * @param[in] idx Index of the block.
+ *
+ * @return Pointer to the beginning of the block.
+ */
+static void * nrf_balloc_idx2block(nrf_balloc_t const * p_pool, uint8_t idx)
+{
+ ASSERT(p_pool != NULL);
+ return (uint8_t *)(p_pool->p_memory_begin) + ((size_t)(idx) * p_pool->block_size);
+}
+
+/**@brief Convert block pointer to index.
+ *
+ * @param[in] p_pool Pointer to the memory pool.
+ * @param[in] p_block Pointer to the beginning of the block.
+ *
+ * @return Index of the block.
+ */
+static uint8_t nrf_balloc_block2idx(nrf_balloc_t const * p_pool, void const * p_block)
+{
+ ASSERT(p_pool != NULL);
+ return ((size_t)(p_block) - (size_t)(p_pool->p_memory_begin)) / p_pool->block_size;
+}
+
+ret_code_t nrf_balloc_init(nrf_balloc_t const * p_pool)
+{
+ uint8_t pool_size;
+
+ VERIFY_PARAM_NOT_NULL(p_pool);
+
+ ASSERT(p_pool->p_cb);
+ ASSERT(p_pool->p_stack_base);
+ ASSERT(p_pool->p_stack_limit);
+ ASSERT(p_pool->p_memory_begin);
+ ASSERT(p_pool->block_size);
+
+ pool_size = p_pool->p_stack_limit - p_pool->p_stack_base;
+
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+ void *p_memory_end = (uint8_t *)(p_pool->p_memory_begin) + (pool_size * p_pool->block_size);
+ if (NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_GET(p_pool->debug_flags))
+ {
+ for (uint32_t * ptr = p_pool->p_memory_begin; ptr < (uint32_t *)(p_memory_end); ptr++)
+ {
+ *ptr = FREE_MEM_FILL;
+ }
+ }
+#endif
+
+ NRF_LOG_INFO("Pool '" POOL_MARKER "' initialized (size: %u x %u = %u bytes)",
+ POOL_ID(p_pool),
+ pool_size,
+ p_pool->block_size,
+ pool_size * p_pool->block_size);
+
+ p_pool->p_cb->p_stack_pointer = p_pool->p_stack_base;
+ while (pool_size--)
+ {
+ *(p_pool->p_cb->p_stack_pointer)++ = pool_size;
+ }
+
+ p_pool->p_cb->max_utilization = 0;
+
+ return NRF_SUCCESS;
+}
+
+void * nrf_balloc_alloc(nrf_balloc_t const * p_pool)
+{
+ ASSERT(p_pool != NULL);
+
+ void * p_block = NULL;
+
+ CRITICAL_REGION_ENTER();
+
+ if (p_pool->p_cb->p_stack_pointer > p_pool->p_stack_base)
+ {
+ // Allocate block.
+ p_block = nrf_balloc_idx2block(p_pool, *--(p_pool->p_cb->p_stack_pointer));
+
+ // Update utilization statistics.
+ uint8_t utilization = p_pool->p_stack_limit - p_pool->p_cb->p_stack_pointer;
+ if (p_pool->p_cb->max_utilization < utilization)
+ {
+ p_pool->p_cb->max_utilization = utilization;
+ }
+ }
+
+ CRITICAL_REGION_EXIT();
+
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+ if (p_block != NULL)
+ {
+ p_block = nrf_balloc_block_unwrap(p_pool, p_block);
+ }
+#endif
+
+ NRF_LOG_DEBUG("nrf_balloc_alloc(pool: '" POOL_MARKER "', element: 0x%08X)",
+ POOL_ID(p_pool), p_block);
+
+ return p_block;
+}
+
+void nrf_balloc_free(nrf_balloc_t const * p_pool, void * p_element)
+{
+ ASSERT(p_pool != NULL);
+ ASSERT(p_element != NULL)
+
+ NRF_LOG_DEBUG("nrf_balloc_free(pool: '" POOL_MARKER "', element: 0x%08X)",
+ POOL_ID(p_pool), p_element);
+
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+ void * p_block = nrf_balloc_element_wrap(p_pool, p_element);
+
+ // These checks could be done outside critical region as they use only pool configuration data.
+ if (NRF_BALLOC_DEBUG_BASIC_CHECKS_GET(p_pool->debug_flags))
+ {
+ uint8_t pool_size = p_pool->p_stack_limit - p_pool->p_stack_base;
+ void *p_memory_end = (uint8_t *)(p_pool->p_memory_begin) + (pool_size * p_pool->block_size);
+
+ // Check if the element belongs to this pool.
+ if ((p_block < p_pool->p_memory_begin) || (p_block >= p_memory_end))
+ {
+ NRF_LOG_ERROR("Attempted to free element that does belong to the pool (pool: '" POOL_MARKER "', element: 0x%08X)",
+ POOL_ID(p_pool), p_element);
+ APP_ERROR_CHECK_BOOL(false);
+ }
+
+ // Check if the pointer is valid.
+ if ((((size_t)(p_block) - (size_t)(p_pool->p_memory_begin)) % p_pool->block_size) != 0)
+ {
+ NRF_LOG_ERROR("Atempted to free corrupted element address (pool: '" POOL_MARKER "', element: 0x%08X)",
+ POOL_ID(p_pool), p_element);
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ }
+#else
+ void * p_block = p_element;
+#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED
+
+ CRITICAL_REGION_ENTER();
+
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+ // These checks have to be done in critical region as they use p_pool->p_stack_pointer.
+ if (NRF_BALLOC_DEBUG_BASIC_CHECKS_GET(p_pool->debug_flags))
+ {
+ // Check for allocated/free ballance.
+ if (p_pool->p_cb->p_stack_pointer >= p_pool->p_stack_limit)
+ {
+ NRF_LOG_ERROR("Attempted to free an element while the pool is full (pool: '" POOL_MARKER "', element: 0x%08X)",
+ POOL_ID(p_pool), p_element);
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ }
+
+ if (NRF_BALLOC_DEBUG_DOUBLE_FREE_CHECK_GET(p_pool->debug_flags))
+ {
+ // Check for double free.
+ for (uint8_t * p_idx = p_pool->p_stack_base; p_idx < p_pool->p_cb->p_stack_pointer; p_idx++)
+ {
+ if (nrf_balloc_idx2block(p_pool, *p_idx) == p_block)
+ {
+ NRF_LOG_ERROR("Attempted to double-free an element (pool: '" POOL_MARKER "', element: 0x%08X)",
+ POOL_ID(p_pool), p_element);
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ }
+ }
+#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED
+
+ // Free the element.
+ *(p_pool->p_cb->p_stack_pointer)++ = nrf_balloc_block2idx(p_pool, p_block);
+
+ CRITICAL_REGION_EXIT();
+}
+
+#endif // NRF_MODULE_ENABLED(NRF_BALLOC)
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/balloc/nrf_balloc.h b/hw/mcu/nordic/nrf52/sdk/libraries/balloc/nrf_balloc.h
new file mode 100644
index 000000000..20c2c35e3
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/balloc/nrf_balloc.h
@@ -0,0 +1,309 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_balloc Block memory allocator
+ * @{
+ * @ingroup app_common
+ * @brief This module handles block memory allocator features.
+ */
+
+
+#ifndef NRF_BALLOC_H__
+#define NRF_BALLOC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "sdk_errors.h"
+#include "sdk_config.h"
+#include "app_util_platform.h"
+#include "app_util.h"
+/**@defgroup NRF_BALLOC_DEBUG Macros for preparing debug flags for block allocator module.
+ * @{ */
+#define NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_SET(words) (((words) & 0xFF) << 0)
+#define NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_GET(flags) (((flags) >> 0) & 0xFF)
+#define NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_SET(words) (((words) & 0xFF) << 8)
+#define NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_GET(flags) (((flags) >> 8) & 0xFF)
+
+#define NRF_BALLOC_DEBUG_BASIC_CHECKS_SET(enable) (!!(enable) << 16)
+#define NRF_BALLOC_DEBUG_BASIC_CHECKS_GET(flags) (flags & (1 << 16))
+#define NRF_BALLOC_DEBUG_DOUBLE_FREE_CHECK_SET(enable) (!!(enable) << 17)
+#define NRF_BALLOC_DEBUG_DOUBLE_FREE_CHECK_GET(flags) (flags & (1 << 17))
+#define NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_SET(enable) (!!(enable) << 18)
+#define NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_GET(flags) (flags & (1 << 18))
+/**@} */
+
+/**@brief Default debug flags for @ref nrf_balloc. This is used by the @ref NRF_BALLOC_DEF macro.
+ * Flags can be changed in @ref sdk_config.
+ */
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+ #define NRF_BALLOC_DEFAULT_DEBUG_FLAGS \
+ ( \
+ NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_SET(NRF_BALLOC_CONFIG_HEAD_GUARD_WORDS) | \
+ NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_SET(NRF_BALLOC_CONFIG_TAIL_GUARD_WORDS) | \
+ NRF_BALLOC_DEBUG_BASIC_CHECKS_SET(NRF_BALLOC_CONFIG_BASIC_CHECKS_ENABLED) | \
+ NRF_BALLOC_DEBUG_DOUBLE_FREE_CHECK_SET(NRF_BALLOC_CONFIG_DOUBLE_FREE_CHECK_ENABLED) | \
+ NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_SET(NRF_BALLOC_CONFIG_DATA_TRASHING_CHECK_ENABLED) \
+ )
+#else
+ #define NRF_BALLOC_DEFAULT_DEBUG_FLAGS 0
+#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED
+
+/**@brief Block memory allocator control block.*/
+typedef struct
+{
+ uint8_t * p_stack_pointer; //!< Current allocation stack pointer.
+ uint8_t max_utilization; //!< Maximum utilization of the memory pool.
+} nrf_balloc_cb_t;
+
+/**@brief Block memory allocator pool instance. The pool is made of elements of the same size. */
+typedef struct
+{
+ nrf_balloc_cb_t * p_cb; //!< Pointer to the instance control block.
+ uint8_t * p_stack_base; //!< Base of the allocation stack.
+ /**<
+ * Stack is used to store handlers to not allocated elements.
+ */
+ uint8_t * p_stack_limit; //!< Maximum possible value of the allocation stack pointer.
+ void * p_memory_begin; //!< Pointer to the start of the memory pool.
+ /**<
+ * Memory is used as a heap for blocks.
+ */
+
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+ const char * p_name; //!< Pointer to string with pool name.
+ uint32_t debug_flags; //!< Debugging settings.
+ /**<
+ * Debug flag should be created by @ref NRF_BALLOC_DEBUG.
+ */
+#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED
+ uint16_t block_size; //!< Size of the allocated block (including debug overhead).
+ /**<
+ * Single block contains user element with header and tail
+ * words.
+ */
+} nrf_balloc_t;
+
+/**@brief Get total memory consumed by single block (element size with overhead caused by debug
+ * flags).
+ *
+ * @param[in] _element_size Size of an element.
+ * @param[in] _debug_flags Debug flags.
+ */
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+ #define NRF_BALLOC_BLOCK_SIZE(_element_size, _debug_flags) \
+ ( \
+ (sizeof(uint32_t) * NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_GET(_debug_flags)) + \
+ ALIGN_NUM(sizeof(uint32_t), (_element_size)) + \
+ (sizeof(uint32_t) * NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_GET(_debug_flags)) \
+ )
+#else
+ #define NRF_BALLOC_BLOCK_SIZE(_element_size, _debug_flags) \
+ ALIGN_NUM(sizeof(uint32_t), (_element_size))
+#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED
+
+
+/**@brief Get element size ( excluding debugging overhead is present)
+ * flags).
+ *
+ * @param[in] _p_balloc Pointer to balloc instance.
+ */
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+#define NRF_BALLOC_ELEMENT_SIZE(_p_balloc) \
+ (ALIGN_NUM(sizeof(uint32_t), (_p_balloc)->block_size) - \
+ ((sizeof(uint32_t) * NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_GET((_p_balloc)->debug_flags)) + \
+ (sizeof(uint32_t) * NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_GET((_p_balloc)->debug_flags))))
+#else
+#define NRF_BALLOC_ELEMENT_SIZE(_p_balloc) \
+ (_p_balloc)->block_size
+#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED
+
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+#define __NRF_BALLOC_ASSIGN_POOL_NAME(_name) .p_name = STRINGIFY(_name),
+#define __NRF_BALLOC_ASSIGN_DEBUG_FLAGS(_debug_flags) .debug_flags = (_debug_flags),
+#else
+#define __NRF_BALLOC_ASSIGN_DEBUG_FLAGS(_debug_flags)
+#define __NRF_BALLOC_ASSIGN_POOL_NAME(_name)
+#endif
+
+
+/**@brief Create a block allocator instance with custom debug flags.
+ *
+ * @note This macro reserves memory for the given block allocator instance.
+ *
+ * @param[in] _name Name of the allocator.
+ * @param[in] _element_size Size of one element.
+ * @param[in] _pool_size Size of the pool.
+ * @param[in] _debug_flags Debug flags (@ref NRF_BALLOC_DEBUG).
+ */
+#define NRF_BALLOC_DBG_DEF(_name, _element_size, _pool_size, _debug_flags) \
+ STATIC_ASSERT((_pool_size) <= UINT8_MAX); \
+ static uint8_t CONCAT_2(_name, _nrf_balloc_pool_stack)[(_pool_size)]; \
+ static uint32_t CONCAT_2(_name,_nrf_balloc_pool_mem) \
+ [NRF_BALLOC_BLOCK_SIZE(_element_size, _debug_flags) * (_pool_size) / sizeof(uint32_t)]; \
+ static nrf_balloc_cb_t CONCAT_2(_name,_nrf_balloc_cb); \
+ static const nrf_balloc_t _name = \
+ { \
+ .p_cb = &CONCAT_2(_name,_nrf_balloc_cb), \
+ .p_stack_base = CONCAT_2(_name,_nrf_balloc_pool_stack), \
+ .p_stack_limit = CONCAT_2(_name,_nrf_balloc_pool_stack) + (_pool_size), \
+ .p_memory_begin = CONCAT_2(_name,_nrf_balloc_pool_mem), \
+ .block_size = NRF_BALLOC_BLOCK_SIZE(_element_size, _debug_flags), \
+ \
+ __NRF_BALLOC_ASSIGN_POOL_NAME(_name) \
+ __NRF_BALLOC_ASSIGN_DEBUG_FLAGS(_debug_flags) \
+ }
+
+/**@brief Create a block allocator instance.
+ *
+ * @note This macro reserves memory for the given block allocator instance.
+ *
+ * @param[in] _name Name of the allocator.
+ * @param[in] _element_size Size of one element.
+ * @param[in] _pool_size Size of the pool.
+ */
+#define NRF_BALLOC_DEF(_name, _element_size, _pool_size) \
+ NRF_BALLOC_DBG_DEF(_name, _element_size, _pool_size, NRF_BALLOC_DEFAULT_DEBUG_FLAGS)
+
+/**@brief Create a block allocator interface.
+ *
+ * @param[in] _type Type which is allocated.
+ * @param[in] _name Name of the allocator.
+ */
+#define NRF_BALLOC_INTERFACE_DEC(_type, _name) \
+ _type * CONCAT_2(_name,_alloc)(void); \
+ void CONCAT_2(_name,_free)(_type * p_element)
+
+/**@brief Define a custom block allocator interface.
+ *
+ * @param[in] _attr Function attribute that will be added to allocator function definition.
+ * @param[in] _type Type which is allocated.
+ * @param[in] _name Name of the allocator.
+ * @param[in] _p_pool Pool from which data will be allocated.
+ */
+#define NRF_BALLOC_INTERFACE_CUSTOM_DEF(_attr, _type, _name, _p_pool) \
+ _attr _type * CONCAT_2(_name,_alloc)(void) \
+ { \
+ GCC_PRAGMA("GCC diagnostic push") \
+ GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
+ ASSERT((_p_pool) != NULL); \
+ ASSERT((_p_pool)->block_size >= \
+ NRF_BALLOC_BLOCK_SIZE(sizeof(_type), (_p_pool)->debug_flags)); \
+ GCC_PRAGMA("GCC diagnostic pop") \
+ return (_type *)(nrf_balloc_alloc(_p_pool)); \
+ } \
+ \
+ _attr void CONCAT_2(_name,_free)(_type * p_element) \
+ { \
+ GCC_PRAGMA("GCC diagnostic push") \
+ GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
+ ASSERT((_p_pool) != NULL); \
+ ASSERT((_p_pool)->block_size >= \
+ NRF_BALLOC_BLOCK_SIZE(sizeof(_type), (_p_pool)->debug_flags)); \
+ GCC_PRAGMA("GCC diagnostic pop") \
+ nrf_balloc_free((_p_pool), p_element); \
+ }
+
+/**@brief Define block allocator interface.
+ *
+ * @param[in] _type Type which is allocated.
+ * @param[in] _name Name of the allocator.
+ * @param[in] _p_pool Pool from which data will be allocated.
+ */
+#define NRF_BALLOC_INTERFACE_DEF(_type, _name, _p_pool) \
+ NRF_BALLOC_INTERFACE_CUSTOM_DEF(/* empty */, _type, _name, _p_pool)
+
+/**@brief Define a local block allocator interface.
+ *
+ * @param[in] _type Type which is allocated.
+ * @param[in] _name Name of the allocator.
+ * @param[in] _p_pool Pool from which data will be allocated.
+ */
+#define NRF_BALLOC_INTERFACE_LOCAL_DEF(_type, _name, _p_pool) \
+ NRF_BALLOC_INTERFACE_CUSTOM_DEF(static, _type, _name, _p_pool)
+
+/**@brief Function for initializing a block memory allocator pool.
+ *
+ * @param[out] p_pool Pointer to the pool that is to be initialized.
+ *
+ * @return NRF_SUCCESS on success, otherwise error code.
+ */
+ret_code_t nrf_balloc_init(nrf_balloc_t const * p_pool);
+
+/**@brief Function for allocating an element from the pool.
+ *
+ * @note This module guarantees that the returned memory is aligned to 4.
+ *
+ * @param[in] p_pool Pointer to the memory pool from which the element will be allocated.
+ *
+ * @return Allocated element or NULL if the specified pool is empty.
+ */
+void * nrf_balloc_alloc(nrf_balloc_t const * p_pool);
+
+/**@brief Function for freeing an element back to the pool.
+ *
+ * @param[in] p_pool Pointer to the memory pool.
+ * @param[in] p_element Element to be freed.
+ */
+void nrf_balloc_free(nrf_balloc_t const * p_pool, void * p_element);
+
+/**@brief Function for getting maximum memory pool utilization.
+ *
+ * @param[in] p_pool Pointer to the memory pool instance.
+ *
+ * @return Maximum number of elements allocated from the pool.
+ */
+__STATIC_INLINE uint8_t nrf_balloc_max_utilization_get(nrf_balloc_t const * p_pool);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+__STATIC_INLINE uint8_t nrf_balloc_max_utilization_get(nrf_balloc_t const * p_pool)
+{
+ ASSERT(p_pool != NULL);
+ return p_pool->p_cb->max_utilization;
+}
+#endif //SUPPRESS_INLINE_IMPLEMENTATION
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_BALLOC_H__
+/** @} */
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/nrf_log.h b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/nrf_log.h
new file mode 100644
index 000000000..967bc1a28
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/nrf_log.h
@@ -0,0 +1,234 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_log Logger module
+ * @{
+ * @ingroup app_common
+ *
+ * @brief The nrf_log module interface.
+ */
+
+#ifndef NRF_LOG_H_
+#define NRF_LOG_H_
+
+#include "sdk_common.h"
+#include "nrf_section.h"
+#if NRF_MODULE_ENABLED(NRF_LOG)
+#include "nrf_strerror.h"
+#define NRF_LOG_ERROR_STRING_GET(code) nrf_strerror_get(code)
+#else
+#define NRF_LOG_ERROR_STRING_GET(code) ""
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief Severity level for the module.
+ *
+ * The severity level can be defined in a module to override the default.
+ */
+#ifndef NRF_LOG_LEVEL
+ #define NRF_LOG_LEVEL NRF_LOG_DEFAULT_LEVEL
+#endif
+
+
+#include "nrf_log_internal.h"
+
+/** @def NRF_LOG_ERROR
+ * @brief Macro for logging error messages. It takes a printf-like, formatted
+ * string with up to seven arguments.
+ *
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
+ */
+
+/** @def NRF_LOG_WARNING
+ * @brief Macro for logging error messages. It takes a printf-like, formatted
+ * string with up to seven arguments.
+ *
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes warning logs.
+ */
+
+/** @def NRF_LOG_INFO
+ * @brief Macro for logging error messages. It takes a printf-like, formatted
+ * string with up to seven arguments.
+ *
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes info logs.
+ */
+
+/** @def NRF_LOG_DEBUG
+ * @brief Macro for logging error messages. It takes a printf-like, formatted
+ * string with up to seven arguments.
+ *
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes debug logs.
+ */
+
+#define NRF_LOG_ERROR(...) NRF_LOG_INTERNAL_ERROR(__VA_ARGS__)
+#define NRF_LOG_WARNING(...) NRF_LOG_INTERNAL_WARNING( __VA_ARGS__)
+#define NRF_LOG_INFO(...) NRF_LOG_INTERNAL_INFO( __VA_ARGS__)
+#define NRF_LOG_DEBUG(...) NRF_LOG_INTERNAL_DEBUG( __VA_ARGS__)
+
+/**
+ * @brief A macro for logging a formatted string without any prefix or timestamp.
+ */
+#define NRF_LOG_RAW_INFO(...) NRF_LOG_INTERNAL_RAW_INFO( __VA_ARGS__)
+
+/** @def NRF_LOG_HEXDUMP_ERROR
+ * @brief Macro for logging raw bytes.
+ * @details It is compiled in only if @ref NRF_LOG_LEVEL includes error logs.
+ *
+ * @param p_data Pointer to data.
+ * @param len Data length in bytes.
+ */
+/** @def NRF_LOG_HEXDUMP_WARNING
+ * @brief Macro for logging raw bytes.
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes warning logs.
+ *
+ * @param p_data Pointer to data.
+ * @param len Data length in bytes.
+ */
+/** @def NRF_LOG_HEXDUMP_INFO
+ * @brief Macro for logging raw bytes.
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes info logs.
+ *
+ * @param p_data Pointer to data.
+ * @param len Data length in bytes.
+ */
+/** @def NRF_LOG_HEXDUMP_DEBUG
+ * @brief Macro for logging raw bytes.
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes debug logs.
+ *
+ * @param p_data Pointer to data.
+ * @param len Data length in bytes.
+ */
+#define NRF_LOG_HEXDUMP_ERROR(p_data, len) NRF_LOG_INTERNAL_HEXDUMP_ERROR(p_data, len)
+#define NRF_LOG_HEXDUMP_WARNING(p_data, len) NRF_LOG_INTERNAL_HEXDUMP_WARNING(p_data, len)
+#define NRF_LOG_HEXDUMP_INFO(p_data, len) NRF_LOG_INTERNAL_HEXDUMP_INFO(p_data, len)
+#define NRF_LOG_HEXDUMP_DEBUG(p_data, len) NRF_LOG_INTERNAL_HEXDUMP_DEBUG(p_data, len)
+
+/**
+ * @brief Macro for logging hexdump without any prefix or timestamp.
+ */
+#define NRF_LOG_RAW_HEXDUMP_INFO(p_data, len) NRF_LOG_INTERNAL_RAW_HEXDUMP_INFO(p_data, len)
+
+/**
+ * @brief A macro for blocking reading from bidirectional backend used for logging.
+ *
+ * Macro call is blocking and returns when single byte is received.
+ */
+#define NRF_LOG_GETCHAR() NRF_LOG_INTERNAL_GETCHAR()
+
+/**
+ * @brief A macro for copying a string to internal logger buffer if logs are deferred.
+ *
+ * @param _str String.
+ */
+#define NRF_LOG_PUSH(_str) NRF_LOG_INTERNAL_LOG_PUSH(_str)
+
+/**
+ * @brief Function for copying a string to the internal logger buffer if logs are deferred.
+ *
+ * Use this function to store a string that is volatile (for example allocated
+ * on stack) or that may change before the deferred logs are processed. Such string is copied
+ * into the internal logger buffer and is persistent until the log is processed.
+ *
+ * @note If the logs are not deferred, then this function returns the input parameter.
+ *
+ * @param p_str Pointer to the user string.
+ *
+ * @return Address to the location where the string is stored in the internal logger buffer.
+ */
+uint32_t nrf_log_push(char * const p_str);
+
+/**
+ * @brief Macro to be used in a formatted string to a pass float number to the log.
+ *
+ * Macro should be used in formatted string instead of the %f specifier together with
+ * @ref NRF_LOG_FLOAT macro.
+ * Example: NRF_LOG_INFO("My float number" NRF_LOG_FLOAT_MARKER "\r\n", NRF_LOG_FLOAT(f)))
+ */
+#define NRF_LOG_FLOAT_MARKER "%s%d.%02d"
+
+/**
+ * @brief Macro for dissecting a float number into two numbers (integer and residuum).
+ */
+#define NRF_LOG_FLOAT(val) (uint32_t)(((val) < 0 && (val) > -1.0) ? "-" : ""), \
+ (int32_t)(val), \
+ (int32_t)((((val) > 0) ? (val) - (int32_t)(val) \
+ : (int32_t)(val) - (val))*100)
+
+
+
+/**
+ * @def NRF_LOG_MODULE_REGISTER
+ * @brief Macro for registering an independent module.
+ */
+#if NRF_LOG_ENABLED
+
+#ifdef UNIT_TEST
+#define _CONST
+#define COMPILED_LOG_LEVEL 4
+#else
+#define _CONST const
+#define COMPILED_LOG_LEVEL NRF_LOG_LEVEL
+#endif
+#define NRF_LOG_MODULE_REGISTER() \
+ NRF_SECTION_ITEM_REGISTER(NRF_LOG_CONST_SECTION_NAME(NRF_LOG_MODULE_NAME), \
+ _CONST nrf_log_module_const_data_t NRF_LOG_MODULE_DATA_CONST) = { \
+ .p_module_name = STRINGIFY(NRF_LOG_MODULE_NAME), \
+ .info_color_id = NRF_LOG_INFO_COLOR, \
+ .debug_color_id = NRF_LOG_DEBUG_COLOR, \
+ .compiled_lvl = COMPILED_LOG_LEVEL, \
+ }; \
+ NRF_SECTION_ITEM_REGISTER(NRF_LOG_DYNAMIC_SECTION_NAME(NRF_LOG_MODULE_NAME), \
+ nrf_log_module_dynamic_data_t NRF_LOG_MODULE_DATA_DYNAMIC)
+#else
+#define NRF_LOG_MODULE_REGISTER() /*lint -save -e19*/ /*lint -restore*/
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_LOG_H_
+
+/** @} */
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/nrf_log_backend_interface.h b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/nrf_log_backend_interface.h
new file mode 100644
index 000000000..e5b965f44
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/nrf_log_backend_interface.h
@@ -0,0 +1,218 @@
+/**
+ * Copyright (c) 2017 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_LOG_BACKEND_INTERFACE_H
+#define NRF_LOG_BACKEND_INTERFACE_H
+
+/**@file
+ * @addtogroup nrf_log Logger module
+ * @ingroup app_common
+ *
+ * @defgroup nrf_log_backend_interface Logger backend interface
+ * @{
+ * @ingroup nrf_log
+ * @brief The nrf_log backend interface.
+ */
+
+#include "nrf_memobj.h"
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief nrf_log entry.
+ */
+typedef nrf_memobj_t nrf_log_entry_t;
+
+/* Forward declaration of the nrf_log_backend_t type. */
+typedef struct nrf_log_backend_s nrf_log_backend_t;
+
+/**
+ * @brief Logger backend API.
+ */
+typedef struct
+{
+ /**
+ * @brief @ref nrf_log_backend_put
+ */
+ void (*put)(nrf_log_backend_t const * p_backend, nrf_log_entry_t * p_entry);
+
+ /**
+ * @brief @ref nrf_log_backend_panic_set
+ */
+ void (*panic_set)(nrf_log_backend_t const * p_backend);
+
+ /**
+ * @brief @ref nrf_log_backend_flush
+ */
+ void (*flush)(nrf_log_backend_t const * p_backend);
+} nrf_log_backend_api_t;
+
+/**
+ * @brief Logger backend structure.
+ */
+struct nrf_log_backend_s
+{
+ nrf_log_backend_api_t const * p_api; //!< Pointer to interface.
+ nrf_log_backend_t * p_next; //!< Pointer to next backend added to the logger.
+ uint8_t id; //!< Backend id.
+ bool enabled;//!< Flag indicating backend status.
+};
+
+/**
+ * @brief Function for putting message with log entry to the backend.
+ *
+ * @param[in] p_backend Pointer to the backend instance.
+ * @param[in] p_msg Pointer to message with log entry.
+ */
+__STATIC_INLINE void nrf_log_backend_put(nrf_log_backend_t const * p_backend,
+ nrf_log_entry_t * p_msg);
+
+/**
+ * @brief Function for reconfiguring backend to panic mode.
+ *
+ * @param[in] p_backend Pointer to the backend instance.
+ */
+__STATIC_INLINE void nrf_log_backend_panic_set(nrf_log_backend_t const * p_backend);
+
+/**
+ * @brief Function for flushing backend.
+ *
+ * @param[in] p_backend Pointer to the backend instance.
+ */
+__STATIC_INLINE void nrf_log_backend_flush(nrf_log_backend_t const * p_backend);
+
+
+/**
+ * @brief Function for setting backend id.
+ *
+ * @note It is used internally by the logger.
+ *
+ * @param[in] p_backend Pointer to the backend instance.
+ * @param[in] id Id.
+ */
+__STATIC_INLINE void nrf_log_backend_id_set(nrf_log_backend_t * p_backend, uint8_t id);
+
+/**
+ * @brief Function for getting backend id.
+ *
+ * @note It is used internally by the logger.
+ *
+ * @param[in] p_backend Pointer to the backend instance.
+ * @return Id.
+ */
+__STATIC_INLINE uint8_t nrf_log_backend_id_get(nrf_log_backend_t const * p_backend);
+
+/**
+ * @brief Function for enabling backend.
+ *
+ * @param[in] p_backend Pointer to the backend instance.
+ */
+__STATIC_INLINE void nrf_log_backend_enable(nrf_log_backend_t * p_backend);
+
+/**
+ * @brief Function for disabling backend.
+ *
+ * @param[in] p_backend Pointer to the backend instance.
+ */
+__STATIC_INLINE void nrf_log_backend_disable(nrf_log_backend_t * p_backend);
+
+/**
+ * @brief Function for checking state of the backend.
+ *
+ * @param[in] p_backend Pointer to the backend instance.
+ *
+ * @return True if backend is enabled, false otherwise.
+ */
+__STATIC_INLINE bool nrf_log_backend_is_enabled(nrf_log_backend_t const * p_backend);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+__STATIC_INLINE void nrf_log_backend_put(nrf_log_backend_t const * p_backend,
+ nrf_log_entry_t * p_msg)
+{
+ p_backend->p_api->put(p_backend, p_msg);
+}
+
+__STATIC_INLINE void nrf_log_backend_panic_set(nrf_log_backend_t const * p_backend)
+{
+ p_backend->p_api->panic_set(p_backend);
+}
+
+__STATIC_INLINE void nrf_log_backend_flush(nrf_log_backend_t const * p_backend)
+{
+ p_backend->p_api->panic_set(p_backend);
+}
+
+__STATIC_INLINE void nrf_log_backend_id_set(nrf_log_backend_t * p_backend, uint8_t id)
+{
+ p_backend->id = id;
+}
+
+__STATIC_INLINE uint8_t nrf_log_backend_id_get(nrf_log_backend_t const * p_backend)
+{
+ return p_backend->id;
+}
+
+__STATIC_INLINE void nrf_log_backend_enable(nrf_log_backend_t * p_backend)
+{
+ p_backend->enabled = true;
+}
+
+__STATIC_INLINE void nrf_log_backend_disable(nrf_log_backend_t * p_backend)
+{
+ p_backend->enabled = false;
+}
+
+__STATIC_INLINE bool nrf_log_backend_is_enabled(nrf_log_backend_t const * p_backend)
+{
+ return p_backend->enabled;
+}
+
+#endif // SUPPRESS_INLINE_IMPLEMENTATION
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //NRF_LOG_BACKEND_INTERFACE_H
+
+/** @} */
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/nrf_log_backend_rtt.h b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/nrf_log_backend_rtt.h
new file mode 100644
index 000000000..66eeeb654
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/nrf_log_backend_rtt.h
@@ -0,0 +1,73 @@
+/**
+ * Copyright (c) 2017 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_log_backend_rtt Log RTT backend
+ * @{
+ * @ingroup nrf_log
+ * @brief Log RTT backend.
+ */
+
+#ifndef NRF_LOG_BACKEND_RTT_H
+#define NRF_LOG_BACKEND_RTT_H
+
+#include "nrf_log_backend_interface.h"
+
+extern const nrf_log_backend_api_t nrf_log_backend_rtt_api;
+
+typedef struct {
+ nrf_log_backend_t backend;
+} nrf_log_backend_rtt_t;
+
+/**
+ * @brief RTT backend definition
+ *
+ * @param _name Name of the instance.
+ */
+#define NRF_LOG_BACKEND_RTT_DEF(_name) \
+ static nrf_log_backend_rtt_t _name = { \
+ .backend = {.p_api = &nrf_log_backend_rtt_api}, \
+ }
+
+void nrf_log_backend_rtt_init(void);
+#endif //NRF_LOG_BACKEND_RTT_H
+
+/** @} */
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/nrf_log_backend_uart.h b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/nrf_log_backend_uart.h
new file mode 100644
index 000000000..4f9ce1290
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/nrf_log_backend_uart.h
@@ -0,0 +1,68 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_log_backend_uart Log UART backend
+ * @{
+ * @ingroup nrf_log
+ * @brief Log UART backend.
+ */
+
+#ifndef NRF_LOG_BACKEND_UART_H
+#define NRF_LOG_BACKEND_UART_H
+
+#include "nrf_log_backend_interface.h"
+
+extern const nrf_log_backend_api_t nrf_log_backend_uart_api;
+
+typedef struct {
+ nrf_log_backend_t backend;
+} nrf_log_backend_uart_t;
+
+#define NRF_LOG_BACKEND_UART_DEF(name) \
+ static nrf_log_backend_uart_t name = { \
+ .backend = {.p_api = &nrf_log_backend_uart_api}, \
+ }
+
+void nrf_log_backend_uart_init(void);
+#endif //NRF_LOG_BACKEND_UART_H
+
+/** @} */
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/nrf_log_ctrl.h b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/nrf_log_ctrl.h
new file mode 100644
index 000000000..0fbce415f
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/nrf_log_ctrl.h
@@ -0,0 +1,233 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_LOG_CTRL_H
+#define NRF_LOG_CTRL_H
+
+/**@file
+ * @addtogroup nrf_log Logger module
+ * @ingroup app_common
+ *
+ * @defgroup nrf_log_ctrl Functions for controlling nrf_log
+ * @{
+ * @ingroup nrf_log
+ * @brief The nrf_log control interface.
+ */
+
+#include "sdk_config.h"
+#include "sdk_errors.h"
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf_log_ctrl_internal.h"
+#include "nrf_log_backend_interface.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum
+{
+ NRF_LOG_SEVERITY_NONE,
+ NRF_LOG_SEVERITY_ERROR,
+ NRF_LOG_SEVERITY_WARNING,
+ NRF_LOG_SEVERITY_INFO,
+ NRF_LOG_SEVERITY_DEBUG,
+} nrf_log_severity_t;
+
+/**
+ * @brief Timestamp function prototype.
+ *
+ * @return Timestamp value.
+ */
+typedef uint32_t (*nrf_log_timestamp_func_t)(void);
+
+/**@brief Macro for initializing the logs.
+ *
+ * @note If timestamps are disabled in the configuration, then the provided pointer
+ * can be NULL. Otherwise, it is expected that timestamp_getter is not NULL.
+ *
+ * @param timestamp_func Function that returns the timestamp.
+ *
+ * @return NRF_SUCCESS after successful initialization, otherwise an error code.
+ */
+#define NRF_LOG_INIT(timestamp_func) NRF_LOG_INTERNAL_INIT(timestamp_func)
+
+
+/**@brief Macro for processing a single log entry from a queue of deferred logs.
+ *
+ * You can call this macro from the main context or from the error handler to process
+ * log entries one by one.
+ *
+ * @note If logs are not deferred, this call has no use and is defined as 'false'.
+ *
+ * @retval true There are more logs to process in the buffer.
+ * @retval false No more logs in the buffer.
+ */
+#define NRF_LOG_PROCESS() NRF_LOG_INTERNAL_PROCESS()
+
+/** @brief Macro for processing all log entries from the buffer.
+ * It blocks until all buffered entries are processed by the backend.
+ *
+ * @note If logs are not deferred, this call has no use and is empty.
+ */
+#define NRF_LOG_FLUSH() NRF_LOG_INTERNAL_FLUSH()
+
+/** @brief Macro for flushing log data before reset.
+ *
+ * @note If logs are not deferred, this call has no use and is empty.
+ *
+ * @note If RTT is used, then a breakpoint is hit once flushed.
+ */
+#define NRF_LOG_FINAL_FLUSH() NRF_LOG_INTERNAL_FINAL_FLUSH()
+
+/**
+ * @brief Function for initializing the frontend and the default backend.
+ *
+ * @ref NRF_LOG_INIT calls this function to initialize the frontend and the backend.
+ * If custom backend is used, then @ref NRF_LOG_INIT should not be called.
+ * Instead, frontend and user backend should be verbosely initialized.
+ *
+ * @param timestamp_func Function for getting a 32-bit timestamp.
+ *
+ * @return Error status.
+ *
+ */
+ret_code_t nrf_log_init(nrf_log_timestamp_func_t timestamp_func);
+
+/**
+ * @brief Function for adding new backend interface to the logger.
+ *
+ * @param p_backend Pointer to the backend interface.
+ * @param severity Initial value of severity level for each module forwarded to the backend. This
+ * option is only applicable if @ref NRF_LOG_FILTERS_ENABLED is set.
+ * @return -1 if backend cannot be added or positive number (backend ID).
+ */
+int32_t nrf_log_backend_add(nrf_log_backend_t * p_backend, nrf_log_severity_t severity);
+
+/**
+ * @brief Function for removing backend from the logger.
+ *
+ * @param p_backend Pointer to the backend interface.
+ *
+ */
+void nrf_log_backend_remove(nrf_log_backend_t * p_backend);
+
+/**
+ * @brief Function for setting logger backends into panic mode.
+ *
+ * When this function is called all attached backends are informed about panic state of the system.
+ * It is up to the backend to react properly (hold or process logs in blocking mode, etc.)
+ */
+void nrf_log_panic(void);
+
+/**
+ * @brief Function for handling a single log entry.
+ *
+ * Use this function only if the logs are buffered. It takes a single entry from the
+ * buffer and attempts to process it.
+ *
+ * @retval true If there are more entries to process.
+ * @retval false If there are no more entries to process.
+ */
+bool nrf_log_frontend_dequeue(void);
+
+/**
+ * @brief Function for getting number of independent log modules registered into the logger.
+ *
+ * @return Number of registered modules.
+ */
+uint32_t nrf_log_module_cnt_get(void);
+
+/**
+ * @brief Function for getting module name.
+ *
+ * @param module_id Module ID.
+ * @param is_ordered_idx Module ID is given is index in alphabetically sorted list of modules.
+ * @return Pointer to string with module name.
+ */
+const char * nrf_log_module_name_get(uint32_t module_id, bool is_ordered_idx);
+
+/**
+ * @brief Function for getting coloring of specific logs.
+ *
+ * @param module_id Module ID.
+ * @param severity Log severity.
+ *
+ * @return ID of the color.
+ */
+uint8_t nrf_log_color_id_get(uint32_t module_id, nrf_log_severity_t severity);
+
+/**
+ * @brief Function for configuring filtering ofs logs in the module.
+ *
+ * Filtering of logs in modules is independent for each backend.
+ *
+ * @param backend_id Backend ID which want to chenge its configuration.
+ * @param module_id Module ID which logs will be reconfigured.
+ * @param severity New severity filter.
+ */
+void nrf_log_module_filter_set(uint32_t backend_id,
+ uint32_t module_id,
+ nrf_log_severity_t severity);
+
+/**
+ * @brief Function for getting module severity level.
+ *
+ * @param backend_id Backend ID.
+ * @param module_id Module ID.
+ * @param is_ordered_idx Module ID is given is index in alphabetically sorted list of modules.
+ * @param dynamic It true current filter for given backend is returned. If false then
+ * compiled-in level is returned (maximum available). If this parameter is
+ * false then backend_id parameter is not used.
+ *
+ * @return Severity.
+ */
+nrf_log_severity_t nrf_log_module_filter_get(uint32_t backend_id,
+ uint32_t module_id,
+ bool is_ordered_idx,
+ bool dynamic);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_LOG_CTRL_H
+
+/**
+ *@}
+ **/
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/nrf_log_default_backends.h b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/nrf_log_default_backends.h
new file mode 100644
index 000000000..982f3b1b5
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/nrf_log_default_backends.h
@@ -0,0 +1,81 @@
+/**
+ * Copyright (c) 2017 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_LOG_DEFAULT_BACKENDS_H__
+#define NRF_LOG_DEFAULT_BACKENDS_H__
+
+/**@file
+ * @addtogroup nrf_log Logger module
+ * @ingroup app_common
+ *
+ * @defgroup nrf_log_default_backends Functions for initializing and adding default backends
+ * @{
+ * @ingroup nrf_log
+ * @brief The nrf_log default backends.
+ */
+
+#include "sdk_config.h"
+#include "sdk_errors.h"
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @def NRF_LOG_DEFAULT_BACKENDS_INIT
+ * @brief Macro for initializing default backends.
+ *
+ * Each backend enabled in configuration is initialized and added as a backend to the logger.
+ */
+#if NRF_LOG_ENABLED
+#define NRF_LOG_DEFAULT_BACKENDS_INIT() nrf_log_default_backends_init()
+#else
+#define NRF_LOG_DEFAULT_BACKENDS_INIT()
+#endif
+
+void nrf_log_default_backends_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+
+#endif // NRF_LOG_DEFAULT_BACKENDS_H__
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/nrf_log_str_formatter.h b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/nrf_log_str_formatter.h
new file mode 100644
index 000000000..134812d4c
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/nrf_log_str_formatter.h
@@ -0,0 +1,67 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_LOG_STR_FORMATTER_H
+#define NRF_LOG_STR_FORMATTER_H
+
+#include <stdint.h>
+#include "nrf_fprintf.h"
+#include "nrf_log_ctrl.h"
+
+typedef struct
+{
+ uint32_t timestamp;
+ uint16_t module_id;
+ nrf_log_severity_t severity;
+ bool raw;
+ uint8_t use_colors;
+} nrf_log_str_formatter_entry_params_t;
+
+void nrf_log_std_entry_process(char const * p_str,
+ uint32_t const * p_args,
+ uint32_t nargs,
+ nrf_log_str_formatter_entry_params_t * p_params,
+ nrf_fprintf_ctx_t * p_ctx);
+
+void nrf_log_hexdump_entry_process(uint8_t * p_data,
+ uint32_t data_len,
+ nrf_log_str_formatter_entry_params_t * p_params,
+ nrf_fprintf_ctx_t * p_ctx);
+
+#endif //NRF_LOG_STR_FORMATTER_H
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_backend_rtt.c b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_backend_rtt.c
new file mode 100644
index 000000000..03c32ca67
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_backend_rtt.c
@@ -0,0 +1,101 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_LOG) && NRF_MODULE_ENABLED(NRF_LOG_BACKEND_RTT)
+#include "nrf_log_backend_rtt.h"
+#include "nrf_log_backend_serial.h"
+#include "nrf_log_str_formatter.h"
+#include "nrf_log_internal.h"
+#include <SEGGER_RTT_Conf.h>
+#include <SEGGER_RTT.h>
+
+static uint8_t m_string_buff[NRF_LOG_BACKEND_RTT_TEMP_BUFFER_SIZE];
+
+void nrf_log_backend_rtt_init(void)
+{
+ SEGGER_RTT_Init();
+}
+
+static void serial_tx(void const * p_context, char const * buffer, size_t len)
+{
+ if (len)
+ {
+ uint32_t idx = 0;
+ uint32_t processed;
+ uint32_t watchdog_counter = 10;
+ do
+ {
+ processed = SEGGER_RTT_WriteNoLock(0, &buffer[idx], len);
+ idx += processed;
+ len -= processed;
+ if (processed == 0)
+ {
+ // If RTT is not connected then ensure that logger does not block
+ watchdog_counter--;
+ if (watchdog_counter == 0)
+ {
+ break;
+ }
+ }
+ } while (len);
+ }
+}
+static void nrf_log_backend_rtt_put(nrf_log_backend_t const * p_backend,
+ nrf_log_entry_t * p_msg)
+{
+ nrf_log_backend_serial_put(p_backend, p_msg, m_string_buff, NRF_LOG_BACKEND_RTT_TEMP_BUFFER_SIZE, serial_tx);
+}
+
+static void nrf_log_backend_rtt_flush(nrf_log_backend_t const * p_backend)
+{
+
+}
+
+static void nrf_log_backend_rtt_panic_set(nrf_log_backend_t const * p_backend)
+{
+
+}
+
+const nrf_log_backend_api_t nrf_log_backend_rtt_api = {
+ .put = nrf_log_backend_rtt_put,
+ .flush = nrf_log_backend_rtt_flush,
+ .panic_set = nrf_log_backend_rtt_panic_set,
+};
+#endif //NRF_MODULE_ENABLED(NRF_LOG) && NRF_MODULE_ENABLED(NRF_LOG_BACKEND_RTT)
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_backend_serial.c b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_backend_serial.c
new file mode 100644
index 000000000..194b9a7b5
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_backend_serial.c
@@ -0,0 +1,116 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_LOG)
+#include "nrf_log_backend_serial.h"
+#include "nrf_log_str_formatter.h"
+#include "nrf_log_internal.h"
+
+void nrf_log_backend_serial_put(nrf_log_backend_t const * p_backend,
+ nrf_log_entry_t * p_msg,
+ uint8_t * p_buffer,
+ uint32_t length,
+ nrf_fprintf_fwrite tx_func)
+{
+ nrf_memobj_get(p_msg);
+
+ nrf_fprintf_ctx_t fprintf_ctx = {
+ .p_io_buffer = (char *)p_buffer,
+ .io_buffer_size = length,
+ .io_buffer_cnt = 0,
+ .auto_flush = false,
+ .p_user_ctx = NULL,
+ .fwrite = tx_func
+ };
+
+ nrf_log_str_formatter_entry_params_t params;
+
+ nrf_log_header_t header;
+ uint32_t memobj_offset = 0;
+ nrf_memobj_read(p_msg, &header, HEADER_SIZE*sizeof(uint32_t), memobj_offset);
+ memobj_offset = HEADER_SIZE*sizeof(uint32_t);
+
+ params.timestamp = header.timestamp;
+ params.module_id = header.module_id;
+ params.use_colors = NRF_LOG_USES_COLORS;
+
+ /*lint -save -e438*/
+ if (header.base.generic.type == HEADER_TYPE_STD)
+ {
+ char const * p_log_str = (char const *)((uint32_t)header.base.std.addr);
+ params.severity = (nrf_log_severity_t)header.base.std.severity;
+ params.raw = header.base.std.raw;
+ uint32_t nargs = header.base.std.nargs;
+ uint32_t args[NRF_LOG_MAX_NUM_OF_ARGS];
+
+ nrf_memobj_read(p_msg, args, nargs*sizeof(uint32_t), memobj_offset);
+ memobj_offset += (nargs*sizeof(uint32_t));
+
+ nrf_log_std_entry_process(p_log_str,
+ args,
+ nargs,
+ &params,
+ &fprintf_ctx);
+
+ }
+ else if (header.base.generic.type == HEADER_TYPE_HEXDUMP)
+ {
+ uint32_t data_len = header.base.hexdump.len;
+ params.severity = (nrf_log_severity_t)header.base.hexdump.severity;
+ params.raw = header.base.hexdump.raw;
+ uint8_t data_buf[8];
+ uint32_t chunk_len;
+ do
+ {
+ chunk_len = sizeof(data_buf) > data_len ? data_len : sizeof(data_buf);
+ nrf_memobj_read(p_msg, data_buf, chunk_len, memobj_offset);
+ memobj_offset += chunk_len;
+ data_len -= chunk_len;
+
+ nrf_log_hexdump_entry_process(data_buf,
+ chunk_len,
+ &params,
+ &fprintf_ctx);
+ } while (data_len > 0);
+ }
+ nrf_memobj_put(p_msg);
+ /*lint -restore*/
+}
+#endif //NRF_LOG_ENABLED
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_backend_serial.h b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_backend_serial.h
new file mode 100644
index 000000000..583bc7294
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_backend_serial.h
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) 2017 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_LOG_BACKEND_SERIAL_H
+#define NRF_LOG_BACKEND_SERIAL_H
+/**@file
+ * @addtogroup nrf_log Logger module
+ * @ingroup app_common
+ *
+ * @defgroup nrf_log_backend_serial Common part of serial backends
+ * @{
+ * @ingroup nrf_log
+ * @brief The nrf_log serial backend common put function.
+ */
+
+
+#include "nrf_log_backend_interface.h"
+#include "nrf_fprintf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief A function for processing logger entry with simple serial interface as output.
+ *
+ *
+ */
+void nrf_log_backend_serial_put(nrf_log_backend_t const * p_backend,
+ nrf_log_entry_t * p_msg,
+ uint8_t * p_buffer,
+ uint32_t length,
+ nrf_fprintf_fwrite tx_func);
+
+#endif //NRF_LOG_BACKEND_SERIAL_H
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_backend_uart.c b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_backend_uart.c
new file mode 100644
index 000000000..f81018c0d
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_backend_uart.c
@@ -0,0 +1,116 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_LOG) && NRF_MODULE_ENABLED(NRF_LOG_BACKEND_UART)
+#include "nrf_log_backend_uart.h"
+#include "nrf_log_backend_serial.h"
+#include "nrf_log_internal.h"
+#include "nrf_drv_uart.h"
+#include "app_error.h"
+
+nrf_drv_uart_t m_uart = NRF_DRV_UART_INSTANCE(0);
+
+static uint8_t m_string_buff[NRF_LOG_BACKEND_UART_TEMP_BUFFER_SIZE];
+static volatile bool m_xfer_done;
+static bool m_async_mode;
+static void uart_evt_handler(nrf_drv_uart_event_t * p_event, void * p_context)
+{
+ m_xfer_done = true;
+}
+
+static void uart_init(bool async_mode)
+{
+ nrf_drv_uart_config_t config = NRF_DRV_UART_DEFAULT_CONFIG;
+ config.pseltxd = NRF_LOG_BACKEND_UART_TX_PIN;
+ config.pselrxd = NRF_UART_PSEL_DISCONNECTED;
+ config.pselcts = NRF_UART_PSEL_DISCONNECTED;
+ config.pselrts = NRF_UART_PSEL_DISCONNECTED;
+ config.baudrate = (nrf_uart_baudrate_t)NRF_LOG_BACKEND_UART_BAUDRATE;
+ ret_code_t err_code = nrf_drv_uart_init(&m_uart, &config, async_mode ? uart_evt_handler : NULL);
+ APP_ERROR_CHECK(err_code);
+
+ m_async_mode = async_mode;
+}
+
+void nrf_log_backend_uart_init(void)
+{
+ bool async_mode = NRF_LOG_DEFERRED ? true : false;
+ uart_init(async_mode);
+}
+
+static void serial_tx(void const * p_context, char const * p_buffer, size_t len)
+{
+ uint8_t len8 = (uint8_t)(len & 0x000000FF);
+ m_xfer_done = false;
+ ret_code_t err_code = nrf_drv_uart_tx(&m_uart, (uint8_t *)p_buffer, len8);
+ APP_ERROR_CHECK(err_code);
+ /* wait for completion since buffer is reused*/
+ while (m_async_mode && (m_xfer_done == false))
+ {
+
+ }
+
+}
+
+static void nrf_log_backend_uart_put(nrf_log_backend_t const * p_backend,
+ nrf_log_entry_t * p_msg)
+{
+ nrf_log_backend_serial_put(p_backend, p_msg, m_string_buff,
+ NRF_LOG_BACKEND_UART_TEMP_BUFFER_SIZE, serial_tx);
+}
+
+static void nrf_log_backend_uart_flush(nrf_log_backend_t const * p_backend)
+{
+
+}
+
+static void nrf_log_backend_uart_panic_set(nrf_log_backend_t const * p_backend)
+{
+ nrf_drv_uart_uninit(&m_uart);
+
+ uart_init(false);
+}
+
+const nrf_log_backend_api_t nrf_log_backend_uart_api = {
+ .put = nrf_log_backend_uart_put,
+ .flush = nrf_log_backend_uart_flush,
+ .panic_set = nrf_log_backend_uart_panic_set,
+};
+#endif //NRF_MODULE_ENABLED(NRF_LOG) && NRF_MODULE_ENABLED(NRF_LOG_BACKEND_UART)
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_ctrl_internal.h b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_ctrl_internal.h
new file mode 100644
index 000000000..fbe36cb96
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_ctrl_internal.h
@@ -0,0 +1,80 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_LOG_CTRL_INTERNAL_H
+#define NRF_LOG_CTRL_INTERNAL_H
+/**
+ * @cond (NODOX)
+ * @defgroup nrf_log_ctrl_internal Auxiliary internal types declarations
+ * @{
+ * @internal
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_LOG)
+
+#define NRF_LOG_INTERNAL_INIT(timestamp_func) \
+ nrf_log_init(timestamp_func)
+
+#define NRF_LOG_INTERNAL_PROCESS() nrf_log_frontend_dequeue()
+#define NRF_LOG_INTERNAL_FLUSH() \
+ do { \
+ while (NRF_LOG_INTERNAL_PROCESS()); \
+ } while (0)
+
+#define NRF_LOG_INTERNAL_FINAL_FLUSH() \
+ do { \
+ nrf_log_panic(); \
+ NRF_LOG_INTERNAL_FLUSH(); \
+ } while (0)
+
+
+#else // NRF_MODULE_ENABLED(NRF_LOG)
+#define NRF_LOG_INTERNAL_PROCESS() false
+#define NRF_LOG_INTERNAL_FLUSH()
+#define NRF_LOG_INTERNAL_INIT(timestamp_func) NRF_SUCCESS
+#define NRF_LOG_INTERNAL_HANDLERS_SET(default_handler, bytes_handler) \
+ UNUSED_PARAMETER(default_handler); UNUSED_PARAMETER(bytes_handler)
+#define NRF_LOG_INTERNAL_FINAL_FLUSH()
+#endif // NRF_MODULE_ENABLED(NRF_LOG)
+
+/** @}
+ * @endcond
+ */
+#endif // NRF_LOG_CTRL_INTERNAL_H
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_default_backends.c b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_default_backends.c
new file mode 100644
index 000000000..039bf6459
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_default_backends.c
@@ -0,0 +1,76 @@
+/**
+ * Copyright (c) 2017 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_LOG)
+#include "nrf_log_default_backends.h"
+#include "nrf_log_ctrl.h"
+#include "nrf_log_internal.h"
+#include "nrf_assert.h"
+
+#if defined(NRF_LOG_BACKEND_RTT_ENABLED) && NRF_LOG_BACKEND_RTT_ENABLED
+#include "nrf_log_backend_rtt.h"
+NRF_LOG_BACKEND_RTT_DEF(rtt_log_backend);
+#endif
+
+#if defined(NRF_LOG_BACKEND_UART_ENABLED) && NRF_LOG_BACKEND_UART_ENABLED
+#include "nrf_log_backend_uart.h"
+NRF_LOG_BACKEND_UART_DEF(uart_log_backend);
+#endif
+
+void nrf_log_default_backends_init(void)
+{
+ int32_t backend_id = -1;
+ (void)backend_id;
+#if defined(NRF_LOG_BACKEND_RTT_ENABLED) && NRF_LOG_BACKEND_RTT_ENABLED
+ nrf_log_backend_rtt_init();
+ backend_id = nrf_log_backend_add(&rtt_log_backend.backend, NRF_LOG_SEVERITY_DEBUG);
+ ASSERT(backend_id >= 0);
+ nrf_log_backend_enable(&rtt_log_backend.backend);
+#endif
+
+#if defined(NRF_LOG_BACKEND_UART_ENABLED) && NRF_LOG_BACKEND_UART_ENABLED
+ nrf_log_backend_uart_init();
+ backend_id = nrf_log_backend_add(&uart_log_backend.backend, NRF_LOG_SEVERITY_DEBUG);
+ ASSERT(backend_id >= 0);
+ nrf_log_backend_enable(&uart_log_backend.backend);
+#endif
+}
+#endif
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_frontend.c b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_frontend.c
new file mode 100644
index 000000000..459dc3e0b
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_frontend.c
@@ -0,0 +1,1146 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_LOG)
+#include "app_util.h"
+#include "app_util_platform.h"
+#include "nrf_log.h"
+#include "nrf_log_internal.h"
+#include "nrf_log_ctrl.h"
+#include "nrf_section.h"
+#include "nrf_memobj.h"
+#include "nrf_atomic.h"
+#include <string.h>
+
+STATIC_ASSERT((NRF_LOG_BUFSIZE % 4) == 0);
+STATIC_ASSERT(IS_POWER_OF_TWO(NRF_LOG_BUFSIZE));
+
+#define NRF_LOG_BUF_WORDS (NRF_LOG_BUFSIZE/4)
+
+#if NRF_LOG_BUF_WORDS < 32
+#warning "NRF_LOG_BUFSIZE too small, significant number of logs may be lost."
+#endif
+
+NRF_MEMOBJ_POOL_DEF(mempool, NRF_LOG_MSGPOOL_ELEMENT_SIZE, NRF_LOG_MSGPOOL_ELEMENT_COUNT);
+
+#define NRF_LOG_BACKENDS_FULL 0xFF
+#define NRF_LOG_FILTER_BITS_PER_BACKEND 3
+#define NRF_LOG_MAX_BACKENDS (32/NRF_LOG_FILTER_BITS_PER_BACKEND)
+#define NRF_LOG_MAX_HEXDUMP (NRF_LOG_MSGPOOL_ELEMENT_SIZE*NRF_LOG_MSGPOOL_ELEMENT_COUNT/2)
+
+/**
+ * brief An internal control block of the logger
+ *
+ * @note Circular buffer is using never cleared indexes and a mask. It means
+ * that logger may break when indexes overflows. However, it is quite unlikely.
+ * With rate of 1000 log entries with 2 parameters per second such situation
+ * would happen after 12 days.
+ */
+typedef struct
+{
+ uint32_t wr_idx; // Current write index (never reset)
+ uint32_t rd_idx; // Current read index (never_reset)
+ uint32_t mask; // Size of buffer (must be power of 2) presented as mask
+ uint32_t buffer[NRF_LOG_BUF_WORDS];
+ nrf_log_timestamp_func_t timestamp_func; // A pointer to function that returns timestamp
+ nrf_log_backend_t * p_backend_head;
+ nrf_atomic_flag_t log_skipping;
+ nrf_atomic_flag_t log_skipped;
+ bool autoflush;
+} log_data_t;
+
+static log_data_t m_log_data;
+static const char * m_overflow_info = "Overflow";
+/*lint -save -esym(526,log_const_data*) -esym(526,log_dynamic_data*)*/
+NRF_SECTION_DEF(log_dynamic_data, nrf_log_module_dynamic_data_t);
+NRF_SECTION_DEF(log_const_data, nrf_log_module_const_data_t);
+/*lint -restore*/
+NRF_LOG_MODULE_REGISTER();
+// Helper macros for section variables.
+#define NRF_LOG_DYNAMIC_SECTION_VARS_GET(i) NRF_SECTION_ITEM_GET(log_dynamic_data, nrf_log_module_dynamic_data_t, (i))
+
+#define NRF_LOG_CONST_SECTION_VARS_GET(i) NRF_SECTION_ITEM_GET(log_const_data, nrf_log_module_const_data_t, (i))
+#define NRF_LOG_CONST_SECTION_VARS_COUNT NRF_SECTION_ITEM_COUNT(log_const_data, nrf_log_module_const_data_t)
+
+#define PUSHED_HEADER_FILL(P_HDR, OFFSET, LENGTH) \
+ (P_HDR)->base.pushed.type = HEADER_TYPE_PUSHED; \
+ (P_HDR)->base.pushed.offset = OFFSET; \
+ (P_HDR)->base.pushed.len = LENGTH
+
+
+ret_code_t nrf_log_init(nrf_log_timestamp_func_t timestamp_func)
+{
+ if (NRF_LOG_USES_TIMESTAMP && (timestamp_func == NULL))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ m_log_data.mask = NRF_LOG_BUF_WORDS - 1;
+ m_log_data.wr_idx = 0;
+ m_log_data.rd_idx = 0;
+ m_log_data.log_skipped = 0;
+ m_log_data.log_skipping = 0;
+ m_log_data.autoflush = NRF_LOG_DEFERRED ? false : true;
+ if (NRF_LOG_USES_TIMESTAMP)
+ {
+ m_log_data.timestamp_func = timestamp_func;
+ }
+
+ ret_code_t err_code = nrf_memobj_pool_init(&mempool);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ uint32_t modules_cnt = NRF_LOG_CONST_SECTION_VARS_COUNT;
+ uint32_t i;
+ if (NRF_LOG_FILTERS_ENABLED)
+ {
+ uint32_t j;
+ //sort modules by name
+ for (i = 0; i < modules_cnt; i++)
+ {
+ uint32_t idx = 0;
+
+ for (j = 0; j < modules_cnt; j++)
+ {
+ if (i != j)
+ {
+ char const * p_name0 = NRF_LOG_CONST_SECTION_VARS_GET(i)->p_module_name;
+ char const * p_name1 = NRF_LOG_CONST_SECTION_VARS_GET(j)->p_module_name;
+ if (strncmp(p_name0, p_name1, 20) > 0)
+ {
+ idx++;
+ }
+ }
+
+ }
+ nrf_log_module_dynamic_data_t * p_module_ddata = NRF_LOG_DYNAMIC_SECTION_VARS_GET(i);
+ p_module_ddata->filter = 0;
+ p_module_ddata->module_id = i;
+ p_module_ddata->order_idx = idx;
+ }
+ }
+ else
+ {
+ for(i = 0; i < modules_cnt; i++)
+ {
+ nrf_log_module_dynamic_data_t * p_module_ddata = NRF_LOG_DYNAMIC_SECTION_VARS_GET(i);
+ p_module_ddata->module_id = i;
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+uint32_t nrf_log_module_cnt_get(void)
+{
+ return NRF_LOG_CONST_SECTION_VARS_COUNT;
+}
+
+static ret_code_t module_idx_get(uint32_t * p_idx, bool ordered_idx)
+{
+ if (ordered_idx)
+ {
+ uint32_t module_cnt = nrf_log_module_cnt_get();
+ uint32_t i;
+ for (i = 0; i < module_cnt; i++)
+ {
+ nrf_log_module_dynamic_data_t * p_module_data = NRF_LOG_DYNAMIC_SECTION_VARS_GET(i);
+ if (p_module_data->order_idx == *p_idx)
+ {
+ *p_idx = i;
+ return NRF_SUCCESS;
+ }
+ }
+ return NRF_ERROR_NOT_FOUND;
+ }
+ else
+ {
+ return NRF_SUCCESS;
+ }
+}
+const char * nrf_log_module_name_get(uint32_t module_id, bool ordered_idx)
+{
+ if (module_idx_get(&module_id, ordered_idx) == NRF_SUCCESS)
+ {
+ nrf_log_module_const_data_t * p_module_data = NRF_LOG_CONST_SECTION_VARS_GET(module_id);
+ return p_module_data->p_module_name;
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+uint8_t nrf_log_color_id_get(uint32_t module_id, nrf_log_severity_t severity)
+{
+ nrf_log_module_const_data_t * p_module_data = NRF_LOG_CONST_SECTION_VARS_GET(module_id);
+ uint8_t color_id;
+ switch (severity)
+ {
+ case NRF_LOG_SEVERITY_ERROR:
+ color_id = NRF_LOG_ERROR_COLOR;
+ break;
+ case NRF_LOG_SEVERITY_WARNING:
+ color_id = NRF_LOG_WARNING_COLOR;
+ break;
+ case NRF_LOG_SEVERITY_INFO:
+ color_id = p_module_data->info_color_id;
+ break;
+ case NRF_LOG_SEVERITY_DEBUG:
+ color_id = p_module_data->debug_color_id;
+ break;
+ default:
+ color_id = 0;
+ break;
+ }
+ return color_id;
+}
+
+static uint32_t higher_lvl_get(uint32_t lvls)
+{
+ uint32_t top_lvl = 0;
+ uint32_t tmp_lvl;
+ uint32_t i;
+
+ //Find highest level enabled by backends
+ for (i = 0; i < (32/NRF_LOG_LEVEL_BITS); i+=NRF_LOG_LEVEL_BITS)
+ {
+ tmp_lvl = BF_GET(lvls,NRF_LOG_LEVEL_BITS, i);
+ if (tmp_lvl > top_lvl)
+ {
+ top_lvl = tmp_lvl;
+ }
+ }
+ return top_lvl;
+}
+
+void nrf_log_module_filter_set(uint32_t backend_id, uint32_t module_id, nrf_log_severity_t severity)
+{
+ if (NRF_LOG_FILTERS_ENABLED)
+ {
+ nrf_log_module_dynamic_data_t * p_module_filter = NRF_LOG_DYNAMIC_SECTION_VARS_GET(module_id);
+ p_module_filter->filter_lvls &= ~(NRF_LOG_LEVEL_MASK << (NRF_LOG_LEVEL_BITS * backend_id));
+ p_module_filter->filter_lvls |= (severity & NRF_LOG_LEVEL_MASK) << (NRF_LOG_LEVEL_BITS * backend_id);
+ p_module_filter->filter = higher_lvl_get(p_module_filter->filter_lvls);
+ }
+}
+
+nrf_log_severity_t nrf_log_module_filter_get(uint32_t backend_id,
+ uint32_t module_id,
+ bool ordered_idx,
+ bool dynamic)
+{
+ nrf_log_severity_t severity = NRF_LOG_SEVERITY_NONE;
+ if (NRF_LOG_FILTERS_ENABLED && dynamic)
+ {
+ if (module_idx_get(&module_id, ordered_idx) == NRF_SUCCESS)
+ {
+ nrf_log_module_dynamic_data_t * p_module_filter =
+ NRF_LOG_DYNAMIC_SECTION_VARS_GET(module_id);
+ severity = (nrf_log_severity_t)((p_module_filter->filter_lvls >> (NRF_LOG_LEVEL_BITS * backend_id)) &
+ NRF_LOG_LEVEL_MASK);
+ }
+ }
+ else if (!dynamic)
+ {
+ if (module_idx_get(&module_id, ordered_idx) == NRF_SUCCESS)
+ {
+ nrf_log_module_const_data_t * p_module_data =
+ NRF_LOG_CONST_SECTION_VARS_GET(module_id);
+ severity = (nrf_log_severity_t)p_module_data->compiled_lvl;
+ }
+ }
+ return severity;
+}
+
+/**
+ * @brief Skips the oldest, not pushed logs to make space for new logs.
+ * @details This function moves forward read index to prepare space for new logs.
+ */
+
+static void log_skip(void)
+{
+ (void)nrf_atomic_flag_set(&m_log_data.log_skipped);
+ (void)nrf_atomic_flag_set(&m_log_data.log_skipping);
+
+ uint32_t rd_idx = m_log_data.rd_idx;
+ uint32_t mask = m_log_data.mask;
+ nrf_log_header_t * p_header = (nrf_log_header_t *)&m_log_data.buffer[rd_idx & mask];
+ nrf_log_header_t header;
+
+ // Skip any string that is pushed to the circular buffer.
+ while (p_header->base.generic.type == HEADER_TYPE_PUSHED)
+ {
+ rd_idx += PUSHED_HEADER_SIZE;
+ rd_idx += (p_header->base.pushed.len + p_header->base.pushed.offset);
+ p_header = (nrf_log_header_t *)&m_log_data.buffer[rd_idx & mask];
+ }
+
+ uint32_t i;
+ for (i = 0; i < HEADER_SIZE; i++)
+ {
+ ((uint32_t*)&header)[i] = m_log_data.buffer[rd_idx++ & mask];
+ }
+
+ switch (header.base.generic.type)
+ {
+ case HEADER_TYPE_HEXDUMP:
+ rd_idx += CEIL_DIV(header.base.hexdump.len, sizeof(uint32_t));
+ break;
+ case HEADER_TYPE_STD:
+ rd_idx += header.base.std.nargs;
+ break;
+ default:
+ ASSERT(false);
+ break;
+ }
+
+ uint32_t log_skipping_tmp = nrf_atomic_flag_clear_fetch(&m_log_data.log_skipping);
+ //update read index only if log_skip was not interrupted by another log skip
+ if (log_skipping_tmp)
+ {
+ m_log_data.rd_idx = rd_idx;
+ }
+}
+
+
+static inline void std_header_set(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t nargs,
+ uint32_t wr_idx,
+ uint32_t mask)
+{
+
+
+ //Prepare header - in reverse order to ensure that packet type is validated (set to STD as last action)
+ uint16_t module_id = severity_mid >> NRF_LOG_MODULE_ID_POS;
+ ASSERT(module_id < nrf_log_module_cnt_get());
+ m_log_data.buffer[(wr_idx + 1) & mask] = module_id;
+
+ if (NRF_LOG_USES_TIMESTAMP)
+ {
+ m_log_data.buffer[(wr_idx + 2) & mask] = m_log_data.timestamp_func();
+ }
+
+ nrf_log_header_t * p_header = (nrf_log_header_t *)&m_log_data.buffer[wr_idx & mask];
+ p_header->base.std.raw = (severity_mid & NRF_LOG_RAW) ? 1 : 0;
+ p_header->base.std.severity = severity_mid & NRF_LOG_LEVEL_MASK;
+ p_header->base.std.nargs = nargs;
+ p_header->base.std.addr = ((uint32_t)(p_str) & STD_ADDR_MASK);
+ p_header->base.std.type = HEADER_TYPE_STD;
+}
+
+/**
+ * @brief Allocates chunk in a buffer for one entry and injects overflow if
+ * there is no room for requested entry.
+ *
+ * @param content_len Number of 32bit arguments. In case of allocating for hex dump it
+ * is the size of the buffer in 32bit words (ceiled).
+ * @param p_wr_idx Pointer to write index.
+ *
+ * @return True if successful allocation, false otherwise.
+ *
+ */
+static inline bool buf_prealloc(uint32_t content_len, uint32_t * p_wr_idx)
+{
+ uint32_t req_len = content_len + HEADER_SIZE;
+ uint32_t ovflw_tag_size = HEADER_SIZE;
+ bool ret = true;
+ CRITICAL_REGION_ENTER();
+ *p_wr_idx = m_log_data.wr_idx;
+ uint32_t available_words = (m_log_data.mask + 1) - (m_log_data.wr_idx - m_log_data.rd_idx);
+ uint32_t required_words = req_len + ovflw_tag_size; // room for current entry and overflow
+ while (required_words > available_words)
+ {
+ if (NRF_LOG_ALLOW_OVERFLOW)
+ {
+ log_skip();
+ available_words = (m_log_data.mask + 1) - (m_log_data.wr_idx - m_log_data.rd_idx);
+ }
+ else
+ {
+ if (available_words >= HEADER_SIZE)
+ {
+ // Overflow entry is injected
+ std_header_set(NRF_LOG_LEVEL_WARNING, m_overflow_info, 0, m_log_data.wr_idx, m_log_data.mask);
+ req_len = HEADER_SIZE;
+ }
+ else
+ {
+ // No more room for any logs.
+ req_len = 0;
+ }
+ ret = false;
+ break;
+ }
+
+ }
+ /* Mark header as invalid.*/
+ nrf_log_generic_header_t * p_header = (nrf_log_generic_header_t *)&m_log_data.buffer[m_log_data.wr_idx & m_log_data.mask];
+ p_header->type = HEADER_TYPE_INVALID;
+
+ m_log_data.wr_idx += req_len;
+
+ CRITICAL_REGION_EXIT();
+ return ret;
+}
+
+
+/**
+ * @brief Function for preallocating a continuous chunk of memory from circular buffer.
+ *
+ * If buffer does not fit starting from current position it will be allocated at
+ * the beginning of the circular buffer and offset will be returned indicating
+ * how much memory has been ommited at the end of the buffer. Function is
+ * using critical section.
+ *
+ * @param len32 Length of buffer to allocate. Given in words.
+ * @param p_offset Offset of the buffer.
+ * @param p_wr_idx Pointer to write index.
+ *
+ * @return A pointer to the allocated buffer. NULL if allocation failed.
+ */
+static inline uint32_t * cont_buf_prealloc(uint32_t len32,
+ uint32_t * p_offset,
+ uint32_t * p_wr_idx)
+{
+ uint32_t * p_buf = NULL;
+
+ len32 += PUSHED_HEADER_SIZE; // Increment because 32bit header is needed to be stored.
+
+ CRITICAL_REGION_ENTER();
+ *p_wr_idx = m_log_data.wr_idx;
+ uint32_t available_words = (m_log_data.mask + 1) -
+ (m_log_data.wr_idx - m_log_data.rd_idx);
+ if (len32 <= available_words)
+ {
+ // buffer will fit as is
+ p_buf = &m_log_data.buffer[(m_log_data.wr_idx + 1) & m_log_data.mask];
+ m_log_data.wr_idx += len32;
+ *p_offset = 0;
+ }
+ else if (len32 < (m_log_data.rd_idx & m_log_data.mask))
+ {
+ // wraping to the begining of the buffer
+ m_log_data.wr_idx += (len32 + available_words - 1);
+ *p_offset = available_words - 1;
+ p_buf = m_log_data.buffer;
+ }
+ available_words = (m_log_data.mask + 1) - (m_log_data.wr_idx - m_log_data.rd_idx);
+ // If there is no more room for even overflow tag indicate failed allocation.
+ if (available_words < HEADER_SIZE)
+ {
+ p_buf = NULL;
+ }
+ CRITICAL_REGION_EXIT();
+
+ return p_buf;
+}
+
+
+uint32_t nrf_log_push(char * const p_str)
+{
+ if ((m_log_data.autoflush) || (p_str == NULL))
+ {
+ return (uint32_t)p_str;
+ }
+
+ uint32_t mask = m_log_data.mask;
+ uint32_t slen = strlen(p_str) + 1;
+ uint32_t buflen = CEIL_DIV(slen, sizeof(uint32_t));
+ uint32_t offset = 0;
+ uint32_t wr_idx;
+ char * p_dst_str = (char *)cont_buf_prealloc(buflen, &offset, &wr_idx);
+ if (p_dst_str)
+ {
+ nrf_log_header_t * p_header = (nrf_log_header_t *)&m_log_data.buffer[wr_idx & mask];
+ PUSHED_HEADER_FILL(p_header, offset, buflen);
+ memcpy(p_dst_str, p_str, slen);
+ }
+ return (uint32_t)p_dst_str;
+}
+
+static inline void std_n(uint32_t severity_mid, char const * const p_str, uint32_t const * args, uint32_t nargs)
+{
+ uint32_t mask = m_log_data.mask;
+ uint32_t wr_idx;
+
+ if (buf_prealloc(nargs, &wr_idx))
+ {
+ // Proceed only if buffer was successfully preallocated.
+
+ uint32_t data_idx = wr_idx + HEADER_SIZE;
+ uint32_t i;
+ for (i = 0; i < nargs; i++)
+ {
+ m_log_data.buffer[data_idx++ & mask] =args[i];
+ }
+ std_header_set(severity_mid, p_str, nargs, wr_idx, mask);
+ }
+ if (m_log_data.autoflush)
+ {
+ NRF_LOG_FLUSH();
+ }
+
+}
+
+void nrf_log_frontend_std_0(uint32_t severity_mid, char const * const p_str)
+{
+ std_n(severity_mid, p_str, NULL, 0);
+}
+
+
+void nrf_log_frontend_std_1(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0)
+{
+ uint32_t args[] = {val0};
+ std_n(severity_mid, p_str, args, ARRAY_SIZE(args));
+}
+
+
+void nrf_log_frontend_std_2(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0,
+ uint32_t val1)
+{
+ uint32_t args[] = {val0, val1};
+ std_n(severity_mid, p_str, args, ARRAY_SIZE(args));
+}
+
+
+void nrf_log_frontend_std_3(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0,
+ uint32_t val1,
+ uint32_t val2)
+{
+ uint32_t args[] = {val0, val1, val2};
+ std_n(severity_mid, p_str, args, ARRAY_SIZE(args));
+}
+
+
+void nrf_log_frontend_std_4(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0,
+ uint32_t val1,
+ uint32_t val2,
+ uint32_t val3)
+{
+ uint32_t args[] = {val0, val1, val2, val3};
+ std_n(severity_mid, p_str, args, ARRAY_SIZE(args));
+}
+
+
+void nrf_log_frontend_std_5(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0,
+ uint32_t val1,
+ uint32_t val2,
+ uint32_t val3,
+ uint32_t val4)
+{
+ uint32_t args[] = {val0, val1, val2, val3, val4};
+ std_n(severity_mid, p_str, args, ARRAY_SIZE(args));
+}
+
+
+void nrf_log_frontend_std_6(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0,
+ uint32_t val1,
+ uint32_t val2,
+ uint32_t val3,
+ uint32_t val4,
+ uint32_t val5)
+{
+ uint32_t args[] = {val0, val1, val2, val3, val4, val5};
+ std_n(severity_mid, p_str, args, ARRAY_SIZE(args));
+}
+
+
+void nrf_log_frontend_hexdump(uint32_t severity_mid,
+ const void * const p_data,
+ uint16_t length)
+{
+ uint32_t mask = m_log_data.mask;
+
+ uint32_t wr_idx;
+ if (buf_prealloc(CEIL_DIV(length, sizeof(uint32_t)), &wr_idx))
+ {
+ uint32_t header_wr_idx = wr_idx;
+ wr_idx += HEADER_SIZE;
+
+ uint32_t space0 = sizeof(uint32_t) * (m_log_data.mask + 1 - (wr_idx & mask));
+ if (length <= space0)
+ {
+ memcpy(&m_log_data.buffer[wr_idx & mask], p_data, length);
+ }
+ else
+ {
+ memcpy(&m_log_data.buffer[wr_idx & mask], p_data, space0);
+ length -= space0;
+ memcpy(&m_log_data.buffer[0], &((uint8_t *)p_data)[space0], length);
+ }
+
+ //Prepare header - in reverse order to ensure that packet type is validated (set to HEXDUMP as last action)
+ if (NRF_LOG_USES_TIMESTAMP)
+ {
+ m_log_data.buffer[(header_wr_idx + 2) & mask] = m_log_data.timestamp_func();
+ }
+
+ m_log_data.buffer[(header_wr_idx + 1) & mask] = severity_mid >> NRF_LOG_MODULE_ID_POS;
+ //Header prepare
+ nrf_log_header_t * p_header = (nrf_log_header_t *)&m_log_data.buffer[header_wr_idx & mask];
+ p_header->base.hexdump.raw = (severity_mid & NRF_LOG_RAW) ? 1 : 0;
+ p_header->base.hexdump.severity = severity_mid & NRF_LOG_LEVEL_MASK;
+ p_header->base.hexdump.offset = 0;
+ p_header->base.hexdump.len = length;
+ p_header->base.hexdump.type = HEADER_TYPE_HEXDUMP;
+
+
+
+ }
+
+ if (m_log_data.autoflush)
+ {
+ NRF_LOG_FLUSH();
+ }
+}
+
+
+bool buffer_is_empty(void)
+{
+ return (m_log_data.rd_idx == m_log_data.wr_idx);
+}
+
+
+bool nrf_log_frontend_dequeue(void)
+{
+ if (buffer_is_empty())
+ {
+ return false;
+ }
+ m_log_data.log_skipped = 0;
+ //It has to be ensured that reading rd_idx occurs after skipped flag is cleared.
+ __DSB();
+ uint32_t rd_idx = m_log_data.rd_idx;
+ uint32_t mask = m_log_data.mask;
+ nrf_log_header_t * p_header = (nrf_log_header_t *)&m_log_data.buffer[rd_idx & mask];
+ nrf_log_header_t header;
+ nrf_memobj_t * p_msg_buf = NULL;
+ uint32_t memobj_offset = 0;
+ uint32_t severity = 0;
+
+ // Skip any string that is pushed to the circular buffer.
+ while (p_header->base.generic.type == HEADER_TYPE_PUSHED)
+ {
+ rd_idx += PUSHED_HEADER_SIZE;
+ rd_idx += (p_header->base.pushed.len + p_header->base.pushed.offset);
+ p_header = (nrf_log_header_t *)&m_log_data.buffer[rd_idx & mask];
+ }
+
+ uint32_t i;
+ for (i = 0; i < HEADER_SIZE; i++)
+ {
+ ((uint32_t*)&header)[i] = m_log_data.buffer[rd_idx++ & mask];
+ }
+
+ if (header.base.generic.type == HEADER_TYPE_HEXDUMP)
+ {
+ uint32_t orig_data_len = header.base.hexdump.len;
+ uint32_t data_len = MIN(header.base.hexdump.len, NRF_LOG_MAX_HEXDUMP); //limit the data
+ header.base.hexdump.len = data_len;
+ uint32_t msg_buf_size8 = sizeof(uint32_t)*HEADER_SIZE + data_len;
+ severity = header.base.hexdump.severity;
+ p_msg_buf = nrf_memobj_alloc(&mempool, msg_buf_size8);
+
+ if (p_msg_buf)
+ {
+ nrf_memobj_get(p_msg_buf);
+ nrf_memobj_write(p_msg_buf, &header, HEADER_SIZE*sizeof(uint32_t), memobj_offset);
+ memobj_offset += HEADER_SIZE*sizeof(uint32_t);
+
+ uint32_t space0 = sizeof(uint32_t) * (mask + 1 - (rd_idx & mask));
+ if (data_len > space0)
+ {
+ uint8_t * ptr0 = space0 ?
+ (uint8_t *)&m_log_data.buffer[rd_idx & mask] :
+ (uint8_t *)&m_log_data.buffer[0];
+ uint8_t len0 = space0 ? space0 : data_len;
+ uint8_t * ptr1 = space0 ?
+ (uint8_t *)&m_log_data.buffer[0] : NULL;
+ uint8_t len1 = space0 ? data_len - space0 : 0;
+
+ nrf_memobj_write(p_msg_buf, ptr0, len0, memobj_offset);
+ memobj_offset += len0;
+ if (ptr1)
+ {
+ nrf_memobj_write(p_msg_buf, ptr1, len1, memobj_offset);
+ }
+ }
+ else
+ {
+ uint8_t * p_data = (uint8_t *)&m_log_data.buffer[rd_idx & mask];
+ nrf_memobj_write(p_msg_buf, p_data, data_len, memobj_offset);
+ }
+ rd_idx += CEIL_DIV(orig_data_len, 4);
+ }
+ }
+ else if (header.base.generic.type == HEADER_TYPE_STD) // standard entry
+ {
+ header.base.std.nargs = MIN(header.base.std.nargs, NRF_LOG_MAX_NUM_OF_ARGS);
+ uint32_t msg_buf_size32 = HEADER_SIZE + header.base.std.nargs;
+ severity = header.base.std.severity;
+
+ p_msg_buf = nrf_memobj_alloc(&mempool, msg_buf_size32*sizeof(uint32_t));
+
+ if (p_msg_buf)
+ {
+ nrf_memobj_get(p_msg_buf);
+ nrf_memobj_write(p_msg_buf, &header, HEADER_SIZE*sizeof(uint32_t), memobj_offset);
+ memobj_offset += HEADER_SIZE*sizeof(uint32_t);
+
+ for (i = 0; i < header.base.std.nargs; i++)
+ {
+ nrf_memobj_write(p_msg_buf, &m_log_data.buffer[rd_idx++ & mask],
+ sizeof(uint32_t), memobj_offset);
+ memobj_offset += sizeof(uint32_t);
+ }
+ }
+ }
+ else if (header.base.generic.type == HEADER_TYPE_INVALID && (m_log_data.log_skipped == 0))
+ {
+ //invalid type can only occur if log entry was interrupted by log_process. It is likly final flush
+ // and finding invalid type means that last entry in the buffer was reached (the one that was interrupted).
+ // Stop processing immediately.
+ return false;
+ }
+ else
+ {
+ //Do nothing. In case of log overflow buffer can contain corrupted data.
+ }
+
+ if (p_msg_buf)
+ {
+ nrf_log_backend_t * p_backend = m_log_data.p_backend_head;
+ if (NRF_LOG_ALLOW_OVERFLOW && m_log_data.log_skipped)
+ {
+ // Check if any log was skipped during log processing. Do not forward log if skipping
+ // occured because data may be invalid.
+ nrf_memobj_put(p_msg_buf);
+ }
+ else
+ {
+ while (p_backend)
+ {
+ bool entry_accepted = false;
+ if (nrf_log_backend_is_enabled(p_backend) == true)
+ {
+ if (NRF_LOG_FILTERS_ENABLED)
+ {
+ uint8_t backend_id = nrf_log_backend_id_get(p_backend);
+ uint32_t filter_lvls = NRF_LOG_DYNAMIC_SECTION_VARS_GET(header.module_id)->filter_lvls;
+ uint32_t backend_lvl = (filter_lvls >> (backend_id*NRF_LOG_LEVEL_BITS))
+ & NRF_LOG_LEVEL_MASK;
+ if (backend_lvl >= severity)
+ {
+ entry_accepted = true;
+ }
+ }
+ else
+ {
+ (void)severity;
+ entry_accepted = true;
+ }
+ }
+ if (entry_accepted)
+ {
+ nrf_log_backend_put(p_backend, p_msg_buf);
+ }
+ p_backend = p_backend->p_next;
+ }
+
+ nrf_memobj_put(p_msg_buf);
+
+ if (NRF_LOG_ALLOW_OVERFLOW)
+ {
+ // Read index can be moved forward only if dequeueing process was not interrupt by
+ // skipping procedure. If NRF_LOG_ALLOW_OVERFLOW is set then in case of buffer gets full
+ // and new logger entry occurs, oldest entry is removed. In that case read index is
+ // changed and updating it here would corrupt the internal circular buffer.
+ CRITICAL_REGION_ENTER();
+ if (m_log_data.log_skipped == 0)
+ {
+ m_log_data.rd_idx = rd_idx;
+ }
+ CRITICAL_REGION_EXIT();
+ }
+ else
+ {
+ m_log_data.rd_idx = rd_idx;
+ }
+ }
+ }
+
+ return buffer_is_empty() ? false : true;
+}
+
+static int32_t backend_id_assign(void)
+{
+ int32_t candidate_id;
+ nrf_log_backend_t * p_backend;
+ bool id_available;
+ for (candidate_id = 0; candidate_id < NRF_LOG_MAX_BACKENDS; candidate_id++)
+ {
+ p_backend = m_log_data.p_backend_head;
+ id_available = true;
+ while (p_backend)
+ {
+ if (nrf_log_backend_id_get(p_backend) == candidate_id)
+ {
+ id_available = false;
+ break;
+ }
+ p_backend = p_backend->p_next;
+ }
+ if (id_available)
+ {
+ return candidate_id;
+ }
+ }
+ return -1;
+}
+
+int32_t nrf_log_backend_add(nrf_log_backend_t * p_backend, nrf_log_severity_t severity)
+{
+ int32_t id = backend_id_assign();
+ if (id == -1)
+ {
+ return id;
+ }
+
+ nrf_log_backend_id_set(p_backend, id);
+ //add to list
+ if (m_log_data.p_backend_head == NULL)
+ {
+ m_log_data.p_backend_head = p_backend;
+ p_backend->p_next = NULL;
+ }
+ else
+ {
+ p_backend->p_next = m_log_data.p_backend_head->p_next;
+ m_log_data.p_backend_head->p_next = p_backend;
+ }
+
+ if (NRF_LOG_FILTERS_ENABLED)
+ {
+ uint32_t i;
+ for (i = 0; i < nrf_log_module_cnt_get(); i++)
+ {
+ nrf_log_severity_t buildin_lvl = nrf_log_module_filter_get(id, i, false, false);
+ nrf_log_severity_t actual_severity = MIN(buildin_lvl, severity);
+ nrf_log_module_filter_set(nrf_log_backend_id_get(p_backend), i, actual_severity);
+ }
+ }
+
+ return id;
+}
+
+void nrf_log_backend_remove(nrf_log_backend_t * p_backend)
+{
+ nrf_log_backend_t * p_curr = m_log_data.p_backend_head;
+ nrf_log_backend_t * p_prev = NULL;
+ while (p_curr != p_backend)
+ {
+ p_prev = p_curr;
+ p_curr = p_curr->p_next;
+ }
+
+ if (p_prev)
+ {
+ p_prev->p_next = p_backend->p_next;
+ }
+ else
+ {
+ m_log_data.p_backend_head = NULL;
+ }
+}
+
+void nrf_log_panic(void)
+{
+ nrf_log_backend_t * p_backend = m_log_data.p_backend_head;
+ m_log_data.autoflush = true;
+ while (p_backend)
+ {
+ nrf_log_backend_enable(p_backend);
+ nrf_log_backend_panic_set(p_backend);
+ p_backend = p_backend->p_next;
+ }
+}
+
+#if NRF_LOG_CLI_CMDS
+#include "nrf_cli.h"
+
+static const char * m_severity_lvls[] = {
+ "none",
+ "error",
+ "warning",
+ "info",
+ "debug",
+};
+
+static const char * m_severity_lvls_sorted[] = {
+ "debug",
+ "error",
+ "info",
+ "none",
+ "warning",
+};
+
+static void log_status(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ uint32_t modules_cnt = nrf_log_module_cnt_get();
+ uint32_t backend_id = p_cli->p_log_backend->backend.id;
+ uint32_t i;
+
+ if (!nrf_log_backend_is_enabled(&p_cli->p_log_backend->backend))
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Logs are halted!\r\n");
+ }
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "%-24s | current | buildin \r\n", "module_name");
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "------------------------------------------\r\n");
+ for (i = 0; i < modules_cnt; i++)
+ {
+ nrf_log_severity_t module_dynamic_lvl = nrf_log_module_filter_get(backend_id, i, true, true);
+ nrf_log_severity_t module_compiled_lvl = nrf_log_module_filter_get(backend_id, i, true, false);
+ nrf_log_severity_t actual_compiled_lvl = MIN(module_compiled_lvl, (nrf_log_severity_t)NRF_LOG_DEFAULT_LEVEL);
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "%-24s | %-7s | %s%s\r\n",
+ nrf_log_module_name_get(i, true),
+ m_severity_lvls[module_dynamic_lvl],
+ m_severity_lvls[actual_compiled_lvl],
+ actual_compiled_lvl < module_compiled_lvl ? "*" : "");
+ }
+}
+
+static bool module_id_get(const char * p_name, uint32_t * p_id)
+{
+ uint32_t modules_cnt = nrf_log_module_cnt_get();
+ const char * p_tmp_name;
+ uint32_t j;
+ for (j = 0; j < modules_cnt; j++)
+ {
+ p_tmp_name = nrf_log_module_name_get(j, false);
+ if (strncmp(p_tmp_name, p_name, 32) == 0)
+ {
+ *p_id = j;
+ break;
+ }
+ }
+ return (j != modules_cnt);
+}
+
+static bool module_id_filter_set(uint32_t backend_id,
+ uint32_t module_id,
+ nrf_log_severity_t lvl)
+{
+ nrf_log_severity_t buildin_lvl = nrf_log_module_filter_get(backend_id, module_id, false, false);
+ if (lvl > buildin_lvl)
+ {
+ return false;
+ }
+ else
+ {
+ nrf_log_module_filter_set(backend_id, module_id, lvl);
+ return true;
+ }
+}
+
+static void log_ctrl(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ uint32_t backend_id = p_cli->p_log_backend->backend.id;
+ nrf_log_severity_t lvl;
+ uint32_t first_m_name_idx;
+ uint32_t i;
+ bool all_modules = false;
+
+ if (argc > 0)
+ {
+ if (strncmp(argv[0], "enable", 7) == 0)
+ {
+ if (argc == 1)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Bad parameter count.\r\n");
+ return;
+ }
+
+ if (argc == 2)
+ {
+ all_modules = true;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(m_severity_lvls); i++)
+ {
+ if (strncmp(argv[1], m_severity_lvls[i], 10) == 0)
+ {
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(m_severity_lvls))
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Unknown severity level: %s\r\n", argv[1]);
+ return;
+ }
+
+ lvl = (nrf_log_severity_t)i;
+ first_m_name_idx = 2;
+
+ }
+ else if (strncmp(argv[0], "disable", 8) == 0)
+ {
+ if (argc == 1)
+ {
+ all_modules = true;
+ }
+ lvl = NRF_LOG_SEVERITY_NONE;
+ first_m_name_idx = 1;
+ }
+ else
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Unknown option: %s\r\n", argv[0]);
+ return;
+ }
+
+ if (all_modules)
+ {
+ for (i = 0; i < nrf_log_module_cnt_get(); i++)
+ {
+ if (module_id_filter_set(backend_id, i, lvl) == false)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Level unavailable for module: %s\r\n", nrf_log_module_name_get(i, false));
+ }
+ }
+ }
+ else
+ {
+ for (i = first_m_name_idx; i < argc; i++)
+ {
+ uint32_t module_id = 0;
+ if (module_id_get(argv[i], &module_id) == false)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Unknown module:%s\r\n", argv[i]);
+ }
+
+ if (module_id_filter_set(backend_id, module_id, lvl) == false)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Level unavailable for module: %s\r\n", nrf_log_module_name_get(module_id, false));
+ }
+ }
+ }
+ }
+}
+static void module_name_get(size_t idx, nrf_cli_static_entry_t * p_static);
+
+NRF_CLI_CREATE_DYNAMIC_CMD(m_module_name, module_name_get);
+
+static void module_name_get(size_t idx, nrf_cli_static_entry_t * p_static)
+{
+ p_static->handler = NULL;
+ p_static->p_help = NULL;
+ p_static->p_subcmd = &m_module_name;
+ p_static->p_syntax = nrf_log_module_name_get(idx, true);
+}
+
+static void severity_lvl_get(size_t idx, nrf_cli_static_entry_t * p_static)
+{
+ p_static->handler = NULL;
+ p_static->p_help = NULL;
+ p_static->p_subcmd = &m_module_name;
+ p_static->p_syntax = (idx < ARRAY_SIZE(m_severity_lvls_sorted)) ?
+ m_severity_lvls_sorted[idx] : NULL;
+}
+
+NRF_CLI_CREATE_DYNAMIC_CMD(m_severity_lvl, severity_lvl_get);
+
+static void log_halt(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ nrf_log_backend_disable(&p_cli->p_log_backend->backend);
+}
+
+static void log_go(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ nrf_log_backend_enable(&p_cli->p_log_backend->backend);
+}
+
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_log_stat)
+{
+ NRF_CLI_CMD(disable, &m_module_name,
+ "'log disable <module_0> .. <module_n>' disables logs in specified "
+ "modules (all if no modules specified).",
+ log_ctrl),
+ NRF_CLI_CMD(enable, &m_severity_lvl,
+ "'log enable <level> <module_0> ... <module_n>' enables logs up to given level in "
+ "specified modules (all if no modules specified).",
+ log_ctrl),
+ NRF_CLI_CMD(go, NULL, "Resume logging", log_go),
+ NRF_CLI_CMD(halt, NULL, "Halt logging", log_halt),
+ NRF_CLI_CMD(status, NULL, "Logger status", log_status),
+ NRF_CLI_SUBCMD_SET_END
+};
+
+static void log_cmd(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ if ((argc == 1) || nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "%s:%s%s\r\n", argv[0], " unknown parameter: ", argv[1]);
+}
+
+NRF_CLI_CMD_REGISTER(log, &m_sub_log_stat, "Commands for controlling logger", log_cmd);
+
+#endif //NRF_LOG_CLI_CMDS
+
+#endif // NRF_MODULE_ENABLED(NRF_LOG)
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_internal.h b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_internal.h
new file mode 100644
index 000000000..3cf7b0600
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_internal.h
@@ -0,0 +1,548 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_LOG_INTERNAL_H__
+#define NRF_LOG_INTERNAL_H__
+#include "sdk_common.h"
+#include "nrf.h"
+#include "nrf_error.h"
+#include "app_util.h"
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifndef NRF_LOG_ERROR_COLOR
+ #define NRF_LOG_ERROR_COLOR NRF_LOG_COLOR_DEFAULT
+#endif
+
+#ifndef NRF_LOG_WARNING_COLOR
+ #define NRF_LOG_WARNING_COLOR NRF_LOG_COLOR_DEFAULT
+#endif
+
+#ifndef NRF_LOG_INFO_COLOR
+ #define NRF_LOG_INFO_COLOR NRF_LOG_COLOR_DEFAULT
+#endif
+
+#ifndef NRF_LOG_DEBUG_COLOR
+ #define NRF_LOG_DEBUG_COLOR NRF_LOG_COLOR_DEFAULT
+#endif
+
+
+#ifndef NRF_LOG_COLOR_DEFAULT
+#define NRF_LOG_COLOR_DEFAULT 0
+#endif
+
+#ifndef NRF_LOG_DEFAULT_LEVEL
+#define NRF_LOG_DEFAULT_LEVEL 0
+#endif
+
+#ifndef NRF_LOG_USES_COLORS
+#define NRF_LOG_USES_COLORS 0
+#endif
+
+#ifndef NRF_LOG_USES_TIMESTAMP
+#define NRF_LOG_USES_TIMESTAMP 0
+#endif
+
+#ifndef NRF_LOG_FILTERS_ENABLED
+#define NRF_LOG_FILTERS_ENABLED 0
+#endif
+
+#ifndef NRF_LOG_MODULE_NAME
+ #define NRF_LOG_MODULE_NAME app
+#endif
+
+#define NRF_LOG_LEVEL_ERROR 1UL
+#define NRF_LOG_LEVEL_WARNING 2UL
+#define NRF_LOG_LEVEL_INFO 3UL
+#define NRF_LOG_LEVEL_DEBUG 4UL
+#define NRF_LOG_LEVEL_INTERNAL 5UL
+#define NRF_LOG_LEVEL_BITS 3
+#define NRF_LOG_LEVEL_MASK ((1UL << NRF_LOG_LEVEL_BITS) - 1)
+#define NRF_LOG_RAW_POS 4U
+#define NRF_LOG_RAW (1UL << NRF_LOG_RAW_POS)
+#define NRF_LOG_MODULE_ID_BITS 16
+#define NRF_LOG_MODULE_ID_POS 16
+#define NRF_LOG_LEVEL_INFO_RAW (NRF_LOG_RAW | NRF_LOG_LEVEL_INFO)
+
+#define NRF_LOG_MAX_NUM_OF_ARGS 6
+
+/*
+ * For GCC sections are sorted in the group by the linker. For IAR and KEIL it is assumed that linker will sort
+ * dynamic and const section in the same order (but in different locations). Proper message formatting
+ * is based on that assumption.
+ */
+#if defined(__GNUC__)
+#define NRF_LOG_DYNAMIC_SECTION_NAME(_module_name) CONCAT_2(log_dynamic_data_,_module_name)
+#define NRF_LOG_CONST_SECTION_NAME(_module_name) CONCAT_2(log_const_data_,_module_name)
+#else
+#define NRF_LOG_DYNAMIC_SECTION_NAME(_module_name) log_dynamic_data
+#define NRF_LOG_CONST_SECTION_NAME(_module_name) log_const_data
+#endif
+
+#define NRF_LOG_MODULE_DATA CONCAT_3(m_nrf_log_,NRF_LOG_MODULE_NAME,_logs_data)
+#define NRF_LOG_MODULE_DATA_DYNAMIC CONCAT_2(NRF_LOG_MODULE_DATA,_dynamic)
+#define NRF_LOG_MODULE_DATA_CONST CONCAT_2(NRF_LOG_MODULE_DATA,_const)
+
+#if NRF_LOG_FILTERS_ENABLED && NRF_LOG_ENABLED
+ #define NRF_LOG_FILTER NRF_LOG_MODULE_DATA_DYNAMIC.filter
+#else
+ #undef NRF_LOG_FILTER
+ #define NRF_LOG_FILTER NRF_LOG_LEVEL_DEBUG
+#endif
+
+#if NRF_LOG_ENABLED
+#define NRF_LOG_MODULE_ID NRF_LOG_MODULE_DATA_DYNAMIC.module_id
+#else
+#define NRF_LOG_MODULE_ID 0
+#endif
+
+
+#define LOG_INTERNAL_X(N, ...) CONCAT_2(LOG_INTERNAL_, N) (__VA_ARGS__)
+#define LOG_INTERNAL(type, ...) LOG_INTERNAL_X(NUM_VA_ARGS_LESS_1( \
+ __VA_ARGS__), type, __VA_ARGS__)
+#if NRF_LOG_ENABLED
+#define NRF_LOG_INTERNAL_LOG_PUSH(_str) nrf_log_push(_str)
+#define LOG_INTERNAL_0(type, str) \
+ nrf_log_frontend_std_0(type, str)
+#define LOG_INTERNAL_1(type, str, arg0) \
+ /*lint -save -e571*/nrf_log_frontend_std_1(type, str, (uint32_t)(arg0))/*lint -restore*/
+#define LOG_INTERNAL_2(type, str, arg0, arg1) \
+ /*lint -save -e571*/nrf_log_frontend_std_2(type, str, (uint32_t)(arg0), \
+ (uint32_t)(arg1))/*lint -restore*/
+#define LOG_INTERNAL_3(type, str, arg0, arg1, arg2) \
+ /*lint -save -e571*/nrf_log_frontend_std_3(type, str, (uint32_t)(arg0), \
+ (uint32_t)(arg1), (uint32_t)(arg2))/*lint -restore*/
+#define LOG_INTERNAL_4(type, str, arg0, arg1, arg2, arg3) \
+ /*lint -save -e571*/nrf_log_frontend_std_4(type, str, (uint32_t)(arg0), \
+ (uint32_t)(arg1), (uint32_t)(arg2), (uint32_t)(arg3))/*lint -restore*/
+#define LOG_INTERNAL_5(type, str, arg0, arg1, arg2, arg3, arg4) \
+ /*lint -save -e571*/nrf_log_frontend_std_5(type, str, (uint32_t)(arg0), \
+ (uint32_t)(arg1), (uint32_t)(arg2), (uint32_t)(arg3), (uint32_t)(arg4))/*lint -restore*/
+#define LOG_INTERNAL_6(type, str, arg0, arg1, arg2, arg3, arg4, arg5) \
+ /*lint -save -e571*/nrf_log_frontend_std_6(type, str, (uint32_t)(arg0), \
+ (uint32_t)(arg1), (uint32_t)(arg2), (uint32_t)(arg3), (uint32_t)(arg4), (uint32_t)(arg5))/*lint -restore*/
+
+
+#else //NRF_LOG_ENABLED
+#define NRF_LOG_INTERNAL_LOG_PUSH(_str) (void)(_str)
+#define LOG_INTERNAL_0(_type, _str) \
+ (void)(_type); (void)(_str)
+#define LOG_INTERNAL_1(_type, _str, _arg0) \
+ (void)(_type); (void)(_str); (void)(_arg0)
+#define LOG_INTERNAL_2(_type, _str, _arg0, _arg1) \
+ (void)(_type); (void)(_str); (void)(_arg0); (void)(_arg1)
+#define LOG_INTERNAL_3(_type, _str, _arg0, _arg1, _arg2) \
+ (void)(_type); (void)(_str); (void)(_arg0); (void)(_arg1); (void)(_arg2)
+#define LOG_INTERNAL_4(_type, _str, _arg0, _arg1, _arg2, _arg3) \
+ (void)(_type); (void)(_str); (void)(_arg0); (void)(_arg1); (void)(_arg2); (void)(_arg3)
+#define LOG_INTERNAL_5(_type, _str, _arg0, _arg1, _arg2, _arg3, _arg4) \
+ (void)(_type); (void)(_str); (void)(_arg0); (void)(_arg1); (void)(_arg2); (void)(_arg3); (void)(_arg4)
+#define LOG_INTERNAL_6(_type, _str, _arg0, _arg1, _arg2, _arg3, _arg4, _arg5) \
+ (void)(_type); (void)(_str); (void)(_arg0); (void)(_arg1); (void)(_arg2); (void)(_arg3); (void)(_arg4); (void)(_arg5)
+#endif //NRF_LOG_ENABLED && (NRF_LOG_DEFAULT_LEVEL >= NRF_LOG_LEVEL_ERROR)
+
+#define LOG_SEVERITY_MOD_ID(severity) ((severity) | NRF_LOG_MODULE_ID << NRF_LOG_MODULE_ID_POS)
+
+#if NRF_LOG_ENABLED
+#define LOG_HEXDUMP(_severity, _p_data, _length) \
+ nrf_log_frontend_hexdump((_severity), (_p_data), (_length))
+#else
+#define LOG_HEXDUMP(_severity, _p_data, _length) \
+ (void)(_severity); (void)(_p_data); (void)_length
+#endif
+
+#define NRF_LOG_INTERNAL_ERROR(...) \
+ if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= NRF_LOG_LEVEL_ERROR) && \
+ (NRF_LOG_LEVEL_ERROR <= NRF_LOG_DEFAULT_LEVEL)) \
+ { \
+ if (NRF_LOG_FILTER >= NRF_LOG_LEVEL_ERROR) \
+ { \
+ LOG_INTERNAL(LOG_SEVERITY_MOD_ID(NRF_LOG_LEVEL_ERROR), __VA_ARGS__); \
+ } \
+ }
+#define NRF_LOG_INTERNAL_HEXDUMP_ERROR(p_data, len) \
+ if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= NRF_LOG_LEVEL_ERROR) && \
+ (NRF_LOG_LEVEL_ERROR <= NRF_LOG_DEFAULT_LEVEL)) \
+ { \
+ if (NRF_LOG_FILTER >= NRF_LOG_LEVEL_ERROR) \
+ { \
+ LOG_HEXDUMP(LOG_SEVERITY_MOD_ID(NRF_LOG_LEVEL_ERROR), \
+ (p_data), (len)); \
+ } \
+ }
+
+#define NRF_LOG_INTERNAL_WARNING(...) \
+ if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= NRF_LOG_LEVEL_WARNING) && \
+ (NRF_LOG_LEVEL_WARNING <= NRF_LOG_DEFAULT_LEVEL)) \
+ { \
+ if (NRF_LOG_FILTER >= NRF_LOG_LEVEL_WARNING) \
+ { \
+ LOG_INTERNAL(LOG_SEVERITY_MOD_ID(NRF_LOG_LEVEL_WARNING), __VA_ARGS__); \
+ } \
+ }
+#define NRF_LOG_INTERNAL_HEXDUMP_WARNING(p_data, len) \
+ if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= NRF_LOG_LEVEL_WARNING) && \
+ (NRF_LOG_LEVEL_WARNING <= NRF_LOG_DEFAULT_LEVEL)) \
+ { \
+ if (NRF_LOG_FILTER >= NRF_LOG_LEVEL_WARNING) \
+ { \
+ LOG_HEXDUMP(LOG_SEVERITY_MOD_ID(NRF_LOG_LEVEL_WARNING, \
+ (p_data), (len)); \
+ } \
+ }
+
+#define NRF_LOG_INTERNAL_INFO(...) \
+ if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= NRF_LOG_LEVEL_INFO) && \
+ (NRF_LOG_LEVEL_INFO <= NRF_LOG_DEFAULT_LEVEL)) \
+ { \
+ if (NRF_LOG_FILTER >= NRF_LOG_LEVEL_INFO) \
+ { \
+ LOG_INTERNAL(LOG_SEVERITY_MOD_ID(NRF_LOG_LEVEL_INFO), __VA_ARGS__); \
+ } \
+ }
+
+#define NRF_LOG_INTERNAL_RAW_INFO(...) \
+ if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= NRF_LOG_LEVEL_INFO) && \
+ (NRF_LOG_LEVEL_INFO <= NRF_LOG_DEFAULT_LEVEL)) \
+ { \
+ if (NRF_LOG_FILTER >= NRF_LOG_LEVEL_INFO) \
+ { \
+ LOG_INTERNAL(LOG_SEVERITY_MOD_ID(NRF_LOG_LEVEL_INFO | NRF_LOG_RAW), \
+ __VA_ARGS__); \
+ } \
+ }
+
+#define NRF_LOG_INTERNAL_HEXDUMP_INFO(p_data, len) \
+ if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= NRF_LOG_LEVEL_INFO) && \
+ (NRF_LOG_LEVEL_INFO <= NRF_LOG_DEFAULT_LEVEL)) \
+ { \
+ if (NRF_LOG_FILTER >= NRF_LOG_LEVEL_INFO) \
+ { \
+ LOG_HEXDUMP(LOG_SEVERITY_MOD_ID(NRF_LOG_LEVEL_INFO), \
+ (p_data), (len)); \
+ } \
+ }
+
+#define NRF_LOG_INTERNAL_RAW_HEXDUMP_INFO(p_data, len) \
+ if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= NRF_LOG_LEVEL_INFO) && \
+ (NRF_LOG_LEVEL_INFO <= NRF_LOG_DEFAULT_LEVEL)) \
+ { \
+ if (NRF_LOG_FILTER >= NRF_LOG_LEVEL_INFO) \
+ { \
+ LOG_HEXDUMP(LOG_SEVERITY_MOD_ID(NRF_LOG_LEVEL_INFO_RAW), \
+ (p_data), (len)); \
+ } \
+ }
+
+#define NRF_LOG_INTERNAL_DEBUG(...) \
+ if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= NRF_LOG_LEVEL_DEBUG) && \
+ (NRF_LOG_LEVEL_DEBUG <= NRF_LOG_DEFAULT_LEVEL)) \
+ { \
+ if (NRF_LOG_FILTER >= NRF_LOG_LEVEL_DEBUG) \
+ { \
+ LOG_INTERNAL(LOG_SEVERITY_MOD_ID(NRF_LOG_LEVEL_DEBUG), __VA_ARGS__); \
+ } \
+ }
+#define NRF_LOG_INTERNAL_HEXDUMP_DEBUG(p_data, len) \
+ if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= NRF_LOG_LEVEL_DEBUG) && \
+ (NRF_LOG_LEVEL_DEBUG <= NRF_LOG_DEFAULT_LEVEL)) \
+ { \
+ if (NRF_LOG_FILTER >= NRF_LOG_LEVEL_DEBUG) \
+ { \
+ LOG_HEXDUMP(LOG_SEVERITY_MOD_ID(NRF_LOG_LEVEL_DEBUG), \
+ (p_data), (len)); \
+ } \
+ }
+
+#if NRF_MODULE_ENABLED(NRF_LOG)
+#define NRF_LOG_INTERNAL_GETCHAR() nrf_log_getchar()
+#else
+#define NRF_LOG_INTERNAL_GETCHAR() (void)
+#endif
+
+typedef struct
+{
+ uint16_t module_id;
+ uint16_t order_idx;
+ uint32_t filter;
+ uint32_t filter_lvls;
+} nrf_log_module_dynamic_data_t;
+
+typedef struct
+{
+ const char * p_module_name;
+ uint8_t info_color_id;
+ uint8_t debug_color_id;
+ uint8_t compiled_lvl;
+} nrf_log_module_const_data_t;
+
+extern nrf_log_module_dynamic_data_t NRF_LOG_MODULE_DATA_DYNAMIC;
+
+/**
+ * Set of macros for encoding and decoding header for log entries.
+ * There are 3 types of entries:
+ * 1. Standard entry (STD)
+ * An entry consists of header, pointer to string and values. Header contains
+ * severity leveland determines number of arguments and thus size of the entry.
+ * Since flash address space starts from 0x00000000 and is limited to kB rather
+ * than MB 22 bits are used to store the address (4MB). It is used that way to
+ * save one RAM memory.
+ *
+ * --------------------------------
+ * |TYPE|SEVERITY|NARGS| P_STR |
+ * |------------------------------|
+ * | Module_ID (optional) |
+ * |------------------------------|
+ * | TIMESTAMP (optional) |
+ * |------------------------------|
+ * | ARG0 |
+ * |------------------------------|
+ * | .... |
+ * |------------------------------|
+ * | ARG(nargs-1) |
+ * --------------------------------
+ *
+ * 2. Hexdump entry (HEXDUMP) is used for dumping raw data. An entry consists of
+ * header, optional timestamp, pointer to string and data. A header contains
+ * length (10bit) and offset which is updated after backend processes part of
+ * data.
+ *
+ * --------------------------------
+ * |TYPE|SEVERITY|NARGS|OFFSET|LEN|
+ * |------------------------------|
+ * | Module_ID (optional) |
+ * |------------------------------|
+ * | TIMESTAMP (optional) |
+ * |------------------------------|
+ * | P_STR |
+ * |------------------------------|
+ * | data |
+ * |------------------------------|
+ * | data | dummy |
+ * --------------------------------
+ *
+ * 3. Pushed string. If string is pushed into the logger internal buffer it is
+ * stored as PUSHED entry. It consists of header, unused data (optional) and
+ * string. Unused data is present if string does not not fit into a buffer
+ * without wrapping (and string cannot be wrapped). In that case header
+ * contains information about offset.
+ *
+ * --------------------------------
+ * |TYPE| OFFSET | LEN |
+ * |------------------------------|
+ * | OFFSET |
+ * |------------------------------|
+ * end| OFFSET |
+ * 0|------------------------------|
+ * | STRING |
+ * |------------------------------|
+ * | STRING | dummy |
+ * --------------------------------
+ */
+
+#define STD_ADDR_MASK ((uint32_t)(1U << 22) - 1U)
+#define HEADER_TYPE_STD 1U
+#define HEADER_TYPE_HEXDUMP 2U
+#define HEADER_TYPE_PUSHED 0U
+#define HEADER_TYPE_INVALID 3U
+
+typedef struct
+{
+ uint32_t type : 2;
+ uint32_t raw : 1;
+ uint32_t data : 29;
+} nrf_log_generic_header_t;
+
+typedef struct
+{
+ uint32_t type : 2;
+ uint32_t raw : 1;
+ uint32_t severity : 3;
+ uint32_t nargs : 4;
+ uint32_t addr : 22;
+} nrf_log_std_header_t;
+
+typedef struct
+{
+ uint32_t type : 2;
+ uint32_t raw : 1;
+ uint32_t severity : 3;
+ uint32_t offset : 10;
+ uint32_t reserved : 6;
+ uint32_t len : 10;
+} nrf_log_hexdump_header_t;
+
+typedef struct
+{
+ uint32_t type : 2;
+ uint32_t reserved0 : 4;
+ uint32_t offset : 10;
+ uint32_t reserved1 : 6;
+ uint32_t len : 10;
+} nrf_log_pushed_header_t;
+
+typedef struct
+{
+ union {
+ nrf_log_generic_header_t generic;
+ nrf_log_std_header_t std;
+ nrf_log_hexdump_header_t hexdump;
+ nrf_log_pushed_header_t pushed;
+ uint32_t raw;
+ } base;
+ uint32_t module_id;
+ uint32_t timestamp;
+} nrf_log_header_t;
+
+#define HEADER_SIZE (sizeof(nrf_log_header_t)/sizeof(uint32_t) - \
+ (NRF_LOG_USES_TIMESTAMP ? 0 : 1))
+
+#define PUSHED_HEADER_SIZE (sizeof(nrf_log_pushed_header_t)/sizeof(uint32_t))
+
+//Implementation assumes that pushed header has one word.
+STATIC_ASSERT(PUSHED_HEADER_SIZE == 1);
+/**
+ * @brief A function for logging raw string.
+ *
+ * @param severity_mid Severity.
+ * @param p_str A pointer to a string.
+ */
+void nrf_log_frontend_std_0(uint32_t severity_mid, char const * const p_str);
+
+/**
+ * @brief A function for logging a formatted string with one argument.
+ *
+ * @param severity_mid Severity.
+ * @param p_str A pointer to a formatted string.
+ * @param val0 An argument.
+ */
+void nrf_log_frontend_std_1(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0);
+
+/**
+ * @brief A function for logging a formatted string with 2 arguments.
+ *
+ * @param severity_mid Severity.
+ * @param p_str A pointer to a formatted string.
+ * @param val0, val1 Arguments for formatting string.
+ */
+void nrf_log_frontend_std_2(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0,
+ uint32_t val1);
+
+/**
+ * @brief A function for logging a formatted string with 3 arguments.
+ *
+ * @param severity_mid Severity.
+ * @param p_str A pointer to a formatted string.
+ * @param val0, val1, val2 Arguments for formatting string.
+ */
+void nrf_log_frontend_std_3(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0,
+ uint32_t val1,
+ uint32_t val2);
+
+/**
+ * @brief A function for logging a formatted string with 4 arguments.
+ *
+ * @param severity_mid Severity.
+ * @param p_str A pointer to a formatted string.
+ * @param val0, val1, val2, val3 Arguments for formatting string.
+ */
+void nrf_log_frontend_std_4(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0,
+ uint32_t val1,
+ uint32_t val2,
+ uint32_t val3);
+
+/**
+ * @brief A function for logging a formatted string with 5 arguments.
+ *
+ * @param severity_mid Severity.
+ * @param p_str A pointer to a formatted string.
+ * @param val0, val1, val2, val3, val4 Arguments for formatting string.
+ */
+void nrf_log_frontend_std_5(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0,
+ uint32_t val1,
+ uint32_t val2,
+ uint32_t val3,
+ uint32_t val4);
+
+/**
+ * @brief A function for logging a formatted string with 6 arguments.
+ *
+ * @param severity_mid Severity.
+ * @param p_str A pointer to a formatted string.
+ * @param val0, val1, val2, val3, val4, val5 Arguments for formatting string.
+ */
+void nrf_log_frontend_std_6(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0,
+ uint32_t val1,
+ uint32_t val2,
+ uint32_t val3,
+ uint32_t val4,
+ uint32_t val5);
+
+/**
+ * @brief A function for logging raw data.
+ *
+ * @param severity_mid Severity.
+ * @param p_str A pointer to a string which is prefixing the data.
+ * @param p_data A pointer to data to be dumped.
+ * @param length Length of data (in bytes).
+ *
+ */
+void nrf_log_frontend_hexdump(uint32_t severity_mid,
+ const void * const p_data,
+ uint16_t length);
+
+/**
+ * @brief A function for reading a byte from log backend.
+ *
+ * @return Byte.
+ */
+uint8_t nrf_log_getchar(void);
+#endif // NRF_LOG_INTERNAL_H__
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_str_formatter.c b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_str_formatter.c
new file mode 100644
index 000000000..accdf224f
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_log/src/nrf_log_str_formatter.c
@@ -0,0 +1,209 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_LOG)
+#include "nrf_log_str_formatter.h"
+#include "nrf_log_internal.h"
+#include "nrf_log_ctrl.h"
+#include "nrf_fprintf.h"
+#include <ctype.h>
+
+#define NRF_LOG_COLOR_CODE_DEFAULT "\x1B[0m"
+#define NRF_LOG_COLOR_CODE_BLACK "\x1B[1;30m"
+#define NRF_LOG_COLOR_CODE_RED "\x1B[1;31m"
+#define NRF_LOG_COLOR_CODE_GREEN "\x1B[1;32m"
+#define NRF_LOG_COLOR_CODE_YELLOW "\x1B[1;33m"
+#define NRF_LOG_COLOR_CODE_BLUE "\x1B[1;34m"
+#define NRF_LOG_COLOR_CODE_MAGENTA "\x1B[1;35m"
+#define NRF_LOG_COLOR_CODE_CYAN "\x1B[1;36m"
+#define NRF_LOG_COLOR_CODE_WHITE "\x1B[1;37m"
+
+static const char * severity_names[] = {
+ NULL,
+ "error",
+ "warning",
+ "info",
+ "debug"
+};
+
+static const char * m_colors[] = {
+ NRF_LOG_COLOR_CODE_DEFAULT,
+ NRF_LOG_COLOR_CODE_BLACK,
+ NRF_LOG_COLOR_CODE_RED,
+ NRF_LOG_COLOR_CODE_GREEN,
+ NRF_LOG_COLOR_CODE_YELLOW,
+ NRF_LOG_COLOR_CODE_BLUE,
+ NRF_LOG_COLOR_CODE_MAGENTA,
+ NRF_LOG_COLOR_CODE_CYAN,
+ NRF_LOG_COLOR_CODE_WHITE,
+};
+
+static void prefix_process(nrf_log_str_formatter_entry_params_t * p_params,
+ nrf_fprintf_ctx_t * p_ctx)
+{
+ if (!(p_params->raw))
+ {
+ if (p_params->use_colors)
+ {
+ nrf_fprintf(p_ctx, "%s",
+ m_colors[nrf_log_color_id_get( p_params->module_id, p_params->severity)]);
+ }
+
+ if (NRF_LOG_USES_TIMESTAMP)
+ {
+ nrf_fprintf(p_ctx, "[%08lu] ", p_params->timestamp);
+ }
+
+ nrf_fprintf(p_ctx, "<%s> %s: ",
+ severity_names[p_params->severity], nrf_log_module_name_get(p_params->module_id, false));
+ }
+}
+
+static void postfix_process(nrf_log_str_formatter_entry_params_t * p_params,
+ nrf_fprintf_ctx_t * p_ctx,
+ bool newline)
+{
+ if (!p_params->raw)
+ {
+ if (p_params->use_colors)
+ {
+ nrf_fprintf(p_ctx, "%s", m_colors[0]);
+ }
+ nrf_fprintf(p_ctx, "\r\n");
+ }
+ else if (newline)
+ {
+ nrf_fprintf(p_ctx, "\r\n");
+ }
+ nrf_fprintf_buffer_flush(p_ctx);
+}
+
+void nrf_log_std_entry_process(char const * p_str,
+ uint32_t const * p_args,
+ uint32_t nargs,
+ nrf_log_str_formatter_entry_params_t * p_params,
+ nrf_fprintf_ctx_t * p_ctx)
+{
+ bool auto_flush = p_ctx->auto_flush;
+ p_ctx->auto_flush = false;
+
+ prefix_process(p_params, p_ctx);
+
+ switch (nargs)
+ {
+ case 0:
+ nrf_fprintf(p_ctx, p_str);
+ break;
+ case 1:
+ nrf_fprintf(p_ctx, p_str, p_args[0]);
+ break;
+ case 2:
+ nrf_fprintf(p_ctx, p_str, p_args[0], p_args[1]);
+ break;
+ case 3:
+ nrf_fprintf(p_ctx, p_str, p_args[0], p_args[1], p_args[2]);
+ break;
+ case 4:
+ nrf_fprintf(p_ctx, p_str, p_args[0], p_args[1], p_args[2], p_args[3]);
+ break;
+ case 5:
+ nrf_fprintf(p_ctx, p_str, p_args[0], p_args[1], p_args[2], p_args[3], p_args[4]);
+ break;
+ case 6:
+ nrf_fprintf(p_ctx, p_str, p_args[0], p_args[1], p_args[2], p_args[3], p_args[4], p_args[5]);
+ break;
+
+ default:
+ break;
+ }
+
+ postfix_process(p_params, p_ctx, false);
+ p_ctx->auto_flush = auto_flush;
+}
+
+#define HEXDUMP_BYTES_IN_LINE 8
+
+void nrf_log_hexdump_entry_process(uint8_t * p_data,
+ uint32_t data_len,
+ nrf_log_str_formatter_entry_params_t * p_params,
+ nrf_fprintf_ctx_t * p_ctx)
+{
+ if (data_len > HEXDUMP_BYTES_IN_LINE)
+ {
+ return;
+ }
+ bool auto_flush = p_ctx->auto_flush;
+ p_ctx->auto_flush = false;
+
+ prefix_process(p_params, p_ctx);
+
+ uint32_t i;
+
+ for (i = 0; i < HEXDUMP_BYTES_IN_LINE; i++)
+ {
+ if (i < data_len)
+ {
+ nrf_fprintf(p_ctx, " %02x", p_data[i]);
+ }
+ else
+ {
+ nrf_fprintf(p_ctx, " ");
+ }
+ }
+ nrf_fprintf(p_ctx, "|");
+
+ for (i = 0; i < HEXDUMP_BYTES_IN_LINE; i++)
+ {
+ if (i < data_len)
+ {
+ char c = (char)p_data[i];
+ nrf_fprintf(p_ctx, "%c", isprint((int)c) ? c :'.');
+ }
+ else
+ {
+ nrf_fprintf(p_ctx, " ");
+ }
+ }
+
+ postfix_process(p_params, p_ctx, true);
+
+ p_ctx->auto_flush = auto_flush;
+}
+#endif //NRF_LOG_ENABLED
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/experimental_memobj/nrf_memobj.c b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_memobj/nrf_memobj.c
new file mode 100644
index 000000000..4d7deef08
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_memobj/nrf_memobj.c
@@ -0,0 +1,231 @@
+/**
+ * Copyright (c) 2017 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "nrf_memobj.h"
+#include "nrf_atomic.h"
+#include "nrf_assert.h"
+
+typedef struct memobj_elem_s memobj_elem_t;
+
+typedef struct
+{
+ memobj_elem_t * p_next;
+} memobj_header_t;
+
+typedef struct
+{
+ uint8_t user_cnt;
+ uint8_t chunk_cnt;
+ uint16_t chunk_size;
+} memobj_head_header_fields_t;
+
+typedef struct
+{
+ union
+ {
+ nrf_atomic_u32_t atomic_user_cnt;
+ memobj_head_header_fields_t fields;
+ } data;
+} memobj_head_header_t;
+
+typedef struct
+{
+ memobj_header_t header;
+ memobj_head_header_t head_header;
+ uint8_t data[1];
+} memobj_head_t;
+
+STATIC_ASSERT(sizeof(memobj_header_t) == NRF_MEMOBJ_STD_HEADER_SIZE);
+
+struct memobj_elem_s
+{
+ memobj_header_t header;
+ uint8_t data[1];
+};
+
+ret_code_t nrf_memobj_pool_init(nrf_memobj_pool_t const * p_pool)
+{
+ return nrf_balloc_init((nrf_balloc_t const *)p_pool);
+}
+
+nrf_memobj_t * nrf_memobj_alloc(nrf_memobj_pool_t const * p_pool,
+ size_t size)
+{
+ uint32_t bsize = (uint32_t)NRF_BALLOC_ELEMENT_SIZE((nrf_balloc_t const *)p_pool) - sizeof(memobj_header_t);
+ uint8_t num_of_chunks = (uint8_t)CEIL_DIV(size + sizeof(memobj_head_header_t), bsize);
+
+ memobj_head_t * p_head = nrf_balloc_alloc((nrf_balloc_t const *)p_pool);
+ if (p_head == NULL)
+ {
+ return NULL;
+ }
+ p_head->head_header.data.fields.user_cnt = 0;
+ p_head->head_header.data.fields.chunk_cnt = 1;
+ p_head->head_header.data.fields.chunk_size = bsize;
+
+ memobj_header_t * p_prev = (memobj_header_t *)p_head;
+ memobj_header_t * p_curr;
+ uint32_t i;
+ uint32_t chunk_less1 = (uint32_t)num_of_chunks - 1;
+
+ p_prev->p_next = (memobj_elem_t *)p_pool;
+ for (i = 0; i < chunk_less1; i++)
+ {
+ p_curr = (memobj_header_t *)nrf_balloc_alloc((nrf_balloc_t const *)p_pool);
+ if (p_curr)
+ {
+ (p_head->head_header.data.fields.chunk_cnt)++;
+ p_prev->p_next = (memobj_elem_t *)p_curr;
+ p_curr->p_next = (memobj_elem_t *)p_pool;
+ p_prev = p_curr;
+ }
+ else
+ {
+ //Couldn't allocate all requested buffers
+ nrf_memobj_free((nrf_memobj_t *)p_head);
+ return NULL;
+ }
+ }
+ return (nrf_memobj_t *)p_head;
+}
+
+void nrf_memobj_free(nrf_memobj_t * p_obj)
+{
+ memobj_head_t * p_head = (memobj_head_t *)p_obj;
+ uint8_t chunk_cnt = p_head->head_header.data.fields.chunk_cnt;
+ uint32_t i;
+ memobj_header_t * p_curr = (memobj_header_t *)p_obj;
+ memobj_header_t * p_next;
+ uint32_t chunk_less1 = (uint32_t)chunk_cnt - 1;
+
+ for (i = 0; i < chunk_less1; i++)
+ {
+ p_curr = (memobj_header_t *)p_curr->p_next;
+ }
+ nrf_balloc_t const * p_pool2 = (nrf_balloc_t const *)p_curr->p_next;
+
+ p_curr = (memobj_header_t *)p_obj;
+ for (i = 0; i < chunk_cnt; i++)
+ {
+ p_next = (memobj_header_t *)p_curr->p_next;
+ nrf_balloc_free(p_pool2, p_curr);
+ p_curr = p_next;
+ }
+}
+
+void nrf_memobj_get(nrf_memobj_t const * p_obj)
+{
+ memobj_head_t * p_head = (memobj_head_t *)p_obj;
+ (void)nrf_atomic_u32_add(&p_head->head_header.data.atomic_user_cnt, 1);
+}
+
+void nrf_memobj_put(nrf_memobj_t * p_obj)
+{
+ memobj_head_t * p_head = (memobj_head_t *)p_obj;
+ uint32_t user_cnt = nrf_atomic_u32_sub(&p_head->head_header.data.atomic_user_cnt, 1);
+ memobj_head_header_fields_t * p_fields = (memobj_head_header_fields_t *)&user_cnt;
+ if (p_fields->user_cnt == 0)
+ {
+ nrf_memobj_free(p_obj);
+ }
+}
+
+static void memobj_op(nrf_memobj_t * p_obj,
+ void * p_data,
+ uint32_t len,
+ uint32_t offset,
+ bool read)
+{
+
+ memobj_head_t * p_head = (memobj_head_t *)p_obj;
+ uint32_t space_in_chunk = p_head->head_header.data.fields.chunk_size;
+ memobj_elem_t * p_curr_chunk = (memobj_elem_t *)p_obj;
+ uint32_t chunk_idx = (offset + sizeof(memobj_head_header_fields_t))/space_in_chunk;
+ uint32_t chunk_offset = (offset + sizeof(memobj_head_header_fields_t)) % space_in_chunk;
+
+ uint8_t chunks_expected = CEIL_DIV((offset + sizeof(memobj_head_header_fields_t) + len),
+ space_in_chunk);
+ UNUSED_VARIABLE(chunks_expected);
+ ASSERT(p_head->head_header.data.fields.chunk_cnt >= chunks_expected);
+
+ while (chunk_idx > 0)
+ {
+ p_curr_chunk = p_curr_chunk->header.p_next;
+ chunk_idx--;
+ }
+
+ uint32_t src_offset = 0;
+ uint32_t curr_cpy_size = space_in_chunk-chunk_offset;
+ curr_cpy_size = curr_cpy_size > len ? len : curr_cpy_size;
+
+ while (len)
+ {
+ if (read)
+ {
+ memcpy(&((uint8_t *)p_data)[src_offset], &p_curr_chunk->data[chunk_offset], curr_cpy_size);
+ }
+ else
+ {
+ memcpy(&p_curr_chunk->data[chunk_offset], &((uint8_t *)p_data)[src_offset], curr_cpy_size);
+ }
+ chunk_offset = 0;
+ p_curr_chunk = p_curr_chunk->header.p_next;
+ len -= curr_cpy_size;
+ src_offset += curr_cpy_size;
+ curr_cpy_size = (space_in_chunk > len) ? len : space_in_chunk;
+ }
+}
+
+void nrf_memobj_write(nrf_memobj_t * p_obj,
+ void * p_data,
+ uint32_t len,
+ uint32_t offset)
+{
+
+ memobj_op(p_obj, p_data, len, offset, false);
+}
+
+void nrf_memobj_read(nrf_memobj_t * p_obj,
+ void * p_data,
+ uint32_t len,
+ uint32_t offset)
+{
+ memobj_op(p_obj, p_data, len, offset, true);
+}
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/experimental_memobj/nrf_memobj.h b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_memobj/nrf_memobj.h
new file mode 100644
index 000000000..d3188d3bc
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_memobj/nrf_memobj.h
@@ -0,0 +1,198 @@
+/**
+ * Copyright (c) 2017 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_MEMOBJ_H
+#define NRF_MEMOBJ_H
+
+/**
+* @defgroup nrf_memobj Memory Object module
+* @{
+* @ingroup app_common
+* @brief Functions for controlling memory object
+*/
+#include <stdint.h>
+#include <stdlib.h>
+#include "sdk_errors.h"
+#include "nrf_balloc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Memory object can consist of multiple object with the same size. Each object has header and data
+ * part. First element in memory object is memory object head which has special header, remaining objects
+ * has the same header. Model of memory object is presented below.
+ *
+ * |---------------------| |---------------------| |---------------------|
+ * | head header (u32): | --->| std header - p_next |------->| p_memobj_pool |
+ * | num_of_chunks, | | |---------------------| |---------------------|
+ * | ref counter | | | | | |
+ * |---------------------| | | | | |
+ * | std header - p_next |-| | | .... | |
+ * |---------------------| | data | | data |
+ * | | | | | |
+ * | data | | | | |
+ * | | | | | |
+ * |---------------------| |---------------------| |---------------------|
+ * head mid_element last_element
+ *
+ *
+ */
+#define NRF_MEMOBJ_STD_HEADER_SIZE sizeof(uint32_t)
+
+/**
+ * @brief Macro for creating a nrf_memobj pool.
+ *
+ * Macro declares nrf_balloc object. Element in the pool contains user defined data part and
+ * memobj header.
+ */
+#define NRF_MEMOBJ_POOL_DEF(_name, _element_size, _pool_size) \
+ NRF_BALLOC_DEF(_name, ((_element_size)+NRF_MEMOBJ_STD_HEADER_SIZE), (_pool_size))
+
+/**
+ * @brief Pool of memobj.
+ */
+typedef nrf_balloc_t nrf_memobj_pool_t;
+
+/**
+ * @brief Memobj handle.
+ */
+typedef void * nrf_memobj_t;
+
+/**
+ * @brief Function for initializing the memobj pool instance.
+ *
+ * This function initializes the pool.
+ *
+ * @param[in] p_pool Pointer to the memobj pool instance structure.
+ *
+ * @return NRF_SUCCESS on success, otherwise error code.
+ */
+ret_code_t nrf_memobj_pool_init(nrf_memobj_pool_t const * p_pool);
+
+/**
+ * @brief Function for allocating memobj with requested size.
+ *
+ * Fixed length elements in the pool are linked together to provide amount of memory requested by
+ * the user. If memory object is successfully allocated then user can use memory however it is
+ * fragmented into multiple object so it has to be access through the API: @ref nrf_memobj_write,
+ * @ref nrf_memobj_read.
+ *
+ * This function initializes the pool.
+ *
+ * @param[in] p_pool Pointer to the memobj pool instance structure.
+ * @param[in] size Data size of requested object.
+ *
+ * @return Pointer to memory object or NULL if requested size cannot be allocated.
+ */
+nrf_memobj_t * nrf_memobj_alloc(nrf_memobj_pool_t const * p_pool,
+ size_t size);
+
+/**
+ * @brief Function for indicating that memory object is used and cannot be freed.
+ *
+ * Memory object can be shared and reused between multiple modules and this mechanism ensures that
+ * object is freed when no longer used by any module. Memory object has a counter which is incremented
+ * whenever this function is called. @ref nrf_memobj_put function decrements the counter.
+ *
+ * @param[in] p_obj Pointer to memory object.
+ */
+void nrf_memobj_get(nrf_memobj_t const * p_obj);
+
+
+/**
+ * @brief Function for indicated that memory object is no longer used by the module and can be freed
+ * if no other module is using it.
+ *
+ * Memory object is returned to the pool if internal counter reaches 0 after decrementing. It means
+ * that no other module is needing it anymore.
+ *
+ * @note Memory object holds pointer to the pool which was used to allocate it so it does not have
+ * to be provided explicitly to this function.
+ *
+ * @param[in] p_obj Pointer to memory object.
+ */
+void nrf_memobj_put(nrf_memobj_t * p_obj);
+
+
+/**
+ * @brief Function for forcing freeing of the memory object.
+ *
+ * @note This function should be use with caution because it can lead to undefined behavior of the
+ * modules since modules using the memory object are not aware that it has been freed.
+ *
+ * @param[in] p_obj Pointer to memory object.
+ */
+void nrf_memobj_free(nrf_memobj_t * p_obj);
+
+/**
+ * @brief Function for writing data to the memory object.
+ *
+ * @param[in] p_obj Pointer to memory object.
+ * @param[in] p_data Pointer to data to be written to the memory object.
+ * @param[in] len Amount of data to be written to the memory object.
+ * @param[in] offset Offset.
+ */
+void nrf_memobj_write(nrf_memobj_t * p_obj,
+ void * p_data,
+ uint32_t len,
+ uint32_t offset);
+
+/**
+ * @brief Function for reading data from the memory object.
+ *
+ * @param[in] p_obj Pointer to memory object.
+ * @param[in] p_data Pointer to the destination buffer.
+ * @param[in] len Amount of data to be read from the memory object.
+ * @param[in] offset Offset.
+ */
+void nrf_memobj_read(nrf_memobj_t * p_obj,
+ void * p_data,
+ uint32_t len,
+ uint32_t offset);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //NRF_MEMOBJ_H
+
+/** @} */
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/experimental_section_vars/nrf_section.h b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_section_vars/nrf_section.h
new file mode 100644
index 000000000..4ac2b3a4a
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_section_vars/nrf_section.h
@@ -0,0 +1,191 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_SECTION_H__
+#define NRF_SECTION_H__
+
+#include "nordic_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup section_vars Section variables
+ * @ingroup app_common
+ * @{
+ *
+ * @brief Section variables.
+ */
+
+//lint -save -e27 -esym(526,*)
+
+#if defined(__ICCARM__)
+// Enable IAR language extensions
+#pragma language=extended
+#endif
+
+/**@brief Macro for obtaining the address of the beginning of a section.
+ *
+ * param[in] section_name Name of the section.
+ * @hideinitializer
+ */
+#if defined(__CC_ARM)
+#define NRF_SECTION_START_ADDR(section_name) &CONCAT_2(section_name, $$Base)
+
+#elif defined(__GNUC__)
+#define NRF_SECTION_START_ADDR(section_name) &CONCAT_2(__start_, section_name)
+
+#elif defined(__ICCARM__)
+#define NRF_SECTION_START_ADDR(section_name) __section_begin(STRINGIFY(section_name))
+#endif
+
+
+/**@brief Macro for obtaining the address of the end of a section.
+ *
+ * @param[in] section_name Name of the section.
+ * @hideinitializer
+ */
+#if defined(__CC_ARM)
+#define NRF_SECTION_END_ADDR(section_name) &CONCAT_2(section_name, $$Limit)
+
+#elif defined(__GNUC__)
+#define NRF_SECTION_END_ADDR(section_name) &CONCAT_2(__stop_, section_name)
+
+#elif defined(__ICCARM__)
+#define NRF_SECTION_END_ADDR(section_name) __section_end(STRINGIFY(section_name))
+#endif
+
+
+/**@brief Macro for retrieving the length of a given section, in bytes.
+ *
+ * @param[in] section_name Name of the section.
+ * @hideinitializer
+ */
+#define NRF_SECTION_LENGTH(section_name) \
+ ((size_t)NRF_SECTION_END_ADDR(section_name) - \
+ (size_t)NRF_SECTION_START_ADDR(section_name))
+
+
+/**@brief Macro for creating a section.
+ *
+ * @param[in] section_name Name of the section.
+ * @param[in] data_type Data type of the variables to be registered in the section.
+ *
+ * @warning Data type must be word aligned to prevent padding.
+ * @hideinitializer
+ */
+#if defined(__CC_ARM)
+#define NRF_SECTION_DEF(section_name, data_type) \
+ extern data_type * CONCAT_2(section_name, $$Base); \
+ extern void * CONCAT_2(section_name, $$Limit)
+
+#elif defined(__GNUC__)
+#define NRF_SECTION_DEF(section_name, data_type) \
+ extern data_type * CONCAT_2(__start_, section_name); \
+ extern void * CONCAT_2(__stop_, section_name)
+
+#elif defined(__ICCARM__)
+#define NRF_SECTION_DEF(section_name, data_type) \
+ _Pragma(STRINGIFY(section = STRINGIFY(section_name)));
+
+#endif
+
+
+/**@brief Macro for declaring a variable and registering it in a section.
+ *
+ * @details Declares a variable and registers it in a named section. This macro ensures that the
+ * variable is not stripped away when using optimizations.
+ *
+ * @note The order in which variables are placed in a section is dependent on the order in
+ * which the linker script encounters the variables during linking.
+ *
+ * @param[in] section_name Name of the section.
+ * @param[in] section_var Variable to register in the given section.
+ * @hideinitializer
+ */
+#if defined(__CC_ARM)
+#define NRF_SECTION_ITEM_REGISTER(section_name, section_var) \
+ section_var __attribute__ ((section(STRINGIFY(section_name)))) __attribute__((used))
+
+#elif defined(__GNUC__)
+#define NRF_SECTION_ITEM_REGISTER(section_name, section_var) \
+ section_var __attribute__ ((section("." STRINGIFY(section_name)))) __attribute__((used))
+
+#elif defined(__ICCARM__)
+#define NRF_SECTION_ITEM_REGISTER(section_name, section_var) \
+ __root section_var @ STRINGIFY(section_name)
+#endif
+
+
+/**@brief Macro for retrieving a variable from a section.
+ *
+ * @warning The stored symbol can only be resolved using this macro if the
+ * type of the data is word aligned. The operation of acquiring
+ * the stored symbol relies on the size of the stored type. No
+ * padding can exist in the named section in between individual
+ * stored items or this macro will fail.
+ *
+ * @param[in] section_name Name of the section.
+ * @param[in] data_type Data type of the variable.
+ * @param[in] i Index of the variable in section.
+ * @hideinitializer
+ */
+#define NRF_SECTION_ITEM_GET(section_name, data_type, i) \
+ ((data_type*)NRF_SECTION_START_ADDR(section_name) + (i))
+
+
+/**@brief Macro for getting the number of variables in a section.
+ *
+ * @param[in] section_name Name of the section.
+ * @param[in] data_type Data type of the variables in the section.
+ * @hideinitializer
+ */
+#define NRF_SECTION_ITEM_COUNT(section_name, data_type) \
+ NRF_SECTION_LENGTH(section_name) / sizeof(data_type)
+
+/** @} */
+
+//lint -restore
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_SECTION_H__
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/experimental_section_vars/nrf_section_iter.c b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_section_vars/nrf_section_iter.c
new file mode 100644
index 000000000..a1c827eba
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_section_vars/nrf_section_iter.c
@@ -0,0 +1,125 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_SECTION_ITER)
+
+#include "nrf_section_iter.h"
+
+
+#if !defined(__GNUC__)
+static void nrf_section_iter_item_set(nrf_section_iter_t * p_iter)
+{
+ ASSERT(p_iter != NULL);
+ ASSERT(p_iter->p_set != NULL);
+ ASSERT(p_iter->p_section != NULL);
+
+ while (true)
+ {
+ if (p_iter->p_section == p_iter->p_set->p_last)
+ {
+ // End of the section set.
+ p_iter->p_item = NULL;
+ return;
+ }
+
+ if (p_iter->p_section->p_start != p_iter->p_section->p_end)
+ {
+ // Not empty section.
+ p_iter->p_item = p_iter->p_section->p_start;
+ return;
+ }
+
+ // Next section.
+ p_iter->p_section++;
+ }
+}
+#endif
+
+
+void nrf_section_iter_init(nrf_section_iter_t * p_iter, nrf_section_set_t const * p_set)
+{
+ ASSERT(p_iter != NULL);
+ ASSERT(p_set != NULL);
+
+ p_iter->p_set = p_set;
+
+#if defined(__GNUC__)
+ p_iter->p_item = p_iter->p_set->section.p_start;
+ if (p_iter->p_item == p_iter->p_set->section.p_end)
+ {
+ p_iter->p_item = NULL;
+ }
+#else
+ p_iter->p_section = p_set->p_first;
+ nrf_section_iter_item_set(p_iter);
+#endif
+}
+
+void nrf_section_iter_next(nrf_section_iter_t * p_iter)
+{
+ ASSERT(p_iter != NULL);
+ ASSERT(p_iter->p_set != NULL);
+
+ if (p_iter->p_item == NULL)
+ {
+ return;
+ }
+
+ p_iter->p_item = (void *)((size_t)(p_iter->p_item) + p_iter->p_set->item_size);
+
+#if defined(__GNUC__)
+ if (p_iter->p_item == p_iter->p_set->section.p_end)
+ {
+ p_iter->p_item = NULL;
+ }
+#else
+ ASSERT(p_iter->p_section != NULL);
+ // End of current section reached?
+ if (p_iter->p_item == p_iter->p_section->p_end)
+ {
+ p_iter->p_section++;
+ nrf_section_iter_item_set(p_iter);
+ }
+#endif
+}
+
+#endif // NRF_MODULE_ENABLED(NRF_SECTION_ITER)
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/experimental_section_vars/nrf_section_iter.h b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_section_vars/nrf_section_iter.h
new file mode 100644
index 000000000..104dc4b0d
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/experimental_section_vars/nrf_section_iter.h
@@ -0,0 +1,206 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_SECTION_ITER_H__
+#define NRF_SECTION_ITER_H__
+
+#include <stddef.h>
+#include "nrf_section.h"
+#include "nrf_assert.h"
+#include "app_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @defgroup nrf_section_iter Section variables iterator
+ * @ingroup app_common
+ * @{
+ */
+
+/**@brief Single section description structure. */
+typedef struct
+{
+ void * p_start; //!< Pointer to the start of section.
+ void * p_end; //!< Pointer to the end of section.
+} nrf_section_t;
+
+
+/**@brief Set of the sections description structure. */
+typedef struct
+{
+#if defined(__GNUC__)
+ nrf_section_t section; //!< Description of the set of sections.
+ /**<
+ * In case of GCC all sections in the set are sorted and
+ * placed in contiguous area, because they are treated as
+ * one section.
+ */
+#else
+ nrf_section_t const * p_first; //!< Pointer to the first section in the set.
+ nrf_section_t const * p_last; //!< Pointer to the last section in the set.
+#endif
+ size_t item_size; //!< Size of the single item in the section.
+} nrf_section_set_t;
+
+
+/**@brief Section iterator structure. */
+typedef struct
+{
+ nrf_section_set_t const * p_set; //!< Pointer to the appropriate section set.
+#if !defined(__GNUC__)
+ nrf_section_t const * p_section; //!< Pointer to the selected section.
+ /**<
+ * In case of GCC all sections in the set are sorted and
+ * placed in contiguous area, because they are treated
+ * as one section.
+ */
+#endif
+ void * p_item; //!< Pointer to the selected item in the section.
+} nrf_section_iter_t;
+
+
+/**@brief Create a set of sections.
+ *
+ * @note This macro reserves memory for the given set of sections.
+ *
+ * @details A set of sections, is an ordered collections of sections.
+ *
+ * @param[in] _name Name of the set.
+ * @param[in] _type Type of the elements stored in the sections.
+ * @param[in] _count Number of the sections in the set. This parameter is ignored in case of GCC.
+ * @hideinitializer
+ */
+#if defined(__GNUC__)
+
+#define NRF_SECTION_SET_DEF(_name, _type, _count) \
+ \
+ NRF_SECTION_DEF(_name, _type); \
+ static nrf_section_set_t const _name = \
+ { \
+ .section = \
+ { \
+ .p_start = NRF_SECTION_START_ADDR(_name), \
+ .p_end = NRF_SECTION_END_ADDR(_name), \
+ }, \
+ .item_size = sizeof(_type), \
+ }
+
+#else
+
+#define NRF_SECTION_SET_DEF(_name, _type, _count) \
+/*lint -save -emacro(14, MACRO_REPEAT_FOR*) */ \
+MACRO_REPEAT_FOR(_count, NRF_SECTION_DEF_, _name, _type) \
+static nrf_section_t const CONCAT_2(_name, _array)[] = \
+{ \
+ MACRO_REPEAT_FOR(_count, NRF_SECTION_SET_DEF_, _name) \
+}; \
+/*lint -restore */ \
+static nrf_section_set_t const _name = \
+{ \
+ .p_first = CONCAT_2(_name, _array), \
+ .p_last = CONCAT_2(_name, _array) + ARRAY_SIZE(CONCAT_2(_name, _array)), \
+ .item_size = sizeof(_type), \
+}
+
+#ifndef DOXYGEN
+#define NRF_SECTION_DEF_(_priority, _name, _type) \
+NRF_SECTION_DEF(CONCAT_2(_name, _priority), _type);
+
+#define NRF_SECTION_SET_DEF_(_priority, _name) \
+{ \
+ .p_start = NRF_SECTION_START_ADDR(CONCAT_2(_name, _priority)), \
+ .p_end = NRF_SECTION_END_ADDR(CONCAT_2(_name, _priority)), \
+},
+#endif // DOXYGEN
+#endif // __GNUC__
+
+
+/**@brief Macro to declare a variable and register it in the section set.
+ *
+ * @note The order of the section in the set is based on the priority. The order with which
+ * variables are placed in a section is dependant on the order with which the linker
+ * encouters the variables during linking.
+ *
+ * @param[in] _name Name of the section set.
+ * @param[in] _priority Priority of the desired section.
+ * @param[in] _var The variable to register in the given section.
+ * @hideinitializer
+ */
+#define NRF_SECTION_SET_ITEM_REGISTER(_name, _priority, _var) \
+ NRF_SECTION_ITEM_REGISTER(CONCAT_2(_name, _priority), _var)
+
+
+/**@brief Function for initializing the section set iterator.
+ *
+ * @param[in] p_iter Pointer to the iterator.
+ * @param[in] p_set Pointer to the sections set.
+ */
+void nrf_section_iter_init(nrf_section_iter_t * p_iter, nrf_section_set_t const * p_set);
+
+
+/**@brief Function for incrementing iterator.
+ *
+ * @param[in] p_iter Pointer to the iterator.
+ */
+void nrf_section_iter_next(nrf_section_iter_t * p_iter);
+
+
+/**@brief Function for getting the element pointed to by the iterator.
+ *
+ * @param[in] p_iter Pointer to the iterator.
+ *
+ * @retval Pointer to the element or NULL if iterator points end of the set.
+ */
+static inline void * nrf_section_iter_get(nrf_section_iter_t const * p_iter)
+{
+ ASSERT(p_iter);
+ return p_iter->p_item;
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_SECTION_ITER_H__
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/strerror/nrf_strerror.c b/hw/mcu/nordic/nrf52/sdk/libraries/strerror/nrf_strerror.c
new file mode 100644
index 000000000..09e3fb0f2
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/strerror/nrf_strerror.c
@@ -0,0 +1,148 @@
+/**
+ * Copyright (c) 2011 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_STRERROR)
+#include "nrf_strerror.h"
+
+/**
+ * @brief Macro for adding an entity to the description array.
+ *
+ * Macro that helps to create a single entity in the description array.
+ */
+#define NRF_STRERROR_ENTITY(mnemonic) {.code = mnemonic, .name = #mnemonic}
+
+/**
+ * @brief Array entity element that describes an error.
+ */
+typedef struct
+{
+ ret_code_t code; /**< Error code. */
+ char const * name; /**< Descriptive name (the same as the internal error mnemonic). */
+}nrf_strerror_desc_t;
+
+/**
+ * @brief Unknown error code.
+ *
+ * The constant string used by @ref nrf_strerror_get when the error description was not found.
+ */
+static char const m_unknown_str[] = "Unknown error code";
+
+/**
+ * @brief Array with error codes.
+ *
+ * Array that describes error codes.
+ *
+ * @note It is required for this array to have error codes placed in ascending order.
+ * This condition is checked in automatic unit test before the release.
+ */
+static nrf_strerror_desc_t const nrf_strerror_array[] =
+{
+ NRF_STRERROR_ENTITY(NRF_SUCCESS),
+ NRF_STRERROR_ENTITY(NRF_ERROR_SVC_HANDLER_MISSING),
+ NRF_STRERROR_ENTITY(NRF_ERROR_SOFTDEVICE_NOT_ENABLED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_INTERNAL),
+ NRF_STRERROR_ENTITY(NRF_ERROR_NO_MEM),
+ NRF_STRERROR_ENTITY(NRF_ERROR_NOT_FOUND),
+ NRF_STRERROR_ENTITY(NRF_ERROR_NOT_SUPPORTED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_INVALID_PARAM),
+ NRF_STRERROR_ENTITY(NRF_ERROR_INVALID_STATE),
+ NRF_STRERROR_ENTITY(NRF_ERROR_INVALID_LENGTH),
+ NRF_STRERROR_ENTITY(NRF_ERROR_INVALID_FLAGS),
+ NRF_STRERROR_ENTITY(NRF_ERROR_INVALID_DATA),
+ NRF_STRERROR_ENTITY(NRF_ERROR_DATA_SIZE),
+ NRF_STRERROR_ENTITY(NRF_ERROR_TIMEOUT),
+ NRF_STRERROR_ENTITY(NRF_ERROR_NULL),
+ NRF_STRERROR_ENTITY(NRF_ERROR_FORBIDDEN),
+ NRF_STRERROR_ENTITY(NRF_ERROR_INVALID_ADDR),
+ NRF_STRERROR_ENTITY(NRF_ERROR_BUSY),
+
+ /* SDK Common errors */
+ NRF_STRERROR_ENTITY(NRF_ERROR_MODULE_NOT_INITIALZED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_MUTEX_INIT_FAILED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_MUTEX_LOCK_FAILED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_MUTEX_UNLOCK_FAILED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_MUTEX_COND_INIT_FAILED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_MODULE_ALREADY_INITIALIZED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_STORAGE_FULL),
+ NRF_STRERROR_ENTITY(NRF_ERROR_API_NOT_IMPLEMENTED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_FEATURE_NOT_ENABLED),
+
+ /* TWI error codes */
+ NRF_STRERROR_ENTITY(NRF_ERROR_DRV_TWI_ERR_OVERRUN),
+ NRF_STRERROR_ENTITY(NRF_ERROR_DRV_TWI_ERR_ANACK),
+ NRF_STRERROR_ENTITY(NRF_ERROR_DRV_TWI_ERR_DNACK)
+};
+
+
+char const * nrf_strerror_get(ret_code_t code)
+{
+ char const * p_ret = nrf_strerror_find(code);
+ return (p_ret == NULL) ? m_unknown_str : p_ret;
+}
+
+char const * nrf_strerror_find(ret_code_t code)
+{
+ nrf_strerror_desc_t const * p_start;
+ nrf_strerror_desc_t const * p_end;
+ p_start = nrf_strerror_array;
+ p_end = nrf_strerror_array + ARRAY_SIZE(nrf_strerror_array);
+
+ while (p_start < p_end)
+ {
+ nrf_strerror_desc_t const * p_mid = p_start + ((p_end - p_start) / 2);
+ ret_code_t mid_c = p_mid->code;
+ if (mid_c > code)
+ {
+ p_end = p_mid;
+ }
+ else if (mid_c < code)
+ {
+ p_start = p_mid + 1;
+ }
+ else
+ {
+ return p_mid->name;
+ }
+ }
+ return NULL;
+}
+
+#endif /* NRF_STRERROR enabled */
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/strerror/nrf_strerror.h b/hw/mcu/nordic/nrf52/sdk/libraries/strerror/nrf_strerror.h
new file mode 100644
index 000000000..f0de77d84
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/strerror/nrf_strerror.h
@@ -0,0 +1,89 @@
+/**
+ * Copyright (c) 2017 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_strerror Error code to string converter
+ * @ingroup app_common
+ *
+ * @brief Module for converting error code into a printable string.
+ * @{
+ */
+#ifndef NRF_STRERROR_H__
+#define NRF_STRERROR_H__
+
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Function for getting a printable error string.
+ *
+ * @param code Error code to convert.
+ *
+ * @note This function cannot fail.
+ * For the function that may fail with error translation, see @ref nrf_strerror_find.
+ *
+ * @return Pointer to the printable string.
+ * If the string is not found,
+ * it returns a simple string that says that the error is unknown.
+ */
+char const * nrf_strerror_get(ret_code_t code);
+
+/**
+ * @brief Function for finding a printable error string.
+ *
+ * This function gets the error string in the same way as @ref nrf_strerror_get,
+ * but if the string is not found, it returns NULL.
+ *
+ * @param code Error code to convert.
+ * @return Pointer to the printable string.
+ * If the string is not found, NULL is returned.
+ */
+char const * nrf_strerror_find(ret_code_t code);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_STRERROR_H__ */
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/util/app_error.c b/hw/mcu/nordic/nrf52/sdk/libraries/util/app_error.c
new file mode 100644
index 000000000..e50e57d22
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/util/app_error.c
@@ -0,0 +1,143 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup app_error Common application error handler
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Common application error handler.
+ */
+
+#include "nrf.h"
+#include <stdio.h>
+#include "app_error.h"
+#include "nordic_common.h"
+#include "sdk_errors.h"
+/**@brief Function for error handling, which is called when an error has occurred.
+ *
+ * @warning This handler is an example only and does not fit a final product. You need to analyze
+ * how your product is supposed to react in case of error.
+ *
+ * @param[in] error_code Error code supplied to the handler.
+ * @param[in] line_num Line number where the handler is called.
+ * @param[in] p_file_name Pointer to the file name.
+ */
+
+/*lint -save -e14 */
+void app_error_handler(ret_code_t error_code, uint32_t line_num, const uint8_t * p_file_name)
+{
+ error_info_t error_info =
+ {
+ .line_num = line_num,
+ .p_file_name = p_file_name,
+ .err_code = error_code,
+ };
+ app_error_fault_handler(NRF_FAULT_ID_SDK_ERROR, 0, (uint32_t)(&error_info));
+
+ UNUSED_VARIABLE(error_info);
+}
+
+/*lint -save -e14 */
+void app_error_handler_bare(ret_code_t error_code)
+{
+ error_info_t error_info =
+ {
+ .line_num = 0,
+ .p_file_name = NULL,
+ .err_code = error_code,
+ };
+
+ app_error_fault_handler(NRF_FAULT_ID_SDK_ERROR, 0, (uint32_t)(&error_info));
+
+ UNUSED_VARIABLE(error_info);
+}
+
+
+void app_error_save_and_stop(uint32_t id, uint32_t pc, uint32_t info)
+{
+ /* static error variables - in order to prevent removal by optimizers */
+ static volatile struct
+ {
+ uint32_t fault_id;
+ uint32_t pc;
+ uint32_t error_info;
+ assert_info_t * p_assert_info;
+ error_info_t * p_error_info;
+ ret_code_t err_code;
+ uint32_t line_num;
+ const uint8_t * p_file_name;
+ } m_error_data = {0};
+
+ // The following variable helps Keil keep the call stack visible, in addition, it can be set to
+ // 0 in the debugger to continue executing code after the error check.
+ volatile bool loop = true;
+ UNUSED_VARIABLE(loop);
+
+ m_error_data.fault_id = id;
+ m_error_data.pc = pc;
+ m_error_data.error_info = info;
+
+ switch (id)
+ {
+ case NRF_FAULT_ID_SDK_ASSERT:
+ m_error_data.p_assert_info = (assert_info_t *)info;
+ m_error_data.line_num = m_error_data.p_assert_info->line_num;
+ m_error_data.p_file_name = m_error_data.p_assert_info->p_file_name;
+ break;
+
+ case NRF_FAULT_ID_SDK_ERROR:
+ m_error_data.p_error_info = (error_info_t *)info;
+ m_error_data.err_code = m_error_data.p_error_info->err_code;
+ m_error_data.line_num = m_error_data.p_error_info->line_num;
+ m_error_data.p_file_name = m_error_data.p_error_info->p_file_name;
+ break;
+ }
+
+ UNUSED_VARIABLE(m_error_data);
+
+ // If printing is disrupted, remove the irq calls, or set the loop variable to 0 in the debugger.
+ __disable_irq();
+ while (loop);
+
+ __enable_irq();
+}
+
+/*lint -restore */
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/util/app_error.h b/hw/mcu/nordic/nrf52/sdk/libraries/util/app_error.h
new file mode 100644
index 000000000..c8c375866
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/util/app_error.h
@@ -0,0 +1,172 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup app_error Common application error handler
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Common application error handler and macros for utilizing a common error handler.
+ */
+
+#ifndef APP_ERROR_H__
+#define APP_ERROR_H__
+
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include "nrf.h"
+#include "sdk_errors.h"
+#include "nordic_common.h"
+#include "app_error_weak.h"
+#ifdef ANT_STACK_SUPPORT_REQD
+#include "ant_error.h"
+#endif // ANT_STACK_SUPPORT_REQD
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NRF_FAULT_ID_SDK_RANGE_START 0x00004000 /**< The start of the range of error IDs defined in the SDK. */
+
+/**@defgroup APP_ERROR_FAULT_IDS Fault ID types
+ * @{ */
+#define NRF_FAULT_ID_SDK_ERROR NRF_FAULT_ID_SDK_RANGE_START + 1 /**< An error stemming from a call to @ref APP_ERROR_CHECK or @ref APP_ERROR_CHECK_BOOL. The info parameter is a pointer to an @ref error_info_t variable. */
+#define NRF_FAULT_ID_SDK_ASSERT NRF_FAULT_ID_SDK_RANGE_START + 2 /**< An error stemming from a call to ASSERT (nrf_assert.h). The info parameter is a pointer to an @ref assert_info_t variable. */
+/**@} */
+
+/**@brief Structure containing info about an error of the type @ref NRF_FAULT_ID_SDK_ERROR.
+ */
+typedef struct
+{
+ uint16_t line_num; /**< The line number where the error occurred. */
+ uint8_t const * p_file_name; /**< The file in which the error occurred. */
+ uint32_t err_code; /**< The error code representing the error that occurred. */
+} error_info_t;
+
+/**@brief Structure containing info about an error of the type @ref NRF_FAULT_ID_SDK_ASSERT.
+ */
+typedef struct
+{
+ uint16_t line_num; /**< The line number where the error occurred. */
+ uint8_t const * p_file_name; /**< The file in which the error occurred. */
+} assert_info_t;
+
+/**@brief Function for error handling, which is called when an error has occurred.
+ *
+ * @param[in] error_code Error code supplied to the handler.
+ * @param[in] line_num Line number where the handler is called.
+ * @param[in] p_file_name Pointer to the file name.
+ */
+void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name);
+
+/**@brief Function for error handling, which is called when an error has occurred.
+ *
+ * @param[in] error_code Error code supplied to the handler.
+ */
+void app_error_handler_bare(ret_code_t error_code);
+
+/**@brief Function for saving the parameters and entering an eternal loop, for debug purposes.
+ *
+ * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS.
+ * @param[in] pc The program counter of the instruction that triggered the fault, or 0 if
+ * unavailable.
+ * @param[in] info Optional additional information regarding the fault. Refer to each fault
+ * identifier for details.
+ */
+void app_error_save_and_stop(uint32_t id, uint32_t pc, uint32_t info);
+
+
+/**@brief Macro for calling error handler function.
+ *
+ * @param[in] ERR_CODE Error code supplied to the error handler.
+ */
+#ifdef DEBUG
+#define APP_ERROR_HANDLER(ERR_CODE) \
+ do \
+ { \
+ app_error_handler((ERR_CODE), __LINE__, (uint8_t*) __FILE__); \
+ } while (0)
+#else
+#define APP_ERROR_HANDLER(ERR_CODE) \
+ do \
+ { \
+ app_error_handler_bare((ERR_CODE)); \
+ } while (0)
+#endif
+/**@brief Macro for calling error handler function if supplied error code any other than NRF_SUCCESS.
+ *
+ * @param[in] ERR_CODE Error code supplied to the error handler.
+ */
+#define APP_ERROR_CHECK(ERR_CODE) \
+ do \
+ { \
+ const uint32_t LOCAL_ERR_CODE = (ERR_CODE); \
+ if (LOCAL_ERR_CODE != NRF_SUCCESS) \
+ { \
+ APP_ERROR_HANDLER(LOCAL_ERR_CODE); \
+ } \
+ } while (0)
+
+/**@brief Macro for calling error handler function if supplied boolean value is false.
+ *
+ * @param[in] BOOLEAN_VALUE Boolean value to be evaluated.
+ */
+#define APP_ERROR_CHECK_BOOL(BOOLEAN_VALUE) \
+ do \
+ { \
+ const uint32_t LOCAL_BOOLEAN_VALUE = (BOOLEAN_VALUE); \
+ if (!LOCAL_BOOLEAN_VALUE) \
+ { \
+ APP_ERROR_HANDLER(0); \
+ } \
+ } while (0)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // APP_ERROR_H__
+
+/** @} */
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/util/app_error_weak.c b/hw/mcu/nordic/nrf52/sdk/libraries/util/app_error_weak.c
new file mode 100644
index 000000000..f00b36f71
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/util/app_error_weak.c
@@ -0,0 +1,109 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "app_error.h"
+
+#include "nrf_log.h"
+#include "nrf_log_ctrl.h"
+#include "nrf_strerror.h"
+
+#if defined(SOFTDEVICE_PRESENT) && SOFTDEVICE_PRESENT
+#include "nrf_sdm.h"
+#endif
+
+/*lint -save -e14 */
+
+/**
+ * Function is implemented as weak so that it can be overwritten by custom application error handler
+ * when needed.
+ */
+__WEAK void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info)
+{
+ NRF_LOG_FINAL_FLUSH();
+
+#ifndef DEBUG
+ NRF_LOG_ERROR("Fatal error");
+#else
+ switch (id)
+ {
+#if defined(SOFTDEVICE_PRESENT) && SOFTDEVICE_PRESENT
+ case NRF_FAULT_ID_SD_ASSERT:
+ NRF_LOG_ERROR("SOFTDEVICE: ASSERTION FAILED");
+ break;
+ case NRF_FAULT_ID_APP_MEMACC:
+ NRF_LOG_ERROR("SOFTDEVICE: INVALID MEMORY ACCESS");
+ break;
+#endif
+ case NRF_FAULT_ID_SDK_ASSERT:
+ {
+ assert_info_t * p_info = (assert_info_t *)info;
+ NRF_LOG_ERROR("ASSERTION FAILED at %s:%u",
+ p_info->p_file_name,
+ p_info->line_num);
+ break;
+ }
+ case NRF_FAULT_ID_SDK_ERROR:
+ {
+ error_info_t * p_info = (error_info_t *)info;
+ NRF_LOG_ERROR("ERROR %u [%s] at %s:%u",
+ p_info->err_code,
+ nrf_strerror_get(p_info->err_code),
+ p_info->p_file_name,
+ p_info->line_num);
+ break;
+ }
+ default:
+ NRF_LOG_ERROR("UNKNOWN FAULT at 0x%08X", pc);
+ break;
+ }
+#endif
+
+ NRF_BREAKPOINT_COND;
+ // On assert, the system can only recover with a reset.
+
+#ifndef DEBUG
+ NRF_LOG_WARNING("System reset");
+ NVIC_SystemReset();
+#else
+ app_error_save_and_stop(id, pc, info);
+#endif // DEBUG
+}
+
+/*lint -restore */
+
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/util/app_error_weak.h b/hw/mcu/nordic/nrf52/sdk/libraries/util/app_error_weak.h
new file mode 100644
index 000000000..fa49dc3f0
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/util/app_error_weak.h
@@ -0,0 +1,85 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_ERROR_WEAK_H__
+#define APP_ERROR_WEAK_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @file
+ *
+ * @defgroup app_error Common application error handler
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Common application error handler.
+ */
+
+/**@brief Callback function for errors, asserts, and faults.
+ *
+ * @details This function is called every time an error is raised in app_error, nrf_assert, or
+ * in the SoftDevice. Information about the error can be found in the @p info
+ * parameter.
+ *
+ * See also @ref nrf_fault_handler_t for more details.
+ *
+ * @note The function is implemented as weak so that it can be redefined by a custom error
+ * handler when needed.
+ *
+ * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS.
+ * @param[in] pc The program counter of the instruction that triggered the fault, or 0 if
+ * unavailable.
+ * @param[in] info Optional additional information regarding the fault. The value of the @p id
+ * parameter dictates how to interpret this parameter. Refer to the documentation
+ * for each fault identifier (@ref NRF_FAULT_IDS and @ref APP_ERROR_FAULT_IDS) for
+ * details about interpreting @p info.
+ */
+void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info);
+
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // APP_ERROR_WEAK_H__
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/util/app_util.h b/hw/mcu/nordic/nrf52/sdk/libraries/util/app_util.h
new file mode 100644
index 000000000..a8ffba29f
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/util/app_util.h
@@ -0,0 +1,1082 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup app_util Utility Functions and Definitions
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Various types and definitions available to all applications.
+ */
+
+#ifndef APP_UTIL_H__
+#define APP_UTIL_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include "compiler_abstraction.h"
+#include "nordic_common.h"
+#include "nrf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//lint -save -e27 -e10 -e19
+#if defined ( __CC_ARM ) && !defined (__LINT__)
+extern char STACK$$Base;
+extern char STACK$$Length;
+#define STACK_BASE &STACK$$Base
+#define STACK_TOP ((void*)((uint32_t)STACK_BASE + (uint32_t)&STACK$$Length))
+#elif defined ( __ICCARM__ )
+extern char CSTACK$$Base;
+extern char CSTACK$$Length;
+#define STACK_BASE &CSTACK$$Base
+#define STACK_TOP ((void*)((uint32_t)STACK_BASE + (uint32_t)&CSTACK$$Length))
+#elif defined ( __GNUC__ )
+extern uint32_t __StackTop;
+extern uint32_t __StackLimit;
+#define STACK_BASE &__StackLimit
+#define STACK_TOP &__StackTop
+#endif
+//lint -restore
+
+enum
+{
+ UNIT_0_625_MS = 625, /**< Number of microseconds in 0.625 milliseconds. */
+ UNIT_1_25_MS = 1250, /**< Number of microseconds in 1.25 milliseconds. */
+ UNIT_10_MS = 10000 /**< Number of microseconds in 10 milliseconds. */
+};
+
+
+/*Segger embedded studio originally has offsetof macro which cannot be used in macros (like STATIC_ASSERT).
+ This redefinition is to allow using that. */
+#if defined(__SES_ARM) && defined(__GNUC__)
+#undef offsetof
+#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
+#endif
+
+/**@brief Implementation specific macro for delayed macro expansion used in string concatenation
+*
+* @param[in] lhs Left hand side in concatenation
+* @param[in] rhs Right hand side in concatenation
+*/
+#define STRING_CONCATENATE_IMPL(lhs, rhs) lhs ## rhs
+
+
+/**@brief Macro used to concatenate string using delayed macro expansion
+*
+* @note This macro will delay concatenation until the expressions have been resolved
+*
+* @param[in] lhs Left hand side in concatenation
+* @param[in] rhs Right hand side in concatenation
+*/
+#define STRING_CONCATENATE(lhs, rhs) STRING_CONCATENATE_IMPL(lhs, rhs)
+
+
+#ifndef __LINT__
+
+#ifdef __GNUC__
+#define STATIC_ASSERT_SIMPLE(EXPR) _Static_assert(EXPR, "unspecified message")
+#define STATIC_ASSERT_MSG(EXPR, MSG) _Static_assert(EXPR, MSG)
+#endif
+
+#ifdef __CC_ARM
+#define STATIC_ASSERT_SIMPLE(EXPR) extern char (*_do_assert(void)) [sizeof(char[1 - 2*!(EXPR)])]
+#define STATIC_ASSERT_MSG(EXPR, MSG) extern char (*_do_assert(void)) [sizeof(char[1 - 2*!(EXPR)])]
+#endif
+
+#ifdef __ICCARM__
+#define STATIC_ASSERT_SIMPLE(EXPR) static_assert(EXPR, "unspecified message")
+#define STATIC_ASSERT_MSG(EXPR, MSG) static_assert(EXPR, MSG)
+#endif
+
+#else // __LINT__
+
+#define STATIC_ASSERT_SIMPLE(EXPR) extern char (*_ignore(void))
+#define STATIC_ASSERT_MSG(EXPR, MSG) extern char (*_ignore(void))
+
+#endif
+
+
+#define _SELECT_ASSERT_FUNC(x, EXPR, MSG, ASSERT_MACRO, ...) ASSERT_MACRO
+
+/**
+ * @brief Static (i.e. compile time) assert macro.
+ *
+ * @note The output of STATIC_ASSERT can be different across compilers.
+ *
+ * Usage:
+ * STATIC_ASSERT(expression);
+ * STATIC_ASSERT(expression, message);
+ *
+ * @hideinitializer
+ */
+//lint -save -esym(???, STATIC_ASSERT)
+#define STATIC_ASSERT(...) \
+ _SELECT_ASSERT_FUNC(x, ##__VA_ARGS__, \
+ STATIC_ASSERT_MSG(__VA_ARGS__), \
+ STATIC_ASSERT_SIMPLE(__VA_ARGS__))
+//lint -restore
+
+
+/**@brief Implementation details for NUM_VAR_ARGS */
+#define NUM_VA_ARGS_IMPL( \
+ _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \
+ _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \
+ _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \
+ _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \
+ _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \
+ _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, \
+ _61, _62, N, ...) N
+
+
+/**@brief Macro to get the number of arguments in a call variadic macro call
+ *
+ * param[in] ... List of arguments
+ *
+ * @retval Number of variadic arguments in the argument list
+ */
+#define NUM_VA_ARGS(...) NUM_VA_ARGS_IMPL(__VA_ARGS__, 63, 62, 61, \
+ 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, \
+ 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, \
+ 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, \
+ 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, \
+ 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, \
+ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
+
+/**@brief Implementation details for NUM_VAR_ARGS */
+#define NUM_VA_ARGS_LESS_1_IMPL( \
+ _ignored, \
+ _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \
+ _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \
+ _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \
+ _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \
+ _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \
+ _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, \
+ _61, _62, N, ...) N
+
+/**@brief Macro to get the number of arguments in a call variadic macro call.
+ * First argument is not counted.
+ *
+ * param[in] ... List of arguments
+ *
+ * @retval Number of variadic arguments in the argument list
+ */
+#define NUM_VA_ARGS_LESS_1(...) NUM_VA_ARGS_LESS_1_IMPL(__VA_ARGS__, 63, 62, 61, \
+ 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, \
+ 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, \
+ 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, \
+ 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, \
+ 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, \
+ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, ~)
+
+
+/**@brief type for holding an encoded (i.e. little endian) 16 bit unsigned integer. */
+typedef uint8_t uint16_le_t[2];
+
+/**@brief Type for holding an encoded (i.e. little endian) 32 bit unsigned integer. */
+typedef uint8_t uint32_le_t[4];
+
+/**@brief Byte array type. */
+typedef struct
+{
+ uint16_t size; /**< Number of array entries. */
+ uint8_t * p_data; /**< Pointer to array entries. */
+} uint8_array_t;
+
+
+/**@brief Macro for performing rounded integer division (as opposed to truncating the result).
+ *
+ * @param[in] A Numerator.
+ * @param[in] B Denominator.
+ *
+ * @return Rounded (integer) result of dividing A by B.
+ */
+#define ROUNDED_DIV(A, B) (((A) + ((B) / 2)) / (B))
+
+
+/**@brief Macro for checking if an integer is a power of two.
+ *
+ * @param[in] A Number to be tested.
+ *
+ * @return true if value is power of two.
+ * @return false if value not power of two.
+ */
+#define IS_POWER_OF_TWO(A) ( ((A) != 0) && ((((A) - 1) & (A)) == 0) )
+
+
+/**@brief Macro for converting milliseconds to ticks.
+ *
+ * @param[in] TIME Number of milliseconds to convert.
+ * @param[in] RESOLUTION Unit to be converted to in [us/ticks].
+ */
+#define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION))
+
+
+/**@brief Macro for performing integer division, making sure the result is rounded up.
+ *
+ * @details One typical use for this is to compute the number of objects with size B is needed to
+ * hold A number of bytes.
+ *
+ * @param[in] A Numerator.
+ * @param[in] B Denominator.
+ *
+ * @return Integer result of dividing A by B, rounded up.
+ */
+#define CEIL_DIV(A, B) \
+ (((A) + (B) - 1) / (B))
+
+
+/**@brief Macro for creating a buffer aligned to 4 bytes.
+ *
+ * @param[in] NAME Name of the buffor.
+ * @param[in] MIN_SIZE Size of this buffor (it will be rounded up to multiples of 4 bytes).
+ */
+#define WORD_ALIGNED_MEM_BUFF(NAME, MIN_SIZE) static uint32_t NAME[CEIL_DIV(MIN_SIZE, sizeof(uint32_t))]
+
+
+/**@brief Macro for calculating the number of words that are needed to hold a number of bytes.
+ *
+ * @details Adds 3 and divides by 4.
+ *
+ * @param[in] n_bytes The number of bytes.
+ *
+ * @return The number of words that @p n_bytes take up (rounded up).
+ */
+#define BYTES_TO_WORDS(n_bytes) (((n_bytes) + 3) >> 2)
+
+
+/**@brief The number of bytes in a word.
+ */
+#define BYTES_PER_WORD (4)
+
+
+/**@brief Macro for increasing a number to the nearest (larger) multiple of another number.
+ *
+ * @param[in] alignment The number to align to.
+ * @param[in] number The number to align (increase).
+ *
+ * @return The aligned (increased) @p number.
+ */
+#define ALIGN_NUM(alignment, number) ((number - 1) + alignment - ((number - 1) % alignment))
+
+/**@brief Macro for getting first of 2 parameters.
+ *
+ * @param[in] a1 First parameter.
+ * @param[in] a2 Second parameter.
+ */
+#define GET_ARG_1(a1, a2) a1
+
+/**@brief Macro for getting second of 2 parameters.
+ *
+ * @param[in] a1 First parameter.
+ * @param[in] a2 Second parameter.
+ */
+#define GET_ARG_2(a1, a2) a2
+
+
+/**@brief Container of macro (borrowed from Linux kernel).
+ *
+ * This macro returns parent structure address basing on child member address.
+ *
+ * @param ptr Address of child type.
+ * @param type Type of parent structure.
+ * @param member Name of child field in parent structure.
+ *
+ * @return Parent structure address.
+ * */
+#define CONTAINER_OF(ptr, type, member) \
+ (type *)((char *)ptr - offsetof(type, member))
+
+
+/**
+ * @brief Define Bit-field mask
+ *
+ * Macro that defined the mask with selected number of bits set, starting from
+ * provided bit number.
+ *
+ * @param[in] bcnt Number of bits in the bit-field
+ * @param[in] boff Lowest bit number
+ */
+#define BF_MASK(bcnt, boff) ( ((1U << (bcnt)) - 1U) << (boff) )
+
+/**
+ * @brief Get bit-field
+ *
+ * Macro that extracts selected bit-field from provided value
+ *
+ * @param[in] val Value from witch selected bit-field would be extracted
+ * @param[in] bcnt Number of bits in the bit-field
+ * @param[in] boff Lowest bit number
+ *
+ * @return Value of the selected bits
+ */
+#define BF_GET(val, bcnt, boff) ( ( (val) & BF_MASK((bcnt), (boff)) ) >> (boff) )
+
+/**
+ * @brief Create bit-field value
+ *
+ * Value is masked and shifted to match given bit-field
+ *
+ * @param[in] val Value to set on bit-field
+ * @param[in] bcnt Number of bits for bit-field
+ * @param[in] boff Offset of bit-field
+ *
+ * @return Value positioned of given bit-field.
+ */
+#define BF_VAL(val, bcnt, boff) ( (((uint32_t)(val)) << (boff)) & BF_MASK(bcnt, boff) )
+
+/**
+ * @name Configuration of complex bit-field
+ *
+ * @sa BF_CX
+ * @{
+ */
+/** @brief Position of bit count in complex bit-field value */
+#define BF_CX_BCNT_POS 0U
+/** @brief Mask of bit count in complex bit-field value */
+#define BF_CX_BCNT_MASK (0xffU << BF_CX_BCNT_POS)
+/** @brief Position of bit position in complex bit-field value */
+#define BF_CX_BOFF_POS 8U
+/** @brief Mask of bit position in complex bit-field value */
+#define BF_CX_BOFF_MASK (0xffU << BF_CX_BOFF_POS)
+/** @} */
+
+/**
+ * @brief Define complex bit-field
+ *
+ * Complex bit-field would contain its position and size in one number.
+ * @sa BF_CX_MASK
+ * @sa BF_CX_POS
+ * @sa BF_CX_GET
+ *
+ * @param[in] bcnt Number of bits in the bit-field
+ * @param[in] boff Lowest bit number
+ *
+ * @return The single number that describes the bit-field completely.
+ */
+#define BF_CX(bcnt, boff) ( ((((uint32_t)(bcnt)) << BF_CX_BCNT_POS) & BF_CX_BCNT_MASK) | ((((uint32_t)(boff)) << BF_CX_BOFF_POS) & BF_CX_BOFF_MASK) )
+
+/**
+ * @brief Get number of bits in bit-field
+ *
+ * @sa BF_CX
+ *
+ * @param bf_cx Complex bit-field
+ *
+ * @return Number of bits in given bit-field
+ */
+#define BF_CX_BCNT(bf_cx) ( ((bf_cx) & BF_CX_BCNT_MASK) >> BF_CX_BCNT_POS )
+
+/**
+ * @brief Get lowest bit number in the field
+ *
+ * @sa BF_CX
+ *
+ * @param[in] bf_cx Complex bit-field
+ *
+ * @return Lowest bit number in given bit-field
+ */
+#define BF_CX_BOFF(bf_cx) ( ((bf_cx) & BF_CX_BOFF_MASK) >> BF_CX_BOFF_POS )
+
+/**
+ * @brief Get bit mask of the selected field
+ *
+ * @sa BF_CX
+ *
+ * @param[in] bf_cx Complex bit-field
+ *
+ * @return Mask of given bit-field
+ */
+#define BF_CX_MASK(bf_cx) BF_MASK(BF_CX_BCNT(bf_cx), BF_CX_BOFF(bf_cx))
+
+/**
+ * @brief Get bit-field
+ *
+ * Macro that extracts selected bit-field from provided value.
+ * Bit-field is given as a complex value.
+ *
+ * @sa BF_CX
+ * @sa BF_GET
+ *
+ * @param[in] val Value from witch selected bit-field would be extracted
+ * @param[in] bf_cx Complex bit-field
+ *
+ * @return Value of the selected bits.
+ */
+#define BF_CX_GET(val, bf_cx) BF_GET(val, BF_CX_BCNT(bf_cx), BF_CX_BOFF(bf_cx))
+
+/**
+ * @brief Create bit-field value
+ *
+ * Value is masked and shifted to match given bit-field.
+ *
+ * @param[in] val Value to set on bit-field
+ * @param[in] bf_cx Complex bit-field
+ *
+ * @return Value positioned of given bit-field.
+ */
+#define BF_CX_VAL(val, bf_cx) BF_VAL(val, BF_CX_BCNT(bf_cx), BF_CX_BOFF(bf_cx))
+
+/**
+ * @brief Extracting data from the brackets
+ *
+ * This macro get rid of brackets around the argument.
+ * It can be used to pass multiple arguments in logical one argument to a macro.
+ * Call it with arguments inside brackets:
+ * @code
+ * #define ARGUMENTS (a, b, c)
+ * BRACKET_EXTRACT(ARGUMENTS)
+ * @endcode
+ * It would produce:
+ * @code
+ * a, b, c
+ * @endcode
+ *
+ * @param a Argument with anything inside brackets
+ * @return Anything that appears inside the brackets of the argument
+ *
+ * @note
+ * The argument of the macro have to be inside brackets.
+ * In other case the compilation would fail.
+ */
+#define BRACKET_EXTRACT(a) BRACKET_EXTRACT_(a)
+#define BRACKET_EXTRACT_(a) BRACKET_EXTRACT__ a
+#define BRACKET_EXTRACT__(...) __VA_ARGS__
+
+
+/**
+ * @brief Check if number of parameters is more than 1
+ *
+ * @param ... Arguments to count
+ *
+ * @return 0 If argument count is <= 1
+ * @return 1 If argument count is > 1
+ *
+ * @sa NUM_VA_ARGS
+ * @sa NUM_IS_MORE_THAN_1
+ */
+#define NUM_VA_ARGS_IS_MORE_THAN_1(...) NUM_IS_MORE_THAN_1(NUM_VA_ARGS(__VA_ARGS__))
+
+/**
+ * @brief Check if given numeric value is bigger than 1
+ *
+ * This macro accepts numeric value, that may be the result of argument expansion.
+ * This numeric value is then converted to 0 if it is lover than 1 or to 1 if
+ * its value is higher than 1.
+ * The generated result can be used to glue it into other macro mnemonic name.
+ *
+ * @param N Numeric value to check
+ *
+ * @return 0 If argument is <= 1
+ * @return 1 If argument is > 1
+ *
+ * @note Any existing definition of a form NUM_IS_MORE_THAN_1_PROBE_[N] can
+ * broke the result of this macro
+ */
+#define NUM_IS_MORE_THAN_1(N) NUM_IS_MORE_THAN_1_(N)
+#define NUM_IS_MORE_THAN_1_(N) NUM_IS_MORE_THAN_1_PROBE_(NUM_IS_MORE_THAN_1_PROBE_ ## N, 1)
+#define NUM_IS_MORE_THAN_1_PROBE_(...) GET_VA_ARG_1(GET_ARGS_AFTER_1(__VA_ARGS__))
+#define NUM_IS_MORE_THAN_1_PROBE_0 ~, 0
+#define NUM_IS_MORE_THAN_1_PROBE_1 ~, 0
+
+/**
+ * @brief Get the first argument
+ *
+ * @param ... Arguments to select
+ *
+ * @return First argument or empty if no arguments are provided
+ */
+#define GET_VA_ARG_1(...) GET_VA_ARG_1_(__VA_ARGS__, ) // Make sure that also for 1 argument it works
+#define GET_VA_ARG_1_(a1, ...) a1
+
+/**
+ * @brief Get all the arguments but the first one
+ *
+ * @param ... Arguments to select
+ *
+ * @return All arguments after the first one or empty if less than 2 arguments are provided
+ */
+#define GET_ARGS_AFTER_1(...) GET_ARGS_AFTER_1_(__VA_ARGS__, ) // Make sure that also for 1 argument it works
+#define GET_ARGS_AFTER_1_(a1, ...) __VA_ARGS__
+
+/**
+ * @brief Size of a field in declared structure
+ *
+ * Macro that returns the size of the structure field.
+ * @param struct_type Variable type to get the field size from
+ * @param field Field name to analyze. It can be even field inside field (field.somethingelse.and_another).
+ *
+ * @return Size of the field
+ */
+#define FIELD_SIZE(struct_type, field) sizeof(((struct struct_type*)NULL)->field)
+
+/**
+ * @brief Number of elements in field array in declared structure
+ *
+ * Macro that returns number of elementy in structure field.
+ * @param struct_type Variable type to get the field size from
+ * @param field Field name to analyze.
+ *
+ * @return Number of elements in field array
+ *
+ * @sa FIELD_SIZE
+ */
+#define FIELD_ARRAY_SIZE(struct_type, field) (FIELD_SIZE(struct_type, field) / FIELD_SIZE(struct_type, field[0]))
+
+/**
+ * @brief Mapping macro
+ *
+ * Macro that process all arguments using given macro
+ *
+ * @param ... Macro name to be used for argument processing followed by arguments to process.
+ * Macro should have following form: MACRO(argument)
+ *
+ * @return All arguments processed by given macro
+ */
+#define MACRO_MAP(...) MACRO_MAP_(__VA_ARGS__)
+#define MACRO_MAP_(...) MACRO_MAP_N(NUM_VA_ARGS_LESS_1(__VA_ARGS__), __VA_ARGS__) // To make sure it works also for 2 arguments in total
+
+/**
+ * @brief Mapping macro, recursive version
+ *
+ * Can be used in @ref MACRO_MAP macro
+ */
+#define MACRO_MAP_REC(...) MACRO_MAP_REC_(__VA_ARGS__)
+#define MACRO_MAP_REC_(...) MACRO_MAP_REC_N(NUM_VA_ARGS_LESS_1(__VA_ARGS__), __VA_ARGS__) // To make sure it works also for 2 arguments in total
+/**
+ * @brief Mapping N arguments macro
+ *
+ * Macro similar to @ref MACRO_MAP but maps exact number of arguments.
+ * If there is more arguments given, the rest would be ignored.
+ *
+ * @param N Number of arguments to map
+ * @param ... Macro name to be used for argument processing followed by arguments to process.
+ * Macro should have following form: MACRO(argument)
+ *
+ * @return Selected number of arguments processed by given macro
+ */
+#define MACRO_MAP_N(N, ...) MACRO_MAP_N_(N, __VA_ARGS__)
+#define MACRO_MAP_N_(N, ...) CONCAT_2(MACRO_MAP_, N)(__VA_ARGS__, )
+
+/**
+ * @brief Mapping N arguments macro, recursive version
+ *
+ * Can be used in @ref MACRO_MAP_N macro
+ */
+#define MACRO_MAP_REC_N(N, ...) MACRO_MAP_REC_N_(N, __VA_ARGS__)
+#define MACRO_MAP_REC_N_(N, ...) CONCAT_2(MACRO_MAP_REC_, N)(__VA_ARGS__, )
+
+#define MACRO_MAP_0( ...)
+#define MACRO_MAP_1( macro, a, ...) macro(a)
+#define MACRO_MAP_2( macro, a, ...) macro(a) MACRO_MAP_1 (macro, __VA_ARGS__, )
+#define MACRO_MAP_3( macro, a, ...) macro(a) MACRO_MAP_2 (macro, __VA_ARGS__, )
+#define MACRO_MAP_4( macro, a, ...) macro(a) MACRO_MAP_3 (macro, __VA_ARGS__, )
+#define MACRO_MAP_5( macro, a, ...) macro(a) MACRO_MAP_4 (macro, __VA_ARGS__, )
+#define MACRO_MAP_6( macro, a, ...) macro(a) MACRO_MAP_5 (macro, __VA_ARGS__, )
+#define MACRO_MAP_7( macro, a, ...) macro(a) MACRO_MAP_6 (macro, __VA_ARGS__, )
+#define MACRO_MAP_8( macro, a, ...) macro(a) MACRO_MAP_7 (macro, __VA_ARGS__, )
+#define MACRO_MAP_9( macro, a, ...) macro(a) MACRO_MAP_8 (macro, __VA_ARGS__, )
+#define MACRO_MAP_10(macro, a, ...) macro(a) MACRO_MAP_9 (macro, __VA_ARGS__, )
+#define MACRO_MAP_11(macro, a, ...) macro(a) MACRO_MAP_10(macro, __VA_ARGS__, )
+#define MACRO_MAP_12(macro, a, ...) macro(a) MACRO_MAP_11(macro, __VA_ARGS__, )
+#define MACRO_MAP_13(macro, a, ...) macro(a) MACRO_MAP_12(macro, __VA_ARGS__, )
+#define MACRO_MAP_14(macro, a, ...) macro(a) MACRO_MAP_13(macro, __VA_ARGS__, )
+#define MACRO_MAP_15(macro, a, ...) macro(a) MACRO_MAP_14(macro, __VA_ARGS__, )
+
+#define MACRO_MAP_REC_0( ...)
+#define MACRO_MAP_REC_1( macro, a, ...) macro(a)
+#define MACRO_MAP_REC_2( macro, a, ...) macro(a) MACRO_MAP_REC_1 (macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_3( macro, a, ...) macro(a) MACRO_MAP_REC_2 (macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_4( macro, a, ...) macro(a) MACRO_MAP_REC_3 (macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_5( macro, a, ...) macro(a) MACRO_MAP_REC_4 (macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_6( macro, a, ...) macro(a) MACRO_MAP_REC_5 (macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_7( macro, a, ...) macro(a) MACRO_MAP_REC_6 (macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_8( macro, a, ...) macro(a) MACRO_MAP_REC_7 (macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_9( macro, a, ...) macro(a) MACRO_MAP_REC_8 (macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_10(macro, a, ...) macro(a) MACRO_MAP_REC_9 (macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_11(macro, a, ...) macro(a) MACRO_MAP_REC_10(macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_12(macro, a, ...) macro(a) MACRO_MAP_REC_11(macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_13(macro, a, ...) macro(a) MACRO_MAP_REC_12(macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_14(macro, a, ...) macro(a) MACRO_MAP_REC_13(macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_15(macro, a, ...) macro(a) MACRO_MAP_REC_14(macro, __VA_ARGS__, )
+
+/**
+ * @brief Mapping macro with current index
+ *
+ * Basically macro similar to @ref MACRO_MAP, but the processing function would get an argument
+ * and current argument index (beginning from 0).
+ *
+ * @param ... Macro name to be used for argument processing followed by arguments to process.
+ * Macro should have following form: MACRO(argument, index)
+ * @return All arguments processed by given macro
+ */
+#define MACRO_MAP_FOR(...) MACRO_MAP_FOR_(__VA_ARGS__)
+#define MACRO_MAP_FOR_N_LIST 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
+#define MACRO_MAP_FOR_(...) MACRO_MAP_FOR_N(NUM_VA_ARGS_LESS_1(__VA_ARGS__), __VA_ARGS__)
+
+/**
+ * @brief Mapping N arguments macro with current index
+ *
+ * Macro is similar to @ref MACRO_MAP_FOR but maps exact number of arguments.
+ * If there is more arguments given, the rest would be ignored.
+ *
+ * @param N Number of arguments to map
+ * @param ... Macro name to be used for argument processing followed by arguments to process.
+ * Macro should have following form: MACRO(argument, index)
+ *
+ * @return Selected number of arguments processed by given macro
+ */
+#define MACRO_MAP_FOR_N(N, ...) MACRO_MAP_FOR_N_(N, __VA_ARGS__)
+#define MACRO_MAP_FOR_N_(N, ...) CONCAT_2(MACRO_MAP_FOR_, N)((MACRO_MAP_FOR_N_LIST), __VA_ARGS__, )
+
+#define MACRO_MAP_FOR_0( n_list, ...)
+#define MACRO_MAP_FOR_1( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)))
+#define MACRO_MAP_FOR_2( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_1 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_3( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_2 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_4( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_3 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_5( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_4 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_6( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_5 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_7( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_6 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_8( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_7 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_9( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_8 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_10(n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_9 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_11(n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_10((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_12(n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_11((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_13(n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_12((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_14(n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_13((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_15(n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_14((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+
+
+/**
+ * @brief Mapping macro with current index and parameter
+ *
+ * Version of @ref MACRO_MAP_FOR that passes also the same parameter to all macros.
+ *
+ * @param param Parameter that would be passed to each macro call during mapping.
+ * @param ... Macro name to be used for argument processing followed by arguments to process.
+ * Macro should have following form: MACRO(argument, index, param)
+ *
+ * @return All arguments processed by given macro
+ */
+#define MACRO_MAP_FOR_PARAM(param, ...) MACRO_MAP_FOR_PARAM_(param, __VA_ARGS__)
+#define MACRO_MAP_FOR_PARAM_(param, ...) MACRO_MAP_FOR_PARAM_N(NUM_VA_ARGS_LESS_1(__VA_ARGS__), param, __VA_ARGS__)
+
+/**
+ * @brief Mapping N arguments macro with with current index and parameter
+ *
+ * @param N Number of arguments to map
+ * @param param Parameter that would be passed to each macro call during mapping.
+ * @param ... Macro name to be used for argument processing followed by arguments to process.
+ * Macro should have following form: MACRO(argument, index, param)
+ *
+ * @return All arguments processed by given macro
+ */
+#define MACRO_MAP_FOR_PARAM_N(N, param, ...) MACRO_MAP_FOR_PARAM_N_(N, param, __VA_ARGS__)
+#define MACRO_MAP_FOR_PARAM_N_(N, param, ...) CONCAT_2(MACRO_MAP_FOR_PARAM_, N)((MACRO_MAP_FOR_N_LIST), param, __VA_ARGS__, )
+
+
+#define MACRO_MAP_FOR_PARAM_0( n_list, param, ...)
+#define MACRO_MAP_FOR_PARAM_1( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param)
+#define MACRO_MAP_FOR_PARAM_2( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_1 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_3( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_2 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_4( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_3 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_5( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_4 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_6( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_5 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_7( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_6 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_8( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_7 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_9( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_8 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_10(n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_9 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_11(n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_10((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_12(n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_11((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_13(n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_12((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_14(n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_13((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_15(n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_14((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+
+
+/**
+ * @brief Repeating macro.
+ *
+ * @param count Count of repeats.
+ * @param macro Macro must have the following form: MACRO(arguments).
+ * @param ... Arguments passed to the macro.
+ *
+ * @return All arguments processed by the given macro.
+ */
+#define MACRO_REPEAT(count, macro, ...) MACRO_REPEAT_(count, macro, __VA_ARGS__)
+#define MACRO_REPEAT_(count, macro, ...) CONCAT_2(MACRO_REPEAT_, count)(macro, __VA_ARGS__)
+
+#define MACRO_REPEAT_0(macro, ...)
+#define MACRO_REPEAT_1(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_0(macro, __VA_ARGS__)
+#define MACRO_REPEAT_2(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_1(macro, __VA_ARGS__)
+#define MACRO_REPEAT_3(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_2(macro, __VA_ARGS__)
+#define MACRO_REPEAT_4(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_3(macro, __VA_ARGS__)
+#define MACRO_REPEAT_5(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_4(macro, __VA_ARGS__)
+#define MACRO_REPEAT_6(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_5(macro, __VA_ARGS__)
+#define MACRO_REPEAT_7(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_6(macro, __VA_ARGS__)
+#define MACRO_REPEAT_8(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_7(macro, __VA_ARGS__)
+#define MACRO_REPEAT_9(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_8(macro, __VA_ARGS__)
+#define MACRO_REPEAT_10(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_9(macro, __VA_ARGS__)
+#define MACRO_REPEAT_11(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_10(macro, __VA_ARGS__)
+#define MACRO_REPEAT_12(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_11(macro, __VA_ARGS__)
+#define MACRO_REPEAT_13(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_12(macro, __VA_ARGS__)
+#define MACRO_REPEAT_14(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_13(macro, __VA_ARGS__)
+#define MACRO_REPEAT_15(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_14(macro, __VA_ARGS__)
+
+
+/**
+ * @brief Repeating macro with current index.
+ *
+ * Macro similar to @ref MACRO_REPEAT but the processing function gets the arguments
+ * and the current argument index (beginning from 0).
+
+ * @param count Count of repeats.
+ * @param macro Macro must have the following form: MACRO(index, arguments).
+ * @param ... Arguments passed to the macro.
+ *
+ * @return All arguments processed by the given macro.
+ */
+#define MACRO_REPEAT_FOR(count, macro, ...) MACRO_REPEAT_FOR_(count, macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_(count, macro, ...) CONCAT_2(MACRO_REPEAT_FOR_, count)((MACRO_MAP_FOR_N_LIST), macro, __VA_ARGS__)
+
+#define MACRO_REPEAT_FOR_0(n_list, macro, ...)
+#define MACRO_REPEAT_FOR_1(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_0((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_2(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_1((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_3(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_2((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_4(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_3((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_5(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_4((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_6(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_5((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_7(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_6((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_8(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_7((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_9(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_8((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_10(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_9((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_11(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_10((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_12(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_11((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_13(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_12((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_14(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_13((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_15(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_14((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+
+/**@brief Adding curly brace to the macro parameter.
+ *
+ * Useful in array of structures initialization.
+ *
+ * @param p Parameter to put into the curly brace. */
+#define PARAM_CBRACE(p) { p },
+
+
+/**@brief Function for changing the value unit.
+ *
+ * @param[in] value Value to be rescaled.
+ * @param[in] old_unit_reversal Reversal of the incoming unit.
+ * @param[in] new_unit_reversal Reversal of the desired unit.
+ *
+ * @return Number of bytes written.
+ */
+static __INLINE uint64_t value_rescale(uint32_t value, uint32_t old_unit_reversal, uint16_t new_unit_reversal)
+{
+ return (uint64_t)ROUNDED_DIV((uint64_t)value * new_unit_reversal, old_unit_reversal);
+}
+
+/**@brief Function for encoding a uint16 value.
+ *
+ * @param[in] value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data is to be written.
+ *
+ * @return Number of bytes written.
+ */
+static __INLINE uint8_t uint16_encode(uint16_t value, uint8_t * p_encoded_data)
+{
+ p_encoded_data[0] = (uint8_t) ((value & 0x00FF) >> 0);
+ p_encoded_data[1] = (uint8_t) ((value & 0xFF00) >> 8);
+ return sizeof(uint16_t);
+}
+
+/**@brief Function for encoding a three-byte value.
+ *
+ * @param[in] value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data is to be written.
+ *
+ * @return Number of bytes written.
+ */
+static __INLINE uint8_t uint24_encode(uint32_t value, uint8_t * p_encoded_data)
+{
+ p_encoded_data[0] = (uint8_t) ((value & 0x000000FF) >> 0);
+ p_encoded_data[1] = (uint8_t) ((value & 0x0000FF00) >> 8);
+ p_encoded_data[2] = (uint8_t) ((value & 0x00FF0000) >> 16);
+ return 3;
+}
+
+/**@brief Function for encoding a uint32 value.
+ *
+ * @param[in] value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data is to be written.
+ *
+ * @return Number of bytes written.
+ */
+static __INLINE uint8_t uint32_encode(uint32_t value, uint8_t * p_encoded_data)
+{
+ p_encoded_data[0] = (uint8_t) ((value & 0x000000FF) >> 0);
+ p_encoded_data[1] = (uint8_t) ((value & 0x0000FF00) >> 8);
+ p_encoded_data[2] = (uint8_t) ((value & 0x00FF0000) >> 16);
+ p_encoded_data[3] = (uint8_t) ((value & 0xFF000000) >> 24);
+ return sizeof(uint32_t);
+}
+
+/**@brief Function for encoding a uint48 value.
+ *
+ * @param[in] value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data is to be written.
+ *
+ * @return Number of bytes written.
+ */
+static __INLINE uint8_t uint48_encode(uint64_t value, uint8_t * p_encoded_data)
+{
+ p_encoded_data[0] = (uint8_t) ((value & 0x0000000000FF) >> 0);
+ p_encoded_data[1] = (uint8_t) ((value & 0x00000000FF00) >> 8);
+ p_encoded_data[2] = (uint8_t) ((value & 0x000000FF0000) >> 16);
+ p_encoded_data[3] = (uint8_t) ((value & 0x0000FF000000) >> 24);
+ p_encoded_data[4] = (uint8_t) ((value & 0x00FF00000000) >> 32);
+ p_encoded_data[5] = (uint8_t) ((value & 0xFF0000000000) >> 40);
+ return 6;
+}
+
+/**@brief Function for decoding a uint16 value.
+ *
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ *
+ * @return Decoded value.
+ */
+static __INLINE uint16_t uint16_decode(const uint8_t * p_encoded_data)
+{
+ return ( (((uint16_t)((uint8_t *)p_encoded_data)[0])) |
+ (((uint16_t)((uint8_t *)p_encoded_data)[1]) << 8 ));
+}
+
+/**@brief Function for decoding a uint16 value in big-endian format.
+ *
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ *
+ * @return Decoded value.
+ */
+static __INLINE uint16_t uint16_big_decode(const uint8_t * p_encoded_data)
+{
+ return ( (((uint16_t)((uint8_t *)p_encoded_data)[0]) << 8 ) |
+ (((uint16_t)((uint8_t *)p_encoded_data)[1])) );
+}
+
+/**@brief Function for decoding a three-byte value.
+ *
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ *
+ * @return Decoded value (uint32_t).
+ */
+static __INLINE uint32_t uint24_decode(const uint8_t * p_encoded_data)
+{
+ return ( (((uint32_t)((uint8_t *)p_encoded_data)[0]) << 0) |
+ (((uint32_t)((uint8_t *)p_encoded_data)[1]) << 8) |
+ (((uint32_t)((uint8_t *)p_encoded_data)[2]) << 16));
+}
+
+/**@brief Function for decoding a uint32 value.
+ *
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ *
+ * @return Decoded value.
+ */
+static __INLINE uint32_t uint32_decode(const uint8_t * p_encoded_data)
+{
+ return ( (((uint32_t)((uint8_t *)p_encoded_data)[0]) << 0) |
+ (((uint32_t)((uint8_t *)p_encoded_data)[1]) << 8) |
+ (((uint32_t)((uint8_t *)p_encoded_data)[2]) << 16) |
+ (((uint32_t)((uint8_t *)p_encoded_data)[3]) << 24 ));
+}
+
+/**@brief Function for decoding a uint32 value in big-endian format.
+ *
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ *
+ * @return Decoded value.
+ */
+static __INLINE uint32_t uint32_big_decode(const uint8_t * p_encoded_data)
+{
+ return ( (((uint32_t)((uint8_t *)p_encoded_data)[0]) << 24) |
+ (((uint32_t)((uint8_t *)p_encoded_data)[1]) << 16) |
+ (((uint32_t)((uint8_t *)p_encoded_data)[2]) << 8) |
+ (((uint32_t)((uint8_t *)p_encoded_data)[3]) << 0) );
+}
+
+/**
+ * @brief Function for encoding an uint16 value in big-endian format.
+ *
+ * @param[in] value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data will be written.
+ *
+ * @return Number of bytes written.
+ */
+static __INLINE uint8_t uint16_big_encode(uint16_t value, uint8_t * p_encoded_data)
+{
+ p_encoded_data[0] = (uint8_t) (value >> 8);
+ p_encoded_data[1] = (uint8_t) (value & 0xFF);
+
+ return sizeof(uint16_t);
+}
+
+/**@brief Function for encoding a uint32 value in big-endian format.
+ *
+ * @param[in] value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data will be written.
+ *
+ * @return Number of bytes written.
+ */
+static __INLINE uint8_t uint32_big_encode(uint32_t value, uint8_t * p_encoded_data)
+{
+ *(uint32_t *)p_encoded_data = __REV(value);
+ return sizeof(uint32_t);
+}
+
+/**@brief Function for decoding a uint48 value.
+ *
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ *
+ * @return Decoded value. (uint64_t)
+ */
+static __INLINE uint64_t uint48_decode(const uint8_t * p_encoded_data)
+{
+ return ( (((uint64_t)((uint8_t *)p_encoded_data)[0]) << 0) |
+ (((uint64_t)((uint8_t *)p_encoded_data)[1]) << 8) |
+ (((uint64_t)((uint8_t *)p_encoded_data)[2]) << 16) |
+ (((uint64_t)((uint8_t *)p_encoded_data)[3]) << 24) |
+ (((uint64_t)((uint8_t *)p_encoded_data)[4]) << 32) |
+ (((uint64_t)((uint8_t *)p_encoded_data)[5]) << 40 ));
+}
+
+/** @brief Function for converting the input voltage (in milli volts) into percentage of 3.0 Volts.
+ *
+ * @details The calculation is based on a linearized version of the battery's discharge
+ * curve. 3.0V returns 100% battery level. The limit for power failure is 2.1V and
+ * is considered to be the lower boundary.
+ *
+ * The discharge curve for CR2032 is non-linear. In this model it is split into
+ * 4 linear sections:
+ * - Section 1: 3.0V - 2.9V = 100% - 42% (58% drop on 100 mV)
+ * - Section 2: 2.9V - 2.74V = 42% - 18% (24% drop on 160 mV)
+ * - Section 3: 2.74V - 2.44V = 18% - 6% (12% drop on 300 mV)
+ * - Section 4: 2.44V - 2.1V = 6% - 0% (6% drop on 340 mV)
+ *
+ * These numbers are by no means accurate. Temperature and
+ * load in the actual application is not accounted for!
+ *
+ * @param[in] mvolts The voltage in mV
+ *
+ * @return Battery level in percent.
+*/
+static __INLINE uint8_t battery_level_in_percent(const uint16_t mvolts)
+{
+ uint8_t battery_level;
+
+ if (mvolts >= 3000)
+ {
+ battery_level = 100;
+ }
+ else if (mvolts > 2900)
+ {
+ battery_level = 100 - ((3000 - mvolts) * 58) / 100;
+ }
+ else if (mvolts > 2740)
+ {
+ battery_level = 42 - ((2900 - mvolts) * 24) / 160;
+ }
+ else if (mvolts > 2440)
+ {
+ battery_level = 18 - ((2740 - mvolts) * 12) / 300;
+ }
+ else if (mvolts > 2100)
+ {
+ battery_level = 6 - ((2440 - mvolts) * 6) / 340;
+ }
+ else
+ {
+ battery_level = 0;
+ }
+
+ return battery_level;
+}
+
+/**@brief Function for checking if a pointer value is aligned to a 4 byte boundary.
+ *
+ * @param[in] p Pointer value to be checked.
+ *
+ * @return TRUE if pointer is aligned to a 4 byte boundary, FALSE otherwise.
+ */
+static __INLINE bool is_word_aligned(void const* p)
+{
+ return (((uintptr_t)p & 0x03) == 0);
+}
+
+/**
+ * @brief Function for checking if provided address is located in stack space.
+ *
+ * @param[in] ptr Pointer to be checked.
+ *
+ * @return true if address is in stack space, false otherwise.
+ */
+static __INLINE bool is_address_from_stack(void * ptr)
+{
+ if (((uint32_t)ptr >= (uint32_t)STACK_BASE) &&
+ ((uint32_t)ptr < (uint32_t)STACK_TOP) )
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // APP_UTIL_H__
+
+/** @} */
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/util/app_util_bds.h b/hw/mcu/nordic/nrf52/sdk/libraries/util/app_util_bds.h
new file mode 100644
index 000000000..e88069322
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/util/app_util_bds.h
@@ -0,0 +1,449 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup app_util Utility Functions and Definitions
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Various types and definitions available to all applications.
+ */
+
+#ifndef APP_UTIL_BDS_H__
+#define APP_UTIL_BDS_H__
+
+#include <stdint.h>
+#include <string.h>
+#include <stdbool.h>
+#include "compiler_abstraction.h"
+#include "app_util.h"
+#include "ble_srv_common.h"
+#include "nordic_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef uint8_t nibble_t;
+typedef uint32_t uint24_t;
+typedef uint64_t uint40_t;
+
+/**@brief IEEE 11073-20601 Regulatory Certification Data List Structure */
+typedef struct
+{
+ uint8_t * p_list; /**< Pointer the byte array containing the encoded opaque structure based on IEEE 11073-20601 specification. */
+ uint8_t list_len; /**< Length of the byte array. */
+} regcertdatalist_t;
+
+/**@brief SFLOAT format (IEEE-11073 16-bit FLOAT, meaning 4 bits for exponent (base 10) and 12 bits mantissa) */
+typedef struct
+{
+ int8_t exponent; /**< Base 10 exponent, should be using only 4 bits */
+ int16_t mantissa; /**< Mantissa, should be using only 12 bits */
+} sfloat_t;
+
+/**@brief Date and Time structure. */
+typedef struct
+{
+ uint16_t year;
+ uint8_t month;
+ uint8_t day;
+ uint8_t hours;
+ uint8_t minutes;
+ uint8_t seconds;
+} ble_date_time_t;
+
+
+/**@brief Function for encoding a uint16 value.
+ *
+ * @param[in] p_value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data is to be written.
+ *
+ * @return Number of bytes written.
+ */
+static __INLINE uint8_t bds_uint16_encode(const uint16_t * p_value, uint8_t * p_encoded_data)
+{
+ p_encoded_data[0] = (uint8_t) ((*p_value & 0x00FF) >> 0);
+ p_encoded_data[1] = (uint8_t) ((*p_value & 0xFF00) >> 8);
+ return sizeof(uint16_t);
+}
+
+static __INLINE uint8_t bds_int16_encode(const int16_t * p_value, uint8_t * p_encoded_data)
+{
+ uint16_t tmp = *p_value;
+ return bds_uint16_encode(&tmp, p_encoded_data);
+}
+
+/**@brief Function for encoding a uint24 value.
+ *
+ * @param[in] p_value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data is to be written.
+ *
+ * @return Number of bytes written.
+ */
+static __INLINE uint8_t bds_uint24_encode(const uint32_t * p_value, uint8_t * p_encoded_data)
+{
+ p_encoded_data[0] = (uint8_t) ((*p_value & 0x000000FF) >> 0);
+ p_encoded_data[1] = (uint8_t) ((*p_value & 0x0000FF00) >> 8);
+ p_encoded_data[2] = (uint8_t) ((*p_value & 0x00FF0000) >> 16);
+ return (3);
+}
+
+
+/**@brief Function for encoding a uint32 value.
+ *
+ * @param[in] p_value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data is to be written.
+ *
+ * @return Number of bytes written.
+ */
+static __INLINE uint8_t bds_uint32_encode(const uint32_t * p_value, uint8_t * p_encoded_data)
+{
+ p_encoded_data[0] = (uint8_t) ((*p_value & 0x000000FF) >> 0);
+ p_encoded_data[1] = (uint8_t) ((*p_value & 0x0000FF00) >> 8);
+ p_encoded_data[2] = (uint8_t) ((*p_value & 0x00FF0000) >> 16);
+ p_encoded_data[3] = (uint8_t) ((*p_value & 0xFF000000) >> 24);
+ return sizeof(uint32_t);
+}
+
+
+/**@brief Function for encoding a uint40 value.
+ *
+ * @param[in] p_value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data is to be written.
+ *
+ * @return Number of bytes written.
+ */
+static __INLINE uint8_t bds_uint40_encode(const uint64_t * p_value, uint8_t * p_encoded_data)
+{
+ p_encoded_data[0] = (uint8_t) ((*p_value & 0x00000000000000FF) >> 0);
+ p_encoded_data[1] = (uint8_t) ((*p_value & 0x000000000000FF00) >> 8);
+ p_encoded_data[2] = (uint8_t) ((*p_value & 0x0000000000FF0000) >> 16);
+ p_encoded_data[3] = (uint8_t) ((*p_value & 0x00000000FF000000) >> 24);
+ p_encoded_data[4] = (uint8_t) ((*p_value & 0x000000FF00000000) >> 32);
+ return 5;
+}
+
+/**@brief Function for encoding a sfloat value.
+ *
+ * @param[in] p_value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data is to be written.
+ *
+ * @return Number of bytes written.
+ */
+static __INLINE uint8_t bds_sfloat_encode(const sfloat_t * p_value, uint8_t * p_encoded_data)
+{
+ uint16_t encoded_val;
+
+ encoded_val = ((p_value->exponent << 12) & 0xF000) |
+ ((p_value->mantissa << 0) & 0x0FFF);
+
+ return(bds_uint16_encode(&encoded_val, p_encoded_data));
+}
+
+
+/**@brief Function for encoding a uint8_array value.
+ *
+ * @param[in] p_value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data is to be written.
+ */
+static __INLINE uint8_t bds_uint8_array_encode(const uint8_array_t * p_value,
+ uint8_t * p_encoded_data)
+{
+ memcpy(p_encoded_data, p_value->p_data, p_value->size);
+ return p_value->size;
+}
+
+
+/**@brief Function for encoding a utf8_str value.
+ *
+ * @param[in] p_value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data is to be written.
+
+ */
+static __INLINE uint8_t bds_ble_srv_utf8_str_encode(const ble_srv_utf8_str_t * p_value,
+ uint8_t * p_encoded_data)
+{
+ memcpy(p_encoded_data, p_value->p_str, p_value->length);
+ return p_value->length;
+}
+
+/**@brief Function for encoding a regcertdatalist value.
+ *
+ * @param[in] p_value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data is to be written.
+
+ */
+static __INLINE uint8_t bds_regcertdatalist_encode(const regcertdatalist_t * p_value,
+ uint8_t * p_encoded_data)
+{
+ memcpy(p_encoded_data, p_value->p_list, p_value->list_len);
+ return p_value->list_len;
+}
+
+
+/**@brief Function for decoding a date_time value.
+ *
+ * @param[in] p_date_time pointer to the date_time structure to encode.
+ * @param[in] p_encoded_data pointer to the encoded data
+ * @return length of the encoded field.
+ */
+static __INLINE uint8_t bds_ble_date_time_encode(const ble_date_time_t * p_date_time,
+ uint8_t * p_encoded_data)
+{
+ uint8_t len = bds_uint16_encode(&p_date_time->year, &p_encoded_data[0]);
+
+ p_encoded_data[len++] = p_date_time->month;
+ p_encoded_data[len++] = p_date_time->day;
+ p_encoded_data[len++] = p_date_time->hours;
+ p_encoded_data[len++] = p_date_time->minutes;
+ p_encoded_data[len++] = p_date_time->seconds;
+
+ return len;
+}
+
+
+/**@brief Function for decoding a uint16 value.
+ *
+ * @param[in] len length of the field to be decoded.
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ * @param[in] p_decoded_val pointer to the decoded value
+ * @return length of the decoded field.
+ */
+static __INLINE uint8_t bds_uint16_decode(const uint8_t len,
+ const uint8_t * p_encoded_data,
+ uint16_t * p_decoded_val)
+{
+ UNUSED_VARIABLE(len);
+ *p_decoded_val = (((uint16_t)((uint8_t *)p_encoded_data)[0])) |
+ (((uint16_t)((uint8_t *)p_encoded_data)[1]) << 8 );
+ return (sizeof(uint16_t));
+}
+
+
+/**@brief Function for decoding a int16 value.
+ *
+ * @param[in] len length of the field to be decoded.
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ * @param[in] p_decoded_val pointer to the decoded value
+ * @return length of the decoded field.
+ */
+static __INLINE uint8_t bds_int16_decode(const uint8_t len,
+ const uint8_t * p_encoded_data,
+ int16_t * p_decoded_val)
+{
+ UNUSED_VARIABLE(len);
+ uint16_t tmp = 0;
+ uint8_t retval = bds_uint16_decode(len, p_encoded_data, &tmp);
+ *p_decoded_val = (int16_t)tmp;
+ return retval;
+}
+
+
+/**@brief Function for decoding a uint24 value.
+ *
+ * @param[in] len length of the field to be decoded.
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ * @param[in] p_decoded_val pointer to the decoded value
+ *
+ * @return length of the decoded field.
+ */
+static __INLINE uint8_t bds_uint24_decode(const uint8_t len,
+ const uint8_t * p_encoded_data,
+ uint32_t * p_decoded_val)
+{
+ UNUSED_VARIABLE(len);
+ *p_decoded_val = (((uint32_t)((uint8_t *)p_encoded_data)[0]) << 0) |
+ (((uint32_t)((uint8_t *)p_encoded_data)[1]) << 8) |
+ (((uint32_t)((uint8_t *)p_encoded_data)[2]) << 16);
+ return (3);
+}
+
+
+/**@brief Function for decoding a uint32 value.
+ *
+ * @param[in] len length of the field to be decoded.
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ * @param[in] p_decoded_val pointer to the decoded value
+ *
+ * @return length of the decoded field.
+ */
+static __INLINE uint8_t bds_uint32_decode(const uint8_t len,
+ const uint8_t * p_encoded_data,
+ uint32_t * p_decoded_val)
+{
+ UNUSED_VARIABLE(len);
+ *p_decoded_val = (((uint32_t)((uint8_t *)p_encoded_data)[0]) << 0) |
+ (((uint32_t)((uint8_t *)p_encoded_data)[1]) << 8) |
+ (((uint32_t)((uint8_t *)p_encoded_data)[2]) << 16) |
+ (((uint32_t)((uint8_t *)p_encoded_data)[3]) << 24 );
+ return (sizeof(uint32_t));
+}
+
+
+/**@brief Function for decoding a uint40 value.
+ *
+ * @param[in] len length of the field to be decoded.
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ * @param[in] p_decoded_val pointer to the decoded value
+ *
+ * @return length of the decoded field.
+ */
+static __INLINE uint8_t bds_uint40_decode(const uint8_t len,
+ const uint8_t * p_encoded_data,
+ uint64_t * p_decoded_val)
+{
+ UNUSED_VARIABLE(len);
+ *p_decoded_val = (((uint64_t)((uint8_t *)p_encoded_data)[0]) << 0) |
+ (((uint64_t)((uint8_t *)p_encoded_data)[1]) << 8) |
+ (((uint64_t)((uint8_t *)p_encoded_data)[2]) << 16) |
+ (((uint64_t)((uint8_t *)p_encoded_data)[3]) << 24 )|
+ (((uint64_t)((uint8_t *)p_encoded_data)[4]) << 32 );
+ return (40);
+}
+
+
+/**@brief Function for decoding a sfloat value.
+ *
+ * @param[in] len length of the field to be decoded.
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ * @param[in] p_decoded_val pointer to the decoded value
+ *
+ * @return length of the decoded field.
+
+ */
+static __INLINE uint8_t bds_sfloat_decode(const uint8_t len,
+ const uint8_t * p_encoded_data,
+ sfloat_t * p_decoded_val)
+{
+
+ p_decoded_val->exponent = 0;
+ bds_uint16_decode(len, p_encoded_data, (uint16_t*)&p_decoded_val->mantissa);
+ p_decoded_val->exponent = (uint8_t)((p_decoded_val->mantissa & 0xF000) >> 12);
+ p_decoded_val->mantissa &= 0x0FFF;
+ return len;
+}
+
+
+/**@brief Function for decoding a uint8_array value.
+ *
+ * @param[in] len length of the field to be decoded.
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ * @param[in] p_decoded_val pointer to the decoded value
+ *
+ * @return length of the decoded field.
+ */
+static __INLINE uint8_t bds_uint8_array_decode(const uint8_t len,
+ const uint8_t * p_encoded_data,
+ uint8_array_t * p_decoded_val)
+{
+ memcpy(p_decoded_val->p_data, p_encoded_data, len);
+ p_decoded_val->size = len;
+ return p_decoded_val->size;
+}
+
+
+/**@brief Function for decoding a utf8_str value.
+ *
+ * @param[in] len length of the field to be decoded.
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ * @param[in] p_decoded_val pointer to the decoded value
+ *
+ * @return length of the decoded field.
+ */
+static __INLINE uint8_t bds_ble_srv_utf8_str_decode(const uint8_t len,
+ const uint8_t * p_encoded_data,
+ ble_srv_utf8_str_t * p_decoded_val)
+{
+ p_decoded_val->p_str = (uint8_t*)p_encoded_data;
+ p_decoded_val->length = len;
+ return p_decoded_val->length;
+}
+
+
+/**@brief Function for decoding a regcertdatalist value.
+ *
+ * @param[in] len length of the field to be decoded.
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ * @param[in] p_decoded_val pointer to the decoded value
+ *
+ * @return length of the decoded field.
+ */
+static __INLINE uint8_t bds_regcertdatalist_decode(const uint8_t len,
+ const uint8_t * p_encoded_data,
+ regcertdatalist_t * p_decoded_val)
+{
+ memcpy(p_decoded_val->p_list, p_encoded_data, len);
+ p_decoded_val->list_len = len;
+ return p_decoded_val->list_len;
+}
+
+
+/**@brief Function for decoding a date_time value.
+ *
+ * @param[in] len length of the field to be decoded.
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ * @param[in] p_date_time pointer to the decoded value
+ *
+ * @return length of the decoded field.
+ */
+static __INLINE uint8_t bds_ble_date_time_decode(const uint8_t len,
+ const uint8_t * p_encoded_data,
+ ble_date_time_t * p_date_time)
+{
+ UNUSED_VARIABLE(len);
+ uint8_t pos = bds_uint16_decode(len, &p_encoded_data[0], &p_date_time->year);
+ p_date_time->month = p_encoded_data[pos++];
+ p_date_time->day = p_encoded_data[pos++];
+ p_date_time->hours = p_encoded_data[pos++];
+ p_date_time->minutes = p_encoded_data[pos++];
+ p_date_time->seconds = p_encoded_data[pos++];
+
+ return pos;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // APP_UTIL_BDS_H__
+
+/** @} */
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/util/app_util_platform.c b/hw/mcu/nordic/nrf52/sdk/libraries/util/app_util_platform.c
new file mode 100644
index 000000000..740d42233
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/util/app_util_platform.c
@@ -0,0 +1,127 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "app_util_platform.h"
+
+#ifdef SOFTDEVICE_PRESENT
+/* Global nvic state instance, required by nrf_nvic.h */
+nrf_nvic_state_t nrf_nvic_state;
+#endif
+
+static uint32_t m_in_critical_region = 0;
+
+void app_util_disable_irq(void)
+{
+ __disable_irq();
+ m_in_critical_region++;
+}
+
+void app_util_enable_irq(void)
+{
+ m_in_critical_region--;
+ if (m_in_critical_region == 0)
+ {
+ __enable_irq();
+ }
+}
+
+void app_util_critical_region_enter(uint8_t *p_nested)
+{
+#if __CORTEX_M == (0x04U)
+ ASSERT(APP_LEVEL_PRIVILEGED == privilege_level_get())
+#endif
+
+#if defined(SOFTDEVICE_PRESENT)
+ /* return value can be safely ignored */
+ (void) sd_nvic_critical_region_enter(p_nested);
+#else
+ app_util_disable_irq();
+#endif
+}
+
+void app_util_critical_region_exit(uint8_t nested)
+{
+#if __CORTEX_M == (0x04U)
+ ASSERT(APP_LEVEL_PRIVILEGED == privilege_level_get())
+#endif
+
+#if defined(SOFTDEVICE_PRESENT)
+ /* return value can be safely ignored */
+ (void) sd_nvic_critical_region_exit(nested);
+#else
+ app_util_enable_irq();
+#endif
+}
+
+
+uint8_t privilege_level_get(void)
+{
+#if __CORTEX_M == (0x00U) || defined(_WIN32) || defined(__unix) || defined(__APPLE__)
+ /* the Cortex-M0 has no concept of privilege */
+ return APP_LEVEL_PRIVILEGED;
+#elif __CORTEX_M == (0x04U)
+ uint32_t isr_vector_num = __get_IPSR() & IPSR_ISR_Msk ;
+ if (0 == isr_vector_num)
+ {
+ /* Thread Mode, check nPRIV */
+ int32_t control = __get_CONTROL();
+ return control & CONTROL_nPRIV_Msk ? APP_LEVEL_UNPRIVILEGED : APP_LEVEL_PRIVILEGED;
+ }
+ else
+ {
+ /* Handler Mode, always privileged */
+ return APP_LEVEL_PRIVILEGED;
+ }
+#endif
+}
+
+
+uint8_t current_int_priority_get(void)
+{
+ uint32_t isr_vector_num = __get_IPSR() & IPSR_ISR_Msk ;
+ if (isr_vector_num > 0)
+ {
+ int32_t irq_type = ((int32_t)isr_vector_num - EXTERNAL_INT_VECTOR_OFFSET);
+ return (NVIC_GetPriority((IRQn_Type)irq_type) & 0xFF);
+ }
+ else
+ {
+ return APP_IRQ_PRIORITY_THREAD;
+ }
+}
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/util/app_util_platform.h b/hw/mcu/nordic/nrf52/sdk/libraries/util/app_util_platform.h
new file mode 100644
index 000000000..141c3394b
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/util/app_util_platform.h
@@ -0,0 +1,262 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup app_util_platform Utility Functions and Definitions (Platform)
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Various types and definitions available to all applications when using SoftDevice.
+ */
+
+#ifndef APP_UTIL_PLATFORM_H__
+#define APP_UTIL_PLATFORM_H__
+
+#include <stdint.h>
+#include "compiler_abstraction.h"
+#include "nrf.h"
+#ifdef SOFTDEVICE_PRESENT
+#include "nrf_soc.h"
+#include "nrf_nvic.h"
+#endif
+#include "nrf_assert.h"
+#include "app_error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if __CORTEX_M == (0x00U)
+#define _PRIO_SD_HIGH 0
+#define _PRIO_APP_HIGH 1
+#define _PRIO_APP_MID 1
+#define _PRIO_SD_LOW 2
+#define _PRIO_APP_LOW 3
+#define _PRIO_APP_LOWEST 3
+#define _PRIO_THREAD 4
+#elif __CORTEX_M == (0x04U)
+#define _PRIO_SD_HIGH 0
+#define _PRIO_SD_MID 1
+#define _PRIO_APP_HIGH 2
+#define _PRIO_APP_MID 3
+#define _PRIO_SD_LOW 4
+#define _PRIO_SD_LOWEST 5
+#define _PRIO_APP_LOW 6
+#define _PRIO_APP_LOWEST 7
+#define _PRIO_THREAD 15
+#else
+ #error "No platform defined"
+#endif
+
+
+//lint -save -e113 -e452
+/**@brief The interrupt priorities available to the application while the SoftDevice is active. */
+typedef enum
+{
+#ifndef SOFTDEVICE_PRESENT
+ APP_IRQ_PRIORITY_HIGHEST = _PRIO_SD_HIGH,
+#else
+ APP_IRQ_PRIORITY_HIGHEST = _PRIO_APP_HIGH,
+#endif
+ APP_IRQ_PRIORITY_HIGH = _PRIO_APP_HIGH,
+#ifndef SOFTDEVICE_PRESENT
+ APP_IRQ_PRIORITY_MID = _PRIO_SD_LOW,
+#else
+ APP_IRQ_PRIORITY_MID = _PRIO_APP_MID,
+#endif
+ APP_IRQ_PRIORITY_LOW = _PRIO_APP_LOW,
+ APP_IRQ_PRIORITY_LOWEST = _PRIO_APP_LOWEST,
+ APP_IRQ_PRIORITY_THREAD = _PRIO_THREAD /**< "Interrupt level" when running in Thread Mode. */
+} app_irq_priority_t;
+//lint -restore
+
+
+/*@brief The privilege levels available to applications in Thread Mode */
+typedef enum
+{
+ APP_LEVEL_UNPRIVILEGED,
+ APP_LEVEL_PRIVILEGED
+} app_level_t;
+
+/**@cond NO_DOXYGEN */
+#define EXTERNAL_INT_VECTOR_OFFSET 16
+/**@endcond */
+
+/**@brief Macro for setting a breakpoint.
+ */
+#if defined(__GNUC__)
+#define NRF_BREAKPOINT __builtin_trap()
+#else
+#define NRF_BREAKPOINT __BKPT(0)
+#endif
+
+/** @brief Macro for setting a breakpoint.
+ *
+ * If it is possible to detect debugger presence then it is set only in that case.
+ *
+ */
+#if __CORTEX_M == 0x04
+#define NRF_BREAKPOINT_COND do { \
+ /* C_DEBUGEN == 1 -> Debugger Connected */ \
+ if (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) \
+ { \
+ /* Generate breakpoint if debugger is connected */ \
+ NRF_BREAKPOINT; \
+ } \
+ }while (0)
+#else
+#define NRF_BREAKPOINT_COND NRF_BREAKPOINT
+#endif // __CORTEX_M == 0x04
+
+#if defined ( __CC_ARM )
+#define PACKED(TYPE) __packed TYPE
+#define PACKED_STRUCT PACKED(struct)
+#elif defined ( __GNUC__ )
+#define PACKED __attribute__((packed))
+#define PACKED_STRUCT struct PACKED
+#elif defined (__ICCARM__)
+#define PACKED_STRUCT __packed struct
+#endif
+
+void app_util_critical_region_enter (uint8_t *p_nested);
+void app_util_critical_region_exit (uint8_t nested);
+
+/**@brief Macro for entering a critical region.
+ *
+ * @note Due to implementation details, there must exist one and only one call to
+ * CRITICAL_REGION_EXIT() for each call to CRITICAL_REGION_ENTER(), and they must be located
+ * in the same scope.
+ */
+#ifdef SOFTDEVICE_PRESENT
+#define CRITICAL_REGION_ENTER() \
+ { \
+ uint8_t __CR_NESTED = 0; \
+ app_util_critical_region_enter(&__CR_NESTED);
+#else
+#define CRITICAL_REGION_ENTER() app_util_critical_region_enter(NULL)
+#endif
+
+/**@brief Macro for leaving a critical region.
+ *
+ * @note Due to implementation details, there must exist one and only one call to
+ * CRITICAL_REGION_EXIT() for each call to CRITICAL_REGION_ENTER(), and they must be located
+ * in the same scope.
+ */
+#ifdef SOFTDEVICE_PRESENT
+#define CRITICAL_REGION_EXIT() \
+ app_util_critical_region_exit(__CR_NESTED); \
+ }
+#else
+#define CRITICAL_REGION_EXIT() app_util_critical_region_exit(0)
+#endif
+
+/* Workaround for Keil 4 */
+#ifndef IPSR_ISR_Msk
+#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
+#endif
+
+
+
+/**@brief Macro to enable anonymous unions from a certain point in the code.
+ */
+#if defined(__CC_ARM)
+ #define ANON_UNIONS_ENABLE _Pragma("push") \
+ _Pragma("anon_unions")
+#elif defined(__ICCARM__)
+ #define ANON_UNIONS_ENABLE _Pragma("language=extended")
+#else
+ #define ANON_UNIONS_ENABLE
+ // No action will be taken.
+ // For GCC anonymous unions are enabled by default.
+#endif
+
+/**@brief Macro to disable anonymous unions from a certain point in the code.
+ * @note Call only after first calling @ref ANON_UNIONS_ENABLE.
+ */
+#if defined(__CC_ARM)
+ #define ANON_UNIONS_DISABLE _Pragma("pop")
+#elif defined(__ICCARM__)
+ #define ANON_UNIONS_DISABLE
+ // for IAR leave anonymous unions enabled
+#else
+ #define ANON_UNIONS_DISABLE
+ // No action will be taken.
+ // For GCC anonymous unions are enabled by default.
+#endif
+
+/**@brief Macro for adding pragma directive only for GCC.
+ */
+#ifdef __GNUC__
+#define GCC_PRAGMA(v) _Pragma(v)
+#else
+#define GCC_PRAGMA(v)
+#endif
+
+/* Workaround for Keil 4 */
+#ifndef CONTROL_nPRIV_Msk
+#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */
+#endif
+
+/**@brief Function for finding the current interrupt level.
+ *
+ * @return Current interrupt level.
+ * @retval APP_IRQ_PRIORITY_HIGH We are running in Application High interrupt level.
+ * @retval APP_IRQ_PRIORITY_LOW We are running in Application Low interrupt level.
+ * @retval APP_IRQ_PRIORITY_THREAD We are running in Thread Mode.
+ */
+uint8_t current_int_priority_get(void);
+
+
+/**@brief Function for finding out the current privilege level.
+ *
+ * @return Current privilege level.
+ * @retval APP_LEVEL_UNPRIVILEGED We are running in unprivileged level.
+ * @retval APP_LEVEL_PRIVILEGED We are running in privileged level.
+ */
+uint8_t privilege_level_get(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // APP_UTIL_PLATFORM_H__
+
+/** @} */
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/util/nordic_common.h b/hw/mcu/nordic/nrf52/sdk/libraries/util/nordic_common.h
new file mode 100644
index 000000000..e7f63b129
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/util/nordic_common.h
@@ -0,0 +1,211 @@
+/**
+ * Copyright (c) 2008 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ * @brief Common defines and macros for firmware developed by Nordic Semiconductor.
+ */
+
+#ifndef NORDIC_COMMON_H__
+#define NORDIC_COMMON_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Check if selected module is enabled
+ *
+ * This is save function for driver enable checking.
+ * Correct from Lint point of view (not using default of undefined value).
+ *
+ * Usage:
+ * @code
+ #if NRF_MODULE_ENABLED(UART)
+ ...
+ #endif
+ * @endcode
+ *
+ * @param module The module name.
+ *
+ * @retval 1 The macro <module>_ENABLE is defined and is non-zero.
+ * @retval 0 The macro <module>_ENABLE is not defined or it equals zero.
+ *
+ * @note
+ * This macro intentionally does not implement second expansion level.
+ * The name of the module to be checked has to be given directly as a parameter.
+ * And given parameter would be connected with @c _ENABLED postfix directly
+ * without evaluating its value.
+ */
+//lint -emacro(491,NRF_MODULE_ENABLED) // Suppers warning 491 "non-standard use of 'defined' preprocessor operator"
+#define NRF_MODULE_ENABLED(module) \
+ ((defined(module ## _ENABLED) && (module ## _ENABLED)) ? 1 : 0)
+
+/** The upper 8 bits of a 32 bit value */
+//lint -emacro(572,MSB_32) // Suppress warning 572 "Excessive shift value"
+#define MSB_32(a) (((a) & 0xFF000000) >> 24)
+/** The lower 8 bits (of a 32 bit value) */
+#define LSB_32(a) ((a) & 0x000000FF)
+
+/** The upper 8 bits of a 16 bit value */
+//lint -emacro(572,MSB_16) // Suppress warning 572 "Excessive shift value"
+#define MSB_16(a) (((a) & 0xFF00) >> 8)
+/** The lower 8 bits (of a 16 bit value) */
+#define LSB_16(a) ((a) & 0x00FF)
+
+/** Leaves the minimum of the two 32-bit arguments */
+/*lint -emacro(506, MIN) */ /* Suppress "Constant value Boolean */
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+/** Leaves the maximum of the two 32-bit arguments */
+/*lint -emacro(506, MAX) */ /* Suppress "Constant value Boolean */
+#define MAX(a, b) ((a) < (b) ? (b) : (a))
+
+/**@brief Concatenates two parameters.
+ *
+ * It realizes two level expansion to make it sure that all the parameters
+ * are actually expanded before gluing them together.
+ *
+ * @param p1 First parameter to concatenating
+ * @param p2 Second parameter to concatenating
+ *
+ * @return Two parameters glued together.
+ * They have to create correct C mnemonic in other case
+ * preprocessor error would be generated.
+ *
+ * @sa CONCAT_3
+ */
+#define CONCAT_2(p1, p2) CONCAT_2_(p1, p2)
+/** Auxiliary macro used by @ref CONCAT_2 */
+#define CONCAT_2_(p1, p2) p1##p2
+
+/**@brief Concatenates three parameters.
+ *
+ * It realizes two level expansion to make it sure that all the parameters
+ * are actually expanded before gluing them together.
+ *
+ * @param p1 First parameter to concatenating
+ * @param p2 Second parameter to concatenating
+ * @param p3 Third parameter to concatenating
+ *
+ * @return Three parameters glued together.
+ * They have to create correct C mnemonic in other case
+ * preprocessor error would be generated.
+ *
+ * @sa CONCAT_2
+ */
+#define CONCAT_3(p1, p2, p3) CONCAT_3_(p1, p2, p3)
+/** Auxiliary macro used by @ref CONCAT_3 */
+#define CONCAT_3_(p1, p2, p3) p1##p2##p3
+
+#define STRINGIFY_(val) #val
+/** Converts a macro argument into a character constant.
+ */
+#define STRINGIFY(val) STRINGIFY_(val)
+
+/** Counts number of elements inside the array
+ */
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+
+/**@brief Set a bit in the uint32 word.
+ *
+ * @param[in] W Word whose bit is being set.
+ * @param[in] B Bit number in the word to be set.
+ */
+#define SET_BIT(W, B) ((W) |= (uint32_t)(1U << (B)))
+
+
+/**@brief Clears a bit in the uint32 word.
+ *
+ * @param[in] W Word whose bit is to be cleared.
+ * @param[in] B Bit number in the word to be cleared.
+ */
+#define CLR_BIT(W, B) ((W) &= (~(uint32_t)(1U << (B))))
+
+
+/**@brief Checks if a bit is set.
+ *
+ * @param[in] W Word whose bit is to be checked.
+ * @param[in] B Bit number in the word to be checked.
+ *
+ * @retval 1 if bit is set.
+ * @retval 0 if bit is not set.
+ */
+#define IS_SET(W, B) (((W) >> (B)) & 1)
+
+#define BIT_0 0x01 /**< The value of bit 0 */
+#define BIT_1 0x02 /**< The value of bit 1 */
+#define BIT_2 0x04 /**< The value of bit 2 */
+#define BIT_3 0x08 /**< The value of bit 3 */
+#define BIT_4 0x10 /**< The value of bit 4 */
+#define BIT_5 0x20 /**< The value of bit 5 */
+#define BIT_6 0x40 /**< The value of bit 6 */
+#define BIT_7 0x80 /**< The value of bit 7 */
+#define BIT_8 0x0100 /**< The value of bit 8 */
+#define BIT_9 0x0200 /**< The value of bit 9 */
+#define BIT_10 0x0400 /**< The value of bit 10 */
+#define BIT_11 0x0800 /**< The value of bit 11 */
+#define BIT_12 0x1000 /**< The value of bit 12 */
+#define BIT_13 0x2000 /**< The value of bit 13 */
+#define BIT_14 0x4000 /**< The value of bit 14 */
+#define BIT_15 0x8000 /**< The value of bit 15 */
+#define BIT_16 0x00010000 /**< The value of bit 16 */
+#define BIT_17 0x00020000 /**< The value of bit 17 */
+#define BIT_18 0x00040000 /**< The value of bit 18 */
+#define BIT_19 0x00080000 /**< The value of bit 19 */
+#define BIT_20 0x00100000 /**< The value of bit 20 */
+#define BIT_21 0x00200000 /**< The value of bit 21 */
+#define BIT_22 0x00400000 /**< The value of bit 22 */
+#define BIT_23 0x00800000 /**< The value of bit 23 */
+#define BIT_24 0x01000000 /**< The value of bit 24 */
+#define BIT_25 0x02000000 /**< The value of bit 25 */
+#define BIT_26 0x04000000 /**< The value of bit 26 */
+#define BIT_27 0x08000000 /**< The value of bit 27 */
+#define BIT_28 0x10000000 /**< The value of bit 28 */
+#define BIT_29 0x20000000 /**< The value of bit 29 */
+#define BIT_30 0x40000000 /**< The value of bit 30 */
+#define BIT_31 0x80000000 /**< The value of bit 31 */
+
+#define UNUSED_VARIABLE(X) ((void)(X))
+#define UNUSED_PARAMETER(X) UNUSED_VARIABLE(X)
+#define UNUSED_RETURN_VALUE(X) UNUSED_VARIABLE(X)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NORDIC_COMMON_H__
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/util/nrf_assert.c b/hw/mcu/nordic/nrf52/sdk/libraries/util/nrf_assert.c
new file mode 100644
index 000000000..6255ba920
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/util/nrf_assert.c
@@ -0,0 +1,54 @@
+/**
+ * Copyright (c) 2006 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "nrf_assert.h"
+#include "app_error.h"
+#include "nordic_common.h"
+
+__WEAK void assert_nrf_callback(uint16_t line_num, const uint8_t * file_name)
+{
+ assert_info_t assert_info =
+ {
+ .line_num = line_num,
+ .p_file_name = file_name,
+ };
+ app_error_fault_handler(NRF_FAULT_ID_SDK_ASSERT, 0, (uint32_t)(&assert_info));
+
+ UNUSED_VARIABLE(assert_info);
+}
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/util/nrf_assert.h b/hw/mcu/nordic/nrf52/sdk/libraries/util/nrf_assert.h
new file mode 100644
index 000000000..2ec647c87
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/util/nrf_assert.h
@@ -0,0 +1,123 @@
+/**
+ * Copyright (c) 2006 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ * @brief Utilities for verifying program logic
+ */
+
+#ifndef NRF_ASSERT_H_
+#define NRF_ASSERT_H_
+
+#include <stdint.h>
+#include "nrf.h"
+#include "app_error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief Function for handling assertions.
+ *
+ *
+ * @note
+ * This function is called when an assertion has triggered.
+ *
+ * @note
+ * This function is deprecated and will be removed in future releases.
+ * Use app_error_fault_handler instead.
+ *
+ *
+ * @post
+ * All hardware is put into an idle non-emitting state (in particular the radio is highly
+ * important to switch off since the radio might be in a state that makes it send
+ * packets continiously while a typical final infinit ASSERT loop is executing).
+ *
+ *
+ * @param line_num The line number where the assertion is called
+ * @param file_name Pointer to the file name
+ */
+//lint -save -esym(14, assert_nrf_callback)
+void assert_nrf_callback(uint16_t line_num, const uint8_t *file_name);
+//lint -restore
+
+#if (defined(DEBUG_NRF) || defined(DEBUG_NRF_USER))
+#define NRF_ASSERT_PRESENT 1
+#else
+#define NRF_ASSERT_PRESENT 0
+#endif
+
+//#if defined(DEBUG_NRF) || defined(DEBUG_NRF_USER)
+
+/*lint -emacro(506, ASSERT) */ /* Suppress "Constant value Boolean */
+/*lint -emacro(774, ASSERT) */ /* Suppress "Boolean within 'if' always evaluates to True" */ \
+
+/** @brief Function for checking intended for production code.
+ *
+ * Check passes if "expr" evaluates to true. */
+
+#ifdef _lint
+#define ASSERT(expr) \
+if (expr) \
+{ \
+} \
+else \
+{ \
+ while (1); \
+}
+#else //_lint
+#define ASSERT(expr) \
+if (NRF_ASSERT_PRESENT) \
+{ \
+ if (expr) \
+ { \
+ } \
+ else \
+ { \
+ assert_nrf_callback((uint16_t)__LINE__, (uint8_t *)__FILE__); \
+ } \
+}
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_ASSERT_H_ */
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/util/nrf_bitmask.h b/hw/mcu/nordic/nrf52/sdk/libraries/util/nrf_bitmask.h
new file mode 100644
index 000000000..72f531f1a
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/util/nrf_bitmask.h
@@ -0,0 +1,147 @@
+/**
+ * Copyright (c) 2006 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_BITMASK_H
+#define NRF_BITMASK_H
+
+#include "compiler_abstraction.h"
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BITMASK_BYTE_GET(abs_bit) ((abs_bit)/8)
+#define BITMASK_RELBIT_GET(abs_bit) ((abs_bit) & 0x00000007)
+
+/**
+ * Function for checking if bit in the multi-byte bit mask is set.
+ *
+ * @param bit Bit index.
+ * @param p_mask A pointer to mask with bit fields.
+ *
+ * @return 0 if bit is not set, positive value otherwise.
+ */
+__STATIC_INLINE uint32_t nrf_bitmask_bit_is_set(uint32_t bit, void const * p_mask)
+{
+ uint8_t const * p_mask8 = (uint8_t const *)p_mask;
+ uint32_t byte_idx = BITMASK_BYTE_GET(bit);
+ bit = BITMASK_RELBIT_GET(bit);
+ return (1 << bit) & p_mask8[byte_idx];
+}
+
+/**
+ * Function for setting a bit in the multi-byte bit mask.
+ *
+ * @param bit Bit index.
+ * @param p_mask A pointer to mask with bit fields.
+ */
+__STATIC_INLINE void nrf_bitmask_bit_set(uint32_t bit, void * p_mask)
+{
+ uint8_t * p_mask8 = (uint8_t *)p_mask;
+ uint32_t byte_idx = BITMASK_BYTE_GET(bit);
+ bit = BITMASK_RELBIT_GET(bit);
+ p_mask8[byte_idx] |= (1 << bit);
+}
+
+/**
+ * Function for clearing a bit in the multi-byte bit mask.
+ *
+ * @param bit Bit index.
+ * @param p_mask A pointer to mask with bit fields.
+ */
+__STATIC_INLINE void nrf_bitmask_bit_clear(uint32_t bit, void * p_mask)
+{
+ uint8_t * p_mask8 = (uint8_t *)p_mask;
+ uint32_t byte_idx = BITMASK_BYTE_GET(bit);
+ bit = BITMASK_RELBIT_GET(bit);
+ p_mask8[byte_idx] &= ~(1 << bit);
+}
+
+/**
+ * Function for performing bitwise OR operation on two multi-byte bit masks.
+ *
+ * @param p_mask1 A pointer to the first bit mask.
+ * @param p_mask2 A pointer to the second bit mask.
+ * @param p_mask_out A pointer to the output bit mask.
+ * @param length Length of output mask in bytes.
+ */
+__STATIC_INLINE void nrf_bitmask_masks_or(void const * p_mask1,
+ void const * p_mask2,
+ void * p_out_mask,
+ uint32_t length)
+{
+ uint8_t const * p_mask8_1 = (uint8_t const *)p_mask1;
+ uint8_t const * p_mask8_2 = (uint8_t const *)p_mask2;
+ uint8_t * p_mask8_out = (uint8_t *)p_out_mask;
+ uint32_t i;
+ for (i = 0; i < length; i++)
+ {
+ p_mask8_out[i] = p_mask8_1[i] | p_mask8_2[i];
+ }
+}
+
+/**
+ * Function for performing bitwise AND operation on two multi-byte bit masks.
+ *
+ * @param p_mask1 A pointer to the first bit mask.
+ * @param p_mask2 A pointer to the second bit mask.
+ * @param p_mask_out A pointer to the output bit mask.
+ * @param length Length of output mask in bytes.
+ */
+__STATIC_INLINE void nrf_bitmask_masks_and(void const * p_mask1,
+ void const * p_mask2,
+ void * p_out_mask,
+ uint32_t length)
+{
+ uint8_t const * p_mask8_1 = (uint8_t const *)p_mask1;
+ uint8_t const * p_mask8_2 = (uint8_t const *)p_mask2;
+ uint8_t * p_mask8_out = (uint8_t *)p_out_mask;
+ uint32_t i;
+ for (i = 0; i < length; i++)
+ {
+ p_mask8_out[i] = p_mask8_1[i] & p_mask8_2[i];
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //NRF_BITMASK_H
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/util/sdk_common.h b/hw/mcu/nordic/nrf52/sdk/libraries/util/sdk_common.h
new file mode 100644
index 000000000..54ef51c4f
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/util/sdk_common.h
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/** @cond */
+/**@file
+ *
+ * @ingroup experimental_api
+ * @defgroup sdk_common SDK Common Header
+ * @brief All common headers needed for SDK examples will be included here so that application
+ * developer does not have to include headers on him/herself.
+ * @{
+ */
+
+#ifndef SDK_COMMON_H__
+#define SDK_COMMON_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include "sdk_config.h"
+#include "nordic_common.h"
+#include "compiler_abstraction.h"
+#include "sdk_os.h"
+#include "sdk_errors.h"
+#include "app_util.h"
+#include "sdk_macros.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @} */
+/** @endcond */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SDK_COMMON_H__
+
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/util/sdk_errors.h b/hw/mcu/nordic/nrf52/sdk/libraries/util/sdk_errors.h
new file mode 100644
index 000000000..96920fc61
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/util/sdk_errors.h
@@ -0,0 +1,166 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup sdk_error SDK Error codes
+ * @{
+ * @ingroup app_common
+ * @{
+ * @details Error codes are 32-bit unsigned integers with the most significant 16-bit reserved for
+ * identifying the module where the error occurred while the least least significant LSB
+ * are used to provide the cause or nature of error. Each module is assigned a 16-bit
+ * unsigned integer. Which it will use to identify all errors that occurred in it. 16-bit
+ * LSB range is with module id as the MSB in the 32-bit error code is reserved for the
+ * module. As an example, if 0x8800 identifies a certain SDK module, all values from
+ * 0x88000000 - 0x8800FFFF are reserved for this module.
+ * It should be noted that common error reasons have been assigned values to make it
+ * possible to decode error reason easily. As an example, lets module uninitialized has
+ * been assigned an error code 0x000A0. Then, if application encounters an error code
+ * 0xZZZZ00A0, it knows that it accessing a certain module without initializing it.
+ * Apart from this, each module is allowed to define error codes that are not covered by
+ * the common ones, however, these values are defined in a range that does not conflict
+ * with common error values. For module, specific error however, it is possible that the
+ * same error value is used by two different modules to indicated errors of very different
+ * nature. If error is already defined by the NRF common error codes, these are reused.
+ * A range is reserved for application as well, it can use this range for defining
+ * application specific errors.
+ *
+ * @note Success code, NRF_SUCCESS, does not include any module identifier.
+
+ */
+
+#ifndef SDK_ERRORS_H__
+#define SDK_ERRORS_H__
+
+#include <stdint.h>
+#include "nrf_error.h"
+#include "sdk_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup sdk_err_base Base defined for SDK Modules
+ * @{
+ */
+#define NRF_ERROR_SDK_ERROR_BASE (NRF_ERROR_BASE_NUM + 0x8000) /**< Base value defined for SDK module identifiers. */
+#define NRF_ERROR_SDK_COMMON_ERROR_BASE (NRF_ERROR_BASE_NUM + 0x0080) /**< Base error value to be used for SDK error values. */
+/** @} */
+
+/**
+ * @defgroup sdk_module_codes Codes reserved as identification for module where the error occurred.
+ * @{
+ */
+#define NRF_ERROR_MEMORY_MANAGER_ERR_BASE (0x8100)
+#define NRF_ERROR_PERIPH_DRIVERS_ERR_BASE (0x8200)
+#define NRF_ERROR_GAZELLE_ERR_BASE (0x8300)
+#define NRF_ERROR_BLE_IPSP_ERR_BASE (0x8400)
+/** @} */
+
+
+/**
+ * @defgroup sdk_iot_errors Codes reserved as identification for IoT errors.
+ * @{
+ */
+#define NRF_ERROR_IOT_ERR_BASE_START (0xA000)
+#define NRF_ERROR_IOT_ERR_BASE_STOP (0xAFFF)
+/** @} */
+
+
+/**
+ * @defgroup sdk_common_errors Codes reserved as identification for common errors.
+ * @{
+ */
+#define NRF_ERROR_MODULE_NOT_INITIALZED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0000)
+#define NRF_ERROR_MUTEX_INIT_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0001)
+#define NRF_ERROR_MUTEX_LOCK_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0002)
+#define NRF_ERROR_MUTEX_UNLOCK_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0003)
+#define NRF_ERROR_MUTEX_COND_INIT_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0004)
+#define NRF_ERROR_MODULE_ALREADY_INITIALIZED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0005)
+#define NRF_ERROR_STORAGE_FULL (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0006)
+#define NRF_ERROR_API_NOT_IMPLEMENTED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0010)
+#define NRF_ERROR_FEATURE_NOT_ENABLED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0011)
+/** @} */
+
+
+/**
+ * @defgroup drv_specific_errors Error / status codes specific to drivers.
+ * @{
+ */
+#define NRF_ERROR_DRV_TWI_ERR_OVERRUN (NRF_ERROR_PERIPH_DRIVERS_ERR_BASE + 0x0000)
+#define NRF_ERROR_DRV_TWI_ERR_ANACK (NRF_ERROR_PERIPH_DRIVERS_ERR_BASE + 0x0001)
+#define NRF_ERROR_DRV_TWI_ERR_DNACK (NRF_ERROR_PERIPH_DRIVERS_ERR_BASE + 0x0002)
+/** @} */
+
+
+/**
+ * @defgroup ble_ipsp_errors IPSP codes
+ * @brief Error and status codes specific to IPSP.
+ * @{
+ */
+#define NRF_ERROR_BLE_IPSP_RX_PKT_TRUNCATED (NRF_ERROR_BLE_IPSP_ERR_BASE + 0x0000)
+#define NRF_ERROR_BLE_IPSP_CHANNEL_ALREADY_EXISTS (NRF_ERROR_BLE_IPSP_ERR_BASE + 0x0001)
+#define NRF_ERROR_BLE_IPSP_LINK_DISCONNECTED (NRF_ERROR_BLE_IPSP_ERR_BASE + 0x0002)
+#define NRF_ERROR_BLE_IPSP_PEER_REJECTED (NRF_ERROR_BLE_IPSP_ERR_BASE + 0x0003)
+/* @} */
+
+
+/**
+ * @brief API Result.
+ *
+ * @details Indicates success or failure of an API procedure. In case of failure, a comprehensive
+ * error code indicating cause or reason for failure is provided.
+ *
+ * Though called an API result, it could used in Asynchronous notifications callback along
+ * with asynchronous callback as event result. This mechanism is employed when an event
+ * marks the end of procedure initiated using API. API result, in this case, will only be
+ * an indicative of whether the procedure has been requested successfully.
+ */
+typedef uint32_t ret_code_t;
+
+/** @} */
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SDK_ERRORS_H__
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/util/sdk_macros.h b/hw/mcu/nordic/nrf52/sdk/libraries/util/sdk_macros.h
new file mode 100644
index 000000000..01dcdf5d4
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/util/sdk_macros.h
@@ -0,0 +1,191 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+
+ * @defgroup sdk_common_macros SDK Common Header
+ * @ingroup app_common
+ * @brief Macros for parameter checking and similar tasks
+ * @{
+ */
+
+#ifndef SDK_MACROS_H__
+#define SDK_MACROS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief Macro for verifying statement to be true. It will cause the exterior function to return
+ * err_code if the statement is not true.
+ *
+ * @param[in] statement Statement to test.
+ * @param[in] err_code Error value to return if test was invalid.
+ *
+ * @retval nothing, but will cause the exterior function to return @p err_code if @p statement
+ * is false.
+ */
+#define VERIFY_TRUE(statement, err_code) \
+do \
+{ \
+ if (!(statement)) \
+ { \
+ return err_code; \
+ } \
+} while (0)
+
+
+/**@brief Macro for verifying statement to be true. It will cause the exterior function to return
+ * if the statement is not true.
+ *
+ * @param[in] statement Statement to test.
+ */
+#define VERIFY_TRUE_VOID(statement) VERIFY_TRUE((statement), )
+
+
+/**@brief Macro for verifying statement to be false. It will cause the exterior function to return
+ * err_code if the statement is not false.
+ *
+ * @param[in] statement Statement to test.
+ * @param[in] err_code Error value to return if test was invalid.
+ *
+ * @retval nothing, but will cause the exterior function to return @p err_code if @p statement
+ * is true.
+ */
+#define VERIFY_FALSE(statement, err_code) \
+do \
+{ \
+ if ((statement)) \
+ { \
+ return err_code; \
+ } \
+} while (0)
+
+
+/**@brief Macro for verifying statement to be false. It will cause the exterior function to return
+ * if the statement is not false.
+ *
+ * @param[in] statement Statement to test.
+ */
+#define VERIFY_FALSE_VOID(statement) VERIFY_FALSE((statement), )
+
+
+/**@brief Macro for verifying that a function returned NRF_SUCCESS. It will cause the exterior
+ * function to return err_code if the err_code is not @ref NRF_SUCCESS.
+ *
+ * @param[in] err_code The error code to check.
+ */
+#ifdef DISABLE_PARAM_CHECK
+#define VERIFY_SUCCESS()
+#else
+#define VERIFY_SUCCESS(err_code) VERIFY_TRUE((err_code) == NRF_SUCCESS, (err_code))
+#endif /* DISABLE_PARAM_CHECK */
+
+
+/**@brief Macro for verifying that a function returned NRF_SUCCESS. It will cause the exterior
+ * function to return if the err_code is not @ref NRF_SUCCESS.
+ *
+ * @param[in] err_code The error code to check.
+ */
+#ifdef DISABLE_PARAM_CHECK
+#define VERIFY_SUCCESS_VOID()
+#else
+#define VERIFY_SUCCESS_VOID(err_code) VERIFY_TRUE_VOID((err_code) == NRF_SUCCESS)
+#endif /* DISABLE_PARAM_CHECK */
+
+
+/**@brief Macro for verifying that the module is initialized. It will cause the exterior function to
+ * return @ref NRF_ERROR_INVALID_STATE if not.
+ *
+ * @note MODULE_INITIALIZED must be defined in each module using this macro. MODULE_INITIALIZED
+ * should be true if the module is initialized, false if not.
+ */
+#ifdef DISABLE_PARAM_CHECK
+#define VERIFY_MODULE_INITIALIZED()
+#else
+#define VERIFY_MODULE_INITIALIZED() VERIFY_TRUE((MODULE_INITIALIZED), NRF_ERROR_INVALID_STATE)
+#endif /* DISABLE_PARAM_CHECK */
+
+
+/**@brief Macro for verifying that the module is initialized. It will cause the exterior function to
+ * return if not.
+ *
+ * @note MODULE_INITIALIZED must be defined in each module using this macro. MODULE_INITIALIZED
+ * should be true if the module is initialized, false if not.
+ */
+#ifdef DISABLE_PARAM_CHECK
+#define VERIFY_MODULE_INITIALIZED_VOID()
+#else
+#define VERIFY_MODULE_INITIALIZED_VOID() VERIFY_TRUE_VOID((MODULE_INITIALIZED))
+#endif /* DISABLE_PARAM_CHECK */
+
+
+/**@brief Macro for verifying that the module is initialized. It will cause the exterior function to
+ * return if not.
+ *
+ * @param[in] param The variable to check if is NULL.
+ */
+#ifdef DISABLE_PARAM_CHECK
+#define VERIFY_PARAM_NOT_NULL()
+#else
+#define VERIFY_PARAM_NOT_NULL(param) VERIFY_FALSE(((param) == NULL), NRF_ERROR_NULL)
+#endif /* DISABLE_PARAM_CHECK */
+
+
+/**@brief Macro for verifying that the module is initialized. It will cause the exterior function to
+ * return if not.
+ *
+ * @param[in] param The variable to check if is NULL.
+ */
+#ifdef DISABLE_PARAM_CHECK
+#define VERIFY_PARAM_NOT_NULL_VOID()
+#else
+#define VERIFY_PARAM_NOT_NULL_VOID(param) VERIFY_FALSE_VOID(((param) == NULL))
+#endif /* DISABLE_PARAM_CHECK */
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SDK_MACROS_H__
+
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/util/sdk_mapped_flags.c b/hw/mcu/nordic/nrf52/sdk/libraries/util/sdk_mapped_flags.c
new file mode 100644
index 000000000..1a99ac382
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/util/sdk_mapped_flags.c
@@ -0,0 +1,220 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "sdk_mapped_flags.h"
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include "compiler_abstraction.h"
+
+
+// Test whether the flag collection type is large enough to hold all the flags. If this fails,
+// reduce SDK_MAPPED_FLAGS_N_KEYS or increase the size of sdk_mapped_flags_t.
+STATIC_ASSERT((sizeof(sdk_mapped_flags_t) * SDK_MAPPED_FLAGS_N_KEYS_PER_BYTE) >= SDK_MAPPED_FLAGS_N_KEYS);
+
+
+/**@brief Function for setting the state of a flag to true.
+ *
+ * @note This function does not check whether the index is valid.
+ *
+ * @param[in] p_flags The collection of flags to modify.
+ * @param[in] index The index of the flag to modify.
+ */
+static __INLINE void sdk_mapped_flags_set_by_index(sdk_mapped_flags_t * p_flags, uint16_t index)
+{
+ *p_flags |= (1U << index);
+}
+
+
+/**@brief Function for setting the state of a flag to false.
+ *
+ * @note This function does not check whether the index is valid.
+ *
+ * @param[in] p_flags The collection of flags to modify.
+ * @param[in] index The index of the flag to modify.
+ */
+static __INLINE void sdk_mapped_flags_clear_by_index(sdk_mapped_flags_t * p_flags, uint16_t index)
+{
+ *p_flags &= ~(1U << index);
+}
+
+
+/**@brief Function for getting the state of a flag.
+ *
+ * @note This function does not check whether the index is valid.
+ *
+ * @param[in] p_flags The collection of flags to read.
+ * @param[in] index The index of the flag to get.
+ */
+static __INLINE bool sdk_mapped_flags_get_by_index(sdk_mapped_flags_t flags, uint16_t index)
+{
+ return ((flags & (1 << index)) != 0);
+}
+
+
+
+uint16_t sdk_mapped_flags_first_key_index_get(sdk_mapped_flags_t flags)
+{
+ for (uint16_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++)
+ {
+ if (sdk_mapped_flags_get_by_index(flags, i))
+ {
+ return i;
+ }
+ }
+ return SDK_MAPPED_FLAGS_INVALID_INDEX;
+}
+
+
+void sdk_mapped_flags_update_by_key(uint16_t * p_keys,
+ sdk_mapped_flags_t * p_flags,
+ uint16_t key,
+ bool value)
+{
+ sdk_mapped_flags_bulk_update_by_key(p_keys, p_flags, 1, key, value);
+}
+
+
+void sdk_mapped_flags_bulk_update_by_key(uint16_t * p_keys,
+ sdk_mapped_flags_t * p_flags,
+ uint32_t n_flag_collections,
+ uint16_t key,
+ bool value)
+{
+ if ((p_keys != NULL) && (p_flags != NULL) && (n_flag_collections > 0))
+ {
+ for (uint32_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++)
+ {
+ if (p_keys[i] == key)
+ {
+ for (uint32_t j = 0; j < n_flag_collections; j++)
+ {
+ if (value)
+ {
+ sdk_mapped_flags_set_by_index(&p_flags[j], i);
+ }
+ else
+ {
+ sdk_mapped_flags_clear_by_index(&p_flags[j], i);
+ }
+ }
+ return;
+ }
+ }
+ }
+}
+
+
+bool sdk_mapped_flags_get_by_key_w_idx(uint16_t * p_keys,
+ sdk_mapped_flags_t flags,
+ uint16_t key,
+ uint8_t * p_index)
+{
+ if (p_keys != NULL)
+ {
+ for (uint32_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++)
+ {
+ if (p_keys[i] == key)
+ {
+ if (p_index != NULL)
+ {
+ *p_index = i;
+ }
+ return sdk_mapped_flags_get_by_index(flags, i);
+ }
+ }
+ }
+ if (p_index != NULL)
+ {
+ *p_index = SDK_MAPPED_FLAGS_N_KEYS;
+ }
+ return false;
+}
+
+
+bool sdk_mapped_flags_get_by_key(uint16_t * p_keys, sdk_mapped_flags_t flags, uint16_t key)
+{
+ if (p_keys != NULL)
+ {
+ for (uint32_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++)
+ {
+ if (p_keys[i] == key)
+ {
+ return sdk_mapped_flags_get_by_index(flags, i);
+ }
+ }
+ }
+ return false;
+}
+
+
+sdk_mapped_flags_key_list_t sdk_mapped_flags_key_list_get(uint16_t * p_keys,
+ sdk_mapped_flags_t flags)
+{
+ sdk_mapped_flags_key_list_t key_list;
+ key_list.len = 0;
+
+ if (p_keys != NULL)
+ {
+ for (uint32_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++)
+ {
+ if (sdk_mapped_flags_get_by_index(flags, i))
+ {
+ key_list.flag_keys[key_list.len++] = p_keys[i];
+ }
+ }
+ }
+
+ return key_list;
+}
+
+
+uint32_t sdk_mapped_flags_n_flags_set(sdk_mapped_flags_t flags)
+{
+ uint32_t n_flags_set = 0;
+
+ for (uint32_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++)
+ {
+ if (sdk_mapped_flags_get_by_index(flags, i))
+ {
+ n_flags_set += 1;
+ }
+ }
+ return n_flags_set;
+}
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/util/sdk_mapped_flags.h b/hw/mcu/nordic/nrf52/sdk/libraries/util/sdk_mapped_flags.h
new file mode 100644
index 000000000..1f9033909
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/util/sdk_mapped_flags.h
@@ -0,0 +1,199 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 SDK_MAPPED_FLAGS_H__
+#define SDK_MAPPED_FLAGS_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "app_util.h"
+#include "compiler_abstraction.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file
+ * @defgroup sdk_mapped_flags Mapped flags
+ * @ingroup app_common
+ * @{
+ * @brief Module for writing and reading flags that are associated
+ * with keys.
+ *
+ * @details The flags are represented as bits in a bitmap called a <i>flag collection</i>. The keys
+ * are uint16_t. Each flag collection contains all flags of the same type, one flag for
+ * each key.
+ *
+ * The mapped flags module does not keep the flag states, nor the list of keys. These are
+ * provided in the API calls. A key's index in the key list determines which bit in the
+ * flag collection is associated with it. This module does not ever edit the key list, and
+ * does not edit flags except in function calls that take the flag collection as a pointer.
+ *
+ */
+
+#define SDK_MAPPED_FLAGS_N_KEYS 32 /**< The number of keys to keep flags for. This is also the number of flags in a flag collection. If changing this value, you might also need change the width of the sdk_mapped_flags_t type. */
+#define SDK_MAPPED_FLAGS_N_KEYS_PER_BYTE 8 /**< The number of flags that fit in one byte. */
+#define SDK_MAPPED_FLAGS_INVALID_INDEX 0xFFFF /**< A flag index guaranteed to be invalid. */
+
+typedef uint32_t sdk_mapped_flags_t; /**< The bitmap to hold flags. Each flag is one bit, and each bit represents the flag state associated with one key. */
+
+
+/**@brief Type used to present a subset of the registered keys.
+ */
+typedef struct
+{
+ uint32_t len; /**< The length of the list. */
+ uint16_t flag_keys[SDK_MAPPED_FLAGS_N_KEYS]; /**< The list of keys. */
+} sdk_mapped_flags_key_list_t;
+
+
+/**@brief Function for getting the first index at which the flag is true in the provided
+ * collection.
+ *
+ * @param[in] flags The flag collection to search for a flag set to true.
+ *
+ * @return The first index that has its flag set to true. If none were found, the
+ * function returns @ref SDK_MAPPED_FLAGS_INVALID_INDEX.
+ */
+uint16_t sdk_mapped_flags_first_key_index_get(sdk_mapped_flags_t flags);
+
+
+/**@brief Function for updating the state of a flag.
+ *
+ * @param[in] p_keys The list of associated keys (assumed to have a length of
+ * @ref SDK_MAPPED_FLAGS_N_KEYS).
+ * @param[out] p_flags The flag collection to modify.
+ * @param[in] key The key to modify the flag of.
+ * @param[in] value The state to set the flag to.
+ */
+void sdk_mapped_flags_update_by_key(uint16_t * p_keys,
+ sdk_mapped_flags_t * p_flags,
+ uint16_t key,
+ bool value);
+
+
+/**@brief Function for updating the state of the same flag in multiple flag collections.
+ *
+ * @details The key and value are the same for all flag collections in the p_flags array.
+ *
+ * @param[in] p_keys The list of associated keys (assumed to have a length of
+ * @ref SDK_MAPPED_FLAGS_N_KEYS).
+ * @param[out] p_flags The flag collections to modify.
+ * @param[out] n_flag_collections The number of flag collections in p_flags.
+ * @param[in] key The key to modify the flag of.
+ * @param[in] value The state to set the flag to.
+ */
+void sdk_mapped_flags_bulk_update_by_key(uint16_t * p_keys,
+ sdk_mapped_flags_t * p_flags,
+ uint32_t n_flag_collections,
+ uint16_t key,
+ bool value);
+
+
+/**@brief Function for getting the state of a specific flag.
+ *
+ * @param[in] p_keys The list of associated keys (assumed to have a length of
+ * @ref SDK_MAPPED_FLAGS_N_KEYS).
+ * @param[in] flags The flag collection to read from.
+ * @param[in] key The key to get the flag for.
+ *
+ * @return The state of the flag.
+ */
+bool sdk_mapped_flags_get_by_key(uint16_t * p_keys, sdk_mapped_flags_t flags, uint16_t key);
+
+
+/**@brief Function for getting the state of a specific flag.
+ *
+ * @param[in] p_keys The list of associated keys (assumed to have a length of
+ * @ref SDK_MAPPED_FLAGS_N_KEYS).
+ * @param[in] flags The flag collection from which to read.
+ * @param[in] key The key for which to get the flag.
+ * @param[out] p_index If not NULL, the index of the key.
+ *
+ * @return The state of the flag.
+ */
+bool sdk_mapped_flags_get_by_key_w_idx(uint16_t * p_keys,
+ sdk_mapped_flags_t flags,
+ uint16_t key,
+ uint8_t * p_index);
+
+
+/**@brief Function for getting a list of all keys that have a specific flag set to true.
+ *
+ * @param[in] p_keys The list of associated keys (assumed to have a length of
+ * @ref SDK_MAPPED_FLAGS_N_KEYS).
+ * @param[in] flags The flag collection to search.
+ *
+ * @return The list of keys.
+ */
+sdk_mapped_flags_key_list_t sdk_mapped_flags_key_list_get(uint16_t * p_keys,
+ sdk_mapped_flags_t flags);
+
+
+/**@brief Function for getting the number of keys that have a specific flag set to true.
+ *
+ * @param[in] flags The flag collection to search.
+ *
+ * @return The number of keys.
+ */
+uint32_t sdk_mapped_flags_n_flags_set(sdk_mapped_flags_t flags);
+
+
+/**@brief Function for querying whether any flags in the collection are set.
+ *
+ * @param[in] flags The flag collection to query.
+ *
+ * @retval true If one or more flags are set to true.
+ * @retval false Otherwise.
+ */
+static __INLINE bool sdk_mapped_flags_any_set(sdk_mapped_flags_t flags)
+{
+ return (flags != 0);
+}
+
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SDK_MAPPED_FLAGS_H__ */
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/util/sdk_os.h b/hw/mcu/nordic/nrf52/sdk/libraries/util/sdk_os.h
new file mode 100644
index 000000000..c1660070b
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/util/sdk_os.h
@@ -0,0 +1,76 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/** @cond */
+/**@file
+ *
+ * @defgroup sdk_os SDK OS Abstraction
+ * @ingroup experimental_api
+ * @details In order to made SDK modules independent of use of an embedded OS, and permit
+ * application with varied task architecture, SDK abstracts the OS specific
+ * elements here in order to make all other modules agnostic to the OS or task
+ * architecture.
+ * @{
+ */
+
+#ifndef SDK_OS_H__
+#define SDK_OS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SDK_MUTEX_DEFINE(X)
+#define SDK_MUTEX_INIT(X)
+#define SDK_MUTEX_LOCK(X)
+#define SDK_MUTEX_UNLOCK(X)
+
+/**
+ * @defgroup os_data_type Data types.
+ */
+
+/** @} */
+/** @endcond */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SDK_OS_H__
+
diff --git a/hw/mcu/nordic/nrf52/sdk/libraries/util/sdk_resources.h b/hw/mcu/nordic/nrf52/sdk/libraries/util/sdk_resources.h
new file mode 100644
index 000000000..91d2af129
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/libraries/util/sdk_resources.h
@@ -0,0 +1,86 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ * @brief Definition file for resource usage by SoftDevice, ESB and Gazell.
+ */
+
+#ifndef APP_RESOURCES_H__
+#define APP_RESOURCES_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef SOFTDEVICE_PRESENT
+ #include "nrf_sd_def.h"
+#else
+ #define SD_PPI_RESTRICTED 0uL /**< 1 if PPI peripheral is restricted, 0 otherwise. */
+ #define SD_PPI_CHANNELS_USED 0uL /**< PPI channels utilized by SotfDevice (not available to th spplication). */
+ #define SD_PPI_GROUPS_USED 0uL /**< PPI groups utilized by SotfDevice (not available to th spplication). */
+ #define SD_TIMERS_USED 0uL /**< Timers used by SoftDevice. */
+ #define SD_SWI_USED 0uL /**< Software interrupts used by SoftDevice. */
+#endif
+
+#ifdef GAZELL_PRESENT
+ #include "nrf_gzll_resources.h"
+#else
+ #define GZLL_PPI_CHANNELS_USED 0uL /**< PPI channels utilized by Gazell (not available to th spplication). */
+ #define GZLL_TIMERS_USED 0uL /**< Timers used by Gazell. */
+ #define GZLL_SWI_USED 0uL /**< Software interrupts used by Gazell */
+#endif
+
+#ifdef ESB_PRESENT
+ #include "nrf_esb_resources.h"
+#else
+ #define ESB_PPI_CHANNELS_USED 0uL /**< PPI channels utilized by ESB (not available to th spplication). */
+ #define ESB_TIMERS_USED 0uL /**< Timers used by ESB. */
+ #define ESB_SWI_USED 0uL /**< Software interrupts used by ESB */
+#endif
+
+#define NRF_PPI_CHANNELS_USED (SD_PPI_CHANNELS_USED | GZLL_PPI_CHANNELS_USED | ESB_PPI_CHANNELS_USED)
+#define NRF_PPI_GROUPS_USED (SD_PPI_GROUPS_USED)
+#define NRF_SWI_USED (SD_SWI_USED | GZLL_SWI_USED | ESB_SWI_USED)
+#define NRF_TIMERS_USED (SD_TIMERS_USED | GZLL_TIMERS_USED | ESB_TIMERS_USED)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // APP_RESOURCES_H__
diff --git a/hw/mcu/nordic/nrf52/sdk/sdk_config.h b/hw/mcu/nordic/nrf52/sdk/sdk_config.h
index fa1f4182e..af867e1d8 100644
--- a/hw/mcu/nordic/nrf52/sdk/sdk_config.h
+++ b/hw/mcu/nordic/nrf52/sdk/sdk_config.h
@@ -58,7 +58,7 @@
// <e> CLOCK_ENABLED - nrf_drv_clock - CLOCK peripheral driver
//==========================================================
#ifndef CLOCK_ENABLED
-#define CLOCK_ENABLED 1
+#define CLOCK_ENABLED 0
#endif
// <o> CLOCK_CONFIG_XTAL_FREQ - HF XTAL Frequency
@@ -540,7 +540,7 @@
#ifndef NRF_FPRINTF_ENABLED
-#define NRF_FPRINTF_ENABLED 1
+#define NRF_FPRINTF_ENABLED 0
#endif
// <q> NRF_MEMOBJ_ENABLED - nrf_memobj - Linked memory allocator module
diff --git a/hw/mcu/nordic/nrf52/sdk/softdevice/common/nrf_sdh.c b/hw/mcu/nordic/nrf52/sdk/softdevice/common/nrf_sdh.c
new file mode 100644
index 000000000..ae7ebb3e3
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/softdevice/common/nrf_sdh.c
@@ -0,0 +1,422 @@
+/**
+ * Copyright (c) 2017 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_SDH)
+
+#include "nrf_sdh.h"
+
+#include <stdint.h>
+
+#include "nrf_sdm.h"
+#include "nrf_nvic.h"
+#include "sdk_config.h"
+#include "app_error.h"
+#include "app_util_platform.h"
+
+
+#define NRF_LOG_MODULE_NAME nrf_sdh
+#if NRF_SDH_LOG_ENABLED
+ #define NRF_LOG_LEVEL NRF_SDH_LOG_LEVEL
+ #define NRF_LOG_INFO_COLOR NRF_SDH_INFO_COLOR
+ #define NRF_LOG_DEBUG_COLOR NRF_SDH_DEBUG_COLOR
+#else
+ #define NRF_LOG_LEVEL 0
+#endif // NRF_SDH_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#if (NRF_SDH_DISPATCH_MODEL == NRF_SDH_DISPATCH_MODEL_APPSH)
+ #if !APP_SCHEDULER_ENABLED
+ #error "APP_SCHEDULER is required."
+ #endif
+ #include "app_scheduler.h"
+#endif // (NRF_SDH_DISPATCH_MODEL == NRF_SDH_DISPATCH_MODEL_APPSH)
+
+
+// Create section "sdh_req_observers".
+NRF_SECTION_SET_DEF(sdh_req_observers, nrf_sdh_req_observer_t, NRF_SDH_REQ_OBSERVER_PRIO_LEVELS);
+
+// Create section "sdh_state_observers".
+NRF_SECTION_SET_DEF(sdh_state_observers, nrf_sdh_state_observer_t, NRF_SDH_STATE_OBSERVER_PRIO_LEVELS);
+
+// Create section "sdh_stack_observers".
+NRF_SECTION_SET_DEF(sdh_stack_observers, nrf_sdh_stack_observer_t, NRF_SDH_STACK_OBSERVER_PRIO_LEVELS);
+
+
+static bool m_nrf_sdh_enabled; /**< Variable to indicate whether the SoftDevice is enabled. */
+static bool m_nrf_sdh_suspended; /**< Variable to indicate whether this module is suspended. */
+static bool m_nrf_sdh_continue; /**< Variable to indicate whether enable/disable process was started. */
+
+
+/**@brief Function for notifying request observers.
+ *
+ * @param[in] evt Type of request event.
+ */
+static ret_code_t sdh_request_observer_notify(nrf_sdh_req_evt_t req)
+{
+ nrf_section_iter_t iter;
+
+ NRF_LOG_DEBUG("State request: 0x%08X", req);
+
+ for (nrf_section_iter_init(&iter, &sdh_req_observers);
+ nrf_section_iter_get(&iter) != NULL;
+ nrf_section_iter_next(&iter))
+ {
+ nrf_sdh_req_observer_t * p_observer;
+ nrf_sdh_req_evt_handler_t handler;
+
+ p_observer = (nrf_sdh_req_observer_t *) nrf_section_iter_get(&iter);
+ handler = p_observer->handler;
+
+ if (handler(req, p_observer->p_context))
+ {
+ NRF_LOG_DEBUG("Notify observer 0x%08X => ready", p_observer);
+ }
+ else
+ {
+ // Process is stopped.
+ NRF_LOG_DEBUG("Notify observer 0x%08X => blocking", p_observer);
+ return NRF_ERROR_BUSY;
+ }
+ }
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for stage request observers.
+ *
+ * @param[in] evt Type of stage event.
+ */
+static void sdh_state_observer_notify(nrf_sdh_state_evt_t evt)
+{
+ nrf_section_iter_t iter;
+
+ NRF_LOG_DEBUG("State change: 0x%08X", evt);
+
+ for (nrf_section_iter_init(&iter, &sdh_state_observers);
+ nrf_section_iter_get(&iter) != NULL;
+ nrf_section_iter_next(&iter))
+ {
+ nrf_sdh_state_observer_t * p_observer;
+ nrf_sdh_state_evt_handler_t handler;
+
+ p_observer = (nrf_sdh_state_observer_t *) nrf_section_iter_get(&iter);
+ handler = p_observer->handler;
+
+ handler(evt, p_observer->p_context);
+ }
+}
+
+
+static void softdevices_evt_irq_enable(void)
+{
+#ifdef SOFTDEVICE_PRESENT
+ ret_code_t ret_code = sd_nvic_EnableIRQ((IRQn_Type)SD_EVT_IRQn);
+ APP_ERROR_CHECK(ret_code);
+#else
+ // In case of serialization, NVIC must be accessed directly.
+ NVIC_EnableIRQ(SD_EVT_IRQn);
+#endif
+}
+
+
+static void softdevice_evt_irq_disable(void)
+{
+#ifdef SOFTDEVICE_PRESENT
+ ret_code_t ret_code = sd_nvic_DisableIRQ((IRQn_Type)SD_EVT_IRQn);
+ APP_ERROR_CHECK(ret_code);
+#else
+ // In case of serialization, NVIC must be accessed directly.
+ NVIC_DisableIRQ(SD_EVT_IRQn);
+#endif
+}
+
+
+#ifndef S140
+static void swi_interrupt_priority_workaround(void)
+{
+ // The priorities of SoftDevice SWI SD_EVT_IRQn and RADIO_NOTIFICATION_IRQn
+ // in version S132 v5.0.0, S112 v5.0.0, S212 v5.0.0 and S332 v5.0.0 are set to 6.
+ // Set their priority to APP_IRQ_PRIORITY_LOWEST (7) so that they don't preempt
+ // peripheral interrupts and vice-versa.
+
+#ifdef SOFTDEVICE_PRESENT
+ ret_code_t ret_code;
+ ret_code = sd_nvic_SetPriority(SD_EVT_IRQn, APP_IRQ_PRIORITY_LOWEST);
+ APP_ERROR_CHECK(ret_code);
+ ret_code = sd_nvic_SetPriority(RADIO_NOTIFICATION_IRQn, APP_IRQ_PRIORITY_LOWEST);
+ APP_ERROR_CHECK(ret_code);
+#else
+ // In case of serialization, NVIC must be accessed directly.
+ NVIC_SetPriority(SD_EVT_IRQn, APP_IRQ_PRIORITY_LOWEST);
+ NVIC_SetPriority(RADIO_NOTIFICATION_IRQn, APP_IRQ_PRIORITY_LOWEST);
+#endif
+}
+#endif
+
+
+ret_code_t nrf_sdh_enable_request(void)
+{
+ ret_code_t ret_code;
+
+ if (m_nrf_sdh_enabled)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ m_nrf_sdh_continue = true;
+
+ // Notify observers about SoftDevice enable request.
+ if (sdh_request_observer_notify(NRF_SDH_EVT_ENABLE_REQUEST) == NRF_ERROR_BUSY)
+ {
+ // Enable process was stopped.
+ return NRF_SUCCESS;
+ }
+
+ // Notify observers about starting SoftDevice enable process.
+ sdh_state_observer_notify(NRF_SDH_EVT_STATE_ENABLE_PREPARE);
+
+ nrf_clock_lf_cfg_t const clock_lf_cfg =
+ {
+ .source = NRF_SDH_CLOCK_LF_SRC,
+ .rc_ctiv = NRF_SDH_CLOCK_LF_RC_CTIV,
+ .rc_temp_ctiv = NRF_SDH_CLOCK_LF_RC_TEMP_CTIV,
+ #ifdef S140
+ .xtal_accuracy = NRF_SDH_CLOCK_LF_XTAL_ACCURACY
+ #else
+ .accuracy = NRF_SDH_CLOCK_LF_XTAL_ACCURACY
+ #endif
+ };
+
+ #ifdef ANT_LICENSE_KEY
+ ret_code = sd_softdevice_enable(&clock_lf_cfg, app_error_fault_handler, ANT_LICENSE_KEY);
+ #else
+ ret_code = sd_softdevice_enable(&clock_lf_cfg, app_error_fault_handler);
+ #endif
+
+ if (ret_code != NRF_SUCCESS)
+ {
+ return ret_code;
+ }
+
+ m_nrf_sdh_enabled = true;
+ m_nrf_sdh_continue = false;
+ m_nrf_sdh_suspended = false;
+
+#ifndef S140
+ // Set the interrupt priority after enabling the SoftDevice, since
+ // sd_softdevice_enable() sets the SoftDevice interrupt priority.
+ swi_interrupt_priority_workaround();
+#endif
+
+ // Enable event interrupt.
+ // Interrupt priority has already been set by the stack.
+ softdevices_evt_irq_enable();
+
+ // Notify observers about a finished SoftDevice enable process.
+ sdh_state_observer_notify(NRF_SDH_EVT_STATE_ENABLED);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_sdh_disable_request(void)
+{
+ ret_code_t ret_code;
+
+ if (!m_nrf_sdh_enabled)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ m_nrf_sdh_continue = true;
+
+ // Notify observers about SoftDevice disable request.
+ if (sdh_request_observer_notify(NRF_SDH_EVT_DISABLE_REQUEST) == NRF_ERROR_BUSY)
+ {
+ // Disable process was stopped.
+ return NRF_SUCCESS;
+ }
+
+ // Notify observers about starting SoftDevice disable process.
+ sdh_state_observer_notify(NRF_SDH_EVT_STATE_DISABLE_PREPARE);
+
+ ret_code = sd_softdevice_disable();
+ if (ret_code != NRF_SUCCESS)
+ {
+ return ret_code;
+ }
+
+ m_nrf_sdh_enabled = false;
+ m_nrf_sdh_continue = false;
+
+ softdevice_evt_irq_disable();
+
+ // Notify observers about a finished SoftDevice enable process.
+ sdh_state_observer_notify(NRF_SDH_EVT_STATE_DISABLED);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_sdh_request_continue(void)
+{
+ if (!m_nrf_sdh_continue)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (m_nrf_sdh_enabled)
+ {
+ return nrf_sdh_disable_request();
+ }
+ else
+ {
+ return nrf_sdh_enable_request();
+ }
+}
+
+
+bool nrf_sdh_is_enabled(void)
+{
+ return m_nrf_sdh_enabled;
+}
+
+
+void nrf_sdh_suspend(void)
+{
+ if (!m_nrf_sdh_enabled)
+ {
+ return;
+ }
+
+ softdevice_evt_irq_disable();
+ m_nrf_sdh_suspended = true;
+}
+
+
+void nrf_sdh_resume(void)
+{
+ if ((!m_nrf_sdh_suspended) || (!m_nrf_sdh_enabled))
+ {
+ return;
+ }
+
+ // Force calling ISR again to make sure that events not previously pulled have been processed.
+#ifdef SOFTDEVICE_PRESENT
+ ret_code_t ret_code = sd_nvic_SetPendingIRQ((IRQn_Type)SD_EVT_IRQn);
+ APP_ERROR_CHECK(ret_code);
+#else
+ NVIC_SetPendingIRQ((IRQn_Type)SD_EVT_IRQn);
+#endif
+
+ softdevices_evt_irq_enable();
+
+ m_nrf_sdh_suspended = false;
+}
+
+
+bool nrf_sdh_is_suspended(void)
+{
+ return (!m_nrf_sdh_enabled) || (m_nrf_sdh_suspended);
+}
+
+
+void nrf_sdh_evts_poll(void)
+{
+ nrf_section_iter_t iter;
+
+ // Notify observers about pending SoftDevice event.
+ for (nrf_section_iter_init(&iter, &sdh_stack_observers);
+ nrf_section_iter_get(&iter) != NULL;
+ nrf_section_iter_next(&iter))
+ {
+ nrf_sdh_stack_observer_t * p_observer;
+ nrf_sdh_stack_evt_handler_t handler;
+
+ p_observer = (nrf_sdh_stack_observer_t *) nrf_section_iter_get(&iter);
+ handler = p_observer->handler;
+
+ handler(p_observer->p_context);
+ }
+}
+
+
+#if (NRF_SDH_DISPATCH_MODEL == NRF_SDH_DISPATCH_MODEL_INTERRUPT)
+
+void SD_EVT_IRQHandler(void)
+{
+ nrf_sdh_evts_poll();
+}
+
+#elif (NRF_SDH_DISPATCH_MODEL == NRF_SDH_DISPATCH_MODEL_APPSH)
+
+/**@brief Function for polling SoftDevice events.
+ *
+ * @note This function is compatible with @ref app_sched_event_handler_t.
+ *
+ * @param[in] p_event_data Pointer to the event data.
+ * @param[in] event_size Size of the event data.
+ */
+static void appsh_events_poll(void * p_event_data, uint16_t event_size)
+{
+ UNUSED_PARAMETER(p_event_data);
+ UNUSED_PARAMETER(event_size);
+
+ nrf_sdh_evts_poll();
+}
+
+
+void SD_EVT_IRQHandler(void)
+{
+ ret_code_t ret_code = app_sched_event_put(NULL, 0, appsh_events_poll);
+ APP_ERROR_CHECK(ret_code);
+}
+
+#elif (NRF_SDH_DISPATCH_MODEL == NRF_SDH_DISPATCH_MODEL_POLLING)
+
+#else
+
+#error "Unknown SoftDevice handler dispatch model."
+
+#endif // NRF_SDH_DISPATCH_MODEL
+
+#endif // NRF_MODULE_ENABLED(NRF_SDH)
diff --git a/hw/mcu/nordic/nrf52/sdk/softdevice/common/nrf_sdh.h b/hw/mcu/nordic/nrf52/sdk/softdevice/common/nrf_sdh.h
new file mode 100644
index 000000000..2fbd0dd63
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/softdevice/common/nrf_sdh.h
@@ -0,0 +1,304 @@
+/**
+ * Copyright (c) 2017 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_sdh SoftDevice Handler
+ * @{
+ * @ingroup app_common
+ * @brief API for initializing and disabling the SoftDevice.
+ */
+
+#ifndef NRF_SDH_H__
+#define NRF_SDH_H__
+
+#include "sdk_config.h"
+#include "sdk_errors.h"
+#include "nrf_section_iter.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @name Softdevice Handler dispatch models
+ * @{
+ * @ingroup nrf_sdh */
+
+/**@brief SoftDevice events are passed to the application from the interrupt context. */
+#define NRF_SDH_DISPATCH_MODEL_INTERRUPT 0
+
+/**@brief SoftDevice events are passed to the application using @ref app_scheduler.
+ *
+ * @note @ref app_scheduler must be initialized before enabling the SoftDevice handler.
+ */
+#define NRF_SDH_DISPATCH_MODEL_APPSH 1
+
+/**@brief SoftDevice events are polled manually using @ref nrf_sdh_evts_poll().
+ *
+ * @note In this mode, a user application can also implement SD_EVT_IRQHandler() to receive a
+ * notification about incoming events.
+ */
+#define NRF_SDH_DISPATCH_MODEL_POLLING 2
+
+/** @} */
+
+/**
+ * @name SoftDevice Handler state change requests
+ * @{
+ * @ingroup nrf_sdh */
+
+/**@brief SoftDevice Handler state requests. */
+typedef enum
+{
+ NRF_SDH_EVT_ENABLE_REQUEST, //!< Request to enable the SoftDevice.
+ NRF_SDH_EVT_DISABLE_REQUEST, //!< Request to disable the SoftDevice.
+} nrf_sdh_req_evt_t;
+
+/**@brief SoftDevice Handler state request handler.
+ *
+ * @retval true If ready for the SoftDevice to change state.
+ * @retval false If not ready for the SoftDevice to change state.
+ * If false is returned, the state change is aborted.
+ */
+typedef bool (*nrf_sdh_req_evt_handler_t)(nrf_sdh_req_evt_t request, void * p_context);
+
+/**@brief SoftDevice Handler state request observer. */
+typedef struct
+{
+ nrf_sdh_req_evt_handler_t handler; //!< Request handler.
+ void * p_context; //!< A parameter to the handler function.
+} const nrf_sdh_req_observer_t;
+
+/**@brief Macro for registering a SoftDevice state change request observer.
+ *
+ * An observer of SoftDevice state change requests receives requests to change the state of the
+ * SoftDevice from enabled to disabled and vice versa. These requests may or may not be acknowledged
+ * by the observer, depending on the value returned by its request handler function. Thus, a
+ * request observer has the capability to defer the change of state of the SoftDevice. If it does
+ * so, it has the responsibility to call @ref nrf_sdh_request_continue when it is ready to let the
+ * SoftDevice change its state. If such capability is not necessary and you only need to be informed
+ * about changes of the SoftDevice state, use the @ref NRF_SDH_STATE_OBSERVER macro instead.
+ *
+ * @note This macro places the observer in a section named "sdh_req_observers".
+ *
+ * @param[in] _observer Name of the observer.
+ * @param[in] _prio Priority of the observer's event handler.
+ * The smaller the number, the higher the priority.
+ * @hideinitializer
+ */
+#define NRF_SDH_REQUEST_OBSERVER(_observer, _prio) \
+STATIC_ASSERT(NRF_SDH_ENABLED, "NRF_SDH_ENABLED not set!"); \
+STATIC_ASSERT(_prio < NRF_SDH_REQ_OBSERVER_PRIO_LEVELS, "Priority level unavailable."); \
+/*lint -esym(528,*_observer) -esym(529,*_observer) : Symbol not referenced. */ \
+NRF_SECTION_SET_ITEM_REGISTER(sdh_req_observers, _prio, nrf_sdh_req_observer_t const _observer)
+
+/** @} */
+
+/**
+ * @name SoftDevice Handler state events
+ * @{
+ * @ingroup nrf_sdh */
+
+/**@brief SoftDevice Handler state events. */
+typedef enum
+{
+ NRF_SDH_EVT_STATE_ENABLE_PREPARE, //!< SoftDevice is going to be enabled.
+ NRF_SDH_EVT_STATE_ENABLED, //!< SoftDevice is enabled.
+ NRF_SDH_EVT_STATE_DISABLE_PREPARE, //!< SoftDevice is going to be disabled.
+ NRF_SDH_EVT_STATE_DISABLED, //!< SoftDevice is disabled.
+} nrf_sdh_state_evt_t;
+
+/**@brief SoftDevice Handler state event handler. */
+typedef void (*nrf_sdh_state_evt_handler_t)(nrf_sdh_state_evt_t state, void * p_context);
+
+/**@brief SoftDevice Handler state observer. */
+typedef struct
+{
+ nrf_sdh_state_evt_handler_t handler; //!< State event handler.
+ void * p_context; //!< A parameter to the event handler.
+} const nrf_sdh_state_observer_t;
+
+/**@brief Macro for registering a SoftDevice state observer.
+ *
+ * A SoftDevice state observer receives events when the SoftDevice state has changed or is
+ * about to change. These events are only meant to inform the state observer, which, contrary
+ * to a state change request observer, does not have the capability to defer the change of state.
+ * If such capability is required, use the @ref NRF_SDH_REQUEST_OBSERVER macro instead.
+ *
+ * This macro places the observer in a section named "sdh_state_observers".
+ *
+ * @param[in] _observer Name of the observer.
+ * @param[in] _prio Priority of the observer's event handler.
+ * The smaller the number, the higher the priority.
+ * @hideinitializer
+ */
+#define NRF_SDH_STATE_OBSERVER(_observer, _prio) \
+STATIC_ASSERT(NRF_SDH_ENABLED, "NRF_SDH_ENABLED not set!"); \
+STATIC_ASSERT(_prio < NRF_SDH_STATE_OBSERVER_PRIO_LEVELS, "Priority level unavailable."); \
+/*lint -esym(528,*_observer) -esym(529,*_observer) : Symbol not referenced. */ \
+NRF_SECTION_SET_ITEM_REGISTER(sdh_state_observers, _prio, static nrf_sdh_state_observer_t const _observer)
+
+/** @} */
+
+/**
+ * @name SoftDevice stack events
+ * @{
+ * @ingroup nrf_sdh */
+
+/**@brief SoftDevice stack event handler. */
+typedef void (*nrf_sdh_stack_evt_handler_t)(void * p_evt);
+
+/**@brief SoftDevice stack event observer. */
+typedef struct
+{
+ nrf_sdh_stack_evt_handler_t handler; //!< SoftDevice event handler.
+ void * p_context; //!< A parameter to the event handler.
+} const nrf_sdh_stack_observer_t;
+
+/**@brief Macro for registering a SoftDevice stack events observer.
+ *
+ * A SoftDevice stack event observer receives all events from the SoftDevice. These events can be
+ * either BLE, ANT, or SoC events. If you need to receive BLE, ANT, or SoC events separately, use the
+ * @ref NRF_SDH_BLE_OBSERVER, @ref NRF_SDH_ANT_OBSERVER, or @ref NRF_SDH_SOC_OBSERVER macros
+ * respectively.
+ *
+ * @note This macro places the observer in a section named "sdh_stack_observers".
+ *
+ * @param[in] _observer Name of the observer.
+ * @param[in] _prio Priority of the observer's event handler.
+ * The smaller the number, the higher the priority.
+ ** @hideinitializer
+ */
+#define NRF_SDH_STACK_OBSERVER(_observer, _prio) \
+STATIC_ASSERT(NRF_SDH_ENABLED, "NRF_SDH_ENABLED not set!"); \
+STATIC_ASSERT(_prio < NRF_SDH_STACK_OBSERVER_PRIO_LEVELS, "Priority level unavailable."); \
+/*lint -esym(528,*_observer) -esym(529,*_observer) : Symbol not referenced. */ \
+NRF_SECTION_SET_ITEM_REGISTER(sdh_stack_observers, _prio, static nrf_sdh_stack_observer_t const _observer)
+
+/** @} */
+
+/**@brief Function for requesting to enable the SoftDevice.
+ *
+ * This function issues a @ref NRF_SDH_EVT_ENABLE_REQUEST request to all observers that
+ * were registered using the @ref NRF_SDH_REQUEST_OBSERVER macro. The observers may or
+ * may not acknowledge the request. If all observers acknowledge the request, the
+ * SoftDevice will be enabled. Otherwise, the process will be stopped and the observers
+ * that did not acknowledge have the responsibility to restart it by calling
+ * @ref nrf_sdh_request_continue when they are ready for the SoftDevice to change state.
+ *
+ * @retval NRF_SUCCESS The process is started.
+ * @retval NRF_ERROR_INVALID_STATE The SoftDevice is already enabled.
+ */
+ret_code_t nrf_sdh_enable_request(void);
+
+
+/**@brief Function for requesting to disable the SoftDevice.
+ *
+ * This function issues a @ref NRF_SDH_EVT_DISABLE_REQUEST request to all observers that
+ * were registered using the @ref NRF_SDH_REQUEST_OBSERVER macro. The observers may or
+ * may not acknowledge the request. If all observers acknowledge the request, the
+ * SoftDevice will be disabled. Otherwise, the process will be stopped and the observers
+ * that did not acknowledge have the responsibility to restart it by calling
+ * @ref nrf_sdh_request_continue when they are ready for the SoftDevice to change state.
+ *
+ * @retval NRF_SUCCESS The process is started.
+ * @retval NRF_ERROR_INVALID_STATE The SoftDevice is already disabled.
+ */
+ret_code_t nrf_sdh_disable_request(void);
+
+
+/**@brief Function for restarting the SoftDevice Enable/Disable process.
+ *
+ * Modules which did not acknowledge a @ref NRF_SDH_EVT_ENABLE_REQUEST or
+ * @ref NRF_SDH_EVT_DISABLE_REQUEST request must call this function to restart the
+ * SoftDevice state change process.
+ *
+ * @retval NRF_SUCCESS The process is restarted.
+ * @retval NRF_ERROR_INVALID_STATE No state change request was pending.
+ */
+ret_code_t nrf_sdh_request_continue(void);
+
+
+/**@brief Function for retrieving the SoftDevice state.
+ *
+ * @retval true If the SoftDevice is enabled.
+ * @retval false If the SoftDevice is disabled.
+ */
+bool nrf_sdh_is_enabled(void);
+
+
+/**@brief Function for stopping the incoming stack events.
+ *
+ * This function disables the SoftDevice interrupt. To resume polling for events,
+ * call @ref nrf_sdh_resume.
+ */
+void nrf_sdh_suspend(void);
+
+
+/**@brief Function for resuming polling incoming events from the SoftDevice. */
+void nrf_sdh_resume(void);
+
+
+/**@brief Function for retrieving the information about the module state.
+ *
+ * @retval true The SoftDevice handler is paused, and it will not fetch events from the stack.
+ * @retval false The SoftDevice handler is running, and it will fetch and dispatch events from
+ * the stack to the registered stack observers.
+ */
+bool nrf_sdh_is_suspended(void);
+
+
+/**@brief Function for polling stack events from the SoftDevice.
+ *
+ * The events are passed to the application using the registered event handlers.
+ *
+ * @note @ref NRF_SDH_DISPATCH_MODEL_POLLING must be selected to use this function.
+ */
+void nrf_sdh_evts_poll(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_SDH_H__
+
+/** @} */
diff --git a/hw/mcu/nordic/nrf52/sdk/softdevice/common/nrf_sdh_ble.c b/hw/mcu/nordic/nrf52/sdk/softdevice/common/nrf_sdh_ble.c
new file mode 100644
index 000000000..990ba0af0
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/softdevice/common/nrf_sdh_ble.c
@@ -0,0 +1,300 @@
+/**
+ * Copyright (c) 2017 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_SDH_BLE)
+
+#include "nrf_sdh_ble.h"
+
+#include "nrf_sdh.h"
+#include "app_error.h"
+#include "nrf_strerror.h"
+
+
+#define NRF_LOG_MODULE_NAME nrf_sdh_ble
+#if NRF_SDH_BLE_LOG_ENABLED
+ #define NRF_LOG_LEVEL NRF_SDH_BLE_LOG_LEVEL
+ #define NRF_LOG_INFO_COLOR NRF_SDH_BLE_INFO_COLOR
+ #define NRF_LOG_DEBUG_COLOR NRF_SDH_BLE_DEBUG_COLOR
+#else
+ #define NRF_LOG_LEVEL 0
+#endif // NRF_SDH_BLE_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+// Create section set "sdh_ble_observers".
+NRF_SECTION_SET_DEF(sdh_ble_observers, nrf_sdh_ble_evt_observer_t, NRF_SDH_BLE_OBSERVER_PRIO_LEVELS);
+
+
+//lint -save -e10 -e19 -e40 -e27 Illegal character (0x24)
+#if defined(__CC_ARM)
+ extern uint32_t Image$$RW_IRAM1$$Base;
+ uint32_t const * const m_ram_start = &Image$$RW_IRAM1$$Base;
+#elif defined(__ICCARM__)
+ extern uint32_t __ICFEDIT_region_RAM_start__;
+ uint32_t const * const m_ram_start = &__ICFEDIT_region_RAM_start__;
+#elif defined(__SES_ARM)
+ extern uint32_t __app_ram_start__;
+ uint32_t const * const m_ram_start = &__app_ram_start__;
+#elif defined(__GNUC__)
+ extern uint32_t __data_start__;
+ uint32_t const * const m_ram_start = &__data_start__;
+#endif
+//lint -restore
+
+#define RAM_START 0x20000000
+#define APP_RAM_START (uint32_t)m_ram_start
+
+
+ret_code_t nrf_sdh_ble_app_ram_start_get(uint32_t * p_app_ram_start)
+{
+ if (p_app_ram_start == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ *p_app_ram_start = APP_RAM_START;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_sdh_ble_default_cfg_set(uint8_t conn_cfg_tag, uint32_t * p_ram_start)
+{
+ uint32_t ret_code;
+
+ ret_code = nrf_sdh_ble_app_ram_start_get(p_ram_start);
+ if (ret_code != NRF_SUCCESS)
+ {
+ return ret_code;
+ }
+
+#ifdef S112
+ STATIC_ASSERT(NRF_SDH_BLE_CENTRAL_LINK_COUNT == 0, "When using s112, NRF_SDH_BLE_CENTRAL_LINK_COUNT must be 0.");
+#endif
+
+ // Overwrite some of the default settings of the BLE stack.
+ // If any of the calls to sd_ble_cfg_set() fail, log the error but carry on so that
+ // wrong RAM settings can be caught by nrf_sdh_ble_enable() and a meaningful error
+ // message will be printed to the user suggesting the correct value.
+ ble_cfg_t ble_cfg;
+
+#if (NRF_SDH_BLE_TOTAL_LINK_COUNT != 0)
+ // Configure the connection count.
+ memset(&ble_cfg, 0, sizeof(ble_cfg));
+ ble_cfg.conn_cfg.conn_cfg_tag = conn_cfg_tag;
+ ble_cfg.conn_cfg.params.gap_conn_cfg.conn_count = NRF_SDH_BLE_TOTAL_LINK_COUNT;
+ ble_cfg.conn_cfg.params.gap_conn_cfg.event_length = NRF_SDH_BLE_GAP_EVENT_LENGTH;
+
+ ret_code = sd_ble_cfg_set(BLE_CONN_CFG_GAP, &ble_cfg, *p_ram_start);
+ if (ret_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("sd_ble_cfg_set() returned %s when attempting to set BLE_CONN_CFG_GAP.",
+ nrf_strerror_get(ret_code));
+ }
+
+ // Configure the connection roles.
+ memset(&ble_cfg, 0, sizeof(ble_cfg));
+ ble_cfg.gap_cfg.role_count_cfg.periph_role_count = NRF_SDH_BLE_PERIPHERAL_LINK_COUNT;
+#ifndef S112
+ ble_cfg.gap_cfg.role_count_cfg.central_role_count = NRF_SDH_BLE_CENTRAL_LINK_COUNT;
+ ble_cfg.gap_cfg.role_count_cfg.central_sec_count = NRF_SDH_BLE_CENTRAL_LINK_COUNT ?
+ BLE_GAP_ROLE_COUNT_CENTRAL_SEC_DEFAULT : 0;
+#endif
+
+ ret_code = sd_ble_cfg_set(BLE_GAP_CFG_ROLE_COUNT, &ble_cfg, *p_ram_start);
+ if (ret_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("sd_ble_cfg_set() returned %s when attempting to set BLE_GAP_CFG_ROLE_COUNT.",
+ nrf_strerror_get(ret_code));
+ }
+
+ // Configure the maximum ATT MTU.
+#if (NRF_SDH_BLE_GATT_MAX_MTU_SIZE != 23)
+ memset(&ble_cfg, 0x00, sizeof(ble_cfg));
+ ble_cfg.conn_cfg.conn_cfg_tag = conn_cfg_tag;
+ ble_cfg.conn_cfg.params.gatt_conn_cfg.att_mtu = NRF_SDH_BLE_GATT_MAX_MTU_SIZE;
+
+ ret_code = sd_ble_cfg_set(BLE_CONN_CFG_GATT, &ble_cfg, *p_ram_start);
+ if (ret_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("sd_ble_cfg_set() returned %s when attempting to set BLE_CONN_CFG_GATT.",
+ nrf_strerror_get(ret_code));
+ }
+#endif
+#endif // NRF_SDH_BLE_TOTAL_LINK_COUNT != 0
+
+ // Configure number of custom UUIDS.
+ memset(&ble_cfg, 0, sizeof(ble_cfg));
+ ble_cfg.common_cfg.vs_uuid_cfg.vs_uuid_count = NRF_SDH_BLE_VS_UUID_COUNT;
+
+ ret_code = sd_ble_cfg_set(BLE_COMMON_CFG_VS_UUID, &ble_cfg, *p_ram_start);
+ if (ret_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("sd_ble_cfg_set() returned %s when attempting to set BLE_COMMON_CFG_VS_UUID.",
+ nrf_strerror_get(ret_code));
+ }
+
+ // Configure the GATTS attribute table.
+ memset(&ble_cfg, 0x00, sizeof(ble_cfg));
+ ble_cfg.gatts_cfg.attr_tab_size.attr_tab_size = NRF_SDH_BLE_GATTS_ATTR_TAB_SIZE;
+
+ ret_code = sd_ble_cfg_set(BLE_GATTS_CFG_ATTR_TAB_SIZE, &ble_cfg, *p_ram_start);
+ if (ret_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("sd_ble_cfg_set() returned %s when attempting to set BLE_GATTS_CFG_ATTR_TAB_SIZE.",
+ nrf_strerror_get(ret_code));
+ }
+
+ // Configure Service Changed characteristic.
+ memset(&ble_cfg, 0x00, sizeof(ble_cfg));
+ ble_cfg.gatts_cfg.service_changed.service_changed = NRF_SDH_BLE_SERVICE_CHANGED;
+
+ ret_code = sd_ble_cfg_set(BLE_GATTS_CFG_SERVICE_CHANGED, &ble_cfg, *p_ram_start);
+ if (ret_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("sd_ble_cfg_set() returned %s when attempting to set BLE_GATTS_CFG_SERVICE_CHANGED.",
+ nrf_strerror_get(ret_code));
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for finding the end address of the RAM. */
+static uint32_t ram_end_address_get(void)
+{
+ uint32_t ram_total_size;
+
+#ifdef NRF51
+ uint32_t block_size = NRF_FICR->SIZERAMBLOCKS;
+ ram_total_size = block_size * NRF_FICR->NUMRAMBLOCK;
+#else
+ ram_total_size = NRF_FICR->INFO.RAM * 1024;
+#endif
+
+ return RAM_START + ram_total_size;
+}
+
+
+ret_code_t nrf_sdh_ble_enable(uint32_t * const p_app_ram_start)
+{
+ // Start of RAM, obtained from linker symbol.
+ uint32_t const app_ram_start_link = *p_app_ram_start;
+
+ NRF_LOG_DEBUG("RAM starts at 0x%x", app_ram_start_link);
+
+ ret_code_t ret_code = sd_ble_enable(p_app_ram_start);
+ if (*p_app_ram_start != app_ram_start_link)
+ {
+ NRF_LOG_WARNING("RAM starts at 0x%x, can be adjusted to 0x%x.",
+ app_ram_start_link, *p_app_ram_start);
+
+ NRF_LOG_WARNING("RAM size can be adjusted to 0x%x.",
+ ram_end_address_get() - (*p_app_ram_start));
+ }
+
+ if (ret_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("sd_ble_enable() returned %s.", nrf_strerror_get(ret_code));
+ }
+
+ return ret_code;
+}
+
+
+/**@brief Function for polling BLE events.
+ *
+ * @param[in] p_context Context of the observer.
+ */
+static void nrf_sdh_ble_evts_poll(void * p_context)
+{
+ ret_code_t ret_code;
+
+ UNUSED_VARIABLE(p_context);
+
+ while (true)
+ {
+ __ALIGN(4) uint8_t evt_buffer[NRF_SDH_BLE_EVT_BUF_SIZE];
+
+ ble_evt_t * p_ble_evt;
+ uint16_t evt_len = (uint16_t)sizeof(evt_buffer);
+
+ ret_code = sd_ble_evt_get(evt_buffer, &evt_len);
+ if (ret_code != NRF_SUCCESS)
+ {
+ break;
+ }
+
+ p_ble_evt = (ble_evt_t *)evt_buffer;
+
+ NRF_LOG_DEBUG("BLE event: 0x%x.", p_ble_evt->header.evt_id);
+
+ // Forward the event to BLE observers.
+ nrf_section_iter_t iter;
+ for (nrf_section_iter_init(&iter, &sdh_ble_observers);
+ nrf_section_iter_get(&iter) != NULL;
+ nrf_section_iter_next(&iter))
+ {
+ nrf_sdh_ble_evt_observer_t * p_observer;
+ nrf_sdh_ble_evt_handler_t handler;
+
+ p_observer = (nrf_sdh_ble_evt_observer_t *)nrf_section_iter_get(&iter);
+ handler = p_observer->handler;
+
+ handler(p_ble_evt, p_observer->p_context);
+ }
+ }
+
+ if (ret_code != NRF_ERROR_NOT_FOUND)
+ {
+ APP_ERROR_HANDLER(ret_code);
+ }
+}
+
+
+NRF_SDH_STACK_OBSERVER(m_nrf_sdh_ble_evts_poll, NRF_SDH_BLE_STACK_OBSERVER_PRIO) =
+{
+ .handler = nrf_sdh_ble_evts_poll,
+ .p_context = NULL,
+};
+
+#endif // NRF_MODULE_ENABLED(NRF_SDH_BLE)
diff --git a/hw/mcu/nordic/nrf52/sdk/softdevice/common/nrf_sdh_ble.h b/hw/mcu/nordic/nrf52/sdk/softdevice/common/nrf_sdh_ble.h
new file mode 100644
index 000000000..0c253b83c
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/softdevice/common/nrf_sdh_ble.h
@@ -0,0 +1,187 @@
+/**
+ * Copyright (c) 2017 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_sdh_ble BLE support in SoftDevice Handler
+ * @{
+ * @ingroup nrf_sdh
+ * @brief This file contains the declarations of types and functions required for BLE stack
+ * support.
+ */
+
+#ifndef NRF_SDH_BLE_H__
+#define NRF_SDH_BLE_H__
+
+#include "app_util.h"
+#include "ble.h"
+#include "nrf_section_iter.h"
+#include "sdk_config.h"
+#include "sdk_errors.h"
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief Size of the buffer for a BLE event. */
+#if (defined(NRF_SD_BLE_API_VERSION) && (NRF_SD_BLE_API_VERSION < 3))
+#define NRF_SDH_BLE_EVT_BUF_SIZE (sizeof(ble_evt_t) + (NRF_SDH_BLE_GATT_MAX_MTU_SIZE))
+#else
+#define NRF_SDH_BLE_EVT_BUF_SIZE BLE_EVT_LEN_MAX(NRF_SDH_BLE_GATT_MAX_MTU_SIZE)
+#endif
+
+#if !(defined(__LINT__))
+/**@brief Macro for registering @ref nrf_sdh_soc_evt_observer_t. Modules that want to be
+ * notified about SoC events must register the handler using this macro.
+ *
+ * @details This macro places the observer in a section named "sdh_soc_observers".
+ *
+ * @param[in] _name Observer name.
+ * @param[in] _prio Priority of the observer event handler.
+ * The smaller the number, the higher the priority.
+ * @param[in] _handler BLE event handler.
+ * @param[in] _context Parameter to the event handler.
+ * @hideinitializer
+ */
+#define NRF_SDH_BLE_OBSERVER(_name, _prio, _handler, _context) \
+STATIC_ASSERT(NRF_SDH_BLE_ENABLED, "NRF_SDH_BLE_ENABLED not set!"); \
+STATIC_ASSERT(_prio < NRF_SDH_BLE_OBSERVER_PRIO_LEVELS, "Priority level unavailable."); \
+NRF_SECTION_SET_ITEM_REGISTER(sdh_ble_observers, _prio, static nrf_sdh_ble_evt_observer_t _name) = \
+{ \
+ .handler = _handler, \
+ .p_context = _context \
+}
+
+/**@brief Macro for registering an array of @ref nrf_sdh_ble_evt_observer_t.
+ * Modules that want to be notified about SoC events must register the handler using
+ * this macro.
+ *
+ * Each observer's handler will be dispatched an event with its relative context from @p _context.
+ * This macro places the observer in a section named "sdh_ble_observers".
+ *
+ * @param[in] _name Observer name.
+ * @param[in] _prio Priority of the observer event handler.
+ * The smaller the number, the higher the priority.
+ * @param[in] _handler BLE event handler.
+ * @param[in] _context An array of parameters to the event handler.
+ * @param[in] _cnt Number of observers to register.
+ * @hideinitializer
+ */
+#define NRF_SDH_BLE_OBSERVERS(_name, _prio, _handler, _context, _cnt) \
+STATIC_ASSERT(NRF_SDH_BLE_ENABLED, "NRF_SDH_BLE_ENABLED not set!"); \
+STATIC_ASSERT(_prio < NRF_SDH_BLE_OBSERVER_PRIO_LEVELS, "Priority level unavailable."); \
+NRF_SECTION_SET_ITEM_REGISTER(sdh_ble_observers, _prio, static nrf_sdh_ble_evt_observer_t _name[_cnt]) = \
+{ \
+ MACRO_REPEAT_FOR(_cnt, HANDLER_SET, _handler, _context) \
+}
+
+#if !(defined(DOXYGEN))
+#define HANDLER_SET(_idx, _handler, _context) \
+{ \
+ .handler = _handler, \
+ .p_context = _context[_idx], \
+},
+#endif
+
+#else // __LINT__
+
+/* Swallow semicolons */
+/*lint -save -esym(528, *) -esym(529, *) : Symbol not referenced. */
+#define NRF_SDH_BLE_OBSERVER(A, B, C, D) static int semicolon_swallow_##A
+#define NRF_SDH_BLE_OBSERVERS(A, B, C, D, E) static int semicolon_swallow_##A
+/*lint -restore */
+
+#endif
+
+
+/**@brief BLE stack event handler. */
+typedef void (*nrf_sdh_ble_evt_handler_t)(ble_evt_t const * p_ble_evt, void * p_context);
+
+/**@brief BLE event observer. */
+typedef struct
+{
+ nrf_sdh_ble_evt_handler_t handler; //!< BLE event handler.
+ void * p_context; //!< A parameter to the event handler.
+} const nrf_sdh_ble_evt_observer_t;
+
+
+/**@brief Function for retrieving the address of the start of application's RAM.
+ *
+ * @param[out] p_app_ram_start Address of the start of application's RAM.
+ *
+ * @retval NRF_SUCCESS If the address was successfully retrieved.
+ * @retval NRF_ERROR_NULL If @p p_app_ram_start was @c NULL.
+ */
+ret_code_t nrf_sdh_ble_app_ram_start_get(uint32_t * p_app_ram_start);
+
+
+/**@brief Set the default BLE stack configuration.
+ *
+ * This function configures the BLE stack with the settings specified in the
+ * SoftDevice handler BLE configuration. The following configurations will be set:
+ * - Number of peripheral links
+ * - Number of central links
+ * - ATT MTU size (for the given connection)
+ * - Vendor specific UUID count
+ * - GATTS Attribute table size
+ * - Service changed
+ *
+ * @param[in] conn_cfg_tag The connection to configure.
+ * @param[out] p_ram_start Application RAM start address.
+ */
+ret_code_t nrf_sdh_ble_default_cfg_set(uint8_t conn_cfg_tag, uint32_t * p_ram_start);
+
+
+/**@brief Function for configuring and enabling the BLE stack.
+ *
+ * @param[in] p_app_ram_start Address of the start of application's RAM.
+ */
+ret_code_t nrf_sdh_ble_enable(uint32_t * p_app_ram_start);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_SDH_BLE_H__
+
+/** @} */
diff --git a/hw/mcu/nordic/nrf52/sdk/softdevice/common/nrf_sdh_soc.c b/hw/mcu/nordic/nrf52/sdk/softdevice/common/nrf_sdh_soc.c
new file mode 100644
index 000000000..cf037022c
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/softdevice/common/nrf_sdh_soc.c
@@ -0,0 +1,118 @@
+/**
+ * Copyright (c) 2017 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_SDH_SOC)
+
+#include "nrf_sdh_soc.h"
+
+#include "nrf_sdh.h"
+#include "nrf_soc.h"
+#include "app_error.h"
+
+
+#define NRF_LOG_MODULE_NAME nrf_sdh_soc
+#if NRF_SDH_SOC_LOG_ENABLED
+ #define NRF_LOG_LEVEL NRF_SDH_SOC_LOG_LEVEL
+ #define NRF_LOG_INFO_COLOR NRF_SDH_SOC_INFO_COLOR
+ #define NRF_LOG_DEBUG_COLOR NRF_SDH_SOC_DEBUG_COLOR
+#else
+ #define NRF_LOG_LEVEL 0
+#endif // NRF_SDH_SOC_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+// Create section set "sdh_soc_observers".
+NRF_SECTION_SET_DEF(sdh_soc_observers, nrf_sdh_soc_evt_observer_t, NRF_SDH_SOC_OBSERVER_PRIO_LEVELS);
+
+
+/**@brief Function for polling SoC events.
+ *
+ * @param[in] p_context Context of the observer.
+ */
+static void nrf_sdh_soc_evts_poll(void * p_context)
+{
+ ret_code_t ret_code;
+
+ UNUSED_VARIABLE(p_context);
+
+ while (true)
+ {
+ uint32_t evt_id;
+
+ ret_code = sd_evt_get(&evt_id);
+ if (ret_code != NRF_SUCCESS)
+ {
+ break;
+ }
+
+ NRF_LOG_DEBUG("SoC event: 0x%x.", evt_id);
+
+ // Forward the event to SoC observers.
+ nrf_section_iter_t iter;
+ for (nrf_section_iter_init(&iter, &sdh_soc_observers);
+ nrf_section_iter_get(&iter) != NULL;
+ nrf_section_iter_next(&iter))
+ {
+ nrf_sdh_soc_evt_observer_t * p_observer;
+ nrf_sdh_soc_evt_handler_t handler;
+
+ p_observer = (nrf_sdh_soc_evt_observer_t *) nrf_section_iter_get(&iter);
+ handler = p_observer->handler;
+
+ handler(evt_id, p_observer->p_context);
+ }
+ }
+
+ if (ret_code != NRF_ERROR_NOT_FOUND)
+ {
+ APP_ERROR_HANDLER(ret_code);
+ }
+}
+
+
+NRF_SDH_STACK_OBSERVER(m_nrf_sdh_soc_evts_poll, NRF_SDH_SOC_STACK_OBSERVER_PRIO) =
+{
+ .handler = nrf_sdh_soc_evts_poll,
+ .p_context = NULL,
+};
+
+#endif // NRF_MODULE_ENABLED(NRF_SDH_SOC)
diff --git a/hw/mcu/nordic/nrf52/sdk/softdevice/common/nrf_sdh_soc.h b/hw/mcu/nordic/nrf52/sdk/softdevice/common/nrf_sdh_soc.h
new file mode 100644
index 000000000..42eb541ac
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/softdevice/common/nrf_sdh_soc.h
@@ -0,0 +1,143 @@
+/**
+ * Copyright (c) 2017 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_sdh_soc SoC support in SoftDevice Handler
+ * @{
+ * @ingroup nrf_sdh
+ * @brief This file contains the declarations of types and functions required for SoftDevice Handler
+ * SoC support.
+ */
+
+#ifndef NRF_SDH_SOC_H__
+#define NRF_SDH_SOC_H__
+
+#include "app_util.h"
+#include "nrf_section_iter.h"
+#include "nrf_soc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if !(defined(__LINT__))
+/**@brief Macro for registering @ref nrf_sdh_soc_evt_observer_t. Modules that want to be
+ * notified about SoC events must register the handler using this macro.
+ *
+ * @details This macro places the observer in a section named "sdh_soc_observers".
+ *
+ * @param[in] _name Observer name.
+ * @param[in] _prio Priority of the observer event handler.
+ * The smaller the number, the higher the priority.
+ * @param[in] _handler SoC event handler.
+ * @param[in] _context Parameter to the event handler.
+ * @hideinitializer
+ */
+#define NRF_SDH_SOC_OBSERVER(_name, _prio, _handler, _context) \
+STATIC_ASSERT(NRF_SDH_SOC_ENABLED, "NRF_SDH_SOC_ENABLED not set!"); \
+STATIC_ASSERT(_prio < NRF_SDH_SOC_OBSERVER_PRIO_LEVELS, "Priority level unavailable."); \
+NRF_SECTION_SET_ITEM_REGISTER(sdh_soc_observers, _prio, static nrf_sdh_soc_evt_observer_t _name) = \
+{ \
+ .handler = _handler, \
+ .p_context = _context \
+}
+
+/**@brief Macro for registering an array of @ref nrf_sdh_soc_evt_observer_t.
+ * Modules that want to be notified about SoC events must register the handler using
+ * this macro.
+ *
+ * Each observer's handler will be dispatched an event with its relative context from @p _context.
+ * This macro places the observer in a section named "sdh_soc_observers".
+ *
+ * @param[in] _name Observer name.
+ * @param[in] _prio Priority of the observer event handler.
+ * The smaller the number, the higher the priority.
+ * @param[in] _handler SoC event handler.
+ * @param[in] _context An array of parameters to the event handler.
+ * @param[in] _cnt Number of observers to register.
+ * @hideinitializer
+ */
+#define NRF_SDH_SOC_EVENT_OBSERVERS(_name, _prio, _handler, _context, _cnt) \
+STATIC_ASSERT(NRF_SDH_SOC_ENABLED, "NRF_SDH_SOC_ENABLED not set!"); \
+STATIC_ASSERT(_prio < NRF_SDH_SOC_OBSERVER_PRIO_LEVELS, "Priority level unavailable."); \
+NRF_SECTION_SET_ITEM_REGISTER(sdh_soc_observers, _prio, static nrf_sdh_soc_evt_observer_t _name[_cnt]) = \
+{ \
+ MACRO_REPEAT_FOR(_cnt, HANDLER_SET, _handler, _context) \
+}
+
+#if !(defined(DOXYGEN))
+#define HANDLER_SET(_idx, _handler, _context) \
+{ \
+ .handler = _handler, \
+ .p_context = _context[_idx], \
+},
+#endif
+
+#else // __LINT__
+
+/* Swallow semicolons */
+/*lint -save -esym(528, *) -esym(529, *) : Symbol not referenced. */
+#define NRF_SDH_SOC_OBSERVER(A, B, C, D) static int semicolon_swallow_##A
+#define NRF_SDH_SOC_OBSERVERS(A, B, C, D, E) static int semicolon_swallow_##A
+/*lint -restore */
+
+#endif
+
+
+/**@brief SoC event handler. */
+typedef void (*nrf_sdh_soc_evt_handler_t) (uint32_t evt_id, void * p_context);
+
+/**@brief SoC event observer. */
+typedef struct
+{
+ nrf_sdh_soc_evt_handler_t handler; //!< SoC event handler.
+ void * p_context; //!< A parameter to the event handler.
+} const nrf_sdh_soc_evt_observer_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_SDH_SOC_H__
+
+/** @} */
diff --git a/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble.h b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble.h
new file mode 100644
index 000000000..c4835fa6e
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble.h
@@ -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__ */
+
+/**
+ @}
+ @}
+*/
diff --git a/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_err.h b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_err.h
new file mode 100644
index 000000000..36d54a0dc
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_err.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
+
+
+/**
+ @}
+ @}
+*/
diff --git a/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_gap.h b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_gap.h
new file mode 100644
index 000000000..339db01fd
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_gap.h
@@ -0,0 +1,2211 @@
+/*
+ * 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_GAP Generic Access Profile (GAP)
+ @{
+ @brief Definitions and prototypes for the GAP interface.
+ */
+
+#ifndef BLE_GAP_H__
+#define BLE_GAP_H__
+
+
+#include "ble_types.h"
+#include "ble_ranges.h"
+#include "nrf_svc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@addtogroup BLE_GAP_ENUMERATIONS Enumerations
+ * @{ */
+
+/**@brief GAP API SVC numbers.
+ */
+enum BLE_GAP_SVCS
+{
+ SD_BLE_GAP_ADDR_SET = BLE_GAP_SVC_BASE, /**< Set own Bluetooth Address. */
+ SD_BLE_GAP_ADDR_GET, /**< Get own Bluetooth Address. */
+ SD_BLE_GAP_WHITELIST_SET, /**< Set active whitelist. */
+ SD_BLE_GAP_DEVICE_IDENTITIES_SET, /**< Set device identity list. */
+ SD_BLE_GAP_PRIVACY_SET, /**< Set Privacy settings*/
+ SD_BLE_GAP_PRIVACY_GET, /**< Get Privacy settings*/
+ SD_BLE_GAP_ADV_DATA_SET, /**< Set Advertising Data. */
+ SD_BLE_GAP_ADV_START, /**< Start Advertising. */
+ SD_BLE_GAP_ADV_STOP, /**< Stop Advertising. */
+ SD_BLE_GAP_CONN_PARAM_UPDATE, /**< Connection Parameter Update. */
+ SD_BLE_GAP_DISCONNECT, /**< Disconnect. */
+ SD_BLE_GAP_TX_POWER_SET, /**< Set TX Power. */
+ SD_BLE_GAP_APPEARANCE_SET, /**< Set Appearance. */
+ SD_BLE_GAP_APPEARANCE_GET, /**< Get Appearance. */
+ SD_BLE_GAP_PPCP_SET, /**< Set PPCP. */
+ SD_BLE_GAP_PPCP_GET, /**< Get PPCP. */
+ SD_BLE_GAP_DEVICE_NAME_SET, /**< Set Device Name. */
+ SD_BLE_GAP_DEVICE_NAME_GET, /**< Get Device Name. */
+ SD_BLE_GAP_AUTHENTICATE, /**< Initiate Pairing/Bonding. */
+ SD_BLE_GAP_SEC_PARAMS_REPLY, /**< Reply with Security Parameters. */
+ SD_BLE_GAP_AUTH_KEY_REPLY, /**< Reply with an authentication key. */
+ SD_BLE_GAP_LESC_DHKEY_REPLY, /**< Reply with an LE Secure Connections DHKey. */
+ SD_BLE_GAP_KEYPRESS_NOTIFY, /**< Notify of a keypress during an authentication procedure. */
+ SD_BLE_GAP_LESC_OOB_DATA_GET, /**< Get the local LE Secure Connections OOB data. */
+ SD_BLE_GAP_LESC_OOB_DATA_SET, /**< Set the remote LE Secure Connections OOB data. */
+ SD_BLE_GAP_ENCRYPT, /**< Initiate encryption procedure. */
+ SD_BLE_GAP_SEC_INFO_REPLY, /**< Reply with Security Information. */
+ SD_BLE_GAP_CONN_SEC_GET, /**< Obtain connection security level. */
+ SD_BLE_GAP_RSSI_START, /**< Start reporting of changes in RSSI. */
+ SD_BLE_GAP_RSSI_STOP, /**< Stop reporting of changes in RSSI. */
+ SD_BLE_GAP_SCAN_START, /**< Start Scanning. */
+ SD_BLE_GAP_SCAN_STOP, /**< Stop Scanning. */
+ SD_BLE_GAP_CONNECT, /**< Connect. */
+ SD_BLE_GAP_CONNECT_CANCEL, /**< Cancel ongoing connection procedure. */
+ SD_BLE_GAP_RSSI_GET, /**< Get the last RSSI sample. */
+ SD_BLE_GAP_PHY_REQUEST, /**< Initiate PHY Update procedure. */
+ SD_BLE_GAP_DATA_LENGTH_UPDATE, /**< Initiate or respond to a Data Length Update Procedure. */
+};
+
+/**@brief GAP Event IDs.
+ * IDs that uniquely identify an event coming from the stack to the application.
+ */
+enum BLE_GAP_EVTS
+{
+ BLE_GAP_EVT_CONNECTED = BLE_GAP_EVT_BASE, /**< Connection established. \n See @ref ble_gap_evt_connected_t. */
+ BLE_GAP_EVT_DISCONNECTED, /**< Disconnected from peer. \n See @ref ble_gap_evt_disconnected_t. */
+ BLE_GAP_EVT_CONN_PARAM_UPDATE, /**< Connection Parameters updated. \n See @ref ble_gap_evt_conn_param_update_t. */
+ BLE_GAP_EVT_SEC_PARAMS_REQUEST, /**< Request to provide security parameters. \n Reply with @ref sd_ble_gap_sec_params_reply. \n See @ref ble_gap_evt_sec_params_request_t. */
+ BLE_GAP_EVT_SEC_INFO_REQUEST, /**< Request to provide security information. \n Reply with @ref sd_ble_gap_sec_info_reply. \n See @ref ble_gap_evt_sec_info_request_t. */
+ BLE_GAP_EVT_PASSKEY_DISPLAY, /**< Request to display a passkey to the user. \n In LESC Numeric Comparison, reply with @ref sd_ble_gap_auth_key_reply. \n See @ref ble_gap_evt_passkey_display_t. */
+ BLE_GAP_EVT_KEY_PRESSED, /**< Notification of a keypress on the remote device.\n See @ref ble_gap_evt_key_pressed_t */
+ BLE_GAP_EVT_AUTH_KEY_REQUEST, /**< Request to provide an authentication key. \n Reply with @ref sd_ble_gap_auth_key_reply. \n See @ref ble_gap_evt_auth_key_request_t. */
+ BLE_GAP_EVT_LESC_DHKEY_REQUEST, /**< Request to calculate an LE Secure Connections DHKey. \n Reply with @ref sd_ble_gap_lesc_dhkey_reply. \n See @ref ble_gap_evt_lesc_dhkey_request_t */
+ BLE_GAP_EVT_AUTH_STATUS, /**< Authentication procedure completed with status. \n See @ref ble_gap_evt_auth_status_t. */
+ BLE_GAP_EVT_CONN_SEC_UPDATE, /**< Connection security updated. \n See @ref ble_gap_evt_conn_sec_update_t. */
+ BLE_GAP_EVT_TIMEOUT, /**< Timeout expired. \n See @ref ble_gap_evt_timeout_t. */
+ BLE_GAP_EVT_RSSI_CHANGED, /**< RSSI report. \n See @ref ble_gap_evt_rssi_changed_t. */
+ BLE_GAP_EVT_ADV_REPORT, /**< Advertising report. \n See @ref ble_gap_evt_adv_report_t. */
+ BLE_GAP_EVT_SEC_REQUEST, /**< Security Request. \n See @ref ble_gap_evt_sec_request_t. */
+ BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, /**< Connection Parameter Update Request. \n Reply with @ref sd_ble_gap_conn_param_update. \n See @ref ble_gap_evt_conn_param_update_request_t. */
+ BLE_GAP_EVT_SCAN_REQ_REPORT, /**< Scan request report. \n See @ref ble_gap_evt_scan_req_report_t. */
+ BLE_GAP_EVT_PHY_UPDATE, /**< PHY have been updated \n See @ref ble_gap_evt_phy_update_t. */
+ BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST, /**< Data Length Update request. \n Reply with @ref sd_ble_gap_data_length_update.\n See @ref ble_gap_evt_data_length_update_request_t. */
+ BLE_GAP_EVT_DATA_LENGTH_UPDATE, /**< LL Data Channel PDU payload length updated. \n See @ref ble_gap_evt_data_length_update_t. */
+};
+
+/**@brief GAP Option IDs.
+ * IDs that uniquely identify a GAP option.
+ */
+enum BLE_GAP_OPTS
+{
+ BLE_GAP_OPT_CH_MAP = BLE_GAP_OPT_BASE, /**< Channel Map. @ref ble_gap_opt_ch_map_t */
+ BLE_GAP_OPT_LOCAL_CONN_LATENCY, /**< Local connection latency. @ref ble_gap_opt_local_conn_latency_t */
+ BLE_GAP_OPT_PASSKEY, /**< Set passkey. @ref ble_gap_opt_passkey_t */
+ BLE_GAP_OPT_SCAN_REQ_REPORT, /**< Scan request report. @ref ble_gap_opt_scan_req_report_t */
+ BLE_GAP_OPT_COMPAT_MODE_1, /**< Compatibility mode. @ref ble_gap_opt_compat_mode_1_t */
+ BLE_GAP_OPT_COMPAT_MODE_2, /**< Compatibility mode. @ref ble_gap_opt_compat_mode_2_t */
+ BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT, /**< Set Authenticated payload timeout. @ref ble_gap_opt_auth_payload_timeout_t */
+ BLE_GAP_OPT_PREFERRED_PHYS_SET, /**< Set the preferred PHYs for all new connections. @ref ble_gap_opt_preferred_phys_t */
+ BLE_GAP_OPT_SLAVE_LATENCY_DISABLE, /**< Disable slave latency. @ref ble_gap_opt_slave_latency_disable_t */
+};
+
+/**@brief GAP Configuration IDs.
+ *
+ * IDs that uniquely identify a GAP configuration.
+ */
+enum BLE_GAP_CFGS
+{
+ BLE_GAP_CFG_ROLE_COUNT = BLE_GAP_CFG_BASE, /**< Role count configuration. */
+ BLE_GAP_CFG_DEVICE_NAME, /**< Device name configuration. */
+};
+
+/** @} */
+
+/**@addtogroup BLE_GAP_DEFINES Defines
+ * @{ */
+
+/**@defgroup BLE_ERRORS_GAP SVC return values specific to GAP
+ * @{ */
+#define BLE_ERROR_GAP_UUID_LIST_MISMATCH (NRF_GAP_ERR_BASE + 0x000) /**< UUID list does not contain an integral number of UUIDs. */
+#define BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST (NRF_GAP_ERR_BASE + 0x001) /**< Use of Whitelist not permitted with discoverable advertising. */
+#define BLE_ERROR_GAP_INVALID_BLE_ADDR (NRF_GAP_ERR_BASE + 0x002) /**< The upper two bits of the address do not correspond to the specified address type. */
+#define BLE_ERROR_GAP_WHITELIST_IN_USE (NRF_GAP_ERR_BASE + 0x003) /**< Attempt to modify the whitelist while already in use by another operation. */
+#define BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE (NRF_GAP_ERR_BASE + 0x004) /**< Attempt to modify the device identity list while already in use by another operation. */
+#define BLE_ERROR_GAP_DEVICE_IDENTITIES_DUPLICATE (NRF_GAP_ERR_BASE + 0x005) /**< The device identity list contains entries with duplicate identity addresses. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_ROLES GAP Roles
+ * @note Not explicitly used in peripheral API, but will be relevant for central API.
+ * @{ */
+#define BLE_GAP_ROLE_INVALID 0x0 /**< Invalid Role. */
+#define BLE_GAP_ROLE_PERIPH 0x1 /**< Peripheral Role. */
+#define BLE_GAP_ROLE_CENTRAL 0x2 /**< Central Role. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_TIMEOUT_SOURCES GAP Timeout sources
+ * @{ */
+#define BLE_GAP_TIMEOUT_SRC_ADVERTISING 0x00 /**< Advertising timeout. */
+#define BLE_GAP_TIMEOUT_SRC_SECURITY_REQUEST 0x01 /**< Security request timeout. */
+#define BLE_GAP_TIMEOUT_SRC_SCAN 0x02 /**< Scanning timeout. */
+#define BLE_GAP_TIMEOUT_SRC_CONN 0x03 /**< Connection timeout. */
+#define BLE_GAP_TIMEOUT_SRC_AUTH_PAYLOAD 0x04 /**< Authenticated payload timeout. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_ADDR_TYPES GAP Address types
+ * @{ */
+#define BLE_GAP_ADDR_TYPE_PUBLIC 0x00 /**< Public address. */
+#define BLE_GAP_ADDR_TYPE_RANDOM_STATIC 0x01 /**< Random static address. */
+#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE 0x02 /**< Random private resolvable address. */
+#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE 0x03 /**< Random private non-resolvable address. */
+/**@} */
+
+
+/**@brief The default interval in seconds at which a private address is refreshed. */
+#define BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S (900) /* 15 minutes. */
+/**@brief The maximum interval in seconds at which a private address can be refreshed. */
+#define BLE_GAP_MAX_PRIVATE_ADDR_CYCLE_INTERVAL_S (41400) /* 11 hours 30 minutes. */
+
+
+/** @brief BLE address length. */
+#define BLE_GAP_ADDR_LEN (6)
+
+
+/**@defgroup BLE_GAP_PRIVACY_MODES Privacy modes
+ * @{ */
+#define BLE_GAP_PRIVACY_MODE_OFF 0x00 /**< Device will send and accept its identity address for its own address. */
+#define BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY 0x01 /**< Device will send and accept only private addresses for its own address. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_AD_TYPE_DEFINITIONS GAP Advertising and Scan Response Data format
+ * @note Found at https://www.bluetooth.org/Technical/AssignedNumbers/generic_access_profile.htm
+ * @{ */
+#define BLE_GAP_AD_TYPE_FLAGS 0x01 /**< Flags for discoverability. */
+#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE 0x02 /**< Partial list of 16 bit service UUIDs. */
+#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE 0x03 /**< Complete list of 16 bit service UUIDs. */
+#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_MORE_AVAILABLE 0x04 /**< Partial list of 32 bit service UUIDs. */
+#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_COMPLETE 0x05 /**< Complete list of 32 bit service UUIDs. */
+#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE 0x06 /**< Partial list of 128 bit service UUIDs. */
+#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE 0x07 /**< Complete list of 128 bit service UUIDs. */
+#define BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME 0x08 /**< Short local device name. */
+#define BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME 0x09 /**< Complete local device name. */
+#define BLE_GAP_AD_TYPE_TX_POWER_LEVEL 0x0A /**< Transmit power level. */
+#define BLE_GAP_AD_TYPE_CLASS_OF_DEVICE 0x0D /**< Class of device. */
+#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C 0x0E /**< Simple Pairing Hash C. */
+#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R 0x0F /**< Simple Pairing Randomizer R. */
+#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE 0x10 /**< Security Manager TK Value. */
+#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS 0x11 /**< Security Manager Out Of Band Flags. */
+#define BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE 0x12 /**< Slave Connection Interval Range. */
+#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT 0x14 /**< List of 16-bit Service Solicitation UUIDs. */
+#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT 0x15 /**< List of 128-bit Service Solicitation UUIDs. */
+#define BLE_GAP_AD_TYPE_SERVICE_DATA 0x16 /**< Service Data - 16-bit UUID. */
+#define BLE_GAP_AD_TYPE_PUBLIC_TARGET_ADDRESS 0x17 /**< Public Target Address. */
+#define BLE_GAP_AD_TYPE_RANDOM_TARGET_ADDRESS 0x18 /**< Random Target Address. */
+#define BLE_GAP_AD_TYPE_APPEARANCE 0x19 /**< Appearance. */
+#define BLE_GAP_AD_TYPE_ADVERTISING_INTERVAL 0x1A /**< Advertising Interval. */
+#define BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS 0x1B /**< LE Bluetooth Device Address. */
+#define BLE_GAP_AD_TYPE_LE_ROLE 0x1C /**< LE Role. */
+#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C256 0x1D /**< Simple Pairing Hash C-256. */
+#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R256 0x1E /**< Simple Pairing Randomizer R-256. */
+#define BLE_GAP_AD_TYPE_SERVICE_DATA_32BIT_UUID 0x20 /**< Service Data - 32-bit UUID. */
+#define BLE_GAP_AD_TYPE_SERVICE_DATA_128BIT_UUID 0x21 /**< Service Data - 128-bit UUID. */
+#define BLE_GAP_AD_TYPE_LESC_CONFIRMATION_VALUE 0x22 /**< LE Secure Connections Confirmation Value */
+#define BLE_GAP_AD_TYPE_LESC_RANDOM_VALUE 0x23 /**< LE Secure Connections Random Value */
+#define BLE_GAP_AD_TYPE_URI 0x24 /**< URI */
+#define BLE_GAP_AD_TYPE_3D_INFORMATION_DATA 0x3D /**< 3D Information Data. */
+#define BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA 0xFF /**< Manufacturer Specific Data. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_ADV_FLAGS GAP Advertisement Flags
+ * @{ */
+#define BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE (0x01) /**< LE Limited Discoverable Mode. */
+#define BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE (0x02) /**< LE General Discoverable Mode. */
+#define BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED (0x04) /**< BR/EDR not supported. */
+#define BLE_GAP_ADV_FLAG_LE_BR_EDR_CONTROLLER (0x08) /**< Simultaneous LE and BR/EDR, Controller. */
+#define BLE_GAP_ADV_FLAG_LE_BR_EDR_HOST (0x10) /**< Simultaneous LE and BR/EDR, Host. */
+#define BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE (BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) /**< LE Limited Discoverable Mode, BR/EDR not supported. */
+#define BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE (BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) /**< LE General Discoverable Mode, BR/EDR not supported. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_ADV_INTERVALS GAP Advertising interval max and min
+ * @{ */
+#define BLE_GAP_ADV_INTERVAL_MIN 0x0020 /**< Minimum Advertising interval in 625 us units, i.e. 20 ms. */
+#define BLE_GAP_ADV_NONCON_INTERVAL_MIN 0x00A0 /**< Minimum Advertising interval in 625 us units for non connectable mode, i.e. 100 ms. */
+#define BLE_GAP_ADV_INTERVAL_MAX 0x4000 /**< Maximum Advertising interval in 625 us units, i.e. 10.24 s. */
+ /**@} */
+
+
+/**@defgroup BLE_GAP_SCAN_INTERVALS GAP Scan interval max and min
+ * @{ */
+#define BLE_GAP_SCAN_INTERVAL_MIN 0x0004 /**< Minimum Scan interval in 625 us units, i.e. 2.5 ms. */
+#define BLE_GAP_SCAN_INTERVAL_MAX 0x4000 /**< Maximum Scan interval in 625 us units, i.e. 10.24 s. */
+ /** @} */
+
+
+/**@defgroup BLE_GAP_SCAN_WINDOW GAP Scan window max and min
+ * @{ */
+#define BLE_GAP_SCAN_WINDOW_MIN 0x0004 /**< Minimum Scan window in 625 us units, i.e. 2.5 ms. */
+#define BLE_GAP_SCAN_WINDOW_MAX 0x4000 /**< Maximum Scan window in 625 us units, i.e. 10.24 s. */
+ /** @} */
+
+
+/**@defgroup BLE_GAP_SCAN_TIMEOUT GAP Scan timeout max and min
+ * @{ */
+#define BLE_GAP_SCAN_TIMEOUT_MIN 0x0001 /**< Minimum Scan timeout in seconds. */
+#define BLE_GAP_SCAN_TIMEOUT_MAX 0xFFFF /**< Maximum Scan timeout in seconds. */
+ /** @} */
+
+
+/**@brief Maximum size of advertising data in octets. */
+#define BLE_GAP_ADV_MAX_SIZE (31)
+
+
+/**@defgroup BLE_GAP_ADV_TYPES GAP Advertising types
+ * @{ */
+#define BLE_GAP_ADV_TYPE_ADV_IND 0x00 /**< Connectable undirected. */
+#define BLE_GAP_ADV_TYPE_ADV_DIRECT_IND 0x01 /**< Connectable directed. */
+#define BLE_GAP_ADV_TYPE_ADV_SCAN_IND 0x02 /**< Scannable undirected. */
+#define BLE_GAP_ADV_TYPE_ADV_NONCONN_IND 0x03 /**< Non connectable undirected. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_ADV_FILTER_POLICIES GAP Advertising filter policies
+ * @{ */
+#define BLE_GAP_ADV_FP_ANY 0x00 /**< Allow scan requests and connect requests from any device. */
+#define BLE_GAP_ADV_FP_FILTER_SCANREQ 0x01 /**< Filter scan requests with whitelist. */
+#define BLE_GAP_ADV_FP_FILTER_CONNREQ 0x02 /**< Filter connect requests with whitelist. */
+#define BLE_GAP_ADV_FP_FILTER_BOTH 0x03 /**< Filter both scan and connect requests with whitelist. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_ADV_TIMEOUT_VALUES GAP Advertising timeout values
+ * @{ */
+#define BLE_GAP_ADV_TIMEOUT_LIMITED_MAX (180) /**< Maximum advertising time in limited discoverable mode (TGAP(lim_adv_timeout) = 180 s). */
+#define BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED (0) /**< Unlimited advertising in general discoverable mode. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_DISC_MODES GAP Discovery modes
+ * @{ */
+#define BLE_GAP_DISC_MODE_NOT_DISCOVERABLE 0x00 /**< Not discoverable discovery Mode. */
+#define BLE_GAP_DISC_MODE_LIMITED 0x01 /**< Limited Discovery Mode. */
+#define BLE_GAP_DISC_MODE_GENERAL 0x02 /**< General Discovery Mode. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_IO_CAPS GAP IO Capabilities
+ * @{ */
+#define BLE_GAP_IO_CAPS_DISPLAY_ONLY 0x00 /**< Display Only. */
+#define BLE_GAP_IO_CAPS_DISPLAY_YESNO 0x01 /**< Display and Yes/No entry. */
+#define BLE_GAP_IO_CAPS_KEYBOARD_ONLY 0x02 /**< Keyboard Only. */
+#define BLE_GAP_IO_CAPS_NONE 0x03 /**< No I/O capabilities. */
+#define BLE_GAP_IO_CAPS_KEYBOARD_DISPLAY 0x04 /**< Keyboard and Display. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_AUTH_KEY_TYPES GAP Authentication Key Types
+ * @{ */
+#define BLE_GAP_AUTH_KEY_TYPE_NONE 0x00 /**< No key (may be used to reject). */
+#define BLE_GAP_AUTH_KEY_TYPE_PASSKEY 0x01 /**< 6-digit Passkey. */
+#define BLE_GAP_AUTH_KEY_TYPE_OOB 0x02 /**< Out Of Band data. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_KP_NOT_TYPES GAP Keypress Notification Types
+ * @{ */
+#define BLE_GAP_KP_NOT_TYPE_PASSKEY_START 0x00 /**< Passkey entry started. */
+#define BLE_GAP_KP_NOT_TYPE_PASSKEY_DIGIT_IN 0x01 /**< Passkey digit entered. */
+#define BLE_GAP_KP_NOT_TYPE_PASSKEY_DIGIT_OUT 0x02 /**< Passkey digit erased. */
+#define BLE_GAP_KP_NOT_TYPE_PASSKEY_CLEAR 0x03 /**< Passkey cleared. */
+#define BLE_GAP_KP_NOT_TYPE_PASSKEY_END 0x04 /**< Passkey entry completed. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_SEC_STATUS GAP Security status
+ * @{ */
+#define BLE_GAP_SEC_STATUS_SUCCESS 0x00 /**< Procedure completed with success. */
+#define BLE_GAP_SEC_STATUS_TIMEOUT 0x01 /**< Procedure timed out. */
+#define BLE_GAP_SEC_STATUS_PDU_INVALID 0x02 /**< Invalid PDU received. */
+#define BLE_GAP_SEC_STATUS_RFU_RANGE1_BEGIN 0x03 /**< Reserved for Future Use range #1 begin. */
+#define BLE_GAP_SEC_STATUS_RFU_RANGE1_END 0x80 /**< Reserved for Future Use range #1 end. */
+#define BLE_GAP_SEC_STATUS_PASSKEY_ENTRY_FAILED 0x81 /**< Passkey entry failed (user canceled or other). */
+#define BLE_GAP_SEC_STATUS_OOB_NOT_AVAILABLE 0x82 /**< Out of Band Key not available. */
+#define BLE_GAP_SEC_STATUS_AUTH_REQ 0x83 /**< Authentication requirements not met. */
+#define BLE_GAP_SEC_STATUS_CONFIRM_VALUE 0x84 /**< Confirm value failed. */
+#define BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP 0x85 /**< Pairing not supported. */
+#define BLE_GAP_SEC_STATUS_ENC_KEY_SIZE 0x86 /**< Encryption key size. */
+#define BLE_GAP_SEC_STATUS_SMP_CMD_UNSUPPORTED 0x87 /**< Unsupported SMP command. */
+#define BLE_GAP_SEC_STATUS_UNSPECIFIED 0x88 /**< Unspecified reason. */
+#define BLE_GAP_SEC_STATUS_REPEATED_ATTEMPTS 0x89 /**< Too little time elapsed since last attempt. */
+#define BLE_GAP_SEC_STATUS_INVALID_PARAMS 0x8A /**< Invalid parameters. */
+#define BLE_GAP_SEC_STATUS_DHKEY_FAILURE 0x8B /**< DHKey check failure. */
+#define BLE_GAP_SEC_STATUS_NUM_COMP_FAILURE 0x8C /**< Numeric Comparison failure. */
+#define BLE_GAP_SEC_STATUS_BR_EDR_IN_PROG 0x8D /**< BR/EDR pairing in progress. */
+#define BLE_GAP_SEC_STATUS_X_TRANS_KEY_DISALLOWED 0x8E /**< BR/EDR Link Key cannot be used for LE keys. */
+#define BLE_GAP_SEC_STATUS_RFU_RANGE2_BEGIN 0x8F /**< Reserved for Future Use range #2 begin. */
+#define BLE_GAP_SEC_STATUS_RFU_RANGE2_END 0xFF /**< Reserved for Future Use range #2 end. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_SEC_STATUS_SOURCES GAP Security status sources
+ * @{ */
+#define BLE_GAP_SEC_STATUS_SOURCE_LOCAL 0x00 /**< Local failure. */
+#define BLE_GAP_SEC_STATUS_SOURCE_REMOTE 0x01 /**< Remote failure. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_CP_LIMITS GAP Connection Parameters Limits
+ * @{ */
+#define BLE_GAP_CP_MIN_CONN_INTVL_NONE 0xFFFF /**< No new minimum connection interval specified in connect parameters. */
+#define BLE_GAP_CP_MIN_CONN_INTVL_MIN 0x0006 /**< Lowest minimum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */
+#define BLE_GAP_CP_MIN_CONN_INTVL_MAX 0x0C80 /**< Highest minimum connection interval permitted, in units of 1.25 ms, i.e. 4 s. */
+#define BLE_GAP_CP_MAX_CONN_INTVL_NONE 0xFFFF /**< No new maximum connection interval specified in connect parameters. */
+#define BLE_GAP_CP_MAX_CONN_INTVL_MIN 0x0006 /**< Lowest maximum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */
+#define BLE_GAP_CP_MAX_CONN_INTVL_MAX 0x0C80 /**< Highest maximum connection interval permitted, in units of 1.25 ms, i.e. 4 s. */
+#define BLE_GAP_CP_SLAVE_LATENCY_MAX 0x01F3 /**< Highest slave latency permitted, in connection events. */
+#define BLE_GAP_CP_CONN_SUP_TIMEOUT_NONE 0xFFFF /**< No new supervision timeout specified in connect parameters. */
+#define BLE_GAP_CP_CONN_SUP_TIMEOUT_MIN 0x000A /**< Lowest supervision timeout permitted, in units of 10 ms, i.e. 100 ms. */
+#define BLE_GAP_CP_CONN_SUP_TIMEOUT_MAX 0x0C80 /**< Highest supervision timeout permitted, in units of 10 ms, i.e. 32 s. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_DEVNAME GAP device name defines.
+ * @{ */
+#define BLE_GAP_DEVNAME_DEFAULT "nRF5x" /**< Default device name value. */
+#define BLE_GAP_DEVNAME_DEFAULT_LEN 31 /**< Default number of octets in device name. */
+#define BLE_GAP_DEVNAME_MAX_LEN 248 /**< Maximum number of octets in device name. */
+/**@} */
+
+
+/**@brief Disable RSSI events for connections */
+#define BLE_GAP_RSSI_THRESHOLD_INVALID 0xFF
+
+/**@defgroup BLE_GAP_PHYS GAP PHYs
+ * @{ */
+#define BLE_GAP_PHY_1MBPS 0x01 /**< 1 Mbps PHY. */
+#define BLE_GAP_PHY_2MBPS 0x02 /**< 2 Mbps PHY. */
+#define BLE_GAP_PHY_CODED 0x04 /**< Coded PHY. */
+/**@} */
+
+/**@defgroup BLE_GAP_CONN_SEC_MODE_SET_MACROS GAP attribute security requirement setters
+ *
+ * See @ref ble_gap_conn_sec_mode_t.
+ * @{ */
+/**@brief Set sec_mode pointed to by ptr to have no access rights.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(ptr) do {(ptr)->sm = 0; (ptr)->lv = 0;} while(0)
+/**@brief Set sec_mode pointed to by ptr to require no protection, open link.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_OPEN(ptr) do {(ptr)->sm = 1; (ptr)->lv = 1;} while(0)
+/**@brief Set sec_mode pointed to by ptr to require encryption, but no MITM protection.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 2;} while(0)
+/**@brief Set sec_mode pointed to by ptr to require encryption and MITM protection.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 3;} while(0)
+/**@brief Set sec_mode pointed to by ptr to require LESC encryption and MITM protection.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_LESC_ENC_WITH_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 4;} while(0)
+/**@brief Set sec_mode pointed to by ptr to require signing or encryption, no MITM protection needed.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 1;} while(0)
+/**@brief Set sec_mode pointed to by ptr to require signing or encryption with MITM protection.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 2;} while(0)
+/**@} */
+
+
+/**@brief GAP Security Random Number Length. */
+#define BLE_GAP_SEC_RAND_LEN 8
+
+
+/**@brief GAP Security Key Length. */
+#define BLE_GAP_SEC_KEY_LEN 16
+
+
+/**@brief GAP LE Secure Connections Elliptic Curve Diffie-Hellman P-256 Public Key Length. */
+#define BLE_GAP_LESC_P256_PK_LEN 64
+
+
+/**@brief GAP LE Secure Connections Elliptic Curve Diffie-Hellman DHKey Length. */
+#define BLE_GAP_LESC_DHKEY_LEN 32
+
+
+/**@brief GAP Passkey Length. */
+#define BLE_GAP_PASSKEY_LEN 6
+
+
+/**@brief Maximum amount of addresses in the whitelist. */
+#define BLE_GAP_WHITELIST_ADDR_MAX_COUNT (8)
+
+
+/**@brief Maximum amount of identities in the device identities list. */
+#define BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT (8)
+
+
+/**@brief Default connection count for a configuration. */
+#define BLE_GAP_CONN_COUNT_DEFAULT (1)
+
+
+/**@defgroup BLE_GAP_EVENT_LENGTH GAP event length defines.
+ * @{ */
+#define BLE_GAP_EVENT_LENGTH_MIN (2) /**< Minimum event length, in 1.25 ms units. */
+#define BLE_GAP_EVENT_LENGTH_DEFAULT (3) /**< Default event length, in 1.25 ms units. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_ROLE_COUNT GAP concurrent connection count defines.
+ * @{ */
+#define BLE_GAP_ROLE_COUNT_PERIPH_DEFAULT (1) /**< Default maximum number of connections concurrently acting as peripherals. */
+#define BLE_GAP_ROLE_COUNT_CENTRAL_DEFAULT (3) /**< Default maximum number of connections concurrently acting as centrals. */
+#define BLE_GAP_ROLE_COUNT_CENTRAL_SEC_DEFAULT (1) /**< Default number of SMP instances shared between all connections acting as centrals. */
+#define BLE_GAP_ROLE_COUNT_COMBINED_MAX (20) /**< Maximum supported number of concurrent connections in the peripheral and central roles combined. */
+/**@} */
+
+
+
+
+/**@brief Automatic data length parameter. */
+#define BLE_GAP_DATA_LENGTH_AUTO 0
+
+
+/**@defgroup GAP_SEC_MODES GAP Security Modes
+ * @{ */
+#define BLE_GAP_SEC_MODE 0x00 /**< No key (may be used to reject). */
+/**@} */
+/** @} */
+
+
+/**@addtogroup BLE_GAP_STRUCTURES Structures
+ * @{ */
+
+/**@brief Bluetooth Low Energy address. */
+typedef struct
+{
+ uint8_t addr_id_peer : 1; /**< Only valid for peer addresses.
+ Reference to peer in device identities list (as set with @ref sd_ble_gap_device_identities_set) when peer is using privacy. */
+ uint8_t addr_type : 7; /**< See @ref BLE_GAP_ADDR_TYPES. */
+ uint8_t addr[BLE_GAP_ADDR_LEN]; /**< 48-bit address, LSB format. */
+} ble_gap_addr_t;
+
+
+/**@brief GAP connection parameters.
+ *
+ * @note When ble_conn_params_t is received in an event, both min_conn_interval and
+ * max_conn_interval will be equal to the connection interval set by the central.
+ *
+ * @note If both conn_sup_timeout and max_conn_interval are specified, then the following constraint applies:
+ * conn_sup_timeout * 4 > (1 + slave_latency) * max_conn_interval
+ * that corresponds to the following Bluetooth Spec requirement:
+ * The Supervision_Timeout in milliseconds shall be larger than
+ * (1 + Conn_Latency) * Conn_Interval_Max * 2, where Conn_Interval_Max is given in milliseconds.
+ */
+typedef struct
+{
+ uint16_t min_conn_interval; /**< Minimum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/
+ uint16_t max_conn_interval; /**< Maximum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/
+ uint16_t slave_latency; /**< Slave Latency in number of connection events, see @ref BLE_GAP_CP_LIMITS.*/
+ uint16_t conn_sup_timeout; /**< Connection Supervision Timeout in 10 ms units, see @ref BLE_GAP_CP_LIMITS.*/
+} ble_gap_conn_params_t;
+
+
+/**@brief GAP connection security modes.
+ *
+ * Security Mode 0 Level 0: No access permissions at all (this level is not defined by the Bluetooth Core specification).\n
+ * Security Mode 1 Level 1: No security is needed (aka open link).\n
+ * Security Mode 1 Level 2: Encrypted link required, MITM protection not necessary.\n
+ * Security Mode 1 Level 3: MITM protected encrypted link required.\n
+ * Security Mode 1 Level 4: LESC MITM protected encrypted link required.\n
+ * Security Mode 2 Level 1: Signing or encryption required, MITM protection not necessary.\n
+ * Security Mode 2 Level 2: MITM protected signing required, unless link is MITM protected encrypted.\n
+ */
+typedef struct
+{
+ uint8_t sm : 4; /**< Security Mode (1 or 2), 0 for no permissions at all. */
+ uint8_t lv : 4; /**< Level (1, 2, 3 or 4), 0 for no permissions at all. */
+
+} ble_gap_conn_sec_mode_t;
+
+
+/**@brief GAP connection security status.*/
+typedef struct
+{
+ ble_gap_conn_sec_mode_t sec_mode; /**< Currently active security mode for this connection.*/
+ uint8_t encr_key_size; /**< Length of currently active encryption key, 7 to 16 octets (only applicable for bonding procedures). */
+} ble_gap_conn_sec_t;
+
+/**@brief Identity Resolving Key. */
+typedef struct
+{
+ uint8_t irk[BLE_GAP_SEC_KEY_LEN]; /**< Array containing IRK. */
+} ble_gap_irk_t;
+
+
+/**@brief Channel mask for RF channels used in advertising. */
+typedef struct
+{
+ uint8_t ch_37_off : 1; /**< Setting this bit to 1 will turn off advertising on channel 37 */
+ uint8_t ch_38_off : 1; /**< Setting this bit to 1 will turn off advertising on channel 38 */
+ uint8_t ch_39_off : 1; /**< Setting this bit to 1 will turn off advertising on channel 39 */
+} ble_gap_adv_ch_mask_t;
+
+
+/**@brief GAP advertising parameters. */
+typedef struct
+{
+ uint8_t type; /**< See @ref BLE_GAP_ADV_TYPES. */
+ ble_gap_addr_t const *p_peer_addr; /**< Address of a known peer.
+ - When privacy is enabled and the local device use @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE addresses, the device identity list is searched for a matching
+ entry. If the local IRK for that device identity is set, the local IRK for that device will be used to generate the advertiser address field in the advertise packet.
+ - If type is @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, this must be set to the targeted initiator. If the initiator is in the device identity list,
+ the peer IRK for that device will be used to generate the initiator address field in the ADV_DIRECT_IND packet. */
+ uint8_t fp; /**< Filter Policy, see @ref BLE_GAP_ADV_FILTER_POLICIES. */
+ uint16_t interval; /**< Advertising interval between 0x0020 and 0x4000 in 0.625 ms units (20 ms to 10.24 s), see @ref BLE_GAP_ADV_INTERVALS.
+ - If type equals @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, this parameter must be set to 0 for high duty cycle directed advertising.
+ - If type equals @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, set @ref BLE_GAP_ADV_INTERVAL_MIN <= interval <= @ref BLE_GAP_ADV_INTERVAL_MAX for low duty cycle advertising.*/
+ uint16_t timeout; /**< Advertising timeout between 0x0001 and 0x3FFF in seconds, 0x0000 disables timeout. See also @ref BLE_GAP_ADV_TIMEOUT_VALUES. If type equals @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, this parameter must be set to 0 for High duty cycle directed advertising. */
+ ble_gap_adv_ch_mask_t channel_mask; /**< Advertising channel mask. See @ref ble_gap_adv_ch_mask_t. */
+} ble_gap_adv_params_t;
+
+
+/**@brief GAP scanning parameters. */
+typedef struct
+{
+ uint8_t active : 1; /**< If 1, perform active scanning (scan requests). */
+ uint8_t use_whitelist : 1; /**< If 1, filter advertisers using current active whitelist. */
+ uint8_t adv_dir_report : 1; /**< If 1, also report directed advertisements where the initiator field is set to a private resolvable address,
+ even if the address did not resolve to an entry in the device identity list. A report will be generated
+ even if the peer is not in the whitelist. */
+ uint16_t interval; /**< Scan interval between 0x0004 and 0x4000 in 0.625 ms units (2.5 ms to 10.24 s). */
+ uint16_t window; /**< Scan window between 0x0004 and 0x4000 in 0.625 ms units (2.5 ms to 10.24 s). */
+ uint16_t timeout; /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */
+} ble_gap_scan_params_t;
+
+
+/**@brief Device Privacy.
+ *
+ * The privacy feature provides a way for the device to avoid being tracked over a period of time.
+ * The privacy feature, when enabled, hides the local device identity and replaces it with a private address
+ * that is automatically refreshed at a specified interval.
+ *
+ * If a device still wants to be recognized by other peers, it needs to share it's Identity Resolving Key (IRK).
+ * With this key, a device can generate a random private address that can only be recognized by peers in possession of that key,
+ * and devices can establish connections without revealing their real identities.
+ *
+ * @note If the device IRK is updated, the new IRK becomes the one to be distributed in all
+ * bonding procedures performed after @ref sd_ble_gap_privacy_set returns.
+ * The IRK distributed during bonding procedure is the device IRK that is active when @ref sd_ble_gap_sec_params_reply is called.
+ */
+typedef struct
+{
+ uint8_t privacy_mode; /**< Privacy mode, see @ref BLE_GAP_PRIVACY_MODES. Default is @ref BLE_GAP_PRIVACY_MODE_OFF. */
+ uint8_t private_addr_type; /**< The private address type must be either @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE or @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE. */
+ uint16_t private_addr_cycle_s; /**< Private address cycle interval in seconds. Providing an address cycle value of 0 will use the default value defined by @ref BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S. */
+ ble_gap_irk_t *p_device_irk; /**< When used as input, pointer to IRK structure that will be used as the default IRK. If NULL, the device default IRK will be used.
+ When used as output, pointer to IRK structure where the current default IRK will be written to. If NULL, this argument is ignored.
+ By default, the default IRK is used to generate random private resolvable addresses for the local device unless instructed otherwise. */
+} ble_gap_privacy_params_t;
+
+
+/**@brief Physical Layer configuration
+ * @note tx_phys and rx_phys are bitfields, to indicate multiple preferred PHYs for each direction they can be ORed together.
+ * @code
+ * p_gap_phys->tx_phys = BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS;
+ * p_gap_phys->rx_phys = BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS;
+ * @endcode
+ *
+ */
+typedef struct
+{
+ uint8_t tx_phys; /**< Preferred transmit PHYs, see @ref BLE_GAP_PHYS. */
+ uint8_t rx_phys; /**< Preferred receive PHYs, see @ref BLE_GAP_PHYS. */
+} ble_gap_phys_t;
+
+/** @brief Keys that can be exchanged during a bonding procedure. */
+typedef struct
+{
+ uint8_t enc : 1; /**< Long Term Key and Master Identification. */
+ uint8_t id : 1; /**< Identity Resolving Key and Identity Address Information. */
+ uint8_t sign : 1; /**< Connection Signature Resolving Key. */
+ uint8_t link : 1; /**< Derive the Link Key from the LTK. */
+} ble_gap_sec_kdist_t;
+
+
+/**@brief GAP security parameters. */
+typedef struct
+{
+ uint8_t bond : 1; /**< Perform bonding. */
+ uint8_t mitm : 1; /**< Enable Man In The Middle protection. */
+ uint8_t lesc : 1; /**< Enable LE Secure Connection pairing. */
+ uint8_t keypress : 1; /**< Enable generation of keypress notifications. */
+ uint8_t io_caps : 3; /**< IO capabilities, see @ref BLE_GAP_IO_CAPS. */
+ uint8_t oob : 1; /**< The OOB data flag.
+ - In LE legacy pairing, this flag is set if a device has out of band authentication data.
+ The OOB method is used if both of the devices have out of band authentication data.
+ - In LE Secure Connections pairing, this flag is set if a device has the peer device's out of band authentication data.
+ The OOB method is used if at least one device has the peer device's OOB data available. */
+ uint8_t min_key_size; /**< Minimum encryption key size in octets between 7 and 16. If 0 then not applicable in this instance. */
+ uint8_t max_key_size; /**< Maximum encryption key size in octets between min_key_size and 16. */
+ ble_gap_sec_kdist_t kdist_own; /**< Key distribution bitmap: keys that the local device will distribute. */
+ ble_gap_sec_kdist_t kdist_peer; /**< Key distribution bitmap: keys that the remote device will distribute. */
+} ble_gap_sec_params_t;
+
+
+/**@brief GAP Encryption Information. */
+typedef struct
+{
+ uint8_t ltk[BLE_GAP_SEC_KEY_LEN]; /**< Long Term Key. */
+ uint8_t lesc : 1; /**< Key generated using LE Secure Connections. */
+ uint8_t auth : 1; /**< Authenticated Key. */
+ uint8_t ltk_len : 6; /**< LTK length in octets. */
+} ble_gap_enc_info_t;
+
+
+/**@brief GAP Master Identification. */
+typedef struct
+{
+ uint16_t ediv; /**< Encrypted Diversifier. */
+ uint8_t rand[BLE_GAP_SEC_RAND_LEN]; /**< Random Number. */
+} ble_gap_master_id_t;
+
+
+/**@brief GAP Signing Information. */
+typedef struct
+{
+ uint8_t csrk[BLE_GAP_SEC_KEY_LEN]; /**< Connection Signature Resolving Key. */
+} ble_gap_sign_info_t;
+
+
+/**@brief GAP LE Secure Connections P-256 Public Key. */
+typedef struct
+{
+ uint8_t pk[BLE_GAP_LESC_P256_PK_LEN]; /**< LE Secure Connections Elliptic Curve Diffie-Hellman P-256 Public Key. Stored in the standard SMP protocol format: {X,Y} both in little-endian. */
+} ble_gap_lesc_p256_pk_t;
+
+
+/**@brief GAP LE Secure Connections DHKey. */
+typedef struct
+{
+ uint8_t key[BLE_GAP_LESC_DHKEY_LEN]; /**< LE Secure Connections Elliptic Curve Diffie-Hellman Key. Stored in little-endian. */
+} ble_gap_lesc_dhkey_t;
+
+
+/**@brief GAP LE Secure Connections OOB data. */
+typedef struct
+{
+ ble_gap_addr_t addr; /**< Bluetooth address of the device. */
+ uint8_t r[BLE_GAP_SEC_KEY_LEN]; /**< Random Number. */
+ uint8_t c[BLE_GAP_SEC_KEY_LEN]; /**< Confirm Value. */
+} ble_gap_lesc_oob_data_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_CONNECTED. */
+typedef struct
+{
+ ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr resolved: @ref ble_gap_addr_t::addr_id_peer is set to 1
+ and the address is the device's identity address. */
+ uint8_t role; /**< BLE role for this connection, see @ref BLE_GAP_ROLES */
+ ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */
+} ble_gap_evt_connected_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_DISCONNECTED. */
+typedef struct
+{
+ uint8_t reason; /**< HCI error code, see @ref BLE_HCI_STATUS_CODES. */
+} ble_gap_evt_disconnected_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_CONN_PARAM_UPDATE. */
+typedef struct
+{
+ ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */
+} ble_gap_evt_conn_param_update_t;
+
+/**@brief Event Structure for @ref BLE_GAP_EVT_PHY_UPDATE. */
+typedef struct
+{
+ uint8_t status; /**< Status of the procedure, see @ref BLE_HCI_STATUS_CODES */
+ uint8_t tx_phy; /**< TX PHY for this connection, see @ref BLE_GAP_PHYS. */
+ uint8_t rx_phy; /**< RX PHY for this connection, see @ref BLE_GAP_PHYS. */
+} ble_gap_evt_phy_update_t;
+
+/**@brief Event structure for @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST. */
+typedef struct
+{
+ ble_gap_sec_params_t peer_params; /**< Initiator Security Parameters. */
+} ble_gap_evt_sec_params_request_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_SEC_INFO_REQUEST. */
+typedef struct
+{
+ ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. */
+ ble_gap_master_id_t master_id; /**< Master Identification for LTK lookup. */
+ uint8_t enc_info : 1; /**< If 1, Encryption Information required. */
+ uint8_t id_info : 1; /**< If 1, Identity Information required. */
+ uint8_t sign_info : 1; /**< If 1, Signing Information required. */
+} ble_gap_evt_sec_info_request_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_PASSKEY_DISPLAY. */
+typedef struct
+{
+ uint8_t passkey[BLE_GAP_PASSKEY_LEN]; /**< 6-digit passkey in ASCII ('0'-'9' digits only). */
+ uint8_t match_request : 1; /**< If 1 requires the application to report the match using @ref sd_ble_gap_auth_key_reply
+ with either @ref BLE_GAP_AUTH_KEY_TYPE_NONE if there is no match or
+ @ref BLE_GAP_AUTH_KEY_TYPE_PASSKEY if there is a match. */
+} ble_gap_evt_passkey_display_t;
+
+/**@brief Event structure for @ref BLE_GAP_EVT_KEY_PRESSED. */
+typedef struct
+{
+ uint8_t kp_not; /**< Keypress notification type, see @ref BLE_GAP_KP_NOT_TYPES. */
+} ble_gap_evt_key_pressed_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_AUTH_KEY_REQUEST. */
+typedef struct
+{
+ uint8_t key_type; /**< See @ref BLE_GAP_AUTH_KEY_TYPES. */
+} ble_gap_evt_auth_key_request_t;
+
+/**@brief Event structure for @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST. */
+typedef struct
+{
+ ble_gap_lesc_p256_pk_t *p_pk_peer; /**< LE Secure Connections remote P-256 Public Key. This will point to the application-supplied memory
+ inside the keyset during the call to @ref sd_ble_gap_sec_params_reply. */
+ uint8_t oobd_req :1; /**< LESC OOB data required. A call to @ref sd_ble_gap_lesc_oob_data_set is required to complete the procedure. */
+} ble_gap_evt_lesc_dhkey_request_t;
+
+
+/**@brief Security levels supported.
+ * @note See Bluetooth Specification Version 4.2 Volume 3, Part C, Chapter 10, Section 10.2.1.
+*/
+typedef struct
+{
+ uint8_t lv1 : 1; /**< If 1: Level 1 is supported. */
+ uint8_t lv2 : 1; /**< If 1: Level 2 is supported. */
+ uint8_t lv3 : 1; /**< If 1: Level 3 is supported. */
+ uint8_t lv4 : 1; /**< If 1: Level 4 is supported. */
+} ble_gap_sec_levels_t;
+
+
+/**@brief Encryption Key. */
+typedef struct
+{
+ ble_gap_enc_info_t enc_info; /**< Encryption Information. */
+ ble_gap_master_id_t master_id; /**< Master Identification. */
+} ble_gap_enc_key_t;
+
+
+/**@brief Identity Key. */
+typedef struct
+{
+ ble_gap_irk_t id_info; /**< Identity Resolving Key. */
+ ble_gap_addr_t id_addr_info; /**< Identity Address. */
+} ble_gap_id_key_t;
+
+
+/**@brief Security Keys. */
+typedef struct
+{
+ ble_gap_enc_key_t *p_enc_key; /**< Encryption Key, or NULL. */
+ ble_gap_id_key_t *p_id_key; /**< Identity Key, or NULL. */
+ ble_gap_sign_info_t *p_sign_key; /**< Signing Key, or NULL. */
+ ble_gap_lesc_p256_pk_t *p_pk; /**< LE Secure Connections P-256 Public Key. When in debug mode the application must use the value defined
+ in the Core Bluetooth Specification v4.2 Vol.3, Part H, Section 2.3.5.6.1 */
+} ble_gap_sec_keys_t;
+
+
+/**@brief Security key set for both local and peer keys. */
+typedef struct
+{
+ ble_gap_sec_keys_t keys_own; /**< Keys distributed by the local device. For LE Secure Connections the encryption key will be generated locally and will always be stored if bonding. */
+ ble_gap_sec_keys_t keys_peer; /**< Keys distributed by the remote device. For LE Secure Connections, p_enc_key must always be NULL. */
+} ble_gap_sec_keyset_t;
+
+
+/**@brief Data Length Update Procedure parameters. */
+typedef struct
+{
+ uint16_t max_tx_octets; /**< Maximum number of payload octets that a Controller supports for transmission of a single Link Layer Data Channel PDU. */
+ uint16_t max_rx_octets; /**< Maximum number of payload octets that a Controller supports for reception of a single Link Layer Data Channel PDU. */
+ uint16_t max_tx_time_us; /**< Maximum time, in microseconds, that a Controller supports for transmission of a single Link Layer Data Channel PDU. */
+ uint16_t max_rx_time_us; /**< Maximum time, in microseconds, that a Controller supports for reception of a single Link Layer Data Channel PDU. */
+} ble_gap_data_length_params_t;
+
+
+/**@brief Data Length Update Procedure local limitation. */
+typedef struct
+{
+ uint16_t tx_payload_limited_octets; /**< If > 0, the requested TX packet length is too long by this many octets. */
+ uint16_t rx_payload_limited_octets; /**< If > 0, the requested RX packet length is too long by this many octets. */
+ uint16_t tx_rx_time_limited_us; /**< If > 0, the requested combination of TX and RX packet lengths is too long by this many microseconds. */
+} ble_gap_data_length_limitation_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_AUTH_STATUS. */
+typedef struct
+{
+ uint8_t auth_status; /**< Authentication status, see @ref BLE_GAP_SEC_STATUS. */
+ uint8_t error_src : 2; /**< On error, source that caused the failure, see @ref BLE_GAP_SEC_STATUS_SOURCES. */
+ uint8_t bonded : 1; /**< Procedure resulted in a bond. */
+ ble_gap_sec_levels_t sm1_levels; /**< Levels supported in Security Mode 1. */
+ ble_gap_sec_levels_t sm2_levels; /**< Levels supported in Security Mode 2. */
+ ble_gap_sec_kdist_t kdist_own; /**< Bitmap stating which keys were exchanged (distributed) by the local device. If bonding with LE Secure Connections, the enc bit will be always set. */
+ ble_gap_sec_kdist_t kdist_peer; /**< Bitmap stating which keys were exchanged (distributed) by the remote device. If bonding with LE Secure Connections, the enc bit will never be set. */
+} ble_gap_evt_auth_status_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_CONN_SEC_UPDATE. */
+typedef struct
+{
+ ble_gap_conn_sec_t conn_sec; /**< Connection security level. */
+} ble_gap_evt_conn_sec_update_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_TIMEOUT. */
+typedef struct
+{
+ uint8_t src; /**< Source of timeout event, see @ref BLE_GAP_TIMEOUT_SOURCES. */
+} ble_gap_evt_timeout_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_RSSI_CHANGED. */
+typedef struct
+{
+ int8_t rssi; /**< Received Signal Strength Indication in dBm. */
+} ble_gap_evt_rssi_changed_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_ADV_REPORT. */
+typedef struct
+{
+ ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr resolved: @ref ble_gap_addr_t::addr_id_peer is set to 1
+ and the address is the device's identity address. */
+ ble_gap_addr_t direct_addr; /**< Set when the scanner is unable to resolve the private resolvable address of the initiator
+ field of a directed advertisement packet and the scanner has been enabled to report this in @ref ble_gap_scan_params_t::adv_dir_report. */
+ int8_t rssi; /**< Received Signal Strength Indication in dBm. */
+ uint8_t scan_rsp : 1; /**< If 1, the report corresponds to a scan response and the type field may be ignored. */
+ uint8_t type : 2; /**< See @ref BLE_GAP_ADV_TYPES. Only valid if the scan_rsp field is 0. */
+ uint8_t dlen : 5; /**< Advertising or scan response data length. */
+ uint8_t data[BLE_GAP_ADV_MAX_SIZE]; /**< Advertising or scan response data. */
+} ble_gap_evt_adv_report_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_SEC_REQUEST. */
+typedef struct
+{
+ uint8_t bond : 1; /**< Perform bonding. */
+ uint8_t mitm : 1; /**< Man In The Middle protection requested. */
+ uint8_t lesc : 1; /**< LE Secure Connections requested. */
+ uint8_t keypress : 1; /**< Generation of keypress notifications requested. */
+} ble_gap_evt_sec_request_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST. */
+typedef struct
+{
+ ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */
+} ble_gap_evt_conn_param_update_request_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_SCAN_REQ_REPORT. */
+typedef struct
+{
+ int8_t rssi; /**< Received Signal Strength Indication in dBm. */
+ ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr resolved: @ref ble_gap_addr_t::addr_id_peer is set to 1
+ and the address is the device's identity address. */
+} ble_gap_evt_scan_req_report_t;
+
+/**@brief Event structure for @ref BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST. */
+typedef struct
+{
+ ble_gap_data_length_params_t peer_params; /**< Peer data length parameters. */
+} ble_gap_evt_data_length_update_request_t;
+
+/**@brief Event structure for @ref BLE_GAP_EVT_DATA_LENGTH_UPDATE. */
+typedef struct
+{
+ ble_gap_data_length_params_t effective_params; /**< The effective data length parameters. */
+} ble_gap_evt_data_length_update_t;
+
+
+/**@brief GAP event structure. */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection Handle on which event occurred. */
+ union /**< union alternative identified by evt_id in enclosing struct. */
+ {
+ ble_gap_evt_connected_t connected; /**< Connected Event Parameters. */
+ ble_gap_evt_disconnected_t disconnected; /**< Disconnected Event Parameters. */
+ ble_gap_evt_conn_param_update_t conn_param_update; /**< Connection Parameter Update Parameters. */
+ ble_gap_evt_sec_params_request_t sec_params_request; /**< Security Parameters Request Event Parameters. */
+ ble_gap_evt_sec_info_request_t sec_info_request; /**< Security Information Request Event Parameters. */
+ ble_gap_evt_passkey_display_t passkey_display; /**< Passkey Display Event Parameters. */
+ ble_gap_evt_key_pressed_t key_pressed; /**< Key Pressed Event Parameters. */
+ ble_gap_evt_auth_key_request_t auth_key_request; /**< Authentication Key Request Event Parameters. */
+ ble_gap_evt_lesc_dhkey_request_t lesc_dhkey_request; /**< LE Secure Connections DHKey calculation request. */
+ ble_gap_evt_auth_status_t auth_status; /**< Authentication Status Event Parameters. */
+ ble_gap_evt_conn_sec_update_t conn_sec_update; /**< Connection Security Update Event Parameters. */
+ ble_gap_evt_timeout_t timeout; /**< Timeout Event Parameters. */
+ ble_gap_evt_rssi_changed_t rssi_changed; /**< RSSI Event Parameters. */
+ ble_gap_evt_adv_report_t adv_report; /**< Advertising Report Event Parameters. */
+ ble_gap_evt_sec_request_t sec_request; /**< Security Request Event Parameters. */
+ ble_gap_evt_conn_param_update_request_t conn_param_update_request; /**< Connection Parameter Update Parameters. */
+ ble_gap_evt_scan_req_report_t scan_req_report; /**< Scan Request Report Parameters. */
+ ble_gap_evt_phy_update_t phy_update; /**< PHY Update Parameters. */
+ ble_gap_evt_data_length_update_request_t data_length_update_request; /**< Data Length Update Request Event Parameters. */
+ ble_gap_evt_data_length_update_t data_length_update; /**< Data Length Update Event Parameters. */
+ } params; /**< Event Parameters. */
+} ble_gap_evt_t;
+
+
+/**
+ * @brief BLE GAP connection configuration parameters, set with @ref sd_ble_cfg_set.
+ *
+ * @retval ::NRF_ERROR_CONN_COUNT The connection count for the connection configurations is zero.
+ * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true:
+ * - The sum of conn_count for all connection configurations combined exceeds UINT8_MAX.
+ * - The event length is smaller than @ref BLE_GAP_EVENT_LENGTH_MIN.
+ */
+typedef struct
+{
+ uint8_t conn_count; /**< The number of concurrent connections the application can create with this configuration.
+ The default and minimum value is @ref BLE_GAP_CONN_COUNT_DEFAULT. */
+ uint16_t event_length; /**< The time set aside for this connection on every connection interval in 1.25 ms units.
+ The default value is @ref BLE_GAP_EVENT_LENGTH_DEFAULT, the minimum value is @ref BLE_GAP_EVENT_LENGTH_MIN.
+ The event length and the connection interval are the primary parameters
+ for setting the throughput of a connection.
+ See the SoftDevice Specification for details on throughput. */
+} ble_gap_conn_cfg_t;
+
+
+/**
+ * @brief Configuration of maximum concurrent connections in the different connected roles, set with
+ * @ref sd_ble_cfg_set.
+ *
+ * @retval ::NRF_ERROR_CONN_COUNT The sum of periph_role_count and central_role_count is too
+ * large. The maximum supported sum of concurrent connections is
+ * @ref BLE_GAP_ROLE_COUNT_COMBINED_MAX.
+ * @retval ::NRF_ERROR_INVALID_PARAM central_sec_count is larger than central_role_count.
+ */
+typedef struct
+{
+ uint8_t periph_role_count; /**< Maximum number of connections concurrently acting as a peripheral. Default value is @ref BLE_GAP_ROLE_COUNT_PERIPH_DEFAULT. */
+ uint8_t central_role_count; /**< Maximum number of connections concurrently acting as a central. Default value is @ref BLE_GAP_ROLE_COUNT_CENTRAL_DEFAULT. */
+ uint8_t central_sec_count; /**< Number of SMP instances shared between all connections acting as a central. Default value is @ref BLE_GAP_ROLE_COUNT_CENTRAL_SEC_DEFAULT. */
+} ble_gap_cfg_role_count_t;
+
+
+/**
+ * @brief Device name and its properties, set with @ref sd_ble_cfg_set.
+ *
+ * @note If the device name is not configured, the default device name will be @ref
+ * BLE_GAP_DEVNAME_DEFAULT, the maximum device name length will be @ref
+ * BLE_GAP_DEVNAME_DEFAULT_LEN, vloc will be set to @ref BLE_GATTS_VLOC_STACK and the device name
+ * will have no write access.
+ *
+ * @note If @ref max_len is more than @ref BLE_GAP_DEVNAME_DEFAULT_LEN and vloc is set to @ref BLE_GATTS_VLOC_STACK,
+ * the attribute table size must be increased to have room for the longer device name (see
+ * @ref sd_ble_cfg_set and @ref ble_gatts_cfg_attr_tab_size_t).
+ *
+ * @note If vloc is @ref BLE_GATTS_VLOC_STACK :
+ * - p_value must point to non-volatile memory (flash) or be NULL.
+ * - If p_value is NULL, the device name will initially be empty.
+ *
+ * @note If vloc is @ref BLE_GATTS_VLOC_USER :
+ * - p_value cannot be NULL.
+ * - If the device name is writable, p_value must point to volatile memory (RAM).
+ *
+ * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true:
+ * - Invalid device name location (vloc).
+ * - Invalid device name security mode.
+ * @retval ::NRF_ERROR_INVALID_LENGTH One or more of the following is true:
+ * - The device name length is invalid (must be between 0 and @ref BLE_GAP_DEVNAME_MAX_LEN).
+ * - The device name length is too long for the given Attribute Table.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Device name security mode is not supported.
+ */
+typedef struct
+{
+ ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */
+ uint8_t vloc:2; /**< Value location, see @ref BLE_GATTS_VLOCS.*/
+ uint8_t *p_value; /**< Pointer to where the value (device name) is stored or will be stored. */
+ uint16_t current_len; /**< Current length in bytes of the memory pointed to by p_value.*/
+ uint16_t max_len; /**< Maximum length in bytes of the memory pointed to by p_value.*/
+} ble_gap_cfg_device_name_t;
+
+
+/**@brief Configuration structure for GAP configurations. */
+typedef union
+{
+ ble_gap_cfg_role_count_t role_count_cfg; /**< Role count configuration, cfg_id is @ref BLE_GAP_CFG_ROLE_COUNT. */
+ ble_gap_cfg_device_name_t device_name_cfg; /**< Device name configuration, cfg_id is @ref BLE_GAP_CFG_DEVICE_NAME. */
+} ble_gap_cfg_t;
+
+
+/**@brief Channel Map option.
+ * Used with @ref sd_ble_opt_get to get the current channel map
+ * or @ref sd_ble_opt_set to set a new channel map. When setting the
+ * channel map, it applies to all current and future connections. When getting the
+ * current channel map, it applies to a single connection and the connection handle
+ * must be supplied.
+ *
+ * @note Setting the channel map may take some time, depending on connection parameters.
+ * The time taken may be different for each connection and the get operation will
+ * return the previous channel map until the new one has taken effect.
+ *
+ * @note After setting the channel map, by spec it can not be set again until at least 1 s has passed.
+ * See Bluetooth Specification Version 4.1 Volume 2, Part E, Section 7.3.46.
+ *
+ * @retval ::NRF_SUCCESS Get or set successful.
+ * @retval ::NRF_ERROR_BUSY Channel map was set again before enough time had passed.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied for get.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Returned by sd_ble_opt_set in peripheral-only SoftDevices.
+ *
+ */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection Handle (only applicable for get) */
+ uint8_t ch_map[5]; /**< Channel Map (37-bit). */
+} ble_gap_opt_ch_map_t;
+
+
+/**@brief Local connection latency option.
+ *
+ * Local connection latency is a feature which enables the slave to improve
+ * current consumption by ignoring the slave latency set by the peer. The
+ * local connection latency can only be set to a multiple of the slave latency,
+ * and cannot be longer than half of the supervision timeout.
+ *
+ * Used with @ref sd_ble_opt_set to set the local connection latency. The
+ * @ref sd_ble_opt_get is not supported for this option, but the actual
+ * local connection latency (unless set to NULL) is set as a return parameter
+ * when setting the option.
+ *
+ * @note The latency set will be truncated down to the closest slave latency event
+ * multiple, or the nearest multiple before half of the supervision timeout.
+ *
+ * @note The local connection latency is disabled by default, and needs to be enabled for new
+ * connections and whenever the connection is updated.
+ *
+ * @retval ::NRF_SUCCESS Set successfully.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Get is not supported.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter.
+ */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection Handle */
+ uint16_t requested_latency; /**< Requested local connection latency. */
+ uint16_t * p_actual_latency; /**< Pointer to storage for the actual local connection latency (can be set to NULL to skip return value). */
+} ble_gap_opt_local_conn_latency_t;
+
+/**@brief Disable slave latency
+ *
+ * Used with @ref sd_ble_opt_set to temporarily disable slave latency of a peripheral connection (see @ref ble_gap_conn_params_t::slave_latency). And to re-enable it again.
+ * When disabled, the peripheral will ignore the slave_latency set by the central.
+ *
+ * @note Shall only be called on peripheral links.
+ *
+ * @retval ::NRF_SUCCESS Set successfully.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Get is not supported.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter.
+ */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection Handle */
+ uint8_t disable : 1; /**< Set to 1 to disable slave latency. Set to 0 enable it again.*/
+} ble_gap_opt_slave_latency_disable_t;
+
+/**@brief Passkey Option.
+ *
+ * Structure containing the passkey to be used during pairing. This can be used with @ref
+ * sd_ble_opt_set to make the SoftDevice use a preprogrammed passkey for authentication
+ * instead of generating a random one.
+ *
+ * @note Repeated pairing attempts using the same preprogrammed passkey makes pairing vulnerable to MITM attacks.
+ *
+ * @note @ref sd_ble_opt_get is not supported for this option.
+ *
+ */
+typedef struct
+{
+ uint8_t const * p_passkey; /**< Pointer to 6-digit ASCII string (digit 0..9 only, no NULL termination) passkey to be used during pairing. If this is NULL, the SoftDevice will generate a random passkey if required.*/
+} ble_gap_opt_passkey_t;
+
+
+/**@brief Scan request report option.
+ *
+ * This can be used with @ref sd_ble_opt_set to make the SoftDevice send
+ * @ref BLE_GAP_EVT_SCAN_REQ_REPORT events.
+ *
+ * @note Due to the limited space reserved for scan request report events,
+ * not all received scan requests will be reported.
+ *
+ * @note If whitelisting is used, only whitelisted requests are reported.
+ *
+ * @retval ::NRF_SUCCESS Set successfully.
+ * @retval ::NRF_ERROR_INVALID_STATE When advertising is ongoing while the option is set.
+ */
+typedef struct
+{
+ uint8_t enable : 1; /**< Enable scan request reports. */
+} ble_gap_opt_scan_req_report_t;
+
+/**@brief Compatibility mode 1 option.
+ *
+ * This can be used with @ref sd_ble_opt_set to enable and disable
+ * compatibility mode 1. Compatibility mode 1 is disabled by default.
+ *
+ * @note Compatibility mode 1 enables interoperability with devices that do not support
+ * a value of 0 for the WinOffset parameter in the Link Layer CONNECT_REQ packet.
+ *
+ * @retval ::NRF_SUCCESS Set successfully.
+ * @retval ::NRF_ERROR_INVALID_STATE When connection creation is ongoing while mode 1 is set.
+ */
+typedef struct
+{
+ uint8_t enable : 1; /**< Enable compatibility mode 1.*/
+} ble_gap_opt_compat_mode_1_t;
+
+/**@brief Compatibility mode 2 option.
+ *
+ * This can be used with @ref sd_ble_opt_set to enable compatibility mode 2.
+ * Compatibility mode 2 is disabled by default.
+ *
+ * @note Compatibility mode 2 enables interoperability with devices that initiate Feature exchange
+ * and version exchange procedure in parallel.
+ *
+ * @retval ::NRF_SUCCESS Set successfully.
+ * @retval ::NRF_ERROR_INVALID_PARAM if enable bit is not set to 1. Currently only enabling is supported.
+ * @retval ::NRF_ERROR_INVALID_STATE When any role is running while mode 2 is set.
+ */
+typedef struct
+{
+ uint8_t enable : 1; /**< Enable compatibility mode 2.*/
+} ble_gap_opt_compat_mode_2_t;
+
+
+/**@brief Authenticated payload timeout option.
+ *
+ * This can be used with @ref sd_ble_opt_set to change the Authenticated payload timeout to a value other than the default of 8 minutes.
+ *
+ * @note The authenticated payload timeout event ::BLE_GAP_TIMEOUT_SRC_AUTH_PAYLOAD will be generated
+ * if auth_payload_timeout time has elapsed without receiving a packet with a valid MIC on an encrypted
+ * link.
+ *
+ * @note The LE ping procedure will be initiated before the timer expires to give the peer a chance
+ * to reset the timer. In addition the stack will try to prioritize running of LE ping over other
+ * activities to increase chances of finishing LE ping before timer expires. To avoid side-effects
+ * on other activities, it is recommended to use high timeout values.
+ * Recommended timeout > 2*(connInterval * (6 + connSlaveLatency)).
+ *
+ * @retval ::NRF_SUCCESS Set successfully.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. auth_payload_timeout was outside of allowed range.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter.
+ */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection Handle */
+ uint16_t auth_payload_timeout; /**< Requested timeout in 10 ms unit. Maximum is 48 000 (=480 000 ms =8 min). Minimum is 1 (=10 ms). */
+} ble_gap_opt_auth_payload_timeout_t;
+
+/**@brief Preferred PHY option
+ *
+ * @details This can be used with @ref sd_ble_opt_set to change the preferred PHYs. Before this function is called the PHYs
+ * for peer initiated PHY Update procedure is @ref BLE_GAP_PHY_1MBPS. If @ref ble_gap_opt_preferred_phys_t::tx_phys or
+ * @ref ble_gap_opt_preferred_phys_t::rx_phys is 0, then the stack will select PHYs based on the peer requirements on that specific direction.
+ *
+ * @note The preferred PHYs are only valid for newly created connections after this option is called. If the PHYs should be
+ * changed for an existing link the @ref sd_ble_gap_phy_request would have to be called, and that would try to update the
+ * PHYs for the given link.
+ *
+ * @note tx_phys and rx_phys are bitfields, to indicate multiple preferred PHYs for each direction they can be ORed together.
+ * @code
+ * tx_phys = BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS;
+ * rx_phys = BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS;
+ * @endcode
+ *
+ * @events
+ * @event{@ref BLE_GAP_EVT_PHY_UPDATE, Result of the PHY Update if initiated by peer.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_CENTRAL_PHY_REQUEST}
+ * @mmsc{@ref BLE_GAP_PERIPHERAL_PHY_REQUEST}
+ * @endmscs
+ *
+ * @retval ::NRF_SUCCESS Set successfully.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ */
+typedef struct
+{
+ uint8_t tx_phys; /**< Preferred transmit PHYs, see @ref BLE_GAP_PHYS. */
+ uint8_t rx_phys; /**< Preferred receive PHYs, see @ref BLE_GAP_PHYS. */
+} ble_gap_opt_preferred_phys_t;
+
+/**@brief Option structure for GAP options. */
+typedef union
+{
+ ble_gap_opt_ch_map_t ch_map; /**< Parameters for the Channel Map option. */
+ ble_gap_opt_local_conn_latency_t local_conn_latency; /**< Parameters for the Local connection latency option */
+ ble_gap_opt_passkey_t passkey; /**< Parameters for the Passkey option.*/
+ ble_gap_opt_scan_req_report_t scan_req_report; /**< Parameters for the scan request report option.*/
+ ble_gap_opt_compat_mode_1_t compat_mode_1; /**< Parameters for the compatibility mode 1 option.*/
+ ble_gap_opt_compat_mode_2_t compat_mode_2; /**< Parameters for the compatibility mode 2 option.*/
+ ble_gap_opt_auth_payload_timeout_t auth_payload_timeout; /**< Parameters for the authenticated payload timeout option.*/
+ ble_gap_opt_preferred_phys_t preferred_phys; /**< Parameters for the preferred PHYs option. */
+ ble_gap_opt_slave_latency_disable_t slave_latency_disable; /**< Parameters for the Disable slave latency option */
+} ble_gap_opt_t;
+/**@} */
+
+
+/**@addtogroup BLE_GAP_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Set the local Bluetooth identity address.
+ *
+ * The local Bluetooth identity address is the address that identifies this device to other peers.
+ * The address type must be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC.
+ * The identity address cannot be changed while roles are running.
+ *
+ * @note This address will be distributed to the peer during bonding.
+ * If the address changes, the address stored in the peer device will not be valid and the ability to
+ * reconnect using the old address will be lost.
+ *
+ * @note By default the SoftDevice will set an address of type @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC upon being
+ * enabled. The address is a random number populated during the IC manufacturing process and remains unchanged
+ * for the lifetime of each IC.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_ADV_MSC}
+ * @endmscs
+ *
+ * @param[in] p_addr Pointer to address structure.
+ *
+ * @retval ::NRF_SUCCESS Address successfully set.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address.
+ * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry.
+ * @retval ::NRF_ERROR_INVALID_STATE The identity address cannot be changed while the roles are running.
+ */
+SVCALL(SD_BLE_GAP_ADDR_SET, uint32_t, sd_ble_gap_addr_set(ble_gap_addr_t const *p_addr));
+
+
+/**@brief Get local Bluetooth identity address.
+ *
+ * @note This will always return the identity address irrespective of the privacy settings,
+ * i.e. the address type will always be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC.
+ *
+ * @param[out] p_addr Pointer to address structure to be filled in.
+ *
+ * @retval ::NRF_SUCCESS Address successfully retrieved.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid or NULL pointer supplied.
+ */
+SVCALL(SD_BLE_GAP_ADDR_GET, uint32_t, sd_ble_gap_addr_get(ble_gap_addr_t *p_addr));
+
+
+/**@brief Set the active whitelist in the SoftDevice.
+ *
+ * @note Only one whitelist can be used at a time and the whitelist is shared between the BLE roles.
+ * The whitelist cannot be set if a BLE role is using the whitelist.
+ *
+ * @note If an address is resolved using the information in the device identity list, then the whitelist
+ * filter policy applies to the peer identity address and not the resolvable address sent on air.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_WL_SHARE_MSC}
+ * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_PRIVATE_SCAN_MSC}
+ * @endmscs
+ *
+ * @param[in] pp_wl_addrs Pointer to a whitelist of peer addresses, if NULL the whitelist will be cleared.
+ * @param[in] len Length of the whitelist, maximum @ref BLE_GAP_WHITELIST_ADDR_MAX_COUNT.
+ *
+ * @retval ::NRF_SUCCESS The whitelist is successfully set/cleared.
+ * @retval ::NRF_ERROR_INVALID_ADDR The whitelist (or one of its entries) provided is invalid.
+ * @retval ::BLE_ERROR_GAP_WHITELIST_IN_USE The whitelist is in use by a BLE role and cannot be set or cleared.
+ * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied.
+ * @retval ::NRF_ERROR_DATA_SIZE The given whitelist size is invalid (zero or too large); this can only return when
+ * pp_wl_addrs is not NULL.
+ */
+SVCALL(SD_BLE_GAP_WHITELIST_SET, uint32_t, sd_ble_gap_whitelist_set(ble_gap_addr_t const * const * pp_wl_addrs, uint8_t len));
+
+
+/**@brief Set device identity list.
+ *
+ * @note Only one device identity list can be used at a time and the list is shared between the BLE roles.
+ * The device identity list cannot be set if a BLE role is using the list.
+ *
+ * @param[in] pp_id_keys Pointer to an array of peer identity addresses and peer IRKs, if NULL the device identity list will be cleared.
+ * @param[in] pp_local_irks Pointer to an array of local IRKs. Each entry in the array maps to the entry in pp_id_keys at the same index.
+ * To fill in the list with the currently set device IRK for all peers, set to NULL.
+ * @param[in] len Length of the device identity list, maximum @ref BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PRIVACY_ADV_MSC}
+ * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_MSC}
+ * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_PRIVATE_SCAN_MSC}
+ * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_CONN_PRIV_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_CONN_PRIV_MSC}
+ * @endmscs
+ *
+ * @retval ::NRF_SUCCESS The device identity list successfully set/cleared.
+ * @retval ::NRF_ERROR_INVALID_ADDR The device identity list (or one of its entries) provided is invalid.
+ * This code may be returned if the local IRK list also has an invalid entry.
+ * @retval ::BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE The device identity list is in use and cannot be set or cleared.
+ * @retval ::BLE_ERROR_GAP_DEVICE_IDENTITIES_DUPLICATE The device identity list contains multiple entries with the same identity address.
+ * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied.
+ * @retval ::NRF_ERROR_DATA_SIZE The given device identity list size invalid (zero or too large); this can
+ * only return when pp_id_keys is not NULL.
+ */
+SVCALL(SD_BLE_GAP_DEVICE_IDENTITIES_SET, uint32_t, sd_ble_gap_device_identities_set(ble_gap_id_key_t const * const * pp_id_keys, ble_gap_irk_t const * const * pp_local_irks, uint8_t len));
+
+
+/**@brief Set privacy settings.
+ *
+ * @note Privacy settings cannot be set while BLE roles are running.
+ *
+ * @param[in] p_privacy_params Privacy settings.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PRIVACY_ADV_MSC}
+ * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_MSC}
+ * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC}
+ * @endmscs
+ *
+ * @retval ::NRF_SUCCESS Set successfully.
+ * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry.
+ * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied.
+ * @retval ::NRF_ERROR_INVALID_ADDR The pointer to privacy settings is NULL or invalid.
+ * Otherwise, the p_device_irk pointer in privacy parameter is an invalid pointer.
+ * @retval ::NRF_ERROR_INVALID_PARAM Out of range parameters are provided.
+ * @retval ::NRF_ERROR_INVALID_STATE Privacy settings cannot be changed while BLE roles using privacy are enabled.
+ */
+SVCALL(SD_BLE_GAP_PRIVACY_SET, uint32_t, sd_ble_gap_privacy_set(ble_gap_privacy_params_t const *p_privacy_params));
+
+
+/**@brief Get privacy settings.
+ *
+ * @note The privacy settings returned include the current device irk as well.
+ *
+ * @param[in] p_privacy_params Privacy settings.
+ *
+ * @retval ::NRF_SUCCESS Privacy settings read.
+ * @retval ::NRF_ERROR_INVALID_ADDR The pointer given for returning the privacy settings may be NULL or invalid.
+ * Otherwise, the p_device_irk pointer in privacy parameter is an invalid pointer.
+ */
+SVCALL(SD_BLE_GAP_PRIVACY_GET, uint32_t, sd_ble_gap_privacy_get(ble_gap_privacy_params_t *p_privacy_params));
+
+
+/**@brief Set, clear or update advertising and scan response data.
+ *
+ * @note The format of the advertising data will be checked by this call to ensure interoperability.
+ * Limitations imposed by this API call to the data provided include having a flags data type in the scan response data and
+ * duplicating the local name in the advertising data and scan response data.
+ *
+ * @note To clear the advertising data and set it to a 0-length packet, simply provide a valid pointer (p_data/p_sr_data) with its corresponding
+ * length (dlen/srdlen) set to 0.
+ *
+ * @note The call will fail if p_data and p_sr_data are both NULL since this would have no effect.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_ADV_MSC}
+ * @mmsc{@ref BLE_GAP_WL_SHARE_MSC}
+ * @endmscs
+ *
+ * @param[in] p_data Raw data to be placed in advertising packet. If NULL, no changes are made to the current advertising packet data.
+ * @param[in] dlen Data length for p_data. Max size: @ref BLE_GAP_ADV_MAX_SIZE octets. Should be 0 if p_data is NULL, can be 0 if p_data is not NULL.
+ * @param[in] p_sr_data Raw data to be placed in scan response packet. If NULL, no changes are made to the current scan response packet data.
+ * @param[in] srdlen Data length for p_sr_data. Max size: @ref BLE_GAP_ADV_MAX_SIZE octets. Should be 0 if p_sr_data is NULL, can be 0 if p_data is not NULL.
+ *
+ * @retval ::NRF_SUCCESS Advertising data successfully updated or cleared.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, both p_data and p_sr_data cannot be NULL.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_FLAGS Invalid combination of advertising flags supplied.
+ * @retval ::NRF_ERROR_INVALID_DATA Invalid data type(s) supplied, check the advertising data format specification.
+ * @retval ::NRF_ERROR_INVALID_LENGTH Invalid data length(s) supplied.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Unsupported data type.
+ * @retval ::BLE_ERROR_GAP_UUID_LIST_MISMATCH Invalid UUID list supplied.
+ */
+SVCALL(SD_BLE_GAP_ADV_DATA_SET, uint32_t, sd_ble_gap_adv_data_set(uint8_t const *p_data, uint8_t dlen, uint8_t const *p_sr_data, uint8_t srdlen));
+
+
+/**@brief Start advertising (GAP Discoverable, Connectable modes, Broadcast Procedure).
+ *
+ * @note An application can start an advertising procedure for broadcasting purposes while a connection
+ * is active. After a @ref BLE_GAP_EVT_CONNECTED event is received, this function may therefore
+ * be called to start a broadcast advertising procedure. The advertising procedure
+ * cannot however be connectable (it must be of type @ref BLE_GAP_ADV_TYPE_ADV_SCAN_IND or
+ * @ref BLE_GAP_ADV_TYPE_ADV_NONCONN_IND). @note Only one advertiser may be active at any time.
+ *
+ * @events
+ * @event{@ref BLE_GAP_EVT_CONNECTED, Generated after connection has been established through connectable advertising.}
+ * @event{@ref BLE_GAP_EVT_TIMEOUT, Advertisement has timed out.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_ADV_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_CONN_PRIV_MSC}
+ * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC}
+ * @mmsc{@ref BLE_GAP_WL_SHARE_MSC}
+ * @endmscs
+ *
+ * @param[in] p_adv_params Pointer to advertising parameters structure.
+ * @param[in] conn_cfg_tag Tag identifying a configuration set by @ref sd_ble_cfg_set or @ref
+ * BLE_CONN_CFG_TAG_DEFAULT to use the default connection configuration.
+ *
+ * @retval ::NRF_SUCCESS The BLE stack has started advertising.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::NRF_ERROR_CONN_COUNT The limit of available connections has been reached; connectable advertiser cannot be started.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check the accepted ranges and limits.
+ * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid Bluetooth address supplied.
+ * @retval ::BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST Discoverable mode and whitelist incompatible.
+ * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry.
+ * @retval ::NRF_ERROR_RESOURCES Not enough BLE role slots available.
+ * Stop one or more currently active roles (Central, Peripheral or Observer) and try again
+ */
+SVCALL(SD_BLE_GAP_ADV_START, uint32_t, sd_ble_gap_adv_start(ble_gap_adv_params_t const *p_adv_params, uint8_t conn_cfg_tag));
+
+
+/**@brief Stop advertising (GAP Discoverable, Connectable modes, Broadcast Procedure).
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_ADV_MSC}
+ * @mmsc{@ref BLE_GAP_WL_SHARE_MSC}
+ * @endmscs
+ *
+ * @retval ::NRF_SUCCESS The BLE stack has stopped advertising.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation (most probably not in advertising state).
+ */
+SVCALL(SD_BLE_GAP_ADV_STOP, uint32_t, sd_ble_gap_adv_stop(void));
+
+
+
+/**@brief Update connection parameters.
+ *
+ * @details In the central role this will initiate a Link Layer connection parameter update procedure,
+ * otherwise in the peripheral role, this will send the corresponding L2CAP request and wait for
+ * the central to perform the procedure. In both cases, and regardless of success or failure, the application
+ * will be informed of the result with a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE event.
+ *
+ * @details This function can be used as a central both to reply to a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST or to start the procedure unrequested.
+ *
+ * @events
+ * @event{@ref BLE_GAP_EVT_CONN_PARAM_UPDATE, Result of the connection parameter update procedure.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_CPU_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC}
+ * @mmsc{@ref BLE_GAP_MULTILINK_CPU_MSC}
+ * @mmsc{@ref BLE_GAP_MULTILINK_CTRL_PROC_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_CPU_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_conn_params Pointer to desired connection parameters. If NULL is provided on a peripheral role,
+ * the parameters in the PPCP characteristic of the GAP service will be used instead.
+ * If NULL is provided on a central role and in response to a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, the peripheral request will be rejected
+ *
+ * @retval ::NRF_SUCCESS The Connection Update procedure has been started successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::NRF_ERROR_BUSY Procedure already in progress or not allowed at this time, process pending events and wait for pending procedures to complete and retry.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
+ */
+SVCALL(SD_BLE_GAP_CONN_PARAM_UPDATE, uint32_t, sd_ble_gap_conn_param_update(uint16_t conn_handle, ble_gap_conn_params_t const *p_conn_params));
+
+
+/**@brief Disconnect (GAP Link Termination).
+ *
+ * @details This call initiates the disconnection procedure, and its completion will be communicated to the application
+ * with a @ref BLE_GAP_EVT_DISCONNECTED event.
+ *
+ * @events
+ * @event{@ref BLE_GAP_EVT_DISCONNECTED, Generated when disconnection procedure is complete.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_CONN_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] hci_status_code HCI status code, see @ref BLE_HCI_STATUS_CODES (accepted values are @ref BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION and @ref BLE_HCI_CONN_INTERVAL_UNACCEPTABLE).
+ *
+ * @retval ::NRF_SUCCESS The disconnection procedure has been started successfully.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation (disconnection is already in progress).
+ */
+SVCALL(SD_BLE_GAP_DISCONNECT, uint32_t, sd_ble_gap_disconnect(uint16_t conn_handle, uint8_t hci_status_code));
+
+
+/**@brief Set the radio's transmit power.
+ *
+ * @param[in] tx_power Radio transmit power in dBm (accepted values are -40, -20, -16, -12, -8, -4, 0, 2, 3, 4, 5, 6, 7, 8 and 9 dBm).
+ *
+ * @note The -40dBm, -20dBm, -16dBm, -12dBm, -8dBm, -4dBm, 0dBm, +2dBm, +3dBm, +4dBm, +5dBm, +6dBm, +7dBm, +8dBm and +9dBm settings are available on nRF52840 series ICs.
+ * @note The -40dBm, -20dBm, -16dBm, -12dBm, -8dBm, -4dBm, 0dBm, +3dBm and +4dBm settings are available on nRF52 series ICs.
+ *
+ * @retval ::NRF_SUCCESS Successfully changed the transmit power.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ */
+SVCALL(SD_BLE_GAP_TX_POWER_SET, uint32_t, sd_ble_gap_tx_power_set(int8_t tx_power));
+
+
+/**@brief Set GAP Appearance value.
+ *
+ * @param[in] appearance Appearance (16-bit), see @ref BLE_APPEARANCES.
+ *
+ * @retval ::NRF_SUCCESS Appearance value set successfully.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ */
+SVCALL(SD_BLE_GAP_APPEARANCE_SET, uint32_t, sd_ble_gap_appearance_set(uint16_t appearance));
+
+
+/**@brief Get GAP Appearance value.
+ *
+ * @param[out] p_appearance Pointer to appearance (16-bit) to be filled in, see @ref BLE_APPEARANCES.
+ *
+ * @retval ::NRF_SUCCESS Appearance value retrieved successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ */
+SVCALL(SD_BLE_GAP_APPEARANCE_GET, uint32_t, sd_ble_gap_appearance_get(uint16_t *p_appearance));
+
+
+/**@brief Set GAP Peripheral Preferred Connection Parameters.
+ *
+ * @param[in] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure with the desired parameters.
+ *
+ * @retval ::NRF_SUCCESS Peripheral Preferred Connection Parameters set successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ */
+SVCALL(SD_BLE_GAP_PPCP_SET, uint32_t, sd_ble_gap_ppcp_set(ble_gap_conn_params_t const *p_conn_params));
+
+
+/**@brief Get GAP Peripheral Preferred Connection Parameters.
+ *
+ * @param[out] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure where the parameters will be stored.
+ *
+ * @retval ::NRF_SUCCESS Peripheral Preferred Connection Parameters retrieved successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ */
+SVCALL(SD_BLE_GAP_PPCP_GET, uint32_t, sd_ble_gap_ppcp_get(ble_gap_conn_params_t *p_conn_params));
+
+
+/**@brief Set GAP device name.
+ *
+ * @note If the device name is located in application flash memory (see @ref ble_gap_cfg_device_name_t),
+ * it cannot be changed. Then @ref NRF_ERROR_FORBIDDEN will be returned.
+ *
+ * @param[in] p_write_perm Write permissions for the Device Name characteristic, see @ref ble_gap_conn_sec_mode_t.
+ * @param[in] p_dev_name Pointer to a UTF-8 encoded, <b>non NULL-terminated</b> string.
+ * @param[in] len Length of the UTF-8, <b>non NULL-terminated</b> string pointed to by p_dev_name in octets (must be smaller or equal than @ref BLE_GAP_DEVNAME_MAX_LEN).
+ *
+ * @retval ::NRF_SUCCESS GAP device name and permissions set successfully.
+ * @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_FORBIDDEN Device name is not writable.
+ */
+SVCALL(SD_BLE_GAP_DEVICE_NAME_SET, uint32_t, sd_ble_gap_device_name_set(ble_gap_conn_sec_mode_t const *p_write_perm, uint8_t const *p_dev_name, uint16_t len));
+
+
+/**@brief Get GAP device name.
+ *
+ * @note If the device name is longer than the size of the supplied buffer,
+ * p_len will return the complete device name length,
+ * and not the number of bytes actually returned in p_dev_name.
+ * The application may use this information to allocate a suitable buffer size.
+ *
+ * @param[out] p_dev_name Pointer to an empty buffer where the UTF-8 <b>non NULL-terminated</b> string will be placed. Set to NULL to obtain the complete device name length.
+ * @param[in,out] p_len Length of the buffer pointed by p_dev_name, complete device name length on output.
+ *
+ * @retval ::NRF_SUCCESS GAP device name retrieved successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied.
+ */
+SVCALL(SD_BLE_GAP_DEVICE_NAME_GET, uint32_t, sd_ble_gap_device_name_get(uint8_t *p_dev_name, uint16_t *p_len));
+
+
+/**@brief Initiate the GAP Authentication procedure.
+ *
+ * @details In the central role, this function will send an SMP Pairing Request (or an SMP Pairing Failed if rejected),
+ * otherwise in the peripheral role, an SMP Security Request will be sent.
+ *
+ * @events
+ * @event{Depending on the security parameters set and the packet exchanges with the peer\, the following events may be generated:}
+ * @event{@ref BLE_GAP_EVT_SEC_PARAMS_REQUEST}
+ * @event{@ref BLE_GAP_EVT_SEC_INFO_REQUEST}
+ * @event{@ref BLE_GAP_EVT_PASSKEY_DISPLAY}
+ * @event{@ref BLE_GAP_EVT_KEY_PRESSED}
+ * @event{@ref BLE_GAP_EVT_AUTH_KEY_REQUEST}
+ * @event{@ref BLE_GAP_EVT_LESC_DHKEY_REQUEST}
+ * @event{@ref BLE_GAP_EVT_CONN_SEC_UPDATE}
+ * @event{@ref BLE_GAP_EVT_AUTH_STATUS}
+ * @event{@ref BLE_GAP_EVT_TIMEOUT}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_SEC_REQ_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_SEC_REQ_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_PAIRING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_sec_params Pointer to the @ref ble_gap_sec_params_t structure with the security parameters to be used during the pairing or bonding procedure.
+ * In the peripheral role, only the bond, mitm, lesc and keypress fields of this structure are used.
+ * In the central role, this pointer may be NULL to reject a Security Request.
+ *
+ * @retval ::NRF_SUCCESS Successfully initiated authentication procedure.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry.
+ * @retval ::NRF_ERROR_NO_MEM The maximum number of authentication procedures that can run in parallel for the given role is reached.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Setting of sign or link fields in @ref ble_gap_sec_kdist_t not supported.
+ * @retval ::NRF_ERROR_TIMEOUT A SMP timeout has occurred, and further SMP operations on this link is prohibited.
+ */
+SVCALL(SD_BLE_GAP_AUTHENTICATE, uint32_t, sd_ble_gap_authenticate(uint16_t conn_handle, ble_gap_sec_params_t const *p_sec_params));
+
+
+/**@brief Reply with GAP security parameters.
+ *
+ * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE.
+ * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters.
+ *
+ * @events
+ * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_BONDING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_PERIPH_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_CENTRAL_OOB_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_BONDING_STATIC_PK_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_CONFIRM_FAIL_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_PAIRING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_PD_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_KS_TOO_SMALL_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_APP_ERROR_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_REMOTE_PAIRING_FAIL_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_TIMEOUT_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_PAIRING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] sec_status Security status, see @ref BLE_GAP_SEC_STATUS.
+ * @param[in] p_sec_params Pointer to a @ref ble_gap_sec_params_t security parameters structure. In the central role this must be set to NULL, as the parameters have
+ * already been provided during a previous call to @ref sd_ble_gap_authenticate.
+ * @param[in,out] p_sec_keyset Pointer to a @ref ble_gap_sec_keyset_t security keyset structure. Any keys generated and/or distributed as a result of the ongoing security procedure
+ * will be stored into the memory referenced by the pointers inside this structure. The keys will be stored and available to the application
+ * upon reception of a @ref BLE_GAP_EVT_AUTH_STATUS event.
+ * Note that the SoftDevice expects the application to provide memory for storing the
+ * peer's keys. So it must be ensured that the relevant pointers inside this structure are not NULL. The pointers to the local key
+ * can, however, be NULL, in which case, the local key data will not be available to the application upon reception of the
+ * @ref BLE_GAP_EVT_AUTH_STATUS event.
+ *
+ * @retval ::NRF_SUCCESS Successfully accepted security parameter from the application.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Setting of sign or link fields in @ref ble_gap_sec_kdist_t not supported.
+ */
+SVCALL(SD_BLE_GAP_SEC_PARAMS_REPLY, uint32_t, sd_ble_gap_sec_params_reply(uint16_t conn_handle, uint8_t sec_status, ble_gap_sec_params_t const *p_sec_params, ble_gap_sec_keyset_t const *p_sec_keyset));
+
+
+/**@brief Reply with an authentication key.
+ *
+ * @details This function is only used to reply to a @ref BLE_GAP_EVT_AUTH_KEY_REQUEST or a @ref BLE_GAP_EVT_PASSKEY_DISPLAY, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE.
+ * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters.
+ *
+ * @events
+ * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_CENTRAL_OOB_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] key_type See @ref BLE_GAP_AUTH_KEY_TYPES.
+ * @param[in] p_key If key type is @ref BLE_GAP_AUTH_KEY_TYPE_NONE, then NULL.
+ * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_PASSKEY, then a 6-byte ASCII string (digit 0..9 only, no NULL termination)
+ * or NULL when confirming LE Secure Connections Numeric Comparison.
+ * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_OOB, then a 16-byte OOB key value in little-endian format.
+ *
+ * @retval ::NRF_SUCCESS Authentication key successfully set.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_AUTH_KEY_REPLY, uint32_t, sd_ble_gap_auth_key_reply(uint16_t conn_handle, uint8_t key_type, uint8_t const *p_key));
+
+/**@brief Reply with an LE Secure connections DHKey.
+ *
+ * @details This function is only used to reply to a @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE.
+ * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters.
+ *
+ * @events
+ * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_PAIRING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_PD_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_dhkey LE Secure Connections DHKey.
+ *
+ * @retval ::NRF_SUCCESS DHKey successfully set.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_LESC_DHKEY_REPLY, uint32_t, sd_ble_gap_lesc_dhkey_reply(uint16_t conn_handle, ble_gap_lesc_dhkey_t const *p_dhkey));
+
+/**@brief Notify the peer of a local keypress.
+ *
+ * @details This function can only be used when an authentication procedure using LE Secure Connection is in progress. Calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] kp_not See @ref BLE_GAP_KP_NOT_TYPES.
+ *
+ * @retval ::NRF_SUCCESS Keypress notification successfully queued for transmission.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either not entering a passkey or keypresses have not been enabled by both peers.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::NRF_ERROR_BUSY The BLE stack is busy. Retry at later time.
+ */
+SVCALL(SD_BLE_GAP_KEYPRESS_NOTIFY, uint32_t, sd_ble_gap_keypress_notify(uint16_t conn_handle, uint8_t kp_not));
+
+/**@brief Generate a set of OOB data to send to a peer out of band.
+ *
+ * @note The @ref ble_gap_addr_t included in the OOB data returned will be the currently active one (or, if a connection has already been established,
+ * the one used during connection setup). The application may manually overwrite it with an updated value.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle. Can be BLE_CONN_HANDLE_INVALID if a BLE connection has not been established yet.
+ * @param[in] p_pk_own LE Secure Connections local P-256 Public Key.
+ * @param[out] p_oobd_own The OOB data to be sent out of band to a peer.
+ *
+ * @retval ::NRF_SUCCESS OOB data successfully generated.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_LESC_OOB_DATA_GET, uint32_t, sd_ble_gap_lesc_oob_data_get(uint16_t conn_handle, ble_gap_lesc_p256_pk_t const *p_pk_own, ble_gap_lesc_oob_data_t *p_oobd_own));
+
+/**@brief Provide the OOB data sent/received out of band.
+ *
+ * @note An authentication procedure with OOB selected as an algorithm must be in progress when calling this function.
+ * @note A @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST event with the oobd_req set to 1 must have been received prior to calling this function.
+ *
+ * @events
+ * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_oobd_own The OOB data sent out of band to a peer or NULL if the peer has not received OOB data.
+ * Must correspond to @ref ble_gap_sec_params_t::oob flag in @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST.
+ * @param[in] p_oobd_peer The OOB data received out of band from a peer or NULL if none received.
+ * Must correspond to @ref ble_gap_sec_params_t::oob flag in @ref sd_ble_gap_authenticate in the central role
+ * or @ref sd_ble_gap_sec_params_reply in the peripheral role.
+ *
+ * @retval ::NRF_SUCCESS OOB data accepted.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_LESC_OOB_DATA_SET, uint32_t, sd_ble_gap_lesc_oob_data_set(uint16_t conn_handle, ble_gap_lesc_oob_data_t const *p_oobd_own, ble_gap_lesc_oob_data_t const *p_oobd_peer));
+
+/**@brief Initiate GAP Encryption procedure.
+ *
+ * @details In the central role, this function will initiate the encryption procedure using the encryption information provided.
+ *
+ * @events
+ * @event{@ref BLE_GAP_EVT_CONN_SEC_UPDATE, The connection security has been updated.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_ENC_MSC}
+ * @mmsc{@ref BLE_GAP_MULTILINK_CTRL_PROC_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_SEC_REQ_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_master_id Pointer to a @ref ble_gap_master_id_t master identification structure.
+ * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information structure.
+ *
+ * @retval ::NRF_SUCCESS Successfully initiated authentication procedure.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::BLE_ERROR_INVALID_ROLE Operation is not supported in the Peripheral role.
+ * @retval ::NRF_ERROR_BUSY Procedure already in progress or not allowed at this time, wait for pending procedures to complete and retry.
+ */
+SVCALL(SD_BLE_GAP_ENCRYPT, uint32_t, sd_ble_gap_encrypt(uint16_t conn_handle, ble_gap_master_id_t const *p_master_id, ble_gap_enc_info_t const *p_enc_info));
+
+
+/**@brief Reply with GAP security information.
+ *
+ * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_INFO_REQUEST, calling it at other times will result in @ref NRF_ERROR_INVALID_STATE.
+ * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters.
+ * @note Data signing is not yet supported, and p_sign_info must therefore be NULL.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_ENC_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information structure. May be NULL to signal none is available.
+ * @param[in] p_id_info Pointer to a @ref ble_gap_irk_t identity information structure. May be NULL to signal none is available.
+ * @param[in] p_sign_info Pointer to a @ref ble_gap_sign_info_t signing information structure. May be NULL to signal none is available.
+ *
+ * @retval ::NRF_SUCCESS Successfully accepted security information.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_SEC_INFO_REPLY, uint32_t, sd_ble_gap_sec_info_reply(uint16_t conn_handle, ble_gap_enc_info_t const *p_enc_info, ble_gap_irk_t const *p_id_info, ble_gap_sign_info_t const *p_sign_info));
+
+
+/**@brief Get the current connection security.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[out] p_conn_sec Pointer to a @ref ble_gap_conn_sec_t structure to be filled in.
+ *
+ * @retval ::NRF_SUCCESS Current connection security successfully retrieved.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_CONN_SEC_GET, uint32_t, sd_ble_gap_conn_sec_get(uint16_t conn_handle, ble_gap_conn_sec_t *p_conn_sec));
+
+
+/**@brief Start reporting the received signal strength to the application.
+ *
+ * A new event is reported whenever the RSSI value changes, until @ref sd_ble_gap_rssi_stop is called.
+ *
+ * @events
+ * @event{@ref BLE_GAP_EVT_RSSI_CHANGED, New RSSI data available. How often the event is generated is
+ * dependent on the settings of the <code>threshold_dbm</code>
+ * and <code>skip_count</code> input parameters.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC}
+ * @mmsc{@ref BLE_GAP_RSSI_FILT_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] threshold_dbm Minimum change in dBm before triggering the @ref BLE_GAP_EVT_RSSI_CHANGED event. Events are disabled if threshold_dbm equals @ref BLE_GAP_RSSI_THRESHOLD_INVALID.
+ * @param[in] skip_count Number of RSSI samples with a change of threshold_dbm or more before sending a new @ref BLE_GAP_EVT_RSSI_CHANGED event.
+ *
+ * @retval ::NRF_SUCCESS Successfully activated RSSI reporting.
+ * @retval ::NRF_ERROR_INVALID_STATE Disconnection in progress. Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_RSSI_START, uint32_t, sd_ble_gap_rssi_start(uint16_t conn_handle, uint8_t threshold_dbm, uint8_t skip_count));
+
+
+/**@brief Stop reporting the received signal strength.
+ *
+ * @note An RSSI change detected before the call but not yet received by the application
+ * may be reported after @ref sd_ble_gap_rssi_stop has been called.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC}
+ * @mmsc{@ref BLE_GAP_RSSI_FILT_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ *
+ * @retval ::NRF_SUCCESS Successfully deactivated RSSI reporting.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_RSSI_STOP, uint32_t, sd_ble_gap_rssi_stop(uint16_t conn_handle));
+
+
+/**@brief Get the received signal strength for the last connection event.
+ *
+ * @ref sd_ble_gap_rssi_start must be called to start reporting RSSI before using this function. @ref NRF_ERROR_NOT_FOUND
+ * will be returned until RSSI was sampled for the first time after calling @ref sd_ble_gap_rssi_start.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[out] p_rssi Pointer to the location where the RSSI measurement shall be stored.
+ *
+ * @retval ::NRF_SUCCESS Successfully read the RSSI.
+ * @retval ::NRF_ERROR_NOT_FOUND No sample is available.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE RSSI reporting is not ongoing, or disconnection in progress.
+ */
+SVCALL(SD_BLE_GAP_RSSI_GET, uint32_t, sd_ble_gap_rssi_get(uint16_t conn_handle, int8_t *p_rssi));
+
+
+/**@brief Start scanning (GAP Discovery procedure, Observer Procedure).
+ *
+ * @events
+ * @event{@ref BLE_GAP_EVT_ADV_REPORT, An advertising or scan response packet has been received.}
+ * @event{@ref BLE_GAP_EVT_TIMEOUT, Scanner has timed out.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_SCAN_MSC}
+ * @mmsc{@ref BLE_GAP_WL_SHARE_MSC}
+ * @endmscs
+ *
+ * @param[in] p_scan_params Pointer to scan parameters structure.
+ *
+ * @retval ::NRF_SUCCESS Successfully initiated scanning procedure.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry.
+ * @retval ::NRF_ERROR_RESOURCES Not enough BLE role slots available.
+ * Stop one or more currently active roles (Central, Peripheral or Broadcaster) and try again
+ */
+SVCALL(SD_BLE_GAP_SCAN_START, uint32_t, sd_ble_gap_scan_start(ble_gap_scan_params_t const *p_scan_params));
+
+
+/**@brief Stop scanning (GAP Discovery procedure, Observer Procedure).
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_SCAN_MSC}
+ * @mmsc{@ref BLE_GAP_WL_SHARE_MSC}
+ * @endmscs
+ *
+ * @retval ::NRF_SUCCESS Successfully stopped scanning procedure.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation (most probably not in scanning state).
+ */
+SVCALL(SD_BLE_GAP_SCAN_STOP, uint32_t, sd_ble_gap_scan_stop(void));
+
+
+/**@brief Create a connection (GAP Link Establishment).
+ *
+ * @note If a scanning procedure is currently in progress it will be automatically stopped when calling this function.
+ * The scanning procedure will be stopped even if the function returns an error.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_WL_SHARE_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_CONN_PRIV_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_CONN_MSC}
+ * @endmscs
+ *
+ * @param[in] p_peer_addr Pointer to peer address. If the use_whitelist bit is set in @ref ble_gap_scan_params_t, then this is ignored.
+ * If @ref ble_gap_addr_t::addr_id_peer is set then p_peer_addr must be present in the device identity list
+ * see @ref sd_ble_gap_device_identities_set.
+ * @param[in] p_scan_params Pointer to scan parameters structure.
+ * @param[in] p_conn_params Pointer to desired connection parameters.
+ * @param[in] conn_cfg_tag Tag identifying a configuration set by @ref sd_ble_cfg_set or @ref
+ * BLE_CONN_CFG_TAG_DEFAULT to use the default connection configuration.
+ *
+ * @retval ::NRF_SUCCESS Successfully initiated connection procedure.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid parameter(s) pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * - Invalid parameter(s) in p_scan_params or p_conn_params.
+ * - Use of whitelist requested but whitelist has not been set, see @ref sd_ble_gap_whitelist_set.
+ * - Peer address was not present in the device identity list, see @ref sd_ble_gap_device_identities_set.
+ * @retval ::NRF_ERROR_INVALID_STATE The SoftDevice is in an invalid state to perform this operation. This may be due to an
+ * existing locally initiated connect procedure, which must complete before initiating again.
+ * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid Peer address.
+ * @retval ::NRF_ERROR_CONN_COUNT The limit of available connections has been reached.
+ * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. If another connection is being established
+ * wait for the corresponding @ref BLE_GAP_EVT_CONNECTED event before calling again.
+ * @retval ::NRF_ERROR_RESOURCES Not enough BLE role slots available.
+ * Stop one or more currently active roles (Central, Peripheral or Broadcaster) and try again
+ */
+SVCALL(SD_BLE_GAP_CONNECT, uint32_t, sd_ble_gap_connect(ble_gap_addr_t const *p_peer_addr, ble_gap_scan_params_t const *p_scan_params, ble_gap_conn_params_t const *p_conn_params, uint8_t conn_cfg_tag));
+
+
+/**@brief Cancel a connection establishment.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_CENTRAL_CONN_MSC}
+ * @endmscs
+ *
+ * @retval ::NRF_SUCCESS Successfully canceled an ongoing connection procedure.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ */
+SVCALL(SD_BLE_GAP_CONNECT_CANCEL, uint32_t, sd_ble_gap_connect_cancel(void));
+
+
+/**@brief PHY Update Request
+ *
+ * @details This function is used to request a new PHY configuration for a central or a peripheral connection. It will always generate a
+ * @ref BLE_GAP_EVT_PHY_UPDATE event if successfully executed. If @ref ble_gap_phys_t::tx_phys or @ref ble_gap_phys_t::rx_phys
+ * is 0, then the stack will select PHYs based on the peer requirements on that specific direction. If the peer does not support
+ * the PHY Update procedure, then the resulting @ref BLE_GAP_EVT_PHY_UPDATE event will have a status different from
+ * @ref BLE_HCI_STATUS_CODE_SUCCESS.
+ *
+ * @note The requested PHYs does not have to be within the set of the preferred PHYs.
+ *
+ * @note If the @ref ble_gap_opt_preferred_phys_t have not been configured with @ref BLE_GAP_PHY_CODED, then this call might return
+ * @ref BLE_ERROR_BLOCKED_BY_OTHER_LINKS if there are multiple devices connected.
+ *
+ *
+ * @events
+ * @event{@ref BLE_GAP_EVT_PHY_UPDATE, Result of the PHY Update procedure procedure.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_CENTRAL_PHY_REQUEST}
+ * @mmsc{@ref BLE_GAP_PERIPHERAL_PHY_REQUEST}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle to indicate the connection for which the PHY Update is requested.
+ * @param[in] p_gap_phys Pointer to PHY structure.
+ *
+ * @retval ::NRF_SUCCESS Successfully requested a PHY Update.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Unsupported PHYs supplied to the call.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::BLE_ERROR_BLOCKED_BY_OTHER_LINKS Other connections may block the scheduling of the current link.
+ * @retval ::NRF_ERROR_BUSY Procedure is already in progress or not allowed at this time. Process pending events and wait for the pending procedure to complete and retry.
+ *
+ */
+SVCALL(SD_BLE_GAP_PHY_REQUEST, uint32_t, sd_ble_gap_phy_request(uint16_t conn_handle, ble_gap_phys_t const *p_gap_phys));
+
+/**@brief Initiate or respond to a Data Length Update Procedure.
+ *
+ * @note Only symmetric input parameters for the Data Length Update is supported. Only @ref
+ * BLE_GAP_DATA_LENGTH_AUTO for max_tx_time_us and max_rx_time_us is supported.
+ *
+ * @note If the application uses @ref BLE_GAP_DATA_LENGTH_AUTO for one or more members of
+ * p_dl_params, the SoftDevice will choose the highest value supported in current
+ * configuration and connection parameters.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_dl_params Pointer to local parameters to be used in Data Length Update
+ * Procedure. Set any member to @ref BLE_GAP_DATA_LENGTH_AUTO to let
+ * the SoftDevice automatically decide the value for that member.
+ * Set to NULL to use automatic values for all members.
+ * @param[out] p_dl_limitation Pointer to limitation to be written when local device does not
+ * have enough resources to accommodate the requested Data Length
+ * Update parameters. Ignored if NULL.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_DATA_LENGTH_UPDATE_PROCEDURE_MSC}
+ * @endmscs
+ *
+ * @retval ::NRF_SUCCESS Successfully set Data Length Extension initiation/response parameters.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameters supplied.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED The requested parameters are not supported by the SoftDevice.
+ * @retval ::NRF_ERROR_RESOURCES The requested parameters can not be accommodated. Inspect
+ * p_dl_limitation so see where the limitation is.
+ * @retval ::NRF_ERROR_BUSY Peer has already initiated a Data Length Update Procedure. Process the
+ * pending @ref BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST event to respond.
+ */
+SVCALL(SD_BLE_GAP_DATA_LENGTH_UPDATE, uint32_t, sd_ble_gap_data_length_update(uint16_t conn_handle, ble_gap_data_length_params_t const *p_dl_params, ble_gap_data_length_limitation_t *p_dl_limitation));
+
+
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+#endif // BLE_GAP_H__
+
+/**
+ @}
+*/
diff --git a/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_gatt.h b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_gatt.h
new file mode 100644
index 000000000..f6e7ee856
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_gatt.h
@@ -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__
+
+/** @} */
diff --git a/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_gattc.h b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_gattc.h
new file mode 100644
index 000000000..b6a75ece7
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_gattc.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__ */
+
+/**
+ @}
+*/
diff --git a/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_gatts.h b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_gatts.h
new file mode 100644
index 000000000..6bb24831d
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_gatts.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__
+
+/**
+ @}
+*/
diff --git a/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_hci.h b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_hci.h
new file mode 100644
index 000000000..21293e8ef
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_hci.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__
+
+/** @} */
diff --git a/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_l2cap.h b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_l2cap.h
new file mode 100644
index 000000000..90cce565d
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_l2cap.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__
+
+/**
+ @}
+*/
diff --git a/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_ranges.h b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_ranges.h
new file mode 100644
index 000000000..f9c6af76b
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_ranges.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__ */
+
+/**
+ @}
+ @}
+*/
diff --git a/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_types.h b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_types.h
new file mode 100644
index 000000000..e24be0b57
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/ble_types.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__ */
+
+/**
+ @}
+ @}
+*/
diff --git a/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf52/nrf_mbr.h b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf52/nrf_mbr.h
new file mode 100644
index 000000000..ccbe96bd5
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf52/nrf_mbr.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__
+
+/**
+ @}
+*/
diff --git a/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf_error.h b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf_error.h
new file mode 100644
index 000000000..43c091630
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf_error.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__
+
+/**
+ @}
+*/
diff --git a/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf_error_sdm.h b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf_error_sdm.h
new file mode 100644
index 000000000..103659a91
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf_error_sdm.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__
+
+/**
+ @}
+ @}
+*/
diff --git a/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf_error_soc.h b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf_error_soc.h
new file mode 100644
index 000000000..e31d8c9c9
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf_error_soc.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__
+/**
+ @}
+ @}
+*/
diff --git a/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf_nvic.h b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf_nvic.h
new file mode 100644
index 000000000..f4e380807
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf_nvic.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__
+
+/**@} */
diff --git a/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf_sd_def.h b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf_sd_def.h
new file mode 100644
index 000000000..0b4d221d6
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf_sd_def.h
@@ -0,0 +1,59 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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_SD_DEF_H__
+#define NRF_SD_DEF_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SD_PPI_CHANNELS_USED 0xFFFE0000uL /**< PPI channels utilized by SotfDevice (not available to the application). */
+#define SD_PPI_GROUPS_USED 0x0000000CuL /**< PPI groups utilized by SoftDevice (not available to the application). */
+#define SD_TIMERS_USED 0x00000001uL /**< Timers used by SoftDevice. */
+#define SD_SWI_USED 0x0000003CuL /**< Software interrupts used by SoftDevice */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_SD_DEF_H__ */
diff --git a/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf_sdm.h b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf_sdm.h
new file mode 100644
index 000000000..57ffe1335
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf_sdm.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__
+
+/**
+ @}
+*/
diff --git a/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf_soc.h b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf_soc.h
new file mode 100644
index 000000000..875f9bb63
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf_soc.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__
+
+/**@} */
diff --git a/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf_svc.h b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf_svc.h
new file mode 100644
index 000000000..31ea67152
--- /dev/null
+++ b/hw/mcu/nordic/nrf52/sdk/softdevice/s140/headers/nrf_svc.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__
diff --git a/hw/mcu/nordic/nrf52/tusb_port/hal_nrf52.c b/hw/mcu/nordic/nrf52/tusb_port/hal_nrf52.c
index 62bf9e77e..995514773 100644
--- a/hw/mcu/nordic/nrf52/tusb_port/hal_nrf52.c
+++ b/hw/mcu/nordic/nrf52/tusb_port/hal_nrf52.c
@@ -37,8 +37,7 @@
#include <stdbool.h>
#include "nrf.h"
#include "nrf_gpio.h"
-#include "nrf_drv_systick.h"
-#include "nrf_drv_clock.h"
+#include "nrf_clock.h"
#include "tusb_hal.h"