aboutsummaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
authorJamie McCrae <jamie.mccrae@lairdconnect.com>2021-04-06 10:47:12 +0100
committerDavid Hu <david.hu@arm.com>2021-04-29 10:58:19 +0200
commit13ff4571b1cbe21ef483f7cc4b7e0281dbbcda05 (patch)
tree93c6cf990538cc0cb771f0e97ed1b4c59ce0cb2f /platform
parent49a558c40931a4ee873a98c0dfbf53cf8947cfbb (diff)
downloadtrusted-firmware-m-13ff4571b1cbe21ef483f7cc4b7e0281dbbcda05.tar.gz
Platform: Add support for BL5340 DVK
This adds supports for the Laird Connectivity BL5340 DVK (development kit) application core, which is based on the nRF5340 SoC. Signed-off-by: Jamie McCrae <jamie.mccrae@lairdconnect.com> Change-Id: I062412918d4cbe692748c1a31fef444190f50661
Diffstat (limited to 'platform')
-rw-r--r--platform/ext/index.rst7
-rw-r--r--platform/ext/target/lairdconnectivity/bl5340_dvk_cpuapp/CMakeLists.txt45
-rw-r--r--platform/ext/target/lairdconnectivity/bl5340_dvk_cpuapp/README.rst179
-rw-r--r--platform/ext/target/lairdconnectivity/bl5340_dvk_cpuapp/RTE_Device.h119
-rw-r--r--platform/ext/target/lairdconnectivity/bl5340_dvk_cpuapp/config.cmake11
-rw-r--r--platform/ext/target/lairdconnectivity/bl5340_dvk_cpuapp/lcz_board.h38
-rw-r--r--platform/ext/target/lairdconnectivity/bl5340_dvk_cpuapp/preload.cmake11
-rw-r--r--platform/ext/target/lairdconnectivity/common/bl5340/CMakeLists.txt93
-rw-r--r--platform/ext/target/lairdconnectivity/common/bl5340/config.cmake13
-rw-r--r--platform/ext/target/lairdconnectivity/common/bl5340/device_cfg.h30
-rw-r--r--platform/ext/target/lairdconnectivity/common/bl5340/partition/flash_layout.h271
-rw-r--r--platform/ext/target/lairdconnectivity/common/bl5340/partition/region_defs.h167
-rw-r--r--platform/ext/target/lairdconnectivity/common/bl5340/preload.cmake18
-rw-r--r--platform/ext/target/lairdconnectivity/common/bl5340/target_cfg.c291
-rw-r--r--platform/ext/target/lairdconnectivity/common/bl5340/target_cfg.h137
-rw-r--r--platform/ext/target/lairdconnectivity/common/bl5340/tfm_peripherals_def.h48
-rw-r--r--platform/ext/target/lairdconnectivity/common/core/CMakeLists.txt123
-rw-r--r--platform/ext/target/lairdconnectivity/common/core/boot_hal.c99
-rw-r--r--platform/ext/target/lairdconnectivity/common/core/cmsis.h37
-rw-r--r--platform/ext/target/lairdconnectivity/common/core/cmsis_drivers/Driver_Flash.c177
-rw-r--r--platform/ext/target/lairdconnectivity/common/core/cmsis_drivers/Driver_QSPI.c266
-rw-r--r--platform/ext/target/lairdconnectivity/common/core/cmsis_drivers/Driver_USART.c386
-rw-r--r--platform/ext/target/lairdconnectivity/common/core/nrfx_config.h87
-rw-r--r--platform/ext/target/lairdconnectivity/common/core/nrfx_config_nrf5340_application.h2158
-rw-r--r--platform/ext/target/lairdconnectivity/common/core/nrfx_glue.h272
-rw-r--r--platform/ext/target/lairdconnectivity/common/core/nrfx_log.h135
-rw-r--r--platform/ext/target/lairdconnectivity/common/core/nv_counters.c275
-rw-r--r--platform/ext/target/lairdconnectivity/common/core/plat_test.c369
-rw-r--r--platform/ext/target/nordic_nrf/common/core/gcc/nordic_nrf_s.ld4
-rw-r--r--platform/ext/target/nordic_nrf/common/core/nrfx/drivers/include/nrfx_qspi.h368
-rw-r--r--platform/ext/target/nordic_nrf/common/core/nrfx/drivers/include/nrfx_twi_twim.h47
-rw-r--r--platform/ext/target/nordic_nrf/common/core/nrfx/drivers/include/nrfx_twim.h384
-rw-r--r--platform/ext/target/nordic_nrf/common/core/nrfx/drivers/src/nrfx_qspi.c452
-rw-r--r--platform/ext/target/nordic_nrf/common/core/nrfx/drivers/src/nrfx_twi_twim.c86
-rw-r--r--platform/ext/target/nordic_nrf/common/core/nrfx/drivers/src/nrfx_twim.c843
-rw-r--r--platform/ext/target/nordic_nrf/common/core/nrfx/hal/nrf_qspi.h966
-rw-r--r--platform/ext/target/nordic_nrf/common/core/nrfx/hal/nrf_twim.h635
37 files changed, 9644 insertions, 3 deletions
diff --git a/platform/ext/index.rst b/platform/ext/index.rst
index 1d12b9a7c..edd2cf63b 100644
--- a/platform/ext/index.rst
+++ b/platform/ext/index.rst
@@ -48,6 +48,13 @@ Supported Platforms
.. toctree::
:maxdepth: 4
+ :caption: Laird Connectivity
+ :glob:
+
+ target/lairdconnectivity/**
+
+.. toctree::
+ :maxdepth: 4
:caption: Nuvoton
:glob:
diff --git a/platform/ext/target/lairdconnectivity/bl5340_dvk_cpuapp/CMakeLists.txt b/platform/ext/target/lairdconnectivity/bl5340_dvk_cpuapp/CMakeLists.txt
new file mode 100644
index 000000000..13b34e79b
--- /dev/null
+++ b/platform/ext/target/lairdconnectivity/bl5340_dvk_cpuapp/CMakeLists.txt
@@ -0,0 +1,45 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020, Nordic Semiconductor ASA.
+# Copyright (c) 2021, Laird Connectivity
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+cmake_policy(SET CMP0076 NEW)
+set(CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR})
+set(NRF_BOARD_SELECTED True)
+# Relative path to core nordic files from scope of the lairdconnectivity/common/core folder
+set(NRF_FOLDER_PATH "../../../nordic_nrf/common/core")
+
+add_subdirectory(../common/bl5340 bl5340)
+
+target_include_directories(platform_region_defs
+ INTERFACE
+ ../common/bl5340/partition
+)
+
+target_sources(platform_s
+ PRIVATE
+ $<$<BOOL:${TFM_PARTITION_PLATFORM}>:${CMAKE_CURRENT_SOURCE_DIR}/services/src/tfm_platform_system.c>
+)
+
+target_include_directories(platform_s
+ PUBLIC
+ .
+ ../common/bl5340/partition
+)
+
+target_include_directories(platform_ns
+ PUBLIC
+ .
+)
+
+if(BL2)
+ target_include_directories(platform_bl2
+ PUBLIC
+ ../common/bl5340/partition
+ PRIVATE
+ .
+ )
+endif()
diff --git a/platform/ext/target/lairdconnectivity/bl5340_dvk_cpuapp/README.rst b/platform/ext/target/lairdconnectivity/bl5340_dvk_cpuapp/README.rst
new file mode 100644
index 000000000..d23de9105
--- /dev/null
+++ b/platform/ext/target/lairdconnectivity/bl5340_dvk_cpuapp/README.rst
@@ -0,0 +1,179 @@
+Laird Connectivity BL5340
+=========================
+
+The BL5340 development kit (DVK, 750-03293) is a single-board development kit
+for the evaluation and development on the Laird Connectivity BL5340 module
+which contains a Nordic Semiconductor nRF5340 System-on-Chip (SoC).
+
+The BL5340 is a module with a dual-core nRF5340 SoC based on the Arm®
+Cortex®-M33 architecture, with:
+
+* a full-featured ARM Cortex-M33F core with DSP instructions, FPU, and
+ ARMv8-M Security Extension, running at up to 128 MHz, referred to as
+ the **Application MCU**
+* a secondary ARM Cortex-M33 core, with a reduced feature set, running at
+ a fixed 64 MHz, referred to as the **Network MCU**.
+
+The BL5340 Application MCU supports the Armv8m Security Extension.
+
+Documentation
+-------------
+
+The following links provide useful information about the BL5340
+
+BL5340 website:
+ https://www.lairdconnect.com/wireless-modules/bluetooth-modules/bluetooth-5-modules/bl5340-series-multi-core-bluetooth-52-802154-nfc-modules
+
+Nordic Semiconductor Infocenter: https://infocenter.nordicsemi.com
+
+Building TF-M on BL5340 Application MCU
+---------------------------------------
+
+To build an S and NS application image for the BL5340 Application MCU run the
+following commands:
+
+.. note::
+
+ On OS X change ``readlink`` to ``greadlink``, available by running
+ ``brew install coreutils``.
+
+.. code:: bash
+
+ $ mkdir build && cd build
+ $ cmake -DTFM_PLATFORM=lairdconnectivity/bl5340_dvk_cpuapp \
+ -DTFM_TOOLCHAIN_FILE=../toolchain_GNUARM.cmake \
+ -G"Unix Makefiles" ../
+ $ make install
+
+.. note::
+
+ Currently, applications can only be built using GCC
+ (GNU ARM Embedded toolchain).
+
+.. note::
+
+ For BL2 (MCUBoot) logging output to be available, the project
+ needs to be built with Debug configuration (CMAKE_BUILD_TYPE=Debug).
+
+Flashing and debugging with on-board Segger J-Link
+--------------------------------------------------
+
+The BL5340 DVK is equipped with a Debug IC (Atmel ATSAM3U2C) which provides the
+following functionality:
+
+* Segger J-Link firmware and desktop tools
+* SWD debug for the BL5340 module
+* USB CDC ACM Serial Port bridged to the second UART peripheral
+* Segger RTT Console
+
+To install the J-Link Software and documentation pack, follow the steps below:
+
+#. Download the appropriate package from the
+`J-Link Software and documentation pack`_ website
+#. Depending on your platform, install the package or run the installer
+#. When connecting a J-Link-enabled board such as a BL5340 DVK, a serial port
+should come up
+
+nRF Command-Line Tools Installation
+***********************************
+
+The nRF Command-line Tools allow you to control your BL5340 module from the
+command line, including resetting it, erasing or programming the flash memory
+and more.
+
+To install them, visit `nRF Command-Line Tools`_ and select your operating
+system.
+
+After installing, make sure that ``nrfjprog`` is somewhere in your executable
+path to be able to invoke it from anywhere.
+
+BL2, S, and NS application images can be flashed into BL5340 separately or may
+be merged together into a single binary.
+
+Flashing the BL5340 DVK
+***********************
+
+To program the flash with a compiled TF-M image (i.e. S, NS or both) after
+having followed the instructions to install the Segger J-Link Software and the
+nRF Command-Line Tools, follow the steps below:
+
+Generate Intel hex files from the output binary (bin) files as follows:
+
+.. code-block:: console
+
+ srec_cat install/outputs/LAIRDCONNECTIVITY/BL5340_DVK_CPUAPP/tfm_s_ns_signed.bin -binary --offset=0x10000 -o install/outputs/LAIRDCONNECTIVITY/BL5340_DVK_CPUAPP/tfm_s_ns_signed.hex -intel
+
+* Connect the micro-USB cable to the BL5340 DVK and to your computer
+* Erase the flash memory in the BL5340 module:
+
+.. code-block:: console
+
+ nrfjprog --eraseall -f nrf53
+
+* Flash the BL2 and the TF-M image binaries from the sample folder of your choice:
+
+.. code-block:: console
+
+ nrfjprog --program <sample folder>/install/outputs/LAIRDCONNECTIVITY/BL5340_DVK_CPUAPP/bl2.hex -f nrf53 --sectorerase
+ nrfjprog --program <sample folder>/install/outputs/LAIRDCONNECTIVITY/BL5340_DVK_CPUAPP/tfm_s_ns_signed.hex -f nrf53 --sectorerase
+
+* Reset and start TF-M:
+
+.. code-block:: console
+
+ nrfjprog --reset -f nrf53
+
+Flashing the BL5340 DVK (Secondary slot in QSPI, with BL2)
+**********************************************************
+
+To program the flash with a compiled TF-M image (i.e. S, NS or both) after
+having followed the instructions to install the Segger J-Link Software and the
+nRF Command-Line Tools to the secondary , follow the steps below:
+
+Generate Intel hex files from the output binary (bin) files as follows:
+
+.. code-block:: console
+
+ srec_cat install/outputs/LAIRDCONNECTIVITY/BL5340_DVK_CPUAPP/tfm_s_ns_signed.bin -binary --offset=0x10000000 -o install/outputs/LAIRDCONNECTIVITY/BL5340_DVK_CPUAPP/tfm_s_ns_signed_qspi.hex -intel
+
+* Connect the micro-USB cable to the BL5340 DVK and to your computer
+* Erase the flash memory in the BL5340 module:
+
+.. code-block:: console
+
+ nrfjprog --eraseall -f nrf53
+
+* Flash the BL2 and the TF-M image binaries from the sample folder of your choice:
+
+.. code-block:: console
+
+ nrfjprog --program <sample folder>/install/outputs/LAIRDCONNECTIVITY/BL5340_DVK_CPUAPP/bl2.hex -f nrf53 --sectorerase
+ nrfjprog --program <sample folder>/install/outputs/LAIRDCONNECTIVITY/BL5340_DVK_CPUAPP/tfm_s_ns_signed.hex -f nrf53 --qspisectorerase
+
+* Reset and start TF-M:
+
+.. code-block:: console
+
+ nrfjprog --reset -f nrf53
+
+
+Secure UART Console on BL5340 DVK
+*********************************
+
+SECURE_UART1 is enabled by default when building TF-M on the BL5340 DVK, so the
+secure firmware console output is available via USART1.
+
+Non-Secure console output is available via USART0.
+
+.. note::
+
+ By default USART0 and USART1 outputs are routed to separate serial ports.
+
+.. _nRF Command-Line Tools: https://www.nordicsemi.com/Software-and-Tools/Development-Tools/nRF-Command-Line-Tools
+
+.. _J-Link Software and documentation pack: https://www.segger.com/jlink-software.html
+
+--------------
+
+*Copyright (c) 2020, Nordic Semiconductor. All rights reserved.*
+*Copyright (c) 2021, Laird Connectivity. All rights reserved.*
diff --git a/platform/ext/target/lairdconnectivity/bl5340_dvk_cpuapp/RTE_Device.h b/platform/ext/target/lairdconnectivity/bl5340_dvk_cpuapp/RTE_Device.h
new file mode 100644
index 000000000..1b2b8b904
--- /dev/null
+++ b/platform/ext/target/lairdconnectivity/bl5340_dvk_cpuapp/RTE_Device.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2019 Arm Limited. All rights reserved.
+ * Copyright (c) 2020 Nordic Semiconductor ASA. All rights reserved.
+ * Copyright (c) 2021 Laird Connectivity. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//-------- <<< Use Configuration Wizard in Context Menu >>> --------------------
+
+#ifndef __RTE_DEVICE_H
+#define __RTE_DEVICE_H
+
+// <e> USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART0]
+// <i> Configuration settings for Driver_USART0 in component ::Drivers:USART
+#define RTE_USART0 1
+// <h> Pin Selection (0xFFFFFFFF means Disconnected)
+// <o> TXD
+#define RTE_USART0_TXD_PIN 20
+// <o> RXD
+#define RTE_USART0_RXD_PIN 22
+// <o> RTS
+#define RTE_USART0_RTS_PIN 19
+// <o> CTS
+#define RTE_USART0_CTS_PIN 21
+// </h> Pin Configuration
+// </e> USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART0]
+
+// <e> USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART1]
+// <i> Configuration settings for Driver_USART1 in component ::Drivers:USART
+#define RTE_USART1 1
+// <h> Pin Selection (0xFFFFFFFF means Disconnected)
+// <o> TXD
+#define RTE_USART1_TXD_PIN 40
+// <o> RXD
+#define RTE_USART1_RXD_PIN 42
+// <o> RTS
+#define RTE_USART1_RTS_PIN 39
+// <o> CTS
+#define RTE_USART1_CTS_PIN 41
+// </h> Pin Configuration
+// </e> USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART1]
+
+// <e> USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART2]
+// <i> Configuration settings for Driver_USART2 in component ::Drivers:USART
+#define RTE_USART2 0
+// <h> Pin Selection (0xFFFFFFFF means Disconnected)
+// <o> TXD
+#define RTE_USART2_TXD_PIN 0xFFFFFFFF
+// <o> RXD
+#define RTE_USART2_RXD_PIN 0xFFFFFFFF
+// <o> RTS
+#define RTE_USART2_RTS_PIN 0xFFFFFFFF
+// <o> CTS
+#define RTE_USART2_CTS_PIN 0xFFFFFFFF
+// </h> Pin Configuration
+// </e> USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART2]
+
+// <e> USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART3]
+// <i> Configuration settings for Driver_USART3 in component ::Drivers:USART
+#define RTE_USART3 0
+// <h> Pin Selection (0xFFFFFFFF means Disconnected)
+// <o> TXD
+#define RTE_USART3_TXD_PIN 0xFFFFFFFF
+// <o> RXD
+#define RTE_USART3_RXD_PIN 0xFFFFFFFF
+// <o> RTS
+#define RTE_USART3_RTS_PIN 0xFFFFFFFF
+// <o> CTS
+#define RTE_USART3_RTS_PIN 0xFFFFFFFF
+// </h> Pin Configuration
+// </e> USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART3]
+
+// <e> TWIM (Two-wire interface master) [Driver_TWIM2]
+// <i> Configuration settings for Driver_TWIM2 in component ::Drivers:TWIM
+#define RTE_TWIM2 1
+// <h> Pin Selection (0xFFFFFFFF means Disconnected)
+// <o> SCL
+#define RTE_TWIM2_SCL_PIN 35
+// <o> SDA
+#define RTE_TWIM2_SDA_PIN 34
+// </h> Pin Configuration
+// </e> TWIM (Two-wire interface master) [Driver_TWIM2]
+
+// <e> QSPI (Quad serial peripheral interface) [Driver_QSPI0]
+// <i> Configuration settings for Driver_QSPI0 in component ::Drivers:QSPI
+#define RTE_QSPI0 1
+// <h> Pin Selection (0xFFFFFFFF means Disconnected)
+// <o> IO0
+#define RTE_QSPI0_IO0_PIN 13
+// <o> IO1
+#define RTE_QSPI0_IO1_PIN 14
+// <o> IO2
+#define RTE_QSPI0_IO2_PIN 15
+// <o> IO3
+#define RTE_QSPI0_IO3_PIN 16
+// <o> SCL
+#define RTE_QSPI0_SCL_PIN 17
+// <o> CSN
+#define RTE_QSPI0_CSN_PIN 18
+// </h> Pin Configuration
+// </e> QSPI (Quad serial peripheral interface) [Driver_QSPI0]
+
+// <e> FLASH (Flash Memory) [Driver_FLASH0]
+// <i> Configuration settings for Driver_FLASH0 in component ::Drivers:FLASH
+#define RTE_FLASH0 1
+// </e> FLASH (Flash Memory) [Driver_FLASH0]
+
+#endif /* __RTE_DEVICE_H */
diff --git a/platform/ext/target/lairdconnectivity/bl5340_dvk_cpuapp/config.cmake b/platform/ext/target/lairdconnectivity/bl5340_dvk_cpuapp/config.cmake
new file mode 100644
index 000000000..7ae3872b2
--- /dev/null
+++ b/platform/ext/target/lairdconnectivity/bl5340_dvk_cpuapp/config.cmake
@@ -0,0 +1,11 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020, Nordic Semiconductor ASA.
+# Copyright (c) 2021, Laird Connectivity
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+set(NRF_PATH platform/ext/target/${TFM_PLATFORM}/..)
+
+include(${NRF_PATH}/common/bl5340/config.cmake)
diff --git a/platform/ext/target/lairdconnectivity/bl5340_dvk_cpuapp/lcz_board.h b/platform/ext/target/lairdconnectivity/bl5340_dvk_cpuapp/lcz_board.h
new file mode 100644
index 000000000..bab20e8be
--- /dev/null
+++ b/platform/ext/target/lairdconnectivity/bl5340_dvk_cpuapp/lcz_board.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2021 Laird Connectivity. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BL5340_BOARD_H__
+#define BL5340_BOARD_H__
+
+#include <hal/nrf_gpio.h>
+
+#define TWI_INSTANCE_NUMBER 2 /* TWI instance number, cannot be 0 or 1 due to UART usage */
+#define TWI_FREQUENCY NRF_TWIM_FREQ_400K /* Speed to operate I2C (TWI) at */
+
+#define PORT_EXPANDER_I2C_ADDRESS (0x70)
+#define PORT_EXPANDER_IO_CONFIG (0x0f) /* IOs 0-3 are input (buttons) and IOs 4-7 are output (LEDs) */
+
+#define PORT_EXPANDER_INTERRUPT_PIN (38UL)
+#define PORT_EXPANDER_INTERRUPT_ACTIVE_LEVEL (0UL)
+#define PORT_EXPANDER_INTERRUPT_PULL (NRF_GPIO_PIN_NOPULL)
+
+#define PORT_EXPANDER_BUTTON1_IO (0x1)
+#define PORT_EXPANDER_BUTTON1_ACTIVE_LEVEL (0x0) /* Corrisponding comparison of above value if button is pressed */
+
+#define PORT_EXPANDER_LED1_IO (0x10)
+#define PORT_EXPANDER_LED1_ACTIVE_LEVEL (0x0) /* Corrisponding comparison of above value if LED is active */
+
+#endif // BL5340_BOARD_H__
diff --git a/platform/ext/target/lairdconnectivity/bl5340_dvk_cpuapp/preload.cmake b/platform/ext/target/lairdconnectivity/bl5340_dvk_cpuapp/preload.cmake
new file mode 100644
index 000000000..9f7c888fd
--- /dev/null
+++ b/platform/ext/target/lairdconnectivity/bl5340_dvk_cpuapp/preload.cmake
@@ -0,0 +1,11 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020, Nordic Semiconductor ASA.
+# Copyright (c) 2021, Laird Connectivity
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+set(NRF_PATH platform/ext/target/${TFM_PLATFORM}/..)
+
+include(${NRF_PATH}/common/bl5340/preload.cmake)
diff --git a/platform/ext/target/lairdconnectivity/common/bl5340/CMakeLists.txt b/platform/ext/target/lairdconnectivity/common/bl5340/CMakeLists.txt
new file mode 100644
index 000000000..e5530c33e
--- /dev/null
+++ b/platform/ext/target/lairdconnectivity/common/bl5340/CMakeLists.txt
@@ -0,0 +1,93 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+# Copyright (c) 2020, Nordic Semiconductor ASA.
+# Copyright (c) 2021, Laird Connectivity.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+cmake_policy(SET CMP0076 NEW)
+set(CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR})
+
+add_subdirectory(../core nrf_common)
+
+#========================= Platform common defs ===============================#
+
+# Specify the location of platform specific build dependencies.
+target_sources(tfm_s
+ PRIVATE
+ $<$<C_COMPILER_ID:GNU>:${CMAKE_CURRENT_SOURCE_DIR}../${NRF_FOLDER_PATH}/../nrf5340/gcc/startup_nrf5340_s.S>
+)
+
+if(NS)
+ target_sources(tfm_ns
+ PRIVATE
+ $<$<C_COMPILER_ID:GNU>:${CMAKE_CURRENT_SOURCE_DIR}../${NRF_FOLDER_PATH}/../nrf5340/gcc/startup_nrf5340_ns.S>
+ )
+endif()
+
+if(BL2)
+ target_sources(bl2
+ PRIVATE
+ $<$<C_COMPILER_ID:GNU>:${CMAKE_CURRENT_SOURCE_DIR}../${NRF_FOLDER_PATH}/../nrf5340/gcc/startup_nrf5340_bl2.S>
+ )
+endif()
+
+#========================= Platform Secure ====================================#
+
+target_include_directories(platform_s
+ PUBLIC
+ .
+)
+
+target_sources(platform_s
+ PRIVATE
+ target_cfg.c
+ ${NRF_FOLDER_PATH}/nrfx/mdk/system_nrf5340_application.c
+)
+
+target_compile_definitions(platform_s
+ PUBLIC
+ NRF5340_XXAA_APPLICATION
+ $<$<BOOL:${TFM_INTERACTIVE_TEST}>:CORE_TEST_INTERACTIVE>
+ $<$<BOOL:${SECURE_QSPI}>:SECURE_QSPI>
+)
+
+#========================= Platform Non-Secure ================================#
+
+target_include_directories(platform_ns
+ PUBLIC
+ .
+)
+
+target_sources(platform_ns
+ PRIVATE
+ ${NRF_FOLDER_PATH}/nrfx/mdk/system_nrf5340_application.c
+)
+
+target_compile_definitions(platform_ns
+ PUBLIC
+ NRF5340_XXAA_APPLICATION
+ NRF_TRUSTZONE_NONSECURE
+ DOMAIN_NS=1
+)
+
+#========================= Platform BL2 =======================================#
+
+if(BL2)
+ target_include_directories(platform_bl2
+ PRIVATE
+ .
+ )
+
+ target_sources(platform_bl2
+ PRIVATE
+ ${NRF_FOLDER_PATH}/nrfx/mdk/system_nrf5340_application.c
+ )
+
+ target_compile_definitions(platform_bl2
+ PUBLIC
+ NRF5340_XXAA_APPLICATION
+ )
+endif()
diff --git a/platform/ext/target/lairdconnectivity/common/bl5340/config.cmake b/platform/ext/target/lairdconnectivity/common/bl5340/config.cmake
new file mode 100644
index 000000000..313092324
--- /dev/null
+++ b/platform/ext/target/lairdconnectivity/common/bl5340/config.cmake
@@ -0,0 +1,13 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020, Nordic Semiconductor ASA.
+# Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+# Copyright (c) 2021, Laird Connectivity.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+set(SECURE_UART1 ON CACHE BOOL "Enable secure UART1")
+set(SECURE_QSPI ON CACHE BOOL "Enable secure QSPI")
+set(ITS_NUM_ASSETS "5" CACHE STRING "The maximum number of assets to be stored in the Internal Trusted Storage area")
+set(MCUBOOT_UPGRADE_STRATEGY "SWAP" CACHE STRING "Enable using scratch flash section for swapping images")
diff --git a/platform/ext/target/lairdconnectivity/common/bl5340/device_cfg.h b/platform/ext/target/lairdconnectivity/common/bl5340/device_cfg.h
new file mode 100644
index 000000000..061931cac
--- /dev/null
+++ b/platform/ext/target/lairdconnectivity/common/bl5340/device_cfg.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016-2019 ARM Limited
+ *
+ * Licensed under the Apache License Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing software
+ * distributed under the License is distributed on an "AS IS" BASIS
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __ARM_LTD_DEVICE_CFG_H__
+#define __ARM_LTD_DEVICE_CFG_H__
+
+/**
+ * \file device_cfg.h
+ * \brief
+ * This is the default device configuration file with all peripherals
+ * defined and configured to be use via the secure and/or non-secure base
+ * address.
+ */
+
+#define DEFAULT_UART_BAUDRATE 115200
+
+#endif /* __ARM_LTD_DEVICE_CFG_H__ */
diff --git a/platform/ext/target/lairdconnectivity/common/bl5340/partition/flash_layout.h b/platform/ext/target/lairdconnectivity/common/bl5340/partition/flash_layout.h
new file mode 100644
index 000000000..4b1cc922d
--- /dev/null
+++ b/platform/ext/target/lairdconnectivity/common/bl5340/partition/flash_layout.h
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2018-2021 Arm Limited. All rights reserved.
+ * Copyright (c) 2020 Nordic Semiconductor ASA. All rights reserved.
+ * Copyright (c) 2021 Laird Connectivity. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __FLASH_LAYOUT_H__
+#define __FLASH_LAYOUT_H__
+
+/* Flash layout on BL5340 Application MCU with BL2:
+ *
+ * Internal flash:
+ * 0x0000_0000 BL2 - MCUBoot (64 KB)
+ * 0x0001_0000 Primary image area (896 KB):
+ * 0x0001_0000 Secure image primary (640 KB)
+ * 0x000B_0000 Non-secure image primary (256 KB)
+ * 0x000f_0000 Protected Storage area (16 KB)
+ * 0x000f_4000 Internal Trusted Storage area (8 KB)
+ * 0x000f_6000 NV counters main area (4 KB)
+ * 0x000f_7000 NV counters backup area (4 KB)
+ * 0x000f_8000 Unused (optional NVS used in Zephyr) (32 KB)
+ * QSPI:
+ * 0x0000_0000 Secondary image area (896 KB):
+ * 0x0000_0000 Secure image secondary (640 KB)
+ * 0x000A_0000 Non-secure image secondary (256 KB)
+ * 0x000e_0000 Scratch (128 KB)
+ * 0x0010_0000 Unused (optional LFS used in Zephyr) (7 MB)
+ *
+ *
+ * Flash layout on BL5340 Application MCU without BL2:
+ *
+ * Internal flash:
+ * 0x0000_0000 Primary image area (960 KB):
+ * 0x0000_0000 Secure image primary (640 KB)
+ * 0x000A_0000 Non-secure image primary (320 KB)
+ * 0x000f_0000 Protected Storage main area (16 KB)
+ * 0x000f_4000 Internal Trusted Storage main area (8 KB)
+ * 0x000f_6000 NV counters main area (4 KB)
+ * 0x000f_7000 NV counters backup area (4 KB)
+ * 0x000f_8000 Unused (optional NVS used in Zephyr) (32 KB)
+ * QSPI:
+ * 0x0000_0000 Unused (1 MB)
+ * 0x0010_0000 Unused (optional LFS used in Zephyr) (7 MB)
+ */
+
+/* This header file is included from linker scatter file as well, where only a
+ * limited C constructs are allowed. Therefore it is not possible to include
+ * here the platform_base_address.h to access flash related defines. To resolve
+ * this some of the values are redefined here with different names, these are
+ * marked with comment.
+ */
+
+/* Size of a Secure and of a Non-secure image */
+#define FLASH_S_PARTITION_SIZE (0xA0000) /* S partition: 640 KB */
+#ifdef BL2
+/* Using BL2 */
+#define FLASH_NS_PARTITION_SIZE (0x40000) /* NS partition: 256 KB */
+#else
+/* Without BL2 */
+#define FLASH_NS_PARTITION_SIZE (0x50000) /* NS partition: 320 KB */
+#endif
+#define FLASH_MAX_PARTITION_SIZE ((FLASH_S_PARTITION_SIZE > \
+ FLASH_NS_PARTITION_SIZE) ? \
+ FLASH_S_PARTITION_SIZE : \
+ FLASH_NS_PARTITION_SIZE)
+
+/* Sector size of the embedded flash hardware (erase/program) */
+#define FLASH_AREA_IMAGE_SECTOR_SIZE (0x1000) /* 4 KB. Flash memory program/erase operations have a page granularity. */
+
+/* FLASH size */
+#define FLASH_TOTAL_SIZE (0x100000) /* 1024 KB */
+
+/* Sector size of QSPI flash chip */
+#define QSPI_FLASH_AREA_IMAGE_SECTOR_SIZE (0x1000) /* 4 KB */
+
+/* Total size of QSPI flash chip */
+#define QSPI_FLASH_TOTAL_SIZE (0x100000) /* 8192 KB = 8 MB */
+
+/* Flash layout info for BL2 bootloader */
+#define FLASH_BASE_ADDRESS (0x00000000)
+
+
+/* Offset and size definitions of the flash partitions that are handled by the
+ * bootloader. The image swapping is done between IMAGE_PRIMARY and
+ * IMAGE_SECONDARY, SCRATCH is used as a temporary storage during image
+ * swapping.
+ */
+#define FLASH_AREA_BL2_OFFSET (0x0)
+#define FLASH_AREA_BL2_SIZE (0x10000) /* 64 KB */
+
+#define FLASH_AREA_SCRATCH_SIZE (0x20000) /* 128 KB */
+
+#if !defined(MCUBOOT_IMAGE_NUMBER) || (MCUBOOT_IMAGE_NUMBER == 1)
+/* Secure + Non-secure image primary slot (internal flash) */
+#define FLASH_AREA_0_ID (1)
+#define FLASH_AREA_0_OFFSET (FLASH_AREA_BL2_OFFSET + FLASH_AREA_BL2_SIZE)
+#define FLASH_AREA_0_SIZE (FLASH_S_PARTITION_SIZE + \
+ FLASH_NS_PARTITION_SIZE)
+
+/* Secure + Non-secure secondary slot (QSPI) */
+#define FLASH_AREA_2_ID (FLASH_AREA_0_ID + 1)
+#define FLASH_AREA_2_OFFSET (0)
+#define FLASH_AREA_2_SIZE (FLASH_S_PARTITION_SIZE + \
+ FLASH_NS_PARTITION_SIZE)
+
+/* Scratch area (QSPI) */
+#define FLASH_AREA_SCRATCH_ID (FLASH_AREA_2_ID + 1)
+#define FLASH_AREA_SCRATCH_OFFSET (FLASH_AREA_2_OFFSET + FLASH_AREA_2_SIZE)
+
+/* Maximum number of image sectors supported by the bootloader. */
+#define MCUBOOT_MAX_IMG_SECTORS ((FLASH_S_PARTITION_SIZE + \
+ FLASH_NS_PARTITION_SIZE) / \
+ FLASH_AREA_IMAGE_SECTOR_SIZE)
+
+#define MCUBOOT_STATUS_MAX_ENTRIES ((FLASH_S_PARTITION_SIZE + \
+ FLASH_NS_PARTITION_SIZE) / \
+ FLASH_AREA_SCRATCH_SIZE)
+
+#define FLASH_PS_AREA_OFFSET (FLASH_AREA_0_OFFSET + FLASH_AREA_0_SIZE)
+
+#elif (MCUBOOT_IMAGE_NUMBER == 2)
+/* Secure image primary slot */
+#define FLASH_AREA_0_ID (1)
+#define FLASH_AREA_0_OFFSET (FLASH_AREA_BL2_OFFSET + FLASH_AREA_BL2_SIZE)
+#define FLASH_AREA_0_SIZE (FLASH_S_PARTITION_SIZE)
+
+/* Non-secure image primary slot */
+#define FLASH_AREA_1_ID (FLASH_AREA_0_ID + 1)
+#define FLASH_AREA_1_OFFSET (FLASH_AREA_0_OFFSET + FLASH_AREA_0_SIZE)
+#define FLASH_AREA_1_SIZE (FLASH_NS_PARTITION_SIZE)
+
+/* Secure image secondary slot */
+#define FLASH_AREA_2_ID (FLASH_AREA_1_ID + 1)
+#define FLASH_AREA_2_OFFSET (0)
+#define FLASH_AREA_2_SIZE (FLASH_S_PARTITION_SIZE)
+
+/* Non-secure image secondary slot */
+#define FLASH_AREA_3_ID (FLASH_AREA_2_ID + 1)
+#define FLASH_AREA_3_OFFSET (FLASH_AREA_2_OFFSET + FLASH_AREA_2_SIZE)
+#define FLASH_AREA_3_SIZE (FLASH_NS_PARTITION_SIZE)
+
+/* Scratch area (QSPI) */
+#define FLASH_AREA_SCRATCH_ID (FLASH_AREA_3_ID + 1)
+#define FLASH_AREA_SCRATCH_OFFSET (FLASH_AREA_3_OFFSET + FLASH_AREA_3_SIZE)
+
+/* Maximum number of image sectors supported by the bootloader. */
+#define MCUBOOT_STATUS_MAX_ENTRIES (FLASH_MAX_PARTITION_SIZE / \
+ FLASH_AREA_SCRATCH_SIZE)
+
+#define MCUBOOT_MAX_IMG_SECTORS (FLASH_MAX_PARTITION_SIZE / \
+ FLASH_AREA_IMAGE_SECTOR_SIZE)
+
+#define FLASH_PS_AREA_OFFSET (FLASH_AREA_1_OFFSET + FLASH_AREA_1_SIZE)
+#else /* MCUBOOT_IMAGE_NUMBER > 2 */
+#error "Only MCUBOOT_IMAGE_NUMBER 1 and 2 are supported!"
+#endif /* MCUBOOT_IMAGE_NUMBER */
+
+#define FLASH_PS_AREA_SIZE (0x4000) /* 16 KB */
+
+/* Internal Trusted Storage (ITS) Service definitions */
+#define FLASH_ITS_AREA_OFFSET (FLASH_PS_AREA_OFFSET + \
+ FLASH_PS_AREA_SIZE)
+#define FLASH_ITS_AREA_SIZE (0x2000) /* 8 KB */
+
+/* NV Counters definitions */
+#define FLASH_NV_COUNTERS_AREA_OFFSET (FLASH_ITS_AREA_OFFSET + \
+ FLASH_ITS_AREA_SIZE)
+#define FLASH_NV_COUNTERS_AREA_SIZE (FLASH_AREA_IMAGE_SECTOR_SIZE)
+
+/* Offset and size definition in flash area used by assemble.py */
+#define SECURE_IMAGE_OFFSET (0x0)
+#define SECURE_IMAGE_MAX_SIZE FLASH_S_PARTITION_SIZE
+
+#define NON_SECURE_IMAGE_OFFSET (SECURE_IMAGE_OFFSET + \
+ SECURE_IMAGE_MAX_SIZE)
+#define NON_SECURE_IMAGE_MAX_SIZE FLASH_NS_PARTITION_SIZE
+
+/* Flash device name used by BL2
+ * Name is defined in flash driver file: Driver_Flash.c
+ */
+#define FLASH_DEV_NAME Driver_FLASH0
+
+/* Flash device name used by secondary slot and scratch area
+ * Name is defined in flash driver file: Driver_QSPI.c
+ */
+#define FLASH_DEV_NAME_2 Driver_FLASH1
+#define FLASH_DEVICE_ID_2 (FLASH_DEVICE_ID+1)
+#define FLASH_DEV_NAME_3 Driver_FLASH1
+#define FLASH_DEVICE_ID_3 (FLASH_DEVICE_ID+1)
+#define FLASH_DEV_NAME_SCRATCH Driver_FLASH1
+#define FLASH_DEVICE_ID_SCRATCH (FLASH_DEVICE_ID+1)
+
+#define TFM_HAL_ITS_FLASH_DRIVER Driver_FLASH0
+#define TFM_HAL_PS_FLASH_DRIVER Driver_FLASH0
+
+/* Protected Storage (PS) Service definitions
+ * Note: Further documentation of these definitions can be found in the
+ * TF-M PS Integration Guide.
+ */
+#define TFM_HAL_PS_FLASH_DRIVER Driver_FLASH0
+
+/* In this target the CMSIS driver requires only the offset from the base
+ * address instead of the full memory address.
+ */
+/* Base address of dedicated flash area for PS */
+#define TFM_HAL_PS_FLASH_AREA_ADDR FLASH_PS_AREA_OFFSET
+/* Size of dedicated flash area for PS */
+#define TFM_HAL_PS_FLASH_AREA_SIZE FLASH_PS_AREA_SIZE
+#define PS_RAM_FS_SIZE TFM_HAL_PS_FLASH_AREA_SIZE
+/* Number of physical erase sectors per logical FS block */
+#define TFM_HAL_PS_SECTORS_PER_BLOCK (1)
+/* Smallest flash programmable unit in bytes */
+#define TFM_HAL_PS_PROGRAM_UNIT (0x4)
+
+/* Internal Trusted Storage (ITS) Service definitions
+ * Note: Further documentation of these definitions can be found in the
+ * TF-M ITS Integration Guide. The ITS should be in the internal flash, but is
+ * allocated in the external flash just for development platforms that don't
+ * have internal flash available.
+ */
+#define TFM_HAL_ITS_FLASH_DRIVER Driver_FLASH0
+
+/* In this target the CMSIS driver requires only the offset from the base
+ * address instead of the full memory address.
+ */
+/* Base address of dedicated flash area for ITS */
+#define TFM_HAL_ITS_FLASH_AREA_ADDR FLASH_ITS_AREA_OFFSET
+/* Size of dedicated flash area for ITS */
+#define TFM_HAL_ITS_FLASH_AREA_SIZE FLASH_ITS_AREA_SIZE
+#define ITS_RAM_FS_SIZE TFM_HAL_ITS_FLASH_AREA_SIZE
+/* Number of physical erase sectors per logical FS block */
+#define TFM_HAL_ITS_SECTORS_PER_BLOCK (1)
+/* Smallest flash programmable unit in bytes */
+#define TFM_HAL_ITS_PROGRAM_UNIT (0x4)
+
+/* NV Counter definitions */
+#define TFM_NV_COUNTERS_AREA_ADDR FLASH_NV_COUNTERS_AREA_OFFSET
+#define TFM_NV_COUNTERS_AREA_SIZE (0x18) /* 24 Bytes */
+#define TFM_NV_COUNTERS_SECTOR_ADDR FLASH_NV_COUNTERS_AREA_OFFSET
+#define TFM_NV_COUNTERS_SECTOR_SIZE FLASH_AREA_IMAGE_SECTOR_SIZE
+
+/* Backup NV Counter definitions */
+#define TFM_NV_COUNTERS_BACKUP_AREA_ADDR (FLASH_NV_COUNTERS_AREA_OFFSET + FLASH_AREA_IMAGE_SECTOR_SIZE)
+#define TFM_NV_COUNTERS_BACKUP_SECTOR_ADDR (FLASH_NV_COUNTERS_AREA_OFFSET + FLASH_AREA_IMAGE_SECTOR_SIZE)
+
+/* Use Flash memory to store Code data */
+#define FLASH_BASE_ADDRESS (0x00000000)
+#define S_ROM_ALIAS_BASE FLASH_BASE_ADDRESS
+#define NS_ROM_ALIAS_BASE FLASH_BASE_ADDRESS
+
+/* Use SRAM memory to store RW data */
+#define SRAM_BASE_ADDRESS (0x20000000)
+#define S_RAM_ALIAS_BASE SRAM_BASE_ADDRESS
+#define NS_RAM_ALIAS_BASE SRAM_BASE_ADDRESS
+
+#define TOTAL_ROM_SIZE FLASH_TOTAL_SIZE
+#define TOTAL_RAM_SIZE (0x00080000) /* 512 KB */
+
+#endif /* __FLASH_LAYOUT_H__ */
diff --git a/platform/ext/target/lairdconnectivity/common/bl5340/partition/region_defs.h b/platform/ext/target/lairdconnectivity/common/bl5340/partition/region_defs.h
new file mode 100644
index 000000000..58dcc3970
--- /dev/null
+++ b/platform/ext/target/lairdconnectivity/common/bl5340/partition/region_defs.h
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2017-2020 Arm Limited. All rights reserved.
+ * Copyright (c) 2020 Nordic Semiconductor ASA. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __REGION_DEFS_H__
+#define __REGION_DEFS_H__
+
+#include "flash_layout.h"
+
+#define BL2_HEAP_SIZE (0x00001000)
+#define BL2_MSP_STACK_SIZE (0x00001800)
+
+#define S_HEAP_SIZE (0x00001000)
+#define S_MSP_STACK_SIZE_INIT (0x00000400)
+#define S_MSP_STACK_SIZE (0x00000800)
+#define S_PSP_STACK_SIZE (0x00000800)
+
+#define NS_HEAP_SIZE (0x00001000)
+#define NS_MSP_STACK_SIZE (0x000000A0)
+#define NS_PSP_STACK_SIZE (0x00000140)
+
+/* Size of nRF SPU (Nordic IDAU) regions */
+#define SPU_FLASH_REGION_SIZE (0x00004000)
+#define SPU_SRAM_REGION_SIZE (0x00002000)
+
+/* This size of buffer is big enough to store an attestation
+ * token produced by initial attestation service
+ */
+#define PSA_INITIAL_ATTEST_TOKEN_MAX_SIZE (0x250)
+
+/*
+ * SPU flash region granularity is 32 KB on nRF5340. Alignment
+ * of partitions is defined in accordance with this constraint.
+ */
+#ifdef BL2
+#ifndef LINK_TO_SECONDARY_PARTITION
+#define S_IMAGE_PRIMARY_PARTITION_OFFSET (FLASH_AREA_0_OFFSET)
+#define S_IMAGE_SECONDARY_PARTITION_OFFSET (FLASH_AREA_2_OFFSET)
+#else
+#define S_IMAGE_PRIMARY_PARTITION_OFFSET (FLASH_AREA_2_OFFSET)
+#define S_IMAGE_SECONDARY_PARTITION_OFFSET (FLASH_AREA_0_OFFSET)
+#endif /* !LINK_TO_SECONDARY_PARTITION */
+#else
+#define S_IMAGE_PRIMARY_PARTITION_OFFSET (0x0)
+#endif /* BL2 */
+
+#ifndef LINK_TO_SECONDARY_PARTITION
+#define NS_IMAGE_PRIMARY_PARTITION_OFFSET (FLASH_AREA_0_OFFSET \
+ + FLASH_S_PARTITION_SIZE)
+#else
+#define NS_IMAGE_PRIMARY_PARTITION_OFFSET (FLASH_AREA_2_OFFSET \
+ + FLASH_S_PARTITION_SIZE)
+#endif /* !LINK_TO_SECONDARY_PARTITION */
+
+/* Boot partition structure if MCUBoot is used:
+ * 0x0_0000 Bootloader header
+ * 0x0_0400 Image area
+ * 0x0_FC00 Trailer
+ */
+/* IMAGE_CODE_SIZE is the space available for the software binary image.
+ * It is less than the FLASH_S_PARTITION_SIZE + FLASH_NS_PARTITION_SIZE
+ * because we reserve space for the image header and trailer introduced
+ * by the bootloader.
+ */
+#ifdef BL2
+#define BL2_HEADER_SIZE (0x400) /* 1 KB */
+#define BL2_TRAILER_SIZE (0x400) /* 1 KB */
+#else
+/* No header if no bootloader, but keep IMAGE_CODE_SIZE the same */
+#define BL2_HEADER_SIZE (0x0)
+#define BL2_TRAILER_SIZE (0x800)
+#endif /* BL2 */
+
+#define IMAGE_S_CODE_SIZE \
+ (FLASH_S_PARTITION_SIZE - BL2_HEADER_SIZE - BL2_TRAILER_SIZE)
+#define IMAGE_NS_CODE_SIZE \
+ (FLASH_NS_PARTITION_SIZE - BL2_HEADER_SIZE - BL2_TRAILER_SIZE)
+
+/* Alias definitions for secure and non-secure areas*/
+#define S_ROM_ALIAS(x) (S_ROM_ALIAS_BASE + (x))
+#define NS_ROM_ALIAS(x) (NS_ROM_ALIAS_BASE + (x))
+
+#define S_RAM_ALIAS(x) (S_RAM_ALIAS_BASE + (x))
+#define NS_RAM_ALIAS(x) (NS_RAM_ALIAS_BASE + (x))
+
+/* Secure regions */
+#define S_IMAGE_PRIMARY_AREA_OFFSET \
+ (S_IMAGE_PRIMARY_PARTITION_OFFSET + BL2_HEADER_SIZE)
+#define S_CODE_START (S_ROM_ALIAS(S_IMAGE_PRIMARY_AREA_OFFSET))
+#define S_CODE_SIZE (IMAGE_S_CODE_SIZE)
+#define S_CODE_LIMIT (S_CODE_START + S_CODE_SIZE - 1)
+
+#define S_DATA_START (S_RAM_ALIAS(0x0))
+#define S_DATA_SIZE ((TOTAL_RAM_SIZE / 4) * 3)
+#define S_DATA_LIMIT (S_DATA_START + S_DATA_SIZE - 1)
+
+/* The CMSE veneers shall be placed in an NSC region
+ * which will be placed in a secure SPU region with the given alignment.
+ */
+#define CMSE_VENEER_REGION_SIZE (0x400)
+/* The Nordic IDAU has different alignment requirements than the ARM SAU, so
+ * these override the default start and end alignments. */
+#define CMSE_VENEER_REGION_START_ALIGN \
+ (ALIGN(SPU_FLASH_REGION_SIZE) - CMSE_VENEER_REGION_SIZE + \
+ (. > (ALIGN(SPU_FLASH_REGION_SIZE) - CMSE_VENEER_REGION_SIZE) \
+ ? SPU_FLASH_REGION_SIZE : 0))
+#define CMSE_VENEER_REGION_END_ALIGN (ALIGN(SPU_FLASH_REGION_SIZE))
+/* We want the veneers placed in the secure code so it isn't placed at the very
+ * end. When placed in code, we don't need an absolute start address. */
+#define CMSE_VENEER_REGION_IN_CODE
+
+/* Non-secure regions */
+#define NS_IMAGE_PRIMARY_AREA_OFFSET \
+ (NS_IMAGE_PRIMARY_PARTITION_OFFSET + BL2_HEADER_SIZE)
+#define NS_CODE_START (NS_ROM_ALIAS(NS_IMAGE_PRIMARY_AREA_OFFSET))
+#define NS_CODE_SIZE (IMAGE_NS_CODE_SIZE)
+#define NS_CODE_LIMIT (NS_CODE_START + NS_CODE_SIZE - 1)
+
+#define NS_DATA_START (NS_RAM_ALIAS(S_DATA_SIZE))
+#define NS_DATA_SIZE (TOTAL_RAM_SIZE - S_DATA_SIZE)
+#define NS_DATA_LIMIT (NS_DATA_START + NS_DATA_SIZE - 1)
+
+/* NS partition information is used for SPU configuration */
+#define NS_PARTITION_START \
+ (NS_ROM_ALIAS(NS_IMAGE_PRIMARY_PARTITION_OFFSET))
+#define NS_PARTITION_SIZE (FLASH_NS_PARTITION_SIZE)
+
+/* Secondary partition for new images in case of firmware upgrade */
+#define SECONDARY_PARTITION_START \
+ (NS_ROM_ALIAS(S_IMAGE_SECONDARY_PARTITION_OFFSET))
+#define SECONDARY_PARTITION_SIZE (FLASH_S_PARTITION_SIZE + \
+ FLASH_NS_PARTITION_SIZE)
+
+#ifdef BL2
+/* Bootloader regions */
+#define BL2_CODE_START (S_ROM_ALIAS(FLASH_AREA_BL2_OFFSET))
+#define BL2_CODE_SIZE (FLASH_AREA_BL2_SIZE)
+#define BL2_CODE_LIMIT (BL2_CODE_START + BL2_CODE_SIZE - 1)
+
+#define BL2_DATA_START (S_RAM_ALIAS(0x0))
+#define BL2_DATA_SIZE (TOTAL_RAM_SIZE)
+#define BL2_DATA_LIMIT (BL2_DATA_START + BL2_DATA_SIZE - 1)
+#endif /* BL2 */
+
+/* Shared data area between bootloader and runtime firmware.
+ * Shared data area is allocated at the beginning of the RAM, it is overlapping
+ * with TF-M Secure code's MSP stack
+ */
+#define BOOT_TFM_SHARED_DATA_BASE S_RAM_ALIAS_BASE
+#define BOOT_TFM_SHARED_DATA_SIZE (0x400)
+#define BOOT_TFM_SHARED_DATA_LIMIT (BOOT_TFM_SHARED_DATA_BASE + \
+ BOOT_TFM_SHARED_DATA_SIZE - 1)
+
+#endif /* __REGION_DEFS_H__ */
diff --git a/platform/ext/target/lairdconnectivity/common/bl5340/preload.cmake b/platform/ext/target/lairdconnectivity/common/bl5340/preload.cmake
new file mode 100644
index 000000000..362251515
--- /dev/null
+++ b/platform/ext/target/lairdconnectivity/common/bl5340/preload.cmake
@@ -0,0 +1,18 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020, Nordic Semiconductor ASA.
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# preload.cmake is used to set things that related to the platform that are both
+# immutable and global, which is to say they should apply to any kind of project
+# that uses this platform. In practise this is normally compiler definitions and
+# variables related to hardware.
+
+# Set architecture and CPU
+set(TFM_SYSTEM_PROCESSOR cortex-m33)
+set(TFM_SYSTEM_ARCHITECTURE armv8-m.main)
+set(TFM_SYSTEM_DSP OFF)
+set(SECURE_UART1 ON)
diff --git a/platform/ext/target/lairdconnectivity/common/bl5340/target_cfg.c b/platform/ext/target/lairdconnectivity/common/bl5340/target_cfg.c
new file mode 100644
index 000000000..7dd55b598
--- /dev/null
+++ b/platform/ext/target/lairdconnectivity/common/bl5340/target_cfg.c
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 2018-2020 Arm Limited. All rights reserved.
+ * Copyright (c) 2020 Nordic Semiconductor ASA.
+ * Copyright (c) 2021 Laird Connectivity.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "target_cfg.h"
+#include "region_defs.h"
+#include "tfm_plat_defs.h"
+#include "region.h"
+
+#include <spu.h>
+#include <nrfx.h>
+#include <hal/nrf_gpio.h>
+
+#define PIN_XL1 0
+#define PIN_XL2 1
+
+struct platform_data_t tfm_peripheral_timer0 = {
+ NRF_TIMER0_S_BASE,
+ NRF_TIMER0_S_BASE + (sizeof(NRF_TIMER_Type) - 1),
+};
+
+struct platform_data_t tfm_peripheral_std_uart = {
+ NRF_UARTE1_S_BASE,
+ NRF_UARTE1_S_BASE + (sizeof(NRF_UARTE_Type) - 1),
+};
+
+#ifdef CORE_TEST_INTERACTIVE
+struct platform_data_t tfm_peripheral_std_i2c = {
+ NRF_TWIM2_S_BASE,
+ NRF_TWIM2_S_BASE + (sizeof(NRF_TWIM_Type) - 1),
+};
+#endif
+
+#ifdef SECURE_QSPI
+struct platform_data_t tfm_peripheral_std_qspi = {
+ NRF_QSPI_S_BASE,
+ NRF_QSPI_S_BASE + (sizeof(NRF_QSPI_Type) - 1),
+};
+#endif
+
+/* The section names come from the scatter file */
+REGION_DECLARE(Load$$LR$$, LR_NS_PARTITION, $$Base);
+REGION_DECLARE(Load$$LR$$, LR_VENEER, $$Base);
+REGION_DECLARE(Load$$LR$$, LR_VENEER, $$Limit);
+
+const struct memory_region_limits memory_regions = {
+ .non_secure_code_start =
+ (uint32_t)&REGION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base) +
+ BL2_HEADER_SIZE,
+
+ .non_secure_partition_base =
+ (uint32_t)&REGION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base),
+
+ .non_secure_partition_limit =
+ (uint32_t)&REGION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base) +
+ NS_PARTITION_SIZE - 1,
+
+ .veneer_base =
+ (uint32_t)&REGION_NAME(Load$$LR$$, LR_VENEER, $$Base),
+
+ .veneer_limit =
+ (uint32_t)&REGION_NAME(Load$$LR$$, LR_VENEER, $$Limit),
+};
+
+/* To write into AIRCR register, 0x5FA value must be write to the VECTKEY field,
+ * otherwise the processor ignores the write.
+ */
+#define SCB_AIRCR_WRITE_MASK ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos))
+
+enum tfm_plat_err_t enable_fault_handlers(void)
+{
+ /* Explicitly set secure fault priority to the highest */
+ NVIC_SetPriority(SecureFault_IRQn, 0);
+
+ /* Enables BUS, MEM, USG and Secure faults */
+ SCB->SHCSR |= SCB_SHCSR_USGFAULTENA_Msk
+ | SCB_SHCSR_BUSFAULTENA_Msk
+ | SCB_SHCSR_MEMFAULTENA_Msk
+ | SCB_SHCSR_SECUREFAULTENA_Msk;
+ return TFM_PLAT_ERR_SUCCESS;
+}
+
+enum tfm_plat_err_t system_reset_cfg(void)
+{
+ uint32_t reg_value = SCB->AIRCR;
+
+ /* Clear SCB_AIRCR_VECTKEY value */
+ reg_value &= ~(uint32_t)(SCB_AIRCR_VECTKEY_Msk);
+
+ /* Enable system reset request only to the secure world */
+ reg_value |= (uint32_t)(SCB_AIRCR_WRITE_MASK | SCB_AIRCR_SYSRESETREQS_Msk);
+
+ SCB->AIRCR = reg_value;
+
+ return TFM_PLAT_ERR_SUCCESS;
+}
+
+enum tfm_plat_err_t init_debug(void)
+{
+#if defined(DAUTH_NONE)
+ /* Disable debugging */
+ NRF_CTRLAP->APPROTECT.DISABLE = 0;
+ NRF_CTRLAP->SECUREAPPROTECT.DISABLE = 0;
+#elif defined(DAUTH_NS_ONLY)
+ /* Allow debugging Non-Secure only */
+ NRF_CTRLAP->APPROTECT.DISABLE = NRF_UICR->APPROTECT;
+ NRF_CTRLAP->SECUREAPPROTECT.DISABLE = 0;
+#elif defined(DAUTH_FULL) || defined(DAUTH_CHIP_DEFAULT)
+ /* Allow debugging */
+ /* Use the configuration in UICR. */
+ NRF_CTRLAP->APPROTECT.DISABLE = NRF_UICR->APPROTECT;
+ NRF_CTRLAP->SECUREAPPROTECT.DISABLE = NRF_UICR->SECUREAPPROTECT;
+#else
+#error "No debug authentication setting is provided."
+#endif
+ /* Lock access to APPROTECT, SECUREAPPROTECT */
+ NRF_CTRLAP->APPROTECT.LOCK = CTRLAPPERI_APPROTECT_LOCK_LOCK_Locked <<
+ CTRLAPPERI_APPROTECT_LOCK_LOCK_Msk;
+ NRF_CTRLAP->SECUREAPPROTECT.LOCK = CTRLAPPERI_SECUREAPPROTECT_LOCK_LOCK_Locked <<
+ CTRLAPPERI_SECUREAPPROTECT_LOCK_LOCK_Msk;
+
+ return TFM_PLAT_ERR_SUCCESS;
+}
+
+/*----------------- NVIC interrupt target state to NS configuration ----------*/
+enum tfm_plat_err_t nvic_interrupt_target_state_cfg(void)
+{
+ /* Target every interrupt to NS; unimplemented interrupts will be Write-Ignored */
+ for (uint8_t i = 0; i < sizeof(NVIC->ITNS) / sizeof(NVIC->ITNS[0]); i++) {
+ NVIC->ITNS[i] = 0xFFFFFFFF;
+ }
+
+ /* Make sure that the SPU is targeted to S state */
+ NVIC_ClearTargetState(NRFX_IRQ_NUMBER_GET(NRF_SPU));
+
+#ifdef SECURE_UART1
+ /* UARTE1 is a secure peripheral, so its IRQ has to target S state */
+ NVIC_ClearTargetState(NRFX_IRQ_NUMBER_GET(NRF_UARTE1));
+#endif
+
+ NVIC_ClearTargetState(NRFX_IRQ_NUMBER_GET(NRF_TWIM2));
+
+ return TFM_PLAT_ERR_SUCCESS;
+}
+
+/*----------------- NVIC interrupt enabling for S peripherals ----------------*/
+enum tfm_plat_err_t nvic_interrupt_enable(void)
+{
+ /* SPU interrupt enabling */
+ spu_enable_interrupts();
+
+ NVIC_ClearPendingIRQ(NRFX_IRQ_NUMBER_GET(NRF_SPU));
+ NVIC_EnableIRQ(NRFX_IRQ_NUMBER_GET(NRF_SPU));
+
+ return TFM_PLAT_ERR_SUCCESS;
+}
+
+/*------------------- SAU/IDAU configuration functions -----------------------*/
+
+void sau_and_idau_cfg(void)
+{
+ /* IDAU (SPU) is always enabled. SAU is non-existent.
+ * Allow SPU to have precedence over (non-existing) ARMv8-M SAU.
+ */
+ TZ_SAU_Disable();
+ SAU->CTRL |= SAU_CTRL_ALLNS_Msk;
+}
+
+enum tfm_plat_err_t spu_init_cfg(void)
+{
+ /*
+ * Configure SPU Regions for Non-Secure Code and SRAM (Data)
+ * Configure SPU for Peripheral Security
+ * Configure Non-Secure Callable Regions
+ * Configure Secondary Image Partition for BL2
+ */
+
+ /* Explicitly reset Flash and SRAM configuration to all-Secure,
+ * in case this has been overwritten by earlier images e.g.
+ * bootloader.
+ */
+ spu_regions_reset_all_secure();
+
+ /* Configures SPU Code and Data regions to be non-secure */
+ spu_regions_flash_config_non_secure(memory_regions.non_secure_partition_base,
+ memory_regions.non_secure_partition_limit);
+ spu_regions_sram_config_non_secure(NS_DATA_START, NS_DATA_LIMIT);
+
+ /* Configures veneers region to be non-secure callable */
+ spu_regions_flash_config_non_secure_callable(memory_regions.veneer_base,
+ memory_regions.veneer_limit - 1);
+
+ return TFM_PLAT_ERR_SUCCESS;
+}
+
+enum tfm_plat_err_t spu_periph_init_cfg(void)
+{
+ /* Peripheral configuration */
+ spu_peripheral_config_non_secure((uint32_t)NRF_FPU, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_REGULATORS, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_CLOCK, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_SPIM0, false);
+#ifndef SECURE_UART1
+ /* UART1 is a secure peripheral, so we need to leave Serial-Box 1 as Secure */
+ spu_peripheral_config_non_secure((uint32_t)NRF_SPIM1, false);
+#endif
+ spu_peripheral_config_non_secure((uint32_t)NRF_SPIM4, false);
+#ifndef CORE_TEST_INTERACTIVE
+ /* TWIM2 is a secure peripheral for the platform test, so we need to leave it as Secure */
+ spu_peripheral_config_non_secure((uint32_t)NRF_SPIM2, false);
+#endif
+ spu_peripheral_config_non_secure((uint32_t)NRF_SPIM3, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_SAADC, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_TIMER0, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_TIMER1, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_TIMER2, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_RTC0, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_RTC1, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_DPPIC, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_WDT0, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_WDT1, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_COMP, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_EGU0, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_EGU1, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_EGU2, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_EGU3, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_EGU4, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_EGU5, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_PWM0, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_PWM1, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_PWM2, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_PWM3, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_PDM0, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_I2S0, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_IPC, false);
+#ifndef SECURE_QSPI
+ spu_peripheral_config_non_secure((uint32_t)NRF_QSPI, false);
+#endif
+ spu_peripheral_config_non_secure((uint32_t)NRF_NFCT, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_GPIOTE1_NS, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_MUTEX, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_QDEC0, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_QDEC1, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_USBD, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_USBREGULATOR, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_NVMC, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_P0, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_P1, false);
+ spu_peripheral_config_non_secure((uint32_t)NRF_VMC, false);
+
+ /* DPPI channel configuration */
+ spu_dppi_config_non_secure(false);
+
+ /* GPIO pin configuration (P0 and P1 ports) */
+ spu_gpio_config_non_secure(0, false);
+ spu_gpio_config_non_secure(1, false);
+
+ /* Configure properly the XL1 and XL2 pins so that the low-frequency crystal
+ * oscillator (LFXO) can be used.
+ * This configuration can be done only from secure code, as otherwise those
+ * register fields are not accessible. That's why it is placed here.
+ */
+ nrf_gpio_pin_mcu_select(PIN_XL1, NRF_GPIO_PIN_MCUSEL_PERIPHERAL);
+ nrf_gpio_pin_mcu_select(PIN_XL2, NRF_GPIO_PIN_MCUSEL_PERIPHERAL);
+
+ return TFM_PLAT_ERR_SUCCESS;
+}
+
+void spu_periph_configure_to_secure(uint32_t periph_num)
+{
+ spu_peripheral_config_secure(periph_num, true);
+}
+
+void spu_periph_configure_to_non_secure(uint32_t periph_num)
+{
+ spu_peripheral_config_non_secure(periph_num, true);
+}
diff --git a/platform/ext/target/lairdconnectivity/common/bl5340/target_cfg.h b/platform/ext/target/lairdconnectivity/common/bl5340/target_cfg.h
new file mode 100644
index 000000000..d1080b6fa
--- /dev/null
+++ b/platform/ext/target/lairdconnectivity/common/bl5340/target_cfg.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2017-2019 Arm Limited
+ * Copyright (c) 2020 Nordic Semiconductor ASA
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TARGET_CFG_H__
+#define __TARGET_CFG_H__
+
+/**
+ * \file target_cfg.h
+ * \brief nRF5340 target configuration header
+ *
+ * This file contains the platform specific functions to configure
+ * the Cortex-M33 core, memory permissions and security attribution
+ * on the nRF5340 platform.
+ *
+ * Memory permissions and security attribution are configured via
+ * the System Protection Unit (SPU) which is the nRF specific Implementation
+ * Defined Attribution Unit (IDAU).
+ */
+
+#include "tfm_plat_defs.h"
+
+#define TFM_DRIVER_STDIO Driver_USART1
+#define NS_DRIVER_STDIO Driver_USART0
+
+/**
+ * \brief Store the addresses of memory regions
+ */
+struct memory_region_limits {
+ uint32_t non_secure_code_start;
+ uint32_t non_secure_partition_base;
+ uint32_t non_secure_partition_limit;
+ uint32_t veneer_base;
+ uint32_t veneer_limit;
+};
+
+/**
+ * \brief Holds the data necessary to do isolation for a specific peripheral.
+ */
+struct platform_data_t
+{
+ uint32_t periph_start;
+ uint32_t periph_limit;
+};
+
+/**
+ * \brief Configures memory permissions via the System Protection Unit.
+ *
+ * \return Returns values as specified by the \ref tfm_plat_err_t
+ */
+enum tfm_plat_err_t spu_init_cfg(void);
+
+/**
+ * \brief Configures peripheral permissions via the System Protection Unit.
+ *
+ * The function does the following:
+ * - grants Non-Secure access to nRF peripherals that are not Secure-only
+ * - grants Non-Secure access to DDPI channels
+ * - grants Non-Secure access to GPIO pins
+ *
+ * \return Returns values as specified by the \ref tfm_plat_err_t
+ */
+enum tfm_plat_err_t spu_periph_init_cfg(void);
+
+/**
+ * \brief Restrict access to peripheral to secure
+ */
+void spu_periph_configure_to_secure(uint32_t periph_num);
+
+/**
+ * \brief Allow non-secure access to peripheral
+ */
+void spu_periph_configure_to_non_secure(uint32_t periph_num);
+
+/**
+ * \brief Clears SPU interrupt.
+ */
+void spu_clear_irq(void);
+
+/**
+ * \brief Configures SAU and IDAU.
+ */
+void sau_and_idau_cfg(void);
+
+/**
+ * \brief Enables the fault handlers and sets priorities.
+ *
+ * \return Returns values as specified by the \ref tfm_plat_err_t
+ */
+enum tfm_plat_err_t enable_fault_handlers(void);
+
+/**
+ * \brief Configures the system reset request properties
+ *
+ * \return Returns values as specified by the \ref tfm_plat_err_t
+ */
+enum tfm_plat_err_t system_reset_cfg(void);
+
+/**
+ * \brief Configures the system debug properties.
+ *
+ * \return Returns values as specified by the \ref tfm_plat_err_t
+ */
+enum tfm_plat_err_t init_debug(void);
+
+/**
+ * \brief Configures all external interrupts to target the
+ * NS state, apart for the ones associated to secure
+ * peripherals (plus SPU)
+ *
+ * \return Returns values as specified by the \ref tfm_plat_err_t
+ */
+enum tfm_plat_err_t nvic_interrupt_target_state_cfg(void);
+
+/**
+ * \brief This function enable the interrupts associated
+ * to the secure peripherals (plus the isolation boundary violation
+ * interrupts)
+ *
+ * \return Returns values as specified by the \ref tfm_plat_err_t
+ */
+enum tfm_plat_err_t nvic_interrupt_enable(void);
+
+#endif /* __TARGET_CFG_H__ */
diff --git a/platform/ext/target/lairdconnectivity/common/bl5340/tfm_peripherals_def.h b/platform/ext/target/lairdconnectivity/common/bl5340/tfm_peripherals_def.h
new file mode 100644
index 000000000..9c7658ae9
--- /dev/null
+++ b/platform/ext/target/lairdconnectivity/common/bl5340/tfm_peripherals_def.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2020, Cypress Semiconductor Corporation. All rights reserved.
+ * Copyright (c) 2020, Nordic Semiconductor ASA. All rights reserved.
+ * Copyright (c) 2021, Laird Connectivity. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_PERIPHERALS_DEF_H__
+#define __TFM_PERIPHERALS_DEF_H__
+
+#include <nrf.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TFM_TIMER0_IRQ (TIMER0_IRQn)
+#define TFM_TIMER1_IRQ (TIMER1_IRQn)
+
+struct platform_data_t;
+
+extern struct platform_data_t tfm_peripheral_std_uart;
+extern struct platform_data_t tfm_peripheral_timer0;
+#ifdef CORE_TEST_INTERACTIVE
+extern struct platform_data_t tfm_peripheral_std_i2c;
+#endif
+#ifdef SECURE_QSPI
+extern struct platform_data_t tfm_peripheral_std_qspi;
+#endif
+
+#define TFM_PERIPHERAL_STD_UART (&tfm_peripheral_std_uart)
+#define TFM_PERIPHERAL_TIMER0 (&tfm_peripheral_timer0)
+#ifdef CORE_TEST_INTERACTIVE
+#define TFM_PERIPHERAL_STD_I2C (&tfm_peripheral_std_i2c)
+#endif
+#ifdef SECURE_QSPI
+#define TFM_PERIPHERAL_STD_QSPI (&tfm_peripheral_std_qspi)
+#endif
+#define TFM_PERIPHERAL_FPGA_IO (0)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_PERIPHERALS_DEF_H__ */
diff --git a/platform/ext/target/lairdconnectivity/common/core/CMakeLists.txt b/platform/ext/target/lairdconnectivity/common/core/CMakeLists.txt
new file mode 100644
index 000000000..d545ae421
--- /dev/null
+++ b/platform/ext/target/lairdconnectivity/common/core/CMakeLists.txt
@@ -0,0 +1,123 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+# Copyright (c) 2020, Nordic Semiconductor ASA.
+# Copyright (c) 2021, Laird Connectivity.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+cmake_policy(SET CMP0076 NEW)
+set(CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR})
+
+#========================= Platform common defs ===============================#
+
+# Specify the location of platform specific build dependencies.
+
+target_add_scatter_file(tfm_s
+ $<$<C_COMPILER_ID:GNU>:${NRF_FOLDER_PATH}/gcc/nordic_nrf_s.ld>
+)
+
+if(NS)
+ target_add_scatter_file(tfm_ns
+ $<$<C_COMPILER_ID:GNU>:${NRF_FOLDER_PATH}/gcc/nordic_nrf_ns.ld>
+ )
+ target_link_libraries(CMSIS_5_tfm_ns
+ INTERFACE
+ CMSIS_5_RTX_V8MMN
+ )
+endif()
+
+if(BL2)
+ target_add_scatter_file(bl2
+ $<$<C_COMPILER_ID:GNU>:${NRF_FOLDER_PATH}/gcc/nordic_nrf_bl2.ld>
+ )
+endif()
+
+#========================= Platform Secure ====================================#
+
+target_include_directories(platform_s
+ PUBLIC
+ .
+ ${NRF_FOLDER_PATH}/native_drivers
+ ${NRF_FOLDER_PATH}/nrfx
+ ${NRF_FOLDER_PATH}/nrfx/mdk
+ ${NRF_FOLDER_PATH}/nrfx/drivers/include
+ ${PLATFORM_DIR}/..
+)
+
+target_sources(platform_s
+ PRIVATE
+ cmsis_drivers/Driver_Flash.c
+ cmsis_drivers/Driver_QSPI.c
+ cmsis_drivers/Driver_USART.c
+ ${NRF_FOLDER_PATH}/nrfx/drivers/src/nrfx_uarte.c
+ ${NRF_FOLDER_PATH}/nrfx/drivers/src/nrfx_nvmc.c
+ ${NRF_FOLDER_PATH}/nrfx/drivers/src/nrfx_twim.c
+ ${NRF_FOLDER_PATH}/nrfx/drivers/src/nrfx_twi_twim.c
+ ${NRF_FOLDER_PATH}/nrfx/drivers/src/nrfx_qspi.c
+ ${NRF_FOLDER_PATH}/nrfx_glue.c
+ ${NRF_FOLDER_PATH}/native_drivers/mpu_armv8m_drv.c
+ ${NRF_FOLDER_PATH}/native_drivers/spu.c
+ ${NRF_FOLDER_PATH}/spm_hal.c
+ ${NRF_FOLDER_PATH}/tfm_hal_isolation.c
+ nv_counters.c
+ plat_test.c
+)
+
+target_compile_options(platform_s
+ PUBLIC
+ ${COMPILER_CMSE_FLAG}
+)
+
+#========================= Platform Non-Secure ================================#
+
+target_include_directories(platform_ns
+ PUBLIC
+ .
+ ${NRF_FOLDER_PATH}/nrfx
+ ${NRF_FOLDER_PATH}/nrfx/mdk
+ ${NRF_FOLDER_PATH}/nrfx/drivers/include
+ ${PLATFORM_DIR}/..
+ PRIVATE
+ ${PLATFORM_DIR}/../interface/include
+)
+
+target_sources(platform_ns
+ PRIVATE
+ cmsis_drivers/Driver_USART.c
+ ${NRF_FOLDER_PATH}/nrfx/drivers/src/nrfx_uarte.c
+ ${NRF_FOLDER_PATH}/nrfx/drivers/src/nrfx_twim.c
+ ${NRF_FOLDER_PATH}/nrfx/drivers/src/nrfx_twi_twim.c
+ ${NRF_FOLDER_PATH}/nrfx_glue.c
+ plat_test.c
+)
+
+#========================= Platform BL2 =======================================#
+
+if(BL2)
+ target_include_directories(platform_bl2
+ PUBLIC
+ .
+ ${NRF_FOLDER_PATH}/nrfx
+ ${NRF_FOLDER_PATH}/nrfx/mdk
+ ${NRF_FOLDER_PATH}/nrfx/drivers/include
+ PRIVATE
+ ${PLATFORM_DIR}/..
+ )
+
+ target_sources(platform_bl2
+ PRIVATE
+ boot_hal.c
+ cmsis_drivers/Driver_Flash.c
+ cmsis_drivers/Driver_QSPI.c
+ cmsis_drivers/Driver_USART.c
+ ${NRF_FOLDER_PATH}/nrfx/drivers/src/nrfx_uarte.c
+ ${NRF_FOLDER_PATH}/nrfx/drivers/src/nrfx_nvmc.c
+ ${NRF_FOLDER_PATH}/nrfx/drivers/src/nrfx_twim.c
+ ${NRF_FOLDER_PATH}/nrfx/drivers/src/nrfx_twi_twim.c
+ ${NRF_FOLDER_PATH}/nrfx/drivers/src/nrfx_qspi.c
+ ${NRF_FOLDER_PATH}/nrfx_glue.c
+ nv_counters.c
+ )
+endif()
diff --git a/platform/ext/target/lairdconnectivity/common/core/boot_hal.c b/platform/ext/target/lairdconnectivity/common/core/boot_hal.c
new file mode 100644
index 000000000..050581410
--- /dev/null
+++ b/platform/ext/target/lairdconnectivity/common/core/boot_hal.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2021, Laird Connectivity. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "cmsis.h"
+#include "region.h"
+#include "target_cfg.h"
+#include "cmsis.h"
+#include "boot_hal.h"
+#include "Driver_Flash.h"
+#include "flash_layout.h"
+#include "region_defs.h"
+#include "RTE_Device.h"
+
+REGION_DECLARE(Image$$, ER_DATA, $$Base)[];
+REGION_DECLARE(Image$$, ARM_LIB_HEAP, $$ZI$$Limit)[];
+
+#ifdef RTE_FLASH0
+extern ARM_DRIVER_FLASH Driver_FLASH0;
+#endif
+#ifdef RTE_QSPI0
+extern ARM_DRIVER_FLASH Driver_FLASH1;
+#endif
+
+__attribute__((naked)) void boot_clear_bl2_ram_area(void)
+{
+ __ASM volatile(
+ "mov r0, #0 \n"
+ "subs %1, %1, %0 \n"
+ "Loop: \n"
+ "subs %1, #4 \n"
+ "itt ge \n"
+ "strge r0, [%0, %1] \n"
+ "bge Loop \n"
+ "bx lr \n"
+ :
+ : "r" (REGION_NAME(Image$$, ER_DATA, $$Base)),
+ "r" (REGION_NAME(Image$$, ARM_LIB_HEAP, $$ZI$$Limit))
+ : "r0", "memory"
+ );
+}
+
+int32_t boot_platform_init(void)
+{
+ int32_t result;
+
+#ifdef RTE_FLASH0
+ result = Driver_FLASH0.Initialize(NULL);
+ if (result != ARM_DRIVER_OK) {
+ return 1;
+ }
+#endif
+
+#ifdef RTE_QSPI0
+ result = Driver_FLASH1.Initialize(NULL);
+ if (result != ARM_DRIVER_OK) {
+ return 1;
+ }
+#endif
+
+ return 0;
+}
+
+void boot_platform_quit(struct boot_arm_vector_table *vt)
+{
+ /* Clang at O0, stores variables on the stack with SP relative addressing.
+ * When manually set the SP then the place of reset vector is lost.
+ * Static variables are stored in 'data' or 'bss' section, change of SP has
+ * no effect on them.
+ */
+ static struct boot_arm_vector_table *vt_cpy;
+
+ vt_cpy = vt;
+
+#if RTE_FLASH0
+ Driver_FLASH0.Uninitialize();
+#endif
+
+#if RTE_QSPI0
+ Driver_FLASH1.Uninitialize();
+#endif
+
+#if defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__)
+ /* Restore the Main Stack Pointer Limit register's reset value
+ * before passing execution to runtime firmware to make the
+ * bootloader transparent to it.
+ */
+ __set_MSPLIM(0);
+#endif
+ __set_MSP(vt_cpy->msp);
+ __DSB();
+ __ISB();
+
+ boot_jump_to_next_image(vt_cpy->reset);
+}
diff --git a/platform/ext/target/lairdconnectivity/common/core/cmsis.h b/platform/ext/target/lairdconnectivity/common/core/cmsis.h
new file mode 100644
index 000000000..f2ffa435d
--- /dev/null
+++ b/platform/ext/target/lairdconnectivity/common/core/cmsis.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2020, 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 the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __NORDIC_NRF_CMSIS_H__
+#define __NORDIC_NRF_CMSIS_H__
+
+#include <nrf.h>
+
+#endif /*__NORDIC_NRF_CMSIS_H__*/
diff --git a/platform/ext/target/lairdconnectivity/common/core/cmsis_drivers/Driver_Flash.c b/platform/ext/target/lairdconnectivity/common/core/cmsis_drivers/Driver_Flash.c
new file mode 100644
index 000000000..bb492ef6e
--- /dev/null
+++ b/platform/ext/target/lairdconnectivity/common/core/cmsis_drivers/Driver_Flash.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2013-2018 Arm Limited. All rights reserved.
+ * Copyright (c) 2020 Nordic Semiconductor ASA. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <Driver_Flash.h>
+#include <RTE_Device.h>
+#include <flash_layout.h>
+#include <string.h>
+#include <nrfx_nvmc.h>
+
+#ifndef ARG_UNUSED
+#define ARG_UNUSED(arg) (void)arg
+#endif
+
+#define ARM_FLASH_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1, 0)
+
+#if RTE_FLASH0
+
+static const ARM_DRIVER_VERSION DriverVersion = {
+ ARM_FLASH_API_VERSION,
+ ARM_FLASH_DRV_VERSION
+};
+
+static const ARM_FLASH_CAPABILITIES DriverCapabilities = {
+ .event_ready = 0,
+ .data_width = 2, /* 32-bit */
+ .erase_chip = 1
+};
+
+static ARM_FLASH_INFO FlashInfo = {
+ .sector_info = NULL, /* Uniform sector layout */
+ .sector_count = FLASH_TOTAL_SIZE / FLASH_AREA_IMAGE_SECTOR_SIZE,
+ .sector_size = FLASH_AREA_IMAGE_SECTOR_SIZE,
+ .page_size = 4, /* 32-bit word = 4 bytes */
+ .program_unit = 4, /* 32-bit word = 4 bytes */
+ .erased_value = 0xFF
+};
+
+static bool is_range_valid(uint32_t addr, uint32_t cnt)
+{
+ uint32_t start_offset = (addr - FLASH_BASE_ADDRESS);
+
+ if (start_offset > FLASH_TOTAL_SIZE) {
+ return false;
+ }
+
+ if (cnt > (FLASH_TOTAL_SIZE - start_offset)) {
+ return false;
+ }
+
+ return true;
+}
+
+static ARM_DRIVER_VERSION ARM_Flash_GetVersion(void)
+{
+ return DriverVersion;
+}
+
+static ARM_FLASH_CAPABILITIES ARM_Flash_GetCapabilities(void)
+{
+ return DriverCapabilities;
+}
+
+static int32_t ARM_Flash_Initialize(ARM_Flash_SignalEvent_t cb_event)
+{
+ ARG_UNUSED(cb_event);
+
+ return ARM_DRIVER_OK;
+}
+
+static int32_t ARM_Flash_Uninitialize(void)
+{
+ return ARM_DRIVER_OK;
+}
+
+static int32_t ARM_Flash_PowerControl(ARM_POWER_STATE state)
+{
+ switch (state) {
+ case ARM_POWER_FULL:
+ /* Nothing to be done */
+ return ARM_DRIVER_OK;
+
+ case ARM_POWER_OFF:
+ case ARM_POWER_LOW:
+ default:
+ return ARM_DRIVER_ERROR_UNSUPPORTED;
+ }
+}
+
+static int32_t ARM_Flash_ReadData(uint32_t addr, void *data, uint32_t cnt)
+{
+ if (!is_range_valid(addr, cnt)) {
+ return ARM_DRIVER_ERROR_PARAMETER;
+ }
+
+ memcpy(data, (const void *)addr, cnt);
+ return ARM_DRIVER_OK;
+}
+
+static int32_t ARM_Flash_ProgramData(uint32_t addr, const void *data,
+ uint32_t cnt)
+{
+ /* Only aligned writes of full 32-bit words are allowed. */
+ if ((addr % sizeof(uint32_t)) || (cnt % sizeof(uint32_t))) {
+ return ARM_DRIVER_ERROR_PARAMETER;
+ }
+
+ if (!is_range_valid(addr, cnt)) {
+ return ARM_DRIVER_ERROR_PARAMETER;
+ }
+
+ uint32_t word_cnt = cnt / sizeof(uint32_t);
+ nrfx_nvmc_words_write(addr, data, word_cnt);
+
+ return ARM_DRIVER_OK;
+}
+
+static int32_t ARM_Flash_EraseSector(uint32_t addr)
+{
+ nrfx_err_t err_code = nrfx_nvmc_page_erase(addr);
+ if (err_code != NRFX_SUCCESS) {
+ return ARM_DRIVER_ERROR_PARAMETER;
+ }
+
+ return ARM_DRIVER_OK;
+}
+
+static int32_t ARM_Flash_EraseChip(void)
+{
+ nrfx_nvmc_all_erase();
+ return ARM_DRIVER_OK;
+}
+
+static ARM_FLASH_STATUS ARM_Flash_GetStatus(void)
+{
+ ARM_FLASH_STATUS status = {
+ .busy = !nrfx_nvmc_write_done_check()
+ };
+
+ return status;
+}
+
+static ARM_FLASH_INFO * ARM_Flash_GetInfo(void)
+{
+ return &FlashInfo;
+}
+
+ARM_DRIVER_FLASH Driver_FLASH0 = {
+ .GetVersion = ARM_Flash_GetVersion,
+ .GetCapabilities = ARM_Flash_GetCapabilities,
+ .Initialize = ARM_Flash_Initialize,
+ .Uninitialize = ARM_Flash_Uninitialize,
+ .PowerControl = ARM_Flash_PowerControl,
+ .ReadData = ARM_Flash_ReadData,
+ .ProgramData = ARM_Flash_ProgramData,
+ .EraseSector = ARM_Flash_EraseSector,
+ .EraseChip = ARM_Flash_EraseChip,
+ .GetStatus = ARM_Flash_GetStatus,
+ .GetInfo = ARM_Flash_GetInfo
+};
+
+#endif /* RTE_FLASH0 */
diff --git a/platform/ext/target/lairdconnectivity/common/core/cmsis_drivers/Driver_QSPI.c b/platform/ext/target/lairdconnectivity/common/core/cmsis_drivers/Driver_QSPI.c
new file mode 100644
index 000000000..34e78caa6
--- /dev/null
+++ b/platform/ext/target/lairdconnectivity/common/core/cmsis_drivers/Driver_QSPI.c
@@ -0,0 +1,266 @@
+/*
+ * Copyright (c) 2013-2018 Arm Limited. All rights reserved.
+ * Copyright (c) 2021 Laird Connectivity. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <Driver_Flash.h>
+#include <RTE_Device.h>
+#include <flash_layout.h>
+#include <string.h>
+#include <nrfx_qspi.h>
+
+#ifndef ARG_UNUSED
+#define ARG_UNUSED(arg) (void)arg
+#endif
+
+#define ARM_FLASH_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1, 0)
+#define QSPI_MIN_READ_SIZE 4
+#define QSPI_READ_SIZE_ALIGNMENT 4
+
+#if RTE_QSPI0
+
+static const ARM_DRIVER_VERSION DriverVersion = {
+ ARM_FLASH_API_VERSION,
+ ARM_FLASH_DRV_VERSION
+};
+
+static const ARM_FLASH_CAPABILITIES DriverCapabilities = {
+ .event_ready = 0,
+ .data_width = 2, /* 32-bit */
+ .erase_chip = 0
+};
+
+static ARM_FLASH_INFO FlashInfo = {
+ .sector_info = NULL, /* Uniform sector layout */
+ .sector_count = QSPI_FLASH_TOTAL_SIZE / QSPI_FLASH_AREA_IMAGE_SECTOR_SIZE,
+ .sector_size = QSPI_FLASH_AREA_IMAGE_SECTOR_SIZE,
+ .page_size = 256,
+ .program_unit = 4, /* 32-bit word = 4 bytes */
+ .erased_value = 0xFF
+};
+
+static const nrfx_qspi_config_t pQSPIConf = NRFX_QSPI_DEFAULT_CONFIG(RTE_QSPI0_SCL_PIN,
+ RTE_QSPI0_CSN_PIN,
+ RTE_QSPI0_IO0_PIN,
+ RTE_QSPI0_IO1_PIN,
+ RTE_QSPI0_IO2_PIN,
+ RTE_QSPI0_IO3_PIN);
+
+static bool bQSPIInit = false;
+
+static bool is_range_valid(uint32_t addr, uint32_t cnt)
+{
+ if (addr > QSPI_FLASH_TOTAL_SIZE) {
+ return false;
+ }
+
+ if (cnt > (QSPI_FLASH_TOTAL_SIZE - addr)) {
+ return false;
+ }
+
+ return true;
+}
+
+static ARM_DRIVER_VERSION ARM_QSPI_Flash_GetVersion(void)
+{
+ return DriverVersion;
+}
+
+static ARM_FLASH_CAPABILITIES ARM_QSPI_Flash_GetCapabilities(void)
+{
+ return DriverCapabilities;
+}
+
+static int32_t ARM_QSPI_Flash_Initialize(ARM_Flash_SignalEvent_t cb_event)
+{
+ ARG_UNUSED(cb_event);
+
+ if (bQSPIInit == false)
+ {
+ if (nrfx_qspi_init(&pQSPIConf, NULL, NULL) != NRFX_SUCCESS)
+ {
+ return ARM_DRIVER_ERROR_PARAMETER;
+ }
+
+ bQSPIInit = true;
+ }
+
+ return ARM_DRIVER_OK;
+}
+
+static int32_t ARM_QSPI_Flash_Uninitialize(void)
+{
+ if (bQSPIInit == true)
+ {
+ nrfx_qspi_uninit();
+ bQSPIInit = false;
+ }
+
+ return ARM_DRIVER_OK;
+}
+
+static int32_t ARM_QSPI_Flash_PowerControl(ARM_POWER_STATE state)
+{
+ switch (state) {
+ case ARM_POWER_FULL:
+ /* Nothing to be done */
+ return ARM_DRIVER_OK;
+
+ case ARM_POWER_OFF:
+ case ARM_POWER_LOW:
+ default:
+ return ARM_DRIVER_ERROR_UNSUPPORTED;
+ }
+}
+
+static int32_t ARM_QSPI_Flash_ReadData(uint32_t addr, void *data, uint32_t cnt)
+{
+ uint8_t nOrigCnt = 0;
+ uint8_t nExtCnt = 0;
+ __ALIGN(4) uint8_t baTmpRAMBuffer[QSPI_MIN_READ_SIZE];
+
+ /* Workaround for TF-M bug T905 */
+ if (cnt < QSPI_MIN_READ_SIZE)
+ {
+ nOrigCnt = cnt;
+ cnt = QSPI_MIN_READ_SIZE;
+ }
+ else if ((cnt % QSPI_READ_SIZE_ALIGNMENT) != 0)
+ {
+ nExtCnt = cnt & (QSPI_READ_SIZE_ALIGNMENT - 1);
+ cnt = cnt ^ (uint32_t)nExtCnt;
+ }
+
+ if (!is_range_valid(addr, cnt)) {
+ return ARM_DRIVER_ERROR_PARAMETER;
+ }
+
+ if (nOrigCnt == 0)
+ {
+ if (nrfx_qspi_read(data, cnt, addr) != NRFX_SUCCESS)
+ {
+ return ARM_DRIVER_ERROR_PARAMETER;
+ }
+ }
+ else
+ {
+ if (nrfx_qspi_read(baTmpRAMBuffer, QSPI_MIN_READ_SIZE, addr) != NRFX_SUCCESS)
+ {
+ return ARM_DRIVER_ERROR_PARAMETER;
+ }
+ memcpy(data, baTmpRAMBuffer, nOrigCnt);
+ }
+
+ /* Workaround for TF-M bug T905 */
+ if (nExtCnt != 0)
+ {
+ if (nrfx_qspi_read(baTmpRAMBuffer, QSPI_MIN_READ_SIZE, (addr + cnt)) != NRFX_SUCCESS)
+ {
+ return ARM_DRIVER_ERROR_PARAMETER;
+ }
+
+ memcpy(data + cnt, baTmpRAMBuffer, nExtCnt);
+ }
+
+ return ARM_DRIVER_OK;
+}
+
+static int32_t ARM_QSPI_Flash_ProgramData(uint32_t addr, const void *data,
+ uint32_t cnt)
+{
+ uint32_t err;
+
+ /* Only aligned writes of full 32-bit words are allowed. */
+ if ((addr % sizeof(uint32_t)) || (cnt % sizeof(uint32_t))) {
+ return ARM_DRIVER_ERROR_PARAMETER;
+ }
+
+ if (!is_range_valid(addr, cnt)) {
+ return ARM_DRIVER_ERROR_PARAMETER;
+ }
+
+ if (!nrfx_is_in_ram(data))
+ {
+ /* Not in RAM, copy to RAM so it can be written to QSPI */
+ __ALIGN(4) uint8_t baRAMDataBuffer[cnt];
+ memcpy(baRAMDataBuffer, data, cnt);
+ err = nrfx_qspi_write(baRAMDataBuffer, cnt, addr);
+ }
+ else
+ {
+ err = nrfx_qspi_write(data, cnt, addr);
+ }
+
+ if (err != NRFX_SUCCESS)
+ {
+ return ARM_DRIVER_ERROR;
+ }
+
+ return ARM_DRIVER_OK;
+}
+
+static int32_t ARM_QSPI_Flash_EraseSector(uint32_t addr)
+{
+ nrfx_err_t err_code;
+
+ if (!is_range_valid(addr, QSPI_FLASH_AREA_IMAGE_SECTOR_SIZE)) {
+ return ARM_DRIVER_ERROR_PARAMETER;
+ }
+
+ err_code = nrfx_qspi_erase(NRF_QSPI_ERASE_LEN_4KB, addr);
+
+ if (err_code != NRFX_SUCCESS) {
+ return ARM_DRIVER_ERROR;
+ }
+
+ return ARM_DRIVER_OK;
+}
+
+static int32_t ARM_QSPI_Flash_EraseChip(void)
+{
+ return ARM_DRIVER_ERROR_UNSUPPORTED;
+}
+
+static ARM_FLASH_STATUS ARM_QSPI_Flash_GetStatus(void)
+{
+ ARM_FLASH_STATUS status = {
+ .busy = (nrfx_qspi_mem_busy_check() == NRFX_SUCCESS)
+ };
+
+ return status;
+}
+
+static ARM_FLASH_INFO * ARM_QSPI_Flash_GetInfo(void)
+{
+ return &FlashInfo;
+}
+
+ARM_DRIVER_FLASH Driver_FLASH1 = {
+ .GetVersion = ARM_QSPI_Flash_GetVersion,
+ .GetCapabilities = ARM_QSPI_Flash_GetCapabilities,
+ .Initialize = ARM_QSPI_Flash_Initialize,
+ .Uninitialize = ARM_QSPI_Flash_Uninitialize,
+ .PowerControl = ARM_QSPI_Flash_PowerControl,
+ .ReadData = ARM_QSPI_Flash_ReadData,
+ .ProgramData = ARM_QSPI_Flash_ProgramData,
+ .EraseSector = ARM_QSPI_Flash_EraseSector,
+ .EraseChip = ARM_QSPI_Flash_EraseChip,
+ .GetStatus = ARM_QSPI_Flash_GetStatus,
+ .GetInfo = ARM_QSPI_Flash_GetInfo
+};
+
+#endif /* RTE_QSPI0 */
diff --git a/platform/ext/target/lairdconnectivity/common/core/cmsis_drivers/Driver_USART.c b/platform/ext/target/lairdconnectivity/common/core/cmsis_drivers/Driver_USART.c
new file mode 100644
index 000000000..78e3da4d0
--- /dev/null
+++ b/platform/ext/target/lairdconnectivity/common/core/cmsis_drivers/Driver_USART.c
@@ -0,0 +1,386 @@
+/*
+ * Copyright (c) 2013-2019 Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2021 Nordic Semiconductor ASA. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <Driver_USART.h>
+#include <RTE_Device.h>
+#include <nrfx_uarte.h>
+#include <string.h>
+
+#ifndef ARG_UNUSED
+#define ARG_UNUSED(arg) (void)arg
+#endif
+
+#define ARM_USART_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2, 2)
+
+#if RTE_USART0 || RTE_USART1 || RTE_USART2 || RTE_USART3
+
+static const ARM_DRIVER_VERSION DriverVersion = {
+ ARM_USART_API_VERSION,
+ ARM_USART_DRV_VERSION
+};
+
+static const ARM_USART_CAPABILITIES DriverCapabilities = {
+ .asynchronous = 1,
+};
+
+typedef struct {
+ const nrfx_uarte_t uarte;
+ const nrfx_uarte_config_t *initial_config;
+ size_t tx_count;
+ size_t rx_count;
+ nrf_uarte_config_t hal_cfg;
+ nrf_uarte_baudrate_t baudrate;
+ bool initialized;
+} UARTx_Resources;
+
+static ARM_DRIVER_VERSION ARM_USART_GetVersion(void)
+{
+ return DriverVersion;
+}
+
+static ARM_USART_CAPABILITIES ARM_USART_GetCapabilities(void)
+{
+ return DriverCapabilities;
+}
+
+static int32_t ARM_USARTx_Initialize(ARM_USART_SignalEvent_t cb_event,
+ UARTx_Resources *uart_resources)
+{
+ ARG_UNUSED(cb_event);
+
+ nrfx_err_t err_code = nrfx_uarte_init(&uart_resources->uarte,
+ uart_resources->initial_config,
+ NULL);
+ if (err_code != NRFX_SUCCESS) {
+ return ARM_DRIVER_ERROR_BUSY;
+ }
+
+ uart_resources->tx_count = 0;
+ uart_resources->rx_count = 0;
+ uart_resources->hal_cfg = uart_resources->initial_config->hal_cfg;
+ uart_resources->baudrate = uart_resources->initial_config->baudrate;
+
+ uart_resources->initialized = true;
+ return ARM_DRIVER_OK;
+}
+
+static int32_t ARM_USARTx_Uninitialize(UARTx_Resources *uart_resources)
+{
+ nrfx_uarte_uninit(&uart_resources->uarte);
+
+ uart_resources->initialized = false;
+ return ARM_DRIVER_OK;
+}
+
+static int32_t ARM_USARTx_PowerControl(ARM_POWER_STATE state,
+ UARTx_Resources *uart_resources)
+{
+ ARG_UNUSED(uart_resources);
+
+ switch (state) {
+ case ARM_POWER_FULL:
+ /* Nothing to be done */
+ return ARM_DRIVER_OK;
+
+ case ARM_POWER_OFF:
+ case ARM_POWER_LOW:
+ default:
+ return ARM_DRIVER_ERROR_UNSUPPORTED;
+ }
+}
+
+#ifndef MIN
+#define MIN(a,b) (((a) <= (b)) ? (a) : (b));
+#endif
+
+#define SEND_RAM_BUF_SIZE 64
+
+static int32_t ARM_USARTx_Send(const void *data, uint32_t num,
+ UARTx_Resources *uart_resources)
+{
+ if (!uart_resources->initialized) {
+ return ARM_DRIVER_ERROR;
+ }
+
+ /* nrfx_uarte_tx() only supports input data from RAM. */
+ if (!nrfx_is_in_ram(data)) {
+ uint8_t ram_buf[SEND_RAM_BUF_SIZE];
+
+ for (uint32_t offs = 0; offs < num; offs += sizeof(ram_buf)) {
+ uint32_t len = MIN(num - offs, sizeof(ram_buf));
+ memcpy(ram_buf, data + offs, len);
+ int32_t cmsis_err = ARM_USARTx_Send(ram_buf, len, uart_resources);
+ if (cmsis_err != ARM_DRIVER_OK) {
+ return cmsis_err;
+ }
+ }
+ } else {
+ nrfx_err_t err_code = nrfx_uarte_tx(&uart_resources->uarte, data, num);
+ if (err_code == NRFX_ERROR_BUSY) {
+ return ARM_DRIVER_ERROR_BUSY;
+ } else if (err_code != NRFX_SUCCESS) {
+ return ARM_DRIVER_ERROR;
+ }
+
+ uart_resources->tx_count = num;
+ }
+
+ return ARM_DRIVER_OK;
+}
+
+static int32_t ARM_USARTx_Receive(void *data, uint32_t num,
+ UARTx_Resources *uart_resources)
+{
+ if (!uart_resources->initialized) {
+ return ARM_DRIVER_ERROR;
+ }
+
+ nrfx_err_t err_code = nrfx_uarte_rx(&uart_resources->uarte, data, num);
+ if (err_code == NRFX_ERROR_BUSY) {
+ return ARM_DRIVER_ERROR_BUSY;
+ } else if (err_code != NRFX_SUCCESS) {
+ return ARM_DRIVER_ERROR;
+ }
+
+ uart_resources->rx_count = num;
+ return ARM_DRIVER_OK;
+}
+
+static int32_t ARM_USART_Transfer(const void *data_out, void *data_in,
+ uint32_t num)
+{
+ ARG_UNUSED(data_out);
+ ARG_UNUSED(data_in);
+ ARG_UNUSED(num);
+
+ return ARM_DRIVER_ERROR_UNSUPPORTED;
+}
+
+static uint32_t ARM_USARTx_GetTxCount(const UARTx_Resources *uart_resources)
+{
+ return uart_resources->tx_count;
+}
+
+static uint32_t ARM_USARTx_GetRxCount(const UARTx_Resources *uart_resources)
+{
+ return uart_resources->rx_count;
+}
+
+static int32_t ARM_USARTx_Control(uint32_t control, uint32_t arg,
+ UARTx_Resources *uart_resources)
+{
+ if ((control & ARM_USART_CONTROL_Msk) != ARM_USART_MODE_ASYNCHRONOUS) {
+ return ARM_DRIVER_ERROR_UNSUPPORTED;
+ }
+
+ nrf_uarte_baudrate_t baudrate = uart_resources->baudrate;
+ nrf_uarte_config_t hal_cfg = uart_resources->hal_cfg;
+ switch (arg) {
+ case 1200: baudrate = NRF_UARTE_BAUDRATE_1200; break;
+ case 2400: baudrate = NRF_UARTE_BAUDRATE_2400; break;
+ case 4800: baudrate = NRF_UARTE_BAUDRATE_4800; break;
+ case 9600: baudrate = NRF_UARTE_BAUDRATE_9600; break;
+ case 14400: baudrate = NRF_UARTE_BAUDRATE_14400; break;
+ case 19200: baudrate = NRF_UARTE_BAUDRATE_19200; break;
+ case 28800: baudrate = NRF_UARTE_BAUDRATE_28800; break;
+ case 31250: baudrate = NRF_UARTE_BAUDRATE_31250; break;
+ case 38400: baudrate = NRF_UARTE_BAUDRATE_38400; break;
+ case 56000: baudrate = NRF_UARTE_BAUDRATE_56000; break;
+ case 57600: baudrate = NRF_UARTE_BAUDRATE_57600; break;
+ case 76800: baudrate = NRF_UARTE_BAUDRATE_76800; break;
+ case 115200: baudrate = NRF_UARTE_BAUDRATE_115200; break;
+ case 230400: baudrate = NRF_UARTE_BAUDRATE_230400; break;
+ case 250000: baudrate = NRF_UARTE_BAUDRATE_250000; break;
+ case 460800: baudrate = NRF_UARTE_BAUDRATE_460800; break;
+ case 921600: baudrate = NRF_UARTE_BAUDRATE_921600; break;
+ case 1000000: baudrate = NRF_UARTE_BAUDRATE_1000000; break;
+ default:
+ return ARM_USART_ERROR_BAUDRATE;
+ }
+
+ if ((control & ARM_USART_DATA_BITS_Msk) != ARM_USART_DATA_BITS_8) {
+ return ARM_USART_ERROR_DATA_BITS;
+ }
+
+ switch (control & ARM_USART_STOP_BITS_Msk) {
+ case ARM_USART_STOP_BITS_1:
+ hal_cfg.stop = NRF_UARTE_STOP_ONE;
+ break;
+
+ case ARM_USART_STOP_BITS_2:
+ hal_cfg.stop = NRF_UARTE_STOP_TWO;
+ break;
+
+ default:
+ return ARM_USART_ERROR_STOP_BITS;
+ }
+
+ switch (control & ARM_USART_PARITY_Msk) {
+ case ARM_USART_PARITY_NONE:
+ hal_cfg.parity = NRF_UARTE_PARITY_EXCLUDED;
+ break;
+
+#if defined(UARTE_CONFIG_PARITYTYPE_Msk)
+ case ARM_USART_PARITY_EVEN:
+ hal_cfg.parity = NRF_UARTE_PARITY_INCLUDED;
+ hal_cfg.paritytype = NRF_UARTE_PARITYTYPE_EVEN;
+ break;
+
+ case ARM_USART_PARITY_ODD:
+ hal_cfg.parity = NRF_UARTE_PARITY_INCLUDED;
+ hal_cfg.paritytype = NRF_UARTE_PARITYTYPE_ODD;
+ break;
+#else
+ case ARM_USART_PARITY_EVEN:
+ hal_cfg.parity = NRF_UARTE_PARITY_INCLUDED;
+ break;
+#endif
+
+ default:
+ return ARM_USART_ERROR_PARITY;
+ }
+
+ switch (control & ARM_USART_FLOW_CONTROL_Msk) {
+ case ARM_USART_FLOW_CONTROL_NONE:
+ hal_cfg.hwfc = NRF_UARTE_HWFC_DISABLED;
+ break;
+
+ case ARM_USART_FLOW_CONTROL_RTS_CTS:
+ hal_cfg.hwfc = NRF_UARTE_HWFC_ENABLED;
+ break;
+
+ default:
+ return ARM_USART_ERROR_FLOW_CONTROL;
+ }
+
+ uart_resources->baudrate = baudrate;
+ uart_resources->hal_cfg = hal_cfg;
+
+ nrf_uarte_baudrate_set(uart_resources->uarte.p_reg,
+ uart_resources->baudrate);
+ nrf_uarte_configure(uart_resources->uarte.p_reg,
+ &uart_resources->hal_cfg);
+
+ return ARM_DRIVER_OK;
+}
+
+static ARM_USART_STATUS ARM_USART_GetStatus(void)
+{
+ ARM_USART_STATUS status = {0};
+ return status;
+}
+
+static int32_t ARM_USART_SetModemControl(ARM_USART_MODEM_CONTROL control)
+{
+ ARG_UNUSED(control);
+ return ARM_DRIVER_ERROR_UNSUPPORTED;
+}
+
+static ARM_USART_MODEM_STATUS ARM_USART_GetModemStatus(void)
+{
+ ARM_USART_MODEM_STATUS status = {0};
+ return status;
+}
+
+#define DRIVER_USART(idx) \
+ static nrfx_uarte_config_t UART##idx##_initial_config = { \
+ .pseltxd = RTE_USART##idx##_TXD_PIN, \
+ .pselrxd = RTE_USART##idx##_RXD_PIN, \
+ .pselrts = RTE_USART##idx##_RTS_PIN, \
+ .pselcts = RTE_USART##idx##_CTS_PIN, \
+ .baudrate = NRF_UARTE_BAUDRATE_115200, \
+ .interrupt_priority = NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY, \
+ .hal_cfg = { \
+ .hwfc = NRF_UARTE_HWFC_DISABLED, \
+ .parity = NRF_UARTE_PARITY_EXCLUDED, \
+ .stop = NRF_UARTE_STOP_ONE, \
+ }, \
+ }; \
+ static UARTx_Resources UART##idx##_Resources = { \
+ .uarte = NRFX_UARTE_INSTANCE(idx), \
+ .initial_config = &UART##idx##_initial_config, \
+ }; \
+ static int32_t ARM_USART##idx##_Initialize( \
+ ARM_USART_SignalEvent_t cb_event) \
+ { \
+ return ARM_USARTx_Initialize(cb_event, &UART##idx##_Resources); \
+ } \
+ static int32_t ARM_USART##idx##_Uninitialize(void) \
+ { \
+ return ARM_USARTx_Uninitialize(&UART##idx##_Resources); \
+ } \
+ static int32_t ARM_USART##idx##_PowerControl(ARM_POWER_STATE state) \
+ { \
+ return ARM_USARTx_PowerControl(state, &UART##idx##_Resources); \
+ } \
+ static int32_t ARM_USART##idx##_Send(const void *data, uint32_t num) \
+ { \
+ return ARM_USARTx_Send(data, num, &UART##idx##_Resources); \
+ } \
+ static int32_t ARM_USART##idx##_Receive(void *data, uint32_t num) \
+ { \
+ return ARM_USARTx_Receive(data, num, &UART##idx##_Resources); \
+ } \
+ static uint32_t ARM_USART##idx##_GetTxCount(void) \
+ { \
+ return ARM_USARTx_GetTxCount(&UART##idx##_Resources); \
+ } \
+ static uint32_t ARM_USART##idx##_GetRxCount(void) \
+ { \
+ return ARM_USARTx_GetRxCount(&UART##idx##_Resources); \
+ } \
+ static int32_t ARM_USART##idx##_Control(uint32_t control, \
+ uint32_t arg) \
+ { \
+ return ARM_USARTx_Control(control, arg, &UART##idx##_Resources); \
+ } \
+ ARM_DRIVER_USART Driver_USART##idx = { \
+ .GetVersion = ARM_USART_GetVersion, \
+ .GetCapabilities = ARM_USART_GetCapabilities, \
+ .Initialize = ARM_USART##idx##_Initialize, \
+ .Uninitialize = ARM_USART##idx##_Uninitialize, \
+ .PowerControl = ARM_USART##idx##_PowerControl, \
+ .Send = ARM_USART##idx##_Send, \
+ .Receive = ARM_USART##idx##_Receive, \
+ .Transfer = ARM_USART_Transfer, \
+ .GetTxCount = ARM_USART##idx##_GetTxCount, \
+ .GetRxCount = ARM_USART##idx##_GetRxCount, \
+ .Control = ARM_USART##idx##_Control, \
+ .GetStatus = ARM_USART_GetStatus, \
+ .SetModemControl = ARM_USART_SetModemControl, \
+ .GetModemStatus = ARM_USART_GetModemStatus \
+ }
+
+#if RTE_USART0
+DRIVER_USART(0);
+#endif
+
+#if RTE_USART1
+DRIVER_USART(1);
+#endif
+
+#if RTE_USART2
+DRIVER_USART(2);
+#endif
+
+#if RTE_USART3
+DRIVER_USART(3);
+#endif
+
+#endif /* RTE_USART0 || RTE_USART1 || RTE_USART2 || RTE_USART3 */
diff --git a/platform/ext/target/lairdconnectivity/common/core/nrfx_config.h b/platform/ext/target/lairdconnectivity/common/core/nrfx_config.h
new file mode 100644
index 000000000..9b7d2cd10
--- /dev/null
+++ b/platform/ext/target/lairdconnectivity/common/core/nrfx_config.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2019 - 2020, Nordic Semiconductor ASA
+ * Copyright (c) 2021, Laird Connectivity
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef NRFX_CONFIG_H__
+#define NRFX_CONFIG_H__
+
+#include <RTE_Device.h>
+
+#if RTE_FLASH0
+#define NRFX_NVMC_ENABLED 1
+#endif
+
+#if RTE_QSPI0
+#define NRFX_QSPI_ENABLED 1
+#endif
+
+#if RTE_USART0 || RTE_USART1 || RTE_USART2 || RTE_USART3
+#define NRFX_UARTE_ENABLED 1
+#endif
+#if RTE_USART0
+#define NRFX_UARTE0_ENABLED 1
+#endif
+#if RTE_USART1
+#define NRFX_UARTE1_ENABLED 1
+#endif
+#if RTE_USART2
+#define NRFX_UARTE2_ENABLED 1
+#endif
+#if RTE_USART3
+#define NRFX_UARTE3_ENABLED 1
+#endif
+
+#if RTE_TWIM2
+#define NRFX_TWIM_ENABLED 1
+#define NRFX_TWIM2_ENABLED 1
+#endif
+
+/*
+ * For chips with TrustZone support, MDK provides CMSIS-Core peripheral
+ * accessing symbols in two flavors, with secure and non-secure base address
+ * mappings. Their names contain the suffix _S or _NS, respectively.
+ * Because nrfx HALs and drivers require these peripheral accessing symbols
+ * without any suffixes, the following macro is provided that will translate
+ * their names according to the kind of the target that is built.
+ */
+#if defined(NRF_TRUSTZONE_NONSECURE)
+#define NRF_PERIPH(P) P##_NS
+#else
+#define NRF_PERIPH(P) P##_S
+#endif
+
+#if defined(NRF5340_XXAA_APPLICATION)
+ #include <nrfx_config_nrf5340_application.h>
+#else
+ #error "Unknown device."
+#endif
+
+#endif // NRFX_CONFIG_H__
diff --git a/platform/ext/target/lairdconnectivity/common/core/nrfx_config_nrf5340_application.h b/platform/ext/target/lairdconnectivity/common/core/nrfx_config_nrf5340_application.h
new file mode 100644
index 000000000..a48cc7787
--- /dev/null
+++ b/platform/ext/target/lairdconnectivity/common/core/nrfx_config_nrf5340_application.h
@@ -0,0 +1,2158 @@
+/*
+ * Copyright (c) 2019 - 2020, 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 the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef NRFX_CONFIG_NRF5340_APPLICATION_H__
+#define NRFX_CONFIG_NRF5340_APPLICATION_H__
+
+#ifndef NRFX_CONFIG_H__
+#error "This file should not be included directly. Include nrfx_config.h instead."
+#endif
+
+#define NRF_CLOCK NRF_PERIPH(NRF_CLOCK)
+#define NRF_COMP NRF_PERIPH(NRF_COMP)
+#define NRF_CTRLAP NRF_PERIPH(NRF_CTRLAP)
+#define NRF_DCNF NRF_PERIPH(NRF_DCNF)
+#define NRF_DPPIC NRF_PERIPH(NRF_DPPIC)
+#define NRF_EGU0 NRF_PERIPH(NRF_EGU0)
+#define NRF_EGU1 NRF_PERIPH(NRF_EGU1)
+#define NRF_EGU2 NRF_PERIPH(NRF_EGU2)
+#define NRF_EGU3 NRF_PERIPH(NRF_EGU3)
+#define NRF_EGU4 NRF_PERIPH(NRF_EGU4)
+#define NRF_EGU5 NRF_PERIPH(NRF_EGU5)
+#define NRF_FPU NRF_PERIPH(NRF_FPU)
+#define NRF_I2S0 NRF_PERIPH(NRF_I2S0)
+#define NRF_IPC NRF_PERIPH(NRF_IPC)
+#define NRF_KMU NRF_PERIPH(NRF_KMU)
+#define NRF_LPCOMP NRF_PERIPH(NRF_LPCOMP)
+#define NRF_MUTEX NRF_PERIPH(NRF_MUTEX)
+#define NRF_NFCT NRF_PERIPH(NRF_NFCT)
+#define NRF_NVMC NRF_PERIPH(NRF_NVMC)
+#define NRF_OSCILLATORS NRF_PERIPH(NRF_OSCILLATORS)
+#define NRF_P0 NRF_PERIPH(NRF_P0)
+#define NRF_P1 NRF_PERIPH(NRF_P1)
+#define NRF_PDM0 NRF_PERIPH(NRF_PDM0)
+#define NRF_POWER NRF_PERIPH(NRF_POWER)
+#define NRF_PWM0 NRF_PERIPH(NRF_PWM0)
+#define NRF_PWM1 NRF_PERIPH(NRF_PWM1)
+#define NRF_PWM2 NRF_PERIPH(NRF_PWM2)
+#define NRF_PWM3 NRF_PERIPH(NRF_PWM3)
+#define NRF_QDEC0 NRF_PERIPH(NRF_QDEC0)
+#define NRF_QDEC1 NRF_PERIPH(NRF_QDEC1)
+#define NRF_QSPI NRF_PERIPH(NRF_QSPI)
+#define NRF_REGULATORS NRF_PERIPH(NRF_REGULATORS)
+#define NRF_RESET NRF_PERIPH(NRF_RESET)
+#define NRF_RTC0 NRF_PERIPH(NRF_RTC0)
+#define NRF_RTC1 NRF_PERIPH(NRF_RTC1)
+#define NRF_SAADC NRF_PERIPH(NRF_SAADC)
+#define NRF_SPIM0 NRF_PERIPH(NRF_SPIM0)
+#define NRF_SPIM1 NRF_PERIPH(NRF_SPIM1)
+#define NRF_SPIM2 NRF_PERIPH(NRF_SPIM2)
+#define NRF_SPIM3 NRF_PERIPH(NRF_SPIM3)
+#define NRF_SPIM4 NRF_PERIPH(NRF_SPIM4)
+#define NRF_SPIS0 NRF_PERIPH(NRF_SPIS0)
+#define NRF_SPIS1 NRF_PERIPH(NRF_SPIS1)
+#define NRF_SPIS2 NRF_PERIPH(NRF_SPIS2)
+#define NRF_SPIS3 NRF_PERIPH(NRF_SPIS3)
+#define NRF_TIMER0 NRF_PERIPH(NRF_TIMER0)
+#define NRF_TIMER1 NRF_PERIPH(NRF_TIMER1)
+#define NRF_TIMER2 NRF_PERIPH(NRF_TIMER2)
+#define NRF_TWIM0 NRF_PERIPH(NRF_TWIM0)
+#define NRF_TWIM1 NRF_PERIPH(NRF_TWIM1)
+#define NRF_TWIM2 NRF_PERIPH(NRF_TWIM2)
+#define NRF_TWIM3 NRF_PERIPH(NRF_TWIM3)
+#define NRF_TWIS0 NRF_PERIPH(NRF_TWIS0)
+#define NRF_TWIS1 NRF_PERIPH(NRF_TWIS1)
+#define NRF_TWIS2 NRF_PERIPH(NRF_TWIS2)
+#define NRF_TWIS3 NRF_PERIPH(NRF_TWIS3)
+#define NRF_UARTE0 NRF_PERIPH(NRF_UARTE0)
+#define NRF_UARTE1 NRF_PERIPH(NRF_UARTE1)
+#define NRF_UARTE2 NRF_PERIPH(NRF_UARTE2)
+#define NRF_UARTE3 NRF_PERIPH(NRF_UARTE3)
+#define NRF_USBD NRF_PERIPH(NRF_USBD)
+#define NRF_USBREGULATOR NRF_PERIPH(NRF_USBREGULATOR)
+#define NRF_VMC NRF_PERIPH(NRF_VMC)
+#define NRF_WDT0 NRF_PERIPH(NRF_WDT0)
+#define NRF_WDT1 NRF_PERIPH(NRF_WDT1)
+
+/*
+ * The following section provides the name translation for peripherals with
+ * only one type of access available. For these peripherals, you cannot choose
+ * between secure and non-secure mapping.
+ */
+#if defined(NRF_TRUSTZONE_NONSECURE)
+#define NRF_GPIOTE1 NRF_GPIOTE1_NS
+#else
+#define NRF_CACHE NRF_CACHE_S
+#define NRF_CACHEINFO NRF_CACHEINFO_S
+#define NRF_CACHEDATA NRF_CACHEDATA_S
+#define NRF_CRYPTOCELL NRF_CRYPTOCELL_S
+#define NRF_CTI NRF_CTI_S
+#define NRF_FICR NRF_FICR_S
+#define NRF_GPIOTE0 NRF_GPIOTE0_S
+#define NRF_SPU NRF_SPU_S
+#define NRF_TAD NRF_TAD_S
+#define NRF_UICR NRF_UICR_S
+#endif
+
+/* Fixup for the QDEC driver. */
+#define NRF_QDEC NRF_QDEC0
+
+/* Fixup for the GPIOTE driver. */
+#if defined(NRF_TRUSTZONE_NONSECURE)
+#define NRF_GPIOTE NRF_GPIOTE1
+#else
+#define NRF_GPIOTE NRF_GPIOTE0
+#endif
+
+
+// <<< Use Configuration Wizard in Context Menu >>>\n
+
+// <h> nRF_Drivers
+
+// <e> NRFX_CLOCK_ENABLED - nrfx_clock - CLOCK peripheral driver.
+//==========================================================
+#ifndef NRFX_CLOCK_ENABLED
+#define NRFX_CLOCK_ENABLED 0
+#endif
+// <o> NRFX_CLOCK_CONFIG_LF_SRC - LF clock source.
+
+// <0=> ULP
+// <1=> RC
+// <2=> XTAL
+// <3=> Synth
+
+#ifndef NRFX_CLOCK_CONFIG_LF_SRC
+#define NRFX_CLOCK_CONFIG_LF_SRC 2
+#endif
+
+// <q> NRFX_CLOCK_CONFIG_LF_CAL_ENABLED - Enables LF Clock Calibration Support
+
+#ifndef NRFX_CLOCK_CONFIG_LF_CAL_ENABLED
+#define NRFX_CLOCK_CONFIG_LF_CAL_ENABLED 0
+#endif
+
+// <q> NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED - Enables two-stage LFXO start procedure
+
+// <i> If set to a non-zero value, LFRC will be started before LFXO and corresponding
+// <i> event will be generated. It means that CPU will be woken up when LFRC
+// <i> oscillator starts, but user callback will be invoked only after LFXO
+// <i> finally starts.
+
+#ifndef NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED
+#define NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED 0
+#endif
+
+
+// <o> NRFX_CLOCK_CONFIG_HFCLK192M_SRC - HFCLK192M source.
+
+// <0=> HFINT
+// <1=> HFXO
+
+#ifndef NRFX_CLOCK_CONFIG_HFCLK192M_SRC
+#define NRFX_CLOCK_CONFIG_HFCLK192M_SRC 1
+#endif
+
+// <o> NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority.
+
+// <0=> 0 (highest)
+// <1=> 1
+// <2=> 2
+// <3=> 3
+// <4=> 4
+// <5=> 5
+// <6=> 6
+// <7=> 7
+
+#ifndef NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY
+#define NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY 7
+#endif
+
+// <e> NRFX_CLOCK_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_CLOCK_CONFIG_LOG_ENABLED
+#define NRFX_CLOCK_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_CLOCK_CONFIG_LOG_LEVEL - Default severity level.
+
+// <0=> Off
+// <1=> Error
+// <2=> Warning
+// <3=> Info
+// <4=> Debug
+
+#ifndef NRFX_CLOCK_CONFIG_LOG_LEVEL
+#define NRFX_CLOCK_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_CLOCK_CONFIG_INFO_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_CLOCK_CONFIG_INFO_COLOR
+#define NRFX_CLOCK_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_CLOCK_CONFIG_DEBUG_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_CLOCK_CONFIG_DEBUG_COLOR
+#define NRFX_CLOCK_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRFX_COMP_ENABLED - nrfx_comp - COMP peripheral driver
+//==========================================================
+#ifndef NRFX_COMP_ENABLED
+#define NRFX_COMP_ENABLED 0
+#endif
+
+// <o> NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority
+
+// <0=> 0 (highest)
+// <1=> 1
+// <2=> 2
+// <3=> 3
+// <4=> 4
+// <5=> 5
+// <6=> 6
+// <7=> 7
+
+#ifndef NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY
+#define NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY 7
+#endif
+
+// <e> NRFX_COMP_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_COMP_CONFIG_LOG_ENABLED
+#define NRFX_COMP_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_COMP_CONFIG_LOG_LEVEL - Default Severity level
+
+// <0=> Off
+// <1=> Error
+// <2=> Warning
+// <3=> Info
+// <4=> Debug
+
+#ifndef NRFX_COMP_CONFIG_LOG_LEVEL
+#define NRFX_COMP_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_COMP_CONFIG_INFO_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_COMP_CONFIG_INFO_COLOR
+#define NRFX_COMP_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_COMP_CONFIG_DEBUG_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_COMP_CONFIG_DEBUG_COLOR
+#define NRFX_COMP_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRFX_DPPI_ENABLED - nrfx_dppi - DPPI allocator.
+//==========================================================
+#ifndef NRFX_DPPI_ENABLED
+#define NRFX_DPPI_ENABLED 0
+#endif
+// <e> NRFX_DPPI_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_DPPI_CONFIG_LOG_ENABLED
+#define NRFX_DPPI_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_DPPI_CONFIG_LOG_LEVEL - Default severity level.
+
+// <0=> Off
+// <1=> Error
+// <2=> Warning
+// <3=> Info
+// <4=> Debug
+
+#ifndef NRFX_DPPI_CONFIG_LOG_LEVEL
+#define NRFX_DPPI_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_DPPI_CONFIG_INFO_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_DPPI_CONFIG_INFO_COLOR
+#define NRFX_DPPI_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_DPPI_CONFIG_DEBUG_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_DPPI_CONFIG_DEBUG_COLOR
+#define NRFX_DPPI_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRFX_EGU_ENABLED - nrfx_egu - EGU peripheral driver.
+//==========================================================
+#ifndef NRFX_EGU_ENABLED
+#define NRFX_EGU_ENABLED 0
+#endif
+
+// <q> NRFX_EGU0_ENABLED - Enable EGU0 instance.
+
+#ifndef NRFX_EGU0_ENABLED
+#define NRFX_EGU0_ENABLED 0
+#endif
+
+// <q> NRFX_EGU1_ENABLED - Enable EGU1 instance.
+
+#ifndef NRFX_EGU1_ENABLED
+#define NRFX_EGU1_ENABLED 0
+#endif
+
+// <q> NRFX_EGU2_ENABLED - Enable EGU2 instance.
+
+#ifndef NRFX_EGU2_ENABLED
+#define NRFX_EGU2_ENABLED 0
+#endif
+
+// <q> NRFX_EGU3_ENABLED - Enable EGU3 instance.
+
+#ifndef NRFX_EGU3_ENABLED
+#define NRFX_EGU3_ENABLED 0
+#endif
+
+// <q> NRFX_EGU4_ENABLED - Enable EGU4 instance.
+
+#ifndef NRFX_EGU4_ENABLED
+#define NRFX_EGU4_ENABLED 0
+#endif
+
+// <q> NRFX_EGU5_ENABLED - Enable EGU5 instance.
+
+#ifndef NRFX_EGU5_ENABLED
+#define NRFX_EGU5_ENABLED 0
+#endif
+
+// <o> NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority.
+
+// <0=> 0 (highest)
+// <1=> 1
+// <2=> 2
+// <3=> 3
+// <4=> 4
+// <5=> 5
+// <6=> 6
+// <7=> 7
+
+#ifndef NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY
+#define NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY 7
+#endif
+
+// </e>
+
+// <e> NRFX_GPIOTE_ENABLED - nrfx_gpiote - GPIOTE peripheral driver.
+//==========================================================
+#ifndef NRFX_GPIOTE_ENABLED
+#define NRFX_GPIOTE_ENABLED 0
+#endif
+// <o> NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS - Number of lower power input pins.
+#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS
+#define NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 1
+#endif
+
+// <o> NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority.
+
+// <0=> 0 (highest)
+// <1=> 1
+// <2=> 2
+// <3=> 3
+// <4=> 4
+// <5=> 5
+// <6=> 6
+// <7=> 7
+
+#ifndef NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY
+#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY 7
+#endif
+
+// <e> NRFX_GPIOTE_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED
+#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_GPIOTE_CONFIG_LOG_LEVEL - Default severity level.
+
+// <0=> Off
+// <1=> Error
+// <2=> Warning
+// <3=> Info
+// <4=> Debug
+
+#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL
+#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_GPIOTE_CONFIG_INFO_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_GPIOTE_CONFIG_INFO_COLOR
+#define NRFX_GPIOTE_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_GPIOTE_CONFIG_DEBUG_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_GPIOTE_CONFIG_DEBUG_COLOR
+#define NRFX_GPIOTE_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRFX_I2S_ENABLED - nrfx_i2s - I2S peripheral driver.
+//==========================================================
+#ifndef NRFX_I2S_ENABLED
+#define NRFX_I2S_ENABLED 0
+#endif
+
+// <o> NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority.
+
+// <0=> 0 (highest)
+// <1=> 1
+// <2=> 2
+// <3=> 3
+// <4=> 4
+// <5=> 5
+// <6=> 6
+// <7=> 7
+
+#ifndef NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY
+#define NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY 7
+#endif
+
+// <e> NRFX_I2S_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_I2S_CONFIG_LOG_ENABLED
+#define NRFX_I2S_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_I2S_CONFIG_LOG_LEVEL - Default severity level.
+
+// <0=> Off
+// <1=> Error
+// <2=> Warning
+// <3=> Info
+// <4=> Debug
+
+#ifndef NRFX_I2S_CONFIG_LOG_LEVEL
+#define NRFX_I2S_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_I2S_CONFIG_INFO_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_I2S_CONFIG_INFO_COLOR
+#define NRFX_I2S_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_I2S_CONFIG_DEBUG_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_I2S_CONFIG_DEBUG_COLOR
+#define NRFX_I2S_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRFX_IPC_ENABLED - nrfx_ipc - IPC peripheral driver
+//==========================================================
+#ifndef NRFX_IPC_ENABLED
+#define NRFX_IPC_ENABLED 0
+#endif
+
+// </e>
+
+// <e> NRFX_LPCOMP_ENABLED - nrfx_lpcomp - LPCOMP peripheral driver
+//==========================================================
+#ifndef NRFX_LPCOMP_ENABLED
+#define NRFX_LPCOMP_ENABLED 0
+#endif
+
+// <o> NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority
+
+// <0=> 0 (highest)
+// <1=> 1
+// <2=> 2
+// <3=> 3
+// <4=> 4
+// <5=> 5
+// <6=> 6
+// <7=> 7
+
+#ifndef NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY
+#define NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY 7
+#endif
+
+// <e> NRFX_LPCOMP_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_LPCOMP_CONFIG_LOG_ENABLED
+#define NRFX_LPCOMP_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_LPCOMP_CONFIG_LOG_LEVEL - Default Severity level
+
+// <0=> Off
+// <1=> Error
+// <2=> Warning
+// <3=> Info
+// <4=> Debug
+
+#ifndef NRFX_LPCOMP_CONFIG_LOG_LEVEL
+#define NRFX_LPCOMP_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_LPCOMP_CONFIG_INFO_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_LPCOMP_CONFIG_INFO_COLOR
+#define NRFX_LPCOMP_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_LPCOMP_CONFIG_DEBUG_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_LPCOMP_CONFIG_DEBUG_COLOR
+#define NRFX_LPCOMP_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRFX_NFCT_ENABLED - nrfx_nfct - NFCT peripheral driver
+//==========================================================
+#ifndef NRFX_NFCT_ENABLED
+#define NRFX_NFCT_ENABLED 0
+#endif
+// <o> NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority
+
+// <0=> 0 (highest)
+// <1=> 1
+// <2=> 2
+// <3=> 3
+// <4=> 4
+// <5=> 5
+// <6=> 6
+// <7=> 7
+
+#ifndef NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY
+#define NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY 7
+#endif
+
+// <o> NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID - Timer instance used for workarounds in the driver.
+
+// <0=> 0
+// <1=> 1
+// <2=> 2
+
+#ifndef NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID
+#define NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID 2
+#endif
+
+// <e> NRFX_NFCT_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_NFCT_CONFIG_LOG_ENABLED
+#define NRFX_NFCT_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_NFCT_CONFIG_LOG_LEVEL - Default Severity level
+
+// <0=> Off
+// <1=> Error
+// <2=> Warning
+// <3=> Info
+// <4=> Debug
+
+#ifndef NRFX_NFCT_CONFIG_LOG_LEVEL
+#define NRFX_NFCT_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_NFCT_CONFIG_INFO_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_NFCT_CONFIG_INFO_COLOR
+#define NRFX_NFCT_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_NFCT_CONFIG_DEBUG_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_NFCT_CONFIG_DEBUG_COLOR
+#define NRFX_NFCT_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRFX_NVMC_ENABLED - nrfx_nvmc - NVMC peripheral driver
+//==========================================================
+#ifndef NRFX_NVMC_ENABLED
+#define NRFX_NVMC_ENABLED 0
+#endif
+
+// </e>
+
+// <e> NRFX_PDM_ENABLED - nrfx_pdm - PDM peripheral driver.
+//==========================================================
+#ifndef NRFX_PDM_ENABLED
+#define NRFX_PDM_ENABLED 0
+#endif
+
+// <o> NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority.
+
+// <0=> 0 (highest)
+// <1=> 1
+// <2=> 2
+// <3=> 3
+// <4=> 4
+// <5=> 5
+// <6=> 6
+// <7=> 7
+
+#ifndef NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY
+#define NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY 7
+#endif
+
+// <e> NRFX_PDM_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_PDM_CONFIG_LOG_ENABLED
+#define NRFX_PDM_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_PDM_CONFIG_LOG_LEVEL - Default severity level.
+
+// <0=> Off
+// <1=> Error
+// <2=> Warning
+// <3=> Info
+// <4=> Debug
+
+#ifndef NRFX_PDM_CONFIG_LOG_LEVEL
+#define NRFX_PDM_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_PDM_CONFIG_INFO_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_PDM_CONFIG_INFO_COLOR
+#define NRFX_PDM_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_PDM_CONFIG_DEBUG_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_PDM_CONFIG_DEBUG_COLOR
+#define NRFX_PDM_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRFX_POWER_ENABLED - nrfx_power - POWER peripheral driver.
+//==========================================================
+#ifndef NRFX_POWER_ENABLED
+#define NRFX_POWER_ENABLED 0
+#endif
+// <o> NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority.
+
+// <0=> 0 (highest)
+// <1=> 1
+// <2=> 2
+// <3=> 3
+// <4=> 4
+// <5=> 5
+// <6=> 6
+// <7=> 7
+
+#ifndef NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY
+#define NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY 7
+#endif
+
+// </e>
+
+// <e> NRFX_PRS_ENABLED - nrfx_prs - Peripheral Resource Sharing (PRS) module.
+//==========================================================
+#ifndef NRFX_PRS_ENABLED
+#define NRFX_PRS_ENABLED 0
+#endif
+// <q> NRFX_PRS_BOX_0_ENABLED - Enables box 0 in the module.
+
+
+#ifndef NRFX_PRS_BOX_0_ENABLED
+#define NRFX_PRS_BOX_0_ENABLED 0
+#endif
+
+// <q> NRFX_PRS_BOX_1_ENABLED - Enables box 1 in the module.
+
+
+#ifndef NRFX_PRS_BOX_1_ENABLED
+#define NRFX_PRS_BOX_1_ENABLED 0
+#endif
+
+// <q> NRFX_PRS_BOX_2_ENABLED - Enables box 2 in the module.
+
+
+#ifndef NRFX_PRS_BOX_2_ENABLED
+#define NRFX_PRS_BOX_2_ENABLED 0
+#endif
+
+// <q> NRFX_PRS_BOX_3_ENABLED - Enables box 3 in the module.
+
+
+#ifndef NRFX_PRS_BOX_3_ENABLED
+#define NRFX_PRS_BOX_3_ENABLED 0
+#endif
+
+// <q> NRFX_PRS_BOX_4_ENABLED - Enables box 4 in the module.
+
+
+#ifndef NRFX_PRS_BOX_4_ENABLED
+#define NRFX_PRS_BOX_4_ENABLED 0
+#endif
+
+
+// <e> NRFX_PRS_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_PRS_CONFIG_LOG_ENABLED
+#define NRFX_PRS_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_PRS_CONFIG_LOG_LEVEL - Default severity level.
+
+// <0=> Off
+// <1=> Error
+// <2=> Warning
+// <3=> Info
+// <4=> Debug
+
+#ifndef NRFX_PRS_CONFIG_LOG_LEVEL
+#define NRFX_PRS_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_PRS_CONFIG_INFO_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_PRS_CONFIG_INFO_COLOR
+#define NRFX_PRS_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_PRS_CONFIG_DEBUG_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_PRS_CONFIG_DEBUG_COLOR
+#define NRFX_PRS_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRFX_PWM_ENABLED - nrfx_pwm - PWM peripheral driver.
+//==========================================================
+#ifndef NRFX_PWM_ENABLED
+#define NRFX_PWM_ENABLED 0
+#endif
+// <q> NRFX_PWM0_ENABLED - Enables PWM0 instance.
+
+
+#ifndef NRFX_PWM0_ENABLED
+#define NRFX_PWM0_ENABLED 0
+#endif
+
+// <q> NRFX_PWM1_ENABLED - Enables PWM1 instance.
+
+
+#ifndef NRFX_PWM1_ENABLED
+#define NRFX_PWM1_ENABLED 0
+#endif
+
+// <q> NRFX_PWM2_ENABLED - Enables PWM2 instance.
+
+
+#ifndef NRFX_PWM2_ENABLED
+#define NRFX_PWM2_ENABLED 0
+#endif
+
+// <q> NRFX_PWM3_ENABLED - Enables PWM3 instance.
+
+
+#ifndef NRFX_PWM3_ENABLED
+#define NRFX_PWM3_ENABLED 0
+#endif
+
+// <o> NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority.
+
+// <0=> 0 (highest)
+// <1=> 1
+// <2=> 2
+// <3=> 3
+// <4=> 4
+// <5=> 5
+// <6=> 6
+// <7=> 7
+
+#ifndef NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY
+#define NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY 7
+#endif
+
+// <e> NRFX_PWM_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_PWM_CONFIG_LOG_ENABLED
+#define NRFX_PWM_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_PWM_CONFIG_LOG_LEVEL - Default severity level.
+
+// <0=> Off
+// <1=> Error
+// <2=> Warning
+// <3=> Info
+// <4=> Debug
+
+#ifndef NRFX_PWM_CONFIG_LOG_LEVEL
+#define NRFX_PWM_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_PWM_CONFIG_INFO_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_PWM_CONFIG_INFO_COLOR
+#define NRFX_PWM_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_PWM_CONFIG_DEBUG_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_PWM_CONFIG_DEBUG_COLOR
+#define NRFX_PWM_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRFX_QDEC_ENABLED - nrfx_qdec - QDEC peripheral driver
+//==========================================================
+#ifndef NRFX_QDEC_ENABLED
+#define NRFX_QDEC_ENABLED 0
+#endif
+
+// <o> NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority
+
+// <0=> 0 (highest)
+// <1=> 1
+// <2=> 2
+// <3=> 3
+// <4=> 4
+// <5=> 5
+// <6=> 6
+// <7=> 7
+
+#ifndef NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY
+#define NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY 7
+#endif
+
+// <e> NRFX_QDEC_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_QDEC_CONFIG_LOG_ENABLED
+#define NRFX_QDEC_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_QDEC_CONFIG_LOG_LEVEL - Default Severity level
+
+// <0=> Off
+// <1=> Error
+// <2=> Warning
+// <3=> Info
+// <4=> Debug
+
+#ifndef NRFX_QDEC_CONFIG_LOG_LEVEL
+#define NRFX_QDEC_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_QDEC_CONFIG_INFO_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_QDEC_CONFIG_INFO_COLOR
+#define NRFX_QDEC_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_QDEC_CONFIG_DEBUG_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_QDEC_CONFIG_DEBUG_COLOR
+#define NRFX_QDEC_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRFX_QSPI_ENABLED - nrfx_qspi - QSPI peripheral driver
+//==========================================================
+#ifndef NRFX_QSPI_ENABLED
+#define NRFX_QSPI_ENABLED 0
+#endif
+
+// <o> NRFX_QSPI_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority
+
+// <0=> 0 (highest)
+// <1=> 1
+// <2=> 2
+// <3=> 3
+// <4=> 4
+// <5=> 5
+// <6=> 6
+// <7=> 7
+
+#ifndef NRFX_QSPI_DEFAULT_CONFIG_IRQ_PRIORITY
+#define NRFX_QSPI_DEFAULT_CONFIG_IRQ_PRIORITY 7
+#endif
+
+// </e>
+
+// <e> NRFX_RTC_ENABLED - nrfx_rtc - RTC peripheral driver.
+//==========================================================
+#ifndef NRFX_RTC_ENABLED
+#define NRFX_RTC_ENABLED 0
+#endif
+// <q> NRFX_RTC0_ENABLED - Enables RTC0 instance.
+
+
+#ifndef NRFX_RTC0_ENABLED
+#define NRFX_RTC0_ENABLED 0
+#endif
+
+// <q> NRFX_RTC1_ENABLED - Enables RTC1 instance.
+
+
+#ifndef NRFX_RTC1_ENABLED
+#define NRFX_RTC1_ENABLED 0
+#endif
+
+// <o> NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority.
+
+// <0=> 0 (highest)
+// <1=> 1
+// <2=> 2
+// <3=> 3
+// <4=> 4
+// <5=> 5
+// <6=> 6
+// <7=> 7
+
+#ifndef NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY
+#define NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY 7
+#endif
+
+// <e> NRFX_RTC_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_RTC_CONFIG_LOG_ENABLED
+#define NRFX_RTC_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_RTC_CONFIG_LOG_LEVEL - Default severity level.
+
+// <0=> Off
+// <1=> Error
+// <2=> Warning
+// <3=> Info
+// <4=> Debug
+
+#ifndef NRFX_RTC_CONFIG_LOG_LEVEL
+#define NRFX_RTC_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_RTC_CONFIG_INFO_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_RTC_CONFIG_INFO_COLOR
+#define NRFX_RTC_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_RTC_CONFIG_DEBUG_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_RTC_CONFIG_DEBUG_COLOR
+#define NRFX_RTC_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRFX_SAADC_ENABLED - nrfx_saadc - SAADC peripheral driver.
+//==========================================================
+#ifndef NRFX_SAADC_ENABLED
+#define NRFX_SAADC_ENABLED 0
+#endif
+
+// <o> NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority.
+
+// <0=> 0 (highest)
+// <1=> 1
+// <2=> 2
+// <3=> 3
+// <4=> 4
+// <5=> 5
+// <6=> 6
+// <7=> 7
+
+#ifndef NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY
+#define NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY 7
+#endif
+
+// <e> NRFX_SAADC_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_SAADC_CONFIG_LOG_ENABLED
+#define NRFX_SAADC_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_SAADC_CONFIG_LOG_LEVEL - Default severity level.
+
+// <0=> Off
+// <1=> Error
+// <2=> Warning
+// <3=> Info
+// <4=> Debug
+
+#ifndef NRFX_SAADC_CONFIG_LOG_LEVEL
+#define NRFX_SAADC_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_SAADC_CONFIG_INFO_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_SAADC_CONFIG_INFO_COLOR
+#define NRFX_SAADC_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_SAADC_CONFIG_DEBUG_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_SAADC_CONFIG_DEBUG_COLOR
+#define NRFX_SAADC_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRFX_SPIM_ENABLED - nrfx_spim - SPIM peripheral driver.
+//==========================================================
+#ifndef NRFX_SPIM_ENABLED
+#define NRFX_SPIM_ENABLED 0
+#endif
+// <q> NRFX_SPIM0_ENABLED - Enables SPIM0 instance.
+
+
+#ifndef NRFX_SPIM0_ENABLED
+#define NRFX_SPIM0_ENABLED 0
+#endif
+
+// <q> NRFX_SPIM1_ENABLED - Enables SPIM1 instance.
+
+
+#ifndef NRFX_SPIM1_ENABLED
+#define NRFX_SPIM1_ENABLED 0
+#endif
+
+// <q> NRFX_SPIM2_ENABLED - Enables SPIM2 instance.
+
+
+#ifndef NRFX_SPIM2_ENABLED
+#define NRFX_SPIM2_ENABLED 0
+#endif
+
+// <q> NRFX_SPIM3_ENABLED - Enables SPIM3 instance.
+
+
+#ifndef NRFX_SPIM3_ENABLED
+#define NRFX_SPIM3_ENABLED 0
+#endif
+
+// <q> NRFX_SPIM4_ENABLED - Enables SPIM4 instance.
+
+
+#ifndef NRFX_SPIM4_ENABLED
+#define NRFX_SPIM4_ENABLED 0
+#endif
+
+// <q> NRFX_SPIM_EXTENDED_ENABLED - Enable extended SPIM features
+
+
+#ifndef NRFX_SPIM_EXTENDED_ENABLED
+#define NRFX_SPIM_EXTENDED_ENABLED 0
+#endif
+
+// <o> NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority.
+
+// <0=> 0 (highest)
+// <1=> 1
+// <2=> 2
+// <3=> 3
+// <4=> 4
+// <5=> 5
+// <6=> 6
+// <7=> 7
+
+#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY
+#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY 7
+#endif
+
+// <e> NRFX_SPIM_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED
+#define NRFX_SPIM_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_SPIM_CONFIG_LOG_LEVEL - Default severity level.
+
+// <0=> Off
+// <1=> Error
+// <2=> Warning
+// <3=> Info
+// <4=> Debug
+
+#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL
+#define NRFX_SPIM_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_SPIM_CONFIG_INFO_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_SPIM_CONFIG_INFO_COLOR
+#define NRFX_SPIM_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_SPIM_CONFIG_DEBUG_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_SPIM_CONFIG_DEBUG_COLOR
+#define NRFX_SPIM_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRFX_SPIS_ENABLED - nrfx_spis - SPIS peripheral driver.
+//==========================================================
+#ifndef NRFX_SPIS_ENABLED
+#define NRFX_SPIS_ENABLED 0
+#endif
+// <q> NRFX_SPIS0_ENABLED - Enables SPIS0 instance.
+
+
+#ifndef NRFX_SPIS0_ENABLED
+#define NRFX_SPIS0_ENABLED 0
+#endif
+
+// <q> NRFX_SPIS1_ENABLED - Enables SPIS1 instance.
+
+
+#ifndef NRFX_SPIS1_ENABLED
+#define NRFX_SPIS1_ENABLED 0
+#endif
+
+// <q> NRFX_SPIS2_ENABLED - Enables SPIS2 instance.
+
+
+#ifndef NRFX_SPIS2_ENABLED
+#define NRFX_SPIS2_ENABLED 0
+#endif
+
+// <q> NRFX_SPIS3_ENABLED - Enables SPIS3 instance.
+
+
+#ifndef NRFX_SPIS3_ENABLED
+#define NRFX_SPIS3_ENABLED 0
+#endif
+
+// <o> NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority.
+
+// <0=> 0 (highest)
+// <1=> 1
+// <2=> 2
+// <3=> 3
+// <4=> 4
+// <5=> 5
+// <6=> 6
+// <7=> 7
+
+#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY
+#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY 7
+#endif
+
+// <e> NRFX_SPIS_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED
+#define NRFX_SPIS_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_SPIS_CONFIG_LOG_LEVEL - Default severity level.
+
+// <0=> Off
+// <1=> Error
+// <2=> Warning
+// <3=> Info
+// <4=> Debug
+
+#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL
+#define NRFX_SPIS_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_SPIS_CONFIG_INFO_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_SPIS_CONFIG_INFO_COLOR
+#define NRFX_SPIS_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_SPIS_CONFIG_DEBUG_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_SPIS_CONFIG_DEBUG_COLOR
+#define NRFX_SPIS_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <q> NRFX_SYSTICK_ENABLED - nrfx_systick - ARM(R) SysTick driver.
+
+
+#ifndef NRFX_SYSTICK_ENABLED
+#define NRFX_SYSTICK_ENABLED 0
+#endif
+
+// <e> NRFX_TIMER_ENABLED - nrfx_timer - TIMER periperal driver.
+//==========================================================
+#ifndef NRFX_TIMER_ENABLED
+#define NRFX_TIMER_ENABLED 0
+#endif
+// <q> NRFX_TIMER0_ENABLED - Enables TIMER0 instance.
+
+
+#ifndef NRFX_TIMER0_ENABLED
+#define NRFX_TIMER0_ENABLED 0
+#endif
+
+// <q> NRFX_TIMER1_ENABLED - Enables TIMER1 instance.
+
+
+#ifndef NRFX_TIMER1_ENABLED
+#define NRFX_TIMER1_ENABLED 0
+#endif
+
+// <q> NRFX_TIMER2_ENABLED - Enables TIMER2 instance.
+
+
+#ifndef NRFX_TIMER2_ENABLED
+#define NRFX_TIMER2_ENABLED 0
+#endif
+
+// <o> NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority.
+
+// <0=> 0 (highest)
+// <1=> 1
+// <2=> 2
+// <3=> 3
+// <4=> 4
+// <5=> 5
+// <6=> 6
+// <7=> 7
+
+#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY
+#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY 7
+#endif
+
+// <e> NRFX_TIMER_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED
+#define NRFX_TIMER_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_TIMER_CONFIG_LOG_LEVEL - Default severity level.
+
+// <0=> Off
+// <1=> Error
+// <2=> Warning
+// <3=> Info
+// <4=> Debug
+
+#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL
+#define NRFX_TIMER_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_TIMER_CONFIG_INFO_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_TIMER_CONFIG_INFO_COLOR
+#define NRFX_TIMER_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_TIMER_CONFIG_DEBUG_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_TIMER_CONFIG_DEBUG_COLOR
+#define NRFX_TIMER_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRFX_TWIM_ENABLED - nrfx_twim - TWIM peripheral driver.
+//==========================================================
+#ifndef NRFX_TWIM_ENABLED
+#define NRFX_TWIM_ENABLED 0
+#endif
+// <q> NRFX_TWIM0_ENABLED - Enables TWIM0 instance.
+
+
+#ifndef NRFX_TWIM0_ENABLED
+#define NRFX_TWIM0_ENABLED 0
+#endif
+
+// <q> NRFX_TWIM1_ENABLED - Enables TWIM1 instance.
+
+
+#ifndef NRFX_TWIM1_ENABLED
+#define NRFX_TWIM1_ENABLED 0
+#endif
+
+// <q> NRFX_TWIM2_ENABLED - Enables TWIM2 instance.
+
+
+#ifndef NRFX_TWIM2_ENABLED
+#define NRFX_TWIM2_ENABLED 0
+#endif
+
+// <q> NRFX_TWIM3_ENABLED - Enables TWIM3 instance.
+
+
+#ifndef NRFX_TWIM3_ENABLED
+#define NRFX_TWIM3_ENABLED 0
+#endif
+
+// <o> NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority.
+
+// <0=> 0 (highest)
+// <1=> 1
+// <2=> 2
+// <3=> 3
+// <4=> 4
+// <5=> 5
+// <6=> 6
+// <7=> 7
+
+#ifndef NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY
+#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY 7
+#endif
+
+// <e> NRFX_TWIM_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_TWIM_CONFIG_LOG_ENABLED
+#define NRFX_TWIM_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_TWIM_CONFIG_LOG_LEVEL - Default severity level.
+
+// <0=> Off
+// <1=> Error
+// <2=> Warning
+// <3=> Info
+// <4=> Debug
+
+#ifndef NRFX_TWIM_CONFIG_LOG_LEVEL
+#define NRFX_TWIM_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_TWIM_CONFIG_INFO_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_TWIM_CONFIG_INFO_COLOR
+#define NRFX_TWIM_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_TWIM_CONFIG_DEBUG_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_TWIM_CONFIG_DEBUG_COLOR
+#define NRFX_TWIM_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRFX_TWIS_ENABLED - nrfx_twis - TWIS peripheral driver.
+//==========================================================
+#ifndef NRFX_TWIS_ENABLED
+#define NRFX_TWIS_ENABLED 0
+#endif
+
+// <q> NRFX_TWIS0_ENABLED - Enables TWIS0 instance.
+
+#ifndef NRFX_TWIS0_ENABLED
+#define NRFX_TWIS0_ENABLED 0
+#endif
+
+// <q> NRFX_TWIS1_ENABLED - Enables TWIS1 instance.
+
+#ifndef NRFX_TWIS1_ENABLED
+#define NRFX_TWIS1_ENABLED 0
+#endif
+
+// <q> NRFX_TWIS2_ENABLED - Enables TWIS2 instance.
+
+#ifndef NRFX_TWIS2_ENABLED
+#define NRFX_TWIS2_ENABLED 0
+#endif
+
+// <q> NRFX_TWIS3_ENABLED - Enables TWIS3 instance.
+
+#ifndef NRFX_TWIS3_ENABLED
+#define NRFX_TWIS3_ENABLED 0
+#endif
+
+// <q> NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY - Assumes that any instance would be initialized only once.
+
+// <i> Optimization flag. Registers used by TWIS are shared by other peripherals. Normally, during initialization driver tries to clear all registers to known state before doing the initialization itself. This gives initialization safe procedure, no matter when it would be called. If you activate TWIS only once and do never uninitialize it - set this flag to 1 what gives more optimal code.
+
+#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY
+#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0
+#endif
+
+// <q> NRFX_TWIS_NO_SYNC_MODE - Removes support for synchronous mode.
+
+// <i> Synchronous mode would be used in specific situations. And it uses some additional code and data memory to safely process state machine by polling it in status functions. If this functionality is not required it may be disabled to free some resources.
+
+#ifndef NRFX_TWIS_NO_SYNC_MODE
+#define NRFX_TWIS_NO_SYNC_MODE 0
+#endif
+
+// <o> NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority.
+
+// <0=> 0 (highest)
+// <1=> 1
+// <2=> 2
+// <3=> 3
+// <4=> 4
+// <5=> 5
+// <6=> 6
+// <7=> 7
+
+#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY
+#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY 7
+#endif
+
+// <e> NRFX_TWIS_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_TWIS_CONFIG_LOG_ENABLED
+#define NRFX_TWIS_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_TWIS_CONFIG_LOG_LEVEL - Default severity level.
+
+// <0=> Off
+// <1=> Error
+// <2=> Warning
+// <3=> Info
+// <4=> Debug
+
+#ifndef NRFX_TWIS_CONFIG_LOG_LEVEL
+#define NRFX_TWIS_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_TWIS_CONFIG_INFO_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_TWIS_CONFIG_INFO_COLOR
+#define NRFX_TWIS_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_TWIS_CONFIG_DEBUG_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_TWIS_CONFIG_DEBUG_COLOR
+#define NRFX_TWIS_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRFX_UARTE_ENABLED - nrfx_uarte - UARTE peripheral driver.
+//==========================================================
+#ifndef NRFX_UARTE_ENABLED
+#define NRFX_UARTE_ENABLED 0
+#endif
+// <o> NRFX_UARTE0_ENABLED - Enables UARTE0 instances
+#ifndef NRFX_UARTE0_ENABLED
+#define NRFX_UARTE0_ENABLED 0
+#endif
+
+// <o> NRFX_UARTE1_ENABLED - Enables UARTE1 instance.
+#ifndef NRFX_UARTE1_ENABLED
+#define NRFX_UARTE1_ENABLED 0
+#endif
+
+// <o> NRFX_UARTE2_ENABLED - Enables UARTE2 instance.
+#ifndef NRFX_UARTE2_ENABLED
+#define NRFX_UARTE2_ENABLED 0
+#endif
+
+// <o> NRFX_UARTE3_ENABLED - Enables UARTE3 instance.
+#ifndef NRFX_UARTE3_ENABLED
+#define NRFX_UARTE3_ENABLED 0
+#endif
+
+// <o> NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority.
+
+// <0=> 0 (highest)
+// <1=> 1
+// <2=> 2
+// <3=> 3
+// <4=> 4
+// <5=> 5
+// <6=> 6
+// <7=> 7
+
+#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY
+#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY 7
+#endif
+
+// <e> NRFX_UARTE_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED
+#define NRFX_UARTE_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_UARTE_CONFIG_LOG_LEVEL - Default severity level.
+
+// <0=> Off
+// <1=> Error
+// <2=> Warning
+// <3=> Info
+// <4=> Debug
+
+#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL
+#define NRFX_UARTE_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_UARTE_CONFIG_INFO_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_UARTE_CONFIG_INFO_COLOR
+#define NRFX_UARTE_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_UARTE_CONFIG_DEBUG_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_UARTE_CONFIG_DEBUG_COLOR
+#define NRFX_UARTE_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRFX_USBD_ENABLED - nrfx_usbd - USBD peripheral driver
+//==========================================================
+#ifndef NRFX_USBD_ENABLED
+#define NRFX_USBD_ENABLED 0
+#endif
+// <o> NRFX_USBD_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority
+
+// <0=> 0 (highest)
+// <1=> 1
+// <2=> 2
+// <3=> 3
+// <4=> 4
+// <5=> 5
+// <6=> 6
+// <7=> 7
+
+#ifndef NRFX_USBD_DEFAULT_CONFIG_IRQ_PRIORITY
+#define NRFX_USBD_DEFAULT_CONFIG_IRQ_PRIORITY 7
+#endif
+
+// <q> USBD_CONFIG_DMASCHEDULER_ISO_BOOST - Give priority to isochronous transfers
+
+// <i> This option gives priority to isochronous transfers.
+// <i> Enabling it assures that isochronous transfers are always processed,
+// <i> even if multiple other transfers are pending.
+// <i> Isochronous endpoints are prioritized before the usbd_dma_scheduler_algorithm
+// <i> function is called, so the option is independent of the algorithm chosen.
+
+#ifndef NRFX_USBD_CONFIG_DMASCHEDULER_ISO_BOOST
+#define NRFX_USBD_CONFIG_DMASCHEDULER_ISO_BOOST 1
+#endif
+
+// <q> USBD_CONFIG_ISO_IN_ZLP - Respond to an IN token on ISO IN endpoint with ZLP when no data is ready
+
+
+// <i> If set, ISO IN endpoint will respond to an IN token with ZLP when no data is ready to be sent.
+// <i> Else, there will be no response.
+
+#ifndef NRFX_USBD_CONFIG_ISO_IN_ZLP
+#define NRFX_USBD_CONFIG_ISO_IN_ZLP 0
+#endif
+
+// <e> NRFX_USBD_CONFIG_LOG_ENABLED - Enable logging in the module
+//==========================================================
+#ifndef NRFX_USBD_CONFIG_LOG_ENABLED
+#define NRFX_USBD_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_USBD_CONFIG_LOG_LEVEL - Default Severity level
+
+// <0=> Off
+// <1=> Error
+// <2=> Warning
+// <3=> Info
+// <4=> Debug
+
+#ifndef NRFX_USBD_CONFIG_LOG_LEVEL
+#define NRFX_USBD_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_USBD_CONFIG_INFO_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_USBD_CONFIG_INFO_COLOR
+#define NRFX_USBD_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_USBD_CONFIG_DEBUG_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_USBD_CONFIG_DEBUG_COLOR
+#define NRFX_USBD_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRFX_USBREG_ENABLED - nrfx_usbreg - USBREG peripheral driver
+//==========================================================
+#ifndef NRFX_USBREG_ENABLED
+#define NRFX_USBREG_ENABLED 0
+#endif
+// <o> NRFX_USBREG_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority
+
+// <0=> 0 (highest)
+// <1=> 1
+// <2=> 2
+// <3=> 3
+// <4=> 4
+// <5=> 5
+// <6=> 6
+// <7=> 7
+
+#ifndef NRFX_USBREG_DEFAULT_CONFIG_IRQ_PRIORITY
+#define NRFX_USBREG_DEFAULT_CONFIG_IRQ_PRIORITY 7
+#endif
+
+// </e>
+
+// </e>
+
+// <e> NRFX_WDT_ENABLED - nrfx_wdt - WDT peripheral driver.
+//==========================================================
+#ifndef NRFX_WDT_ENABLED
+#define NRFX_WDT_ENABLED 0
+#endif
+// <q> NRFX_WDT0_ENABLED - Enable WDT0 instance.
+
+
+#ifndef NRFX_WDT0_ENABLED
+#define NRFX_WDT0_ENABLED 0
+#endif
+
+// <q> NRFX_WDT1_ENABLED - Enable WDT1 instance.
+
+
+#ifndef NRFX_WDT1_ENABLED
+#define NRFX_WDT1_ENABLED 0
+#endif
+
+// <o> NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver.
+
+// <0=> Include WDT IRQ handling
+// <1=> Remove WDT IRQ handling
+
+#ifndef NRFX_WDT_CONFIG_NO_IRQ
+#define NRFX_WDT_CONFIG_NO_IRQ 0
+#endif
+
+// <o> NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority.
+
+// <0=> 0 (highest)
+// <1=> 1
+// <2=> 2
+// <3=> 3
+// <4=> 4
+// <5=> 5
+// <6=> 6
+// <7=> 7
+
+#ifndef NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY
+#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY 7
+#endif
+
+// <e> NRFX_WDT_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef NRFX_WDT_CONFIG_LOG_ENABLED
+#define NRFX_WDT_CONFIG_LOG_ENABLED 0
+#endif
+// <o> NRFX_WDT_CONFIG_LOG_LEVEL - Default severity level.
+
+// <0=> Off
+// <1=> Error
+// <2=> Warning
+// <3=> Info
+// <4=> Debug
+
+#ifndef NRFX_WDT_CONFIG_LOG_LEVEL
+#define NRFX_WDT_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> NRFX_WDT_CONFIG_INFO_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_WDT_CONFIG_INFO_COLOR
+#define NRFX_WDT_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> NRFX_WDT_CONFIG_DEBUG_COLOR - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRFX_WDT_CONFIG_DEBUG_COLOR
+#define NRFX_WDT_CONFIG_DEBUG_COLOR 0
+#endif
+
+// </e>
+
+// </e>
+
+// </h>
+
+#endif // NRFX_CONFIG_NRF5340_APPLICATION_H__
diff --git a/platform/ext/target/lairdconnectivity/common/core/nrfx_glue.h b/platform/ext/target/lairdconnectivity/common/core/nrfx_glue.h
new file mode 100644
index 000000000..e8b5f6327
--- /dev/null
+++ b/platform/ext/target/lairdconnectivity/common/core/nrfx_glue.h
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 2017 - 2020, 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 the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef NRFX_GLUE_H__
+#define NRFX_GLUE_H__
+
+#include <assert.h>
+
+#include <soc/nrfx_coredep.h>
+#include <soc/nrfx_irqs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup nrfx_glue nrfx_glue.h
+ * @{
+ * @ingroup nrfx
+ *
+ * @brief This file contains macros that should be implemented according to
+ * the needs of the host environment into which @em nrfx is integrated.
+ */
+
+//------------------------------------------------------------------------------
+
+/**
+ * @brief Macro for placing a runtime assertion.
+ *
+ * @param expression Expression to be evaluated.
+ */
+#if defined(NDEBUG)
+#define NRFX_ASSERT(expression) if (0 && (expression)) {}
+#else
+#define NRFX_ASSERT(expression) assert(expression)
+#endif
+
+/**
+ * @brief Macro for placing a compile time assertion.
+ *
+ * @param expression Expression to be evaluated.
+ */
+#define NRFX_STATIC_ASSERT(expression) _Static_assert(expression, "")
+
+//------------------------------------------------------------------------------
+
+/**
+ * @brief Macro for setting the priority of a specific IRQ.
+ *
+ * @param irq_number IRQ number.
+ * @param priority Priority to be set.
+ */
+#define NRFX_IRQ_PRIORITY_SET(irq_number, priority) \
+ NVIC_SetPriority(irq_number, priority)
+
+/**
+ * @brief Macro for enabling a specific IRQ.
+ *
+ * @param irq_number IRQ number.
+ */
+#define NRFX_IRQ_ENABLE(irq_number) NVIC_EnableIRQ(irq_number)
+
+/**
+ * @brief Macro for checking if a specific IRQ is enabled.
+ *
+ * @param irq_number IRQ number.
+ *
+ * @retval true If the IRQ is enabled.
+ * @retval false Otherwise.
+ */
+#define NRFX_IRQ_IS_ENABLED(irq_number) NVIC_GetEnableIRQ(irq_number)
+
+/**
+ * @brief Macro for disabling a specific IRQ.
+ *
+ * @param irq_number IRQ number.
+ */
+#define NRFX_IRQ_DISABLE(irq_number) NVIC_DisableIRQ(irq_number)
+
+/**
+ * @brief Macro for setting a specific IRQ as pending.
+ *
+ * @param irq_number IRQ number.
+ */
+#define NRFX_IRQ_PENDING_SET(irq_number) NVIC_SetPendingIRQ(irq_number)
+
+/**
+ * @brief Macro for clearing the pending status of a specific IRQ.
+ *
+ * @param irq_number IRQ number.
+ */
+#define NRFX_IRQ_PENDING_CLEAR(irq_number) NVIC_ClearPendingIRQ(irq_number)
+
+/**
+ * @brief Macro for checking the pending status of a specific IRQ.
+ *
+ * @retval true If the IRQ is pending.
+ * @retval false Otherwise.
+ */
+#define NRFX_IRQ_IS_PENDING(irq_number) NVIC_GetPendingIRQ(irq_number)
+
+/** @brief Macro for entering into a critical section. */
+#define NRFX_CRITICAL_SECTION_ENTER() nrfx_critical_section_enter()
+void nrfx_critical_section_enter(void);
+
+/** @brief Macro for exiting from a critical section. */
+#define NRFX_CRITICAL_SECTION_EXIT() nrfx_critical_section_exit()
+void nrfx_critical_section_exit(void);
+
+//------------------------------------------------------------------------------
+
+/**
+ * @brief When set to a non-zero value, this macro specifies that
+ * @ref nrfx_coredep_delay_us uses a precise DWT-based solution.
+ * A compilation error is generated if the DWT unit is not present
+ * in the SoC used.
+ */
+#define NRFX_DELAY_DWT_BASED 0
+
+/**
+ * @brief Macro for delaying the code execution for at least the specified time.
+ *
+ * @param us_time Number of microseconds to wait.
+ */
+#define NRFX_DELAY_US(us_time) nrfx_coredep_delay_us(us_time)
+
+//------------------------------------------------------------------------------
+
+/** @brief Atomic 32-bit unsigned type. */
+#define nrfx_atomic_t
+
+/**
+ * @brief Macro for storing a value to an atomic object and returning its previous value.
+ *
+ * @param[in] p_data Atomic memory pointer.
+ * @param[in] value Value to store.
+ *
+ * @return Previous value of the atomic object.
+ */
+#define NRFX_ATOMIC_FETCH_STORE(p_data, value)
+
+/**
+ * @brief Macro for running a bitwise OR operation on an atomic object and returning its previous value.
+ *
+ * @param[in] p_data Atomic memory pointer.
+ * @param[in] value Value of the second operand in the OR operation.
+ *
+ * @return Previous value of the atomic object.
+ */
+#define NRFX_ATOMIC_FETCH_OR(p_data, value)
+
+/**
+ * @brief Macro for running a bitwise AND operation on an atomic object
+ * and returning its previous value.
+ *
+ * @param[in] p_data Atomic memory pointer.
+ * @param[in] value Value of the second operand in the AND operation.
+ *
+ * @return Previous value of the atomic object.
+ */
+#define NRFX_ATOMIC_FETCH_AND(p_data, value)
+
+/**
+ * @brief Macro for running a bitwise XOR operation on an atomic object
+ * and returning its previous value.
+ *
+ * @param[in] p_data Atomic memory pointer.
+ * @param[in] value Value of the second operand in the XOR operation.
+ *
+ * @return Previous value of the atomic object.
+ */
+#define NRFX_ATOMIC_FETCH_XOR(p_data, value)
+
+/**
+ * @brief Macro for running an addition operation on an atomic object
+ * and returning its previous value.
+ *
+ * @param[in] p_data Atomic memory pointer.
+ * @param[in] value Value of the second operand in the ADD operation.
+ *
+ * @return Previous value of the atomic object.
+ */
+#define NRFX_ATOMIC_FETCH_ADD(p_data, value)
+
+/**
+ * @brief Macro for running a subtraction operation on an atomic object
+ * and returning its previous value.
+ *
+ * @param[in] p_data Atomic memory pointer.
+ * @param[in] value Value of the second operand in the SUB operation.
+ *
+ * @return Previous value of the atomic object.
+ */
+#define NRFX_ATOMIC_FETCH_SUB(p_data, value)
+
+//------------------------------------------------------------------------------
+
+/**
+ * @brief When set to a non-zero value, this macro specifies that the
+ * @ref nrfx_error_codes and the @ref nrfx_err_t type itself are defined
+ * in a customized way and the default definitions from @c <nrfx_error.h>
+ * should not be used.
+ */
+#define NRFX_CUSTOM_ERROR_CODES 0
+
+//------------------------------------------------------------------------------
+
+/**
+ * @brief When set to a non-zero value, this macro specifies that inside HALs
+ * the event registers are read back after clearing, on devices that
+ * otherwise could defer the actual register modification.
+ */
+#define NRFX_EVENT_READBACK_ENABLED 1
+
+//------------------------------------------------------------------------------
+
+/** @brief Bitmask that defines DPPI channels that are reserved for use outside of the nrfx library. */
+#define NRFX_DPPI_CHANNELS_USED 0
+
+/** @brief Bitmask that defines DPPI groups that are reserved for use outside of the nrfx library. */
+#define NRFX_DPPI_GROUPS_USED 0
+
+/** @brief Bitmask that defines PPI channels that are reserved for use outside of the nrfx library. */
+#define NRFX_PPI_CHANNELS_USED 0
+
+/** @brief Bitmask that defines PPI groups that are reserved for use outside of the nrfx library. */
+#define NRFX_PPI_GROUPS_USED 0
+
+/** @brief Bitmask that defines GPIOTE channels that are reserved for use outside of the nrfx library. */
+#define NRFX_GPIOTE_CHANNELS_USED 0
+
+/** @brief Bitmask that defines EGU instances that are reserved for use outside of the nrfx library. */
+#define NRFX_EGUS_USED 0
+
+/** @brief Bitmask that defines TIMER instances that are reserved for use outside of the nrfx library. */
+#define NRFX_TIMERS_USED 0
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRFX_GLUE_H__
diff --git a/platform/ext/target/lairdconnectivity/common/core/nrfx_log.h b/platform/ext/target/lairdconnectivity/common/core/nrfx_log.h
new file mode 100644
index 000000000..80d8efbdf
--- /dev/null
+++ b/platform/ext/target/lairdconnectivity/common/core/nrfx_log.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2017 - 2020, 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 the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef NRFX_LOG_H__
+#define NRFX_LOG_H__
+
+// THIS IS A TEMPLATE FILE.
+// It should be copied to a suitable location within the host environment into
+// which nrfx is integrated, and the following macros should be provided with
+// appropriate implementations.
+// And this comment should be removed from the customized file.
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup nrfx_log nrfx_log.h
+ * @{
+ * @ingroup nrfx
+ *
+ * @brief This file contains macros that should be implemented according to
+ * the needs of the host environment into which @em nrfx is integrated.
+ */
+
+/**
+ * @brief Macro for logging a message with the severity level ERROR.
+ *
+ * @param format printf-style format string, optionally followed by arguments
+ * to be formatted and inserted in the resulting string.
+ */
+#define NRFX_LOG_ERROR(format, ...)
+
+/**
+ * @brief Macro for logging a message with the severity level WARNING.
+ *
+ * @param format printf-style format string, optionally followed by arguments
+ * to be formatted and inserted in the resulting string.
+ */
+#define NRFX_LOG_WARNING(format, ...)
+
+/**
+ * @brief Macro for logging a message with the severity level INFO.
+ *
+ * @param format printf-style format string, optionally followed by arguments
+ * to be formatted and inserted in the resulting string.
+ */
+#define NRFX_LOG_INFO(format, ...)
+
+/**
+ * @brief Macro for logging a message with the severity level DEBUG.
+ *
+ * @param format printf-style format string, optionally followed by arguments
+ * to be formatted and inserted in the resulting string.
+ */
+#define NRFX_LOG_DEBUG(format, ...)
+
+
+/**
+ * @brief Macro for logging a memory dump with the severity level ERROR.
+ *
+ * @param[in] p_memory Pointer to the memory region to be dumped.
+ * @param[in] length Length of the memory region in bytes.
+ */
+#define NRFX_LOG_HEXDUMP_ERROR(p_memory, length)
+
+/**
+ * @brief Macro for logging a memory dump with the severity level WARNING.
+ *
+ * @param[in] p_memory Pointer to the memory region to be dumped.
+ * @param[in] length Length of the memory region in bytes.
+ */
+#define NRFX_LOG_HEXDUMP_WARNING(p_memory, length)
+
+/**
+ * @brief Macro for logging a memory dump with the severity level INFO.
+ *
+ * @param[in] p_memory Pointer to the memory region to be dumped.
+ * @param[in] length Length of the memory region in bytes.
+ */
+#define NRFX_LOG_HEXDUMP_INFO(p_memory, length)
+
+/**
+ * @brief Macro for logging a memory dump with the severity level DEBUG.
+ *
+ * @param[in] p_memory Pointer to the memory region to be dumped.
+ * @param[in] length Length of the memory region in bytes.
+ */
+#define NRFX_LOG_HEXDUMP_DEBUG(p_memory, length)
+
+
+/**
+ * @brief Macro for getting the textual representation of a given error code.
+ *
+ * @param[in] error_code Error code.
+ *
+ * @return String containing the textual representation of the error code.
+ */
+#define NRFX_LOG_ERROR_STRING_GET(error_code)
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRFX_LOG_H__
diff --git a/platform/ext/target/lairdconnectivity/common/core/nv_counters.c b/platform/ext/target/lairdconnectivity/common/core/nv_counters.c
new file mode 100644
index 000000000..6ae028f40
--- /dev/null
+++ b/platform/ext/target/lairdconnectivity/common/core/nv_counters.c
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2021, Laird Connectivity. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/* NOTE: This API should be implemented by the end-user. For the security of
+ * the protected storage system's and the bootloader's rollback protection etc.
+ * it is CRITICAL to use a internal (in-die) persistent memory for multiple time
+ * programmable (MTP) non-volatile counters or use a One-time Programmable (OTP)
+ * non-volatile counters solution.
+ *
+ * This dummy implementation assumes that the NV counters are the only data in
+ * the flash sectors. To use it, two flash sectors should be allocated exclusively
+ * for the NV counters (one acts as a backup in case of power failure during write).
+ */
+
+#include "tfm_plat_nv_counters.h"
+
+#include <limits.h>
+#include "Driver_Flash.h"
+#include "flash_layout.h"
+
+/* Compilation time checks to be sure the defines are well defined */
+#ifndef TFM_NV_COUNTERS_AREA_ADDR
+#error "TFM_NV_COUNTERS_AREA_ADDR must be defined in flash_layout.h"
+#endif
+
+#ifndef TFM_NV_COUNTERS_AREA_SIZE
+#error "TFM_NV_COUNTERS_AREA_SIZE must be defined in flash_layout.h"
+#endif
+
+#ifndef TFM_NV_COUNTERS_SECTOR_ADDR
+#error "TFM_NV_COUNTERS_SECTOR_ADDR must be defined in flash_layout.h"
+#endif
+
+#ifndef TFM_NV_COUNTERS_SECTOR_SIZE
+#error "TFM_NV_COUNTERS_SECTOR_SIZE must be defined in flash_layout.h"
+#endif
+
+#if (TFM_NV_COUNTERS_BACKUP_AREA_ADDR || TFM_NV_COUNTERS_BACKUP_SECTOR_ADDR)
+#ifndef TFM_NV_COUNTERS_BACKUP_AREA_ADDR
+#error "TFM_NV_COUNTERS_BACKUP_AREA_ADDR must be defined in flash_layout.h as one or more backup NV counter defines are set"
+#endif
+#ifndef TFM_NV_COUNTERS_BACKUP_SECTOR_ADDR
+#error "TFM_NV_COUNTERS_BACKUP_SECTOR_ADDR must be defined in flash_layout.h as one or more backup NV counter defines are set"
+#endif
+#endif
+
+#ifndef NV_COUNTERS_FLASH_DEV_NAME
+ #ifndef FLASH_DEV_NAME
+ #error "NV_COUNTERS_FLASH_DEV_NAME or FLASH_DEV_NAME must be defined in flash_layout.h"
+ #else
+ #define NV_COUNTERS_FLASH_DEV_NAME FLASH_DEV_NAME
+ #endif
+#endif
+/* End of compilation time checks to be sure the defines are well defined */
+
+#define NV_COUNTER_SIZE sizeof(uint32_t)
+#define INIT_VALUE_SIZE NV_COUNTER_SIZE
+#define NUM_NV_COUNTERS ((TFM_NV_COUNTERS_AREA_SIZE - INIT_VALUE_SIZE) \
+ / NV_COUNTER_SIZE)
+
+#define NV_COUNTERS_INITIALIZED 0xC0DE0042U
+
+/**
+ * \brief Struct representing the NV counter data in flash.
+ */
+struct nv_counters_t {
+ uint32_t counters[NUM_NV_COUNTERS]; /**< Array of NV counters */
+ uint32_t init_value; /**< Watermark to indicate if the NV counters have been
+ * initialised
+ */
+};
+
+/* Import the CMSIS flash device driver */
+extern ARM_DRIVER_FLASH NV_COUNTERS_FLASH_DEV_NAME;
+
+enum tfm_plat_err_t tfm_plat_init_nv_counter(void)
+{
+ int32_t err;
+ uint32_t i;
+ struct nv_counters_t nv_counters = {{0}};
+
+ err = NV_COUNTERS_FLASH_DEV_NAME.Initialize(NULL);
+ if (err != ARM_DRIVER_OK) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ /* Read the NV counter area to be able to erase the sector and write later
+ * in the flash.
+ */
+ err = NV_COUNTERS_FLASH_DEV_NAME.ReadData(TFM_NV_COUNTERS_AREA_ADDR,
+ &nv_counters,
+ TFM_NV_COUNTERS_AREA_SIZE);
+ if (err != ARM_DRIVER_OK) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ if (nv_counters.init_value == NV_COUNTERS_INITIALIZED) {
+ return TFM_PLAT_ERR_SUCCESS;
+ }
+
+#ifdef TFM_NV_COUNTERS_BACKUP_AREA_ADDR
+ /* Read the NV counter backup area to be able to erase the sector and
+ * write later in the flash.
+ */
+ err = NV_COUNTERS_FLASH_DEV_NAME.ReadData(TFM_NV_COUNTERS_BACKUP_AREA_ADDR,
+ &nv_counters,
+ TFM_NV_COUNTERS_AREA_SIZE);
+ if (err != ARM_DRIVER_OK) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ if (nv_counters.init_value == NV_COUNTERS_INITIALIZED) {
+ /* Erase main sector before write in it */
+ err = NV_COUNTERS_FLASH_DEV_NAME.EraseSector(TFM_NV_COUNTERS_SECTOR_ADDR);
+ if (err != ARM_DRIVER_OK) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ /* Write in flash the in-memory NV counter content from the backup sector */
+ err = NV_COUNTERS_FLASH_DEV_NAME.ProgramData(TFM_NV_COUNTERS_AREA_ADDR,
+ &nv_counters,
+ TFM_NV_COUNTERS_AREA_SIZE);
+ if (err != ARM_DRIVER_OK) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ return TFM_PLAT_ERR_SUCCESS;
+ }
+#endif
+
+ /* Add watermark, at the end of the NV counters area, to indicate that NV
+ * counters have been initialized.
+ */
+ nv_counters.init_value = NV_COUNTERS_INITIALIZED;
+
+ /* Initialize all counters to 0 */
+ for (i = 0; i < NUM_NV_COUNTERS; i++) {
+ nv_counters.counters[i] = 0;
+ }
+
+ /* Erase main sector before write in it */
+ err = NV_COUNTERS_FLASH_DEV_NAME.EraseSector(TFM_NV_COUNTERS_SECTOR_ADDR);
+ if (err != ARM_DRIVER_OK) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ /* Erase backup sector before write in it */
+ err = NV_COUNTERS_FLASH_DEV_NAME.EraseSector(TFM_NV_COUNTERS_BACKUP_SECTOR_ADDR);
+ if (err != ARM_DRIVER_OK) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ /* Write in flash the in-memory NV counter content after modification to the main sector */
+ err = NV_COUNTERS_FLASH_DEV_NAME.ProgramData(TFM_NV_COUNTERS_AREA_ADDR,
+ &nv_counters,
+ TFM_NV_COUNTERS_AREA_SIZE);
+ if (err != ARM_DRIVER_OK) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ /* Write in flash the in-memory NV counter content after modification to the backup sector */
+ err = NV_COUNTERS_FLASH_DEV_NAME.ProgramData(TFM_NV_COUNTERS_BACKUP_AREA_ADDR,
+ &nv_counters,
+ TFM_NV_COUNTERS_AREA_SIZE);
+ if (err != ARM_DRIVER_OK) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ return TFM_PLAT_ERR_SUCCESS;
+}
+
+enum tfm_plat_err_t tfm_plat_read_nv_counter(enum tfm_nv_counter_t counter_id,
+ uint32_t size, uint8_t *val)
+{
+ int32_t err;
+ uint32_t flash_addr;
+
+ if (size != NV_COUNTER_SIZE) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ flash_addr = TFM_NV_COUNTERS_AREA_ADDR + (counter_id * NV_COUNTER_SIZE);
+
+ err = NV_COUNTERS_FLASH_DEV_NAME.ReadData(flash_addr, val, NV_COUNTER_SIZE);
+ if (err != ARM_DRIVER_OK) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ return TFM_PLAT_ERR_SUCCESS;
+}
+
+enum tfm_plat_err_t tfm_plat_set_nv_counter(enum tfm_nv_counter_t counter_id,
+ uint32_t value)
+{
+ int32_t err;
+ struct nv_counters_t nv_counters = {{0}};
+
+ /* Read the NV counter area to be able to erase the sector and write later
+ * in the flash.
+ */
+ err = NV_COUNTERS_FLASH_DEV_NAME.ReadData(TFM_NV_COUNTERS_AREA_ADDR,
+ &nv_counters,
+ TFM_NV_COUNTERS_AREA_SIZE);
+ if (err != ARM_DRIVER_OK) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ if (value != nv_counters.counters[counter_id]) {
+
+ if (value > nv_counters.counters[counter_id]) {
+ nv_counters.counters[counter_id] = value;
+ } else {
+ return TFM_PLAT_ERR_INVALID_INPUT;
+ }
+
+#ifdef TFM_NV_COUNTERS_BACKUP_AREA_ADDR
+ /* Erase backup sector before write in it */
+ err = NV_COUNTERS_FLASH_DEV_NAME.EraseSector(
+ TFM_NV_COUNTERS_BACKUP_SECTOR_ADDR);
+ if (err != ARM_DRIVER_OK) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ /* Write in flash the in-memory NV counter content after modification to the backup sector */
+ err = NV_COUNTERS_FLASH_DEV_NAME.ProgramData(TFM_NV_COUNTERS_BACKUP_AREA_ADDR,
+ &nv_counters,
+ TFM_NV_COUNTERS_AREA_SIZE);
+ if (err != ARM_DRIVER_OK) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+#endif
+
+ /* Erase main sector before write in it */
+ err = NV_COUNTERS_FLASH_DEV_NAME.EraseSector(
+ TFM_NV_COUNTERS_SECTOR_ADDR);
+ if (err != ARM_DRIVER_OK) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ /* Write in flash the in-memory NV counter content after modification to the main sector */
+ err = NV_COUNTERS_FLASH_DEV_NAME.ProgramData(TFM_NV_COUNTERS_AREA_ADDR,
+ &nv_counters,
+ TFM_NV_COUNTERS_AREA_SIZE);
+ if (err != ARM_DRIVER_OK) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+ }
+
+ return TFM_PLAT_ERR_SUCCESS;
+}
+
+enum tfm_plat_err_t tfm_plat_increment_nv_counter(
+ enum tfm_nv_counter_t counter_id)
+{
+ uint32_t security_cnt;
+ enum tfm_plat_err_t err;
+
+ err = tfm_plat_read_nv_counter(counter_id,
+ sizeof(security_cnt),
+ (uint8_t *)&security_cnt);
+ if (err != TFM_PLAT_ERR_SUCCESS) {
+ return err;
+ }
+
+ if (security_cnt == UINT32_MAX) {
+ return TFM_PLAT_ERR_MAX_VALUE;
+ }
+
+ return tfm_plat_set_nv_counter(counter_id, security_cnt + 1u);
+}
diff --git a/platform/ext/target/lairdconnectivity/common/core/plat_test.c b/platform/ext/target/lairdconnectivity/common/core/plat_test.c
new file mode 100644
index 000000000..99a1a47bb
--- /dev/null
+++ b/platform/ext/target/lairdconnectivity/common/core/plat_test.c
@@ -0,0 +1,369 @@
+/*
+ * Copyright (c) 2020 Nordic Semiconductor ASA. All rights reserved.
+ * Copyright (c) 2021 Laird Connectivity. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string.h>
+#include "tfm_plat_test.h"
+#include <stdint.h>
+#include <stdbool.h>
+#include <hal/nrf_gpio.h>
+#include <hal/nrf_timer.h>
+#include <helpers/nrfx_reset_reason.h>
+#include <hal/nrf_twim.h>
+#include <drivers/include/nrfx_twim.h>
+#include <drivers/include/nrfx_twi_twim.h>
+#include <lcz_board.h>
+#include <tfm_platform_api.h>
+#include <log/tfm_log.h>
+
+#ifndef RTE_TWIM2
+#error "RTE_TWIM2 must be defined to enable use of the I2C (TWI) GPIO port expander"
+#endif
+
+#define TIMER_RELOAD_VALUE (1*1000*1000)
+
+/* Area used by psa-arch-tests to keep state. */
+#define PSA_TEST_SCRATCH_AREA_SIZE (0x400)
+
+/* Port expander defines */
+#define TCA9538_REG_INPUT (0x00)
+#define TCA9538_REG_OUTPUT (0x01)
+#define TCA9538_REG_CONFIG (0x03)
+#define TCA9538_DEFAULT_OUTPUT (0xff)
+#define TWI_BUFFER_SIZE (2)
+
+static bool initialized = false;
+
+static const nrfx_twim_t TWIM0 = NRFX_TWIM_INSTANCE(TWI_INSTANCE_NUMBER);
+static const nrfx_twim_config_t TWIMConfig = {
+ .scl = RTE_TWIM2_SCL_PIN,
+ .sda = RTE_TWIM2_SDA_PIN,
+ .frequency = TWI_FREQUENCY
+};
+
+static nrfx_twim_xfer_desc_t TWIData = {
+ .address = PORT_EXPANDER_I2C_ADDRESS,
+};
+
+static uint8_t TWIBuffer[TWI_BUFFER_SIZE];
+
+static void gpio_init(void)
+{
+ nrfx_err_t err;
+
+ /* Configure I2C (TWI) port */
+ err = nrfx_twim_init(&TWIM0, &TWIMConfig, NULL, NULL);
+
+ if (err != NRFX_SUCCESS)
+ {
+ LOG_MSG("I2C (TWIM) init failed %d", err);
+ return;
+ }
+
+ nrfx_twim_enable(&TWIM0);
+
+ /* Configure IO pins on port expander */
+ TWIData.type = NRFX_TWIM_XFER_TX;
+ TWIData.p_primary_buf = TWIBuffer;
+ TWIData.primary_length = 2;
+ TWIBuffer[0] = TCA9538_REG_CONFIG;
+ TWIBuffer[1] = PORT_EXPANDER_IO_CONFIG;
+ TWIData.p_secondary_buf = NULL;
+ TWIData.secondary_length = 0;
+
+ err = nrfx_twim_xfer(&TWIM0, &TWIData, 0);
+
+ if (err != NRFX_SUCCESS)
+ {
+ LOG_MSG("I2C (TWIM) transfer failed %d", err);
+ return;
+ }
+
+ /* Configure port expander interrupt pin */
+ nrf_gpio_cfg_input(PORT_EXPANDER_INTERRUPT_PIN, PORT_EXPANDER_INTERRUPT_PULL);
+
+ initialized = true;
+}
+
+void tfm_plat_test_wait_user_button_pressed(void)
+{
+ nrfx_err_t err;
+
+ if (!initialized) gpio_init();
+
+ /* Wait until button is pressed */
+ while (1)
+ {
+ /* Wait for port expander interrupt pint to be asserted */
+ while (nrf_gpio_pin_read(PORT_EXPANDER_INTERRUPT_PIN) != PORT_EXPANDER_INTERRUPT_ACTIVE_LEVEL) { ; }
+
+ /* Read the state of the IOs from the port expander */
+ TWIData.type = NRFX_TWIM_XFER_TX;
+ TWIData.p_primary_buf = TWIBuffer;
+ TWIData.primary_length = 1;
+ TWIBuffer[0] = TCA9538_REG_INPUT;
+ TWIData.p_secondary_buf = NULL;
+ TWIData.secondary_length = 0;
+
+ err = nrfx_twim_xfer(&TWIM0, &TWIData, NRFX_TWIM_FLAG_TX_NO_STOP);
+
+ if (err != NRFX_SUCCESS)
+ {
+ LOG_MSG("I2C (TWIM) transfer failed %d", err);
+ return;
+ }
+
+ TWIData.type = NRFX_TWIM_XFER_RX;
+ TWIData.p_primary_buf = TWIBuffer;
+ TWIData.primary_length = 1;
+ TWIBuffer[0] = 0;
+ TWIData.p_secondary_buf = NULL;
+ TWIData.secondary_length = 0;
+
+ err = nrfx_twim_xfer(&TWIM0, &TWIData, 0);
+
+ if (err != NRFX_SUCCESS)
+ {
+ LOG_MSG("I2C (TWIM) transfer failed %d", err);
+ return;
+ }
+
+ if ((TWIBuffer[0] & PORT_EXPANDER_BUTTON1_IO) == PORT_EXPANDER_BUTTON1_ACTIVE_LEVEL)
+ {
+ /* Button has been pressed, break from loop */
+ break;
+ }
+ }
+}
+
+void tfm_plat_test_wait_user_button_released(void)
+{
+ nrfx_err_t err;
+
+ if (!initialized) gpio_init();
+
+ /* Wait until button is released */
+ while (1)
+ {
+ while (nrf_gpio_pin_read(PORT_EXPANDER_INTERRUPT_PIN) != PORT_EXPANDER_INTERRUPT_ACTIVE_LEVEL) { ; }
+
+ /* Read the state of the IOs from the port expander */
+ TWIData.type = NRFX_TWIM_XFER_TX;
+ TWIData.p_primary_buf = TWIBuffer;
+ TWIData.primary_length = 1;
+ TWIBuffer[0] = TCA9538_REG_INPUT;
+ TWIData.p_secondary_buf = NULL;
+ TWIData.secondary_length = 0;
+
+ err = nrfx_twim_xfer(&TWIM0, &TWIData, NRFX_TWIM_FLAG_TX_NO_STOP);
+
+ if (err != NRFX_SUCCESS)
+ {
+ LOG_MSG("I2C (TWIM) transfer failed %d", err);
+ return;
+ }
+
+ TWIData.type = NRFX_TWIM_XFER_RX;
+ TWIData.p_primary_buf = TWIBuffer;
+ TWIData.primary_length = 1;
+ TWIBuffer[0] = 0;
+ TWIData.p_secondary_buf = NULL;
+ TWIData.secondary_length = 0;
+
+ err = nrfx_twim_xfer(&TWIM0, &TWIData, 0);
+
+ if (err != NRFX_SUCCESS)
+ {
+ LOG_MSG("I2C (TWIM) transfer failed %d", err);
+ return;
+ }
+
+ if ((TWIBuffer[0] & PORT_EXPANDER_BUTTON1_IO) != PORT_EXPANDER_BUTTON1_ACTIVE_LEVEL)
+ {
+ break;
+ }
+ }
+}
+
+uint32_t tfm_plat_test_get_led_status(void)
+{
+ nrfx_err_t err;
+
+ if (!initialized) gpio_init();
+
+ /* Read the state of the IOs from the port expander */
+ TWIData.type = NRFX_TWIM_XFER_TX;
+ TWIData.p_primary_buf = TWIBuffer;
+ TWIData.primary_length = 1;
+ TWIBuffer[0] = TCA9538_REG_INPUT;
+ TWIData.p_secondary_buf = NULL;
+ TWIData.secondary_length = 0;
+
+ err = nrfx_twim_xfer(&TWIM0, &TWIData, NRFX_TWIM_FLAG_TX_NO_STOP);
+
+ if (err != NRFX_SUCCESS)
+ {
+ LOG_MSG("I2C (TWIM) transfer failed %d", err);
+ return;
+ }
+
+ TWIData.type = NRFX_TWIM_XFER_RX;
+ TWIData.p_primary_buf = TWIBuffer;
+ TWIData.primary_length = 1;
+ TWIBuffer[0] = 0;
+ TWIData.p_secondary_buf = NULL;
+ TWIData.secondary_length = 0;
+
+ err = nrfx_twim_xfer(&TWIM0, &TWIData, 0);
+
+ if (err != NRFX_SUCCESS)
+ {
+ LOG_MSG("I2C (TWIM) transfer failed %d", err);
+ return;
+ }
+
+ return ((TWIBuffer[0] & PORT_EXPANDER_LED1_IO) == PORT_EXPANDER_LED1_ACTIVE_LEVEL);
+}
+
+void tfm_plat_test_set_led_status(uint32_t status)
+{
+ nrfx_err_t err;
+
+ if (!initialized) gpio_init();
+
+ /* Change output state on port expander */
+ TWIData.type = NRFX_TWIM_XFER_TX;
+ TWIData.p_primary_buf = TWIBuffer;
+ TWIData.primary_length = 2;
+ TWIBuffer[0] = TCA9538_REG_OUTPUT;
+ if (status == 0)
+ {
+ /* Turn LED off */
+ TWIBuffer[1] = TCA9538_DEFAULT_OUTPUT;
+ }
+ else
+ {
+ /* Turn LED on */
+ TWIBuffer[1] = (TCA9538_DEFAULT_OUTPUT & (~PORT_EXPANDER_LED1_IO));
+ }
+ TWIData.p_secondary_buf = NULL;
+ TWIData.secondary_length = 0;
+
+ err = nrfx_twim_xfer(&TWIM0, &TWIData, 0);
+
+ if (err != NRFX_SUCCESS)
+ {
+ LOG_MSG("I2C (TWIM) transfer failed %d", err);
+ return;
+ }
+}
+
+uint32_t tfm_plat_test_get_userled_mask(void)
+{
+#warning "check this"
+ return PORT_EXPANDER_LED1_IO;
+}
+
+static void timer_init(NRF_TIMER_Type * TIMER, uint32_t ticks)
+{
+ nrf_timer_mode_set(TIMER, NRF_TIMER_MODE_TIMER);
+ nrf_timer_bit_width_set(TIMER, NRF_TIMER_BIT_WIDTH_32);
+ nrf_timer_frequency_set(TIMER, NRF_TIMER_FREQ_1MHz);
+ nrf_timer_cc_set(TIMER, NRF_TIMER_CC_CHANNEL0, ticks);
+ nrf_timer_one_shot_enable(TIMER, NRF_TIMER_CC_CHANNEL0);
+}
+
+static void timer_stop(NRF_TIMER_Type * TIMER)
+{
+ nrf_timer_task_trigger(TIMER, NRF_TIMER_TASK_STOP);
+ nrf_timer_int_disable(TIMER, NRF_TIMER_INT_COMPARE0_MASK);
+ nrf_timer_event_clear(TIMER, NRF_TIMER_EVENT_COMPARE0);
+}
+
+static void timer_start(NRF_TIMER_Type * TIMER)
+{
+ timer_stop(TIMER);
+
+ nrf_timer_task_trigger(TIMER, NRF_TIMER_TASK_CLEAR);
+ nrf_timer_int_enable(TIMER, NRF_TIMER_INT_COMPARE0_MASK);
+
+ nrf_timer_task_trigger(TIMER, NRF_TIMER_TASK_START);
+}
+
+void tfm_plat_test_secure_timer_start(void)
+{
+ timer_init(NRF_TIMER0, TIMER_RELOAD_VALUE);
+ timer_start(NRF_TIMER0);
+}
+
+void tfm_plat_test_secure_timer_stop(void)
+{
+ timer_stop(NRF_TIMER0);
+}
+
+void tfm_plat_test_non_secure_timer_start(void)
+{
+ timer_init(NRF_TIMER1, TIMER_RELOAD_VALUE);
+ timer_start(NRF_TIMER1);
+}
+
+void tfm_plat_test_non_secure_timer_stop(void)
+{
+ timer_stop(NRF_TIMER1);
+}
+
+void pal_timer_init_ns(uint32_t ticks)
+{
+ timer_init(NRF_TIMER1, ticks);
+ NVIC_EnableIRQ(TIMER1_IRQn);
+}
+
+void pal_timer_start_ns(void)
+{
+ timer_start(NRF_TIMER1);
+}
+
+void pal_timer_stop_ns(void)
+{
+ timer_stop(NRF_TIMER1);
+}
+
+#if !defined(TFM_ENABLE_IRQ_TEST)
+/* Watchdog timeout handler. */
+void TIMER1_Handler(void)
+{
+ pal_timer_stop_ns();
+ int ret = tfm_platform_system_reset();
+ if (ret) {
+ LOG_MSG("Reset failed: %d\n", ret);
+ }
+}
+#endif
+
+uint32_t pal_nvmem_get_addr(void)
+{
+ static bool psa_scratch_initialized = false;
+ static __ALIGN(4) uint8_t __psa_scratch[PSA_TEST_SCRATCH_AREA_SIZE];
+
+ if (!psa_scratch_initialized && (nrfx_reset_reason_get() == 0)) {
+ /* PSA API tests expect this area to be initialized to all 0xFFs after a
+ * power-on reset.
+ */
+ memset(__psa_scratch, 0xFF, PSA_TEST_SCRATCH_AREA_SIZE);
+ }
+ psa_scratch_initialized = true;
+ return (uint32_t)__psa_scratch;
+}
diff --git a/platform/ext/target/nordic_nrf/common/core/gcc/nordic_nrf_s.ld b/platform/ext/target/nordic_nrf/common/core/gcc/nordic_nrf_s.ld
index a9da1ad59..a8e10836a 100644
--- a/platform/ext/target/nordic_nrf/common/core/gcc/nordic_nrf_s.ld
+++ b/platform/ext/target/nordic_nrf/common/core/gcc/nordic_nrf_s.ld
@@ -33,10 +33,8 @@ MEMORY
#if defined(PSA_PROXY_SHARED_MEMORY_BASE)
PSA_PROXY_SHARED_MEMORY_RAM (rw) : ORIGIN = PSA_PROXY_SHARED_MEMORY_BASE, LENGTH = PSA_PROXY_SHARED_MEMORY_SIZE
#endif
-
}
-
#ifdef TFM_MULTI_CORE_TOPOLOGY
#define VENEERS()
#else
@@ -162,7 +160,7 @@ SECTIONS
*psa_client.*(.rodata*)
*psa_service.*(.text*) /* NXP */
*psa_service.*(.rodata*)
- *psa_lifecycle.*(.text*) /* NXP */
+ *psa_lifecycle.*(.text*) /* NXP */
*psa_lifecycle.*(.rodata*)
*tfm_log_raw.*(.text*) /* NXP */
*tfm_log_raw.*(.rodata*)
diff --git a/platform/ext/target/nordic_nrf/common/core/nrfx/drivers/include/nrfx_qspi.h b/platform/ext/target/nordic_nrf/common/core/nrfx/drivers/include/nrfx_qspi.h
new file mode 100644
index 000000000..fb48d0dd8
--- /dev/null
+++ b/platform/ext/target/nordic_nrf/common/core/nrfx/drivers/include/nrfx_qspi.h
@@ -0,0 +1,368 @@
+/*
+ * Copyright (c) 2016 - 2020, 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 the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef NRFX_QSPI_H__
+#define NRFX_QSPI_H__
+
+#include <nrfx.h>
+#include <hal/nrf_qspi.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup nrfx_qspi QSPI driver
+ * @{
+ * @ingroup nrf_qspi
+ * @brief Quad Serial Peripheral Interface (QSPI) peripheral driver.
+ */
+
+/** @brief QSPI driver instance configuration structure. */
+typedef struct
+{
+ uint32_t xip_offset; /**< Address offset into the external memory for Execute in Place operation. */
+ nrf_qspi_pins_t pins; /**< Pin configuration structure. */
+ nrf_qspi_prot_conf_t prot_if; /**< Protocol layer interface configuration structure. */
+ nrf_qspi_phy_conf_t phy_if; /**< Physical layer interface configuration structure. */
+ uint8_t irq_priority; /**< Interrupt priority. */
+} nrfx_qspi_config_t;
+
+/**
+ * @brief QSPI instance default configuration.
+ *
+ * This configuration sets up QSPI with the following options:
+ * - no offset for address in the external memory for Execute in Place operation
+ * - single data line
+ * - FAST_READ opcode for reading
+ * - PP opcode for writing
+ * - 24 bit addressing mode
+ * - Deep Power-down disabled
+ * - clock frequency: 2 MHz for nRF52 Series, 6 MHz for nRF53 Series
+ * - SCK delay 5 clock ticks
+ * - mode 0 (data captured on the clock rising edge and transmitted on a falling edge. Clock base level is '0')
+ *
+ * @param[in] _pin_sck Pin for clock signal.
+ * @param[in] _pin_csn Pin for chip select signal.
+ * @param[in] _pin_io0 Pin 0 for I/O data.
+ * @param[in] _pin_io1 Pin 1 for I/O data.
+ * @param[in] _pin_io2 Pin 2 for I/O data.
+ * @param[in] _pin_io3 Pin 3 for I/O data.
+ */
+#define NRFX_QSPI_DEFAULT_CONFIG(_pin_sck, _pin_csn, _pin_io0, \
+ _pin_io1, _pin_io2, _pin_io3) \
+{ \
+ .xip_offset = 0, \
+ .pins = { \
+ .sck_pin = _pin_sck, \
+ .csn_pin = _pin_csn, \
+ .io0_pin = _pin_io0, \
+ .io1_pin = _pin_io1, \
+ .io2_pin = _pin_io2, \
+ .io3_pin = _pin_io3 \
+ }, \
+ .prot_if = { \
+ .readoc = NRF_QSPI_READOC_FASTREAD, \
+ .writeoc = NRF_QSPI_WRITEOC_PP, \
+ .addrmode = NRF_QSPI_ADDRMODE_24BIT, \
+ .dpmconfig = false, \
+ }, \
+ .phy_if = { \
+ .sck_delay = 0x05, \
+ .dpmen = false, \
+ .spi_mode = NRF_QSPI_MODE_0, \
+ .sck_freq = NRF_QSPI_FREQ_DIV16, \
+ }, \
+ .irq_priority = (uint8_t)NRFX_QSPI_DEFAULT_CONFIG_IRQ_PRIORITY, \
+}
+
+/** @brief QSPI custom instruction helper with the default configuration. */
+#define NRFX_QSPI_DEFAULT_CINSTR(opc, len) \
+{ \
+ .opcode = (opc), \
+ .length = (len), \
+ .io2_level = false, \
+ .io3_level = false, \
+ .wipwait = false, \
+ .wren = false \
+}
+
+/**
+ * @brief QSPI master driver event types, passed to the handler routine provided
+ * during initialization.
+ */
+typedef enum
+{
+ NRFX_QSPI_EVENT_DONE, /**< Transfer done. */
+} nrfx_qspi_evt_t;
+
+/** @brief QSPI driver event handler type. */
+typedef void (*nrfx_qspi_handler_t)(nrfx_qspi_evt_t event, void * p_context);
+
+/**
+ * @brief Function for initializing the QSPI driver instance.
+ *
+ * This function configures the peripheral and its interrupts, and activates it. During the
+ * activation process, the internal clocks are started and the QSPI peripheral tries to read
+ * the status byte to read the busy bit. Reading the status byte is done in a simple poll and wait
+ * mechanism.
+ * If the busy bit is 1, this indicates issues with the external memory device. As a result,
+ * @ref nrfx_qspi_init returns NRFX_ERROR_TIMEOUT.
+ *
+ * In case of issues:
+ * - Check the connection.
+ * - Make sure that the memory device does not perform other operations like erasing or writing.
+ * - Check if there is a short circuit.
+ *
+ * @param[in] p_config Pointer to the structure with the initial configuration.
+ * @param[in] handler Event handler provided by the user. If NULL, transfers
+ * will be performed in blocking mode.
+ * @param[in] p_context Pointer to context. Use in the interrupt handler.
+ *
+ * @retval NRFX_SUCCESS Initialization was successful.
+ * @retval NRFX_ERROR_TIMEOUT The peripheral cannot connect with external memory.
+ * @retval NRFX_ERROR_INVALID_STATE The driver was already initialized.
+ * @retval NRFX_ERROR_INVALID_PARAM The pin configuration was incorrect.
+ */
+nrfx_err_t nrfx_qspi_init(nrfx_qspi_config_t const * p_config,
+ nrfx_qspi_handler_t handler,
+ void * p_context);
+
+/** @brief Function for uninitializing the QSPI driver instance. */
+void nrfx_qspi_uninit(void);
+
+/**
+ * @brief Function for reading data from the QSPI memory.
+ *
+ * Write, read, and erase operations check memory device busy state before starting the operation.
+ * If the memory is busy, the resulting action depends on the mode in which the read operation is used:
+ * - blocking mode (without handler) - a delay occurs until the last operation runs and
+ * until the operation data is being read.
+ * - interrupt mode (with handler) - event emission occurs after the last operation
+ * and reading of data are finished.
+ *
+ * @param[out] p_rx_buffer Pointer to the receive buffer.
+ * @param[in] rx_buffer_length Size of the data to read.
+ * @param[in] src_address Address in memory to read from.
+ *
+ * @retval NRFX_SUCCESS The operation was successful (blocking mode) or operation
+ * was commissioned (handler mode).
+ * @retval NRFX_ERROR_BUSY The driver currently handles another operation.
+ * @retval NRFX_ERROR_INVALID_ADDR The provided buffer is not placed in the Data RAM region
+ * or its address is not aligned to a 32-bit word.
+ */
+nrfx_err_t nrfx_qspi_read(void * p_rx_buffer,
+ size_t rx_buffer_length,
+ uint32_t src_address);
+
+/**
+ * @brief Function for writing data to QSPI memory.
+ *
+ * Write, read, and erase operations check memory device busy state before starting the operation.
+ * If the memory is busy, the resulting action depends on the mode in which the write operation is used:
+ * - blocking mode (without handler) - a delay occurs until the last operation runs or
+ * until the operation data is being sent.
+ * - interrupt mode (with handler) - event emission occurs after the last operation
+ * and sending of operation data are finished.
+ * To manually control operation execution in the memory device, use @ref nrfx_qspi_mem_busy_check
+ * after executing the write function.
+ * Remember that an incoming event signalizes only that data was sent to the memory device and the periheral
+ * before the write operation checked if memory was busy.
+ *
+ * @param[in] p_tx_buffer Pointer to the writing buffer.
+ * @param[in] tx_buffer_length Size of the data to write.
+ * @param[in] dst_address Address in memory to write to.
+ *
+ * @retval NRFX_SUCCESS The operation was successful (blocking mode) or operation
+ * was commissioned (handler mode).
+ * @retval NRFX_ERROR_BUSY The driver currently handles other operation.
+ * @retval NRFX_ERROR_INVALID_ADDR The provided buffer is not placed in the Data RAM region
+ * or its address is not aligned to a 32-bit word.
+ */
+nrfx_err_t nrfx_qspi_write(void const * p_tx_buffer,
+ size_t tx_buffer_length,
+ uint32_t dst_address);
+
+/**
+ * @brief Function for starting erasing of one memory block - 4KB, 64KB, or the whole chip.
+ *
+ * Write, read, and erase operations check memory device busy state before starting the operation.
+ * If the memory is busy, the resulting action depends on the mode in which the erase operation is used:
+ * - blocking mode (without handler) - a delay occurs until the last operation runs or
+ * until the operation data is being sent.
+ * - interrupt mode (with handler) - event emission occurs after the last operation
+ * and sending of operation data are finished.
+ * To manually control operation execution in the memory device, use @ref nrfx_qspi_mem_busy_check
+ * after executing the erase function.
+ * Remember that an incoming event signalizes only that data was sent to the memory device and the periheral
+ * before the erase operation checked if memory was busy.
+ *
+ * @param[in] length Size of data to erase. See @ref nrf_qspi_erase_len_t.
+ * @param[in] start_address Memory address to start erasing. If chip erase is performed, address
+ * field is ommited.
+ *
+ * @retval NRFX_SUCCESS The operation was successful (blocking mode) or operation
+ * was commissioned (handler mode).
+ * @retval NRFX_ERROR_INVALID_ADDR The provided start address is not aligned to a 32-bit word.
+ * @retval NRFX_ERROR_BUSY The driver currently handles another operation.
+ */
+nrfx_err_t nrfx_qspi_erase(nrf_qspi_erase_len_t length,
+ uint32_t start_address);
+
+/**
+ * @brief Function for starting an erase operation of the whole chip.
+ *
+ * @retval NRFX_SUCCESS The operation was successful (blocking mode) or operation
+ * was commissioned (handler mode).
+ * @retval NRFX_ERROR_BUSY The driver currently handles another operation.
+ */
+nrfx_err_t nrfx_qspi_chip_erase(void);
+
+/**
+ * @brief Function for getting the current driver status and status byte of memory device with
+ * testing WIP (write in progress) bit.
+ *
+ * @retval NRFX_SUCCESS The driver and memory are ready to handle a new operation.
+ * @retval NRFX_ERROR_BUSY The driver or memory currently handle another operation.
+ */
+nrfx_err_t nrfx_qspi_mem_busy_check(void);
+
+/**
+ * @brief Function for sending operation code, sending data, and receiving data from the memory device.
+ *
+ * Use this function to transfer configuration data to memory and to receive data from memory.
+ * Pointers can be addresses from flash memory.
+ * This function is a synchronous function and should be used only if necessary.
+ *
+ * @param[in] p_config Pointer to the structure with opcode and transfer configuration.
+ * @param[in] p_tx_buffer Pointer to the array with data to send. Can be NULL if only opcode is transmitted.
+ * @param[out] p_rx_buffer Pointer to the array for data to receive. Can be NULL if there is nothing to receive.
+ *
+ * @retval NRFX_SUCCESS The operation was successful.
+ * @retval NRFX_ERROR_TIMEOUT The external memory is busy or there are connection issues.
+ * @retval NRFX_ERROR_BUSY The driver currently handles other operation.
+ */
+nrfx_err_t nrfx_qspi_cinstr_xfer(nrf_qspi_cinstr_conf_t const * p_config,
+ void const * p_tx_buffer,
+ void * p_rx_buffer);
+
+/**
+ * @brief Function for sending operation code and data to the memory device with simpler configuration.
+ *
+ * Use this function to transfer configuration data to memory and to receive data from memory.
+ * This function is a synchronous function and should be used only if necessary.
+ *
+ * @param[in] opcode Operation code. Sending first.
+ * @param[in] length Length of the data to send and opcode. See @ref nrf_qspi_cinstr_len_t.
+ * @param[in] p_tx_buffer Pointer to input data array.
+ *
+ * @retval NRFX_SUCCESS The operation was successful.
+ * @retval NRFX_ERROR_BUSY The driver currently handles another operation.
+ */
+nrfx_err_t nrfx_qspi_cinstr_quick_send(uint8_t opcode,
+ nrf_qspi_cinstr_len_t length,
+ void const * p_tx_buffer);
+
+/**
+ * @brief Function for starting the custom instruction long frame mode.
+ *
+ * The long frame mode is a mechanism that allows for arbitrary byte length custom instructions.
+ * Use this function to initiate a custom transaction by sending custom instruction opcode.
+ * To send and receive data, use @ref nrfx_qspi_lfm_xfer.
+ *
+ * @param[in] p_config Pointer to the structure with custom instruction opcode and transfer
+ * configuration. Transfer length must be set to @ref NRF_QSPI_CINSTR_LEN_1B.
+ *
+ * @retval NRFX_SUCCESS Operation was successful.
+ * @retval NRFX_ERROR_BUSY Driver currently handles other operation.
+ * @retval NRFX_ERROR_TIMEOUT External memory is busy or there are connection issues.
+ */
+nrfx_err_t nrfx_qspi_lfm_start(nrf_qspi_cinstr_conf_t const * p_config);
+
+/**
+ * @brief Function for sending and receiving data in the custom instruction long frame mode.
+ *
+ * Both specified buffers must be at least @p transfer_length bytes in size.
+ *
+ * @param[in] p_tx_buffer Pointer to the array with data to send.
+ * Can be NULL if there is nothing to send.
+ * @param[out] p_rx_buffer Pointer to the array for receiving data.
+ * Can be NULL if there is nothing to receive.
+ * @param[in] transfer_length Number of bytes to send and receive.
+ * @param[in] finalize True if custom instruction long frame mode is to be finalized
+ * after this transfer.
+ *
+ * @retval NRFX_SUCCESS Operation was successful.
+ * @retval NRFX_ERROR_TIMEOUT External memory is busy or there are connection issues.
+ * Long frame mode becomes deactivated.
+ */
+nrfx_err_t nrfx_qspi_lfm_xfer(void const * p_tx_buffer,
+ void * p_rx_buffer,
+ size_t transfer_length,
+ bool finalize);
+
+#if NRF_QSPI_HAS_XIP_ENC
+/**
+ * @brief Function for setting the XIP encryption.
+ *
+ * @param[in] p_config XIP encryption configuration structure.
+ * To disable encryption, pass NULL pointer as argument.
+ *
+ * @retval NRFX_SUCCESS Operation was successful.
+ * @retval NRFX_ERROR_BUSY Driver currently handles other operation.
+ */
+nrfx_err_t nrfx_qspi_xip_encrypt(nrf_qspi_encryption_t const * p_config);
+#endif
+
+#if NRF_QSPI_HAS_DMA_ENC
+/**
+ * @brief Function for setting the EasyDMA encryption.
+ *
+ * @param[in] p_config DMA encryption configuration structure.
+ * To disable encryption, pass NULL pointer as argument.
+ *
+ * @retval NRFX_SUCCESS Operation was successful.
+ * @retval NRFX_ERROR_BUSY Driver currently handles other operation.
+ */
+nrfx_err_t nrfx_qspi_dma_encrypt(nrf_qspi_encryption_t const * p_config);
+#endif
+
+/** @} */
+
+
+void nrfx_qspi_irq_handler(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRFX_QSPI_H__
diff --git a/platform/ext/target/nordic_nrf/common/core/nrfx/drivers/include/nrfx_twi_twim.h b/platform/ext/target/nordic_nrf/common/core/nrfx/drivers/include/nrfx_twi_twim.h
new file mode 100644
index 000000000..1f62c62d5
--- /dev/null
+++ b/platform/ext/target/nordic_nrf/common/core/nrfx/drivers/include/nrfx_twi_twim.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2019 - 2020, 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 the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef NRFX_TWI_TWIM_H
+#define NRFX_TWI_TWIM_H
+
+#include <nrfx.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+nrfx_err_t nrfx_twi_twim_bus_recover(uint32_t scl_pin, uint32_t sda_pin);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRFX_TWI_TWIM_H
diff --git a/platform/ext/target/nordic_nrf/common/core/nrfx/drivers/include/nrfx_twim.h b/platform/ext/target/nordic_nrf/common/core/nrfx/drivers/include/nrfx_twim.h
new file mode 100644
index 000000000..94ba0802b
--- /dev/null
+++ b/platform/ext/target/nordic_nrf/common/core/nrfx/drivers/include/nrfx_twim.h
@@ -0,0 +1,384 @@
+/*
+ * Copyright (c) 2015 - 2020, 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 the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef NRFX_TWIM_H__
+#define NRFX_TWIM_H__
+
+#include <nrfx.h>
+#include <nrfx_twi_twim.h>
+#include <hal/nrf_twim.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup nrfx_twim TWIM driver
+ * @{
+ * @ingroup nrf_twim
+ * @brief Two Wire Interface Master with EasyDMA (TWIM) peripheral driver.
+ */
+
+/** @brief Structure for the TWI master driver instance. */
+typedef struct
+{
+ NRF_TWIM_Type * p_twim; ///< Pointer to a structure with TWIM registers.
+ uint8_t drv_inst_idx; ///< Index of the driver instance. For internal use only.
+} nrfx_twim_t;
+
+/** @brief Macro for creating a TWI master driver instance. */
+#define NRFX_TWIM_INSTANCE(id) \
+{ \
+ .p_twim = NRFX_CONCAT_2(NRF_TWIM, id), \
+ .drv_inst_idx = NRFX_CONCAT_3(NRFX_TWIM, id, _INST_IDX), \
+}
+
+#ifndef __NRFX_DOXYGEN__
+enum {
+#if NRFX_CHECK(NRFX_TWIM0_ENABLED)
+ NRFX_TWIM0_INST_IDX,
+#endif
+#if NRFX_CHECK(NRFX_TWIM1_ENABLED)
+ NRFX_TWIM1_INST_IDX,
+#endif
+#if NRFX_CHECK(NRFX_TWIM2_ENABLED)
+ NRFX_TWIM2_INST_IDX,
+#endif
+#if NRFX_CHECK(NRFX_TWIM3_ENABLED)
+ NRFX_TWIM3_INST_IDX,
+#endif
+ NRFX_TWIM_ENABLED_COUNT
+};
+#endif
+
+/** @brief Structure for the TWI master driver instance configuration. */
+typedef struct
+{
+ uint32_t scl; ///< SCL pin number.
+ uint32_t sda; ///< SDA pin number.
+ nrf_twim_frequency_t frequency; ///< TWIM frequency.
+ uint8_t interrupt_priority; ///< Interrupt priority.
+ bool hold_bus_uninit; ///< Hold pull up state on GPIO pins after uninit.
+} nrfx_twim_config_t;
+
+/**
+ * @brief TWIM driver default configuration.
+ *
+ * This configuration sets up TWIM with the following options:
+ * - clock frequency: 100 kHz
+ * - disable bus holding after uninit
+ *
+ * @param[in] _pin_scl SCL pin.
+ * @param[in] _pin_sda SDA pin.
+ */
+#define NRFX_TWIM_DEFAULT_CONFIG(_pin_scl, _pin_sda) \
+{ \
+ .scl = _pin_scl, \
+ .sda = _pin_sda, \
+ .frequency = NRF_TWIM_FREQ_100K, \
+ .interrupt_priority = NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY, \
+ .hold_bus_uninit = false, \
+}
+
+/** @brief Flag indicating that TX buffer address will be incremented after the transfer. */
+#define NRFX_TWIM_FLAG_TX_POSTINC (1UL << 0)
+/** @brief Flag indicating that RX buffer address will be incremented after the transfer. */
+#define NRFX_TWIM_FLAG_RX_POSTINC (1UL << 1)
+/** @brief Flag indicating that the interrupt after each transfer will be suppressed, and the event handler will not be called. */
+#define NRFX_TWIM_FLAG_NO_XFER_EVT_HANDLER (1UL << 2)
+/** @brief Flag indicating that the transfer will be set up, but not started. */
+#define NRFX_TWIM_FLAG_HOLD_XFER (1UL << 3)
+/** @brief Flag indicating that the transfer will be executed multiple times. */
+#define NRFX_TWIM_FLAG_REPEATED_XFER (1UL << 4)
+/** @brief Flag indicating that the TX transfer will not end with a stop condition. */
+#define NRFX_TWIM_FLAG_TX_NO_STOP (1UL << 5)
+/** @brief Flag indicating that checks for spurious STOP condition will not be performed. */
+#define NRFX_TWIM_FLAG_NO_SPURIOUS_STOP_CHECK (1UL << 6)
+
+/** @brief TWI master driver event types. */
+typedef enum
+{
+ NRFX_TWIM_EVT_DONE, ///< Transfer completed event.
+ NRFX_TWIM_EVT_ADDRESS_NACK, ///< Error event: NACK received after sending the address.
+ NRFX_TWIM_EVT_DATA_NACK, ///< Error event: NACK received after sending a data byte.
+ NRFX_TWIM_EVT_OVERRUN, ///< Error event: The unread data is replaced by new data.
+ NRFX_TWIM_EVT_BUS_ERROR ///< Error event: An unexpected transition occurred on the bus.
+} nrfx_twim_evt_type_t;
+
+/** @brief TWI master driver transfer types. */
+typedef enum
+{
+ NRFX_TWIM_XFER_TX, ///< TX transfer.
+ NRFX_TWIM_XFER_RX, ///< RX transfer.
+ NRFX_TWIM_XFER_TXRX, ///< TX transfer followed by RX transfer with repeated start.
+ NRFX_TWIM_XFER_TXTX ///< TX transfer followed by TX transfer with repeated start.
+} nrfx_twim_xfer_type_t;
+
+/** @brief Structure for a TWI transfer descriptor. */
+typedef struct
+{
+ nrfx_twim_xfer_type_t type; ///< Type of transfer.
+ uint8_t address; ///< Slave address.
+ size_t primary_length; ///< Number of bytes transferred.
+ size_t secondary_length; ///< Number of bytes transferred.
+ uint8_t * p_primary_buf; ///< Pointer to transferred data.
+ uint8_t * p_secondary_buf; ///< Pointer to transferred data.
+} nrfx_twim_xfer_desc_t;
+
+
+/** @brief Macro for setting the TX transfer descriptor. */
+#define NRFX_TWIM_XFER_DESC_TX(addr, p_data, length) \
+{ \
+ .type = NRFX_TWIM_XFER_TX, \
+ .address = (addr), \
+ .primary_length = (length), \
+ .secondary_length = 0, \
+ .p_primary_buf = (p_data), \
+ .p_secondary_buf = NULL, \
+}
+
+/** @brief Macro for setting the RX transfer descriptor. */
+#define NRFX_TWIM_XFER_DESC_RX(addr, p_data, length) \
+{ \
+ .type = NRFX_TWIM_XFER_RX, \
+ .address = (addr), \
+ .primary_length = (length), \
+ .secondary_length = 0, \
+ .p_primary_buf = (p_data), \
+ .p_secondary_buf = NULL, \
+}
+
+/** @brief Macro for setting the TX-RX transfer descriptor. */
+#define NRFX_TWIM_XFER_DESC_TXRX(addr, p_tx, tx_len, p_rx, rx_len) \
+{ \
+ .type = NRFX_TWIM_XFER_TXRX, \
+ .address = (addr), \
+ .primary_length = (tx_len), \
+ .secondary_length = (rx_len), \
+ .p_primary_buf = (p_tx), \
+ .p_secondary_buf = (p_rx), \
+}
+
+/** @brief Macro for setting the TX-TX transfer descriptor. */
+#define NRFX_TWIM_XFER_DESC_TXTX(addr, p_tx, tx_len, p_tx2, tx_len2) \
+{ \
+ .type = NRFX_TWIM_XFER_TXTX, \
+ .address = (addr), \
+ .primary_length = (tx_len), \
+ .secondary_length = (tx_len2), \
+ .p_primary_buf = (p_tx), \
+ .p_secondary_buf = (p_tx2), \
+}
+
+/** @brief Structure for a TWI event. */
+typedef struct
+{
+ nrfx_twim_evt_type_t type; ///< Event type.
+ nrfx_twim_xfer_desc_t xfer_desc; ///< Transfer details.
+} nrfx_twim_evt_t;
+
+/** @brief TWI event handler prototype. */
+typedef void (* nrfx_twim_evt_handler_t)(nrfx_twim_evt_t const * p_event,
+ void * p_context);
+
+/**
+ * @brief Function for initializing the TWI driver instance.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ * @param[in] p_config Pointer to the structure with the initial configuration.
+ * @param[in] event_handler Event handler provided by the user. If NULL, blocking mode is enabled.
+ * @param[in] p_context Context passed to event handler.
+ *
+ * @retval NRFX_SUCCESS Initialization was successful.
+ * @retval NRFX_ERROR_INVALID_STATE The driver is in invalid state.
+ * @retval NRFX_ERROR_BUSY Some other peripheral with the same
+ * instance ID is already in use. This is
+ * possible only if @ref nrfx_prs module
+ * is enabled.
+ */
+nrfx_err_t nrfx_twim_init(nrfx_twim_t const * p_instance,
+ nrfx_twim_config_t const * p_config,
+ nrfx_twim_evt_handler_t event_handler,
+ void * p_context);
+
+/**
+ * @brief Function for uninitializing the TWI instance.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ */
+void nrfx_twim_uninit(nrfx_twim_t const * p_instance);
+
+/**
+ * @brief Function for enabling the TWI instance.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ */
+void nrfx_twim_enable(nrfx_twim_t const * p_instance);
+
+/**
+ * @brief Function for disabling the TWI instance.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ */
+void nrfx_twim_disable(nrfx_twim_t const * p_instance);
+
+/**
+ * @brief Function for performing a TWI transfer.
+ *
+ * The following transfer types can be configured (@ref nrfx_twim_xfer_desc_t.type):
+ * - @ref NRFX_TWIM_XFER_TXRX - Write operation followed by a read operation (without STOP condition in between).
+ * - @ref NRFX_TWIM_XFER_TXTX - Write operation followed by a write operation (without STOP condition in between).
+ * - @ref NRFX_TWIM_XFER_TX - Write operation (with or without STOP condition).
+ * - @ref NRFX_TWIM_XFER_RX - Read operation (with STOP condition).
+ *
+ * @note TX-RX and TX-TX transfers are supported only in non-blocking mode.
+ *
+ * Additional options are provided using the flags parameter:
+ * - @ref NRFX_TWIM_FLAG_TX_POSTINC and @ref NRFX_TWIM_FLAG_RX_POSTINC - Post-incrementation of buffer addresses.
+ * - @ref NRFX_TWIM_FLAG_NO_XFER_EVT_HANDLER - No user event handler after the transfer completion. In most cases, this also means no interrupt at the end of the transfer.
+ * - @ref NRFX_TWIM_FLAG_HOLD_XFER - Driver is not starting the transfer. Use this flag if the transfer is triggered externally by PPI.
+ * Use @ref nrfx_twim_start_task_get to get the address of the start task.
+ * - @ref NRFX_TWIM_FLAG_REPEATED_XFER - Prepare for repeated transfers. You can set up a number of transfers that will be triggered externally (for example by PPI).
+ * An example is a TXRX transfer with the options @ref NRFX_TWIM_FLAG_RX_POSTINC, @ref NRFX_TWIM_FLAG_NO_XFER_EVT_HANDLER, and @ref NRFX_TWIM_FLAG_REPEATED_XFER.
+ * After the transfer is set up, a set of transfers can be triggered by PPI that will read, for example, the same register of an
+ * external component and put it into a RAM buffer without any interrupts. @ref nrfx_twim_stopped_event_get can be used to get the
+ * address of the STOPPED event, which can be used to count the number of transfers. If @ref NRFX_TWIM_FLAG_REPEATED_XFER is used,
+ * the driver does not set the driver instance into busy state, so you must ensure that the next transfers are set up
+ * when TWIM is not active.
+ * - @ref NRFX_TWIM_FLAG_TX_NO_STOP - No stop condition after the TX transfer.
+ * - @ref NRFX_TWIM_FLAG_NO_SPURIOUS_STOP_CHECK - Checks for spurious STOP conditions are disabled.
+ * Used together with @ref NRFX_TWIM_FLAG_NO_XFER_EVT_HANDLER can result in lower power consumption
+ * when transfers are triggered externally and CPU is sleeping.
+ * Use only with I2C standard-compliant slave devices.
+ *
+ * @note
+ * Some flag combinations are invalid:
+ * - @ref NRFX_TWIM_FLAG_TX_NO_STOP with @ref nrfx_twim_xfer_desc_t.type different than @ref NRFX_TWIM_XFER_TX
+ * - @ref NRFX_TWIM_FLAG_REPEATED_XFER with @ref nrfx_twim_xfer_desc_t.type set to @ref NRFX_TWIM_XFER_TXTX
+ *
+ * If @ref nrfx_twim_xfer_desc_t.type is set to @ref NRFX_TWIM_XFER_TX and the @ref NRFX_TWIM_FLAG_TX_NO_STOP and @ref NRFX_TWIM_FLAG_REPEATED_XFER
+ * flags are set, two tasks must be used to trigger a transfer: TASKS_RESUME followed by TASKS_STARTTX. If no stop condition is generated,
+ * TWIM is in SUSPENDED state. Therefore, it must be resumed before the transfer can be started.
+ *
+ * @note Peripherals using EasyDMA (including TWIM) require the transfer buffers
+ * to be placed in the Data RAM region. If this condition is not met,
+ * this function will fail with the error code NRFX_ERROR_INVALID_ADDR.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ * @param[in] p_xfer_desc Pointer to the transfer descriptor.
+ * @param[in] flags Transfer options (0 for default settings).
+ *
+ * @retval NRFX_SUCCESS The procedure is successful.
+ * @retval NRFX_ERROR_BUSY The driver is not ready for a new transfer.
+ * @retval NRFX_ERROR_NOT_SUPPORTED The provided parameters are not supported.
+ * @retval NRFX_ERROR_INTERNAL An unexpected transition occurred on the bus.
+ * @retval NRFX_ERROR_INVALID_ADDR The provided buffers are not placed in the Data RAM region.
+ * @retval NRFX_ERROR_DRV_TWI_ERR_OVERRUN The unread data is replaced by new data.
+ * @retval NRFX_ERROR_DRV_TWI_ERR_ANACK NACK is received after sending the address.
+ * @retval NRFX_ERROR_DRV_TWI_ERR_DNACK NACK is received after sending a data byte.
+ */
+nrfx_err_t nrfx_twim_xfer(nrfx_twim_t const * p_instance,
+ nrfx_twim_xfer_desc_t const * p_xfer_desc,
+ uint32_t flags);
+
+/**
+ * @brief Function for checking the TWI driver state.
+ *
+ * @param[in] p_instance TWI instance.
+ *
+ * @retval true The TWI driver is currently busy performing a transfer.
+ * @retval false The TWI driver is ready for a new transfer.
+ */
+bool nrfx_twim_is_busy(nrfx_twim_t const * p_instance);
+
+
+/**
+ * @brief Function for returning the address of a TWIM start task.
+ *
+ * This function is to be used if @ref nrfx_twim_xfer was called with the flag @ref NRFX_TWIM_FLAG_HOLD_XFER.
+ * In that case, the transfer is not started by the driver, but it must be started externally by PPI.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ * @param[in] xfer_type Transfer type used in the last call of the @ref nrfx_twim_xfer function.
+ *
+ * @return Start task address (TX or RX) depending on the value of xfer_type.
+ */
+uint32_t nrfx_twim_start_task_get(nrfx_twim_t const * p_instance, nrfx_twim_xfer_type_t xfer_type);
+
+/**
+ * @brief Function for returning the address of a STOPPED TWIM event.
+ *
+ * A STOPPED event can be used to detect the end of a transfer if the @ref NRFX_TWIM_FLAG_NO_XFER_EVT_HANDLER
+ * option is used.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ *
+ * @return STOPPED event address.
+ */
+uint32_t nrfx_twim_stopped_event_get(nrfx_twim_t const * p_instance);
+
+/**
+ * @brief Function for recovering the bus.
+ *
+ * This function checks if the bus is not stuck because of a slave holding the SDA line in the low state,
+ * and if needed it performs required number of pulses on the SCL line to make the slave release the SDA line.
+ * Finally, the function generates a STOP condition on the bus to put it into a known state.
+ *
+ * @note This function can be used only if the TWIM driver is uninitialized.
+ *
+ * @param[in] scl_pin SCL pin number.
+ * @param[in] sda_pin SDA pin number.
+ *
+ * @retval NRFX_SUCCESS Bus recovery was successful.
+ * @retval NRFX_ERROR_INTERNAL Bus recovery failed.
+ */
+NRFX_STATIC_INLINE nrfx_err_t nrfx_twim_bus_recover(uint32_t scl_pin, uint32_t sda_pin);
+
+#ifndef NRFX_DECLARE_ONLY
+NRFX_STATIC_INLINE nrfx_err_t nrfx_twim_bus_recover(uint32_t scl_pin, uint32_t sda_pin)
+{
+ return nrfx_twi_twim_bus_recover(scl_pin, sda_pin);
+}
+#endif
+
+/** @} */
+
+void nrfx_twim_0_irq_handler(void);
+void nrfx_twim_1_irq_handler(void);
+void nrfx_twim_2_irq_handler(void);
+void nrfx_twim_3_irq_handler(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRFX_TWIM_H__
diff --git a/platform/ext/target/nordic_nrf/common/core/nrfx/drivers/src/nrfx_qspi.c b/platform/ext/target/nordic_nrf/common/core/nrfx/drivers/src/nrfx_qspi.c
new file mode 100644
index 000000000..3983e8c95
--- /dev/null
+++ b/platform/ext/target/nordic_nrf/common/core/nrfx/drivers/src/nrfx_qspi.c
@@ -0,0 +1,452 @@
+/*
+ * Copyright (c) 2016 - 2020, 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 the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <nrfx.h>
+
+#if NRFX_CHECK(NRFX_QSPI_ENABLED)
+
+#include <nrfx_qspi.h>
+
+/** @brief Command byte used to read status register. */
+#define QSPI_STD_CMD_RDSR 0x05
+
+/** @brief Byte used to mask status register and retrieve the write-in-progess bit. */
+#define QSPI_MEM_STATUSREG_WIP_Pos 0x01
+
+/** @brief Default time used in timeout function. */
+#define QSPI_DEF_WAIT_TIME_US 10
+
+/** @brief Default number of tries in timeout function. */
+#define QSPI_DEF_WAIT_ATTEMPTS 100
+
+/** @brief Control block - driver instance local data. */
+typedef struct
+{
+ nrfx_qspi_handler_t handler; /**< Handler. */
+ nrfx_drv_state_t state; /**< Driver state. */
+ volatile bool is_busy; /**< Flag indicating that an operation is currently being performed. */
+ void * p_context; /**< Driver context used in interrupt. */
+} qspi_control_block_t;
+
+static qspi_control_block_t m_cb;
+
+static nrfx_err_t qspi_task_perform(nrf_qspi_task_t task)
+{
+ // Wait for peripheral
+ if (m_cb.is_busy)
+ {
+ return NRFX_ERROR_BUSY;
+ }
+
+ nrf_qspi_event_clear(NRF_QSPI, NRF_QSPI_EVENT_READY);
+
+ if (m_cb.handler)
+ {
+ m_cb.is_busy = true;
+ nrf_qspi_int_enable(NRF_QSPI, NRF_QSPI_INT_READY_MASK);
+ }
+
+ nrf_qspi_task_trigger(NRF_QSPI, task);
+
+ if (m_cb.handler == NULL)
+ {
+ while (!nrf_qspi_event_check(NRF_QSPI, NRF_QSPI_EVENT_READY))
+ {};
+ }
+ return NRFX_SUCCESS;
+}
+
+static bool qspi_pins_configure(nrf_qspi_pins_t const * p_config)
+{
+ // Check if the user set meaningful values to struct fields. If not, return false.
+ if ((p_config->sck_pin == NRF_QSPI_PIN_NOT_CONNECTED) ||
+ (p_config->csn_pin == NRF_QSPI_PIN_NOT_CONNECTED) ||
+ (p_config->io0_pin == NRF_QSPI_PIN_NOT_CONNECTED) ||
+ (p_config->io1_pin == NRF_QSPI_PIN_NOT_CONNECTED))
+ {
+ return false;
+ }
+
+ nrf_qspi_pins_set(NRF_QSPI, p_config);
+
+ return true;
+}
+
+static nrfx_err_t qspi_ready_wait(void)
+{
+ bool result;
+ NRFX_WAIT_FOR(nrf_qspi_event_check(NRF_QSPI, NRF_QSPI_EVENT_READY),
+ QSPI_DEF_WAIT_ATTEMPTS,
+ QSPI_DEF_WAIT_TIME_US,
+ result);
+ if (!result)
+ {
+ return NRFX_ERROR_TIMEOUT;
+ }
+
+ return NRFX_SUCCESS;
+}
+
+nrfx_err_t nrfx_qspi_init(nrfx_qspi_config_t const * p_config,
+ nrfx_qspi_handler_t handler,
+ void * p_context)
+{
+ NRFX_ASSERT(p_config);
+ if (m_cb.state != NRFX_DRV_STATE_UNINITIALIZED)
+ {
+ return NRFX_ERROR_INVALID_STATE;
+ }
+
+ if (!qspi_pins_configure(&p_config->pins))
+ {
+ return NRFX_ERROR_INVALID_PARAM;
+ }
+
+ nrf_qspi_xip_offset_set(NRF_QSPI, p_config->xip_offset);
+ nrf_qspi_ifconfig0_set(NRF_QSPI, &p_config->prot_if);
+ nrf_qspi_ifconfig1_set(NRF_QSPI, &p_config->phy_if);
+
+ m_cb.is_busy = false;
+ m_cb.handler = handler;
+ m_cb.p_context = p_context;
+
+ /* QSPI interrupt is disabled because the device should be enabled in polling mode (wait for activate
+ task event ready)*/
+ nrf_qspi_int_disable(NRF_QSPI, NRF_QSPI_INT_READY_MASK);
+
+ if (handler)
+ {
+ NRFX_IRQ_PRIORITY_SET(QSPI_IRQn, p_config->irq_priority);
+ NRFX_IRQ_ENABLE(QSPI_IRQn);
+ }
+
+ m_cb.state = NRFX_DRV_STATE_INITIALIZED;
+
+ nrf_qspi_enable(NRF_QSPI);
+
+ nrf_qspi_event_clear(NRF_QSPI, NRF_QSPI_EVENT_READY);
+ nrf_qspi_task_trigger(NRF_QSPI, NRF_QSPI_TASK_ACTIVATE);
+
+ // Waiting for the peripheral to activate
+
+ return qspi_ready_wait();
+}
+
+nrfx_err_t nrfx_qspi_cinstr_xfer(nrf_qspi_cinstr_conf_t const * p_config,
+ void const * p_tx_buffer,
+ void * p_rx_buffer)
+{
+ NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
+
+ if (m_cb.is_busy)
+ {
+ return NRFX_ERROR_BUSY;
+ }
+
+ nrf_qspi_event_clear(NRF_QSPI, NRF_QSPI_EVENT_READY);
+ /* In some cases, only opcode should be sent. To prevent execution, set function code is
+ * surrounded by an if.
+ */
+ if (p_tx_buffer)
+ {
+ nrf_qspi_cinstrdata_set(NRF_QSPI, p_config->length, p_tx_buffer);
+ }
+
+ nrf_qspi_int_disable(NRF_QSPI, NRF_QSPI_INT_READY_MASK);
+
+ nrf_qspi_cinstr_transfer_start(NRF_QSPI, p_config);
+
+ if (qspi_ready_wait() == NRFX_ERROR_TIMEOUT)
+ {
+ // This timeout should never occur when WIPWAIT is not active, since in this
+ // case the QSPI peripheral should send the command immediately, without any
+ // waiting for previous write to complete.
+ NRFX_ASSERT(p_config->wipwait);
+
+ return NRFX_ERROR_TIMEOUT;
+ }
+ nrf_qspi_event_clear(NRF_QSPI, NRF_QSPI_EVENT_READY);
+
+ if (p_rx_buffer)
+ {
+ nrf_qspi_cinstrdata_get(NRF_QSPI, p_config->length, p_rx_buffer);
+ }
+
+ return NRFX_SUCCESS;
+}
+
+nrfx_err_t nrfx_qspi_cinstr_quick_send(uint8_t opcode,
+ nrf_qspi_cinstr_len_t length,
+ void const * p_tx_buffer)
+{
+ nrf_qspi_cinstr_conf_t config = NRFX_QSPI_DEFAULT_CINSTR(opcode, length);
+ return nrfx_qspi_cinstr_xfer(&config, p_tx_buffer, NULL);
+}
+
+nrfx_err_t nrfx_qspi_lfm_start(nrf_qspi_cinstr_conf_t const * p_config)
+{
+ NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
+ NRFX_ASSERT(!(nrf_qspi_cinstr_long_transfer_is_ongoing(NRF_QSPI)));
+ NRFX_ASSERT(p_config->length == NRF_QSPI_CINSTR_LEN_1B);
+
+ if (m_cb.is_busy)
+ {
+ return NRFX_ERROR_BUSY;
+ }
+
+ nrf_qspi_cinstr_long_transfer_start(NRF_QSPI, p_config);
+
+ if (qspi_ready_wait() == NRFX_ERROR_TIMEOUT)
+ {
+ /* In case of error, abort long frame mode */
+ nrf_qspi_cinstr_long_transfer_continue(NRF_QSPI, NRF_QSPI_CINSTR_LEN_1B, true);
+ return NRFX_ERROR_TIMEOUT;
+ }
+
+ m_cb.is_busy = true;
+ return NRFX_SUCCESS;
+}
+
+nrfx_err_t nrfx_qspi_lfm_xfer(void const * p_tx_buffer,
+ void * p_rx_buffer,
+ size_t transfer_length,
+ bool finalize)
+{
+ NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
+ NRFX_ASSERT(nrf_qspi_cinstr_long_transfer_is_ongoing(NRF_QSPI));
+
+ nrfx_err_t status = NRFX_SUCCESS;
+
+ /* Perform transfers in packets of 8 bytes. Last transfer may be shorter. */
+ nrf_qspi_cinstr_len_t length = NRF_QSPI_CINSTR_LEN_9B;
+ for (uint32_t curr_byte = 0; curr_byte < transfer_length; curr_byte += 8)
+ {
+ uint32_t remaining_bytes = transfer_length - curr_byte;
+ if (remaining_bytes < 8)
+ {
+ length = (nrf_qspi_cinstr_len_t)(remaining_bytes + 1);
+ }
+
+ if (p_tx_buffer)
+ {
+ nrf_qspi_cinstrdata_set(NRF_QSPI,
+ length,
+ &((uint8_t const *)p_tx_buffer)[curr_byte]);
+ }
+
+ nrf_qspi_event_clear(NRF_QSPI, NRF_QSPI_EVENT_READY);
+
+ if (remaining_bytes <= 8)
+ {
+ nrf_qspi_cinstr_long_transfer_continue(NRF_QSPI, length, finalize);
+ }
+ else
+ {
+ nrf_qspi_cinstr_long_transfer_continue(NRF_QSPI, length, false);
+ }
+
+ if (qspi_ready_wait() == NRFX_ERROR_TIMEOUT)
+ {
+ /* In case of error, abort long frame mode */
+ nrf_qspi_cinstr_long_transfer_continue(NRF_QSPI, NRF_QSPI_CINSTR_LEN_1B, true);
+ status = NRFX_ERROR_TIMEOUT;
+ break;
+ }
+
+ if (p_rx_buffer)
+ {
+ nrf_qspi_cinstrdata_get(NRF_QSPI,
+ length,
+ &((uint8_t *)p_rx_buffer)[curr_byte]);
+ }
+ }
+ nrf_qspi_event_clear(NRF_QSPI, NRF_QSPI_EVENT_READY);
+
+ if ((finalize) || (status == NRFX_ERROR_TIMEOUT))
+ {
+ m_cb.is_busy = false;
+ }
+
+ return status;
+}
+
+nrfx_err_t nrfx_qspi_mem_busy_check(void)
+{
+ nrfx_err_t ret_code;
+ uint8_t status_value = 0;
+
+ nrf_qspi_cinstr_conf_t const config =
+ NRFX_QSPI_DEFAULT_CINSTR(QSPI_STD_CMD_RDSR,
+ NRF_QSPI_CINSTR_LEN_2B);
+ ret_code = nrfx_qspi_cinstr_xfer(&config, &status_value, &status_value);
+
+ if (ret_code != NRFX_SUCCESS)
+ {
+ return ret_code;
+ }
+
+ if ((status_value & QSPI_MEM_STATUSREG_WIP_Pos) != 0x00)
+ {
+ return NRFX_ERROR_BUSY;
+ }
+
+ return NRFX_SUCCESS;
+}
+
+void nrfx_qspi_uninit(void)
+{
+ NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
+
+ if (nrf_qspi_cinstr_long_transfer_is_ongoing(NRF_QSPI))
+ {
+ nrf_qspi_cinstr_long_transfer_continue(NRF_QSPI, NRF_QSPI_CINSTR_LEN_1B, true);
+ }
+
+ nrf_qspi_int_disable(NRF_QSPI, NRF_QSPI_INT_READY_MASK);
+
+ nrf_qspi_task_trigger(NRF_QSPI, NRF_QSPI_TASK_DEACTIVATE);
+
+ nrf_qspi_disable(NRF_QSPI);
+
+ NRFX_IRQ_DISABLE(QSPI_IRQn);
+
+ nrf_qspi_event_clear(NRF_QSPI, NRF_QSPI_EVENT_READY);
+
+ m_cb.state = NRFX_DRV_STATE_UNINITIALIZED;
+}
+
+nrfx_err_t nrfx_qspi_write(void const * p_tx_buffer,
+ size_t tx_buffer_length,
+ uint32_t dst_address)
+{
+ NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
+ NRFX_ASSERT(p_tx_buffer != NULL);
+
+ if (!nrfx_is_in_ram(p_tx_buffer) || !nrfx_is_word_aligned(p_tx_buffer))
+ {
+ return NRFX_ERROR_INVALID_ADDR;
+ }
+
+ nrf_qspi_write_buffer_set(NRF_QSPI, p_tx_buffer, tx_buffer_length, dst_address);
+ return qspi_task_perform(NRF_QSPI_TASK_WRITESTART);
+}
+
+nrfx_err_t nrfx_qspi_read(void * p_rx_buffer,
+ size_t rx_buffer_length,
+ uint32_t src_address)
+{
+ NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
+ NRFX_ASSERT(p_rx_buffer != NULL);
+
+ if (!nrfx_is_in_ram(p_rx_buffer) || !nrfx_is_word_aligned(p_rx_buffer))
+ {
+ return NRFX_ERROR_INVALID_ADDR;
+ }
+
+ nrf_qspi_read_buffer_set(NRF_QSPI, p_rx_buffer, rx_buffer_length, src_address);
+ return qspi_task_perform(NRF_QSPI_TASK_READSTART);
+}
+
+nrfx_err_t nrfx_qspi_erase(nrf_qspi_erase_len_t length,
+ uint32_t start_address)
+{
+ NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
+
+ if (!nrfx_is_word_aligned((void const *)start_address))
+ {
+ return NRFX_ERROR_INVALID_ADDR;
+ }
+
+ nrf_qspi_erase_ptr_set(NRF_QSPI, start_address, length);
+ return qspi_task_perform(NRF_QSPI_TASK_ERASESTART);
+}
+
+nrfx_err_t nrfx_qspi_chip_erase(void)
+{
+ return nrfx_qspi_erase(NRF_QSPI_ERASE_LEN_ALL, 0);
+}
+
+#if NRF_QSPI_HAS_XIP_ENC
+nrfx_err_t nrfx_qspi_xip_encrypt(nrf_qspi_encryption_t const * p_config)
+{
+ if (m_cb.is_busy)
+ {
+ return NRFX_ERROR_BUSY;
+ }
+
+ if (p_config)
+ {
+ nrf_qspi_xip_encryption_configure(NRF_QSPI, p_config);
+ nrf_qspi_xip_encryption_set(NRF_QSPI, true);
+ }
+ else
+ {
+ nrf_qspi_xip_encryption_set(NRF_QSPI, false);
+ }
+
+ return NRFX_SUCCESS;
+}
+#endif
+
+#if NRF_QSPI_HAS_DMA_ENC
+nrfx_err_t nrfx_qspi_dma_encrypt(nrf_qspi_encryption_t const * p_config)
+{
+ if (m_cb.is_busy)
+ {
+ return NRFX_ERROR_BUSY;
+ }
+
+ if (p_config)
+ {
+ nrf_qspi_dma_encryption_configure(NRF_QSPI, p_config);
+ nrf_qspi_dma_encryption_set(NRF_QSPI, true);
+ }
+ else
+ {
+ nrf_qspi_dma_encryption_set(NRF_QSPI, false);
+ }
+
+ return NRFX_SUCCESS;
+}
+#endif
+
+void nrfx_qspi_irq_handler(void)
+{
+ // Catch Event ready interrupts
+ if (nrf_qspi_event_check(NRF_QSPI, NRF_QSPI_EVENT_READY))
+ {
+ m_cb.is_busy = false;
+ nrf_qspi_event_clear(NRF_QSPI, NRF_QSPI_EVENT_READY);
+ m_cb.handler(NRFX_QSPI_EVENT_DONE, m_cb.p_context);
+ }
+}
+
+#endif // NRFX_CHECK(NRFX_QSPI_ENABLED)
diff --git a/platform/ext/target/nordic_nrf/common/core/nrfx/drivers/src/nrfx_twi_twim.c b/platform/ext/target/nordic_nrf/common/core/nrfx/drivers/src/nrfx_twi_twim.c
new file mode 100644
index 000000000..b15f7c681
--- /dev/null
+++ b/platform/ext/target/nordic_nrf/common/core/nrfx/drivers/src/nrfx_twi_twim.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2019 - 2020, 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 the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <nrfx_twi_twim.h>
+
+#if NRFX_CHECK(NRFX_TWI_ENABLED) || NRFX_CHECK(NRFX_TWIM_ENABLED)
+
+#include <hal/nrf_gpio.h>
+
+#define TWI_TWIM_PIN_CONFIGURE(_pin) nrf_gpio_cfg((_pin), \
+ NRF_GPIO_PIN_DIR_OUTPUT, \
+ NRF_GPIO_PIN_INPUT_CONNECT, \
+ NRF_GPIO_PIN_PULLUP, \
+ NRF_GPIO_PIN_S0D1, \
+ NRF_GPIO_PIN_NOSENSE)
+
+nrfx_err_t nrfx_twi_twim_bus_recover(uint32_t scl_pin, uint32_t sda_pin)
+{
+ nrf_gpio_pin_set(scl_pin);
+ nrf_gpio_pin_set(sda_pin);
+
+ TWI_TWIM_PIN_CONFIGURE(scl_pin);
+ TWI_TWIM_PIN_CONFIGURE(sda_pin);
+ NRFX_DELAY_US(4);
+
+ for (uint8_t i = 0; i < 9; i++)
+ {
+ if (nrf_gpio_pin_read(sda_pin))
+ {
+ break;
+ }
+ else
+ {
+ // Pulse CLOCK signal
+ nrf_gpio_pin_clear(scl_pin);
+ NRFX_DELAY_US(4);
+ nrf_gpio_pin_set(scl_pin);
+ NRFX_DELAY_US(4);
+ }
+ }
+
+ // Generate a STOP condition on the bus
+ nrf_gpio_pin_clear(sda_pin);
+ NRFX_DELAY_US(4);
+ nrf_gpio_pin_set(sda_pin);
+ NRFX_DELAY_US(4);
+
+ if (nrf_gpio_pin_read(sda_pin))
+ {
+ return NRFX_SUCCESS;
+ }
+ else
+ {
+ return NRFX_ERROR_INTERNAL;
+ }
+}
+
+#endif // NRFX_CHECK(NRFX_TWI_ENABLED) || NRFX_CHECK(NRFX_TWIM_ENABLED)
diff --git a/platform/ext/target/nordic_nrf/common/core/nrfx/drivers/src/nrfx_twim.c b/platform/ext/target/nordic_nrf/common/core/nrfx/drivers/src/nrfx_twim.c
new file mode 100644
index 000000000..85ba60c5b
--- /dev/null
+++ b/platform/ext/target/nordic_nrf/common/core/nrfx/drivers/src/nrfx_twim.c
@@ -0,0 +1,843 @@
+/*
+ * Copyright (c) 2015 - 2020, 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 the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <nrfx.h>
+
+#if NRFX_CHECK(NRFX_TWIM_ENABLED)
+
+#if !(NRFX_CHECK(NRFX_TWIM0_ENABLED) || \
+ NRFX_CHECK(NRFX_TWIM1_ENABLED) || \
+ NRFX_CHECK(NRFX_TWIM2_ENABLED) || \
+ NRFX_CHECK(NRFX_TWIM3_ENABLED))
+#error "No enabled TWIM instances. Check <nrfx_config.h>."
+#endif
+
+#include <nrfx_twim.h>
+#include <hal/nrf_gpio.h>
+#include "prs/nrfx_prs.h"
+
+#define NRFX_LOG_MODULE TWIM
+#include <nrfx_log.h>
+
+#define EVT_TO_STR(event) \
+ (event == NRFX_TWIM_EVT_DONE ? "EVT_DONE" : \
+ (event == NRFX_TWIM_EVT_ADDRESS_NACK ? "EVT_ADDRESS_NACK" : \
+ (event == NRFX_TWIM_EVT_DATA_NACK ? "EVT_DATA_NACK" : \
+ (event == NRFX_TWIM_EVT_OVERRUN ? "EVT_OVERRUN" : \
+ (event == NRFX_TWIM_EVT_BUS_ERROR ? "EVT_BUS_ERROR" : \
+ "UNKNOWN ERROR")))))
+
+#define EVT_TO_STR_TWIM(event) \
+ (event == NRF_TWIM_EVENT_STOPPED ? "NRF_TWIM_EVENT_STOPPED" : \
+ (event == NRF_TWIM_EVENT_ERROR ? "NRF_TWIM_EVENT_ERROR" : \
+ (event == NRF_TWIM_EVENT_SUSPENDED ? "NRF_TWIM_EVENT_SUSPENDED" : \
+ (event == NRF_TWIM_EVENT_RXSTARTED ? "NRF_TWIM_EVENT_RXSTARTED" : \
+ (event == NRF_TWIM_EVENT_TXSTARTED ? "NRF_TWIM_EVENT_TXSTARTED" : \
+ (event == NRF_TWIM_EVENT_LASTRX ? "NRF_TWIM_EVENT_LASTRX" : \
+ (event == NRF_TWIM_EVENT_LASTTX ? "NRF_TWIM_EVENT_LASTTX" : \
+ "UNKNOWN ERROR")))))))
+
+#define TRANSFER_TO_STR(type) \
+ (type == NRFX_TWIM_XFER_TX ? "XFER_TX" : \
+ (type == NRFX_TWIM_XFER_RX ? "XFER_RX" : \
+ (type == NRFX_TWIM_XFER_TXRX ? "XFER_TXRX" : \
+ (type == NRFX_TWIM_XFER_TXTX ? "XFER_TXTX" : \
+ "UNKNOWN TRANSFER TYPE"))))
+
+#define TWIM_PIN_INIT(_pin) nrf_gpio_cfg((_pin), \
+ NRF_GPIO_PIN_DIR_INPUT, \
+ NRF_GPIO_PIN_INPUT_CONNECT, \
+ NRF_GPIO_PIN_PULLUP, \
+ NRF_GPIO_PIN_S0D1, \
+ NRF_GPIO_PIN_NOSENSE)
+
+#define TWIMX_LENGTH_VALIDATE(peripheral, drv_inst_idx, len1, len2) \
+ (((drv_inst_idx) == NRFX_CONCAT_3(NRFX_, peripheral, _INST_IDX)) && \
+ NRFX_EASYDMA_LENGTH_VALIDATE(peripheral, len1, len2))
+
+#if NRFX_CHECK(NRFX_TWIM0_ENABLED)
+#define TWIM0_LENGTH_VALIDATE(...) TWIMX_LENGTH_VALIDATE(TWIM0, __VA_ARGS__)
+#else
+#define TWIM0_LENGTH_VALIDATE(...) 0
+#endif
+
+#if NRFX_CHECK(NRFX_TWIM1_ENABLED)
+#define TWIM1_LENGTH_VALIDATE(...) TWIMX_LENGTH_VALIDATE(TWIM1, __VA_ARGS__)
+#else
+#define TWIM1_LENGTH_VALIDATE(...) 0
+#endif
+
+#if NRFX_CHECK(NRFX_TWIM2_ENABLED)
+#define TWIM2_LENGTH_VALIDATE(...) TWIMX_LENGTH_VALIDATE(TWIM2, __VA_ARGS__)
+#else
+#define TWIM2_LENGTH_VALIDATE(...) 0
+#endif
+
+#if NRFX_CHECK(NRFX_TWIM3_ENABLED)
+#define TWIM3_LENGTH_VALIDATE(...) TWIMX_LENGTH_VALIDATE(TWIM3, __VA_ARGS__)
+#else
+#define TWIM3_LENGTH_VALIDATE(...) 0
+#endif
+
+#define TWIM_LENGTH_VALIDATE(drv_inst_idx, len1, len2) \
+ (TWIM0_LENGTH_VALIDATE(drv_inst_idx, len1, len2) || \
+ TWIM1_LENGTH_VALIDATE(drv_inst_idx, len1, len2) || \
+ TWIM2_LENGTH_VALIDATE(drv_inst_idx, len1, len2) || \
+ TWIM3_LENGTH_VALIDATE(drv_inst_idx, len1, len2))
+
+// Control block - driver instance local data.
+typedef struct
+{
+ nrfx_twim_evt_handler_t handler;
+ void * p_context;
+ volatile uint32_t int_mask;
+ nrfx_twim_xfer_desc_t xfer_desc;
+ uint32_t flags;
+ uint8_t * p_curr_buf;
+ size_t curr_length;
+ bool curr_no_stop;
+ nrfx_drv_state_t state;
+ bool error;
+ volatile bool busy;
+ bool repeated;
+ uint8_t bytes_transferred;
+ bool hold_bus_uninit;
+#if NRFX_CHECK(NRFX_TWIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED)
+ nrf_twim_frequency_t bus_frequency;
+#endif
+} twim_control_block_t;
+
+static twim_control_block_t m_cb[NRFX_TWIM_ENABLED_COUNT];
+
+static nrfx_err_t twi_process_error(uint32_t errorsrc)
+{
+ nrfx_err_t ret = NRFX_ERROR_INTERNAL;
+
+ if (errorsrc & NRF_TWIM_ERROR_OVERRUN)
+ {
+ ret = NRFX_ERROR_DRV_TWI_ERR_OVERRUN;
+ }
+
+ if (errorsrc & NRF_TWIM_ERROR_ADDRESS_NACK)
+ {
+ ret = NRFX_ERROR_DRV_TWI_ERR_ANACK;
+ }
+
+ if (errorsrc & NRF_TWIM_ERROR_DATA_NACK)
+ {
+ ret = NRFX_ERROR_DRV_TWI_ERR_DNACK;
+ }
+
+ return ret;
+}
+
+static bool xfer_completeness_check(NRF_TWIM_Type * p_twim, twim_control_block_t const * p_cb)
+{
+ // If the actual number of transferred bytes is not equal to what was requested,
+ // but there was no error signaled by the peripheral, this means that something
+ // unexpected, like a premature STOP condition, was received on the bus.
+ // In such case the peripheral has to be disabled and re-enabled, so that its
+ // internal state machine is reinitialized.
+
+ bool transfer_complete = true;
+ switch (p_cb->xfer_desc.type)
+ {
+ case NRFX_TWIM_XFER_TXTX:
+ // int_mask variable is used to determine which length should be checked
+ // against number of bytes latched in EasyDMA.
+ // NRF_TWIM_INT_SUSPENDED_MASK is configured only in first TX of TXTX transfer.
+ if (((p_cb->int_mask & NRF_TWIM_INT_SUSPENDED_MASK) &&
+ (nrf_twim_txd_amount_get(p_twim) != p_cb->xfer_desc.primary_length)) ||
+ (!(p_cb->int_mask & NRF_TWIM_INT_SUSPENDED_MASK) &&
+ (nrf_twim_txd_amount_get(p_twim) != p_cb->xfer_desc.secondary_length)))
+ {
+ transfer_complete = false;
+ }
+ break;
+ case NRFX_TWIM_XFER_TXRX:
+ if ((nrf_twim_txd_amount_get(p_twim) != p_cb->xfer_desc.primary_length) ||
+ (nrf_twim_rxd_amount_get(p_twim) != p_cb->xfer_desc.secondary_length))
+ {
+ transfer_complete = false;
+ }
+ break;
+ case NRFX_TWIM_XFER_TX:
+ if (nrf_twim_txd_amount_get(p_twim) != p_cb->xfer_desc.primary_length)
+ {
+ transfer_complete = false;
+ }
+ break;
+ case NRFX_TWIM_XFER_RX:
+ if (nrf_twim_rxd_amount_get(p_twim) != p_cb->xfer_desc.primary_length)
+ {
+ transfer_complete = false;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (!transfer_complete)
+ {
+ nrf_twim_disable(p_twim);
+ nrf_twim_enable(p_twim);
+ }
+
+ return transfer_complete;
+}
+
+nrfx_err_t nrfx_twim_init(nrfx_twim_t const * p_instance,
+ nrfx_twim_config_t const * p_config,
+ nrfx_twim_evt_handler_t event_handler,
+ void * p_context)
+{
+ NRFX_ASSERT(p_config);
+ NRFX_ASSERT(p_config->scl != p_config->sda);
+ twim_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
+ nrfx_err_t err_code;
+
+ if (p_cb->state != NRFX_DRV_STATE_UNINITIALIZED)
+ {
+ err_code = NRFX_ERROR_INVALID_STATE;
+ NRFX_LOG_WARNING("Function: %s, error code: %s.",
+ __func__,
+ NRFX_LOG_ERROR_STRING_GET(err_code));
+ return err_code;
+ }
+
+#if NRFX_CHECK(NRFX_PRS_ENABLED)
+ static nrfx_irq_handler_t const irq_handlers[NRFX_TWIM_ENABLED_COUNT] = {
+ #if NRFX_CHECK(NRFX_TWIM0_ENABLED)
+ nrfx_twim_0_irq_handler,
+ #endif
+ #if NRFX_CHECK(NRFX_TWIM1_ENABLED)
+ nrfx_twim_1_irq_handler,
+ #endif
+ #if NRFX_CHECK(NRFX_TWIM2_ENABLED)
+ nrfx_twim_2_irq_handler,
+ #endif
+ #if NRFX_CHECK(NRFX_TWIM3_ENABLED)
+ nrfx_twim_3_irq_handler,
+ #endif
+ };
+ if (nrfx_prs_acquire(p_instance->p_twim,
+ irq_handlers[p_instance->drv_inst_idx]) != NRFX_SUCCESS)
+ {
+ err_code = NRFX_ERROR_BUSY;
+ NRFX_LOG_WARNING("Function: %s, error code: %s.",
+ __func__,
+ NRFX_LOG_ERROR_STRING_GET(err_code));
+ return err_code;
+ }
+#endif // NRFX_CHECK(NRFX_PRS_ENABLED)
+
+ p_cb->handler = event_handler;
+ p_cb->p_context = p_context;
+ p_cb->int_mask = 0;
+ p_cb->repeated = false;
+ p_cb->busy = false;
+ p_cb->hold_bus_uninit = p_config->hold_bus_uninit;
+#if NRFX_CHECK(NRFX_TWIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED)
+ p_cb->bus_frequency = (nrf_twim_frequency_t)p_config->frequency;
+#endif
+
+ /* To secure correct signal levels on the pins used by the TWI
+ master when the system is in OFF mode, and when the TWI master is
+ disabled, these pins must be configured in the GPIO peripheral.
+ */
+ TWIM_PIN_INIT(p_config->scl);
+ TWIM_PIN_INIT(p_config->sda);
+
+ NRF_TWIM_Type * p_twim = p_instance->p_twim;
+ nrf_twim_pins_set(p_twim, p_config->scl, p_config->sda);
+ nrf_twim_frequency_set(p_twim,
+ (nrf_twim_frequency_t)p_config->frequency);
+
+ if (p_cb->handler)
+ {
+ NRFX_IRQ_PRIORITY_SET(nrfx_get_irq_number(p_instance->p_twim),
+ p_config->interrupt_priority);
+ NRFX_IRQ_ENABLE(nrfx_get_irq_number(p_instance->p_twim));
+ }
+
+ p_cb->state = NRFX_DRV_STATE_INITIALIZED;
+
+ err_code = NRFX_SUCCESS;
+ NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
+ return err_code;
+}
+
+void nrfx_twim_uninit(nrfx_twim_t const * p_instance)
+{
+ twim_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
+ NRFX_ASSERT(p_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
+
+ if (p_cb->handler)
+ {
+ NRFX_IRQ_DISABLE(nrfx_get_irq_number(p_instance->p_twim));
+ }
+ nrfx_twim_disable(p_instance);
+
+#if NRFX_CHECK(NRFX_PRS_ENABLED)
+ nrfx_prs_release(p_instance->p_twim);
+#endif
+
+ if (!p_cb->hold_bus_uninit)
+ {
+ nrf_gpio_cfg_default(nrf_twim_scl_pin_get(p_instance->p_twim));
+ nrf_gpio_cfg_default(nrf_twim_sda_pin_get(p_instance->p_twim));
+ }
+
+ p_cb->state = NRFX_DRV_STATE_UNINITIALIZED;
+ NRFX_LOG_INFO("Instance uninitialized: %d.", p_instance->drv_inst_idx);
+}
+
+void nrfx_twim_enable(nrfx_twim_t const * p_instance)
+{
+ twim_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
+ NRFX_ASSERT(p_cb->state == NRFX_DRV_STATE_INITIALIZED);
+
+ nrf_twim_enable(p_instance->p_twim);
+
+ p_cb->state = NRFX_DRV_STATE_POWERED_ON;
+ NRFX_LOG_INFO("Instance enabled: %d.", p_instance->drv_inst_idx);
+}
+
+void nrfx_twim_disable(nrfx_twim_t const * p_instance)
+{
+ twim_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
+ NRFX_ASSERT(p_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
+
+ NRF_TWIM_Type * p_twim = p_instance->p_twim;
+ p_cb->int_mask = 0;
+ nrf_twim_int_disable(p_twim, NRF_TWIM_ALL_INTS_MASK);
+ nrf_twim_shorts_disable(p_twim, NRF_TWIM_ALL_SHORTS_MASK);
+ nrf_twim_disable(p_twim);
+
+ p_cb->state = NRFX_DRV_STATE_INITIALIZED;
+ NRFX_LOG_INFO("Instance disabled: %d.", p_instance->drv_inst_idx);
+}
+
+
+bool nrfx_twim_is_busy(nrfx_twim_t const * p_instance)
+{
+ twim_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
+ return p_cb->busy;
+}
+
+
+static void twim_list_enable_handle(NRF_TWIM_Type * p_twim, uint32_t flags)
+{
+ if (NRFX_TWIM_FLAG_TX_POSTINC & flags)
+ {
+ nrf_twim_tx_list_enable(p_twim);
+ }
+ else
+ {
+ nrf_twim_tx_list_disable(p_twim);
+ }
+
+ if (NRFX_TWIM_FLAG_RX_POSTINC & flags)
+ {
+ nrf_twim_rx_list_enable(p_twim);
+ }
+ else
+ {
+ nrf_twim_rx_list_disable(p_twim);
+ }
+}
+static nrfx_err_t twim_xfer(twim_control_block_t * p_cb,
+ NRF_TWIM_Type * p_twim,
+ nrfx_twim_xfer_desc_t const * p_xfer_desc,
+ uint32_t flags)
+{
+ nrfx_err_t err_code = NRFX_SUCCESS;
+ nrf_twim_task_t start_task = NRF_TWIM_TASK_STARTTX;
+ p_cb->error = false;
+
+ if (!nrfx_is_in_ram(p_xfer_desc->p_primary_buf))
+ {
+ err_code = NRFX_ERROR_INVALID_ADDR;
+ NRFX_LOG_WARNING("Function: %s, error code: %s.",
+ __func__,
+ NRFX_LOG_ERROR_STRING_GET(err_code));
+ return err_code;
+ }
+ /* Block TWI interrupts to ensure that function is not interrupted by TWI interrupt. */
+ nrf_twim_int_disable(p_twim, NRF_TWIM_ALL_INTS_MASK);
+ if (p_cb->busy)
+ {
+ nrf_twim_int_enable(p_twim, p_cb->int_mask);
+ err_code = NRFX_ERROR_BUSY;
+ NRFX_LOG_WARNING("Function: %s, error code: %s.",
+ __func__,
+ NRFX_LOG_ERROR_STRING_GET(err_code));
+ return err_code;
+ }
+ else
+ {
+ p_cb->busy = ((NRFX_TWIM_FLAG_NO_XFER_EVT_HANDLER & flags) ||
+ (NRFX_TWIM_FLAG_REPEATED_XFER & flags)) ? false: true;
+ }
+
+ p_cb->xfer_desc = *p_xfer_desc;
+ p_cb->repeated = (flags & NRFX_TWIM_FLAG_REPEATED_XFER) ? true : false;
+ p_cb->flags = flags;
+ nrf_twim_address_set(p_twim, p_xfer_desc->address);
+
+ nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_STOPPED);
+ nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_ERROR);
+ nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_LASTTX);
+ nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_SUSPENDED);
+
+ twim_list_enable_handle(p_twim, flags);
+ switch (p_xfer_desc->type)
+ {
+ case NRFX_TWIM_XFER_TXTX:
+ NRFX_ASSERT(!(flags & NRFX_TWIM_FLAG_REPEATED_XFER));
+ NRFX_ASSERT(!(flags & NRFX_TWIM_FLAG_HOLD_XFER));
+ NRFX_ASSERT(!(flags & NRFX_TWIM_FLAG_NO_XFER_EVT_HANDLER));
+ if (!nrfx_is_in_ram(p_xfer_desc->p_secondary_buf))
+ {
+ err_code = NRFX_ERROR_INVALID_ADDR;
+ NRFX_LOG_WARNING("Function: %s, error code: %s.",
+ __func__,
+ NRFX_LOG_ERROR_STRING_GET(err_code));
+ return err_code;
+ }
+ nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_SUSPEND_MASK);
+ nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length);
+ nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED);
+ nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
+ nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STARTTX);
+ while (!nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_TXSTARTED))
+ {}
+ NRFX_LOG_DEBUG("TWIM: Event: %s.", EVT_TO_STR_TWIM(NRF_TWIM_EVENT_TXSTARTED));
+ nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED);
+ nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_secondary_buf, p_xfer_desc->secondary_length);
+ p_cb->int_mask = NRF_TWIM_INT_SUSPENDED_MASK;
+ break;
+ case NRFX_TWIM_XFER_TXRX:
+ nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length);
+ if (!nrfx_is_in_ram(p_xfer_desc->p_secondary_buf))
+ {
+ err_code = NRFX_ERROR_INVALID_ADDR;
+ NRFX_LOG_WARNING("Function: %s, error code: %s.",
+ __func__,
+ NRFX_LOG_ERROR_STRING_GET(err_code));
+ return err_code;
+ }
+ nrf_twim_rx_buffer_set(p_twim, p_xfer_desc->p_secondary_buf, p_xfer_desc->secondary_length);
+ nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_STARTRX_MASK |
+ NRF_TWIM_SHORT_LASTRX_STOP_MASK);
+ p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK;
+ nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
+ break;
+ case NRFX_TWIM_XFER_TX:
+ nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length);
+ if (NRFX_TWIM_FLAG_TX_NO_STOP & flags)
+ {
+ nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_SUSPEND_MASK);
+ p_cb->int_mask = NRF_TWIM_INT_SUSPENDED_MASK;
+ }
+ else
+ {
+ nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_STOP_MASK);
+ p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK;
+ }
+ nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
+ break;
+ case NRFX_TWIM_XFER_RX:
+ nrf_twim_rx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length);
+ nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTRX_STOP_MASK);
+ p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK;
+ start_task = NRF_TWIM_TASK_STARTRX;
+ nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
+ break;
+ default:
+ err_code = NRFX_ERROR_INVALID_PARAM;
+ break;
+ }
+
+ if (!(flags & NRFX_TWIM_FLAG_HOLD_XFER) && (p_xfer_desc->type != NRFX_TWIM_XFER_TXTX))
+ {
+ nrf_twim_task_trigger(p_twim, start_task);
+ }
+
+ if (p_cb->handler)
+ {
+ if (flags & NRFX_TWIM_FLAG_NO_XFER_EVT_HANDLER)
+ {
+ p_cb->int_mask = 0;
+ }
+
+ if (!(flags & NRFX_TWIM_FLAG_NO_SPURIOUS_STOP_CHECK))
+ {
+ p_cb->int_mask |= NRF_TWIM_INT_STOPPED_MASK;
+ }
+
+ // Interrupts for ERROR are implicitly enabled, regardless of driver configuration.
+ p_cb->int_mask |= NRF_TWIM_INT_ERROR_MASK;
+ nrf_twim_int_enable(p_twim, p_cb->int_mask);
+
+#if NRFX_CHECK(NRFX_TWIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED)
+ if ((flags & NRFX_TWIM_FLAG_HOLD_XFER) && (p_xfer_desc->type != NRFX_TWIM_XFER_RX))
+ {
+ twim_list_enable_handle(p_twim, 0);
+ p_twim->FREQUENCY = 0;
+ nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED);
+ nrf_twim_int_enable(p_twim, NRF_TWIM_INT_TXSTARTED_MASK);
+ }
+ else
+ {
+ nrf_twim_frequency_set(p_twim, p_cb->bus_frequency);
+ }
+#endif
+ }
+ else
+ {
+ bool transmission_finished = false;
+ do {
+ if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_SUSPENDED))
+ {
+ NRFX_LOG_DEBUG("TWIM: Event: %s.", EVT_TO_STR_TWIM(NRF_TWIM_EVENT_SUSPENDED));
+ transmission_finished = true;
+ }
+
+ if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_STOPPED))
+ {
+ nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_STOPPED);
+ NRFX_LOG_DEBUG("TWIM: Event: %s.", EVT_TO_STR_TWIM(NRF_TWIM_EVENT_STOPPED));
+ transmission_finished = true;
+ }
+
+ if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_ERROR))
+ {
+ nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_ERROR);
+ NRFX_LOG_DEBUG("TWIM: Event: %s.", EVT_TO_STR_TWIM(NRF_TWIM_EVENT_ERROR));
+
+ bool lasttx_triggered = nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_LASTTX);
+ uint32_t shorts_mask = nrf_twim_shorts_get(p_twim);
+
+ if (!(lasttx_triggered && (shorts_mask & NRF_TWIM_SHORT_LASTTX_STOP_MASK)))
+ {
+ // Unless LASTTX event arrived and LASTTX_STOP shortcut is active,
+ // triggering of STOP task in case of error has to be done manually.
+ nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
+ nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STOP);
+
+ // Mark transmission as not finished yet,
+ // as STOPPED event is expected to arrive.
+ // If LASTTX_SUSPENDED shortcut is active,
+ // NACK has been received on last byte sent
+ // and SUSPENDED event happened to be checked before ERROR,
+ // transmission will be marked as finished.
+ // In such case this flag has to be overwritten.
+ transmission_finished = false;
+ }
+
+ if (lasttx_triggered && (shorts_mask & NRF_TWIM_SHORT_LASTTX_SUSPEND_MASK))
+ {
+ // When STOP task was triggered just before SUSPEND task has taken effect,
+ // SUSPENDED event may not arrive.
+ // However if SUSPENDED arrives it always arrives after ERROR.
+ // Therefore SUSPENDED has to be cleared
+ // so it does not cause premature termination of busy loop
+ // waiting for STOPPED event to arrive.
+ nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_SUSPENDED);
+
+ // Mark transmission as not finished yet,
+ // for same reasons as above.
+ transmission_finished = false;
+ }
+ }
+ } while (!transmission_finished);
+
+ uint32_t errorsrc = nrf_twim_errorsrc_get_and_clear(p_twim);
+
+ p_cb->busy = false;
+
+ if (errorsrc)
+ {
+ err_code = twi_process_error(errorsrc);
+ }
+ else
+ {
+ if (!(flags & NRFX_TWIM_FLAG_NO_SPURIOUS_STOP_CHECK) &&
+ !xfer_completeness_check(p_twim, p_cb))
+ {
+ err_code = NRFX_ERROR_INTERNAL;
+ }
+ }
+ }
+ return err_code;
+}
+
+
+nrfx_err_t nrfx_twim_xfer(nrfx_twim_t const * p_instance,
+ nrfx_twim_xfer_desc_t const * p_xfer_desc,
+ uint32_t flags)
+{
+ NRFX_ASSERT(TWIM_LENGTH_VALIDATE(p_instance->drv_inst_idx,
+ p_xfer_desc->primary_length,
+ p_xfer_desc->secondary_length));
+
+ nrfx_err_t err_code = NRFX_SUCCESS;
+ twim_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
+
+ // TXRX and TXTX transfers are supported only in non-blocking mode.
+ NRFX_ASSERT( !((p_cb->handler == NULL) && (p_xfer_desc->type == NRFX_TWIM_XFER_TXRX)));
+ NRFX_ASSERT( !((p_cb->handler == NULL) && (p_xfer_desc->type == NRFX_TWIM_XFER_TXTX)));
+
+ NRFX_LOG_INFO("Transfer type: %s.", TRANSFER_TO_STR(p_xfer_desc->type));
+ NRFX_LOG_INFO("Transfer buffers length: primary: %d, secondary: %d.",
+ p_xfer_desc->primary_length,
+ p_xfer_desc->secondary_length);
+ NRFX_LOG_DEBUG("Primary buffer data:");
+ NRFX_LOG_HEXDUMP_DEBUG(p_xfer_desc->p_primary_buf,
+ p_xfer_desc->primary_length * sizeof(p_xfer_desc->p_primary_buf[0]));
+ NRFX_LOG_DEBUG("Secondary buffer data:");
+ NRFX_LOG_HEXDUMP_DEBUG(p_xfer_desc->p_secondary_buf,
+ p_xfer_desc->secondary_length * sizeof(p_xfer_desc->p_secondary_buf[0]));
+
+ err_code = twim_xfer(p_cb, (NRF_TWIM_Type *)p_instance->p_twim, p_xfer_desc, flags);
+ NRFX_LOG_WARNING("Function: %s, error code: %s.",
+ __func__,
+ NRFX_LOG_ERROR_STRING_GET(err_code));
+ return err_code;
+}
+
+uint32_t nrfx_twim_start_task_get(nrfx_twim_t const * p_instance,
+ nrfx_twim_xfer_type_t xfer_type)
+{
+ return nrf_twim_task_address_get(p_instance->p_twim,
+ (xfer_type != NRFX_TWIM_XFER_RX) ? NRF_TWIM_TASK_STARTTX : NRF_TWIM_TASK_STARTRX);
+}
+
+uint32_t nrfx_twim_stopped_event_get(nrfx_twim_t const * p_instance)
+{
+ return nrf_twim_event_address_get(p_instance->p_twim, NRF_TWIM_EVENT_STOPPED);
+}
+
+static void twim_irq_handler(NRF_TWIM_Type * p_twim, twim_control_block_t * p_cb)
+{
+
+#if NRFX_CHECK(NRFX_TWIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED)
+ /* Handle only workaround case. Can be used without TWIM handler in IRQs. */
+ if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_TXSTARTED))
+ {
+ nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED);
+ nrf_twim_int_disable(p_twim, NRF_TWIM_INT_TXSTARTED_MASK);
+ if (p_twim->FREQUENCY == 0)
+ {
+ // Set enable to zero to reset TWIM internal state.
+ nrf_twim_disable(p_twim);
+ nrf_twim_enable(p_twim);
+
+ // Set proper frequency.
+ nrf_twim_frequency_set(p_twim, p_cb->bus_frequency);
+ twim_list_enable_handle(p_twim, p_cb->flags);
+
+ // Start proper transmission.
+ nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STARTTX);
+ return;
+ }
+ }
+#endif
+
+ NRFX_ASSERT(p_cb->handler);
+
+ if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_ERROR))
+ {
+ nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_ERROR);
+ NRFX_LOG_DEBUG("TWIM: Event: %s.", EVT_TO_STR_TWIM(NRF_TWIM_EVENT_ERROR));
+ if (!nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_STOPPED))
+ {
+ nrf_twim_int_disable(p_twim, p_cb->int_mask);
+ p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK;
+ nrf_twim_int_enable(p_twim, p_cb->int_mask);
+
+ if (!(nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_LASTTX) &&
+ (nrf_twim_shorts_get(p_twim) & NRF_TWIM_SHORT_LASTTX_STOP_MASK)))
+ {
+ nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
+ nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STOP);
+ }
+
+ p_cb->error = true;
+ return;
+ }
+ }
+
+ nrfx_twim_evt_t event;
+
+ if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_STOPPED))
+ {
+ NRFX_LOG_DEBUG("TWIM: Event: %s.", EVT_TO_STR_TWIM(NRF_TWIM_EVENT_STOPPED));
+ nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_STOPPED);
+
+ if (!(p_cb->flags & NRFX_TWIM_FLAG_NO_SPURIOUS_STOP_CHECK) && !p_cb->error)
+ {
+ p_cb->error = !xfer_completeness_check(p_twim, p_cb);
+ }
+
+ // Further processing of STOPPED event is valid only if NO_XFER_EVT_HANDLER
+ // setting is not used.
+ if (!(p_cb->flags & NRFX_TWIM_FLAG_NO_XFER_EVT_HANDLER))
+ {
+ event.xfer_desc = p_cb->xfer_desc;
+ nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_LASTTX);
+ nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_LASTRX);
+ if (!p_cb->repeated || p_cb->error)
+ {
+ nrf_twim_shorts_set(p_twim, 0);
+ p_cb->int_mask = 0;
+ nrf_twim_int_disable(p_twim, NRF_TWIM_ALL_INTS_MASK);
+
+ // At this point interrupt handler should not be invoked again for current transfer.
+ // If STOPPED arrived during ERROR processing,
+ // its pending interrupt should be ignored.
+ // Otherwise spurious NRFX_TWIM_EVT_DONE or NRFX_TWIM_EVT_BUS_ERROR
+ // would be passed to user's handler.
+ NRFX_IRQ_PENDING_CLEAR(nrfx_get_irq_number(p_twim));
+ }
+ }
+
+#if NRFX_CHECK(NRFX_TWIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED)
+ else if (p_cb->xfer_desc.type != NRFX_TWIM_XFER_RX)
+ {
+ /* Add Anomaly 109 workaround for each potential repeated transfer starting from TX. */
+ twim_list_enable_handle(p_twim, 0);
+ p_twim->FREQUENCY = 0;
+ nrf_twim_int_enable(p_twim, NRF_TWIM_INT_TXSTARTED_MASK);
+ }
+#endif
+ }
+ else
+ {
+ nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_SUSPENDED);
+ NRFX_LOG_DEBUG("TWIM: Event: %s.", EVT_TO_STR_TWIM(NRF_TWIM_EVENT_SUSPENDED));
+ if (p_cb->xfer_desc.type == NRFX_TWIM_XFER_TX)
+ {
+ event.xfer_desc = p_cb->xfer_desc;
+ if (!p_cb->repeated)
+ {
+ nrf_twim_shorts_set(p_twim, 0);
+ p_cb->int_mask = 0;
+ nrf_twim_int_disable(p_twim, NRF_TWIM_ALL_INTS_MASK);
+
+ // At this point interrupt handler should not be invoked again for current transfer.
+ // If STOPPED arrived during SUSPENDED processing,
+ // its pending interrupt should be ignored.
+ // Otherwise spurious NRFX_TWIM_EVT_DONE or NRFX_TWIM_EVT_BUS_ERROR
+ // would be passed to user's handler.
+ NRFX_IRQ_PENDING_CLEAR(nrfx_get_irq_number(p_twim));
+ }
+ }
+ else
+ {
+ nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_STOP_MASK);
+ p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK;
+ nrf_twim_int_disable(p_twim, NRF_TWIM_ALL_INTS_MASK);
+ nrf_twim_int_enable(p_twim, p_cb->int_mask);
+ nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STARTTX);
+ nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
+ return;
+ }
+ }
+
+ uint32_t errorsrc = nrf_twim_errorsrc_get_and_clear(p_twim);
+ if (errorsrc & NRF_TWIM_ERROR_ADDRESS_NACK)
+ {
+ event.type = NRFX_TWIM_EVT_ADDRESS_NACK;
+ NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRFX_TWIM_EVT_ADDRESS_NACK));
+ }
+ else if (errorsrc & NRF_TWIM_ERROR_DATA_NACK)
+ {
+ event.type = NRFX_TWIM_EVT_DATA_NACK;
+ NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRFX_TWIM_EVT_DATA_NACK));
+ }
+ else if (errorsrc & NRF_TWIM_ERROR_OVERRUN)
+ {
+ event.type = NRFX_TWIM_EVT_OVERRUN;
+ NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRFX_TWIM_EVT_OVERRUN));
+ }
+ else if (p_cb->error)
+ {
+ event.type = NRFX_TWIM_EVT_BUS_ERROR;
+ NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRFX_TWIM_EVT_BUS_ERROR));
+ }
+ else
+ {
+ event.type = NRFX_TWIM_EVT_DONE;
+ NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRFX_TWIM_EVT_DONE));
+ }
+
+ if (!p_cb->repeated)
+ {
+ p_cb->busy = false;
+ }
+
+ if (!(p_cb->flags & NRFX_TWIM_FLAG_NO_XFER_EVT_HANDLER) || p_cb->error)
+ {
+ p_cb->handler(&event, p_cb->p_context);
+ }
+}
+
+#if NRFX_CHECK(NRFX_TWIM0_ENABLED)
+void nrfx_twim_0_irq_handler(void)
+{
+ twim_irq_handler(NRF_TWIM0, &m_cb[NRFX_TWIM0_INST_IDX]);
+}
+#endif
+
+#if NRFX_CHECK(NRFX_TWIM1_ENABLED)
+void nrfx_twim_1_irq_handler(void)
+{
+ twim_irq_handler(NRF_TWIM1, &m_cb[NRFX_TWIM1_INST_IDX]);
+}
+#endif
+
+#if NRFX_CHECK(NRFX_TWIM2_ENABLED)
+void nrfx_twim_2_irq_handler(void)
+{
+ twim_irq_handler(NRF_TWIM2, &m_cb[NRFX_TWIM2_INST_IDX]);
+}
+#endif
+
+#if NRFX_CHECK(NRFX_TWIM3_ENABLED)
+void nrfx_twim_3_irq_handler(void)
+{
+ twim_irq_handler(NRF_TWIM3, &m_cb[NRFX_TWIM3_INST_IDX]);
+}
+#endif
+
+#endif // NRFX_CHECK(NRFX_TWIM_ENABLED)
diff --git a/platform/ext/target/nordic_nrf/common/core/nrfx/hal/nrf_qspi.h b/platform/ext/target/nordic_nrf/common/core/nrfx/hal/nrf_qspi.h
new file mode 100644
index 000000000..4ee209e0a
--- /dev/null
+++ b/platform/ext/target/nordic_nrf/common/core/nrfx/hal/nrf_qspi.h
@@ -0,0 +1,966 @@
+/*
+ * Copyright (c) 2016 - 2020, 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 the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef NRF_QSPI_H__
+#define NRF_QSPI_H__
+
+#include <nrfx.h>
+#include <nrf_erratas.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup nrf_qspi_hal QSPI HAL
+ * @{
+ * @ingroup nrf_qspi
+ * @brief Hardware access layer for managing the QSPI peripheral.
+ */
+
+#if defined(QSPI_XIPEN_XIPEN_Msk) || defined(__NRFX_DOXYGEN__)
+/** @brief Symbol indicating whether XIP can be explicitly enabled or disabled via XIPEN register. */
+#define NRF_QSPI_HAS_XIPEN 1
+#else
+#define NRF_QSPI_HAS_XIPEN 0
+#endif
+
+#if defined(QSPI_XIP_ENC_ENABLE_ENABLE_Msk) || defined(__NRFX_DOXYGEN__)
+/** @brief Symbol indicating whether encryption for XIP is present. */
+#define NRF_QSPI_HAS_XIP_ENC 1
+#else
+#define NRF_QSPI_HAS_XIP_ENC 0
+#endif
+
+#if defined(QSPI_DMA_ENC_ENABLE_ENABLE_Msk) || defined(__NRFX_DOXYGEN__)
+/** @brief Symbol indicating whether encryption for EasyDMA is present. */
+#define NRF_QSPI_HAS_DMA_ENC 1
+#else
+#define NRF_QSPI_HAS_DMA_ENC 0
+#endif
+
+#if defined(QSPI_IFCONFIG1_SPIMODE_MODE3) || defined(__NRFX_DOXYGEN__)
+/** @brief Symbol indicating whether support for QSPI mode 1 is present. */
+#define NRF_QSPI_HAS_MODE_1 1
+#else
+#define NRF_QSPI_HAS_MODE_1 0
+#endif
+
+#if defined(NRF53_SERIES) || defined(__NRFX_DOXYGEN__)
+/** @brief Value representing QSPI base clock frequency. */
+#define NRF_QSPI_BASE_CLOCK_FREQ 96000000uL
+#else
+#define NRF_QSPI_BASE_CLOCK_FREQ 32000000uL
+#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
+{
+ 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. */
+ NRF_QSPI_TASK_DEACTIVATE = offsetof(NRF_QSPI_Type, TASKS_DEACTIVATE), /**< Deactivate the QSPI interface. */
+} nrf_qspi_task_t;
+
+/** @brief QSPI events. */
+typedef enum
+{
+ NRF_QSPI_EVENT_READY = offsetof(NRF_QSPI_Type, EVENTS_READY) /**< QSPI peripheral is ready after it executes any task. */
+} 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 base clock frequency divider values. */
+typedef enum
+{
+ NRF_QSPI_FREQ_DIV1, /**< Divide by 1. */
+ NRF_QSPI_FREQ_DIV2, /**< Divide by 2. */
+ NRF_QSPI_FREQ_DIV3, /**< Divide by 3. */
+ NRF_QSPI_FREQ_DIV4, /**< Divide by 4. */
+ NRF_QSPI_FREQ_DIV5, /**< Divide by 5. */
+ NRF_QSPI_FREQ_DIV6, /**< Divide by 6. */
+ NRF_QSPI_FREQ_DIV7, /**< Divide by 7. */
+ NRF_QSPI_FREQ_DIV8, /**< Divide by 8. */
+ NRF_QSPI_FREQ_DIV9, /**< Divide by 9. */
+ NRF_QSPI_FREQ_DIV10, /**< Divide by 10. */
+ NRF_QSPI_FREQ_DIV11, /**< Divide by 11. */
+ NRF_QSPI_FREQ_DIV12, /**< Divide by 12. */
+ NRF_QSPI_FREQ_DIV13, /**< Divide by 13. */
+ NRF_QSPI_FREQ_DIV14, /**< Divide by 14. */
+ NRF_QSPI_FREQ_DIV15, /**< Divide by 15. */
+ NRF_QSPI_FREQ_DIV16, /**< Divide by 16. */
+} nrf_qspi_frequency_t;
+
+#if defined(NRF52_SERIES)
+/** Symbols translation for backward compatibility. */
+#define NRF_QSPI_FREQ_32MDIV1 NRF_QSPI_FREQ_DIV1
+#define NRF_QSPI_FREQ_32MDIV2 NRF_QSPI_FREQ_DIV2
+#define NRF_QSPI_FREQ_32MDIV3 NRF_QSPI_FREQ_DIV3
+#define NRF_QSPI_FREQ_32MDIV4 NRF_QSPI_FREQ_DIV4
+#define NRF_QSPI_FREQ_32MDIV5 NRF_QSPI_FREQ_DIV5
+#define NRF_QSPI_FREQ_32MDIV6 NRF_QSPI_FREQ_DIV6
+#define NRF_QSPI_FREQ_32MDIV7 NRF_QSPI_FREQ_DIV7
+#define NRF_QSPI_FREQ_32MDIV8 NRF_QSPI_FREQ_DIV8
+#define NRF_QSPI_FREQ_32MDIV9 NRF_QSPI_FREQ_DIV9
+#define NRF_QSPI_FREQ_32MDIV10 NRF_QSPI_FREQ_DIV10
+#define NRF_QSPI_FREQ_32MDIV11 NRF_QSPI_FREQ_DIV11
+#define NRF_QSPI_FREQ_32MDIV12 NRF_QSPI_FREQ_DIV12
+#define NRF_QSPI_FREQ_32MDIV13 NRF_QSPI_FREQ_DIV13
+#define NRF_QSPI_FREQ_32MDIV14 NRF_QSPI_FREQ_DIV14
+#define NRF_QSPI_FREQ_32MDIV15 NRF_QSPI_FREQ_DIV15
+#define NRF_QSPI_FREQ_32MDIV16 NRF_QSPI_FREQ_DIV16
+#endif
+
+/** @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). */
+#if NRF_QSPI_HAS_MODE_1
+ NRF_QSPI_MODE_1 = QSPI_IFCONFIG1_SPIMODE_MODE3 /**< Mode 1 (CPOL=1, CPHA=1). */
+#endif
+} 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 Pin 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 the 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 or 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 QSPI base clock frequency divider.
+ * To calculate @p sck_freq value corresponding to chosen frequency,
+ * use the following equation:
+ *
+ * sck_freq = (NRF_QSPI_BASE_CLOCK_FREQ / frequency) - 1
+ *
+ * @note Achievable frequencies are determined by available
+ * divider values and QSPI base clock frequency.
+ */
+} nrf_qspi_phy_conf_t;
+
+
+#if NRF_QSPI_HAS_XIP_ENC || NRF_QSPI_HAS_DMA_ENC
+/** @brief QSPI encryption settings for XIP and DMA transfers. */
+typedef struct
+{
+ uint32_t key[4]; /**< AES 128-bit key, stored on 4 32-bit words. */
+ uint32_t nonce[3]; /**< AES 96-bit nonce, stored on 3 32-bit words. */
+} nrf_qspi_encryption_t;
+#endif
+
+/**
+ * @brief Function for activating the specified QSPI task.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] task Task to be activated.
+ */
+NRF_STATIC_INLINE void nrf_qspi_task_trigger(NRF_QSPI_Type * p_reg, nrf_qspi_task_t task);
+
+/**
+ * @brief Function for getting the address of the specified QSPI task register.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] task QSPI task.
+ *
+ * @return Address of the specified task register.
+ */
+NRF_STATIC_INLINE uint32_t nrf_qspi_task_address_get(NRF_QSPI_Type const * p_reg,
+ nrf_qspi_task_t task);
+
+/**
+ * @brief Function for clearing the specified QSPI event.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] event Event to be cleared.
+ */
+NRF_STATIC_INLINE void nrf_qspi_event_clear(NRF_QSPI_Type * p_reg, nrf_qspi_event_t event);
+
+/**
+ * @brief Function for retrieving the state of the QSPI event.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] event Event to be checked.
+ *
+ * @retval true The event has been generated.
+ * @retval false The event has not been generated.
+ */
+NRF_STATIC_INLINE bool nrf_qspi_event_check(NRF_QSPI_Type const * p_reg, nrf_qspi_event_t event);
+
+/**
+ * @brief Function for getting the address of the specified QSPI event register.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] event The specified event.
+ *
+ * @return Address of the specified event register.
+ */
+NRF_STATIC_INLINE uint32_t nrf_qspi_event_address_get(NRF_QSPI_Type const * p_reg,
+ nrf_qspi_event_t event);
+
+/**
+ * @brief Function for enabling specified interrupts.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] mask Mask of interrupts to be enabled.
+ */
+NRF_STATIC_INLINE void nrf_qspi_int_enable(NRF_QSPI_Type * p_reg, uint32_t mask);
+
+/**
+ * @brief Function for disabling specified interrupts.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] mask Mask of interrupts to be disabled.
+ */
+NRF_STATIC_INLINE void nrf_qspi_int_disable(NRF_QSPI_Type * p_reg, uint32_t mask);
+
+/**
+ * @brief Function for checking if the specified interrupts are enabled.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] mask Mask of interrupts to be checked.
+ *
+ * @return Mask of enabled interrupts.
+ */
+NRF_STATIC_INLINE uint32_t nrf_qspi_int_enable_check(NRF_QSPI_Type const * p_reg, uint32_t mask);
+
+/**
+ * @brief Function for enabling the QSPI peripheral.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ */
+NRF_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 structure of registers of the peripheral.
+ */
+NRF_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 structure of registers of the peripheral.
+ * @param[in] p_pins Pointer to the pins configuration structure. See @ref nrf_qspi_pins_t.
+ */
+NRF_STATIC_INLINE void nrf_qspi_pins_set(NRF_QSPI_Type * p_reg,
+ nrf_qspi_pins_t const * p_pins);
+
+/**
+ * @brief Function for setting the QSPI XIPOFFSET register.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] xip_offset Address offset in the external memory for Execute in Place operation.
+ */
+NRF_STATIC_INLINE void nrf_qspi_xip_offset_set(NRF_QSPI_Type * p_reg,
+ uint32_t xip_offset);
+
+/**
+ * @brief Function for setting the QSPI IFCONFIG0 register.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] p_config Pointer to the QSPI protocol interface configuration structure.
+ * See @ref nrf_qspi_prot_conf_t.
+ */
+NRF_STATIC_INLINE void nrf_qspi_ifconfig0_set(NRF_QSPI_Type * p_reg,
+ nrf_qspi_prot_conf_t const * p_config);
+
+/**
+ * @brief Function for setting the QSPI IFCONFIG1 register.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] p_config Pointer to the QSPI physical interface configuration structure.
+ * See @ref nrf_qspi_phy_conf_t.
+ */
+NRF_STATIC_INLINE void nrf_qspi_ifconfig1_set(NRF_QSPI_Type * p_reg,
+ nrf_qspi_phy_conf_t const * p_config);
+
+/**
+ * @brief Function for setting the QSPI ADDRCONF register.
+ *
+ * This 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 structure of registers of the peripheral.
+ * @param[in] p_config Pointer to the addressing mode configuration structure.
+ * See @ref nrf_qspi_addrconfig_conf_t.
+*/
+NRF_STATIC_INLINE void nrf_qspi_addrconfig_set(NRF_QSPI_Type * p_reg,
+ nrf_qspi_addrconfig_conf_t const * p_config);
+
+/**
+ * @brief Function for setting write data into the peripheral register (without starting the process).
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @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.
+ */
+NRF_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 structure of registers of the peripheral.
+ * @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.
+ */
+NRF_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 structure of registers of the peripheral.
+ * @param[in] erase_addr Start address to erase. Address must have padding set to 4 bytes.
+ * @param[in] len Size of erasing area.
+ */
+NRF_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 structure of registers of the peripheral.
+ *
+ * @return Peripheral status register.
+ */
+NRF_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 structure of registers of the peripheral.
+ *
+ * @return Device status register (lower byte).
+ */
+NRF_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 structure of registers of the peripheral.
+ *
+ * @retval true The QSPI is busy.
+ * @retval false The QSPI is ready.
+ */
+NRF_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 structure of registers of the peripheral.
+ * @param[in] length Length of the custom instruction data.
+ * @param[in] p_tx_data Pointer to the data to send with the custom instruction.
+ */
+NRF_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 structure of registers of the peripheral.
+ * @param[in] length Length of the custom instruction data.
+ * @param[in] p_rx_data Pointer to the reading buffer.
+ */
+NRF_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 structure of registers of the peripheral.
+ * @param[in] p_config Pointer to the custom instruction configuration structure.
+ * See @ref nrf_qspi_cinstr_conf_t.
+ */
+NRF_STATIC_INLINE void nrf_qspi_cinstr_transfer_start(NRF_QSPI_Type * p_reg,
+ nrf_qspi_cinstr_conf_t const * p_config);
+
+/**
+ * @brief Function for starting a custom instruction long transfer.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] p_config Pointer to the custom instruction configuration structure.
+ * See @ref nrf_qspi_cinstr_conf_t.
+ */
+NRF_STATIC_INLINE void nrf_qspi_cinstr_long_transfer_start(NRF_QSPI_Type * p_reg,
+ nrf_qspi_cinstr_conf_t const * p_config);
+
+/**
+ * @brief Function for checking whether a custom instruction long transfer is ongoing.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ *
+ * @retval true Custom instruction long transfer is ongoing.
+ * @retval false Custom instruction long transfer is not ongoing.
+ */
+NRF_STATIC_INLINE bool nrf_qspi_cinstr_long_transfer_is_ongoing(NRF_QSPI_Type const * p_reg);
+
+/**
+ * @brief Function for continuing a custom instruction long transfer.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] length Length of the custom instruction data.
+ * @param[in] finalize True if the custom instruction long transfer is to be finalized.
+ * False if the custom instruction long transfer is to be continued.
+ */
+NRF_STATIC_INLINE void nrf_qspi_cinstr_long_transfer_continue(NRF_QSPI_Type * p_reg,
+ nrf_qspi_cinstr_len_t length,
+ bool finalize);
+
+#if NRF_QSPI_HAS_XIPEN
+/**
+ * @brief Function for enabling or disabling Execute in Place (XIP) operation.
+ *
+ * @note XIP can be enabled after reset. See Product Specification.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] enable True if XIP is to be enabled, false otherwise.
+ */
+NRF_STATIC_INLINE void nrf_qspi_xip_set(NRF_QSPI_Type * p_reg, bool enable);
+#endif
+
+#if NRF_QSPI_HAS_XIP_ENC
+/**
+ * @brief Function for configuring the XIP encryption.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] p_cfg Pointer to encryption configuration structure.
+ */
+NRF_STATIC_INLINE void nrf_qspi_xip_encryption_configure(NRF_QSPI_Type * p_reg,
+ nrf_qspi_encryption_t const * p_cfg);
+
+/**
+ * @brief Function for enabling or disabling the XIP encryption.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] enable True if XIP encryption is to be enabled, false otherwise.
+ */
+NRF_STATIC_INLINE void nrf_qspi_xip_encryption_set(NRF_QSPI_Type * p_reg, bool enable);
+#endif
+
+#if NRF_QSPI_HAS_DMA_ENC
+/**
+ * @brief Function for configuring the EasyDMA encryption.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] p_cfg Pointer to encryption configuration structure.
+ */
+NRF_STATIC_INLINE void nrf_qspi_dma_encryption_configure(NRF_QSPI_Type * p_reg,
+ nrf_qspi_encryption_t const * p_cfg);
+
+/**
+ * @brief Function for enabling or disabling the EasyDMA encryption.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] enable True if EasyDMA encryption is to be enabled, false otherwise.
+ */
+NRF_STATIC_INLINE void nrf_qspi_dma_encryption_set(NRF_QSPI_Type * p_reg, bool enable);
+#endif
+
+#ifndef NRF_DECLARE_ONLY
+
+NRF_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;
+}
+
+NRF_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);
+}
+
+NRF_STATIC_INLINE void nrf_qspi_event_clear(NRF_QSPI_Type * p_reg, nrf_qspi_event_t event)
+{
+ *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
+}
+
+NRF_STATIC_INLINE bool nrf_qspi_event_check(NRF_QSPI_Type const * p_reg, nrf_qspi_event_t event)
+{
+ return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
+}
+
+NRF_STATIC_INLINE uint32_t nrf_qspi_event_address_get(NRF_QSPI_Type const * p_reg,
+ nrf_qspi_event_t event)
+{
+ return (uint32_t)((uint8_t *)p_reg + (uint32_t)event);
+}
+
+NRF_STATIC_INLINE void nrf_qspi_int_enable(NRF_QSPI_Type * p_reg, uint32_t mask)
+{
+ p_reg->INTENSET = mask;
+}
+
+NRF_STATIC_INLINE void nrf_qspi_int_disable(NRF_QSPI_Type * p_reg, uint32_t mask)
+{
+ p_reg->INTENCLR = mask;
+}
+
+NRF_STATIC_INLINE uint32_t nrf_qspi_int_enable_check(NRF_QSPI_Type const * p_reg, uint32_t mask)
+{
+ return p_reg->INTENSET & mask;
+}
+
+NRF_STATIC_INLINE void nrf_qspi_enable(NRF_QSPI_Type * p_reg)
+{
+ p_reg->ENABLE = (QSPI_ENABLE_ENABLE_Enabled << QSPI_ENABLE_ENABLE_Pos);
+}
+
+NRF_STATIC_INLINE void nrf_qspi_disable(NRF_QSPI_Type * p_reg)
+{
+ if (nrf52_errata_122())
+ {
+ // Workaround for anomaly 122: "QSPI: QSPI uses current after being disabled".
+ *(volatile uint32_t *)0x40029054ul = 1ul;
+ }
+ p_reg->ENABLE = (QSPI_ENABLE_ENABLE_Disabled << QSPI_ENABLE_ENABLE_Pos);
+}
+
+NRF_STATIC_INLINE void nrf_qspi_pins_set(NRF_QSPI_Type * p_reg, nrf_qspi_pins_t const * 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);
+}
+
+NRF_STATIC_INLINE void nrf_qspi_xip_offset_set(NRF_QSPI_Type * p_reg,
+ uint32_t xip_offset)
+{
+ p_reg->XIPOFFSET = xip_offset;
+}
+
+NRF_STATIC_INLINE void nrf_qspi_ifconfig0_set(NRF_QSPI_Type * p_reg,
+ nrf_qspi_prot_conf_t const * 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;
+}
+
+NRF_STATIC_INLINE void nrf_qspi_ifconfig1_set(NRF_QSPI_Type * p_reg,
+ nrf_qspi_phy_conf_t const * 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;
+}
+
+NRF_STATIC_INLINE void nrf_qspi_addrconfig_set(NRF_QSPI_Type * p_reg,
+ nrf_qspi_addrconfig_conf_t const * 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;
+}
+
+NRF_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;
+}
+
+NRF_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;
+}
+
+NRF_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;
+}
+
+NRF_STATIC_INLINE uint32_t nrf_qspi_status_reg_get(NRF_QSPI_Type const * p_reg)
+{
+ return p_reg->STATUS;
+}
+
+NRF_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;
+}
+
+NRF_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;
+}
+
+NRF_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;
+ /* FALLTHROUGH */
+ case NRF_QSPI_CINSTR_LEN_8B:
+ reg |= ((uint32_t)p_tx_data_8[6]) << QSPI_CINSTRDAT1_BYTE6_Pos;
+ /* FALLTHROUGH */
+ case NRF_QSPI_CINSTR_LEN_7B:
+ reg |= ((uint32_t)p_tx_data_8[5]) << QSPI_CINSTRDAT1_BYTE5_Pos;
+ /* FALLTHROUGH */
+ case NRF_QSPI_CINSTR_LEN_6B:
+ reg |= ((uint32_t)p_tx_data_8[4]);
+ p_reg->CINSTRDAT1 = reg;
+ reg = 0;
+ /* FALLTHROUGH */
+ case NRF_QSPI_CINSTR_LEN_5B:
+ reg |= ((uint32_t)p_tx_data_8[3]) << QSPI_CINSTRDAT0_BYTE3_Pos;
+ /* FALLTHROUGH */
+ case NRF_QSPI_CINSTR_LEN_4B:
+ reg |= ((uint32_t)p_tx_data_8[2]) << QSPI_CINSTRDAT0_BYTE2_Pos;
+ /* FALLTHROUGH */
+ case NRF_QSPI_CINSTR_LEN_3B:
+ reg |= ((uint32_t)p_tx_data_8[1]) << QSPI_CINSTRDAT0_BYTE1_Pos;
+ /* FALLTHROUGH */
+ case NRF_QSPI_CINSTR_LEN_2B:
+ reg |= ((uint32_t)p_tx_data_8[0]);
+ p_reg->CINSTRDAT0 = reg;
+ /* FALLTHROUGH */
+ case NRF_QSPI_CINSTR_LEN_1B:
+ /* Send only opcode. Case to avoid compiler warnings. */
+ break;
+ default:
+ break;
+ }
+}
+
+NRF_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 reg1 = p_reg->CINSTRDAT1;
+ uint32_t reg0 = p_reg->CINSTRDAT0;
+ switch (length)
+ {
+ case NRF_QSPI_CINSTR_LEN_9B:
+ p_rx_data_8[7] = (uint8_t)(reg1 >> QSPI_CINSTRDAT1_BYTE7_Pos);
+ /* FALLTHROUGH */
+ case NRF_QSPI_CINSTR_LEN_8B:
+ p_rx_data_8[6] = (uint8_t)(reg1 >> QSPI_CINSTRDAT1_BYTE6_Pos);
+ /* FALLTHROUGH */
+ case NRF_QSPI_CINSTR_LEN_7B:
+ p_rx_data_8[5] = (uint8_t)(reg1 >> QSPI_CINSTRDAT1_BYTE5_Pos);
+ /* FALLTHROUGH */
+ case NRF_QSPI_CINSTR_LEN_6B:
+ p_rx_data_8[4] = (uint8_t)(reg1);
+ /* FALLTHROUGH */
+ case NRF_QSPI_CINSTR_LEN_5B:
+ p_rx_data_8[3] = (uint8_t)(reg0 >> QSPI_CINSTRDAT0_BYTE3_Pos);
+ /* FALLTHROUGH */
+ case NRF_QSPI_CINSTR_LEN_4B:
+ p_rx_data_8[2] = (uint8_t)(reg0 >> QSPI_CINSTRDAT0_BYTE2_Pos);
+ /* FALLTHROUGH */
+ case NRF_QSPI_CINSTR_LEN_3B:
+ p_rx_data_8[1] = (uint8_t)(reg0 >> QSPI_CINSTRDAT0_BYTE1_Pos);
+ /* FALLTHROUGH */
+ case NRF_QSPI_CINSTR_LEN_2B:
+ p_rx_data_8[0] = (uint8_t)(reg0);
+ /* FALLTHROUGH */
+ case NRF_QSPI_CINSTR_LEN_1B:
+ /* Send only opcode. Case to avoid compiler warnings. */
+ break;
+ default:
+ break;
+ }
+}
+
+NRF_STATIC_INLINE void nrf_qspi_cinstr_transfer_start(NRF_QSPI_Type * p_reg,
+ nrf_qspi_cinstr_conf_t const * 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));
+}
+
+NRF_STATIC_INLINE void nrf_qspi_cinstr_long_transfer_start(NRF_QSPI_Type * p_reg,
+ nrf_qspi_cinstr_conf_t const * 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) |
+ (QSPI_CINSTRCONF_LFEN_Msk));
+}
+
+NRF_STATIC_INLINE bool nrf_qspi_cinstr_long_transfer_is_ongoing(NRF_QSPI_Type const * p_reg)
+{
+ return (bool)((p_reg->CINSTRCONF & (QSPI_CINSTRCONF_LFEN_Msk | QSPI_CINSTRCONF_LFSTOP_Msk))
+ == QSPI_CINSTRCONF_LFEN_Msk);
+}
+
+NRF_STATIC_INLINE void nrf_qspi_cinstr_long_transfer_continue(NRF_QSPI_Type * p_reg,
+ nrf_qspi_cinstr_len_t length,
+ bool finalize)
+{
+ uint32_t mask = (((uint32_t)length << QSPI_CINSTRCONF_LENGTH_Pos) | (QSPI_CINSTRCONF_LFEN_Msk));
+ mask |= (finalize ? QSPI_CINSTRCONF_LFSTOP_Msk : 0);
+
+ p_reg->CINSTRCONF = mask;
+}
+
+#if NRF_QSPI_HAS_XIPEN
+NRF_STATIC_INLINE void nrf_qspi_xip_set(NRF_QSPI_Type * p_reg, bool enable)
+{
+ p_reg->XIPEN = (enable ? QSPI_XIPEN_XIPEN_Enable << QSPI_XIPEN_XIPEN_Pos
+ : QSPI_XIPEN_XIPEN_Disable << QSPI_XIPEN_XIPEN_Pos);
+}
+#endif
+
+#if NRF_QSPI_HAS_XIP_ENC
+NRF_STATIC_INLINE void nrf_qspi_xip_encryption_configure(NRF_QSPI_Type * p_reg,
+ nrf_qspi_encryption_t const * p_cfg)
+{
+ p_reg->XIP_ENC.KEY0 = p_cfg->key[0];
+ p_reg->XIP_ENC.KEY1 = p_cfg->key[1];
+ p_reg->XIP_ENC.KEY2 = p_cfg->key[2];
+ p_reg->XIP_ENC.KEY3 = p_cfg->key[3];
+ p_reg->XIP_ENC.NONCE0 = p_cfg->nonce[0];
+ p_reg->XIP_ENC.NONCE1 = p_cfg->nonce[1];
+ p_reg->XIP_ENC.NONCE2 = p_cfg->nonce[2];
+}
+
+NRF_STATIC_INLINE void nrf_qspi_xip_encryption_set(NRF_QSPI_Type * p_reg, bool enable)
+{
+ p_reg->XIP_ENC.ENABLE =
+ (enable ? QSPI_XIP_ENC_ENABLE_ENABLE_Enabled << QSPI_XIP_ENC_ENABLE_ENABLE_Pos
+ : QSPI_XIP_ENC_ENABLE_ENABLE_Disabled << QSPI_XIP_ENC_ENABLE_ENABLE_Pos);
+}
+#endif
+
+#if NRF_QSPI_HAS_DMA_ENC
+NRF_STATIC_INLINE void nrf_qspi_dma_encryption_configure(NRF_QSPI_Type * p_reg,
+ nrf_qspi_encryption_t const * p_cfg)
+{
+ p_reg->DMA_ENC.KEY0 = p_cfg->key[0];
+ p_reg->DMA_ENC.KEY1 = p_cfg->key[1];
+ p_reg->DMA_ENC.KEY2 = p_cfg->key[2];
+ p_reg->DMA_ENC.KEY3 = p_cfg->key[3];
+ p_reg->DMA_ENC.NONCE0 = p_cfg->nonce[0];
+ p_reg->DMA_ENC.NONCE1 = p_cfg->nonce[1];
+ p_reg->DMA_ENC.NONCE2 = p_cfg->nonce[2];
+}
+
+NRF_STATIC_INLINE void nrf_qspi_dma_encryption_set(NRF_QSPI_Type * p_reg, bool enable)
+{
+ p_reg->DMA_ENC.ENABLE =
+ (enable ? QSPI_DMA_ENC_ENABLE_ENABLE_Enabled << QSPI_DMA_ENC_ENABLE_ENABLE_Pos
+ : QSPI_DMA_ENC_ENABLE_ENABLE_Disabled << QSPI_DMA_ENC_ENABLE_ENABLE_Pos);
+}
+#endif
+#endif // NRF_DECLARE_ONLY
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_QSPI_H__
diff --git a/platform/ext/target/nordic_nrf/common/core/nrfx/hal/nrf_twim.h b/platform/ext/target/nordic_nrf/common/core/nrfx/hal/nrf_twim.h
new file mode 100644
index 000000000..c5ed69b73
--- /dev/null
+++ b/platform/ext/target/nordic_nrf/common/core/nrfx/hal/nrf_twim.h
@@ -0,0 +1,635 @@
+/*
+ * Copyright (c) 2015 - 2020, 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 the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef NRF_TWIM_H__
+#define NRF_TWIM_H__
+
+#include <nrfx.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup nrf_twim_hal TWIM HAL
+ * @{
+ * @ingroup nrf_twim
+ * @brief Hardware access layer for managing the TWIM peripheral.
+ */
+
+/** @brief TWIM tasks. */
+typedef enum
+{
+ 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.
+} nrf_twim_task_t;
+
+/** @brief TWIM events. */
+typedef enum
+{
+ 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.
+} 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_ALL_SHORTS_MASK = TWIM_SHORTS_LASTTX_STARTRX_Msk |
+ TWIM_SHORTS_LASTTX_SUSPEND_Msk |
+ TWIM_SHORTS_LASTTX_STOP_Msk |
+ TWIM_SHORTS_LASTRX_STARTTX_Msk |
+ TWIM_SHORTS_LASTRX_STOP_Msk ///< All TWIM shortcuts.
+} 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 = TWIM_INTENSET_SUSPENDED_Msk, ///< 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_ALL_INTS_MASK = TWIM_INTENSET_STOPPED_Msk |
+ TWIM_INTENSET_ERROR_Msk |
+ TWIM_INTENSET_SUSPENDED_Msk |
+ TWIM_INTENSET_RXSTARTED_Msk |
+ TWIM_INTENSET_TXSTARTED_Msk |
+ TWIM_INTENSET_LASTRX_Msk |
+ TWIM_INTENSET_LASTTX_Msk ///< All TWIM interrupts.
+} 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.
+#if defined(TWIM_FREQUENCY_FREQUENCY_K1000) || defined(__NRFX_DOXYGEN__)
+ NRF_TWIM_FREQ_1000K = TWIM_FREQUENCY_FREQUENCY_K1000 ///< 1000 kbps.
+#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.
+ NRF_TWIM_ERROR_OVERRUN = TWIM_ERRORSRC_OVERRUN_Msk ///< Overrun error.
+ /**< A new byte was received before the previous byte was
+ * handled by peripheral. (previous data is lost). */
+} nrf_twim_error_t;
+
+
+/**
+ * @brief Function for activating the specified TWIM task.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] task Task to be activated.
+ */
+NRF_STATIC_INLINE void nrf_twim_task_trigger(NRF_TWIM_Type * p_reg,
+ nrf_twim_task_t task);
+
+/**
+ * @brief Function for getting the address of the specified TWIM task register.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] task The specified task.
+ *
+ * @return Address of the specified task register.
+ */
+NRF_STATIC_INLINE uint32_t nrf_twim_task_address_get(NRF_TWIM_Type const * p_reg,
+ nrf_twim_task_t task);
+
+/**
+ * @brief Function for clearing the specified TWIM event.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] event Event to clear.
+ */
+NRF_STATIC_INLINE void nrf_twim_event_clear(NRF_TWIM_Type * p_reg,
+ nrf_twim_event_t event);
+
+/**
+ * @brief Function for retrieving the state of the TWIM event.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] event Event to be checked.
+ *
+ * @retval true The event has been generated.
+ * @retval false The event has not been generated.
+ */
+NRF_STATIC_INLINE bool nrf_twim_event_check(NRF_TWIM_Type const * p_reg,
+ nrf_twim_event_t event);
+
+/**
+ * @brief Function for getting the address of the specified TWIM event register.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] event The specified event.
+ *
+ * @return Address of the specified event register.
+ */
+NRF_STATIC_INLINE uint32_t nrf_twim_event_address_get(NRF_TWIM_Type const * p_reg,
+ nrf_twim_event_t event);
+
+/**
+ * @brief Function for enabling the specified shortcuts.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] mask Shortcuts to be enabled.
+ */
+NRF_STATIC_INLINE void nrf_twim_shorts_enable(NRF_TWIM_Type * p_reg,
+ uint32_t mask);
+
+/**
+ * @brief Function for disabling the specified shortcuts.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] mask Shortcuts to be disabled.
+ */
+NRF_STATIC_INLINE void nrf_twim_shorts_disable(NRF_TWIM_Type * p_reg,
+ uint32_t mask);
+
+/**
+ * @brief Function for enabling the specified interrupts.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] mask Mask of interrupts to be enabled.
+ */
+NRF_STATIC_INLINE void nrf_twim_int_enable(NRF_TWIM_Type * p_reg,
+ uint32_t mask);
+
+/**
+ * @brief Function for disabling the specified interrupts.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] mask Mask of interrupts to be disabled.
+ */
+NRF_STATIC_INLINE void nrf_twim_int_disable(NRF_TWIM_Type * p_reg,
+ uint32_t mask);
+
+/**
+ * @brief Function for checking if the specified interrupts are enabled.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] mask Mask of interrupts to be checked.
+ *
+ * @return Mask of enabled interrupts.
+ */
+NRF_STATIC_INLINE uint32_t nrf_twim_int_enable_check(NRF_TWIM_Type const * p_reg, uint32_t mask);
+
+#if defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
+/**
+ * @brief Function for setting the subscribe configuration for a given
+ * TWIM task.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] task Task for which to set the configuration.
+ * @param[in] channel Channel through which to subscribe events.
+ */
+NRF_STATIC_INLINE void nrf_twim_subscribe_set(NRF_TWIM_Type * p_reg,
+ nrf_twim_task_t task,
+ uint8_t channel);
+
+/**
+ * @brief Function for clearing the subscribe configuration for a given
+ * TWIM task.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] task Task for which to clear the configuration.
+ */
+NRF_STATIC_INLINE void nrf_twim_subscribe_clear(NRF_TWIM_Type * p_reg,
+ nrf_twim_task_t task);
+
+/**
+ * @brief Function for setting the publish configuration for a given
+ * TWIM event.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] event Event for which to set the configuration.
+ * @param[in] channel Channel through which to publish the event.
+ */
+NRF_STATIC_INLINE void nrf_twim_publish_set(NRF_TWIM_Type * p_reg,
+ nrf_twim_event_t event,
+ uint8_t channel);
+
+/**
+ * @brief Function for clearing the publish configuration for a given
+ * TWIM event.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] event Event for which to clear the configuration.
+ */
+NRF_STATIC_INLINE void nrf_twim_publish_clear(NRF_TWIM_Type * p_reg,
+ nrf_twim_event_t event);
+#endif // defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
+
+/**
+ * @brief Function for enabling the TWIM peripheral.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ */
+NRF_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 structure of registers of the peripheral.
+ */
+NRF_STATIC_INLINE void nrf_twim_disable(NRF_TWIM_Type * p_reg);
+
+/**
+ * @brief Function for configuring TWI pins.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] scl_pin SCL pin number.
+ * @param[in] sda_pin SDA pin number.
+ */
+NRF_STATIC_INLINE void nrf_twim_pins_set(NRF_TWIM_Type * p_reg,
+ uint32_t scl_pin,
+ uint32_t sda_pin);
+
+/**
+ * @brief Function for retrieving the SCL pin selection.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ *
+ * @return SCL pin selection.
+ */
+NRF_STATIC_INLINE uint32_t nrf_twim_scl_pin_get(NRF_TWIM_Type const * p_reg);
+
+/**
+ * @brief Function for retrieving the SDA pin selection.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ *
+ * @return SDA pin selection.
+ */
+NRF_STATIC_INLINE uint32_t nrf_twim_sda_pin_get(NRF_TWIM_Type const * p_reg);
+
+/**
+ * @brief Function for setting the TWI master clock frequency.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] frequency TWI frequency.
+ */
+NRF_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 structure of registers of the peripheral.
+ *
+ * @return Mask with error source flags.
+ */
+NRF_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 structure of registers of the peripheral.
+ * @param[in] address Address to be used in transfers.
+ */
+NRF_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 structure of registers of the peripheral.
+ * @param[in] p_buffer Pointer to the buffer with data to send.
+ * @param[in] length Maximum number of data bytes to transmit.
+ */
+NRF_STATIC_INLINE void nrf_twim_tx_buffer_set(NRF_TWIM_Type * p_reg,
+ uint8_t const * p_buffer,
+ size_t length);
+
+/**
+ * @brief Function for setting the receive buffer.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] p_buffer Pointer to the buffer for received data.
+ * @param[in] length Maximum number of data bytes to receive.
+ */
+NRF_STATIC_INLINE void nrf_twim_rx_buffer_set(NRF_TWIM_Type * p_reg,
+ uint8_t * p_buffer,
+ size_t length);
+
+/**
+ * @brief Function for setting the specified shortcuts.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ * @param[in] mask Shortcuts to be set.
+ */
+NRF_STATIC_INLINE void nrf_twim_shorts_set(NRF_TWIM_Type * p_reg,
+ uint32_t mask);
+
+/**
+ * @brief Function for getting the shortcut setting.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ *
+ * @return Current shortcut configuration.
+ */
+NRF_STATIC_INLINE uint32_t nrf_twim_shorts_get(NRF_TWIM_Type const * p_reg);
+
+/**
+ * @brief Function for getting the amount of transmitted bytes.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ *
+ * @return Amount of transmitted bytes.
+ */
+NRF_STATIC_INLINE size_t nrf_twim_txd_amount_get(NRF_TWIM_Type const * p_reg);
+
+/**
+ * @brief Function for getting the amount of received bytes.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ *
+ * @return Amount of received bytes.
+ */
+NRF_STATIC_INLINE size_t nrf_twim_rxd_amount_get(NRF_TWIM_Type const * p_reg);
+
+/**
+ * @brief Function for enabling the TX list feature.
+ *
+ * @param[in] p_reg Pointer to the structure of registers of the peripheral.
+ */
+NRF_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 structure of registers of the peripheral.
+ */
+NRF_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 structure of registers of the peripheral.
+ */
+NRF_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 structure of registers of the peripheral.
+ */
+NRF_STATIC_INLINE void nrf_twim_rx_list_disable(NRF_TWIM_Type * p_reg);
+
+
+#ifndef NRF_DECLARE_ONLY
+
+NRF_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;
+}
+
+NRF_STATIC_INLINE uint32_t nrf_twim_task_address_get(NRF_TWIM_Type const * p_reg,
+ nrf_twim_task_t task)
+{
+ return (uint32_t)((uint8_t *)p_reg + (uint32_t)task);
+}
+
+NRF_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;
+ nrf_event_readback((uint8_t *)p_reg + (uint32_t)event);
+}
+
+NRF_STATIC_INLINE bool nrf_twim_event_check(NRF_TWIM_Type const * p_reg,
+ nrf_twim_event_t event)
+{
+ return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
+}
+
+NRF_STATIC_INLINE uint32_t nrf_twim_event_address_get(NRF_TWIM_Type const * p_reg,
+ nrf_twim_event_t event)
+{
+ return (uint32_t)((uint8_t *)p_reg + (uint32_t)event);
+}
+
+NRF_STATIC_INLINE void nrf_twim_shorts_enable(NRF_TWIM_Type * p_reg,
+ uint32_t mask)
+{
+ p_reg->SHORTS |= mask;
+}
+
+NRF_STATIC_INLINE void nrf_twim_shorts_disable(NRF_TWIM_Type * p_reg,
+ uint32_t mask)
+{
+ p_reg->SHORTS &= ~(mask);
+}
+
+NRF_STATIC_INLINE void nrf_twim_int_enable(NRF_TWIM_Type * p_reg,
+ uint32_t mask)
+{
+ p_reg->INTENSET = mask;
+}
+
+NRF_STATIC_INLINE void nrf_twim_int_disable(NRF_TWIM_Type * p_reg,
+ uint32_t mask)
+{
+ p_reg->INTENCLR = mask;
+}
+
+NRF_STATIC_INLINE uint32_t nrf_twim_int_enable_check(NRF_TWIM_Type const * p_reg, uint32_t mask)
+{
+ return p_reg->INTENSET & mask;
+}
+
+#if defined(DPPI_PRESENT)
+NRF_STATIC_INLINE void nrf_twim_subscribe_set(NRF_TWIM_Type * p_reg,
+ nrf_twim_task_t task,
+ uint8_t channel)
+{
+ *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) =
+ ((uint32_t)channel | TWIM_SUBSCRIBE_STARTRX_EN_Msk);
+}
+
+NRF_STATIC_INLINE void nrf_twim_subscribe_clear(NRF_TWIM_Type * p_reg,
+ nrf_twim_task_t task)
+{
+ *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) = 0;
+}
+
+NRF_STATIC_INLINE void nrf_twim_publish_set(NRF_TWIM_Type * p_reg,
+ nrf_twim_event_t event,
+ uint8_t channel)
+{
+ *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) =
+ ((uint32_t)channel | TWIM_PUBLISH_STOPPED_EN_Msk);
+}
+
+NRF_STATIC_INLINE void nrf_twim_publish_clear(NRF_TWIM_Type * p_reg,
+ nrf_twim_event_t event)
+{
+ *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) = 0;
+}
+#endif // defined(DPPI_PRESENT)
+
+NRF_STATIC_INLINE void nrf_twim_enable(NRF_TWIM_Type * p_reg)
+{
+ p_reg->ENABLE = (TWIM_ENABLE_ENABLE_Enabled << TWIM_ENABLE_ENABLE_Pos);
+}
+
+NRF_STATIC_INLINE void nrf_twim_disable(NRF_TWIM_Type * p_reg)
+{
+ p_reg->ENABLE = (TWIM_ENABLE_ENABLE_Disabled << TWIM_ENABLE_ENABLE_Pos);
+}
+
+NRF_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;
+}
+
+NRF_STATIC_INLINE uint32_t nrf_twim_scl_pin_get(NRF_TWIM_Type const * p_reg)
+{
+ return p_reg->PSEL.SCL;
+}
+
+NRF_STATIC_INLINE uint32_t nrf_twim_sda_pin_get(NRF_TWIM_Type const * p_reg)
+{
+ return p_reg->PSEL.SDA;
+}
+
+NRF_STATIC_INLINE void nrf_twim_frequency_set(NRF_TWIM_Type * p_reg,
+ nrf_twim_frequency_t frequency)
+{
+ p_reg->FREQUENCY = frequency;
+}
+
+NRF_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;
+}
+
+NRF_STATIC_INLINE void nrf_twim_address_set(NRF_TWIM_Type * p_reg,
+ uint8_t address)
+{
+ p_reg->ADDRESS = address;
+}
+
+NRF_STATIC_INLINE void nrf_twim_tx_buffer_set(NRF_TWIM_Type * p_reg,
+ uint8_t const * p_buffer,
+ size_t length)
+{
+ p_reg->TXD.PTR = (uint32_t)p_buffer;
+ p_reg->TXD.MAXCNT = length;
+}
+
+NRF_STATIC_INLINE void nrf_twim_rx_buffer_set(NRF_TWIM_Type * p_reg,
+ uint8_t * p_buffer,
+ size_t length)
+{
+ p_reg->RXD.PTR = (uint32_t)p_buffer;
+ p_reg->RXD.MAXCNT = length;
+}
+
+NRF_STATIC_INLINE void nrf_twim_shorts_set(NRF_TWIM_Type * p_reg,
+ uint32_t mask)
+{
+ p_reg->SHORTS = mask;
+}
+
+NRF_STATIC_INLINE uint32_t nrf_twim_shorts_get(NRF_TWIM_Type const * p_reg)
+{
+ return p_reg->SHORTS;
+}
+
+NRF_STATIC_INLINE size_t nrf_twim_txd_amount_get(NRF_TWIM_Type const * p_reg)
+{
+ return p_reg->TXD.AMOUNT;
+}
+
+NRF_STATIC_INLINE size_t nrf_twim_rxd_amount_get(NRF_TWIM_Type const * p_reg)
+{
+ return p_reg->RXD.AMOUNT;
+}
+
+NRF_STATIC_INLINE void nrf_twim_tx_list_enable(NRF_TWIM_Type * p_reg)
+{
+ p_reg->TXD.LIST = TWIM_TXD_LIST_LIST_ArrayList << TWIM_TXD_LIST_LIST_Pos;
+}
+
+NRF_STATIC_INLINE void nrf_twim_tx_list_disable(NRF_TWIM_Type * p_reg)
+{
+ p_reg->TXD.LIST = TWIM_TXD_LIST_LIST_Disabled << TWIM_TXD_LIST_LIST_Pos;
+}
+
+NRF_STATIC_INLINE void nrf_twim_rx_list_enable(NRF_TWIM_Type * p_reg)
+{
+ p_reg->RXD.LIST = TWIM_RXD_LIST_LIST_ArrayList << TWIM_RXD_LIST_LIST_Pos;
+}
+
+NRF_STATIC_INLINE void nrf_twim_rx_list_disable(NRF_TWIM_Type * p_reg)
+{
+ p_reg->RXD.LIST = TWIM_RXD_LIST_LIST_Disabled << TWIM_RXD_LIST_LIST_Pos;
+}
+#endif // NRF_DECLARE_ONLY
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_TWIM_H__